diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_tf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_tf.py new file mode 100644 index 0000000000000000000000000000000000000000..126172ffbd3000f7887c2d2a5d3526d8fc473cba --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_tf.py @@ -0,0 +1,298 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + Benchmarking the library on inference and training in PyTorch. +""" + + +import random +import timeit +from functools import wraps +from typing import Callable, Optional + +from ..configuration_utils import PretrainedConfig +from ..models.auto.modeling_tf_auto import TF_MODEL_MAPPING, TF_MODEL_WITH_LM_HEAD_MAPPING +from ..utils import is_py3nvml_available, is_tf_available, logging +from .benchmark_utils import ( + Benchmark, + Memory, + MemorySummary, + measure_peak_memory_cpu, + start_memory_tracing, + stop_memory_tracing, +) + + +if is_tf_available(): + import tensorflow as tf + from tensorflow.python.framework.errors_impl import ResourceExhaustedError + + from .benchmark_args_tf import TensorFlowBenchmarkArguments + +if is_py3nvml_available(): + import py3nvml.py3nvml as nvml + +logger = logging.get_logger(__name__) + + +def run_with_tf_optimizations(do_eager_mode: bool, use_xla: bool): + def run_func(func): + @wraps(func) + def run_in_eager_mode(*args, **kwargs): + return func(*args, **kwargs) + + @wraps(func) + @tf.function(experimental_compile=use_xla) + def run_in_graph_mode(*args, **kwargs): + return func(*args, **kwargs) + + if do_eager_mode is True: + assert ( + use_xla is False + ), "Cannot run model in XLA, if `args.eager_mode` is set to `True`. Please set `args.eager_mode=False`." + return run_in_eager_mode + else: + return run_in_graph_mode + + return run_func + + +def random_input_ids(batch_size: int, sequence_length: int, vocab_size: int) -> ["tf.Tensor"]: + rng = random.Random() + values = [rng.randint(0, vocab_size - 1) for i in range(batch_size * sequence_length)] + return tf.constant(values, shape=(batch_size, sequence_length), dtype=tf.int32) + + +class TensorFlowBenchmark(Benchmark): + args: TensorFlowBenchmarkArguments + configs: PretrainedConfig + framework: str = "TensorFlow" + + @property + def framework_version(self): + return tf.__version__ + + def _inference_speed(self, model_name: str, batch_size: int, sequence_length: int) -> float: + # initialize GPU on separate process + strategy = self.args.strategy + assert strategy is not None, "A device strategy has to be initialized before using TensorFlow." + _inference = self._prepare_inference_func(model_name, batch_size, sequence_length) + return self._measure_speed(_inference) + + def _train_speed(self, model_name: str, batch_size: int, sequence_length: int) -> float: + strategy = self.args.strategy + assert strategy is not None, "A device strategy has to be initialized before using TensorFlow." + _train = self._prepare_train_func(model_name, batch_size, sequence_length) + return self._measure_speed(_train) + + def _inference_memory( + self, model_name: str, batch_size: int, sequence_length: int + ) -> [Memory, Optional[MemorySummary]]: + # initialize GPU on separate process + if self.args.is_gpu: + tf.config.experimental.set_memory_growth(self.args.gpu_list[self.args.device_idx], True) + strategy = self.args.strategy + assert strategy is not None, "A device strategy has to be initialized before using TensorFlow." + _inference = self._prepare_inference_func(model_name, batch_size, sequence_length) + return self._measure_memory(_inference) + + def _train_memory( + self, model_name: str, batch_size: int, sequence_length: int + ) -> [Memory, Optional[MemorySummary]]: + if self.args.is_gpu: + tf.config.experimental.set_memory_growth(self.args.gpu_list[self.args.device_idx], True) + strategy = self.args.strategy + assert strategy is not None, "A device strategy has to be initialized before using TensorFlow." + + _train = self._prepare_train_func(model_name, batch_size, sequence_length) + return self._measure_memory(_train) + + def _prepare_inference_func(self, model_name: str, batch_size: int, sequence_length: int) -> Callable[[], None]: + config = self.config_dict[model_name] + + if self.args.fp16: + raise NotImplementedError("Mixed precision is currently not supported.") + + has_model_class_in_config = ( + hasattr(config, "architectures") + and isinstance(config.architectures, list) + and len(config.architectures) > 0 + ) + if not self.args.only_pretrain_model and has_model_class_in_config: + try: + model_class = "TF" + config.architectures[0] # prepend 'TF' for tensorflow model + transformers_module = __import__("transformers", fromlist=[model_class]) + model_cls = getattr(transformers_module, model_class) + model = model_cls(config) + except ImportError: + raise ImportError( + f"{model_class} does not exist. If you just want to test the pretrained model, you might want to" + " set `--only_pretrain_model` or `args.only_pretrain_model=True`." + ) + else: + model = TF_MODEL_MAPPING[config.__class__](config) + + # encoder-decoder has vocab size saved differently + vocab_size = config.vocab_size if hasattr(config, "vocab_size") else config.encoder.vocab_size + input_ids = random_input_ids(batch_size, sequence_length, vocab_size) + + @run_with_tf_optimizations(self.args.eager_mode, self.args.use_xla) + def encoder_decoder_forward(): + return model(input_ids, decoder_input_ids=input_ids, training=False) + + @run_with_tf_optimizations(self.args.eager_mode, self.args.use_xla) + def encoder_forward(): + return model(input_ids, training=False) + + _inference = encoder_decoder_forward if config.is_encoder_decoder else encoder_forward + + return _inference + + def _prepare_train_func(self, model_name: str, batch_size: int, sequence_length: int) -> Callable[[], None]: + config = self.config_dict[model_name] + + assert ( + self.args.eager_mode is False + ), "Training cannot be done in eager mode. Please make sure that `args.eager_mode = False`." + + if self.args.fp16: + raise NotImplementedError("Mixed precision is currently not supported.") + + has_model_class_in_config = ( + hasattr(config, "architectures") + and isinstance(config.architectures, list) + and len(config.architectures) > 0 + ) + if not self.args.only_pretrain_model and has_model_class_in_config: + try: + model_class = "TF" + config.architectures[0] # prepend 'TF' for tensorflow model + transformers_module = __import__("transformers", fromlist=[model_class]) + model_cls = getattr(transformers_module, model_class) + model = model_cls(config) + except ImportError: + raise ImportError( + f"{model_class} does not exist. If you just want to test the pretrained model, you might want to" + " set `--only_pretrain_model` or `args.only_pretrain_model=True`." + ) + else: + model = TF_MODEL_WITH_LM_HEAD_MAPPING[config.__class__](config) + + # encoder-decoder has vocab size saved differently + vocab_size = config.vocab_size if hasattr(config, "vocab_size") else config.encoder.vocab_size + input_ids = random_input_ids(batch_size, sequence_length, vocab_size) + + @run_with_tf_optimizations(self.args.eager_mode, self.args.use_xla) + def encoder_decoder_train(): + loss = model(input_ids, decoder_input_ids=input_ids, labels=input_ids, training=True)[0] + gradients = tf.gradients(loss, model.trainable_variables) + return gradients + + @run_with_tf_optimizations(self.args.eager_mode, self.args.use_xla) + def encoder_train(): + loss = model(input_ids, labels=input_ids, training=True)[0] + gradients = tf.gradients(loss, model.trainable_variables) + return gradients + + _train = encoder_decoder_train if config.is_encoder_decoder else encoder_train + + return _train + + def _measure_speed(self, func) -> float: + with self.args.strategy.scope(): + try: + if self.args.is_tpu or self.args.use_xla: + # run additional 10 times to stabilize compilation for tpu + logger.info("Do inference on TPU. Running model 5 times to stabilize compilation") + timeit.repeat(func, repeat=1, number=5) + + # as written in https://docs.python.org/2/library/timeit.html#timeit.Timer.repeat, min should be taken rather than the average + runtimes = timeit.repeat( + func, + repeat=self.args.repeat, + number=10, + ) + + return min(runtimes) / 10.0 + except ResourceExhaustedError as e: + self.print_fn(f"Doesn't fit on GPU. {e}") + + def _measure_memory(self, func: Callable[[], None]) -> [Memory, MemorySummary]: + logger.info( + "Note that TensorFlow allocates more memory than " + "it might need to speed up computation. " + "The memory reported here corresponds to the memory " + "reported by `nvidia-smi`, which can vary depending " + "on total available memory on the GPU that is used." + ) + with self.args.strategy.scope(): + try: + if self.args.trace_memory_line_by_line: + assert self.args.eager_mode, ( + "`args.eager_mode` is set to `False`. Make sure to run model in eager mode to measure memory" + " consumption line by line." + ) + trace = start_memory_tracing("transformers") + + if self.args.is_tpu: + # tpu + raise NotImplementedError( + "Memory Benchmarking is currently not implemented for TPU. Please disable memory benchmarking" + " with `args.memory=False`" + ) + elif self.args.is_gpu: + # gpu + if not is_py3nvml_available(): + logger.warning( + "py3nvml not installed, we won't log GPU memory usage. " + "Install py3nvml (pip install py3nvml) to log information about GPU." + ) + memory = "N/A" + else: + logger.info( + "Measuring total GPU usage on GPU device. Make sure to not have additional processes" + " running on the same GPU." + ) + # init nvml + nvml.nvmlInit() + func() + handle = nvml.nvmlDeviceGetHandleByIndex(self.args.device_idx) + meminfo = nvml.nvmlDeviceGetMemoryInfo(handle) + max_bytes_in_use = meminfo.used + memory = Memory(max_bytes_in_use) + # shutdown nvml + nvml.nvmlShutdown() + else: + # cpu + if self.args.trace_memory_line_by_line: + logger.info( + "When enabling line by line tracing, the max peak memory for CPU is inaccurate in" + " TensorFlow." + ) + memory = None + else: + memory_bytes = measure_peak_memory_cpu(func) + memory = Memory(memory_bytes) if isinstance(memory_bytes, int) else memory_bytes + if self.args.trace_memory_line_by_line: + summary = stop_memory_tracing(trace) + if memory is None: + memory = summary.total + else: + summary = None + + return memory, summary + except ResourceExhaustedError as e: + self.print_fn(f"Doesn't fit on GPU. {e}") + return "N/A", None diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b7008a7ab755a37923d2de02859735a1e2eea2a0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/benchmark/benchmark_utils.py @@ -0,0 +1,913 @@ +# This file is adapted from the AllenNLP library at https://github.com/allenai/allennlp + +# Copyright 2020 The HuggingFace Team and the AllenNLP authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Utilities for working with the local dataset cache. +""" + +import copy +import csv +import linecache +import os +import platform +import sys +import warnings +from abc import ABC, abstractmethod +from collections import defaultdict, namedtuple +from datetime import datetime +from multiprocessing import Pipe, Process, Queue +from multiprocessing.connection import Connection +from typing import Callable, Iterable, List, NamedTuple, Optional, Union + +from .. import AutoConfig, PretrainedConfig +from .. import __version__ as version +from ..utils import is_psutil_available, is_py3nvml_available, is_tf_available, is_torch_available, logging +from .benchmark_args_utils import BenchmarkArguments + + +if is_torch_available(): + from torch.cuda import empty_cache as torch_empty_cache + +if is_tf_available(): + from tensorflow.python.eager import context as tf_context + +if is_psutil_available(): + import psutil + +if is_py3nvml_available(): + import py3nvml.py3nvml as nvml + +if platform.system() == "Windows": + from signal import CTRL_C_EVENT as SIGKILL +else: + from signal import SIGKILL + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +_is_memory_tracing_enabled = False + +BenchmarkOutput = namedtuple( + "BenchmarkOutput", + [ + "time_inference_result", + "memory_inference_result", + "time_train_result", + "memory_train_result", + "inference_summary", + "train_summary", + ], +) + + +def separate_process_wrapper_fn(func: Callable[[], None], do_multi_processing: bool) -> Callable[[], None]: + """ + This function wraps another function into its own separated process. In order to ensure accurate memory + measurements it is important that the function is executed in a separate process + + Args: + - `func`: (`callable`): function() -> ... generic function which will be executed in its own separate process + - `do_multi_processing`: (`bool`) Whether to run function on separate process or not + """ + + def multi_process_func(*args, **kwargs): + # run function in an individual + # process to get correct memory + def wrapper_func(queue: Queue, *args): + try: + result = func(*args) + except Exception as e: + logger.error(e) + print(e) + result = "N/A" + queue.put(result) + + queue = Queue() + p = Process(target=wrapper_func, args=[queue] + list(args)) + p.start() + result = queue.get() + p.join() + return result + + if do_multi_processing: + logger.info(f"Function {func} is executed in its own process...") + return multi_process_func + else: + return func + + +def is_memory_tracing_enabled(): + global _is_memory_tracing_enabled + return _is_memory_tracing_enabled + + +class Frame(NamedTuple): + """ + `Frame` is a NamedTuple used to gather the current frame state. `Frame` has the following fields: + + - 'filename' (string): Name of the file currently executed + - 'module' (string): Name of the module currently executed + - 'line_number' (int): Number of the line currently executed + - 'event' (string): Event that triggered the tracing (default will be "line") + - 'line_text' (string): Text of the line in the python script + """ + + filename: str + module: str + line_number: int + event: str + line_text: str + + +class UsedMemoryState(NamedTuple): + """ + `UsedMemoryState` are named tuples with the following fields: + + - 'frame': a `Frame` namedtuple (see below) storing information on the current tracing frame (current file, + location in current file) + - 'cpu_memory': CPU RSS memory state *before* executing the line + - 'gpu_memory': GPU used memory *before* executing the line (sum for all GPUs or for only `gpus_to_trace` if + provided) + """ + + frame: Frame + cpu_memory: int + gpu_memory: int + + +class Memory(NamedTuple): + """ + `Memory` NamedTuple have a single field `bytes` and you can get a human readable str of the number of mega bytes by + calling `__repr__` + + - `byte` (integer): number of bytes, + """ + + bytes: int + + def __repr__(self) -> str: + return str(bytes_to_mega_bytes(self.bytes)) + + +class MemoryState(NamedTuple): + """ + `MemoryState` are namedtuples listing frame + CPU/GPU memory with the following fields: + + - `frame` (`Frame`): the current frame (see above) + - `cpu`: CPU memory consumed at during the current frame as a `Memory` named tuple + - `gpu`: GPU memory consumed at during the current frame as a `Memory` named tuple + - `cpu_gpu`: CPU + GPU memory consumed at during the current frame as a `Memory` named tuple + """ + + frame: Frame + cpu: Memory + gpu: Memory + cpu_gpu: Memory + + +class MemorySummary(NamedTuple): + """ + `MemorySummary` namedtuple otherwise with the fields: + + - `sequential`: a list of `MemoryState` namedtuple (see below) computed from the provided `memory_trace` by + subtracting the memory after executing each line from the memory before executing said line. + - `cumulative`: a list of `MemoryState` namedtuple (see below) with cumulative increase in memory for each line + obtained by summing repeated memory increase for a line if it's executed several times. The list is sorted + from the frame with the largest memory consumption to the frame with the smallest (can be negative if memory + is released) + - `total`: total memory increase during the full tracing as a `Memory` named tuple (see below). Line with + memory release (negative consumption) are ignored if `ignore_released_memory` is `True` (default). + """ + + sequential: List[MemoryState] + cumulative: List[MemoryState] + current: List[MemoryState] + total: Memory + + +MemoryTrace = List[UsedMemoryState] + + +def measure_peak_memory_cpu(function: Callable[[], None], interval=0.5, device_idx=None) -> int: + """ + measures peak cpu memory consumption of a given `function` running the function for at least interval seconds and + at most 20 * interval seconds. This function is heavily inspired by: `memory_usage` of the package + `memory_profiler`: + https://github.com/pythonprofilers/memory_profiler/blob/895c4ac7a08020d66ae001e24067da6dcea42451/memory_profiler.py#L239 + + Args: + - `function`: (`callable`): function() -> ... function without any arguments to measure for which to measure + the peak memory + + - `interval`: (`float`, `optional`, defaults to `0.5`) interval in second for which to measure the memory usage + + - `device_idx`: (`int`, `optional`, defaults to `None`) device id for which to measure gpu usage + + Returns: + + - `max_memory`: (`int`) consumed memory peak in Bytes + """ + + def get_cpu_memory(process_id: int) -> int: + """ + measures current cpu memory usage of a given `process_id` + + Args: + - `process_id`: (`int`) process_id for which to measure memory + + Returns + + - `memory`: (`int`) consumed memory in Bytes + """ + process = psutil.Process(process_id) + try: + meminfo_attr = "memory_info" if hasattr(process, "memory_info") else "get_memory_info" + memory = getattr(process, meminfo_attr)()[0] + except psutil.AccessDenied: + raise ValueError("Error with Psutil.") + return memory + + if not is_psutil_available(): + logger.warning( + "Psutil not installed, we won't log CPU memory usage. " + "Install Psutil (pip install psutil) to use CPU memory tracing." + ) + max_memory = "N/A" + else: + + class MemoryMeasureProcess(Process): + + """ + `MemoryMeasureProcess` inherits from `Process` and overwrites its `run()` method. Used to measure the + memory usage of a process + """ + + def __init__(self, process_id: int, child_connection: Connection, interval: float): + super().__init__() + self.process_id = process_id + self.interval = interval + self.connection = child_connection + self.num_measurements = 1 + self.mem_usage = get_cpu_memory(self.process_id) + + def run(self): + self.connection.send(0) + stop = False + while True: + self.mem_usage = max(self.mem_usage, get_cpu_memory(self.process_id)) + self.num_measurements += 1 + + if stop: + break + + stop = self.connection.poll(self.interval) + + # send results to parent pipe + self.connection.send(self.mem_usage) + self.connection.send(self.num_measurements) + + while True: + # create child, parent connection + child_connection, parent_connection = Pipe() + + # instantiate process + mem_process = MemoryMeasureProcess(os.getpid(), child_connection, interval) + mem_process.start() + + # wait until we get memory + parent_connection.recv() + + try: + # execute function + function() + + # start parent connection + parent_connection.send(0) + + # receive memory and num measurements + max_memory = parent_connection.recv() + num_measurements = parent_connection.recv() + except Exception: + # kill process in a clean way + parent = psutil.Process(os.getpid()) + for child in parent.children(recursive=True): + os.kill(child.pid, SIGKILL) + mem_process.join(0) + raise RuntimeError("Process killed. Error in Process") + + # run process at least 20 * interval or until it finishes + mem_process.join(20 * interval) + + if (num_measurements > 4) or (interval < 1e-6): + break + + # reduce interval + interval /= 10 + + return max_memory + + +def start_memory_tracing( + modules_to_trace: Optional[Union[str, Iterable[str]]] = None, + modules_not_to_trace: Optional[Union[str, Iterable[str]]] = None, + events_to_trace: str = "line", + gpus_to_trace: Optional[List[int]] = None, +) -> MemoryTrace: + """ + Setup line-by-line tracing to record rss mem (RAM) at each line of a module or sub-module. See `./benchmark.py` for + usage examples. Current memory consumption is returned using psutil and in particular is the RSS memory "Resident + Set Size” (the non-swapped physical memory the process is using). See + https://psutil.readthedocs.io/en/latest/#psutil.Process.memory_info + + Args: + - `modules_to_trace`: (None, string, list/tuple of string) if None, all events are recorded if string or list + of strings: only events from the listed module/sub-module will be recorded (e.g. 'fairseq' or + 'transformers.models.gpt2.modeling_gpt2') + - `modules_not_to_trace`: (None, string, list/tuple of string) if None, no module is avoided if string or list + of strings: events from the listed module/sub-module will not be recorded (e.g. 'torch') + - `events_to_trace`: string or list of string of events to be recorded (see official python doc for + `sys.settrace` for the list of events) default to line + - `gpus_to_trace`: (optional list, default None) list of GPUs to trace. Default to tracing all GPUs + + Return: + + - `memory_trace` is a list of `UsedMemoryState` for each event (default each line of the traced script). + + - `UsedMemoryState` are named tuples with the following fields: + + - 'frame': a `Frame` namedtuple (see below) storing information on the current tracing frame (current + file, location in current file) + - 'cpu_memory': CPU RSS memory state *before* executing the line + - 'gpu_memory': GPU used memory *before* executing the line (sum for all GPUs or for only + `gpus_to_trace` if provided) + + `Frame` is a namedtuple used by `UsedMemoryState` to list the current frame state. `Frame` has the following + fields: - 'filename' (string): Name of the file currently executed - 'module' (string): Name of the module + currently executed - 'line_number' (int): Number of the line currently executed - 'event' (string): Event that + triggered the tracing (default will be "line") - 'line_text' (string): Text of the line in the python script + + """ + if is_psutil_available(): + process = psutil.Process(os.getpid()) + else: + logger.warning( + "Psutil not installed, we won't log CPU memory usage. " + "Install psutil (pip install psutil) to use CPU memory tracing." + ) + process = None + + if is_py3nvml_available(): + try: + nvml.nvmlInit() + devices = list(range(nvml.nvmlDeviceGetCount())) if gpus_to_trace is None else gpus_to_trace + nvml.nvmlShutdown() + except (OSError, nvml.NVMLError): + logger.warning("Error while initializing communication with GPU. We won't perform GPU memory tracing.") + log_gpu = False + else: + log_gpu = is_torch_available() or is_tf_available() + else: + logger.warning( + "py3nvml not installed, we won't log GPU memory usage. " + "Install py3nvml (pip install py3nvml) to use GPU memory tracing." + ) + log_gpu = False + + memory_trace = [] + + def traceit(frame, event, args): + """ + Tracing method executed before running each line in a module or sub-module Record memory allocated in a list + with debugging information + """ + global _is_memory_tracing_enabled + + if not _is_memory_tracing_enabled: + return traceit + + # Filter events + if events_to_trace is not None: + if isinstance(events_to_trace, str) and event != events_to_trace: + return traceit + elif isinstance(events_to_trace, (list, tuple)) and event not in events_to_trace: + return traceit + + if "__name__" not in frame.f_globals: + return traceit + + # Filter modules + name = frame.f_globals["__name__"] + if not isinstance(name, str): + return traceit + else: + # Filter whitelist of modules to trace + if modules_to_trace is not None: + if isinstance(modules_to_trace, str) and modules_to_trace not in name: + return traceit + elif isinstance(modules_to_trace, (list, tuple)) and all(m not in name for m in modules_to_trace): + return traceit + + # Filter blacklist of modules not to trace + if modules_not_to_trace is not None: + if isinstance(modules_not_to_trace, str) and modules_not_to_trace in name: + return traceit + elif isinstance(modules_not_to_trace, (list, tuple)) and any(m in name for m in modules_not_to_trace): + return traceit + + # Record current tracing state (file, location in file...) + lineno = frame.f_lineno + filename = frame.f_globals["__file__"] + if filename.endswith(".pyc") or filename.endswith(".pyo"): + filename = filename[:-1] + line = linecache.getline(filename, lineno).rstrip() + traced_state = Frame(filename, name, lineno, event, line) + + # Record current memory state (rss memory) and compute difference with previous memory state + cpu_mem = 0 + if process is not None: + mem = process.memory_info() + cpu_mem = mem.rss + + gpu_mem = 0 + if log_gpu: + # Clear GPU caches + if is_torch_available(): + torch_empty_cache() + if is_tf_available(): + tf_context.context()._clear_caches() # See https://github.com/tensorflow/tensorflow/issues/20218#issuecomment-416771802 + + # Sum used memory for all GPUs + nvml.nvmlInit() + + for i in devices: + handle = nvml.nvmlDeviceGetHandleByIndex(i) + meminfo = nvml.nvmlDeviceGetMemoryInfo(handle) + gpu_mem += meminfo.used + + nvml.nvmlShutdown() + + mem_state = UsedMemoryState(traced_state, cpu_mem, gpu_mem) + memory_trace.append(mem_state) + + return traceit + + sys.settrace(traceit) + + global _is_memory_tracing_enabled + _is_memory_tracing_enabled = True + + return memory_trace + + +def stop_memory_tracing( + memory_trace: Optional[MemoryTrace] = None, ignore_released_memory: bool = True +) -> Optional[MemorySummary]: + """ + Stop memory tracing cleanly and return a summary of the memory trace if a trace is given. + + Args: + `memory_trace` (optional output of start_memory_tracing, default: None): + memory trace to convert in summary + `ignore_released_memory` (boolean, default: None): + if True we only sum memory increase to compute total memory + + Return: + + - None if `memory_trace` is None + - `MemorySummary` namedtuple otherwise with the fields: + + - `sequential`: a list of `MemoryState` namedtuple (see below) computed from the provided `memory_trace` by + subtracting the memory after executing each line from the memory before executing said line. + - `cumulative`: a list of `MemoryState` namedtuple (see below) with cumulative increase in memory for each + line obtained by summing repeated memory increase for a line if it's executed several times. The list is + sorted from the frame with the largest memory consumption to the frame with the smallest (can be negative + if memory is released) + - `total`: total memory increase during the full tracing as a `Memory` named tuple (see below). Line with + memory release (negative consumption) are ignored if `ignore_released_memory` is `True` (default). + + `Memory` named tuple have fields + + - `byte` (integer): number of bytes, + - `string` (string): same as human readable string (ex: "3.5MB") + + `Frame` are namedtuple used to list the current frame state and have the following fields: + + - 'filename' (string): Name of the file currently executed + - 'module' (string): Name of the module currently executed + - 'line_number' (int): Number of the line currently executed + - 'event' (string): Event that triggered the tracing (default will be "line") + - 'line_text' (string): Text of the line in the python script + + `MemoryState` are namedtuples listing frame + CPU/GPU memory with the following fields: + + - `frame` (`Frame`): the current frame (see above) + - `cpu`: CPU memory consumed at during the current frame as a `Memory` named tuple + - `gpu`: GPU memory consumed at during the current frame as a `Memory` named tuple + - `cpu_gpu`: CPU + GPU memory consumed at during the current frame as a `Memory` named tuple + """ + global _is_memory_tracing_enabled + _is_memory_tracing_enabled = False + + if memory_trace is not None and len(memory_trace) > 1: + memory_diff_trace = [] + memory_curr_trace = [] + + cumulative_memory_dict = defaultdict(lambda: [0, 0, 0]) + + for ( + (frame, cpu_mem, gpu_mem), + (next_frame, next_cpu_mem, next_gpu_mem), + ) in zip(memory_trace[:-1], memory_trace[1:]): + cpu_mem_inc = next_cpu_mem - cpu_mem + gpu_mem_inc = next_gpu_mem - gpu_mem + cpu_gpu_mem_inc = cpu_mem_inc + gpu_mem_inc + memory_diff_trace.append( + MemoryState( + frame=frame, + cpu=Memory(cpu_mem_inc), + gpu=Memory(gpu_mem_inc), + cpu_gpu=Memory(cpu_gpu_mem_inc), + ) + ) + + memory_curr_trace.append( + MemoryState( + frame=frame, + cpu=Memory(next_cpu_mem), + gpu=Memory(next_gpu_mem), + cpu_gpu=Memory(next_gpu_mem + next_cpu_mem), + ) + ) + + cumulative_memory_dict[frame][0] += cpu_mem_inc + cumulative_memory_dict[frame][1] += gpu_mem_inc + cumulative_memory_dict[frame][2] += cpu_gpu_mem_inc + + cumulative_memory = sorted( + cumulative_memory_dict.items(), key=lambda x: x[1][2], reverse=True + ) # order by the total CPU + GPU memory increase + cumulative_memory = [ + MemoryState( + frame=frame, + cpu=Memory(cpu_mem_inc), + gpu=Memory(gpu_mem_inc), + cpu_gpu=Memory(cpu_gpu_mem_inc), + ) + for frame, (cpu_mem_inc, gpu_mem_inc, cpu_gpu_mem_inc) in cumulative_memory + ] + + memory_curr_trace = sorted(memory_curr_trace, key=lambda x: x.cpu_gpu.bytes, reverse=True) + + if ignore_released_memory: + total_memory = sum(max(0, step_trace.cpu_gpu.bytes) for step_trace in memory_diff_trace) + else: + total_memory = sum(step_trace.cpu_gpu.bytes for step_trace in memory_diff_trace) + + total_memory = Memory(total_memory) + + return MemorySummary( + sequential=memory_diff_trace, + cumulative=cumulative_memory, + current=memory_curr_trace, + total=total_memory, + ) + + return None + + +def bytes_to_mega_bytes(memory_amount: int) -> int: + """Utility to convert a number of bytes (int) into a number of mega bytes (int)""" + return memory_amount >> 20 + + +class Benchmark(ABC): + """ + Benchmarks is a simple but feature-complete benchmarking script to compare memory and time performance of models in + Transformers. + """ + + args: BenchmarkArguments + configs: PretrainedConfig + framework: str + + def __init__(self, args: BenchmarkArguments = None, configs: PretrainedConfig = None): + self.args = args + if configs is None: + self.config_dict = { + model_name: AutoConfig.from_pretrained(model_name) for model_name in self.args.model_names + } + else: + self.config_dict = dict(zip(self.args.model_names, configs)) + + warnings.warn( + f"The class {self.__class__} is deprecated. Hugging Face Benchmarking utils" + " are deprecated in general and it is advised to use external Benchmarking libraries " + " to benchmark Transformer models.", + FutureWarning, + ) + + if self.args.memory and os.getenv("TRANSFORMERS_USE_MULTIPROCESSING") == 0: + logger.warning( + "Memory consumption will not be measured accurately if `args.multi_process` is set to `False.` The" + " flag 'TRANSFORMERS_USE_MULTIPROCESSING' should only be disabled for debugging / testing." + ) + + self._print_fn = None + self._framework_version = None + self._environment_info = None + + @property + def print_fn(self): + if self._print_fn is None: + if self.args.log_print: + + def print_and_log(*args): + with open(self.args.log_filename, "a") as log_file: + log_file.write("".join(args) + "\n") + print(*args) + + self._print_fn = print_and_log + else: + self._print_fn = print + return self._print_fn + + @property + @abstractmethod + def framework_version(self): + pass + + @abstractmethod + def _inference_speed(self, model_name: str, batch_size: int, sequence_length: int) -> float: + pass + + @abstractmethod + def _train_speed(self, model_name: str, batch_size: int, sequence_length: int) -> float: + pass + + @abstractmethod + def _inference_memory( + self, model_name: str, batch_size: int, sequence_length: int + ) -> [Memory, Optional[MemorySummary]]: + pass + + @abstractmethod + def _train_memory( + self, model_name: str, batch_size: int, sequence_length: int + ) -> [Memory, Optional[MemorySummary]]: + pass + + def inference_speed(self, *args, **kwargs) -> float: + return separate_process_wrapper_fn(self._inference_speed, self.args.do_multi_processing)(*args, **kwargs) + + def train_speed(self, *args, **kwargs) -> float: + return separate_process_wrapper_fn(self._train_speed, self.args.do_multi_processing)(*args, **kwargs) + + def inference_memory(self, *args, **kwargs) -> [Memory, Optional[MemorySummary]]: + return separate_process_wrapper_fn(self._inference_memory, self.args.do_multi_processing)(*args, **kwargs) + + def train_memory(self, *args, **kwargs) -> [Memory, Optional[MemorySummary]]: + return separate_process_wrapper_fn(self._train_memory, self.args.do_multi_processing)(*args, **kwargs) + + def run(self): + result_dict = {model_name: {} for model_name in self.args.model_names} + inference_result_time = copy.deepcopy(result_dict) + inference_result_memory = copy.deepcopy(result_dict) + train_result_time = copy.deepcopy(result_dict) + train_result_memory = copy.deepcopy(result_dict) + + for c, model_name in enumerate(self.args.model_names): + self.print_fn(f"{c + 1} / {len(self.args.model_names)}") + + model_dict = { + "bs": self.args.batch_sizes, + "ss": self.args.sequence_lengths, + "result": {i: {} for i in self.args.batch_sizes}, + } + inference_result_time[model_name] = copy.deepcopy(model_dict) + inference_result_memory[model_name] = copy.deepcopy(model_dict) + train_result_time[model_name] = copy.deepcopy(model_dict) + train_result_memory[model_name] = copy.deepcopy(model_dict) + + inference_summary = train_summary = None + + for batch_size in self.args.batch_sizes: + for sequence_length in self.args.sequence_lengths: + if self.args.inference: + if self.args.memory: + memory, inference_summary = self.inference_memory(model_name, batch_size, sequence_length) + inference_result_memory[model_name]["result"][batch_size][sequence_length] = memory + if self.args.speed: + time = self.inference_speed(model_name, batch_size, sequence_length) + inference_result_time[model_name]["result"][batch_size][sequence_length] = time + + if self.args.training: + if self.args.memory: + memory, train_summary = self.train_memory(model_name, batch_size, sequence_length) + train_result_memory[model_name]["result"][batch_size][sequence_length] = memory + if self.args.speed: + time = self.train_speed(model_name, batch_size, sequence_length) + train_result_time[model_name]["result"][batch_size][sequence_length] = time + + if self.args.inference: + if self.args.speed: + self.print_fn("\n" + 20 * "=" + ("INFERENCE - SPEED - RESULT").center(40) + 20 * "=") + self.print_results(inference_result_time, type_label="Time in s") + self.save_to_csv(inference_result_time, self.args.inference_time_csv_file) + if self.args.is_tpu: + self.print_fn( + "TPU was used for inference. Note that the time after compilation stabilized (after ~10" + " inferences model.forward(..) calls) was measured." + ) + + if self.args.memory: + self.print_fn("\n" + 20 * "=" + ("INFERENCE - MEMORY - RESULT").center(40) + 20 * "=") + self.print_results(inference_result_memory, type_label="Memory in MB") + self.save_to_csv(inference_result_memory, self.args.inference_memory_csv_file) + + if self.args.trace_memory_line_by_line: + self.print_fn("\n" + 20 * "=" + ("INFERENCE - MEMOMRY - LINE BY LINE - SUMMARY").center(40) + 20 * "=") + self.print_memory_trace_statistics(inference_summary) + + if self.args.training: + if self.args.speed: + self.print_fn("\n" + 20 * "=" + ("TRAIN - SPEED - RESULTS").center(40) + 20 * "=") + self.print_results(train_result_time, "Time in s") + self.save_to_csv(train_result_time, self.args.train_time_csv_file) + if self.args.is_tpu: + self.print_fn( + "TPU was used for training. Note that the time after compilation stabilized (after ~10 train" + " loss=model.forward(...) + loss.backward() calls) was measured." + ) + + if self.args.memory: + self.print_fn("\n" + 20 * "=" + ("TRAIN - MEMORY - RESULTS").center(40) + 20 * "=") + self.print_results(train_result_memory, type_label="Memory in MB") + self.save_to_csv(train_result_memory, self.args.train_memory_csv_file) + + if self.args.trace_memory_line_by_line: + self.print_fn("\n" + 20 * "=" + ("TRAIN - MEMOMRY - LINE BY LINE - SUMMARY").center(40) + 20 * "=") + self.print_memory_trace_statistics(train_summary) + + if self.args.env_print: + self.print_fn("\n" + 20 * "=" + ("ENVIRONMENT INFORMATION").center(40) + 20 * "=") + self.print_fn("\n".join([f"- {prop}: {val}" for prop, val in self.environment_info.items()]) + "\n") + + if self.args.save_to_csv: + with open(self.args.env_info_csv_file, mode="w", newline="") as csv_file: + writer = csv.writer(csv_file) + for key, value in self.environment_info.items(): + writer.writerow([key, value]) + + return BenchmarkOutput( + inference_result_time, + inference_result_memory, + train_result_time, + train_result_memory, + inference_summary, + train_summary, + ) + + @property + def environment_info(self): + if self._environment_info is None: + info = {} + info["transformers_version"] = version + info["framework"] = self.framework + if self.framework == "PyTorch": + info["use_torchscript"] = self.args.torchscript + if self.framework == "TensorFlow": + info["eager_mode"] = self.args.eager_mode + info["use_xla"] = self.args.use_xla + info["framework_version"] = self.framework_version + info["python_version"] = platform.python_version() + info["system"] = platform.system() + info["cpu"] = platform.processor() + info["architecture"] = platform.architecture()[0] + info["date"] = datetime.date(datetime.now()) + info["time"] = datetime.time(datetime.now()) + info["fp16"] = self.args.fp16 + info["use_multiprocessing"] = self.args.do_multi_processing + info["only_pretrain_model"] = self.args.only_pretrain_model + + if is_psutil_available(): + info["cpu_ram_mb"] = bytes_to_mega_bytes(psutil.virtual_memory().total) + else: + logger.warning( + "Psutil not installed, we won't log available CPU memory. " + "Install psutil (pip install psutil) to log available CPU memory." + ) + info["cpu_ram_mb"] = "N/A" + + info["use_gpu"] = self.args.is_gpu + if self.args.is_gpu: + info["num_gpus"] = 1 # TODO(PVP) Currently only single GPU is supported + if is_py3nvml_available(): + nvml.nvmlInit() + handle = nvml.nvmlDeviceGetHandleByIndex(self.args.device_idx) + info["gpu"] = nvml.nvmlDeviceGetName(handle) + info["gpu_ram_mb"] = bytes_to_mega_bytes(nvml.nvmlDeviceGetMemoryInfo(handle).total) + info["gpu_power_watts"] = nvml.nvmlDeviceGetPowerManagementLimit(handle) / 1000 + info["gpu_performance_state"] = nvml.nvmlDeviceGetPerformanceState(handle) + nvml.nvmlShutdown() + else: + logger.warning( + "py3nvml not installed, we won't log GPU memory usage. " + "Install py3nvml (pip install py3nvml) to log information about GPU." + ) + info["gpu"] = "N/A" + info["gpu_ram_mb"] = "N/A" + info["gpu_power_watts"] = "N/A" + info["gpu_performance_state"] = "N/A" + + info["use_tpu"] = self.args.is_tpu + # TODO(PVP): See if we can add more information about TPU + # see: https://github.com/pytorch/xla/issues/2180 + + self._environment_info = info + return self._environment_info + + def print_results(self, result_dict, type_label): + self.print_fn(80 * "-") + self.print_fn( + "Model Name".center(30) + "Batch Size".center(15) + "Seq Length".center(15) + type_label.center(15) + ) + self.print_fn(80 * "-") + for model_name in self.args.model_names: + for batch_size in result_dict[model_name]["bs"]: + for sequence_length in result_dict[model_name]["ss"]: + result = result_dict[model_name]["result"][batch_size][sequence_length] + if isinstance(result, float): + result = round(1000 * result) / 1000 + result = "< 0.001" if result == 0.0 else str(result) + else: + result = str(result) + self.print_fn( + model_name[:30].center(30) + str(batch_size).center(15), + str(sequence_length).center(15), + result.center(15), + ) + self.print_fn(80 * "-") + + def print_memory_trace_statistics(self, summary: MemorySummary): + self.print_fn( + "\nLine by line memory consumption:\n" + + "\n".join( + f"{state.frame.filename}:{state.frame.line_number}: mem {state.cpu_gpu}: {state.frame.line_text}" + for state in summary.sequential + ) + ) + self.print_fn( + "\nLines with top memory consumption:\n" + + "\n".join( + f"=> {state.frame.filename}:{state.frame.line_number}: mem {state.cpu_gpu}: {state.frame.line_text}" + for state in summary.cumulative[:6] + ) + ) + self.print_fn( + "\nLines with lowest memory consumption:\n" + + "\n".join( + f"=> {state.frame.filename}:{state.frame.line_number}: mem {state.cpu_gpu}: {state.frame.line_text}" + for state in summary.cumulative[-6:] + ) + ) + self.print_fn(f"\nTotal memory increase: {summary.total}") + + def save_to_csv(self, result_dict, filename): + if not self.args.save_to_csv: + return + self.print_fn("Saving results to csv.") + with open(filename, mode="w") as csv_file: + assert len(self.args.model_names) > 0, f"At least 1 model should be defined, but got {self.model_names}" + + fieldnames = ["model", "batch_size", "sequence_length"] + writer = csv.DictWriter(csv_file, fieldnames=fieldnames + ["result"]) + writer.writeheader() + + for model_name in self.args.model_names: + result_dict_model = result_dict[model_name]["result"] + for bs in result_dict_model: + for ss in result_dict_model[bs]: + result_model = result_dict_model[bs][ss] + writer.writerow( + { + "model": model_name, + "batch_size": bs, + "sequence_length": ss, + "result": ("{}" if not isinstance(result_model, float) else "{:.4f}").format( + result_model + ), + } + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model.py new file mode 100644 index 0000000000000000000000000000000000000000..85d053a14873a372136f8de007f3039ed3367e97 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model.py @@ -0,0 +1,259 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import warnings +from argparse import ArgumentParser, Namespace +from pathlib import Path +from typing import List + +from ..utils import logging +from . import BaseTransformersCLICommand + + +try: + from cookiecutter.main import cookiecutter + + _has_cookiecutter = True +except ImportError: + _has_cookiecutter = False + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +def add_new_model_command_factory(args: Namespace): + return AddNewModelCommand(args.testing, args.testing_file, path=args.path) + + +class AddNewModelCommand(BaseTransformersCLICommand): + @staticmethod + def register_subcommand(parser: ArgumentParser): + add_new_model_parser = parser.add_parser("add-new-model") + add_new_model_parser.add_argument("--testing", action="store_true", help="If in testing mode.") + add_new_model_parser.add_argument("--testing_file", type=str, help="Configuration file on which to run.") + add_new_model_parser.add_argument( + "--path", type=str, help="Path to cookiecutter. Should only be used for testing purposes." + ) + add_new_model_parser.set_defaults(func=add_new_model_command_factory) + + def __init__(self, testing: bool, testing_file: str, path=None, *args): + self._testing = testing + self._testing_file = testing_file + self._path = path + + def run(self): + warnings.warn( + "The command `transformers-cli add-new-model` is deprecated and will be removed in v5 of Transformers. " + "It is not actively maintained anymore, so might give a result that won't pass all tests and quality " + "checks, you should use `transformers-cli add-new-model-like` instead." + ) + if not _has_cookiecutter: + raise ImportError( + "Model creation dependencies are required to use the `add_new_model` command. Install them by running " + "the following at the root of your `transformers` clone:\n\n\t$ pip install -e .[modelcreation]\n" + ) + # Ensure that there is no other `cookiecutter-template-xxx` directory in the current working directory + directories = [directory for directory in os.listdir() if "cookiecutter-template-" == directory[:22]] + if len(directories) > 0: + raise ValueError( + "Several directories starting with `cookiecutter-template-` in current working directory. " + "Please clean your directory by removing all folders starting with `cookiecutter-template-` or " + "change your working directory." + ) + + path_to_transformer_root = ( + Path(__file__).parent.parent.parent.parent if self._path is None else Path(self._path).parent.parent + ) + path_to_cookiecutter = path_to_transformer_root / "templates" / "adding_a_new_model" + + # Execute cookiecutter + if not self._testing: + cookiecutter(str(path_to_cookiecutter)) + else: + with open(self._testing_file, "r") as configuration_file: + testing_configuration = json.load(configuration_file) + + cookiecutter( + str(path_to_cookiecutter if self._path is None else self._path), + no_input=True, + extra_context=testing_configuration, + ) + + directory = [directory for directory in os.listdir() if "cookiecutter-template-" in directory[:22]][0] + + # Retrieve configuration + with open(directory + "/configuration.json", "r") as configuration_file: + configuration = json.load(configuration_file) + + lowercase_model_name = configuration["lowercase_modelname"] + generate_tensorflow_pytorch_and_flax = configuration["generate_tensorflow_pytorch_and_flax"] + os.remove(f"{directory}/configuration.json") + + output_pytorch = "PyTorch" in generate_tensorflow_pytorch_and_flax + output_tensorflow = "TensorFlow" in generate_tensorflow_pytorch_and_flax + output_flax = "Flax" in generate_tensorflow_pytorch_and_flax + + model_dir = f"{path_to_transformer_root}/src/transformers/models/{lowercase_model_name}" + os.makedirs(model_dir, exist_ok=True) + os.makedirs(f"{path_to_transformer_root}/tests/models/{lowercase_model_name}", exist_ok=True) + + # Tests require submodules as they have parent imports + with open(f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/__init__.py", "w"): + pass + + shutil.move( + f"{directory}/__init__.py", + f"{model_dir}/__init__.py", + ) + shutil.move( + f"{directory}/configuration_{lowercase_model_name}.py", + f"{model_dir}/configuration_{lowercase_model_name}.py", + ) + + def remove_copy_lines(path): + with open(path, "r") as f: + lines = f.readlines() + with open(path, "w") as f: + for line in lines: + if "# Copied from transformers." not in line: + f.write(line) + + if output_pytorch: + if not self._testing: + remove_copy_lines(f"{directory}/modeling_{lowercase_model_name}.py") + + shutil.move( + f"{directory}/modeling_{lowercase_model_name}.py", + f"{model_dir}/modeling_{lowercase_model_name}.py", + ) + + shutil.move( + f"{directory}/test_modeling_{lowercase_model_name}.py", + f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_{lowercase_model_name}.py", + ) + else: + os.remove(f"{directory}/modeling_{lowercase_model_name}.py") + os.remove(f"{directory}/test_modeling_{lowercase_model_name}.py") + + if output_tensorflow: + if not self._testing: + remove_copy_lines(f"{directory}/modeling_tf_{lowercase_model_name}.py") + + shutil.move( + f"{directory}/modeling_tf_{lowercase_model_name}.py", + f"{model_dir}/modeling_tf_{lowercase_model_name}.py", + ) + + shutil.move( + f"{directory}/test_modeling_tf_{lowercase_model_name}.py", + f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_tf_{lowercase_model_name}.py", + ) + else: + os.remove(f"{directory}/modeling_tf_{lowercase_model_name}.py") + os.remove(f"{directory}/test_modeling_tf_{lowercase_model_name}.py") + + if output_flax: + if not self._testing: + remove_copy_lines(f"{directory}/modeling_flax_{lowercase_model_name}.py") + + shutil.move( + f"{directory}/modeling_flax_{lowercase_model_name}.py", + f"{model_dir}/modeling_flax_{lowercase_model_name}.py", + ) + + shutil.move( + f"{directory}/test_modeling_flax_{lowercase_model_name}.py", + f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_flax_{lowercase_model_name}.py", + ) + else: + os.remove(f"{directory}/modeling_flax_{lowercase_model_name}.py") + os.remove(f"{directory}/test_modeling_flax_{lowercase_model_name}.py") + + shutil.move( + f"{directory}/{lowercase_model_name}.mdx", + f"{path_to_transformer_root}/docs/source/en/model_doc/{lowercase_model_name}.mdx", + ) + + shutil.move( + f"{directory}/tokenization_{lowercase_model_name}.py", + f"{model_dir}/tokenization_{lowercase_model_name}.py", + ) + + shutil.move( + f"{directory}/tokenization_fast_{lowercase_model_name}.py", + f"{model_dir}/tokenization_{lowercase_model_name}_fast.py", + ) + + from os import fdopen, remove + from shutil import copymode, move + from tempfile import mkstemp + + def replace(original_file: str, line_to_copy_below: str, lines_to_copy: List[str]): + # Create temp file + fh, abs_path = mkstemp() + line_found = False + with fdopen(fh, "w") as new_file: + with open(original_file) as old_file: + for line in old_file: + new_file.write(line) + if line_to_copy_below in line: + line_found = True + for line_to_copy in lines_to_copy: + new_file.write(line_to_copy) + + if not line_found: + raise ValueError(f"Line {line_to_copy_below} was not found in file.") + + # Copy the file permissions from the old file to the new file + copymode(original_file, abs_path) + # Remove original file + remove(original_file) + # Move new file + move(abs_path, original_file) + + def skip_units(line): + return ( + ("generating PyTorch" in line and not output_pytorch) + or ("generating TensorFlow" in line and not output_tensorflow) + or ("generating Flax" in line and not output_flax) + ) + + def replace_in_files(path_to_datafile): + with open(path_to_datafile) as datafile: + lines_to_copy = [] + skip_file = False + skip_snippet = False + for line in datafile: + if "# To replace in: " in line and "##" not in line: + file_to_replace_in = line.split('"')[1] + skip_file = skip_units(line) + elif "# Below: " in line and "##" not in line: + line_to_copy_below = line.split('"')[1] + skip_snippet = skip_units(line) + elif "# End." in line and "##" not in line: + if not skip_file and not skip_snippet: + replace(file_to_replace_in, line_to_copy_below, lines_to_copy) + + lines_to_copy = [] + elif "# Replace with" in line and "##" not in line: + lines_to_copy = [] + elif "##" not in line: + lines_to_copy.append(line) + + remove(path_to_datafile) + + replace_in_files(f"{directory}/to_replace_{lowercase_model_name}.py") + os.rmdir(directory) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model_like.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model_like.py new file mode 100644 index 0000000000000000000000000000000000000000..91ce8a143c5935e4be9bf48769e6de0f5fd50199 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/commands/add_new_model_like.py @@ -0,0 +1,1710 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import difflib +import json +import os +import re +from argparse import ArgumentParser, Namespace +from dataclasses import dataclass +from datetime import date +from itertools import chain +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Pattern, Tuple, Union + +from ..models import auto as auto_module +from ..models.auto.configuration_auto import model_type_to_module_name +from ..utils import is_flax_available, is_tf_available, is_torch_available, logging +from . import BaseTransformersCLICommand + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +CURRENT_YEAR = date.today().year +TRANSFORMERS_PATH = Path(__file__).parent.parent +REPO_PATH = TRANSFORMERS_PATH.parent.parent + + +@dataclass +class ModelPatterns: + """ + Holds the basic information about a new model for the add-new-model-like command. + + Args: + model_name (`str`): The model name. + checkpoint (`str`): The checkpoint to use for doc examples. + model_type (`str`, *optional*): + The model type, the identifier used internally in the library like `bert` or `xlm-roberta`. Will default to + `model_name` lowercased with spaces replaced with minuses (-). + model_lower_cased (`str`, *optional*): + The lowercased version of the model name, to use for the module name or function names. Will default to + `model_name` lowercased with spaces and minuses replaced with underscores. + model_camel_cased (`str`, *optional*): + The camel-cased version of the model name, to use for the class names. Will default to `model_name` + camel-cased (with spaces and minuses both considered as word separators. + model_upper_cased (`str`, *optional*): + The uppercased version of the model name, to use for the constant names. Will default to `model_name` + uppercased with spaces and minuses replaced with underscores. + config_class (`str`, *optional*): + The tokenizer class associated with this model. Will default to `"{model_camel_cased}Config"`. + tokenizer_class (`str`, *optional*): + The tokenizer class associated with this model (leave to `None` for models that don't use a tokenizer). + image_processor_class (`str`, *optional*): + The image processor class associated with this model (leave to `None` for models that don't use an image + processor). + feature_extractor_class (`str`, *optional*): + The feature extractor class associated with this model (leave to `None` for models that don't use a feature + extractor). + processor_class (`str`, *optional*): + The processor class associated with this model (leave to `None` for models that don't use a processor). + """ + + model_name: str + checkpoint: str + model_type: Optional[str] = None + model_lower_cased: Optional[str] = None + model_camel_cased: Optional[str] = None + model_upper_cased: Optional[str] = None + config_class: Optional[str] = None + tokenizer_class: Optional[str] = None + image_processor_class: Optional[str] = None + feature_extractor_class: Optional[str] = None + processor_class: Optional[str] = None + + def __post_init__(self): + if self.model_type is None: + self.model_type = self.model_name.lower().replace(" ", "-") + if self.model_lower_cased is None: + self.model_lower_cased = self.model_name.lower().replace(" ", "_").replace("-", "_") + if self.model_camel_cased is None: + # Split the model name on - and space + words = self.model_name.split(" ") + words = list(chain(*[w.split("-") for w in words])) + # Make sure each word is capitalized + words = [w[0].upper() + w[1:] for w in words] + self.model_camel_cased = "".join(words) + if self.model_upper_cased is None: + self.model_upper_cased = self.model_name.upper().replace(" ", "_").replace("-", "_") + if self.config_class is None: + self.config_class = f"{self.model_camel_cased}Config" + + +ATTRIBUTE_TO_PLACEHOLDER = { + "config_class": "[CONFIG_CLASS]", + "tokenizer_class": "[TOKENIZER_CLASS]", + "image_processor_class": "[IMAGE_PROCESSOR_CLASS]", + "feature_extractor_class": "[FEATURE_EXTRACTOR_CLASS]", + "processor_class": "[PROCESSOR_CLASS]", + "checkpoint": "[CHECKPOINT]", + "model_type": "[MODEL_TYPE]", + "model_upper_cased": "[MODEL_UPPER_CASED]", + "model_camel_cased": "[MODEL_CAMELCASED]", + "model_lower_cased": "[MODEL_LOWER_CASED]", + "model_name": "[MODEL_NAME]", +} + + +def is_empty_line(line: str) -> bool: + """ + Determines whether a line is empty or not. + """ + return len(line) == 0 or line.isspace() + + +def find_indent(line: str) -> int: + """ + Returns the number of spaces that start a line indent. + """ + search = re.search(r"^(\s*)(?:\S|$)", line) + if search is None: + return 0 + return len(search.groups()[0]) + + +def parse_module_content(content: str) -> List[str]: + """ + Parse the content of a module in the list of objects it defines. + + Args: + content (`str`): The content to parse + + Returns: + `List[str]`: The list of objects defined in the module. + """ + objects = [] + current_object = [] + lines = content.split("\n") + # Doc-styler takes everything between two triple quotes in docstrings, so we need a fake """ here to go with this. + end_markers = [")", "]", "}", '"""'] + + for line in lines: + # End of an object + is_valid_object = len(current_object) > 0 + if is_valid_object and len(current_object) == 1: + is_valid_object = not current_object[0].startswith("# Copied from") + if not is_empty_line(line) and find_indent(line) == 0 and is_valid_object: + # Closing parts should be included in current object + if line in end_markers: + current_object.append(line) + objects.append("\n".join(current_object)) + current_object = [] + else: + objects.append("\n".join(current_object)) + current_object = [line] + else: + current_object.append(line) + + # Add last object + if len(current_object) > 0: + objects.append("\n".join(current_object)) + + return objects + + +def extract_block(content: str, indent_level: int = 0) -> str: + """Return the first block in `content` with the indent level `indent_level`. + + The first line in `content` should be indented at `indent_level` level, otherwise an error will be thrown. + + This method will immediately stop the search when a (non-empty) line with indent level less than `indent_level` is + encountered. + + Args: + content (`str`): The content to parse + indent_level (`int`, *optional*, default to 0): The indent level of the blocks to search for + + Returns: + `str`: The first block in `content` with the indent level `indent_level`. + """ + current_object = [] + lines = content.split("\n") + # Doc-styler takes everything between two triple quotes in docstrings, so we need a fake """ here to go with this. + end_markers = [")", "]", "}", '"""'] + + for idx, line in enumerate(lines): + if idx == 0 and indent_level > 0 and not is_empty_line(line) and find_indent(line) != indent_level: + raise ValueError( + f"When `indent_level > 0`, the first line in `content` should have indent level {indent_level}. Got " + f"{find_indent(line)} instead." + ) + + if find_indent(line) < indent_level and not is_empty_line(line): + break + + # End of an object + is_valid_object = len(current_object) > 0 + if ( + not is_empty_line(line) + and not line.endswith(":") + and find_indent(line) == indent_level + and is_valid_object + ): + # Closing parts should be included in current object + if line.lstrip() in end_markers: + current_object.append(line) + return "\n".join(current_object) + else: + current_object.append(line) + + # Add last object + if len(current_object) > 0: + return "\n".join(current_object) + + +def add_content_to_text( + text: str, + content: str, + add_after: Optional[Union[str, Pattern]] = None, + add_before: Optional[Union[str, Pattern]] = None, + exact_match: bool = False, +) -> str: + """ + A utility to add some content inside a given text. + + Args: + text (`str`): The text in which we want to insert some content. + content (`str`): The content to add. + add_after (`str` or `Pattern`): + The pattern to test on a line of `text`, the new content is added after the first instance matching it. + add_before (`str` or `Pattern`): + The pattern to test on a line of `text`, the new content is added before the first instance matching it. + exact_match (`bool`, *optional*, defaults to `False`): + A line is considered a match with `add_after` or `add_before` if it matches exactly when `exact_match=True`, + otherwise, if `add_after`/`add_before` is present in the line. + + + + The arguments `add_after` and `add_before` are mutually exclusive, and one exactly needs to be provided. + + + + Returns: + `str`: The text with the new content added if a match was found. + """ + if add_after is None and add_before is None: + raise ValueError("You need to pass either `add_after` or `add_before`") + if add_after is not None and add_before is not None: + raise ValueError("You can't pass both `add_after` or `add_before`") + pattern = add_after if add_before is None else add_before + + def this_is_the_line(line): + if isinstance(pattern, Pattern): + return pattern.search(line) is not None + elif exact_match: + return pattern == line + else: + return pattern in line + + new_lines = [] + for line in text.split("\n"): + if this_is_the_line(line): + if add_before is not None: + new_lines.append(content) + new_lines.append(line) + if add_after is not None: + new_lines.append(content) + else: + new_lines.append(line) + + return "\n".join(new_lines) + + +def add_content_to_file( + file_name: Union[str, os.PathLike], + content: str, + add_after: Optional[Union[str, Pattern]] = None, + add_before: Optional[Union[str, Pattern]] = None, + exact_match: bool = False, +): + """ + A utility to add some content inside a given file. + + Args: + file_name (`str` or `os.PathLike`): The name of the file in which we want to insert some content. + content (`str`): The content to add. + add_after (`str` or `Pattern`): + The pattern to test on a line of `text`, the new content is added after the first instance matching it. + add_before (`str` or `Pattern`): + The pattern to test on a line of `text`, the new content is added before the first instance matching it. + exact_match (`bool`, *optional*, defaults to `False`): + A line is considered a match with `add_after` or `add_before` if it matches exactly when `exact_match=True`, + otherwise, if `add_after`/`add_before` is present in the line. + + + + The arguments `add_after` and `add_before` are mutually exclusive, and one exactly needs to be provided. + + + """ + with open(file_name, "r", encoding="utf-8") as f: + old_content = f.read() + + new_content = add_content_to_text( + old_content, content, add_after=add_after, add_before=add_before, exact_match=exact_match + ) + + with open(file_name, "w", encoding="utf-8") as f: + f.write(new_content) + + +def replace_model_patterns( + text: str, old_model_patterns: ModelPatterns, new_model_patterns: ModelPatterns +) -> Tuple[str, str]: + """ + Replace all patterns present in a given text. + + Args: + text (`str`): The text to treat. + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + + Returns: + `Tuple(str, str)`: A tuple of with the treated text and the replacement actually done in it. + """ + # The order is crucially important as we will check and replace in that order. For instance the config probably + # contains the camel-cased named, but will be treated before. + attributes_to_check = ["config_class"] + # Add relevant preprocessing classes + for attr in ["tokenizer_class", "image_processor_class", "feature_extractor_class", "processor_class"]: + if getattr(old_model_patterns, attr) is not None and getattr(new_model_patterns, attr) is not None: + attributes_to_check.append(attr) + + # Special cases for checkpoint and model_type + if old_model_patterns.checkpoint not in [old_model_patterns.model_type, old_model_patterns.model_lower_cased]: + attributes_to_check.append("checkpoint") + if old_model_patterns.model_type != old_model_patterns.model_lower_cased: + attributes_to_check.append("model_type") + else: + text = re.sub( + rf'(\s*)model_type = "{old_model_patterns.model_type}"', + r'\1model_type = "[MODEL_TYPE]"', + text, + ) + + # Special case when the model camel cased and upper cased names are the same for the old model (like for GPT2) but + # not the new one. We can't just do a replace in all the text and will need a special regex + if old_model_patterns.model_upper_cased == old_model_patterns.model_camel_cased: + old_model_value = old_model_patterns.model_upper_cased + if re.search(rf"{old_model_value}_[A-Z_]*[^A-Z_]", text) is not None: + text = re.sub(rf"{old_model_value}([A-Z_]*)([^a-zA-Z_])", r"[MODEL_UPPER_CASED]\1\2", text) + else: + attributes_to_check.append("model_upper_cased") + + attributes_to_check.extend(["model_camel_cased", "model_lower_cased", "model_name"]) + + # Now let's replace every other attribute by their placeholder + for attr in attributes_to_check: + text = text.replace(getattr(old_model_patterns, attr), ATTRIBUTE_TO_PLACEHOLDER[attr]) + + # Finally we can replace the placeholder byt the new values. + replacements = [] + for attr, placeholder in ATTRIBUTE_TO_PLACEHOLDER.items(): + if placeholder in text: + replacements.append((getattr(old_model_patterns, attr), getattr(new_model_patterns, attr))) + text = text.replace(placeholder, getattr(new_model_patterns, attr)) + + # If we have two inconsistent replacements, we don't return anything (ex: GPT2->GPT_NEW and GPT2->GPTNew) + old_replacement_values = [old for old, new in replacements] + if len(set(old_replacement_values)) != len(old_replacement_values): + return text, "" + + replacements = simplify_replacements(replacements) + replacements = [f"{old}->{new}" for old, new in replacements] + return text, ",".join(replacements) + + +def simplify_replacements(replacements): + """ + Simplify a list of replacement patterns to make sure there are no needless ones. + + For instance in the sequence "Bert->BertNew, BertConfig->BertNewConfig, bert->bert_new", the replacement + "BertConfig->BertNewConfig" is implied by "Bert->BertNew" so not needed. + + Args: + replacements (`List[Tuple[str, str]]`): List of patterns (old, new) + + Returns: + `List[Tuple[str, str]]`: The list of patterns simplified. + """ + if len(replacements) <= 1: + # Nothing to simplify + return replacements + + # Next let's sort replacements by length as a replacement can only "imply" another replacement if it's shorter. + replacements.sort(key=lambda x: len(x[0])) + + idx = 0 + while idx < len(replacements): + old, new = replacements[idx] + # Loop through all replacements after + j = idx + 1 + while j < len(replacements): + old_2, new_2 = replacements[j] + # If the replacement is implied by the current one, we can drop it. + if old_2.replace(old, new) == new_2: + replacements.pop(j) + else: + j += 1 + idx += 1 + + return replacements + + +def get_module_from_file(module_file: Union[str, os.PathLike]) -> str: + """ + Returns the module name corresponding to a module file. + """ + full_module_path = Path(module_file).absolute() + module_parts = full_module_path.with_suffix("").parts + + # Find the first part named transformers, starting from the end. + idx = len(module_parts) - 1 + while idx >= 0 and module_parts[idx] != "transformers": + idx -= 1 + if idx < 0: + raise ValueError(f"{module_file} is not a transformers module.") + + return ".".join(module_parts[idx:]) + + +SPECIAL_PATTERNS = { + "_CHECKPOINT_FOR_DOC =": "checkpoint", + "_CONFIG_FOR_DOC =": "config_class", + "_TOKENIZER_FOR_DOC =": "tokenizer_class", + "_IMAGE_PROCESSOR_FOR_DOC =": "image_processor_class", + "_FEAT_EXTRACTOR_FOR_DOC =": "feature_extractor_class", + "_PROCESSOR_FOR_DOC =": "processor_class", +} + + +_re_class_func = re.compile(r"^(?:class|def)\s+([^\s:\(]+)\s*(?:\(|\:)", flags=re.MULTILINE) + + +def remove_attributes(obj, target_attr): + """Remove `target_attr` in `obj`.""" + lines = obj.split(os.linesep) + + target_idx = None + for idx, line in enumerate(lines): + # search for assignment + if line.lstrip().startswith(f"{target_attr} = "): + target_idx = idx + break + # search for function/method definition + elif line.lstrip().startswith(f"def {target_attr}("): + target_idx = idx + break + + # target not found + if target_idx is None: + return obj + + line = lines[target_idx] + indent_level = find_indent(line) + # forward pass to find the ending of the block (including empty lines) + parsed = extract_block("\n".join(lines[target_idx:]), indent_level) + num_lines = len(parsed.split("\n")) + for idx in range(num_lines): + lines[target_idx + idx] = None + + # backward pass to find comments or decorator + for idx in range(target_idx - 1, -1, -1): + line = lines[idx] + if (line.lstrip().startswith("#") or line.lstrip().startswith("@")) and find_indent(line) == indent_level: + lines[idx] = None + else: + break + + new_obj = os.linesep.join([x for x in lines if x is not None]) + + return new_obj + + +def duplicate_module( + module_file: Union[str, os.PathLike], + old_model_patterns: ModelPatterns, + new_model_patterns: ModelPatterns, + dest_file: Optional[str] = None, + add_copied_from: bool = True, + attrs_to_remove: List[str] = None, +): + """ + Create a new module from an existing one and adapting all function and classes names from old patterns to new ones. + + Args: + module_file (`str` or `os.PathLike`): Path to the module to duplicate. + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + dest_file (`str` or `os.PathLike`, *optional*): Path to the new module. + add_copied_from (`bool`, *optional*, defaults to `True`): + Whether or not to add `# Copied from` statements in the duplicated module. + """ + if dest_file is None: + dest_file = str(module_file).replace( + old_model_patterns.model_lower_cased, new_model_patterns.model_lower_cased + ) + + with open(module_file, "r", encoding="utf-8") as f: + content = f.read() + + content = re.sub(r"# Copyright (\d+)\s", f"# Copyright {CURRENT_YEAR} ", content) + objects = parse_module_content(content) + + # Loop and treat all objects + new_objects = [] + for obj in objects: + # Special cases + if "PRETRAINED_CONFIG_ARCHIVE_MAP = {" in obj: + # docstyle-ignore + obj = ( + f"{new_model_patterns.model_upper_cased}_PRETRAINED_CONFIG_ARCHIVE_MAP = " + + "{" + + f""" + "{new_model_patterns.checkpoint}": "https://huggingface.co/{new_model_patterns.checkpoint}/resolve/main/config.json", +""" + + "}\n" + ) + new_objects.append(obj) + continue + elif "PRETRAINED_MODEL_ARCHIVE_LIST = [" in obj: + if obj.startswith("TF_"): + prefix = "TF_" + elif obj.startswith("FLAX_"): + prefix = "FLAX_" + else: + prefix = "" + # docstyle-ignore + obj = f"""{prefix}{new_model_patterns.model_upper_cased}_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "{new_model_patterns.checkpoint}", + # See all {new_model_patterns.model_name} models at https://huggingface.co/models?filter={new_model_patterns.model_type} +] +""" + new_objects.append(obj) + continue + + special_pattern = False + for pattern, attr in SPECIAL_PATTERNS.items(): + if pattern in obj: + obj = obj.replace(getattr(old_model_patterns, attr), getattr(new_model_patterns, attr)) + new_objects.append(obj) + special_pattern = True + break + + if special_pattern: + continue + + # Regular classes functions + old_obj = obj + obj, replacement = replace_model_patterns(obj, old_model_patterns, new_model_patterns) + has_copied_from = re.search(r"^#\s+Copied from", obj, flags=re.MULTILINE) is not None + if add_copied_from and not has_copied_from and _re_class_func.search(obj) is not None and len(replacement) > 0: + # Copied from statement must be added just before the class/function definition, which may not be the + # first line because of decorators. + module_name = get_module_from_file(module_file) + old_object_name = _re_class_func.search(old_obj).groups()[0] + obj = add_content_to_text( + obj, f"# Copied from {module_name}.{old_object_name} with {replacement}", add_before=_re_class_func + ) + # In all cases, we remove Copied from statement with indent on methods. + obj = re.sub("\n[ ]+# Copied from [^\n]*\n", "\n", obj) + + new_objects.append(obj) + + content = "\n".join(new_objects) + # Remove some attributes that we don't want to copy to the new file(s) + if attrs_to_remove is not None: + for attr in attrs_to_remove: + content = remove_attributes(content, target_attr=attr) + + with open(dest_file, "w", encoding="utf-8") as f: + f.write(content) + + +def filter_framework_files( + files: List[Union[str, os.PathLike]], frameworks: Optional[List[str]] = None +) -> List[Union[str, os.PathLike]]: + """ + Filter a list of files to only keep the ones corresponding to a list of frameworks. + + Args: + files (`List[Union[str, os.PathLike]]`): The list of files to filter. + frameworks (`List[str]`, *optional*): The list of allowed frameworks. + + Returns: + `List[Union[str, os.PathLike]]`: The list of filtered files. + """ + if frameworks is None: + frameworks = get_default_frameworks() + + framework_to_file = {} + others = [] + for f in files: + parts = Path(f).name.split("_") + if "modeling" not in parts: + others.append(f) + continue + if "tf" in parts: + framework_to_file["tf"] = f + elif "flax" in parts: + framework_to_file["flax"] = f + else: + framework_to_file["pt"] = f + + return [framework_to_file[f] for f in frameworks if f in framework_to_file] + others + + +def get_model_files(model_type: str, frameworks: Optional[List[str]] = None) -> Dict[str, Union[Path, List[Path]]]: + """ + Retrieves all the files associated to a model. + + Args: + model_type (`str`): A valid model type (like "bert" or "gpt2") + frameworks (`List[str]`, *optional*): + If passed, will only keep the model files corresponding to the passed frameworks. + + Returns: + `Dict[str, Union[Path, List[Path]]]`: A dictionary with the following keys: + - **doc_file** -- The documentation file for the model. + - **model_files** -- All the files in the model module. + - **test_files** -- The test files for the model. + """ + module_name = model_type_to_module_name(model_type) + + model_module = TRANSFORMERS_PATH / "models" / module_name + model_files = list(model_module.glob("*.py")) + model_files = filter_framework_files(model_files, frameworks=frameworks) + + doc_file = REPO_PATH / "docs" / "source" / "en" / "model_doc" / f"{model_type}.mdx" + + # Basic pattern for test files + test_files = [ + f"test_modeling_{module_name}.py", + f"test_modeling_tf_{module_name}.py", + f"test_modeling_flax_{module_name}.py", + f"test_tokenization_{module_name}.py", + f"test_image_processing_{module_name}.py", + f"test_feature_extraction_{module_name}.py", + f"test_processor_{module_name}.py", + ] + test_files = filter_framework_files(test_files, frameworks=frameworks) + # Add the test directory + test_files = [REPO_PATH / "tests" / "models" / module_name / f for f in test_files] + # Filter by existing files + test_files = [f for f in test_files if f.exists()] + + return {"doc_file": doc_file, "model_files": model_files, "module_name": module_name, "test_files": test_files} + + +_re_checkpoint_for_doc = re.compile(r"^_CHECKPOINT_FOR_DOC\s+=\s+(\S*)\s*$", flags=re.MULTILINE) + + +def find_base_model_checkpoint( + model_type: str, model_files: Optional[Dict[str, Union[Path, List[Path]]]] = None +) -> str: + """ + Finds the model checkpoint used in the docstrings for a given model. + + Args: + model_type (`str`): A valid model type (like "bert" or "gpt2") + model_files (`Dict[str, Union[Path, List[Path]]`, *optional*): + The files associated to `model_type`. Can be passed to speed up the function, otherwise will be computed. + + Returns: + `str`: The checkpoint used. + """ + if model_files is None: + model_files = get_model_files(model_type) + module_files = model_files["model_files"] + for fname in module_files: + if "modeling" not in str(fname): + continue + + with open(fname, "r", encoding="utf-8") as f: + content = f.read() + if _re_checkpoint_for_doc.search(content) is not None: + checkpoint = _re_checkpoint_for_doc.search(content).groups()[0] + # Remove quotes + checkpoint = checkpoint.replace('"', "") + checkpoint = checkpoint.replace("'", "") + return checkpoint + + # TODO: Find some kind of fallback if there is no _CHECKPOINT_FOR_DOC in any of the modeling file. + return "" + + +def get_default_frameworks(): + """ + Returns the list of frameworks (PyTorch, TensorFlow, Flax) that are installed in the environment. + """ + frameworks = [] + if is_torch_available(): + frameworks.append("pt") + if is_tf_available(): + frameworks.append("tf") + if is_flax_available(): + frameworks.append("flax") + return frameworks + + +_re_model_mapping = re.compile("MODEL_([A-Z_]*)MAPPING_NAMES") + + +def retrieve_model_classes(model_type: str, frameworks: Optional[List[str]] = None) -> Dict[str, List[str]]: + """ + Retrieve the model classes associated to a given model. + + Args: + model_type (`str`): A valid model type (like "bert" or "gpt2") + frameworks (`List[str]`, *optional*): + The frameworks to look for. Will default to `["pt", "tf", "flax"]`, passing a smaller list will restrict + the classes returned. + + Returns: + `Dict[str, List[str]]`: A dictionary with one key per framework and the list of model classes associated to + that framework as values. + """ + if frameworks is None: + frameworks = get_default_frameworks() + + modules = { + "pt": auto_module.modeling_auto if is_torch_available() else None, + "tf": auto_module.modeling_tf_auto if is_tf_available() else None, + "flax": auto_module.modeling_flax_auto if is_flax_available() else None, + } + + model_classes = {} + for framework in frameworks: + new_model_classes = [] + if modules[framework] is None: + raise ValueError(f"You selected {framework} in the frameworks, but it is not installed.") + model_mappings = [attr for attr in dir(modules[framework]) if _re_model_mapping.search(attr) is not None] + for model_mapping_name in model_mappings: + model_mapping = getattr(modules[framework], model_mapping_name) + if model_type in model_mapping: + new_model_classes.append(model_mapping[model_type]) + + if len(new_model_classes) > 0: + # Remove duplicates + model_classes[framework] = list(set(new_model_classes)) + + return model_classes + + +def retrieve_info_for_model(model_type, frameworks: Optional[List[str]] = None): + """ + Retrieves all the information from a given model_type. + + Args: + model_type (`str`): A valid model type (like "bert" or "gpt2") + frameworks (`List[str]`, *optional*): + If passed, will only keep the info corresponding to the passed frameworks. + + Returns: + `Dict`: A dictionary with the following keys: + - **frameworks** (`List[str]`): The list of frameworks that back this model type. + - **model_classes** (`Dict[str, List[str]]`): The model classes implemented for that model type. + - **model_files** (`Dict[str, Union[Path, List[Path]]]`): The files associated with that model type. + - **model_patterns** (`ModelPatterns`): The various patterns for the model. + """ + if model_type not in auto_module.MODEL_NAMES_MAPPING: + raise ValueError(f"{model_type} is not a valid model type.") + + model_name = auto_module.MODEL_NAMES_MAPPING[model_type] + config_class = auto_module.configuration_auto.CONFIG_MAPPING_NAMES[model_type] + archive_map = auto_module.configuration_auto.CONFIG_ARCHIVE_MAP_MAPPING_NAMES.get(model_type, None) + if model_type in auto_module.tokenization_auto.TOKENIZER_MAPPING_NAMES: + tokenizer_classes = auto_module.tokenization_auto.TOKENIZER_MAPPING_NAMES[model_type] + tokenizer_class = tokenizer_classes[0] if tokenizer_classes[0] is not None else tokenizer_classes[1] + else: + tokenizer_class = None + image_processor_class = auto_module.image_processing_auto.IMAGE_PROCESSOR_MAPPING_NAMES.get(model_type, None) + feature_extractor_class = auto_module.feature_extraction_auto.FEATURE_EXTRACTOR_MAPPING_NAMES.get(model_type, None) + processor_class = auto_module.processing_auto.PROCESSOR_MAPPING_NAMES.get(model_type, None) + + model_files = get_model_files(model_type, frameworks=frameworks) + model_camel_cased = config_class.replace("Config", "") + + available_frameworks = [] + for fname in model_files["model_files"]: + if "modeling_tf" in str(fname): + available_frameworks.append("tf") + elif "modeling_flax" in str(fname): + available_frameworks.append("flax") + elif "modeling" in str(fname): + available_frameworks.append("pt") + + if frameworks is None: + frameworks = get_default_frameworks() + + frameworks = [f for f in frameworks if f in available_frameworks] + + model_classes = retrieve_model_classes(model_type, frameworks=frameworks) + + # Retrieve model upper-cased name from the constant name of the pretrained archive map. + if archive_map is None: + model_upper_cased = model_camel_cased.upper() + else: + parts = archive_map.split("_") + idx = 0 + while idx < len(parts) and parts[idx] != "PRETRAINED": + idx += 1 + if idx < len(parts): + model_upper_cased = "_".join(parts[:idx]) + else: + model_upper_cased = model_camel_cased.upper() + + model_patterns = ModelPatterns( + model_name, + checkpoint=find_base_model_checkpoint(model_type, model_files=model_files), + model_type=model_type, + model_camel_cased=model_camel_cased, + model_lower_cased=model_files["module_name"], + model_upper_cased=model_upper_cased, + config_class=config_class, + tokenizer_class=tokenizer_class, + image_processor_class=image_processor_class, + feature_extractor_class=feature_extractor_class, + processor_class=processor_class, + ) + + return { + "frameworks": frameworks, + "model_classes": model_classes, + "model_files": model_files, + "model_patterns": model_patterns, + } + + +def clean_frameworks_in_init( + init_file: Union[str, os.PathLike], frameworks: Optional[List[str]] = None, keep_processing: bool = True +): + """ + Removes all the import lines that don't belong to a given list of frameworks or concern tokenizers/feature + extractors/image processors/processors in an init. + + Args: + init_file (`str` or `os.PathLike`): The path to the init to treat. + frameworks (`List[str]`, *optional*): + If passed, this will remove all imports that are subject to a framework not in frameworks + keep_processing (`bool`, *optional*, defaults to `True`): + Whether or not to keep the preprocessing (tokenizer, feature extractor, image processor, processor) imports + in the init. + """ + if frameworks is None: + frameworks = get_default_frameworks() + + names = {"pt": "torch"} + to_remove = [names.get(f, f) for f in ["pt", "tf", "flax"] if f not in frameworks] + if not keep_processing: + to_remove.extend(["sentencepiece", "tokenizers", "vision"]) + + if len(to_remove) == 0: + # Nothing to do + return + + remove_pattern = "|".join(to_remove) + re_conditional_imports = re.compile(rf"^\s*if not is_({remove_pattern})_available\(\):\s*$") + re_try = re.compile(r"\s*try:") + re_else = re.compile(r"\s*else:") + re_is_xxx_available = re.compile(rf"is_({remove_pattern})_available") + + with open(init_file, "r", encoding="utf-8") as f: + content = f.read() + + lines = content.split("\n") + new_lines = [] + idx = 0 + while idx < len(lines): + # Conditional imports in try-except-else blocks + if (re_conditional_imports.search(lines[idx]) is not None) and (re_try.search(lines[idx - 1]) is not None): + # Remove the preceding `try:` + new_lines.pop() + idx += 1 + # Iterate until `else:` + while is_empty_line(lines[idx]) or re_else.search(lines[idx]) is None: + idx += 1 + idx += 1 + indent = find_indent(lines[idx]) + while find_indent(lines[idx]) >= indent or is_empty_line(lines[idx]): + idx += 1 + # Remove the import from utils + elif re_is_xxx_available.search(lines[idx]) is not None: + line = lines[idx] + for framework in to_remove: + line = line.replace(f", is_{framework}_available", "") + line = line.replace(f"is_{framework}_available, ", "") + line = line.replace(f"is_{framework}_available,", "") + line = line.replace(f"is_{framework}_available", "") + + if len(line.strip()) > 0: + new_lines.append(line) + idx += 1 + # Otherwise we keep the line, except if it's a tokenizer import and we don't want to keep it. + elif keep_processing or ( + re.search(r'^\s*"(tokenization|processing|feature_extraction|image_processing)', lines[idx]) is None + and re.search(r"^\s*from .(tokenization|processing|feature_extraction|image_processing)", lines[idx]) + is None + ): + new_lines.append(lines[idx]) + idx += 1 + else: + idx += 1 + + with open(init_file, "w", encoding="utf-8") as f: + f.write("\n".join(new_lines)) + + +def add_model_to_main_init( + old_model_patterns: ModelPatterns, + new_model_patterns: ModelPatterns, + frameworks: Optional[List[str]] = None, + with_processing: bool = True, +): + """ + Add a model to the main init of Transformers. + + Args: + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + frameworks (`List[str]`, *optional*): + If specified, only the models implemented in those frameworks will be added. + with_processsing (`bool`, *optional*, defaults to `True`): + Whether the tokenizer/feature extractor/processor of the model should also be added to the init or not. + """ + with open(TRANSFORMERS_PATH / "__init__.py", "r", encoding="utf-8") as f: + content = f.read() + + lines = content.split("\n") + idx = 0 + new_lines = [] + framework = None + while idx < len(lines): + new_framework = False + if not is_empty_line(lines[idx]) and find_indent(lines[idx]) == 0: + framework = None + elif lines[idx].lstrip().startswith("if not is_torch_available"): + framework = "pt" + new_framework = True + elif lines[idx].lstrip().startswith("if not is_tf_available"): + framework = "tf" + new_framework = True + elif lines[idx].lstrip().startswith("if not is_flax_available"): + framework = "flax" + new_framework = True + + if new_framework: + # For a new framework, we need to skip until the else: block to get where the imports are. + while lines[idx].strip() != "else:": + new_lines.append(lines[idx]) + idx += 1 + + # Skip if we are in a framework not wanted. + if framework is not None and frameworks is not None and framework not in frameworks: + new_lines.append(lines[idx]) + idx += 1 + elif re.search(rf'models.{old_model_patterns.model_lower_cased}( |")', lines[idx]) is not None: + block = [lines[idx]] + indent = find_indent(lines[idx]) + idx += 1 + while find_indent(lines[idx]) > indent: + block.append(lines[idx]) + idx += 1 + if lines[idx].strip() in [")", "]", "],"]: + block.append(lines[idx]) + idx += 1 + block = "\n".join(block) + new_lines.append(block) + + add_block = True + if not with_processing: + processing_classes = [ + old_model_patterns.tokenizer_class, + old_model_patterns.image_processor_class, + old_model_patterns.feature_extractor_class, + old_model_patterns.processor_class, + ] + # Only keep the ones that are not None + processing_classes = [c for c in processing_classes if c is not None] + for processing_class in processing_classes: + block = block.replace(f' "{processing_class}",', "") + block = block.replace(f', "{processing_class}"', "") + block = block.replace(f" {processing_class},", "") + block = block.replace(f", {processing_class}", "") + + if processing_class in block: + add_block = False + if add_block: + new_lines.append(replace_model_patterns(block, old_model_patterns, new_model_patterns)[0]) + else: + new_lines.append(lines[idx]) + idx += 1 + + with open(TRANSFORMERS_PATH / "__init__.py", "w", encoding="utf-8") as f: + f.write("\n".join(new_lines)) + + +def insert_tokenizer_in_auto_module(old_model_patterns: ModelPatterns, new_model_patterns: ModelPatterns): + """ + Add a tokenizer to the relevant mappings in the auto module. + + Args: + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + """ + if old_model_patterns.tokenizer_class is None or new_model_patterns.tokenizer_class is None: + return + + with open(TRANSFORMERS_PATH / "models" / "auto" / "tokenization_auto.py", "r", encoding="utf-8") as f: + content = f.read() + + lines = content.split("\n") + idx = 0 + # First we get to the TOKENIZER_MAPPING_NAMES block. + while not lines[idx].startswith(" TOKENIZER_MAPPING_NAMES = OrderedDict("): + idx += 1 + idx += 1 + + # That block will end at this prompt: + while not lines[idx].startswith("TOKENIZER_MAPPING = _LazyAutoMapping"): + # Either all the tokenizer block is defined on one line, in which case, it ends with ")," + if lines[idx].endswith(","): + block = lines[idx] + # Otherwise it takes several lines until we get to a ")," + else: + block = [] + while not lines[idx].startswith(" ),"): + block.append(lines[idx]) + idx += 1 + block = "\n".join(block) + idx += 1 + + # If we find the model type and tokenizer class in that block, we have the old model tokenizer block + if f'"{old_model_patterns.model_type}"' in block and old_model_patterns.tokenizer_class in block: + break + + new_block = block.replace(old_model_patterns.model_type, new_model_patterns.model_type) + new_block = new_block.replace(old_model_patterns.tokenizer_class, new_model_patterns.tokenizer_class) + + new_lines = lines[:idx] + [new_block] + lines[idx:] + with open(TRANSFORMERS_PATH / "models" / "auto" / "tokenization_auto.py", "w", encoding="utf-8") as f: + f.write("\n".join(new_lines)) + + +AUTO_CLASSES_PATTERNS = { + "configuration_auto.py": [ + ' ("{model_type}", "{model_name}"),', + ' ("{model_type}", "{config_class}"),', + ' ("{model_type}", "{pretrained_archive_map}"),', + ], + "feature_extraction_auto.py": [' ("{model_type}", "{feature_extractor_class}"),'], + "image_processing_auto.py": [' ("{model_type}", "{image_processor_class}"),'], + "modeling_auto.py": [' ("{model_type}", "{any_pt_class}"),'], + "modeling_tf_auto.py": [' ("{model_type}", "{any_tf_class}"),'], + "modeling_flax_auto.py": [' ("{model_type}", "{any_flax_class}"),'], + "processing_auto.py": [' ("{model_type}", "{processor_class}"),'], +} + + +def add_model_to_auto_classes( + old_model_patterns: ModelPatterns, new_model_patterns: ModelPatterns, model_classes: Dict[str, List[str]] +): + """ + Add a model to the relevant mappings in the auto module. + + Args: + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + model_classes (`Dict[str, List[str]]`): A dictionary framework to list of model classes implemented. + """ + for filename in AUTO_CLASSES_PATTERNS: + # Extend patterns with all model classes if necessary + new_patterns = [] + for pattern in AUTO_CLASSES_PATTERNS[filename]: + if re.search("any_([a-z]*)_class", pattern) is not None: + framework = re.search("any_([a-z]*)_class", pattern).groups()[0] + if framework in model_classes: + new_patterns.extend( + [ + pattern.replace("{" + f"any_{framework}_class" + "}", cls) + for cls in model_classes[framework] + ] + ) + elif "{config_class}" in pattern: + new_patterns.append(pattern.replace("{config_class}", old_model_patterns.config_class)) + elif "{image_processor_class}" in pattern: + if ( + old_model_patterns.image_processor_class is not None + and new_model_patterns.image_processor_class is not None + ): + new_patterns.append( + pattern.replace("{image_processor_class}", old_model_patterns.image_processor_class) + ) + elif "{feature_extractor_class}" in pattern: + if ( + old_model_patterns.feature_extractor_class is not None + and new_model_patterns.feature_extractor_class is not None + ): + new_patterns.append( + pattern.replace("{feature_extractor_class}", old_model_patterns.feature_extractor_class) + ) + elif "{processor_class}" in pattern: + if old_model_patterns.processor_class is not None and new_model_patterns.processor_class is not None: + new_patterns.append(pattern.replace("{processor_class}", old_model_patterns.processor_class)) + else: + new_patterns.append(pattern) + + # Loop through all patterns. + for pattern in new_patterns: + full_name = TRANSFORMERS_PATH / "models" / "auto" / filename + old_model_line = pattern + new_model_line = pattern + for attr in ["model_type", "model_name"]: + old_model_line = old_model_line.replace("{" + attr + "}", getattr(old_model_patterns, attr)) + new_model_line = new_model_line.replace("{" + attr + "}", getattr(new_model_patterns, attr)) + if "pretrained_archive_map" in pattern: + old_model_line = old_model_line.replace( + "{pretrained_archive_map}", f"{old_model_patterns.model_upper_cased}_PRETRAINED_CONFIG_ARCHIVE_MAP" + ) + new_model_line = new_model_line.replace( + "{pretrained_archive_map}", f"{new_model_patterns.model_upper_cased}_PRETRAINED_CONFIG_ARCHIVE_MAP" + ) + + new_model_line = new_model_line.replace( + old_model_patterns.model_camel_cased, new_model_patterns.model_camel_cased + ) + + add_content_to_file(full_name, new_model_line, add_after=old_model_line) + + # Tokenizers require special handling + insert_tokenizer_in_auto_module(old_model_patterns, new_model_patterns) + + +DOC_OVERVIEW_TEMPLATE = """## Overview + +The {model_name} model was proposed in []() by . + + +The abstract from the paper is the following: + +** + +Tips: + + + +This model was contributed by [INSERT YOUR HF USERNAME HERE](https://huggingface.co/). +The original code can be found [here](). + +""" + + +def duplicate_doc_file( + doc_file: Union[str, os.PathLike], + old_model_patterns: ModelPatterns, + new_model_patterns: ModelPatterns, + dest_file: Optional[Union[str, os.PathLike]] = None, + frameworks: Optional[List[str]] = None, +): + """ + Duplicate a documentation file and adapts it for a new model. + + Args: + module_file (`str` or `os.PathLike`): Path to the doc file to duplicate. + old_model_patterns (`ModelPatterns`): The patterns for the old model. + new_model_patterns (`ModelPatterns`): The patterns for the new model. + dest_file (`str` or `os.PathLike`, *optional*): Path to the new doc file. + Will default to the a file named `{new_model_patterns.model_type}.mdx` in the same folder as `module_file`. + frameworks (`List[str]`, *optional*): + If passed, will only keep the model classes corresponding to this list of frameworks in the new doc file. + """ + with open(doc_file, "r", encoding="utf-8") as f: + content = f.read() + + content = re.sub(r" +""" + +AUTOGENERATED_KERAS_COMMENT = """ + +""" + + +TASK_TAG_TO_NAME_MAPPING = { + "fill-mask": "Masked Language Modeling", + "image-classification": "Image Classification", + "image-segmentation": "Image Segmentation", + "multiple-choice": "Multiple Choice", + "object-detection": "Object Detection", + "question-answering": "Question Answering", + "summarization": "Summarization", + "table-question-answering": "Table Question Answering", + "text-classification": "Text Classification", + "text-generation": "Causal Language Modeling", + "text2text-generation": "Sequence-to-sequence Language Modeling", + "token-classification": "Token Classification", + "translation": "Translation", + "zero-shot-classification": "Zero Shot Classification", + "automatic-speech-recognition": "Automatic Speech Recognition", +} + + +METRIC_TAGS = [ + "accuracy", + "bleu", + "f1", + "matthews_correlation", + "pearsonr", + "precision", + "recall", + "rouge", + "sacrebleu", + "spearmanr", + "wer", +] + + +def _listify(obj): + if obj is None: + return [] + elif isinstance(obj, str): + return [obj] + else: + return obj + + +def _insert_values_as_list(metadata, name, values): + if values is None: + return metadata + if isinstance(values, str): + values = [values] + values = [v for v in values if v is not None] + if len(values) == 0: + return metadata + metadata[name] = values + return metadata + + +def infer_metric_tags_from_eval_results(eval_results): + if eval_results is None: + return {} + result = {} + for key in eval_results.keys(): + if key.lower().replace(" ", "_") in METRIC_TAGS: + result[key.lower().replace(" ", "_")] = key + elif key.lower() == "rouge1": + result["rouge"] = key + return result + + +def _insert_value(metadata, name, value): + if value is None: + return metadata + metadata[name] = value + return metadata + + +def is_hf_dataset(dataset): + if not is_datasets_available(): + return False + + from datasets import Dataset, IterableDataset + + return isinstance(dataset, (Dataset, IterableDataset)) + + +def _get_mapping_values(mapping): + result = [] + for v in mapping.values(): + if isinstance(v, (tuple, list)): + result += list(v) + else: + result.append(v) + return result + + +@dataclass +class TrainingSummary: + model_name: str + language: Optional[Union[str, List[str]]] = None + license: Optional[str] = None + tags: Optional[Union[str, List[str]]] = None + finetuned_from: Optional[str] = None + tasks: Optional[Union[str, List[str]]] = None + dataset: Optional[Union[str, List[str]]] = None + dataset_tags: Optional[Union[str, List[str]]] = None + dataset_args: Optional[Union[str, List[str]]] = None + dataset_metadata: Optional[Dict[str, Any]] = None + eval_results: Optional[Dict[str, float]] = None + eval_lines: Optional[List[str]] = None + hyperparameters: Optional[Dict[str, Any]] = None + source: Optional[str] = "trainer" + + def __post_init__(self): + # Infer default license from the checkpoint used, if possible. + if ( + self.license is None + and not is_offline_mode() + and self.finetuned_from is not None + and len(self.finetuned_from) > 0 + ): + try: + info = model_info(self.finetuned_from) + for tag in info.tags: + if tag.startswith("license:"): + self.license = tag[8:] + except (requests.exceptions.HTTPError, HFValidationError): + pass + + def create_model_index(self, metric_mapping): + model_index = {"name": self.model_name} + + # Dataset mapping tag -> name + dataset_names = _listify(self.dataset) + dataset_tags = _listify(self.dataset_tags) + dataset_args = _listify(self.dataset_args) + dataset_metadata = _listify(self.dataset_metadata) + if len(dataset_args) < len(dataset_tags): + dataset_args = dataset_args + [None] * (len(dataset_tags) - len(dataset_args)) + dataset_mapping = dict(zip(dataset_tags, dataset_names)) + dataset_arg_mapping = dict(zip(dataset_tags, dataset_args)) + dataset_metadata_mapping = dict(zip(dataset_tags, dataset_metadata)) + + task_mapping = { + task: TASK_TAG_TO_NAME_MAPPING[task] for task in _listify(self.tasks) if task in TASK_TAG_TO_NAME_MAPPING + } + + model_index["results"] = [] + + if len(task_mapping) == 0 and len(dataset_mapping) == 0: + return [model_index] + if len(task_mapping) == 0: + task_mapping = {None: None} + if len(dataset_mapping) == 0: + dataset_mapping = {None: None} + + # One entry per dataset and per task + all_possibilities = [(task_tag, ds_tag) for task_tag in task_mapping for ds_tag in dataset_mapping] + for task_tag, ds_tag in all_possibilities: + result = {} + if task_tag is not None: + result["task"] = {"name": task_mapping[task_tag], "type": task_tag} + + if ds_tag is not None: + metadata = dataset_metadata_mapping.get(ds_tag, {}) + result["dataset"] = { + "name": dataset_mapping[ds_tag], + "type": ds_tag, + **metadata, + } + if dataset_arg_mapping[ds_tag] is not None: + result["dataset"]["args"] = dataset_arg_mapping[ds_tag] + + if len(metric_mapping) > 0: + result["metrics"] = [] + for metric_tag, metric_name in metric_mapping.items(): + result["metrics"].append( + { + "name": metric_name, + "type": metric_tag, + "value": self.eval_results[metric_name], + } + ) + + # Remove partial results to avoid the model card being rejected. + if "task" in result and "dataset" in result and "metrics" in result: + model_index["results"].append(result) + else: + logger.info(f"Dropping the following result as it does not have all the necessary fields:\n{result}") + + return [model_index] + + def create_metadata(self): + metric_mapping = infer_metric_tags_from_eval_results(self.eval_results) + + metadata = {} + metadata = _insert_values_as_list(metadata, "language", self.language) + metadata = _insert_value(metadata, "license", self.license) + metadata = _insert_values_as_list(metadata, "tags", self.tags) + metadata = _insert_values_as_list(metadata, "datasets", self.dataset_tags) + metadata = _insert_values_as_list(metadata, "metrics", list(metric_mapping.keys())) + metadata["model-index"] = self.create_model_index(metric_mapping) + + return metadata + + def to_model_card(self): + model_card = "" + + metadata = yaml.dump(self.create_metadata(), sort_keys=False) + if len(metadata) > 0: + model_card = f"---\n{metadata}---\n" + + # Now the model card for realsies. + if self.source == "trainer": + model_card += AUTOGENERATED_TRAINER_COMMENT + else: + model_card += AUTOGENERATED_KERAS_COMMENT + + model_card += f"\n# {self.model_name}\n\n" + + if self.finetuned_from is None: + model_card += "This model was trained from scratch on " + else: + model_card += ( + "This model is a fine-tuned version of" + f" [{self.finetuned_from}](https://huggingface.co/{self.finetuned_from}) on " + ) + + if self.dataset is None: + model_card += "an unknown dataset." + else: + if isinstance(self.dataset, str): + model_card += f"the {self.dataset} dataset." + elif isinstance(self.dataset, (tuple, list)) and len(self.dataset) == 1: + model_card += f"the {self.dataset[0]} dataset." + else: + model_card += ( + ", ".join([f"the {ds}" for ds in self.dataset[:-1]]) + f" and the {self.dataset[-1]} datasets." + ) + + if self.eval_results is not None: + model_card += "\nIt achieves the following results on the evaluation set:\n" + model_card += "\n".join([f"- {name}: {_maybe_round(value)}" for name, value in self.eval_results.items()]) + model_card += "\n" + + model_card += "\n## Model description\n\nMore information needed\n" + model_card += "\n## Intended uses & limitations\n\nMore information needed\n" + model_card += "\n## Training and evaluation data\n\nMore information needed\n" + + model_card += "\n## Training procedure\n" + model_card += "\n### Training hyperparameters\n" + if self.hyperparameters is not None: + model_card += "\nThe following hyperparameters were used during training:\n" + model_card += "\n".join([f"- {name}: {value}" for name, value in self.hyperparameters.items()]) + model_card += "\n" + else: + model_card += "\nMore information needed\n" + + if self.eval_lines is not None: + model_card += "\n### Training results\n\n" + model_card += make_markdown_table(self.eval_lines) + model_card += "\n" + + model_card += "\n### Framework versions\n\n" + model_card += f"- Transformers {__version__}\n" + + if self.source == "trainer" and is_torch_available(): + import torch + + model_card += f"- Pytorch {torch.__version__}\n" + elif self.source == "keras" and is_tf_available(): + import tensorflow as tf + + model_card += f"- TensorFlow {tf.__version__}\n" + if is_datasets_available(): + import datasets + + model_card += f"- Datasets {datasets.__version__}\n" + if is_tokenizers_available(): + import tokenizers + + model_card += f"- Tokenizers {tokenizers.__version__}\n" + + return model_card + + @classmethod + def from_trainer( + cls, + trainer, + language=None, + license=None, + tags=None, + model_name=None, + finetuned_from=None, + tasks=None, + dataset_tags=None, + dataset_metadata=None, + dataset=None, + dataset_args=None, + ): + # Infer default from dataset + one_dataset = trainer.eval_dataset if trainer.eval_dataset is not None else trainer.train_dataset + if is_hf_dataset(one_dataset) and (dataset_tags is None or dataset_args is None or dataset_metadata is None): + default_tag = one_dataset.builder_name + # Those are not real datasets from the Hub so we exclude them. + if default_tag not in ["csv", "json", "pandas", "parquet", "text"]: + if dataset_metadata is None: + dataset_metadata = [{"config": one_dataset.config_name, "split": str(one_dataset.split)}] + if dataset_tags is None: + dataset_tags = [default_tag] + if dataset_args is None: + dataset_args = [one_dataset.config_name] + + if dataset is None and dataset_tags is not None: + dataset = dataset_tags + + # Infer default finetuned_from + if ( + finetuned_from is None + and hasattr(trainer.model.config, "_name_or_path") + and not os.path.isdir(trainer.model.config._name_or_path) + ): + finetuned_from = trainer.model.config._name_or_path + + # Infer default task tag: + if tasks is None: + model_class_name = trainer.model.__class__.__name__ + for task, mapping in TASK_MAPPING.items(): + if model_class_name in _get_mapping_values(mapping): + tasks = task + + if model_name is None: + model_name = Path(trainer.args.output_dir).name + if len(model_name) == 0: + model_name = finetuned_from + + # Add `generated_from_trainer` to the tags + if tags is None: + tags = ["generated_from_trainer"] + elif isinstance(tags, str) and tags != "generated_from_trainer": + tags = [tags, "generated_from_trainer"] + elif "generated_from_trainer" not in tags: + tags.append("generated_from_trainer") + + _, eval_lines, eval_results = parse_log_history(trainer.state.log_history) + hyperparameters = extract_hyperparameters_from_trainer(trainer) + + return cls( + language=language, + license=license, + tags=tags, + model_name=model_name, + finetuned_from=finetuned_from, + tasks=tasks, + dataset=dataset, + dataset_tags=dataset_tags, + dataset_args=dataset_args, + dataset_metadata=dataset_metadata, + eval_results=eval_results, + eval_lines=eval_lines, + hyperparameters=hyperparameters, + ) + + @classmethod + def from_keras( + cls, + model, + model_name, + keras_history=None, + language=None, + license=None, + tags=None, + finetuned_from=None, + tasks=None, + dataset_tags=None, + dataset=None, + dataset_args=None, + ): + # Infer default from dataset + if dataset is not None: + if is_hf_dataset(dataset) and (dataset_tags is None or dataset_args is None): + default_tag = dataset.builder_name + # Those are not real datasets from the Hub so we exclude them. + if default_tag not in ["csv", "json", "pandas", "parquet", "text"]: + if dataset_tags is None: + dataset_tags = [default_tag] + if dataset_args is None: + dataset_args = [dataset.config_name] + + if dataset is None and dataset_tags is not None: + dataset = dataset_tags + + # Infer default finetuned_from + if ( + finetuned_from is None + and hasattr(model.config, "_name_or_path") + and not os.path.isdir(model.config._name_or_path) + ): + finetuned_from = model.config._name_or_path + + # Infer default task tag: + if tasks is None: + model_class_name = model.__class__.__name__ + for task, mapping in TASK_MAPPING.items(): + if model_class_name in _get_mapping_values(mapping): + tasks = task + + # Add `generated_from_keras_callback` to the tags + if tags is None: + tags = ["generated_from_keras_callback"] + elif isinstance(tags, str) and tags != "generated_from_keras_callback": + tags = [tags, "generated_from_keras_callback"] + elif "generated_from_keras_callback" not in tags: + tags.append("generated_from_keras_callback") + + if keras_history is not None: + _, eval_lines, eval_results = parse_keras_history(keras_history) + else: + eval_lines = [] + eval_results = {} + hyperparameters = extract_hyperparameters_from_keras(model) + + return cls( + language=language, + license=license, + tags=tags, + model_name=model_name, + finetuned_from=finetuned_from, + tasks=tasks, + dataset_tags=dataset_tags, + dataset=dataset, + dataset_args=dataset_args, + eval_results=eval_results, + eval_lines=eval_lines, + hyperparameters=hyperparameters, + source="keras", + ) + + +def parse_keras_history(logs): + """ + Parse the `logs` of either a `tf.keras.History` object returned by `model.fit()` or an accumulated logs `dict` + passed to the `PushToHubCallback`. Returns lines and logs compatible with those returned by `parse_log_history`. + """ + if hasattr(logs, "history"): + # This looks like a `History` object + if not hasattr(logs, "epoch"): + # This history looks empty, return empty results + return None, [], {} + logs.history["epoch"] = logs.epoch + logs = logs.history + else: + # Training logs is a list of dicts, let's invert it to a dict of lists to match a History object + logs = {log_key: [single_dict[log_key] for single_dict in logs] for log_key in logs[0]} + + lines = [] + for i in range(len(logs["epoch"])): + epoch_dict = {log_key: log_value_list[i] for log_key, log_value_list in logs.items()} + values = {} + for k, v in epoch_dict.items(): + if k.startswith("val_"): + k = "validation_" + k[4:] + elif k != "epoch": + k = "train_" + k + splits = k.split("_") + name = " ".join([part.capitalize() for part in splits]) + values[name] = v + lines.append(values) + + eval_results = lines[-1] + + return logs, lines, eval_results + + +def parse_log_history(log_history): + """ + Parse the `log_history` of a Trainer to get the intermediate and final evaluation results. + """ + idx = 0 + while idx < len(log_history) and "train_runtime" not in log_history[idx]: + idx += 1 + + # If there are no training logs + if idx == len(log_history): + idx -= 1 + while idx >= 0 and "eval_loss" not in log_history[idx]: + idx -= 1 + + if idx >= 0: + return None, None, log_history[idx] + else: + return None, None, None + + # From now one we can assume we have training logs: + train_log = log_history[idx] + lines = [] + training_loss = "No log" + for i in range(idx): + if "loss" in log_history[i]: + training_loss = log_history[i]["loss"] + if "eval_loss" in log_history[i]: + metrics = log_history[i].copy() + _ = metrics.pop("total_flos", None) + epoch = metrics.pop("epoch", None) + step = metrics.pop("step", None) + _ = metrics.pop("eval_runtime", None) + _ = metrics.pop("eval_samples_per_second", None) + _ = metrics.pop("eval_steps_per_second", None) + _ = metrics.pop("eval_jit_compilation_time", None) + values = {"Training Loss": training_loss, "Epoch": epoch, "Step": step} + for k, v in metrics.items(): + if k == "eval_loss": + values["Validation Loss"] = v + else: + splits = k.split("_") + name = " ".join([part.capitalize() for part in splits[1:]]) + values[name] = v + lines.append(values) + + idx = len(log_history) - 1 + while idx >= 0 and "eval_loss" not in log_history[idx]: + idx -= 1 + + if idx > 0: + eval_results = {} + for key, value in log_history[idx].items(): + if key.startswith("eval_"): + key = key[5:] + if key not in ["runtime", "samples_per_second", "steps_per_second", "epoch", "step"]: + camel_cased_key = " ".join([part.capitalize() for part in key.split("_")]) + eval_results[camel_cased_key] = value + return train_log, lines, eval_results + else: + return train_log, lines, None + + +def extract_hyperparameters_from_keras(model): + import tensorflow as tf + + hyperparameters = {} + if hasattr(model, "optimizer") and model.optimizer is not None: + hyperparameters["optimizer"] = model.optimizer.get_config() + else: + hyperparameters["optimizer"] = None + hyperparameters["training_precision"] = tf.keras.mixed_precision.global_policy().name + + return hyperparameters + + +def _maybe_round(v, decimals=4): + if isinstance(v, float) and len(str(v).split(".")) > 1 and len(str(v).split(".")[1]) > decimals: + return f"{v:.{decimals}f}" + return str(v) + + +def _regular_table_line(values, col_widths): + values_with_space = [f"| {v}" + " " * (w - len(v) + 1) for v, w in zip(values, col_widths)] + return "".join(values_with_space) + "|\n" + + +def _second_table_line(col_widths): + values = ["|:" + "-" * w + ":" for w in col_widths] + return "".join(values) + "|\n" + + +def make_markdown_table(lines): + """ + Create a nice Markdown table from the results in `lines`. + """ + if lines is None or len(lines) == 0: + return "" + col_widths = {key: len(str(key)) for key in lines[0].keys()} + for line in lines: + for key, value in line.items(): + if col_widths[key] < len(_maybe_round(value)): + col_widths[key] = len(_maybe_round(value)) + + table = _regular_table_line(list(lines[0].keys()), list(col_widths.values())) + table += _second_table_line(list(col_widths.values())) + for line in lines: + table += _regular_table_line([_maybe_round(v) for v in line.values()], list(col_widths.values())) + return table + + +_TRAINING_ARGS_KEYS = [ + "learning_rate", + "train_batch_size", + "eval_batch_size", + "seed", +] + + +def extract_hyperparameters_from_trainer(trainer): + hyperparameters = {k: getattr(trainer.args, k) for k in _TRAINING_ARGS_KEYS} + + if trainer.args.parallel_mode not in [ParallelMode.NOT_PARALLEL, ParallelMode.NOT_DISTRIBUTED]: + hyperparameters["distributed_type"] = ( + "multi-GPU" if trainer.args.parallel_mode == ParallelMode.DISTRIBUTED else trainer.args.parallel_mode.value + ) + if trainer.args.world_size > 1: + hyperparameters["num_devices"] = trainer.args.world_size + if trainer.args.gradient_accumulation_steps > 1: + hyperparameters["gradient_accumulation_steps"] = trainer.args.gradient_accumulation_steps + + total_train_batch_size = ( + trainer.args.train_batch_size * trainer.args.world_size * trainer.args.gradient_accumulation_steps + ) + if total_train_batch_size != hyperparameters["train_batch_size"]: + hyperparameters["total_train_batch_size"] = total_train_batch_size + total_eval_batch_size = trainer.args.eval_batch_size * trainer.args.world_size + if total_eval_batch_size != hyperparameters["eval_batch_size"]: + hyperparameters["total_eval_batch_size"] = total_eval_batch_size + + if trainer.args.adafactor: + hyperparameters["optimizer"] = "Adafactor" + else: + hyperparameters["optimizer"] = ( + f"Adam with betas=({trainer.args.adam_beta1},{trainer.args.adam_beta2}) and" + f" epsilon={trainer.args.adam_epsilon}" + ) + + hyperparameters["lr_scheduler_type"] = trainer.args.lr_scheduler_type.value + if trainer.args.warmup_ratio != 0.0: + hyperparameters["lr_scheduler_warmup_ratio"] = trainer.args.warmup_ratio + if trainer.args.warmup_steps != 0.0: + hyperparameters["lr_scheduler_warmup_steps"] = trainer.args.warmup_steps + if trainer.args.max_steps != -1: + hyperparameters["training_steps"] = trainer.args.max_steps + else: + hyperparameters["num_epochs"] = trainer.args.num_train_epochs + + if trainer.args.fp16: + if trainer.use_cuda_amp: + hyperparameters["mixed_precision_training"] = "Native AMP" + elif trainer.use_apex: + hyperparameters["mixed_precision_training"] = f"Apex, opt level {trainer.args.fp16_opt_level}" + + if trainer.args.label_smoothing_factor != 0.0: + hyperparameters["label_smoothing_factor"] = trainer.args.label_smoothing_factor + + return hyperparameters diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_pytorch_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_pytorch_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..5de6a985df4116dc9037a59f5622b383a633ee44 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_pytorch_utils.py @@ -0,0 +1,421 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch - Flax general utilities.""" + + +import os +from pickle import UnpicklingError +from typing import Dict, Tuple + +import jax +import jax.numpy as jnp +import numpy as np +from flax.serialization import from_bytes +from flax.traverse_util import flatten_dict, unflatten_dict + +import transformers + +from .utils import logging + + +logger = logging.get_logger(__name__) + + +##################### +# PyTorch => Flax # +##################### + + +def load_pytorch_checkpoint_in_flax_state_dict( + flax_model, pytorch_checkpoint_path, is_sharded, allow_missing_keys=False +): + """Load pytorch checkpoints in a flax model""" + try: + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a PyTorch model in Flax, requires both PyTorch and Flax to be installed. Please see" + " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation" + " instructions." + ) + raise + + if not is_sharded: + pt_path = os.path.abspath(pytorch_checkpoint_path) + logger.info(f"Loading PyTorch weights from {pt_path}") + + pt_state_dict = torch.load(pt_path, map_location="cpu") + logger.info(f"PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()):,} parameters.") + + flax_state_dict = convert_pytorch_state_dict_to_flax(pt_state_dict, flax_model) + else: + # model is sharded and pytorch_checkpoint_path already contains the list of .pt shard files + flax_state_dict = convert_pytorch_sharded_state_dict_to_flax(pytorch_checkpoint_path, flax_model) + return flax_state_dict + + +def rename_key_and_reshape_tensor( + pt_tuple_key: Tuple[str], + pt_tensor: np.ndarray, + random_flax_state_dict: Dict[str, jnp.ndarray], + model_prefix: str, +) -> (Tuple[str], np.ndarray): + """Rename PT weight names to corresponding Flax weight names and reshape tensor if necessary""" + + def is_key_or_prefix_key_in_dict(key: Tuple[str]) -> bool: + """Checks if `key` of `(prefix,) + key` is in random_flax_state_dict""" + return len(set(random_flax_state_dict) & {key, (model_prefix,) + key}) > 0 + + # layer norm + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("scale",) + if pt_tuple_key[-1] in ["weight", "gamma"] and is_key_or_prefix_key_in_dict(renamed_pt_tuple_key): + return renamed_pt_tuple_key, pt_tensor + + # batch norm layer mean + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("mean",) + if pt_tuple_key[-1] == "running_mean" and not is_key_or_prefix_key_in_dict(pt_tuple_key): + return renamed_pt_tuple_key, pt_tensor + + # batch norm layer var + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("var",) + if pt_tuple_key[-1] == "running_var" and not is_key_or_prefix_key_in_dict(pt_tuple_key): + return renamed_pt_tuple_key, pt_tensor + + # embedding + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("embedding",) + if pt_tuple_key[-1] == "weight" and is_key_or_prefix_key_in_dict(renamed_pt_tuple_key): + return renamed_pt_tuple_key, pt_tensor + + # conv layer + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("kernel",) + if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4 and not is_key_or_prefix_key_in_dict(pt_tuple_key): + pt_tensor = pt_tensor.transpose(2, 3, 1, 0) + return renamed_pt_tuple_key, pt_tensor + + # linear layer + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("kernel",) + if pt_tuple_key[-1] == "weight" and not is_key_or_prefix_key_in_dict(pt_tuple_key): + pt_tensor = pt_tensor.T + return renamed_pt_tuple_key, pt_tensor + + # old PyTorch layer norm weight + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("weight",) + if pt_tuple_key[-1] == "gamma": + return renamed_pt_tuple_key, pt_tensor + + # old PyTorch layer norm bias + renamed_pt_tuple_key = pt_tuple_key[:-1] + ("bias",) + if pt_tuple_key[-1] == "beta": + return renamed_pt_tuple_key, pt_tensor + + return pt_tuple_key, pt_tensor + + +def convert_pytorch_state_dict_to_flax(pt_state_dict, flax_model): + # convert pytorch tensor to numpy + pt_state_dict = {k: v.numpy() for k, v in pt_state_dict.items()} + + model_prefix = flax_model.base_model_prefix + + # use params dict if the model contains batch norm layers + if "params" in flax_model.params: + flax_model_params = flax_model.params["params"] + else: + flax_model_params = flax_model.params + random_flax_state_dict = flatten_dict(flax_model_params) + + # add batch_stats keys,values to dict + if "batch_stats" in flax_model.params: + flax_batch_stats = flatten_dict(flax_model.params["batch_stats"]) + random_flax_state_dict.update(flax_batch_stats) + + flax_state_dict = {} + + load_model_with_head_into_base_model = (model_prefix not in flax_model_params) and ( + model_prefix in {k.split(".")[0] for k in pt_state_dict.keys()} + ) + load_base_model_into_model_with_head = (model_prefix in flax_model_params) and ( + model_prefix not in {k.split(".")[0] for k in pt_state_dict.keys()} + ) + + # Need to change some parameters name to match Flax names + for pt_key, pt_tensor in pt_state_dict.items(): + pt_tuple_key = tuple(pt_key.split(".")) + + # remove base model prefix if necessary + has_base_model_prefix = pt_tuple_key[0] == model_prefix + if load_model_with_head_into_base_model and has_base_model_prefix: + pt_tuple_key = pt_tuple_key[1:] + + # Correctly rename weight parameters + flax_key, flax_tensor = rename_key_and_reshape_tensor( + pt_tuple_key, pt_tensor, random_flax_state_dict, model_prefix + ) + + # add model prefix if necessary + require_base_model_prefix = (model_prefix,) + flax_key in random_flax_state_dict + if load_base_model_into_model_with_head and require_base_model_prefix: + flax_key = (model_prefix,) + flax_key + + if flax_key in random_flax_state_dict: + if flax_tensor.shape != random_flax_state_dict[flax_key].shape: + raise ValueError( + f"PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape " + f"{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}." + ) + + # add batch stats if the model contains batchnorm layers + if "batch_stats" in flax_model.params: + if "mean" in flax_key[-1] or "var" in flax_key[-1]: + flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) + continue + # remove num_batches_tracked key + if "num_batches_tracked" in flax_key[-1]: + flax_state_dict.pop(flax_key, None) + continue + + # also add unexpected weight so that warning is thrown + flax_state_dict[("params",) + flax_key] = jnp.asarray(flax_tensor) + + else: + # also add unexpected weight so that warning is thrown + flax_state_dict[flax_key] = jnp.asarray(flax_tensor) + + return unflatten_dict(flax_state_dict) + + +############################ +# Sharded Pytorch => Flax # +############################ + + +def convert_pytorch_sharded_state_dict_to_flax(shard_filenames, flax_model): + import torch + + # Load the index + flax_state_dict = {} + for shard_file in shard_filenames: + # load using msgpack utils + pt_state_dict = torch.load(shard_file) + pt_state_dict = {k: v.numpy() for k, v in pt_state_dict.items()} + + model_prefix = flax_model.base_model_prefix + + # use params dict if the model contains batch norm layers and then add batch_stats keys,values to dict + if "batch_stats" in flax_model.params: + flax_model_params = flax_model.params["params"] + + random_flax_state_dict = flatten_dict(flax_model_params) + random_flax_state_dict.update(flatten_dict(flax_model.params["batch_stats"])) + else: + flax_model_params = flax_model.params + random_flax_state_dict = flatten_dict(flax_model_params) + + load_model_with_head_into_base_model = (model_prefix not in flax_model_params) and ( + model_prefix in {k.split(".")[0] for k in pt_state_dict.keys()} + ) + load_base_model_into_model_with_head = (model_prefix in flax_model_params) and ( + model_prefix not in {k.split(".")[0] for k in pt_state_dict.keys()} + ) + # Need to change some parameters name to match Flax names + for pt_key, pt_tensor in pt_state_dict.items(): + pt_tuple_key = tuple(pt_key.split(".")) + + # remove base model prefix if necessary + has_base_model_prefix = pt_tuple_key[0] == model_prefix + if load_model_with_head_into_base_model and has_base_model_prefix: + pt_tuple_key = pt_tuple_key[1:] + + # Correctly rename weight parameters + flax_key, flax_tensor = rename_key_and_reshape_tensor( + pt_tuple_key, pt_tensor, random_flax_state_dict, model_prefix + ) + # add model prefix if necessary + require_base_model_prefix = (model_prefix,) + flax_key in random_flax_state_dict + if load_base_model_into_model_with_head and require_base_model_prefix: + flax_key = (model_prefix,) + flax_key + + if flax_key in random_flax_state_dict: + if flax_tensor.shape != random_flax_state_dict[flax_key].shape: + raise ValueError( + f"PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape " + f"{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}." + ) + + # add batch stats if the model contains batchnorm layers + if "batch_stats" in flax_model.params: + if "mean" in flax_key[-1]: + flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) + continue + if "var" in flax_key[-1]: + flax_state_dict[("batch_stats",) + flax_key] = jnp.asarray(flax_tensor) + continue + # remove num_batches_tracked key + if "num_batches_tracked" in flax_key[-1]: + flax_state_dict.pop(flax_key, None) + continue + + # also add unexpected weight so that warning is thrown + flax_state_dict[("params",) + flax_key] = jnp.asarray(flax_tensor) + + else: + # also add unexpected weight so that warning is thrown + flax_state_dict[flax_key] = jnp.asarray(flax_tensor) + return unflatten_dict(flax_state_dict) + + +##################### +# Flax => PyTorch # +##################### + + +def load_flax_checkpoint_in_pytorch_model(model, flax_checkpoint_path): + """Load flax checkpoints in a PyTorch model""" + flax_checkpoint_path = os.path.abspath(flax_checkpoint_path) + logger.info(f"Loading Flax weights from {flax_checkpoint_path}") + + # import correct flax class + flax_cls = getattr(transformers, "Flax" + model.__class__.__name__) + + # load flax weight dict + with open(flax_checkpoint_path, "rb") as state_f: + try: + flax_state_dict = from_bytes(flax_cls, state_f.read()) + except UnpicklingError: + raise EnvironmentError(f"Unable to convert {flax_checkpoint_path} to Flax deserializable object. ") + + return load_flax_weights_in_pytorch_model(model, flax_state_dict) + + +def load_flax_weights_in_pytorch_model(pt_model, flax_state): + """Load flax checkpoints in a PyTorch model""" + + try: + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a Flax weights in PyTorch, requires both PyTorch and Flax to be installed. Please see" + " https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation" + " instructions." + ) + raise + + # check if we have bf16 weights + is_type_bf16 = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype == jnp.bfloat16, flax_state)).values() + if any(is_type_bf16): + # convert all weights to fp32 if the are bf16 since torch.from_numpy can-not handle bf16 + # and bf16 is not fully supported in PT yet. + logger.warning( + "Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` " + "before loading those in PyTorch model." + ) + flax_state = jax.tree_util.tree_map( + lambda params: params.astype(np.float32) if params.dtype == jnp.bfloat16 else params, flax_state + ) + + flax_state_dict = flatten_dict(flax_state) + pt_model_dict = pt_model.state_dict() + + load_model_with_head_into_base_model = (pt_model.base_model_prefix in flax_state) and ( + pt_model.base_model_prefix not in {k.split(".")[0] for k in pt_model_dict.keys()} + ) + load_base_model_into_model_with_head = (pt_model.base_model_prefix not in flax_state) and ( + pt_model.base_model_prefix in {k.split(".")[0] for k in pt_model_dict.keys()} + ) + + # keep track of unexpected & missing keys + unexpected_keys = [] + missing_keys = set(pt_model_dict.keys()) + + for flax_key_tuple, flax_tensor in flax_state_dict.items(): + has_base_model_prefix = flax_key_tuple[0] == pt_model.base_model_prefix + require_base_model_prefix = ".".join((pt_model.base_model_prefix,) + flax_key_tuple) in pt_model_dict + + # adapt flax_key to prepare for loading from/to base model only + if load_model_with_head_into_base_model and has_base_model_prefix: + flax_key_tuple = flax_key_tuple[1:] + elif load_base_model_into_model_with_head and require_base_model_prefix: + flax_key_tuple = (pt_model.base_model_prefix,) + flax_key_tuple + + # rename flax weights to PyTorch format + if flax_key_tuple[-1] == "kernel" and flax_tensor.ndim == 4 and ".".join(flax_key_tuple) not in pt_model_dict: + # conv layer + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + flax_tensor = jnp.transpose(flax_tensor, (3, 2, 0, 1)) + elif flax_key_tuple[-1] == "kernel" and ".".join(flax_key_tuple) not in pt_model_dict: + # linear layer + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + flax_tensor = flax_tensor.T + elif flax_key_tuple[-1] in ["scale", "embedding"]: + flax_key_tuple = flax_key_tuple[:-1] + ("weight",) + + # adding batch stats from flax batch norm to pt + elif "mean" in flax_key_tuple[-1]: + flax_key_tuple = flax_key_tuple[:-1] + ("running_mean",) + elif "var" in flax_key_tuple[-1]: + flax_key_tuple = flax_key_tuple[:-1] + ("running_var",) + + if "batch_stats" in flax_state: + flax_key = ".".join(flax_key_tuple[1:]) # Remove the params/batch_stats header + else: + flax_key = ".".join(flax_key_tuple) + + if flax_key in pt_model_dict: + if flax_tensor.shape != pt_model_dict[flax_key].shape: + raise ValueError( + f"Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected " + f"to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}." + ) + else: + # add weight to pytorch dict + flax_tensor = np.asarray(flax_tensor) if not isinstance(flax_tensor, np.ndarray) else flax_tensor + pt_model_dict[flax_key] = torch.from_numpy(flax_tensor) + # remove from missing keys + missing_keys.remove(flax_key) + else: + # weight is not expected by PyTorch model + unexpected_keys.append(flax_key) + + pt_model.load_state_dict(pt_model_dict) + + # re-transform missing_keys to list + missing_keys = list(missing_keys) + + if len(unexpected_keys) > 0: + logger.warning( + "Some weights of the Flax model were not used when initializing the PyTorch model" + f" {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" + f" {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture" + " (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This" + f" IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect" + " to be exactly identical (e.g. initializing a BertForSequenceClassification model from a" + " FlaxBertForSequenceClassification model)." + ) + else: + logger.warning(f"All Flax model weights were used when initializing {pt_model.__class__.__name__}.\n") + if len(missing_keys) > 0: + logger.warning( + f"Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly" + f" initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to" + " use it for predictions and inference." + ) + else: + logger.warning( + f"All the weights of {pt_model.__class__.__name__} were initialized from the Flax model.\n" + "If your task is similar to the task the model of the checkpoint was trained on, " + f"you can already use {pt_model.__class__.__name__} for predictions without further training." + ) + + return pt_model diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..eee84ba5f96591b7609ee4b57fa18b3850280ecc --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_flax_utils.py @@ -0,0 +1,1170 @@ +# coding=utf-8 +# Copyright 2021 The Google Flax Team Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import gc +import json +import os +import re +from functools import partial +from pickle import UnpicklingError +from typing import Any, Dict, Set, Tuple, Union + +import flax.linen as nn +import jax +import jax.numpy as jnp +import msgpack.exceptions +from flax.core.frozen_dict import FrozenDict, unfreeze +from flax.serialization import from_bytes, to_bytes +from flax.traverse_util import flatten_dict, unflatten_dict +from jax.random import PRNGKey + +from .configuration_utils import PretrainedConfig +from .dynamic_module_utils import custom_object_save +from .generation import FlaxGenerationMixin, GenerationConfig +from .modeling_flax_pytorch_utils import load_pytorch_checkpoint_in_flax_state_dict +from .utils import ( + FLAX_WEIGHTS_INDEX_NAME, + FLAX_WEIGHTS_NAME, + WEIGHTS_INDEX_NAME, + WEIGHTS_NAME, + PushToHubMixin, + add_code_sample_docstrings, + add_start_docstrings_to_model_forward, + cached_file, + copy_func, + download_url, + has_file, + is_offline_mode, + is_remote_url, + logging, + replace_return_docstrings, +) +from .utils.hub import convert_file_size_to_int, get_checkpoint_shard_files + + +logger = logging.get_logger(__name__) + + +def quick_gelu(x): + return x * jax.nn.sigmoid(1.702 * x) + + +ACT2FN = { + "gelu": partial(nn.gelu, approximate=False), + "relu": nn.relu, + "silu": nn.swish, + "swish": nn.swish, + "gelu_new": partial(nn.gelu, approximate=True), + "quick_gelu": quick_gelu, +} + + +def dtype_byte_size(dtype): + """ + Returns the size (in bytes) occupied by one parameter of type `dtype`. Example: + ```py + >>> dtype_byte_size(np.float32) + 4 + ``` + """ + if dtype == bool: + return 1 / 8 + bit_search = re.search(r"[^\d](\d+)$", dtype.name) + if bit_search is None: + raise ValueError(f"`dtype` is not a valid dtype: {dtype}.") + bit_size = int(bit_search.groups()[0]) + return bit_size // 8 + + +def flax_shard_checkpoint(params, max_shard_size="10GB"): + """ + Splits a model state dictionary in sub-checkpoints so that the final size of each sub-checkpoint does not exceed a + given size. The sub-checkpoints are determined by iterating through the `state_dict` in the order of its keys, so + there is no optimization made to make each sub-checkpoint as close as possible to the maximum size passed. For + example, if the limit is 10GB and we have weights of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as + [6GB], [6+2GB], [6+2+2GB] and not [6+2+2GB], [6+2GB], [6GB]. + + + + If one of the model's weight is bigger that `max_shard_size`, it will end up in its own sub-checkpoint which will + have a size greater than `max_shard_size`. + + + + Args: + params (`Union[Dict, FrozenDict]`): A `PyTree` of model parameters. + max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): + The maximum size of each sub-checkpoint. If expressed as a string, needs to be digits followed by a unit + (like `"5MB"`). + """ + max_shard_size = convert_file_size_to_int(max_shard_size) + + sharded_state_dicts = [] + current_block = {} + current_block_size = 0 + total_size = 0 + + # flatten the weights to chunk + weights = flatten_dict(params, sep="/") + for item in weights: + weight_size = weights[item].size * dtype_byte_size(weights[item].dtype) + + # If this weight is going to tip up over the maximal size, we split. + if current_block_size + weight_size > max_shard_size: + sharded_state_dicts.append(current_block) + current_block = {} + current_block_size = 0 + + current_block[item] = weights[item] + current_block_size += weight_size + total_size += weight_size + + # Add the last block + sharded_state_dicts.append(current_block) + + # If we only have one shard, we return it + if len(sharded_state_dicts) == 1: + return {FLAX_WEIGHTS_NAME: sharded_state_dicts[0]}, None + + # Otherwise, let's build the index + weight_map = {} + shards = {} + for idx, shard in enumerate(sharded_state_dicts): + shard_file = FLAX_WEIGHTS_NAME.replace(".msgpack", f"-{idx+1:05d}-of-{len(sharded_state_dicts):05d}.msgpack") + shards[shard_file] = shard + for weight_name in shard.keys(): + weight_map[weight_name] = shard_file + + # Add the metadata + metadata = {"total_size": total_size} + index = {"metadata": metadata, "weight_map": weight_map} + return shards, index + + +class FlaxPreTrainedModel(PushToHubMixin, FlaxGenerationMixin): + r""" + Base class for all models. + + [`FlaxPreTrainedModel`] takes care of storing the configuration of the models and handles methods for loading, + downloading and saving models. + + Class attributes (overridden by derived classes): + + - **config_class** ([`PretrainedConfig`]) -- A subclass of [`PretrainedConfig`] to use as configuration class + for this model architecture. + - **base_model_prefix** (`str`) -- A string indicating the attribute associated to the base model in derived + classes of the same architecture adding modules on top of the base model. + - **main_input_name** (`str`) -- The name of the principal input to the model (often `input_ids` for NLP + models, `pixel_values` for vision models and `input_values` for speech models). + """ + config_class = None + base_model_prefix = "" + main_input_name = "input_ids" + _auto_class = None + _missing_keys = set() + + def __init__( + self, + config: PretrainedConfig, + module: nn.Module, + input_shape: Tuple = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + ): + if config is None: + raise ValueError("config cannot be None") + + if module is None: + raise ValueError("module cannot be None") + + # Those are private to be exposed as typed property on derived classes. + self._config = config + self._module = module + + # Those are public as their type is generic to every derived classes. + self.key = PRNGKey(seed) + self.dtype = dtype + self.input_shape = input_shape + self.generation_config = GenerationConfig.from_model_config(config) if self.can_generate() else None + + # To check if the model was intialized automatically. + self._is_initialized = _do_init + + if _do_init: + # randomly initialized parameters + random_params = self.init_weights(self.key, input_shape) + params_shape_tree = jax.eval_shape(lambda params: params, random_params) + else: + init_fn = partial(self.init_weights, input_shape=input_shape) + params_shape_tree = jax.eval_shape(init_fn, self.key) + + logger.info( + "Model weights are not initialized as `_do_init` is set to `False`. " + f"Make sure to call `{self.__class__.__name__}.init_weights` manually to initialize the weights." + ) + + # get the shape of the parameters + self._params_shape_tree = params_shape_tree + + # save required_params as set + self._required_params = set(flatten_dict(unfreeze(params_shape_tree)).keys()) + + # initialize the parameters + if _do_init: + self.params = random_params + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> Dict: + raise NotImplementedError(f"init method has to be implemented for {self}") + + def enable_gradient_checkpointing(self): + raise NotImplementedError(f"gradient checkpointing method has to be implemented for {self}") + + @classmethod + def _from_config(cls, config, **kwargs): + """ + All context managers that the model should be initialized under go here. + """ + return cls(config, **kwargs) + + @property + def framework(self) -> str: + """ + :str: Identifies that this is a Flax model. + """ + return "flax" + + @property + def config(self) -> PretrainedConfig: + return self._config + + @property + def module(self) -> nn.Module: + return self._module + + @property + def params(self) -> Union[Dict, FrozenDict]: + if not self._is_initialized: + raise ValueError( + "`params` cannot be accessed from model when the model is created with `_do_init=False`. " + "You must call `init_weights` manually and store the params outside of the model and " + "pass it explicitly where needed." + ) + return self._params + + @property + def required_params(self) -> Set: + return self._required_params + + @property + def params_shape_tree(self) -> Dict: + return self._params_shape_tree + + @params.setter + def params(self, params: Union[Dict, FrozenDict]): + # don't set params if the model is not initialized + if not self._is_initialized: + raise ValueError( + "`params` cannot be set from model when the model is created with `_do_init=False`. " + "You store the params outside of the model." + ) + + if isinstance(params, FrozenDict): + params = unfreeze(params) + param_keys = set(flatten_dict(params).keys()) + if len(self.required_params - param_keys) > 0: + raise ValueError( + "Some parameters are missing. Make sure that `params` include the following " + f"parameters {self.required_params - param_keys}" + ) + self._params = params + + def _cast_floating_to(self, params: Union[Dict, FrozenDict], dtype: jnp.dtype, mask: Any = None) -> Any: + """ + Helper method to cast floating-point values of given parameter `PyTree` to given `dtype`. + """ + + # taken from https://github.com/deepmind/jmp/blob/3a8318abc3292be38582794dbf7b094e6583b192/jmp/_src/policy.py#L27 + def conditional_cast(param): + if isinstance(param, jnp.ndarray) and jnp.issubdtype(param.dtype, jnp.floating): + param = param.astype(dtype) + return param + + if mask is None: + return jax.tree_util.tree_map(conditional_cast, params) + + flat_params = flatten_dict(params) + flat_mask, _ = jax.tree_util.tree_flatten(mask) + + for masked, key in zip(flat_mask, flat_params.keys()): + if masked: + param = flat_params[key] + flat_params[key] = conditional_cast(param) + + return unflatten_dict(flat_params) + + def to_bf16(self, params: Union[Dict, FrozenDict], mask: Any = None): + r""" + Cast the floating-point `params` to `jax.numpy.bfloat16`. This returns a new `params` tree and does not cast + the `params` in place. + + This method can be used on TPU to explicitly convert the model parameters to bfloat16 precision to do full + half-precision training or to save weights in bfloat16 for inference in order to save memory and improve speed. + + Arguments: + params (`Union[Dict, FrozenDict]`): + A `PyTree` of model parameters. + mask (`Union[Dict, FrozenDict]`): + A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params + you want to cast, and should be `False` for those you want to skip. + + Examples: + + ```python + >>> from transformers import FlaxBertModel + + >>> # load model + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> # By default, the model parameters will be in fp32 precision, to cast these to bfloat16 precision + >>> model.params = model.to_bf16(model.params) + >>> # If you want don't want to cast certain parameters (for example layer norm bias and scale) + >>> # then pass the mask as follows + >>> from flax import traverse_util + + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> flat_params = traverse_util.flatten_dict(model.params) + >>> mask = { + ... path: (path[-2] != ("LayerNorm", "bias") and path[-2:] != ("LayerNorm", "scale")) + ... for path in flat_params + ... } + >>> mask = traverse_util.unflatten_dict(mask) + >>> model.params = model.to_bf16(model.params, mask) + ```""" + return self._cast_floating_to(params, jnp.bfloat16, mask) + + def to_fp32(self, params: Union[Dict, FrozenDict], mask: Any = None): + r""" + Cast the floating-point `parmas` to `jax.numpy.float32`. This method can be used to explicitly convert the + model parameters to fp32 precision. This returns a new `params` tree and does not cast the `params` in place. + + Arguments: + params (`Union[Dict, FrozenDict]`): + A `PyTree` of model parameters. + mask (`Union[Dict, FrozenDict]`): + A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params + you want to cast, and should be `False` for those you want to skip + + Examples: + + ```python + >>> from transformers import FlaxBertModel + + >>> # Download model and configuration from huggingface.co + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> # By default, the model params will be in fp32, to illustrate the use of this method, + >>> # we'll first cast to fp16 and back to fp32 + >>> model.params = model.to_f16(model.params) + >>> # now cast back to fp32 + >>> model.params = model.to_fp32(model.params) + ```""" + return self._cast_floating_to(params, jnp.float32, mask) + + def to_fp16(self, params: Union[Dict, FrozenDict], mask: Any = None): + r""" + Cast the floating-point `parmas` to `jax.numpy.float16`. This returns a new `params` tree and does not cast the + `params` in place. + + This method can be used on GPU to explicitly convert the model parameters to float16 precision to do full + half-precision training or to save weights in float16 for inference in order to save memory and improve speed. + + Arguments: + params (`Union[Dict, FrozenDict]`): + A `PyTree` of model parameters. + mask (`Union[Dict, FrozenDict]`): + A `PyTree` with same structure as the `params` tree. The leaves should be booleans, `True` for params + you want to cast, and should be `False` for those you want to skip + + Examples: + + ```python + >>> from transformers import FlaxBertModel + + >>> # load model + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> # By default, the model params will be in fp32, to cast these to float16 + >>> model.params = model.to_fp16(model.params) + >>> # If you want don't want to cast certain parameters (for example layer norm bias and scale) + >>> # then pass the mask as follows + >>> from flax import traverse_util + + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> flat_params = traverse_util.flatten_dict(model.params) + >>> mask = { + ... path: (path[-2] != ("LayerNorm", "bias") and path[-2:] != ("LayerNorm", "scale")) + ... for path in flat_params + ... } + >>> mask = traverse_util.unflatten_dict(mask) + >>> model.params = model.to_fp16(model.params, mask) + ```""" + return self._cast_floating_to(params, jnp.float16, mask) + + @classmethod + def load_flax_sharded_weights(cls, shard_files): + """ + This is the same as [`flax.serialization.from_bytes`] + (https:lax.readthedocs.io/en/latest/_modules/flax/serialization.html#from_bytes) but for a sharded checkpoint. + + This load is performed efficiently: each checkpoint shard is loaded one by one in RAM and deleted after being + loaded in the model. + + Args: + shard_files (`List[str]`: + The list of shard files to load. + + Returns: + `Dict`: A nested dictionary of the model parameters, in the expected format for flax models : `{'model': + {'params': {'...'}}}`. + """ + + # Load the index + state_sharded_dict = {} + + for shard_file in shard_files: + # load using msgpack utils + try: + with open(shard_file, "rb") as state_f: + state = from_bytes(cls, state_f.read()) + except (UnpicklingError, msgpack.exceptions.ExtraData) as e: + with open(shard_file) as f: + if f.read().startswith("version"): + raise OSError( + "You seem to have cloned a repository without having git-lfs installed. Please" + " install git-lfs and run `git lfs install` followed by `git lfs pull` in the" + " folder you cloned." + ) + else: + raise ValueError from e + except (UnicodeDecodeError, ValueError): + raise EnvironmentError(f"Unable to convert {shard_file} to Flax deserializable object. ") + + state = flatten_dict(state, sep="/") + state_sharded_dict.update(state) + del state + gc.collect() + + # the state dict is unflattened to the match the format of model.params + return unflatten_dict(state_sharded_dict, sep="/") + + def can_generate(self) -> bool: + """ + Returns whether this model can generate sequences with `.generate()`. Returns: + `bool`: Whether this model can generate sequences with `.generate()`. + """ + # Detects whether `prepare_inputs_for_generation` has been overwritten, which is a requirement for generation + if "GenerationMixin" in str(self.prepare_inputs_for_generation): + return False + return True + + @classmethod + def from_pretrained( + cls, + pretrained_model_name_or_path: Union[str, os.PathLike], + dtype: jnp.dtype = jnp.float32, + *model_args, + **kwargs, + ): + r""" + Instantiate a pretrained flax model from a pre-trained model configuration. + + The warning *Weights from XXX not initialized from pretrained model* means that the weights of XXX do not come + pretrained with the rest of the model. It is up to you to train those weights with a downstream fine-tuning + task. + + The warning *Weights from XXX not used in YYY* means that the layer XXX is not used by YYY, therefore those + weights are discarded. + + Parameters: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing model weights saved using + [`~FlaxPreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. + - A path or url to a *pt index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In this case, + `from_pt` should be set to `True`. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. + model_args (sequence of positional arguments, *optional*): + All remaining positional arguments will be passed to the underlying model's `__init__` method. + config (`Union[PretrainedConfig, str, os.PathLike]`, *optional*): + Can be either: + + - an instance of a class derived from [`PretrainedConfig`], + - a string or path valid as input to [`~PretrainedConfig.from_pretrained`]. + + Configuration for the model to use instead of an automatically loaded configuration. Configuration can + be automatically loaded when: + + - The model is a model provided by the library (loaded with the *model id* string of a pretrained + model). + - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the + save directory. + - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a + configuration JSON file named *config.json* is found in the directory. + cache_dir (`Union[str, os.PathLike]`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + from_pt (`bool`, *optional*, defaults to `False`): + Load the model weights from a PyTorch checkpoint save file (see docstring of + `pretrained_model_name_or_path` argument). + ignore_mismatched_sizes (`bool`, *optional*, defaults to `False`): + Whether or not to raise an error if some of the weights from the checkpoint do not have the same size + as the weights of the model (if for instance, you are instantiating a model with 10 labels from a + checkpoint with 3 labels). + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download of the model weights and configuration files, overriding the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + local_files_only(`bool`, *optional*, defaults to `False`): + Whether or not to only look at local files (i.e., do not try to download the model). + use_auth_token (`str` or `bool`, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use + the token generated when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + + + + + To test a pull request you made on the Hub, you can pass `revision="refs/pr/". + + + + subfolder (`str`, *optional*, defaults to `""`): + In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can + specify the folder name here. + kwargs (remaining dictionary of keyword arguments, *optional*): + Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., + `output_attentions=True`). Behaves differently depending on whether a `config` is provided or + automatically loaded: + + - If a configuration is provided with `config`, `**kwargs` will be directly passed to the + underlying model's `__init__` method (we assume all relevant updates to the configuration have + already been done) + - If a configuration is not provided, `kwargs` will be first passed to the configuration class + initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that + corresponds to a configuration attribute will be used to override said attribute with the + supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute + will be passed to the underlying model's `__init__` function. + + Examples: + + ```python + >>> from transformers import BertConfig, FlaxBertModel + + >>> # Download model and configuration from huggingface.co and cache. + >>> model = FlaxBertModel.from_pretrained("bert-base-cased") + >>> # Model was saved using *save_pretrained('./test/saved_model/')* (for example purposes, not runnable). + >>> model = FlaxBertModel.from_pretrained("./test/saved_model/") + >>> # Loading from a PyTorch checkpoint file instead of a PyTorch model (slower, for example purposes, not runnable). + >>> config = BertConfig.from_json_file("./pt_model/config.json") + >>> model = FlaxBertModel.from_pretrained("./pt_model/pytorch_model.bin", from_pt=True, config=config) + ```""" + config = kwargs.pop("config", None) + cache_dir = kwargs.pop("cache_dir", None) + from_pt = kwargs.pop("from_pt", False) + ignore_mismatched_sizes = kwargs.pop("ignore_mismatched_sizes", False) + force_download = kwargs.pop("force_download", False) + resume_download = kwargs.pop("resume_download", False) + proxies = kwargs.pop("proxies", None) + local_files_only = kwargs.pop("local_files_only", False) + use_auth_token = kwargs.pop("use_auth_token", None) + revision = kwargs.pop("revision", None) + trust_remote_code = kwargs.pop("trust_remote_code", None) + from_pipeline = kwargs.pop("_from_pipeline", None) + from_auto_class = kwargs.pop("_from_auto", False) + _do_init = kwargs.pop("_do_init", True) + subfolder = kwargs.pop("subfolder", "") + commit_hash = kwargs.pop("_commit_hash", None) + + if trust_remote_code is True: + logger.warning( + "The argument `trust_remote_code` is to be used with Auto classes. It has no effect here and is" + " ignored." + ) + + user_agent = {"file_type": "model", "framework": "flax", "from_auto_class": from_auto_class} + if from_pipeline is not None: + user_agent["using_pipeline"] = from_pipeline + + if is_offline_mode() and not local_files_only: + logger.info("Offline mode: forcing local_files_only=True") + local_files_only = True + + # Load config if we don't provide a configuration + if not isinstance(config, PretrainedConfig): + config_path = config if config is not None else pretrained_model_name_or_path + config, model_kwargs = cls.config_class.from_pretrained( + config_path, + cache_dir=cache_dir, + return_unused_kwargs=True, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + local_files_only=local_files_only, + use_auth_token=use_auth_token, + revision=revision, + subfolder=subfolder, + _from_auto=from_auto_class, + _from_pipeline=from_pipeline, + _commit_hash=commit_hash, + **kwargs, + ) + else: + model_kwargs = kwargs.copy() + + if commit_hash is None: + commit_hash = getattr(config, "_commit_hash", None) + + # Add the dtype to model_kwargs + model_kwargs["dtype"] = dtype + + # This variable will flag if we're loading a sharded checkpoint. In this case the archive file is just the + # index of the files. + is_sharded = False + + # Load model + if pretrained_model_name_or_path is not None: + pretrained_model_name_or_path = str(pretrained_model_name_or_path) + is_local = os.path.isdir(pretrained_model_name_or_path) + if os.path.isdir(pretrained_model_name_or_path): + if from_pt and os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME)): + # Load from a PyTorch checkpoint + archive_file = os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME) + elif from_pt and os.path.isfile( + os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_INDEX_NAME) + ): + # Load from a sharded pytorch checkpoint + archive_file = os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_INDEX_NAME) + is_sharded = True + elif os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME)): + # Load from a Flax checkpoint + archive_file = os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_NAME) + elif os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_INDEX_NAME)): + # Load from a sharded Flax checkpoint + archive_file = os.path.join(pretrained_model_name_or_path, subfolder, FLAX_WEIGHTS_INDEX_NAME) + is_sharded = True + # At this stage we don't have a weight file so we will raise an error. + elif os.path.isfile(os.path.join(pretrained_model_name_or_path, subfolder, WEIGHTS_NAME)): + raise EnvironmentError( + f"Error no file named {FLAX_WEIGHTS_NAME} found in directory {pretrained_model_name_or_path} " + "but there is a file for PyTorch weights. Use `from_pt=True` to load this model from those " + "weights." + ) + else: + raise EnvironmentError( + f"Error no file named {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME} found in directory " + f"{pretrained_model_name_or_path}." + ) + elif os.path.isfile(os.path.join(subfolder, pretrained_model_name_or_path)): + archive_file = pretrained_model_name_or_path + is_local = True + elif is_remote_url(pretrained_model_name_or_path): + filename = pretrained_model_name_or_path + resolved_archive_file = download_url(pretrained_model_name_or_path) + else: + filename = WEIGHTS_NAME if from_pt else FLAX_WEIGHTS_NAME + try: + # Load from URL or cache if already cached + cached_file_kwargs = { + "cache_dir": cache_dir, + "force_download": force_download, + "proxies": proxies, + "resume_download": resume_download, + "local_files_only": local_files_only, + "use_auth_token": use_auth_token, + "user_agent": user_agent, + "revision": revision, + "subfolder": subfolder, + "_raise_exceptions_for_missing_entries": False, + "_commit_hash": commit_hash, + } + resolved_archive_file = cached_file(pretrained_model_name_or_path, filename, **cached_file_kwargs) + + # Since we set _raise_exceptions_for_missing_entries=False, we don't get an expection but a None + # result when internet is up, the repo and revision exist, but the file does not. + if resolved_archive_file is None and filename == FLAX_WEIGHTS_NAME: + # Maybe the checkpoint is sharded, we try to grab the index name in this case. + resolved_archive_file = cached_file( + pretrained_model_name_or_path, FLAX_WEIGHTS_INDEX_NAME, **cached_file_kwargs + ) + if resolved_archive_file is not None: + is_sharded = True + # Maybe the checkpoint is pytorch sharded, we try to grab the pytorch index name in this case. + elif resolved_archive_file is None and from_pt: + resolved_archive_file = cached_file( + pretrained_model_name_or_path, WEIGHTS_INDEX_NAME, **cached_file_kwargs + ) + if resolved_archive_file is not None: + is_sharded = True + if resolved_archive_file is None: + # Otherwise, maybe there is a TF or Flax model file. We try those to give a helpful error + # message. + has_file_kwargs = { + "revision": revision, + "proxies": proxies, + "use_auth_token": use_auth_token, + } + if has_file(pretrained_model_name_or_path, WEIGHTS_NAME, **has_file_kwargs): + raise EnvironmentError( + f"{pretrained_model_name_or_path} does not appear to have a file named" + f" {FLAX_WEIGHTS_NAME} but there is a file for PyTorch weights. Use `from_pt=True` to" + " load this model from those weights." + ) + elif has_file(pretrained_model_name_or_path, WEIGHTS_INDEX_NAME, **has_file_kwargs): + raise EnvironmentError( + f"{pretrained_model_name_or_path} does not appear to have a file named" + f" {FLAX_WEIGHTS_INDEX_NAME} but there is a sharded file for PyTorch weights. Use" + " `from_pt=True` to load this model from those weights." + ) + else: + raise EnvironmentError( + f"{pretrained_model_name_or_path} does not appear to have a file named" + f" {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME}." + ) + except EnvironmentError: + # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted + # to the original exception. + raise + except Exception: + # For any other exception, we throw a generic error. + raise EnvironmentError( + f"Can't load the model for '{pretrained_model_name_or_path}'. If you were trying to load it" + " from 'https://huggingface.co/models', make sure you don't have a local directory with the" + f" same name. Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a" + f" directory containing a file named {FLAX_WEIGHTS_NAME} or {WEIGHTS_NAME}." + ) + + if is_local: + logger.info(f"loading weights file {archive_file}") + resolved_archive_file = archive_file + else: + logger.info(f"loading weights file {filename} from cache at {resolved_archive_file}") + else: + resolved_archive_file = None + + # We'll need to download and cache each checkpoint shard if the checkpoint is sharded. + if is_sharded: + # resolved_archive_file becomes a list of files that point to the different checkpoint shards in this case. + resolved_archive_file, _ = get_checkpoint_shard_files( + pretrained_model_name_or_path, + resolved_archive_file, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + use_auth_token=use_auth_token, + user_agent=user_agent, + revision=revision, + subfolder=subfolder, + _commit_hash=commit_hash, + ) + + # init random models + model = cls(config, *model_args, _do_init=_do_init, **model_kwargs) + + if from_pt: + state = load_pytorch_checkpoint_in_flax_state_dict(model, resolved_archive_file, is_sharded) + else: + if is_sharded: + state = cls.load_flax_sharded_weights(resolved_archive_file) + else: + try: + with open(resolved_archive_file, "rb") as state_f: + state = from_bytes(cls, state_f.read()) + except (UnpicklingError, msgpack.exceptions.ExtraData) as e: + try: + with open(resolved_archive_file) as f: + if f.read().startswith("version"): + raise OSError( + "You seem to have cloned a repository without having git-lfs installed. Please" + " install git-lfs and run `git lfs install` followed by `git lfs pull` in the" + " folder you cloned." + ) + else: + raise ValueError from e + except (UnicodeDecodeError, ValueError): + raise EnvironmentError(f"Unable to convert {archive_file} to Flax deserializable object. ") + # make sure all arrays are stored as jnp.arrays + # NOTE: This is to prevent a bug this will be fixed in Flax >= v0.3.4: + # https://github.com/google/flax/issues/1261 + if _do_init: + state = jax.tree_util.tree_map(jnp.array, state) + else: + # keep the params on CPU if we don't want to initialize + state = jax.tree_util.tree_map(lambda x: jax.device_put(x, jax.devices("cpu")[0]), state) + + if "batch_stats" in state: # if flax model contains batch norm layers + # if model is base model only use model_prefix key + if ( + cls.base_model_prefix not in dict(model.params_shape_tree["params"]) + and cls.base_model_prefix in state["params"] + ): + state["params"] = state["params"][cls.base_model_prefix] + state["batch_stats"] = state["batch_stats"][cls.base_model_prefix] + + # if model is head model and we are loading weights from base model + # we initialize new params dict with base_model_prefix + if ( + cls.base_model_prefix in dict(model.params_shape_tree["params"]) + and cls.base_model_prefix not in state["params"] + ): + state = { + "params": {cls.base_model_prefix: state["params"]}, + "batch_stats": {cls.base_model_prefix: state["batch_stats"]}, + } + + else: + # if model is base model only use model_prefix key + if cls.base_model_prefix not in dict(model.params_shape_tree) and cls.base_model_prefix in state: + state = state[cls.base_model_prefix] + + # if model is head model and we are loading weights from base model + # we initialize new params dict with base_model_prefix + if cls.base_model_prefix in dict(model.params_shape_tree) and cls.base_model_prefix not in state: + state = {cls.base_model_prefix: state} + + # flatten dicts + state = flatten_dict(state) + + random_state = flatten_dict(unfreeze(model.params if _do_init else model.params_shape_tree)) + + missing_keys = model.required_params - set(state.keys()) + unexpected_keys = set(state.keys()) - model.required_params + + # Disabling warning when porting pytorch weights to flax, flax does not uses num_batches_tracked + for unexpected_key in unexpected_keys.copy(): + if "num_batches_tracked" in unexpected_key[-1]: + unexpected_keys.remove(unexpected_key) + + if missing_keys and not _do_init: + logger.warning( + f"The checkpoint {pretrained_model_name_or_path} is missing required keys: {missing_keys}. " + "Make sure to call model.init_weights to initialize the missing weights." + ) + cls._missing_keys = missing_keys + + # Mistmatched keys contains tuples key/shape1/shape2 of weights in the checkpoint that have a shape not + # matching the weights in the model. + mismatched_keys = [] + for key in state.keys(): + if key in random_state and state[key].shape != random_state[key].shape: + if ignore_mismatched_sizes: + mismatched_keys.append((key, state[key].shape, random_state[key].shape)) + state[key] = random_state[key] + else: + raise ValueError( + f"Trying to load the pretrained weight for {key} failed: checkpoint has shape " + f"{state[key].shape} which is incompatible with the model shape {random_state[key].shape}. " + "Using `ignore_mismatched_sizes=True` if you really want to load this checkpoint inside this " + "model." + ) + + # add missing keys as random parameters if we are initializing + if missing_keys and _do_init: + for missing_key in missing_keys: + state[missing_key] = random_state[missing_key] + + # remove unexpected keys to not be saved again + for unexpected_key in unexpected_keys: + del state[unexpected_key] + + if len(unexpected_keys) > 0: + logger.warning( + f"Some weights of the model checkpoint at {pretrained_model_name_or_path} were not used when" + f" initializing {model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are" + f" initializing {model.__class__.__name__} from the checkpoint of a model trained on another task or" + " with another architecture (e.g. initializing a BertForSequenceClassification model from a" + " BertForPreTraining model).\n- This IS NOT expected if you are initializing" + f" {model.__class__.__name__} from the checkpoint of a model that you expect to be exactly identical" + " (initializing a BertForSequenceClassification model from a BertForSequenceClassification model)." + ) + else: + logger.info(f"All model checkpoint weights were used when initializing {model.__class__.__name__}.\n") + + if len(missing_keys) > 0: + logger.warning( + f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at" + f" {pretrained_model_name_or_path} and are newly initialized: {missing_keys}\nYou should probably" + " TRAIN this model on a down-stream task to be able to use it for predictions and inference." + ) + elif len(mismatched_keys) == 0: + logger.info( + f"All the weights of {model.__class__.__name__} were initialized from the model checkpoint at" + f" {pretrained_model_name_or_path}.\nIf your task is similar to the task the model of the checkpoint" + f" was trained on, you can already use {model.__class__.__name__} for predictions without further" + " training." + ) + if len(mismatched_keys) > 0: + mismatched_warning = "\n".join( + [ + f"- {key}: found shape {shape1} in the checkpoint and {shape2} in the model instantiated" + for key, shape1, shape2 in mismatched_keys + ] + ) + logger.warning( + f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at" + f" {pretrained_model_name_or_path} and are newly initialized because the shapes did not" + f" match:\n{mismatched_warning}\nYou should probably TRAIN this model on a down-stream task to be able" + " to use it for predictions and inference." + ) + + # dictionary of key: dtypes for the model params + param_dtypes = jax.tree_util.tree_map(lambda x: x.dtype, state) + # extract keys of parameters not in jnp.float32 + fp16_params = [k for k in param_dtypes if param_dtypes[k] == jnp.float16] + bf16_params = [k for k in param_dtypes if param_dtypes[k] == jnp.bfloat16] + + # raise a warning if any of the parameters are not in jnp.float32 + if len(fp16_params) > 0: + logger.warning( + f"Some of the weights of {model.__class__.__name__} were initialized in float16 precision from " + f"the model checkpoint at {pretrained_model_name_or_path}:\n{fp16_params}\n" + "You should probably UPCAST the model weights to float32 if this was not intended. " + "See [`~FlaxPreTrainedModel.to_fp32`] for further information on how to do this." + ) + + if len(bf16_params) > 0: + logger.warning( + f"Some of the weights of {model.__class__.__name__} were initialized in bfloat16 precision from " + f"the model checkpoint at {pretrained_model_name_or_path}:\n{bf16_params}\n" + "You should probably UPCAST the model weights to float32 if this was not intended. " + "See [`~FlaxPreTrainedModel.to_fp32`] for further information on how to do this." + ) + + # If it is a model with generation capabilities, attempt to load the generation config + if model.can_generate(): + try: + model.generation_config = GenerationConfig.from_pretrained( + pretrained_model_name_or_path, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + local_files_only=local_files_only, + use_auth_token=use_auth_token, + revision=revision, + subfolder=subfolder, + _from_auto=from_auto_class, + _from_pipeline=from_pipeline, + **kwargs, + ) + except OSError: + logger.info( + "Generation config file not found, using a generation config created from the model config." + ) + pass + + if _do_init: + # set correct parameters + model.params = unflatten_dict(state) + return model + else: + return model, unflatten_dict(state) + + def save_pretrained( + self, save_directory: Union[str, os.PathLike], params=None, push_to_hub=False, max_shard_size="10GB", **kwargs + ): + """ + Save a model and its configuration file to a directory, so that it can be re-loaded using the + `[`~FlaxPreTrainedModel.from_pretrained`]` class method + + Arguments: + save_directory (`str` or `os.PathLike`): + Directory to which to save. Will be created if it doesn't exist. + push_to_hub (`bool`, *optional*, defaults to `False`): + Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the + repository you want to push to with `repo_id` (will default to the name of `save_directory` in your + namespace). + max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): + The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size + lower than this size. If expressed as a string, needs to be digits followed by a unit (like `"5MB"`). + + + + If a single weight of the model is bigger than `max_shard_size`, it will be in its own checkpoint shard + which will be bigger than `max_shard_size`. + + + + kwargs: + Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method. + """ + if os.path.isfile(save_directory): + logger.error(f"Provided path ({save_directory}) should be a directory, not a file") + return + + os.makedirs(save_directory, exist_ok=True) + + if push_to_hub: + commit_message = kwargs.pop("commit_message", None) + repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1]) + repo_id = self._create_repo(repo_id, **kwargs) + files_timestamps = self._get_files_timestamps(save_directory) + + # get abs dir + save_directory = os.path.abspath(save_directory) + # save config as well + self.config.architectures = [self.__class__.__name__[4:]] + + # If we have a custom model, we copy the file defining it in the folder and set the attributes so it can be + # loaded from the Hub. + if self._auto_class is not None: + custom_object_save(self, save_directory, config=self.config) + + self.config.save_pretrained(save_directory) + if self.can_generate(): + self.generation_config.save_pretrained(save_directory) + + # save model + output_model_file = os.path.join(save_directory, FLAX_WEIGHTS_NAME) + + shards, index = flax_shard_checkpoint(params if params is not None else self.params, max_shard_size) + # Clean the folder from a previous save + for filename in os.listdir(save_directory): + full_filename = os.path.join(save_directory, filename) + if ( + filename.startswith(FLAX_WEIGHTS_NAME[:-4]) + and os.path.isfile(full_filename) + and filename not in shards.keys() + ): + os.remove(full_filename) + + if index is None: + with open(output_model_file, "wb") as f: + params = params if params is not None else self.params + model_bytes = to_bytes(params) + f.write(model_bytes) + + else: + save_index_file = os.path.join(save_directory, FLAX_WEIGHTS_INDEX_NAME) + # Save the index as well + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + logger.info( + f"The model is bigger than the maximum size per checkpoint ({max_shard_size}) and is going to be " + f"split in {len(shards)} checkpoint shards. You can find where each parameters has been saved in the " + f"index located at {save_index_file}." + ) + for shard_file, shard in shards.items(): + # the shard item are unflattened, to save them we need to flatten them again + with open(os.path.join(save_directory, shard_file), mode="wb") as f: + params = unflatten_dict(shard, sep="/") + shard_bytes = to_bytes(params) + f.write(shard_bytes) + + logger.info(f"Model weights saved in {output_model_file}") + + if push_to_hub: + self._upload_modified_files( + save_directory, + repo_id, + files_timestamps, + commit_message=commit_message, + token=kwargs.get("use_auth_token"), + ) + + @classmethod + def register_for_auto_class(cls, auto_class="FlaxAutoModel"): + """ + Register this class with a given auto class. This should only be used for custom models as the ones in the + library are already mapped with an auto class. + + + + This API is experimental and may have some slight breaking changes in the next releases. + + + + Args: + auto_class (`str` or `type`, *optional*, defaults to `"FlaxAutoModel"`): + The auto class to register this new model with. + """ + if not isinstance(auto_class, str): + auto_class = auto_class.__name__ + + import transformers.models.auto as auto_module + + if not hasattr(auto_module, auto_class): + raise ValueError(f"{auto_class} is not a valid auto class.") + + cls._auto_class = auto_class + + +# To update the docstring, we need to copy the method, otherwise we change the original docstring. +FlaxPreTrainedModel.push_to_hub = copy_func(FlaxPreTrainedModel.push_to_hub) +if FlaxPreTrainedModel.push_to_hub.__doc__ is not None: + FlaxPreTrainedModel.push_to_hub.__doc__ = FlaxPreTrainedModel.push_to_hub.__doc__.format( + object="model", object_class="FlaxAutoModel", object_files="model checkpoint" + ) + + +def overwrite_call_docstring(model_class, docstring): + # copy __call__ function to be sure docstring is changed only for this function + model_class.__call__ = copy_func(model_class.__call__) + # delete existing docstring + model_class.__call__.__doc__ = None + # set correct docstring + model_class.__call__ = add_start_docstrings_to_model_forward(docstring)(model_class.__call__) + + +def append_call_sample_docstring(model_class, checkpoint, output_type, config_class, mask=None): + model_class.__call__ = copy_func(model_class.__call__) + model_class.__call__ = add_code_sample_docstrings( + checkpoint=checkpoint, + output_type=output_type, + config_class=config_class, + model_cls=model_class.__name__, + )(model_class.__call__) + + +def append_replace_return_docstrings(model_class, output_type, config_class): + model_class.__call__ = copy_func(model_class.__call__) + model_class.__call__ = replace_return_docstrings( + output_type=output_type, + config_class=config_class, + )(model_class.__call__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_tf_pytorch_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_tf_pytorch_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..3b1c030699b9f26be34013d281d61f286206c990 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/modeling_tf_pytorch_utils.py @@ -0,0 +1,578 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch - TF 2.0 general utilities.""" + + +import os +import re + +import numpy + +from .utils import ExplicitEnum, expand_dims, is_numpy_array, is_torch_tensor, logging, reshape, squeeze, tensor_size +from .utils import transpose as transpose_func + + +logger = logging.get_logger(__name__) + + +class TransposeType(ExplicitEnum): + """ + Possible ... + """ + + NO = "no" + SIMPLE = "simple" + CONV1D = "conv1d" + CONV2D = "conv2d" + + +def convert_tf_weight_name_to_pt_weight_name( + tf_name, start_prefix_to_remove="", tf_weight_shape=None, name_scope=None +): + """ + Convert a TF 2.0 model variable name in a pytorch model weight name. + + Conventions for TF2.0 scopes -> PyTorch attribute names conversions: + + - '$1___$2' is replaced by $2 (can be used to duplicate or remove layers in TF2.0 vs PyTorch) + - '_._' is replaced by a new level separation (can be used to convert TF2.0 lists in PyTorch nn.ModulesList) + + return tuple with: + + - pytorch model weight name + - transpose: `TransposeType` member indicating whether and how TF2.0 and PyTorch weights matrices should be + transposed with regards to each other + """ + if name_scope is not None: + if not tf_name.startswith(name_scope): + raise ValueError( + f"Weight name {tf_name} does not start with name_scope {name_scope}. This is an internal error " + "in Transformers, so (unless you were doing something really evil) please open an issue to report it!" + ) + tf_name = tf_name[len(name_scope) :] + tf_name = tf_name.lstrip("/") + tf_name = tf_name.replace(":0", "") # device ids + tf_name = re.sub( + r"/[^/]*___([^/]*)/", r"/\1/", tf_name + ) # '$1___$2' is replaced by $2 (can be used to duplicate or remove layers in TF2.0 vs PyTorch) + tf_name = tf_name.replace( + "_._", "/" + ) # '_._' is replaced by a level separation (can be used to convert TF2.0 lists in PyTorch nn.ModulesList) + tf_name = re.sub(r"//+", "/", tf_name) # Remove empty levels at the end + tf_name = tf_name.split("/") # Convert from TF2.0 '/' separators to PyTorch '.' separators + # Some weights have a single name without "/" such as final_logits_bias in BART + if len(tf_name) > 1: + tf_name = tf_name[1:] # Remove level zero + + tf_weight_shape = list(tf_weight_shape) + + # When should we transpose the weights + if tf_name[-1] == "kernel" and tf_weight_shape is not None and len(tf_weight_shape) == 4: + transpose = TransposeType.CONV2D + elif tf_name[-1] == "kernel" and tf_weight_shape is not None and len(tf_weight_shape) == 3: + transpose = TransposeType.CONV1D + elif bool( + tf_name[-1] in ["kernel", "pointwise_kernel", "depthwise_kernel"] + or "emb_projs" in tf_name + or "out_projs" in tf_name + ): + transpose = TransposeType.SIMPLE + else: + transpose = TransposeType.NO + + # Convert standard TF2.0 names in PyTorch names + if tf_name[-1] == "kernel" or tf_name[-1] == "embeddings" or tf_name[-1] == "gamma": + tf_name[-1] = "weight" + if tf_name[-1] == "beta": + tf_name[-1] = "bias" + + # The SeparableConv1D TF layer contains two weights that are translated to PyTorch Conv1D here + if tf_name[-1] == "pointwise_kernel" or tf_name[-1] == "depthwise_kernel": + tf_name[-1] = tf_name[-1].replace("_kernel", ".weight") + + # Remove prefix if needed + tf_name = ".".join(tf_name) + if start_prefix_to_remove: + tf_name = tf_name.replace(start_prefix_to_remove, "", 1) + + return tf_name, transpose + + +def apply_transpose(transpose: TransposeType, weight, match_shape=None, pt_to_tf=True): + """ + Apply a transpose to some weight then tries to reshape the weight to the same shape as a given shape, all in a + framework agnostic way. + """ + if transpose is TransposeType.CONV2D: + # Conv2D weight: + # PT: (num_out_channel, num_in_channel, kernel[0], kernel[1]) + # -> TF: (kernel[0], kernel[1], num_in_channel, num_out_channel) + axes = (2, 3, 1, 0) if pt_to_tf else (3, 2, 0, 1) + weight = transpose_func(weight, axes=axes) + elif transpose is TransposeType.CONV1D: + # Conv1D weight: + # PT: (num_out_channel, num_in_channel, kernel) + # -> TF: (kernel, num_in_channel, num_out_channel) + weight = transpose_func(weight, axes=(2, 1, 0)) + elif transpose is TransposeType.SIMPLE: + weight = transpose_func(weight) + + if match_shape is None: + return weight + + if len(match_shape) < len(weight.shape): + weight = squeeze(weight) + elif len(match_shape) > len(weight.shape): + weight = expand_dims(weight, axis=0) + + if list(match_shape) != list(weight.shape): + try: + weight = reshape(weight, match_shape) + except AssertionError as e: + e.args += (match_shape, match_shape) + raise e + + return weight + + +##################### +# PyTorch => TF 2.0 # +##################### + + +def load_pytorch_checkpoint_in_tf2_model( + tf_model, + pytorch_checkpoint_path, + tf_inputs=None, + allow_missing_keys=False, + output_loading_info=False, + _prefix=None, + tf_to_pt_weight_rename=None, +): + """Load pytorch checkpoints in a TF 2.0 model""" + try: + import tensorflow as tf # noqa: F401 + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a PyTorch model in TensorFlow, requires both PyTorch and TensorFlow to be installed. Please see " + "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + # Treats a single file as a collection of shards with 1 shard. + if isinstance(pytorch_checkpoint_path, str): + pytorch_checkpoint_path = [pytorch_checkpoint_path] + + # Loads all shards into a single state dictionary + pt_state_dict = {} + for path in pytorch_checkpoint_path: + pt_path = os.path.abspath(path) + logger.info(f"Loading PyTorch weights from {pt_path}") + pt_state_dict.update(torch.load(pt_path, map_location="cpu")) + + logger.info(f"PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()):,} parameters") + + return load_pytorch_weights_in_tf2_model( + tf_model, + pt_state_dict, + tf_inputs=tf_inputs, + allow_missing_keys=allow_missing_keys, + output_loading_info=output_loading_info, + _prefix=_prefix, + tf_to_pt_weight_rename=tf_to_pt_weight_rename, + ) + + +def load_pytorch_model_in_tf2_model(tf_model, pt_model, tf_inputs=None, allow_missing_keys=False): + """Load pytorch checkpoints in a TF 2.0 model""" + pt_state_dict = pt_model.state_dict() + + return load_pytorch_weights_in_tf2_model( + tf_model, pt_state_dict, tf_inputs=tf_inputs, allow_missing_keys=allow_missing_keys + ) + + +def load_pytorch_weights_in_tf2_model( + tf_model, + pt_state_dict, + tf_inputs=None, + allow_missing_keys=False, + output_loading_info=False, + _prefix=None, + tf_to_pt_weight_rename=None, +): + """Load pytorch state_dict in a TF 2.0 model.""" + try: + import tensorflow as tf # noqa: F401 + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a PyTorch model in TensorFlow, requires both PyTorch and TensorFlow to be installed. Please see " + "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + pt_state_dict = {k: v.numpy() for k, v in pt_state_dict.items()} + return load_pytorch_state_dict_in_tf2_model( + tf_model, + pt_state_dict, + tf_inputs=tf_inputs, + allow_missing_keys=allow_missing_keys, + output_loading_info=output_loading_info, + _prefix=_prefix, + tf_to_pt_weight_rename=tf_to_pt_weight_rename, + ) + + +def load_pytorch_state_dict_in_tf2_model( + tf_model, + pt_state_dict, + tf_inputs=None, + allow_missing_keys=False, + output_loading_info=False, + _prefix=None, + tf_to_pt_weight_rename=None, + ignore_mismatched_sizes=False, +): + """Load a pytorch state_dict in a TF 2.0 model.""" + import tensorflow as tf + from packaging.version import parse + + if parse(tf.__version__) >= parse("2.11.0"): + from keras import backend as K + else: + from tensorflow.python.keras import backend as K + + if tf_inputs is None: + tf_inputs = tf_model.dummy_inputs + + if _prefix is None: + _prefix = "" + if tf_inputs is not None: + with tf.name_scope(_prefix): + tf_model(tf_inputs, training=False) # Make sure model is built + # Adapt state dict - TODO remove this and update the AWS weights files instead + # Convert old format to new format if needed from a PyTorch state_dict + old_keys = [] + new_keys = [] + for key in pt_state_dict.keys(): + new_key = None + if "gamma" in key: + new_key = key.replace("gamma", "weight") + if "beta" in key: + new_key = key.replace("beta", "bias") + if "running_var" in key: + new_key = key.replace("running_var", "moving_variance") + if "running_mean" in key: + new_key = key.replace("running_mean", "moving_mean") + if new_key: + old_keys.append(key) + new_keys.append(new_key) + for old_key, new_key in zip(old_keys, new_keys): + pt_state_dict[new_key] = pt_state_dict.pop(old_key) + + # Matt: All TF models store the actual model stem in a MainLayer class, including the base model. + # In PT, the derived models (with heads) use the base model class as the stem instead, and the base model + # just contains the stem itself, and there is no MainLayer class. This means that TF base classes have one + # extra layer in their weight names, corresponding to the MainLayer class. This code block compensates for that. + start_prefix_to_remove = "" + if not any(s.startswith(tf_model.base_model_prefix) for s in pt_state_dict.keys()): + start_prefix_to_remove = tf_model.base_model_prefix + "." + + symbolic_weights = tf_model.trainable_weights + tf_model.non_trainable_weights + tf_loaded_numel = 0 + weight_value_tuples = [] + all_pytorch_weights = set(pt_state_dict.keys()) + missing_keys = [] + mismatched_keys = [] + for symbolic_weight in symbolic_weights: + sw_name = symbolic_weight.name + name, transpose = convert_tf_weight_name_to_pt_weight_name( + sw_name, + start_prefix_to_remove=start_prefix_to_remove, + tf_weight_shape=symbolic_weight.shape, + name_scope=_prefix, + ) + if tf_to_pt_weight_rename is not None: + name = tf_to_pt_weight_rename(name) + + # Find associated numpy array in pytorch model state dict + if name not in pt_state_dict: + if allow_missing_keys: + missing_keys.append(name) + continue + elif tf_model._keys_to_ignore_on_load_missing is not None: + # authorized missing keys don't have to be loaded + if any(re.search(pat, name) is not None for pat in tf_model._keys_to_ignore_on_load_missing): + continue + raise AttributeError(f"{name} not found in PyTorch model") + + try: + array = apply_transpose(transpose, pt_state_dict[name], symbolic_weight.shape) + except tf.errors.InvalidArgumentError as e: + if not ignore_mismatched_sizes: + error_msg = str(e) + error_msg += ( + "\n\tYou may consider adding `ignore_mismatched_sizes=True` in the model `from_pretrained` method." + ) + raise tf.errors.InvalidArgumentError(error_msg) + else: + mismatched_keys.append((name, pt_state_dict[name].shape, symbolic_weight.shape)) + continue + + tf_loaded_numel += tensor_size(array) + + weight_value_tuples.append((symbolic_weight, array)) + all_pytorch_weights.discard(name) + + K.batch_set_value(weight_value_tuples) + + if tf_inputs is not None: + tf_model(tf_inputs, training=False) # Make sure restore ops are run + + logger.info(f"Loaded {tf_loaded_numel:,} parameters in the TF 2.0 model.") + + unexpected_keys = list(all_pytorch_weights) + + if tf_model._keys_to_ignore_on_load_missing is not None: + for pat in tf_model._keys_to_ignore_on_load_missing: + missing_keys = [k for k in missing_keys if re.search(pat, k) is None] + if tf_model._keys_to_ignore_on_load_unexpected is not None: + for pat in tf_model._keys_to_ignore_on_load_unexpected: + unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None] + + if len(unexpected_keys) > 0: + logger.warning( + "Some weights of the PyTorch model were not used when initializing the TF 2.0 model" + f" {tf_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" + f" {tf_model.__class__.__name__} from a PyTorch model trained on another task or with another architecture" + " (e.g. initializing a TFBertForSequenceClassification model from a BertForPreTraining model).\n- This IS" + f" NOT expected if you are initializing {tf_model.__class__.__name__} from a PyTorch model that you expect" + " to be exactly identical (e.g. initializing a TFBertForSequenceClassification model from a" + " BertForSequenceClassification model)." + ) + else: + logger.warning(f"All PyTorch model weights were used when initializing {tf_model.__class__.__name__}.\n") + if len(missing_keys) > 0: + logger.warning( + f"Some weights or buffers of the TF 2.0 model {tf_model.__class__.__name__} were not initialized from the" + f" PyTorch model and are newly initialized: {missing_keys}\nYou should probably TRAIN this model on a" + " down-stream task to be able to use it for predictions and inference." + ) + else: + logger.warning( + f"All the weights of {tf_model.__class__.__name__} were initialized from the PyTorch model.\n" + "If your task is similar to the task the model of the checkpoint was trained on, " + f"you can already use {tf_model.__class__.__name__} for predictions without further training." + ) + + if len(mismatched_keys) > 0: + mismatched_warning = "\n".join( + [ + f"- {key}: found shape {shape1} in the checkpoint and {shape2} in the model instantiated" + for key, shape1, shape2 in mismatched_keys + ] + ) + logger.warning( + f"Some weights of {tf_model.__class__.__name__} were not initialized from the model checkpoint" + f" are newly initialized because the shapes did not" + f" match:\n{mismatched_warning}\nYou should probably TRAIN this model on a down-stream task to be able" + " to use it for predictions and inference." + ) + + if output_loading_info: + loading_info = { + "missing_keys": missing_keys, + "unexpected_keys": unexpected_keys, + "mismatched_keys": mismatched_keys, + } + return tf_model, loading_info + + return tf_model + + +##################### +# TF 2.0 => PyTorch # +##################### + + +def load_tf2_checkpoint_in_pytorch_model( + pt_model, tf_checkpoint_path, tf_inputs=None, allow_missing_keys=False, output_loading_info=False +): + """ + Load TF 2.0 HDF5 checkpoint in a PyTorch model We use HDF5 to easily do transfer learning (see + https://github.com/tensorflow/tensorflow/blob/ee16fcac960ae660e0e4496658a366e2f745e1f0/tensorflow/python/keras/engine/network.py#L1352-L1357). + """ + try: + import tensorflow as tf # noqa: F401 + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed. Please see " + "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + import transformers + + from .modeling_tf_utils import load_tf_weights + + logger.info(f"Loading TensorFlow weights from {tf_checkpoint_path}") + + # Instantiate and load the associated TF 2.0 model + tf_model_class_name = "TF" + pt_model.__class__.__name__ # Add "TF" at the beginning + tf_model_class = getattr(transformers, tf_model_class_name) + tf_model = tf_model_class(pt_model.config) + + if tf_inputs is None: + tf_inputs = tf_model.dummy_inputs + + if tf_inputs is not None: + tf_model(tf_inputs, training=False) # Make sure model is built + + load_tf_weights(tf_model, tf_checkpoint_path) + + return load_tf2_model_in_pytorch_model( + pt_model, tf_model, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info + ) + + +def load_tf2_model_in_pytorch_model(pt_model, tf_model, allow_missing_keys=False, output_loading_info=False): + """Load TF 2.0 model in a pytorch model""" + weights = tf_model.weights + + return load_tf2_weights_in_pytorch_model( + pt_model, weights, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info + ) + + +def load_tf2_weights_in_pytorch_model(pt_model, tf_weights, allow_missing_keys=False, output_loading_info=False): + """Load TF2.0 symbolic weights in a PyTorch model""" + try: + import tensorflow as tf # noqa: F401 + import torch # noqa: F401 + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed. Please see " + "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions." + ) + raise + + tf_state_dict = {tf_weight.name: tf_weight.numpy() for tf_weight in tf_weights} + return load_tf2_state_dict_in_pytorch_model( + pt_model, tf_state_dict, allow_missing_keys=allow_missing_keys, output_loading_info=output_loading_info + ) + + +def load_tf2_state_dict_in_pytorch_model(pt_model, tf_state_dict, allow_missing_keys=False, output_loading_info=False): + import torch + + new_pt_params_dict = {} + current_pt_params_dict = dict(pt_model.named_parameters()) + + # Make sure we are able to load PyTorch base models as well as derived models (with heads) + # TF models always have a prefix, some of PyTorch models (base ones) don't + start_prefix_to_remove = "" + if not any(s.startswith(pt_model.base_model_prefix) for s in current_pt_params_dict.keys()): + start_prefix_to_remove = pt_model.base_model_prefix + "." + + # Build a map from potential PyTorch weight names to TF 2.0 Variables + tf_weights_map = {} + for name, tf_weight in tf_state_dict.items(): + pt_name, transpose = convert_tf_weight_name_to_pt_weight_name( + name, start_prefix_to_remove=start_prefix_to_remove, tf_weight_shape=tf_weight.shape + ) + tf_weights_map[pt_name] = (tf_weight, transpose) + + all_tf_weights = set(tf_weights_map.keys()) + loaded_pt_weights_data_ptr = {} + missing_keys_pt = [] + for pt_weight_name, pt_weight in current_pt_params_dict.items(): + # Handle PyTorch shared weight ()not duplicated in TF 2.0 + if pt_weight.data_ptr() in loaded_pt_weights_data_ptr: + new_pt_params_dict[pt_weight_name] = loaded_pt_weights_data_ptr[pt_weight.data_ptr()] + continue + + # Find associated numpy array in pytorch model state dict + if pt_weight_name not in tf_weights_map: + if allow_missing_keys: + missing_keys_pt.append(pt_weight_name) + continue + + raise AttributeError(f"{pt_weight_name} not found in TF 2.0 model") + + array, transpose = tf_weights_map[pt_weight_name] + + array = apply_transpose(transpose, array, pt_weight.shape, pt_to_tf=False) + + if numpy.isscalar(array): + array = numpy.array(array) + if not is_torch_tensor(array) and not is_numpy_array(array): + array = array.numpy() + if is_numpy_array(array): + # Convert to torch tensor + array = torch.from_numpy(array) + + new_pt_params_dict[pt_weight_name] = array + loaded_pt_weights_data_ptr[pt_weight.data_ptr()] = array + all_tf_weights.discard(pt_weight_name) + + missing_keys, unexpected_keys = pt_model.load_state_dict(new_pt_params_dict, strict=False) + missing_keys += missing_keys_pt + + # Some models may have keys that are not in the state by design, removing them before needlessly warning + # the user. + if pt_model._keys_to_ignore_on_load_missing is not None: + for pat in pt_model._keys_to_ignore_on_load_missing: + missing_keys = [k for k in missing_keys if re.search(pat, k) is None] + + if pt_model._keys_to_ignore_on_load_unexpected is not None: + for pat in pt_model._keys_to_ignore_on_load_unexpected: + unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None] + + if len(unexpected_keys) > 0: + logger.warning( + "Some weights of the TF 2.0 model were not used when initializing the PyTorch model" + f" {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing" + f" {pt_model.__class__.__name__} from a TF 2.0 model trained on another task or with another architecture" + " (e.g. initializing a BertForSequenceClassification model from a TFBertForPreTraining model).\n- This IS" + f" NOT expected if you are initializing {pt_model.__class__.__name__} from a TF 2.0 model that you expect" + " to be exactly identical (e.g. initializing a BertForSequenceClassification model from a" + " TFBertForSequenceClassification model)." + ) + else: + logger.warning(f"All TF 2.0 model weights were used when initializing {pt_model.__class__.__name__}.\n") + if len(missing_keys) > 0: + logger.warning( + f"Some weights of {pt_model.__class__.__name__} were not initialized from the TF 2.0 model and are newly" + f" initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to" + " use it for predictions and inference." + ) + else: + logger.warning( + f"All the weights of {pt_model.__class__.__name__} were initialized from the TF 2.0 model.\n" + "If your task is similar to the task the model of the checkpoint was trained on, " + f"you can already use {pt_model.__class__.__name__} for predictions without further training." + ) + + logger.info(f"Weights or buffers not loaded from TF 2.0 model: {all_tf_weights}") + + if output_loading_info: + loading_info = {"missing_keys": missing_keys, "unexpected_keys": unexpected_keys} + return pt_model, loading_info + + return pt_model diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..168c68db837d08817e08e493efa81e7419ab9de9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/__init__.py @@ -0,0 +1,179 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_sentencepiece_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_albert": ["ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP", "AlbertConfig", "AlbertOnnxConfig"], +} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_albert"] = ["AlbertTokenizer"] + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_albert_fast"] = ["AlbertTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_albert"] = [ + "ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST", + "AlbertForMaskedLM", + "AlbertForMultipleChoice", + "AlbertForPreTraining", + "AlbertForQuestionAnswering", + "AlbertForSequenceClassification", + "AlbertForTokenClassification", + "AlbertModel", + "AlbertPreTrainedModel", + "load_tf_weights_in_albert", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_albert"] = [ + "TF_ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFAlbertForMaskedLM", + "TFAlbertForMultipleChoice", + "TFAlbertForPreTraining", + "TFAlbertForQuestionAnswering", + "TFAlbertForSequenceClassification", + "TFAlbertForTokenClassification", + "TFAlbertMainLayer", + "TFAlbertModel", + "TFAlbertPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_albert"] = [ + "FlaxAlbertForMaskedLM", + "FlaxAlbertForMultipleChoice", + "FlaxAlbertForPreTraining", + "FlaxAlbertForQuestionAnswering", + "FlaxAlbertForSequenceClassification", + "FlaxAlbertForTokenClassification", + "FlaxAlbertModel", + "FlaxAlbertPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_albert import ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, AlbertConfig, AlbertOnnxConfig + + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_albert import AlbertTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_albert_fast import AlbertTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_albert import ( + ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + AlbertForMaskedLM, + AlbertForMultipleChoice, + AlbertForPreTraining, + AlbertForQuestionAnswering, + AlbertForSequenceClassification, + AlbertForTokenClassification, + AlbertModel, + AlbertPreTrainedModel, + load_tf_weights_in_albert, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_albert import ( + TF_ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + TFAlbertForMaskedLM, + TFAlbertForMultipleChoice, + TFAlbertForPreTraining, + TFAlbertForQuestionAnswering, + TFAlbertForSequenceClassification, + TFAlbertForTokenClassification, + TFAlbertMainLayer, + TFAlbertModel, + TFAlbertPreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_albert import ( + FlaxAlbertForMaskedLM, + FlaxAlbertForMultipleChoice, + FlaxAlbertForPreTraining, + FlaxAlbertForQuestionAnswering, + FlaxAlbertForSequenceClassification, + FlaxAlbertForTokenClassification, + FlaxAlbertModel, + FlaxAlbertPreTrainedModel, + ) +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/configuration_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/configuration_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..fd0c623887925790b8c84cf92b86234f8ebf8c49 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/configuration_albert.py @@ -0,0 +1,172 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" ALBERT model configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig + + +ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "albert-base-v1": "https://huggingface.co/albert-base-v1/resolve/main/config.json", + "albert-large-v1": "https://huggingface.co/albert-large-v1/resolve/main/config.json", + "albert-xlarge-v1": "https://huggingface.co/albert-xlarge-v1/resolve/main/config.json", + "albert-xxlarge-v1": "https://huggingface.co/albert-xxlarge-v1/resolve/main/config.json", + "albert-base-v2": "https://huggingface.co/albert-base-v2/resolve/main/config.json", + "albert-large-v2": "https://huggingface.co/albert-large-v2/resolve/main/config.json", + "albert-xlarge-v2": "https://huggingface.co/albert-xlarge-v2/resolve/main/config.json", + "albert-xxlarge-v2": "https://huggingface.co/albert-xxlarge-v2/resolve/main/config.json", +} + + +class AlbertConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AlbertModel`] or a [`TFAlbertModel`]. It is used + to instantiate an ALBERT model according to the specified arguments, defining the model architecture. Instantiating + a configuration with the defaults will yield a similar configuration to that of the ALBERT + [albert-xxlarge-v2](https://huggingface.co/albert-xxlarge-v2) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vocab_size (`int`, *optional*, defaults to 30000): + Vocabulary size of the ALBERT model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`AlbertModel`] or [`TFAlbertModel`]. + embedding_size (`int`, *optional*, defaults to 128): + Dimensionality of vocabulary embeddings. + hidden_size (`int`, *optional*, defaults to 4096): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_hidden_groups (`int`, *optional*, defaults to 1): + Number of groups for the hidden layers, parameters in the same group are shared. + num_attention_heads (`int`, *optional*, defaults to 64): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 16384): + The dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + inner_group_num (`int`, *optional*, defaults to 1): + The number of inner repetition of attention and ffn. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu_new"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`AlbertModel`] or [`TFAlbertModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + classifier_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for attached classifiers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + + Examples: + + ```python + >>> from transformers import AlbertConfig, AlbertModel + + >>> # Initializing an ALBERT-xxlarge style configuration + >>> albert_xxlarge_configuration = AlbertConfig() + + >>> # Initializing an ALBERT-base style configuration + >>> albert_base_configuration = AlbertConfig( + ... hidden_size=768, + ... num_attention_heads=12, + ... intermediate_size=3072, + ... ) + + >>> # Initializing a model (with random weights) from the ALBERT-base style configuration + >>> model = AlbertModel(albert_xxlarge_configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "albert" + + def __init__( + self, + vocab_size=30000, + embedding_size=128, + hidden_size=4096, + num_hidden_layers=12, + num_hidden_groups=1, + num_attention_heads=64, + intermediate_size=16384, + inner_group_num=1, + hidden_act="gelu_new", + hidden_dropout_prob=0, + attention_probs_dropout_prob=0, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + classifier_dropout_prob=0.1, + position_embedding_type="absolute", + pad_token_id=0, + bos_token_id=2, + eos_token_id=3, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.embedding_size = embedding_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_hidden_groups = num_hidden_groups + self.num_attention_heads = num_attention_heads + self.inner_group_num = inner_group_num + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.classifier_dropout_prob = classifier_dropout_prob + self.position_embedding_type = position_embedding_type + + +# Copied from transformers.models.bert.configuration_bert.BertOnnxConfig with Roberta->Albert +class AlbertOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ("token_type_ids", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..eecada8b432a2def95f71b1c613839647fc0ca6f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py @@ -0,0 +1,63 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert ALBERT checkpoint.""" + + +import argparse + +import torch + +from ...utils import logging +from . import AlbertConfig, AlbertForPreTraining, load_tf_weights_in_albert + + +logging.set_verbosity_info() + + +def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, albert_config_file, pytorch_dump_path): + # Initialise PyTorch model + config = AlbertConfig.from_json_file(albert_config_file) + print(f"Building PyTorch model from configuration: {config}") + model = AlbertForPreTraining(config) + + # Load weights from tf checkpoint + load_tf_weights_in_albert(model, config, tf_checkpoint_path) + + # Save pytorch-model + print(f"Save PyTorch model to {pytorch_dump_path}") + torch.save(model.state_dict(), pytorch_dump_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path." + ) + parser.add_argument( + "--albert_config_file", + default=None, + type=str, + required=True, + help=( + "The config json file corresponding to the pre-trained ALBERT model. \n" + "This specifies the model architecture." + ), + ) + parser.add_argument( + "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + args = parser.parse_args() + convert_tf_checkpoint_to_pytorch(args.tf_checkpoint_path, args.albert_config_file, args.pytorch_dump_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..687a927ef0c486f0bc2607d16f93872dfe03f804 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_albert.py @@ -0,0 +1,1403 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTorch ALBERT model.""" + +import math +import os +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple, Union + +import torch +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPooling, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_albert import AlbertConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "albert-base-v2" +_CONFIG_FOR_DOC = "AlbertConfig" + + +ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "albert-base-v1", + "albert-large-v1", + "albert-xlarge-v1", + "albert-xxlarge-v1", + "albert-base-v2", + "albert-large-v2", + "albert-xlarge-v2", + "albert-xxlarge-v2", + # See all ALBERT models at https://huggingface.co/models?filter=albert +] + + +def load_tf_weights_in_albert(model, config, tf_checkpoint_path): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + + for name, array in zip(names, arrays): + print(name) + + for name, array in zip(names, arrays): + original_name = name + + # If saved from the TF HUB module + name = name.replace("module/", "") + + # Renaming and simplifying + name = name.replace("ffn_1", "ffn") + name = name.replace("bert/", "albert/") + name = name.replace("attention_1", "attention") + name = name.replace("transform/", "") + name = name.replace("LayerNorm_1", "full_layer_layer_norm") + name = name.replace("LayerNorm", "attention/LayerNorm") + name = name.replace("transformer/", "") + + # The feed forward layer had an 'intermediate' step which has been abstracted away + name = name.replace("intermediate/dense/", "") + name = name.replace("ffn/intermediate/output/dense/", "ffn_output/") + + # ALBERT attention was split between self and output which have been abstracted away + name = name.replace("/output/", "/") + name = name.replace("/self/", "/") + + # The pooler is a linear layer + name = name.replace("pooler/dense", "pooler") + + # The classifier was simplified to predictions from cls/predictions + name = name.replace("cls/predictions", "predictions") + name = name.replace("predictions/attention", "predictions") + + # Naming was changed to be more explicit + name = name.replace("embeddings/attention", "embeddings") + name = name.replace("inner_group_", "albert_layers/") + name = name.replace("group_", "albert_layer_groups/") + + # Classifier + if len(name.split("/")) == 1 and ("output_bias" in name or "output_weights" in name): + name = "classifier/" + name + + # No ALBERT model currently handles the next sentence prediction task + if "seq_relationship" in name: + name = name.replace("seq_relationship/output_", "sop_classifier/classifier/") + name = name.replace("weights", "weight") + + name = name.split("/") + + # Ignore the gradients applied by the LAMB/ADAM optimizers. + if ( + "adam_m" in name + or "adam_v" in name + or "AdamWeightDecayOptimizer" in name + or "AdamWeightDecayOptimizer_1" in name + or "global_step" in name + ): + logger.info(f"Skipping {'/'.join(name)}") + continue + + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + try: + pointer = getattr(pointer, scope_names[0]) + except AttributeError: + logger.info(f"Skipping {'/'.join(name)}") + continue + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + + if m_name[-11:] == "_embeddings": + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + print(f"Initialize PyTorch weight {name} from {original_name}") + pointer.data = torch.from_numpy(array) + + return model + + +class AlbertEmbeddings(nn.Module): + """ + Construct the embeddings from word, position and token_type embeddings. + """ + + def __init__(self, config: AlbertConfig): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.embedding_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.forward + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + +class AlbertAttention(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads}" + ) + + self.num_attention_heads = config.num_attention_heads + self.hidden_size = config.hidden_size + self.attention_head_size = config.hidden_size // config.num_attention_heads + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.attention_dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.output_dropout = nn.Dropout(config.hidden_dropout_prob) + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.pruned_heads = set() + + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + # Copied from transformers.models.bert.modeling_bert.BertSelfAttention.transpose_for_scores + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def prune_heads(self, heads: List[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.num_attention_heads, self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.query = prune_linear_layer(self.query, index) + self.key = prune_linear_layer(self.key, index) + self.value = prune_linear_layer(self.value, index) + self.dense = prune_linear_layer(self.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.num_attention_heads = self.num_attention_heads - len(heads) + self.all_head_size = self.attention_head_size * self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor], Tuple[torch.Tensor, torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + mixed_key_layer = self.key(hidden_states) + mixed_value_layer = self.value(hidden_states) + + query_layer = self.transpose_for_scores(mixed_query_layer) + key_layer = self.transpose_for_scores(mixed_key_layer) + value_layer = self.transpose_for_scores(mixed_value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in BertModel forward() function) + attention_scores = attention_scores + attention_mask + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + seq_length = hidden_states.size()[1] + position_ids_l = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.attention_dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + context_layer = context_layer.transpose(2, 1).flatten(2) + + projected_context_layer = self.dense(context_layer) + projected_context_layer_dropout = self.output_dropout(projected_context_layer) + layernormed_context_layer = self.LayerNorm(hidden_states + projected_context_layer_dropout) + return (layernormed_context_layer, attention_probs) if output_attentions else (layernormed_context_layer,) + + +class AlbertLayer(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + + self.config = config + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.full_layer_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.attention = AlbertAttention(config) + self.ffn = nn.Linear(config.hidden_size, config.intermediate_size) + self.ffn_output = nn.Linear(config.intermediate_size, config.hidden_size) + self.activation = ACT2FN[config.hidden_act] + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + ) -> Tuple[torch.Tensor, torch.Tensor]: + attention_output = self.attention(hidden_states, attention_mask, head_mask, output_attentions) + + ffn_output = apply_chunking_to_forward( + self.ff_chunk, + self.chunk_size_feed_forward, + self.seq_len_dim, + attention_output[0], + ) + hidden_states = self.full_layer_layer_norm(ffn_output + attention_output[0]) + + return (hidden_states,) + attention_output[1:] # add attentions if we output them + + def ff_chunk(self, attention_output: torch.Tensor) -> torch.Tensor: + ffn_output = self.ffn(attention_output) + ffn_output = self.activation(ffn_output) + ffn_output = self.ffn_output(ffn_output) + return ffn_output + + +class AlbertLayerGroup(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + + self.albert_layers = nn.ModuleList([AlbertLayer(config) for _ in range(config.inner_group_num)]) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + ) -> Tuple[Union[torch.Tensor, Tuple[torch.Tensor]], ...]: + layer_hidden_states = () + layer_attentions = () + + for layer_index, albert_layer in enumerate(self.albert_layers): + layer_output = albert_layer(hidden_states, attention_mask, head_mask[layer_index], output_attentions) + hidden_states = layer_output[0] + + if output_attentions: + layer_attentions = layer_attentions + (layer_output[1],) + + if output_hidden_states: + layer_hidden_states = layer_hidden_states + (hidden_states,) + + outputs = (hidden_states,) + if output_hidden_states: + outputs = outputs + (layer_hidden_states,) + if output_attentions: + outputs = outputs + (layer_attentions,) + return outputs # last-layer hidden state, (layer hidden states), (layer attentions) + + +class AlbertTransformer(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + + self.config = config + self.embedding_hidden_mapping_in = nn.Linear(config.embedding_size, config.hidden_size) + self.albert_layer_groups = nn.ModuleList([AlbertLayerGroup(config) for _ in range(config.num_hidden_groups)]) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[BaseModelOutput, Tuple]: + hidden_states = self.embedding_hidden_mapping_in(hidden_states) + + all_hidden_states = (hidden_states,) if output_hidden_states else None + all_attentions = () if output_attentions else None + + head_mask = [None] * self.config.num_hidden_layers if head_mask is None else head_mask + + for i in range(self.config.num_hidden_layers): + # Number of layers in a hidden group + layers_per_group = int(self.config.num_hidden_layers / self.config.num_hidden_groups) + + # Index of the hidden group + group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups)) + + layer_group_output = self.albert_layer_groups[group_idx]( + hidden_states, + attention_mask, + head_mask[group_idx * layers_per_group : (group_idx + 1) * layers_per_group], + output_attentions, + output_hidden_states, + ) + hidden_states = layer_group_output[0] + + if output_attentions: + all_attentions = all_attentions + layer_group_output[-1] + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class AlbertPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = AlbertConfig + load_tf_weights = load_tf_weights_in_albert + base_model_prefix = "albert" + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +@dataclass +class AlbertForPreTrainingOutput(ModelOutput): + """ + Output type of [`AlbertForPreTraining`]. + + Args: + loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`): + Total loss as the sum of the masked language modeling loss and the next sequence prediction + (classification) loss. + prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + sop_logits (`torch.FloatTensor` of shape `(batch_size, 2)`): + Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation + before SoftMax). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + prediction_logits: torch.FloatTensor = None + sop_logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +ALBERT_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Args: + config ([`AlbertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +ALBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and + [`PreTrainedTokenizer.encode`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare ALBERT Model transformer outputting raw hidden-states without any specific head on top.", + ALBERT_START_DOCSTRING, +) +class AlbertModel(AlbertPreTrainedModel): + config_class = AlbertConfig + base_model_prefix = "albert" + + def __init__(self, config: AlbertConfig, add_pooling_layer: bool = True): + super().__init__(config) + + self.config = config + self.embeddings = AlbertEmbeddings(config) + self.encoder = AlbertTransformer(config) + if add_pooling_layer: + self.pooler = nn.Linear(config.hidden_size, config.hidden_size) + self.pooler_activation = nn.Tanh() + else: + self.pooler = None + self.pooler_activation = None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Embedding: + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value: nn.Embedding) -> None: + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} ALBERT has + a different architecture in that its layers are shared across groups, which then has inner groups. If an ALBERT + model has 12 hidden layers and 2 hidden groups, with two inner groups, there is a total of 4 different layers. + + These layers are flattened: the indices [0,1] correspond to the two inner groups of the first hidden layer, + while [2,3] correspond to the two inner groups of the second hidden layer. + + Any layer with in index other than [0,1,2,3] will result in an error. See base class PreTrainedModel for more + information about head pruning + """ + for layer, heads in heads_to_prune.items(): + group_idx = int(layer / self.config.inner_group_num) + inner_group_idx = int(layer - group_idx * self.config.inner_group_num) + self.encoder.albert_layer_groups[group_idx].albert_layers[inner_group_idx].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + output_attentions: Optional[None] = None, + output_hidden_states: Optional[None] = None, + return_dict: Optional[None] = None, + ) -> Union[BaseModelOutputWithPooling, Tuple]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2) + extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility + extended_attention_mask = (1.0 - extended_attention_mask) * torch.finfo(self.dtype).min + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds + ) + encoder_outputs = self.encoder( + embedding_output, + extended_attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = encoder_outputs[0] + + pooled_output = self.pooler_activation(self.pooler(sequence_output[:, 0])) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a + `sentence order prediction (classification)` head. + """, + ALBERT_START_DOCSTRING, +) +class AlbertForPreTraining(AlbertPreTrainedModel): + _keys_to_ignore_on_load_missing = [ + "predictions.decoder.weight", + "predictions.decoder.bias", + "embeddings.position_ids", + ] + + def __init__(self, config: AlbertConfig): + super().__init__(config) + + self.albert = AlbertModel(config) + self.predictions = AlbertMLMHead(config) + self.sop_classifier = AlbertSOPHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self) -> nn.Linear: + return self.predictions.decoder + + def set_output_embeddings(self, new_embeddings: nn.Linear) -> None: + self.predictions.decoder = new_embeddings + + def get_input_embeddings(self) -> nn.Embedding: + return self.albert.embeddings.word_embeddings + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=AlbertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + sentence_order_label: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[AlbertForPreTrainingOutput, Tuple]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + sentence_order_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair + (see `input_ids` docstring) Indices should be in `[0, 1]`. `0` indicates original order (sequence A, then + sequence B), `1` indicates switched order (sequence B, then sequence A). + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, AlbertForPreTraining + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("albert-base-v2") + >>> model = AlbertForPreTraining.from_pretrained("albert-base-v2") + + >>> input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) + >>> # Batch size 1 + >>> outputs = model(input_ids) + + >>> prediction_logits = outputs.prediction_logits + >>> sop_logits = outputs.sop_logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.albert( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output, pooled_output = outputs[:2] + + prediction_scores = self.predictions(sequence_output) + sop_scores = self.sop_classifier(pooled_output) + + total_loss = None + if labels is not None and sentence_order_label is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + sentence_order_loss = loss_fct(sop_scores.view(-1, 2), sentence_order_label.view(-1)) + total_loss = masked_lm_loss + sentence_order_loss + + if not return_dict: + output = (prediction_scores, sop_scores) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return AlbertForPreTrainingOutput( + loss=total_loss, + prediction_logits=prediction_scores, + sop_logits=sop_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class AlbertMLMHead(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + + self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.dense = nn.Linear(config.hidden_size, config.embedding_size) + self.decoder = nn.Linear(config.embedding_size, config.vocab_size) + self.activation = ACT2FN[config.hidden_act] + self.decoder.bias = self.bias + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.activation(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + hidden_states = self.decoder(hidden_states) + + prediction_scores = hidden_states + + return prediction_scores + + def _tie_weights(self) -> None: + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + self.bias = self.decoder.bias + + +class AlbertSOPHead(nn.Module): + def __init__(self, config: AlbertConfig): + super().__init__() + + self.dropout = nn.Dropout(config.classifier_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, pooled_output: torch.Tensor) -> torch.Tensor: + dropout_pooled_output = self.dropout(pooled_output) + logits = self.classifier(dropout_pooled_output) + return logits + + +@add_start_docstrings( + "Albert Model with a `language modeling` head on top.", + ALBERT_START_DOCSTRING, +) +class AlbertForMaskedLM(AlbertPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [ + "predictions.decoder.weight", + "predictions.decoder.bias", + "embeddings.position_ids", + ] + + def __init__(self, config): + super().__init__(config) + + self.albert = AlbertModel(config, add_pooling_layer=False) + self.predictions = AlbertMLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self) -> nn.Linear: + return self.predictions.decoder + + def set_output_embeddings(self, new_embeddings: nn.Linear) -> None: + self.predictions.decoder = new_embeddings + + def get_input_embeddings(self) -> nn.Embedding: + return self.albert.embeddings.word_embeddings + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=MaskedLMOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[MaskedLMOutput, Tuple]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Returns: + + Example: + + ```python + >>> import torch + >>> from transformers import AutoTokenizer, AlbertForMaskedLM + + >>> tokenizer = AutoTokenizer.from_pretrained("albert-base-v2") + >>> model = AlbertForMaskedLM.from_pretrained("albert-base-v2") + + >>> # add mask_token + >>> inputs = tokenizer("The capital of [MASK] is Paris.", return_tensors="pt") + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> # retrieve index of [MASK] + >>> mask_token_index = (inputs.input_ids == tokenizer.mask_token_id)[0].nonzero(as_tuple=True)[0] + >>> predicted_token_id = logits[0, mask_token_index].argmax(axis=-1) + >>> tokenizer.decode(predicted_token_id) + 'france' + ``` + + ```python + >>> labels = tokenizer("The capital of France is Paris.", return_tensors="pt")["input_ids"] + >>> labels = torch.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) + >>> outputs = model(**inputs, labels=labels) + >>> round(outputs.loss.item(), 2) + 0.81 + ``` + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_outputs = outputs[0] + + prediction_scores = self.predictions(sequence_outputs) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled + output) e.g. for GLUE tasks. + """, + ALBERT_START_DOCSTRING, +) +class AlbertForSequenceClassification(AlbertPreTrainedModel): + def __init__(self, config: AlbertConfig): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.albert = AlbertModel(config) + self.dropout = nn.Dropout(config.classifier_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, self.config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="textattack/albert-base-v2-imdb", + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="'LABEL_1'", + expected_loss=0.12, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[SequenceClassifierOutput, Tuple]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + ALBERT_START_DOCSTRING, +) +class AlbertForTokenClassification(AlbertPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config: AlbertConfig): + super().__init__(config) + self.num_labels = config.num_labels + + self.albert = AlbertModel(config, add_pooling_layer=False) + classifier_dropout_prob = ( + config.classifier_dropout_prob + if config.classifier_dropout_prob is not None + else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, self.config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[TokenClassifierOutput, Tuple]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.albert( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + ALBERT_START_DOCSTRING, +) +class AlbertForQuestionAnswering(AlbertPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config: AlbertConfig): + super().__init__(config) + self.num_labels = config.num_labels + + self.albert = AlbertModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="twmkn9/albert-base-v2-squad2", + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + qa_target_start_index=12, + qa_target_end_index=13, + expected_output="'a nice puppet'", + expected_loss=7.36, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[AlbertForPreTrainingOutput, Tuple]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits: torch.Tensor = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + ALBERT_START_DOCSTRING, +) +class AlbertForMultipleChoice(AlbertPreTrainedModel): + def __init__(self, config: AlbertConfig): + super().__init__(config) + + self.albert = AlbertModel(config) + self.dropout = nn.Dropout(config.classifier_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[AlbertForPreTrainingOutput, Tuple]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where *num_choices* is the size of the second dimension of the input tensors. (see + *input_ids* above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + outputs = self.albert( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits: torch.Tensor = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_flax_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_flax_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..0ff1b9276a19d6a6ee101520f375a2af04a1defe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_flax_albert.py @@ -0,0 +1,1119 @@ +# coding=utf-8 +# Copyright 2021 Google AI, Google Brain and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Callable, Optional, Tuple + +import flax +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutput, + FlaxBaseModelOutputWithPooling, + FlaxMaskedLMOutput, + FlaxMultipleChoiceModelOutput, + FlaxQuestionAnsweringModelOutput, + FlaxSequenceClassifierOutput, + FlaxTokenClassifierOutput, +) +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_call_sample_docstring, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_albert import AlbertConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "albert-base-v2" +_CONFIG_FOR_DOC = "AlbertConfig" + + +@flax.struct.dataclass +class FlaxAlbertForPreTrainingOutput(ModelOutput): + """ + Output type of [`FlaxAlbertForPreTraining`]. + + Args: + prediction_logits (`jnp.ndarray` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + sop_logits (`jnp.ndarray` of shape `(batch_size, 2)`): + Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation + before SoftMax). + hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + prediction_logits: jnp.ndarray = None + sop_logits: jnp.ndarray = None + hidden_states: Optional[Tuple[jnp.ndarray]] = None + attentions: Optional[Tuple[jnp.ndarray]] = None + + +ALBERT_START_DOCSTRING = r""" + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading, saving and converting weights from PyTorch models) + + This model is also a Flax Linen [flax.linen.Module](https://flax.readthedocs.io/en/latest/flax.linen.html#module) + subclass. Use it as a regular Flax linen Module and refer to the Flax documentation for all matter related to + general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`AlbertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + +ALBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`numpy.ndarray` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`numpy.ndarray` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + +""" + + +class FlaxAlbertEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.word_embeddings = nn.Embed( + self.config.vocab_size, + self.config.embedding_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.position_embeddings = nn.Embed( + self.config.max_position_embeddings, + self.config.embedding_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.token_type_embeddings = nn.Embed( + self.config.type_vocab_size, + self.config.embedding_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings.__call__ + def __call__(self, input_ids, token_type_ids, position_ids, deterministic: bool = True): + # Embed + inputs_embeds = self.word_embeddings(input_ids.astype("i4")) + position_embeds = self.position_embeddings(position_ids.astype("i4")) + token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) + + # Sum all embeddings + hidden_states = inputs_embeds + token_type_embeddings + position_embeds + + # Layer Norm + hidden_states = self.LayerNorm(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxAlbertSelfAttention(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + if self.config.hidden_size % self.config.num_attention_heads != 0: + raise ValueError( + "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " + " : {self.config.num_attention_heads}" + ) + + self.query = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.key = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.value = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, attention_mask, deterministic=True, output_attentions: bool = False): + head_dim = self.config.hidden_size // self.config.num_attention_heads + + query_states = self.query(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + value_states = self.value(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + key_states = self.key(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.config.attention_probs_dropout_prob > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.config.attention_probs_dropout_prob, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) + + projected_attn_output = self.dense(attn_output) + projected_attn_output = self.dropout(projected_attn_output, deterministic=deterministic) + layernormed_attn_output = self.LayerNorm(projected_attn_output + hidden_states) + outputs = (layernormed_attn_output, attn_weights) if output_attentions else (layernormed_attn_output,) + return outputs + + +class FlaxAlbertLayer(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.attention = FlaxAlbertSelfAttention(self.config, dtype=self.dtype) + self.ffn = nn.Dense( + self.config.intermediate_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.activation = ACT2FN[self.config.hidden_act] + self.ffn_output = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.full_layer_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + ): + attention_outputs = self.attention( + hidden_states, attention_mask, deterministic=deterministic, output_attentions=output_attentions + ) + attention_output = attention_outputs[0] + ffn_output = self.ffn(attention_output) + ffn_output = self.activation(ffn_output) + ffn_output = self.ffn_output(ffn_output) + ffn_output = self.dropout(ffn_output, deterministic=deterministic) + hidden_states = self.full_layer_layer_norm(ffn_output + attention_output) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attention_outputs[1],) + return outputs + + +class FlaxAlbertLayerCollection(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxAlbertLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.inner_group_num) + ] + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + ): + layer_hidden_states = () + layer_attentions = () + + for layer_index, albert_layer in enumerate(self.layers): + layer_output = albert_layer( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + ) + hidden_states = layer_output[0] + + if output_attentions: + layer_attentions = layer_attentions + (layer_output[1],) + + if output_hidden_states: + layer_hidden_states = layer_hidden_states + (hidden_states,) + + outputs = (hidden_states,) + if output_hidden_states: + outputs = outputs + (layer_hidden_states,) + if output_attentions: + outputs = outputs + (layer_attentions,) + return outputs # last-layer hidden state, (layer hidden states), (layer attentions) + + +class FlaxAlbertLayerCollections(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + layer_index: Optional[str] = None + + def setup(self): + self.albert_layers = FlaxAlbertLayerCollection(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + ): + outputs = self.albert_layers( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + ) + return outputs + + +class FlaxAlbertLayerGroups(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxAlbertLayerCollections(self.config, name=str(i), layer_index=str(i), dtype=self.dtype) + for i in range(self.config.num_hidden_groups) + ] + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = (hidden_states,) if output_hidden_states else None + + for i in range(self.config.num_hidden_layers): + # Index of the hidden group + group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups)) + layer_group_output = self.layers[group_idx]( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + ) + hidden_states = layer_group_output[0] + + if output_attentions: + all_attentions = all_attentions + layer_group_output[-1] + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxAlbertEncoder(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.embedding_hidden_mapping_in = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.albert_layer_groups = FlaxAlbertLayerGroups(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + hidden_states = self.embedding_hidden_mapping_in(hidden_states) + return self.albert_layer_groups( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + ) + + +class FlaxAlbertOnlyMLMHead(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros + + def setup(self): + self.dense = nn.Dense(self.config.embedding_size, dtype=self.dtype) + self.activation = ACT2FN[self.config.hidden_act] + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.decoder = nn.Dense(self.config.vocab_size, dtype=self.dtype, use_bias=False) + self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) + + def __call__(self, hidden_states, shared_embedding=None): + hidden_states = self.dense(hidden_states) + hidden_states = self.activation(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + + if shared_embedding is not None: + hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + hidden_states = self.decoder(hidden_states) + + hidden_states += self.bias + return hidden_states + + +class FlaxAlbertSOPHead(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.dropout = nn.Dropout(self.config.classifier_dropout_prob) + self.classifier = nn.Dense(2, dtype=self.dtype) + + def __call__(self, pooled_output, deterministic=True): + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) + return logits + + +class FlaxAlbertPreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = AlbertConfig + base_model_prefix = "albert" + module_class: nn.Module = None + + def __init__( + self, + config: AlbertConfig, + input_shape: Tuple = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + token_type_ids = jnp.zeros_like(input_ids) + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) + attention_mask = jnp.ones_like(input_ids) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init( + rngs, input_ids, attention_mask, token_type_ids, position_ids, return_dict=False + )["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def __call__( + self, + input_ids, + attention_mask=None, + token_type_ids=None, + position_ids=None, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # init input tensors if not passed + if token_type_ids is None: + token_type_ids = jnp.zeros_like(input_ids) + + if position_ids is None: + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + return self.module.apply( + {"params": params or self.params}, + jnp.array(input_ids, dtype="i4"), + jnp.array(attention_mask, dtype="i4"), + jnp.array(token_type_ids, dtype="i4"), + jnp.array(position_ids, dtype="i4"), + not train, + output_attentions, + output_hidden_states, + return_dict, + rngs=rngs, + ) + + +class FlaxAlbertModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + add_pooling_layer: bool = True + + def setup(self): + self.embeddings = FlaxAlbertEmbeddings(self.config, dtype=self.dtype) + self.encoder = FlaxAlbertEncoder(self.config, dtype=self.dtype) + if self.add_pooling_layer: + self.pooler = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + name="pooler", + ) + self.pooler_activation = nn.tanh + else: + self.pooler = None + self.pooler_activation = None + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids: Optional[np.ndarray] = None, + position_ids: Optional[np.ndarray] = None, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # make sure `token_type_ids` is correctly initialized when not passed + if token_type_ids is None: + token_type_ids = jnp.zeros_like(input_ids) + + # make sure `position_ids` is correctly initialized when not passed + if position_ids is None: + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + hidden_states = self.embeddings(input_ids, token_type_ids, position_ids, deterministic=deterministic) + + outputs = self.encoder( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = outputs[0] + if self.add_pooling_layer: + pooled = self.pooler(hidden_states[:, 0]) + pooled = self.pooler_activation(pooled) + else: + pooled = None + + if not return_dict: + # if pooled is None, don't return it + if pooled is None: + return (hidden_states,) + outputs[1:] + return (hidden_states, pooled) + outputs[1:] + + return FlaxBaseModelOutputWithPooling( + last_hidden_state=hidden_states, + pooler_output=pooled, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + "The bare Albert Model transformer outputting raw hidden-states without any specific head on top.", + ALBERT_START_DOCSTRING, +) +class FlaxAlbertModel(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertModule + + +append_call_sample_docstring(FlaxAlbertModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) + + +class FlaxAlbertForPreTrainingModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) + self.predictions = FlaxAlbertOnlyMLMHead(config=self.config, dtype=self.dtype) + self.sop_classifier = FlaxAlbertSOPHead(config=self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.tie_word_embeddings: + shared_embedding = self.albert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] + else: + shared_embedding = None + + hidden_states = outputs[0] + pooled_output = outputs[1] + + prediction_scores = self.predictions(hidden_states, shared_embedding=shared_embedding) + sop_scores = self.sop_classifier(pooled_output, deterministic=deterministic) + + if not return_dict: + return (prediction_scores, sop_scores) + outputs[2:] + + return FlaxAlbertForPreTrainingOutput( + prediction_logits=prediction_scores, + sop_logits=sop_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a + `sentence order prediction (classification)` head. + """, + ALBERT_START_DOCSTRING, +) +class FlaxAlbertForPreTraining(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForPreTrainingModule + + +FLAX_ALBERT_FOR_PRETRAINING_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, FlaxAlbertForPreTraining + + >>> tokenizer = AutoTokenizer.from_pretrained("albert-base-v2") + >>> model = FlaxAlbertForPreTraining.from_pretrained("albert-base-v2") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.prediction_logits + >>> seq_relationship_logits = outputs.sop_logits + ``` +""" + +overwrite_call_docstring( + FlaxAlbertForPreTraining, + ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length") + FLAX_ALBERT_FOR_PRETRAINING_DOCSTRING, +) +append_replace_return_docstrings( + FlaxAlbertForPreTraining, output_type=FlaxAlbertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC +) + + +class FlaxAlbertForMaskedLMModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, add_pooling_layer=False, dtype=self.dtype) + self.predictions = FlaxAlbertOnlyMLMHead(config=self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + if self.config.tie_word_embeddings: + shared_embedding = self.albert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] + else: + shared_embedding = None + + # Compute the prediction scores + logits = self.predictions(hidden_states, shared_embedding=shared_embedding) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxMaskedLMOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings("""Albert Model with a `language modeling` head on top.""", ALBERT_START_DOCSTRING) +class FlaxAlbertForMaskedLM(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForMaskedLMModule + + +append_call_sample_docstring(FlaxAlbertForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) + + +class FlaxAlbertForSequenceClassificationModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) + classifier_dropout = ( + self.config.classifier_dropout_prob + if self.config.classifier_dropout_prob is not None + else self.config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(rate=classifier_dropout) + self.classifier = nn.Dense( + self.config.num_labels, + dtype=self.dtype, + ) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) + + if not return_dict: + return (logits,) + outputs[2:] + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled + output) e.g. for GLUE tasks. + """, + ALBERT_START_DOCSTRING, +) +class FlaxAlbertForSequenceClassification(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForSequenceClassificationModule + + +append_call_sample_docstring( + FlaxAlbertForSequenceClassification, + _CHECKPOINT_FOR_DOC, + FlaxSequenceClassifierOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxAlbertForMultipleChoiceModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + self.classifier = nn.Dense(1, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + num_choices = input_ids.shape[1] + input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None + attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None + token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None + position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None + + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) + + reshaped_logits = logits.reshape(-1, num_choices) + + if not return_dict: + return (reshaped_logits,) + outputs[2:] + + return FlaxMultipleChoiceModelOutput( + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + ALBERT_START_DOCSTRING, +) +class FlaxAlbertForMultipleChoice(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForMultipleChoiceModule + + +overwrite_call_docstring( + FlaxAlbertForMultipleChoice, ALBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") +) +append_call_sample_docstring( + FlaxAlbertForMultipleChoice, + _CHECKPOINT_FOR_DOC, + FlaxMultipleChoiceModelOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxAlbertForTokenClassificationModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) + classifier_dropout = ( + self.config.classifier_dropout_prob + if self.config.classifier_dropout_prob is not None + else self.config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(rate=classifier_dropout) + self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + logits = self.classifier(hidden_states) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxTokenClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + ALBERT_START_DOCSTRING, +) +class FlaxAlbertForTokenClassification(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForTokenClassificationModule + + +append_call_sample_docstring( + FlaxAlbertForTokenClassification, + _CHECKPOINT_FOR_DOC, + FlaxTokenClassifierOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxAlbertForQuestionAnsweringModule(nn.Module): + config: AlbertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.albert = FlaxAlbertModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) + self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.albert( + input_ids, + attention_mask, + token_type_ids, + position_ids, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + + logits = self.qa_outputs(hidden_states) + start_logits, end_logits = logits.split(self.config.num_labels, axis=-1) + start_logits = start_logits.squeeze(-1) + end_logits = end_logits.squeeze(-1) + + if not return_dict: + return (start_logits, end_logits) + outputs[1:] + + return FlaxQuestionAnsweringModelOutput( + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Albert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + ALBERT_START_DOCSTRING, +) +class FlaxAlbertForQuestionAnswering(FlaxAlbertPreTrainedModel): + module_class = FlaxAlbertForQuestionAnsweringModule + + +append_call_sample_docstring( + FlaxAlbertForQuestionAnswering, + _CHECKPOINT_FOR_DOC, + FlaxQuestionAnsweringModelOutput, + _CONFIG_FOR_DOC, +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_tf_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_tf_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..247ee395dc60fe23ee3b6acd96c8da70805fbd50 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/modeling_tf_albert.py @@ -0,0 +1,1487 @@ +# coding=utf-8 +# Copyright 2018 The OpenAI Team Authors and HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 ALBERT model.""" + +import math +from dataclasses import dataclass +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFBaseModelOutputWithPooling, + TFMaskedLMOutput, + TFMultipleChoiceModelOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFMaskedLanguageModelingLoss, + TFModelInputType, + TFMultipleChoiceLoss, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFTokenClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + MULTIPLE_CHOICE_DUMMY_INPUTS, + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_albert import AlbertConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "albert-base-v2" +_CONFIG_FOR_DOC = "AlbertConfig" + +TF_ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "albert-base-v1", + "albert-large-v1", + "albert-xlarge-v1", + "albert-xxlarge-v1", + "albert-base-v2", + "albert-large-v2", + "albert-xlarge-v2", + "albert-xxlarge-v2", + # See all ALBERT models at https://huggingface.co/models?filter=albert +] + + +class TFAlbertPreTrainingLoss: + """ + Loss function suitable for ALBERT pretraining, that is, the task of pretraining a language model by combining SOP + + MLM. .. note:: Any label of -100 will be ignored (along with the corresponding logits) in the loss computation. + """ + + def hf_compute_loss(self, labels: tf.Tensor, logits: tf.Tensor) -> tf.Tensor: + loss_fn = tf.keras.losses.SparseCategoricalCrossentropy( + from_logits=True, reduction=tf.keras.losses.Reduction.NONE + ) + if self.config.tf_legacy_loss: + # make sure only labels that are not equal to -100 + # are taken into account as loss + masked_lm_active_loss = tf.not_equal(tf.reshape(tensor=labels["labels"], shape=(-1,)), -100) + masked_lm_reduced_logits = tf.boolean_mask( + tensor=tf.reshape(tensor=logits[0], shape=(-1, shape_list(logits[0])[2])), + mask=masked_lm_active_loss, + ) + masked_lm_labels = tf.boolean_mask( + tensor=tf.reshape(tensor=labels["labels"], shape=(-1,)), mask=masked_lm_active_loss + ) + sentence_order_active_loss = tf.not_equal( + tf.reshape(tensor=labels["sentence_order_label"], shape=(-1,)), -100 + ) + sentence_order_reduced_logits = tf.boolean_mask( + tensor=tf.reshape(tensor=logits[1], shape=(-1, 2)), mask=sentence_order_active_loss + ) + sentence_order_label = tf.boolean_mask( + tensor=tf.reshape(tensor=labels["sentence_order_label"], shape=(-1,)), mask=sentence_order_active_loss + ) + masked_lm_loss = loss_fn(y_true=masked_lm_labels, y_pred=masked_lm_reduced_logits) + sentence_order_loss = loss_fn(y_true=sentence_order_label, y_pred=sentence_order_reduced_logits) + masked_lm_loss = tf.reshape(tensor=masked_lm_loss, shape=(-1, shape_list(sentence_order_loss)[0])) + masked_lm_loss = tf.reduce_mean(input_tensor=masked_lm_loss, axis=0) + + return masked_lm_loss + sentence_order_loss + + # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway + unmasked_lm_losses = loss_fn(y_true=tf.nn.relu(labels["labels"]), y_pred=logits[0]) + # make sure only labels that are not equal to -100 + # are taken into account for the loss computation + lm_loss_mask = tf.cast(labels["labels"] != -100, dtype=unmasked_lm_losses.dtype) + masked_lm_losses = unmasked_lm_losses * lm_loss_mask + reduced_masked_lm_loss = tf.reduce_sum(masked_lm_losses) / tf.reduce_sum(lm_loss_mask) + + sop_logits = tf.reshape(logits[1], (-1, 2)) + # Clip negative labels to zero here to avoid NaNs and errors - those positions will get masked later anyway + unmasked_sop_loss = loss_fn(y_true=tf.nn.relu(labels["sentence_order_label"]), y_pred=sop_logits) + sop_loss_mask = tf.cast(labels["sentence_order_label"] != -100, dtype=unmasked_sop_loss.dtype) + + masked_sop_loss = unmasked_sop_loss * sop_loss_mask + reduced_masked_sop_loss = tf.reduce_sum(masked_sop_loss) / tf.reduce_sum(sop_loss_mask) + + return tf.reshape(reduced_masked_lm_loss + reduced_masked_sop_loss, (1,)) + + +class TFAlbertEmbeddings(tf.keras.layers.Layer): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.embedding_size = config.embedding_size + self.max_position_embeddings = config.max_position_embeddings + self.initializer_range = config.initializer_range + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def build(self, input_shape: tf.TensorShape): + with tf.name_scope("word_embeddings"): + self.weight = self.add_weight( + name="weight", + shape=[self.config.vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("token_type_embeddings"): + self.token_type_embeddings = self.add_weight( + name="embeddings", + shape=[self.config.type_vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("position_embeddings"): + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + + super().build(input_shape) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertEmbeddings.call + def call( + self, + input_ids: tf.Tensor = None, + position_ids: tf.Tensor = None, + token_type_ids: tf.Tensor = None, + inputs_embeds: tf.Tensor = None, + past_key_values_length=0, + training: bool = False, + ) -> tf.Tensor: + """ + Applies embedding based on inputs tensor. + + Returns: + final_embeddings (`tf.Tensor`): output embedding tensor. + """ + if input_ids is None and inputs_embeds is None: + raise ValueError("Need to provide either `input_ids` or `input_embeds`.") + + if input_ids is not None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.config.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.config.vocab_size})" + ), + ) + inputs_embeds = tf.gather(params=self.weight, indices=input_ids) + + input_shape = shape_list(inputs_embeds)[:-1] + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + if position_ids is None: + position_ids = tf.expand_dims( + tf.range(start=past_key_values_length, limit=input_shape[1] + past_key_values_length), axis=0 + ) + + position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) + token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) + final_embeddings = inputs_embeds + position_embeds + token_type_embeds + final_embeddings = self.LayerNorm(inputs=final_embeddings) + final_embeddings = self.dropout(inputs=final_embeddings, training=training) + + return final_embeddings + + +class TFAlbertAttention(tf.keras.layers.Layer): + """Contains the complete attention sublayer, including both dropouts and layer norm.""" + + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + self.output_attentions = config.output_attentions + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + # Two different dropout probabilities; see https://github.com/google-research/albert/blob/master/modeling.py#L971-L993 + self.attention_dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + self.output_dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + input_tensor: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(input_tensor)[0] + mixed_query_layer = self.query(inputs=input_tensor) + mixed_key_layer = self.key(inputs=input_tensor) + mixed_value_layer = self.value(inputs=input_tensor) + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) + value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) + attention_scores = tf.divide(attention_scores, dk) + + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in TFAlbertModel call() function) + attention_scores = tf.add(attention_scores, attention_mask) + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.attention_dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + context_layer = tf.matmul(attention_probs, value_layer) + context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + context_layer = tf.reshape(tensor=context_layer, shape=(batch_size, -1, self.all_head_size)) + self_outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + hidden_states = self_outputs[0] + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.output_dropout(inputs=hidden_states, training=training) + attention_output = self.LayerNorm(inputs=hidden_states + input_tensor) + + # add attentions if we output them + outputs = (attention_output,) + self_outputs[1:] + + return outputs + + +class TFAlbertLayer(tf.keras.layers.Layer): + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFAlbertAttention(config, name="attention") + self.ffn = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="ffn" + ) + + if isinstance(config.hidden_act, str): + self.activation = get_tf_activation(config.hidden_act) + else: + self.activation = config.hidden_act + + self.ffn_output = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="ffn_output" + ) + self.full_layer_layer_norm = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="full_layer_layer_norm" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + input_tensor=hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + training=training, + ) + ffn_output = self.ffn(inputs=attention_outputs[0]) + ffn_output = self.activation(ffn_output) + ffn_output = self.ffn_output(inputs=ffn_output) + ffn_output = self.dropout(inputs=ffn_output, training=training) + hidden_states = self.full_layer_layer_norm(inputs=ffn_output + attention_outputs[0]) + + # add attentions if we output them + outputs = (hidden_states,) + attention_outputs[1:] + + return outputs + + +class TFAlbertLayerGroup(tf.keras.layers.Layer): + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + self.albert_layers = [ + TFAlbertLayer(config, name=f"albert_layers_._{i}") for i in range(config.inner_group_num) + ] + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + output_hidden_states: bool, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + layer_hidden_states = () if output_hidden_states else None + layer_attentions = () if output_attentions else None + + for layer_index, albert_layer in enumerate(self.albert_layers): + if output_hidden_states: + layer_hidden_states = layer_hidden_states + (hidden_states,) + + layer_output = albert_layer( + hidden_states=hidden_states, + attention_mask=attention_mask, + head_mask=head_mask[layer_index], + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_output[0] + + if output_attentions: + layer_attentions = layer_attentions + (layer_output[1],) + + # Add last layer + if output_hidden_states: + layer_hidden_states = layer_hidden_states + (hidden_states,) + + return tuple(v for v in [hidden_states, layer_hidden_states, layer_attentions] if v is not None) + + +class TFAlbertTransformer(tf.keras.layers.Layer): + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + self.num_hidden_layers = config.num_hidden_layers + self.num_hidden_groups = config.num_hidden_groups + # Number of layers in a hidden group + self.layers_per_group = int(config.num_hidden_layers / config.num_hidden_groups) + self.embedding_hidden_mapping_in = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + name="embedding_hidden_mapping_in", + ) + self.albert_layer_groups = [ + TFAlbertLayerGroup(config, name=f"albert_layer_groups_._{i}") for i in range(config.num_hidden_groups) + ] + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + output_hidden_states: bool, + return_dict: bool, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + hidden_states = self.embedding_hidden_mapping_in(inputs=hidden_states) + all_attentions = () if output_attentions else None + all_hidden_states = (hidden_states,) if output_hidden_states else None + + for i in range(self.num_hidden_layers): + # Index of the hidden group + group_idx = int(i / (self.num_hidden_layers / self.num_hidden_groups)) + layer_group_output = self.albert_layer_groups[group_idx]( + hidden_states=hidden_states, + attention_mask=attention_mask, + head_mask=head_mask[group_idx * self.layers_per_group : (group_idx + 1) * self.layers_per_group], + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + training=training, + ) + hidden_states = layer_group_output[0] + + if output_attentions: + all_attentions = all_attentions + layer_group_output[-1] + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class TFAlbertPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = AlbertConfig + base_model_prefix = "albert" + + +class TFAlbertMLMHead(tf.keras.layers.Layer): + def __init__(self, config: AlbertConfig, input_embeddings: tf.keras.layers.Layer, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.embedding_size = config.embedding_size + self.dense = tf.keras.layers.Dense( + config.embedding_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + if isinstance(config.hidden_act, str): + self.activation = get_tf_activation(config.hidden_act) + else: + self.activation = config.hidden_act + + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.decoder = input_embeddings + + def build(self, input_shape: tf.TensorShape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + self.decoder_bias = self.add_weight( + shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="decoder/bias" + ) + + super().build(input_shape) + + def get_output_embeddings(self) -> tf.keras.layers.Layer: + return self.decoder + + def set_output_embeddings(self, value: tf.Variable): + self.decoder.weight = value + self.decoder.vocab_size = shape_list(value)[0] + + def get_bias(self) -> Dict[str, tf.Variable]: + return {"bias": self.bias, "decoder_bias": self.decoder_bias} + + def set_bias(self, value: tf.Variable): + self.bias = value["bias"] + self.decoder_bias = value["decoder_bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.activation(hidden_states) + hidden_states = self.LayerNorm(inputs=hidden_states) + seq_length = shape_list(tensor=hidden_states)[1] + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.embedding_size]) + hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) + hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.decoder_bias) + + return hidden_states + + +@keras_serializable +class TFAlbertMainLayer(tf.keras.layers.Layer): + config_class = AlbertConfig + + def __init__(self, config: AlbertConfig, add_pooling_layer: bool = True, **kwargs): + super().__init__(**kwargs) + + self.config = config + + self.embeddings = TFAlbertEmbeddings(config, name="embeddings") + self.encoder = TFAlbertTransformer(config, name="encoder") + self.pooler = ( + tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + activation="tanh", + name="pooler", + ) + if add_pooling_layer + else None + ) + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings + + def set_input_embeddings(self, value: tf.Variable): + self.embeddings.weight = value + self.embeddings.vocab_size = shape_list(value)[0] + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor]]: + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = tf.fill(dims=input_shape, value=1) + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + training=training, + ) + + # We create a 3D attention mask from a 2D tensor mask. + # Sizes are [batch_size, 1, 1, to_seq_length] + # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] + # this attention mask is more simple than the triangular masking of causal attention + # used in OpenAI GPT, we just need to prepare the broadcast dimension here. + extended_attention_mask = tf.reshape(attention_mask, (input_shape[0], 1, 1, input_shape[1])) + + # Since attention_mask is 1.0 for positions we want to attend and 0.0 for + # masked positions, this operation will create a tensor which is 0.0 for + # positions we want to attend and -10000.0 for masked positions. + # Since we are adding it to the raw scores before the softmax, this is + # effectively the same as removing these entirely. + extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) + one_cst = tf.constant(1.0, dtype=embedding_output.dtype) + ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) + extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + encoder_outputs = self.encoder( + hidden_states=embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(inputs=sequence_output[:, 0]) if self.pooler is not None else None + + if not return_dict: + return ( + sequence_output, + pooled_output, + ) + encoder_outputs[1:] + + return TFBaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@dataclass +class TFAlbertForPreTrainingOutput(ModelOutput): + """ + Output type of [`TFAlbertForPreTraining`]. + + Args: + prediction_logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + sop_logits (`tf.Tensor` of shape `(batch_size, 2)`): + Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation + before SoftMax). + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: tf.Tensor = None + prediction_logits: tf.Tensor = None + sop_logits: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +ALBERT_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`AlbertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +ALBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and + [`PreTrainedTokenizer.encode`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare Albert Model transformer outputting raw hidden-states without any specific head on top.", + ALBERT_START_DOCSTRING, +) +class TFAlbertModel(TFAlbertPreTrainedModel): + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.albert = TFAlbertMainLayer(config, name="albert") + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor]]: + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFBaseModelOutputWithPooling) -> TFBaseModelOutputWithPooling: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutputWithPooling( + last_hidden_state=output.last_hidden_state, + pooler_output=output.pooler_output, + hidden_states=hs, + attentions=attns, + ) + + +@add_start_docstrings( + """ + Albert Model with two heads on top for pretraining: a `masked language modeling` head and a `sentence order + prediction` (classification) head. + """, + ALBERT_START_DOCSTRING, +) +class TFAlbertForPreTraining(TFAlbertPreTrainedModel, TFAlbertPreTrainingLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"predictions.decoder.weight"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.albert = TFAlbertMainLayer(config, name="albert") + self.predictions = TFAlbertMLMHead(config, input_embeddings=self.albert.embeddings, name="predictions") + self.sop_classifier = TFAlbertSOPHead(config, name="sop_classifier") + + def get_lm_head(self) -> tf.keras.layers.Layer: + return self.predictions + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=TFAlbertForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + sentence_order_label: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFAlbertForPreTrainingOutput, Tuple[tf.Tensor]]: + r""" + Return: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import AutoTokenizer, TFAlbertForPreTraining + + >>> tokenizer = AutoTokenizer.from_pretrained("albert-base-v2") + >>> model = TFAlbertForPreTraining.from_pretrained("albert-base-v2") + + >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True))[None, :] + >>> # Batch size 1 + >>> outputs = model(input_ids) + + >>> prediction_logits = outputs.prediction_logits + >>> sop_logits = outputs.sop_logits + ```""" + + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output, pooled_output = outputs[:2] + prediction_scores = self.predictions(hidden_states=sequence_output) + sop_scores = self.sop_classifier(pooled_output=pooled_output, training=training) + total_loss = None + + if labels is not None and sentence_order_label is not None: + d_labels = {"labels": labels} + d_labels["sentence_order_label"] = sentence_order_label + total_loss = self.hf_compute_loss(labels=d_labels, logits=(prediction_scores, sop_scores)) + + if not return_dict: + output = (prediction_scores, sop_scores) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return TFAlbertForPreTrainingOutput( + loss=total_loss, + prediction_logits=prediction_scores, + sop_logits=sop_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFAlbertForPreTrainingOutput) -> TFAlbertForPreTrainingOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFAlbertForPreTrainingOutput( + prediction_logits=output.prediction_logits, + sop_logits=output.sop_logits, + hidden_states=hs, + attentions=attns, + ) + + +class TFAlbertSOPHead(tf.keras.layers.Layer): + def __init__(self, config: AlbertConfig, **kwargs): + super().__init__(**kwargs) + + self.dropout = tf.keras.layers.Dropout(rate=config.classifier_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, + kernel_initializer=get_initializer(config.initializer_range), + name="classifier", + ) + + def call(self, pooled_output: tf.Tensor, training: bool) -> tf.Tensor: + dropout_pooled_output = self.dropout(inputs=pooled_output, training=training) + logits = self.classifier(inputs=dropout_pooled_output) + + return logits + + +@add_start_docstrings("""Albert Model with a `language modeling` head on top.""", ALBERT_START_DOCSTRING) +class TFAlbertForMaskedLM(TFAlbertPreTrainedModel, TFMaskedLanguageModelingLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions.decoder.weight"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") + self.predictions = TFAlbertMLMHead(config, input_embeddings=self.albert.embeddings, name="predictions") + + def get_lm_head(self) -> tf.keras.layers.Layer: + return self.predictions + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=TFMaskedLMOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMaskedLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Returns: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import AutoTokenizer, TFAlbertForMaskedLM + + >>> tokenizer = AutoTokenizer.from_pretrained("albert-base-v2") + >>> model = TFAlbertForMaskedLM.from_pretrained("albert-base-v2") + + >>> # add mask_token + >>> inputs = tokenizer(f"The capital of [MASK] is Paris.", return_tensors="tf") + >>> logits = model(**inputs).logits + + >>> # retrieve index of [MASK] + >>> mask_token_index = tf.where(inputs.input_ids == tokenizer.mask_token_id)[0][1] + >>> predicted_token_id = tf.math.argmax(logits[0, mask_token_index], axis=-1) + >>> tokenizer.decode(predicted_token_id) + 'france' + ``` + + ```python + >>> labels = tokenizer("The capital of France is Paris.", return_tensors="tf")["input_ids"] + >>> labels = tf.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) + >>> outputs = model(**inputs, labels=labels) + >>> round(float(outputs.loss), 2) + 0.81 + ``` + """ + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + prediction_scores = self.predictions(hidden_states=sequence_output, training=training) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + + return ((loss,) + output) if loss is not None else output + + return TFMaskedLMOutput( + loss=loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMaskedLM.serving_output + def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedLMOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled + output) e.g. for GLUE tasks. + """, + ALBERT_START_DOCSTRING, +) +class TFAlbertForSequenceClassification(TFAlbertPreTrainedModel, TFSequenceClassificationLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"predictions"] + _keys_to_ignore_on_load_missing = [r"dropout"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.albert = TFAlbertMainLayer(config, name="albert") + self.dropout = tf.keras.layers.Dropout(rate=config.classifier_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="vumichien/albert-base-v2-imdb", + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="'LABEL_1'", + expected_loss=0.12, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + pooled_output = outputs[1] + pooled_output = self.dropout(inputs=pooled_output, training=training) + logits = self.classifier(inputs=pooled_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[2:] + + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForSequenceClassification.serving_output + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + Albert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + ALBERT_START_DOCSTRING, +) +class TFAlbertForTokenClassification(TFAlbertPreTrainedModel, TFTokenClassificationLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] + _keys_to_ignore_on_load_missing = [r"dropout"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") + classifier_dropout_prob = ( + config.classifier_dropout_prob + if config.classifier_dropout_prob is not None + else config.hidden_dropout_prob + ) + self.dropout = tf.keras.layers.Dropout(rate=classifier_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + sequence_output = self.dropout(inputs=sequence_output, training=training) + logits = self.classifier(inputs=sequence_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[2:] + + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForTokenClassification.serving_output + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + Albert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layer on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + ALBERT_START_DOCSTRING, +) +class TFAlbertForQuestionAnswering(TFAlbertPreTrainedModel, TFQuestionAnsweringLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.albert = TFAlbertMainLayer(config, add_pooling_layer=False, name="albert") + self.qa_outputs = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="vumichien/albert-base-v2-squad2", + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + qa_target_start_index=12, + qa_target_end_index=13, + expected_output="'a nice puppet'", + expected_loss=7.36, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + outputs = self.albert( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + logits = self.qa_outputs(inputs=sequence_output) + start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) + start_logits = tf.squeeze(input=start_logits, axis=-1) + end_logits = tf.squeeze(input=end_logits, axis=-1) + loss = None + + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForQuestionAnswering.serving_output + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) + + +@add_start_docstrings( + """ + Albert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + ALBERT_START_DOCSTRING, +) +class TFAlbertForMultipleChoice(TFAlbertPreTrainedModel, TFMultipleChoiceLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"predictions"] + _keys_to_ignore_on_load_missing = [r"dropout"] + + def __init__(self, config: AlbertConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.albert = TFAlbertMainLayer(config, name="albert") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @property + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + tf.Tensor with dummy inputs + """ + return {"input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32)} + + @unpack_inputs + @add_start_docstrings_to_model_forward(ALBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMultipleChoiceModelOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` + where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) + """ + + if input_ids is not None: + num_choices = shape_list(input_ids)[1] + seq_length = shape_list(input_ids)[2] + else: + num_choices = shape_list(inputs_embeds)[1] + seq_length = shape_list(inputs_embeds)[2] + + flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None + flat_attention_mask = ( + tf.reshape(tensor=attention_mask, shape=(-1, seq_length)) if attention_mask is not None else None + ) + flat_token_type_ids = ( + tf.reshape(tensor=token_type_ids, shape=(-1, seq_length)) if token_type_ids is not None else None + ) + flat_position_ids = ( + tf.reshape(tensor=position_ids, shape=(-1, seq_length)) if position_ids is not None else None + ) + flat_inputs_embeds = ( + tf.reshape(tensor=inputs_embeds, shape=(-1, seq_length, shape_list(inputs_embeds)[3])) + if inputs_embeds is not None + else None + ) + outputs = self.albert( + input_ids=flat_input_ids, + attention_mask=flat_attention_mask, + token_type_ids=flat_token_type_ids, + position_ids=flat_position_ids, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + pooled_output = outputs[1] + pooled_output = self.dropout(inputs=pooled_output, training=training) + logits = self.classifier(inputs=pooled_output) + reshaped_logits = tf.reshape(tensor=logits, shape=(-1, num_choices)) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=reshaped_logits) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFMultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), + "token_type_ids": tf.TensorSpec((None, None, None), tf.int32, name="token_type_ids"), + } + ] + ) + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving + def serving(self, inputs: Dict[str, tf.Tensor]) -> TFMultipleChoiceModelOutput: + output = self.call(input_ids=inputs) + + return self.serving_output(output) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving_output + def serving_output(self, output: TFMultipleChoiceModelOutput) -> TFMultipleChoiceModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMultipleChoiceModelOutput(logits=output.logits, hidden_states=hs, attentions=attns) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..b043a14989fc5732e8105be17215eed78969501b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert.py @@ -0,0 +1,369 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization classes for ALBERT model.""" + + +import os +import unicodedata +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as spm + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) +VOCAB_FILES_NAMES = {"vocab_file": "spiece.model"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "albert-base-v1": "https://huggingface.co/albert-base-v1/resolve/main/spiece.model", + "albert-large-v1": "https://huggingface.co/albert-large-v1/resolve/main/spiece.model", + "albert-xlarge-v1": "https://huggingface.co/albert-xlarge-v1/resolve/main/spiece.model", + "albert-xxlarge-v1": "https://huggingface.co/albert-xxlarge-v1/resolve/main/spiece.model", + "albert-base-v2": "https://huggingface.co/albert-base-v2/resolve/main/spiece.model", + "albert-large-v2": "https://huggingface.co/albert-large-v2/resolve/main/spiece.model", + "albert-xlarge-v2": "https://huggingface.co/albert-xlarge-v2/resolve/main/spiece.model", + "albert-xxlarge-v2": "https://huggingface.co/albert-xxlarge-v2/resolve/main/spiece.model", + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "albert-base-v1": 512, + "albert-large-v1": 512, + "albert-xlarge-v1": 512, + "albert-xxlarge-v1": 512, + "albert-base-v2": 512, + "albert-large-v2": 512, + "albert-xlarge-v2": 512, + "albert-xxlarge-v2": 512, +} + +SPIECE_UNDERLINE = "▁" + + +class AlbertTokenizer(PreTrainedTokenizer): + """ + Construct an ALBERT tokenizer. Based on [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + remove_space (`bool`, *optional*, defaults to `True`): + Whether or not to strip the text when tokenizing (removing excess spaces before and after the string). + keep_accents (`bool`, *optional*, defaults to `False`): + Whether or not to keep accents when tokenizing. + bos_token (`str`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + + def __init__( + self, + vocab_file, + do_lower_case=True, + remove_space=True, + keep_accents=False, + bos_token="[CLS]", + eos_token="[SEP]", + unk_token="", + sep_token="[SEP]", + pad_token="", + cls_token="[CLS]", + mask_token="[MASK]", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + # Mask token behave like a normal word, i.e. include the space before it and + # is included in the raw text, there should be a match in a non-normalized sentence. + mask_token = ( + AddedToken(mask_token, lstrip=True, rstrip=False, normalized=False) + if isinstance(mask_token, str) + else mask_token + ) + + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + do_lower_case=do_lower_case, + remove_space=remove_space, + keep_accents=keep_accents, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + self.do_lower_case = do_lower_case + self.remove_space = remove_space + self.keep_accents = keep_accents + self.vocab_file = vocab_file + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(vocab_file) + + @property + def vocab_size(self): + return len(self.sp_model) + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(self.vocab_file) + + def preprocess_text(self, inputs): + if self.remove_space: + outputs = " ".join(inputs.strip().split()) + else: + outputs = inputs + outputs = outputs.replace("``", '"').replace("''", '"') + + if not self.keep_accents: + outputs = unicodedata.normalize("NFKD", outputs) + outputs = "".join([c for c in outputs if not unicodedata.combining(c)]) + if self.do_lower_case: + outputs = outputs.lower() + + return outputs + + def _tokenize(self, text: str) -> List[str]: + """Tokenize a string.""" + text = self.preprocess_text(text) + pieces = self.sp_model.encode(text, out_type=str) + new_pieces = [] + for piece in pieces: + if len(piece) > 1 and piece[-1] == str(",") and piece[-2].isdigit(): + cur_pieces = self.sp_model.EncodeAsPieces(piece[:-1].replace(SPIECE_UNDERLINE, "")) + if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE: + if len(cur_pieces[0]) == 1: + cur_pieces = cur_pieces[1:] + else: + cur_pieces[0] = cur_pieces[0][1:] + cur_pieces.append(piece[-1]) + new_pieces.extend(cur_pieces) + else: + new_pieces.append(piece) + + return new_pieces + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.sp_model.PieceToId(token) + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.sp_model.IdToPiece(index) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + current_sub_tokens = [] + out_string = "" + prev_is_special = False + for token in tokens: + # make sure that special tokens are not decoded using sentencepiece model + if token in self.all_special_tokens: + if not prev_is_special: + out_string += " " + out_string += self.sp_model.decode(current_sub_tokens) + token + prev_is_special = True + current_sub_tokens = [] + else: + current_sub_tokens.append(token) + prev_is_special = False + out_string += self.sp_model.decode(current_sub_tokens) + return out_string.strip() + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An ALBERT sequence has the following format: + + - single sequence: `[CLS] X [SEP]` + - pair of sequences: `[CLS] A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return cls + token_ids_0 + sep + return cls + token_ids_0 + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. An ALBERT + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..16c54e7eac6c94421ab1d3acb52b2d4080060230 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/albert/tokenization_albert_fast.py @@ -0,0 +1,242 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization classes for ALBERT model.""" + + +import os +from shutil import copyfile +from typing import List, Optional, Tuple + +from ...tokenization_utils import AddedToken +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import is_sentencepiece_available, logging + + +if is_sentencepiece_available(): + from .tokenization_albert import AlbertTokenizer +else: + AlbertTokenizer = None + +logger = logging.get_logger(__name__) +VOCAB_FILES_NAMES = {"vocab_file": "spiece.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "albert-base-v1": "https://huggingface.co/albert-base-v1/resolve/main/spiece.model", + "albert-large-v1": "https://huggingface.co/albert-large-v1/resolve/main/spiece.model", + "albert-xlarge-v1": "https://huggingface.co/albert-xlarge-v1/resolve/main/spiece.model", + "albert-xxlarge-v1": "https://huggingface.co/albert-xxlarge-v1/resolve/main/spiece.model", + "albert-base-v2": "https://huggingface.co/albert-base-v2/resolve/main/spiece.model", + "albert-large-v2": "https://huggingface.co/albert-large-v2/resolve/main/spiece.model", + "albert-xlarge-v2": "https://huggingface.co/albert-xlarge-v2/resolve/main/spiece.model", + "albert-xxlarge-v2": "https://huggingface.co/albert-xxlarge-v2/resolve/main/spiece.model", + }, + "tokenizer_file": { + "albert-base-v1": "https://huggingface.co/albert-base-v1/resolve/main/tokenizer.json", + "albert-large-v1": "https://huggingface.co/albert-large-v1/resolve/main/tokenizer.json", + "albert-xlarge-v1": "https://huggingface.co/albert-xlarge-v1/resolve/main/tokenizer.json", + "albert-xxlarge-v1": "https://huggingface.co/albert-xxlarge-v1/resolve/main/tokenizer.json", + "albert-base-v2": "https://huggingface.co/albert-base-v2/resolve/main/tokenizer.json", + "albert-large-v2": "https://huggingface.co/albert-large-v2/resolve/main/tokenizer.json", + "albert-xlarge-v2": "https://huggingface.co/albert-xlarge-v2/resolve/main/tokenizer.json", + "albert-xxlarge-v2": "https://huggingface.co/albert-xxlarge-v2/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "albert-base-v1": 512, + "albert-large-v1": 512, + "albert-xlarge-v1": 512, + "albert-xxlarge-v1": 512, + "albert-base-v2": 512, + "albert-large-v2": 512, + "albert-xlarge-v2": 512, + "albert-xxlarge-v2": 512, +} + +SPIECE_UNDERLINE = "▁" + + +class AlbertTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" ALBERT tokenizer (backed by HuggingFace's *tokenizers* library). Based on + [Unigram](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=unigram#models). This + tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + remove_space (`bool`, *optional*, defaults to `True`): + Whether or not to strip the text when tokenizing (removing excess spaces before and after the string). + keep_accents (`bool`, *optional*, defaults to `False`): + Whether or not to keep accents when tokenizing. + bos_token (`str`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. .. note:: When building a sequence using special tokens, this is not the token + that is used for the end of sequence. The token used is the `sep_token`. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + slow_tokenizer_class = AlbertTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + do_lower_case=True, + remove_space=True, + keep_accents=False, + bos_token="[CLS]", + eos_token="[SEP]", + unk_token="", + sep_token="[SEP]", + pad_token="", + cls_token="[CLS]", + mask_token="[MASK]", + **kwargs, + ): + # Mask token behave like a normal word, i.e. include the space before it and + # is included in the raw text, there should be a match in a non-normalized sentence. + mask_token = ( + AddedToken(mask_token, lstrip=True, rstrip=False, normalized=False) + if isinstance(mask_token, str) + else mask_token + ) + + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + do_lower_case=do_lower_case, + remove_space=remove_space, + keep_accents=keep_accents, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + **kwargs, + ) + + self.do_lower_case = do_lower_case + self.remove_space = remove_space + self.keep_accents = keep_accents + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An ALBERT sequence has the following format: + + - single sequence: `[CLS] X [SEP]` + - pair of sequences: `[CLS] A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: list of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return cls + token_ids_0 + sep + return cls + token_ids_0 + sep + token_ids_1 + sep + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Creates a mask from the two sequences passed to be used in a sequence-pair classification task. An ALBERT + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + if token_ids_1 is None, only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of ids. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8f9a6c40a7169f5829ceb4fff9db6311ed4ff421 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/__init__.py @@ -0,0 +1,73 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_torch_available, +) + + +_import_structure = { + "configuration_align": [ + "ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP", + "AlignConfig", + "AlignTextConfig", + "AlignVisionConfig", + ], + "processing_align": ["AlignProcessor"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_align"] = [ + "ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST", + "AlignModel", + "AlignPreTrainedModel", + "AlignTextModel", + "AlignVisionModel", + ] + +if TYPE_CHECKING: + from .configuration_align import ( + ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP, + AlignConfig, + AlignTextConfig, + AlignVisionConfig, + ) + from .processing_align import AlignProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_align import ( + ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST, + AlignModel, + AlignPreTrainedModel, + AlignTextModel, + AlignVisionModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/configuration_align.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/configuration_align.py new file mode 100644 index 0000000000000000000000000000000000000000..488b7f6fe458ac2ed0a9f5a9e5a2579a6ecb8d17 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/configuration_align.py @@ -0,0 +1,398 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" ALIGN model configuration""" + +import copy +import os +from typing import TYPE_CHECKING, List, Union + + +if TYPE_CHECKING: + pass + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "kakaobrain/align-base": "https://huggingface.co/kakaobrain/align-base/resolve/main/config.json", +} + + +class AlignTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AlignTextModel`]. It is used to instantiate a + ALIGN text encoder according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the text encoder of the ALIGN + [kakaobrain/align-base](https://huggingface.co/kakaobrain/align-base) architecture. The default values here are + copied from BERT. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the Align Text model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`AlignTextModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`AlignTextModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + pad_token_id (`int`, *optional*, defaults to 0) + Padding token id. + + Example: + + ```python + >>> from transformers import AlignTextConfig, AlignTextModel + + >>> # Initializing a AlignTextConfig with kakaobrain/align-base style configuration + >>> configuration = AlignTextConfig() + + >>> # Initializing a AlignTextModel (with random weights) from the kakaobrain/align-base style configuration + >>> model = AlignTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "align_text_model" + + def __init__( + self, + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=0, + position_embedding_type="absolute", + use_cache=True, + **kwargs, + ): + super().__init__(**kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.pad_token_id = pad_token_id + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig": + config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs) + + # get the text config dict if we are loading from AlignConfig + if config_dict.get("model_type") == "align": + config_dict = config_dict["text_config"] + + if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type: + logger.warning( + f"You are using a model of type {config_dict['model_type']} to instantiate a model of type " + f"{cls.model_type}. This is not supported for all configurations of models and can yield errors." + ) + + return cls.from_dict(config_dict, **kwargs) + + +class AlignVisionConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AlignVisionModel`]. It is used to instantiate a + ALIGN vision encoder according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the vision encoder of the ALIGN + [kakaobrain/align-base](https://huggingface.co/kakaobrain/align-base) architecture. The default values are copied + from EfficientNet (efficientnet-b7) + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + image_size (`int`, *optional*, defaults to 600): + The input image size. + width_coefficient (`float`, *optional*, defaults to 2.0): + Scaling coefficient for network width at each stage. + depth_coefficient (`float`, *optional*, defaults to 3.1): + Scaling coefficient for network depth at each stage. + depth_divisor `int`, *optional*, defaults to 8): + A unit of network width. + kernel_sizes (`List[int]`, *optional*, defaults to `[3, 3, 5, 3, 5, 5, 3]`): + List of kernel sizes to be used in each block. + in_channels (`List[int]`, *optional*, defaults to `[32, 16, 24, 40, 80, 112, 192]`): + List of input channel sizes to be used in each block for convolutional layers. + out_channels (`List[int]`, *optional*, defaults to `[16, 24, 40, 80, 112, 192, 320]`): + List of output channel sizes to be used in each block for convolutional layers. + depthwise_padding (`List[int]`, *optional*, defaults to `[]`): + List of block indices with square padding. + strides: (`List[int]`, *optional*, defaults to `[1, 2, 2, 2, 1, 2, 1]`): + List of stride sizes to be used in each block for convolutional layers. + num_block_repeats (`List[int]`, *optional*, defaults to `[1, 2, 2, 3, 3, 4, 1]`): + List of the number of times each block is to repeated. + expand_ratios (`List[int]`, *optional*, defaults to `[1, 6, 6, 6, 6, 6, 6]`): + List of scaling coefficient of each block. + squeeze_expansion_ratio (`float`, *optional*, defaults to 0.25): + Squeeze expansion ratio. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in each block. If string, `"gelu"`, `"relu"`, + `"selu", `"gelu_new"`, `"silu"` and `"mish"` are supported. + hiddem_dim (`int`, *optional*, defaults to 1280): + The hidden dimension of the layer before the classification head. + pooling_type (`str` or `function`, *optional*, defaults to `"mean"`): + Type of final pooling to be applied before the dense classification head. Available options are [`"mean"`, + `"max"`] + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + batch_norm_eps (`float`, *optional*, defaults to 1e-3): + The epsilon used by the batch normalization layers. + batch_norm_momentum (`float`, *optional*, defaults to 0.99): + The momentum used by the batch normalization layers. + dropout_rate (`float`, *optional*, defaults to 0.5): + The dropout rate to be applied before final classifier layer. + drop_connect_rate (`float`, *optional*, defaults to 0.2): + The drop rate for skip connections. + + Example: + + ```python + >>> from transformers import AlignVisionConfig, AlignVisionModel + + >>> # Initializing a AlignVisionConfig with kakaobrain/align-base style configuration + >>> configuration = AlignVisionConfig() + + >>> # Initializing a AlignVisionModel (with random weights) from the kakaobrain/align-base style configuration + >>> model = AlignVisionModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "align_vision_model" + + def __init__( + self, + num_channels: int = 3, + image_size: int = 600, + width_coefficient: float = 2.0, + depth_coefficient: float = 3.1, + depth_divisor: int = 8, + kernel_sizes: List[int] = [3, 3, 5, 3, 5, 5, 3], + in_channels: List[int] = [32, 16, 24, 40, 80, 112, 192], + out_channels: List[int] = [16, 24, 40, 80, 112, 192, 320], + depthwise_padding: List[int] = [], + strides: List[int] = [1, 2, 2, 2, 1, 2, 1], + num_block_repeats: List[int] = [1, 2, 2, 3, 3, 4, 1], + expand_ratios: List[int] = [1, 6, 6, 6, 6, 6, 6], + squeeze_expansion_ratio: float = 0.25, + hidden_act: str = "swish", + hidden_dim: int = 2560, + pooling_type: str = "mean", + initializer_range: float = 0.02, + batch_norm_eps: float = 0.001, + batch_norm_momentum: float = 0.99, + dropout_rate: float = 0.5, + drop_connect_rate: float = 0.2, + **kwargs, + ): + super().__init__(**kwargs) + + self.num_channels = num_channels + self.image_size = image_size + self.width_coefficient = width_coefficient + self.depth_coefficient = depth_coefficient + self.depth_divisor = depth_divisor + self.kernel_sizes = kernel_sizes + self.in_channels = in_channels + self.out_channels = out_channels + self.depthwise_padding = depthwise_padding + self.strides = strides + self.num_block_repeats = num_block_repeats + self.expand_ratios = expand_ratios + self.squeeze_expansion_ratio = squeeze_expansion_ratio + self.hidden_act = hidden_act + self.hidden_dim = hidden_dim + self.pooling_type = pooling_type + self.initializer_range = initializer_range + self.batch_norm_eps = batch_norm_eps + self.batch_norm_momentum = batch_norm_momentum + self.dropout_rate = dropout_rate + self.drop_connect_rate = drop_connect_rate + self.num_hidden_layers = sum(num_block_repeats) * 4 + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig": + config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs) + + # get the vision config dict if we are loading from AlignConfig + if config_dict.get("model_type") == "align": + config_dict = config_dict["vision_config"] + + if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type: + logger.warning( + f"You are using a model of type {config_dict['model_type']} to instantiate a model of type " + f"{cls.model_type}. This is not supported for all configurations of models and can yield errors." + ) + + return cls.from_dict(config_dict, **kwargs) + + +class AlignConfig(PretrainedConfig): + r""" + [`AlignConfig`] is the configuration class to store the configuration of a [`AlignModel`]. It is used to + instantiate a ALIGN model according to the specified arguments, defining the text model and vision model configs. + Instantiating a configuration with the defaults will yield a similar configuration to that of the ALIGN + [kakaobrain/align-base](https://huggingface.co/kakaobrain/align-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + text_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`AlignTextConfig`]. + vision_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`AlignVisionConfig`]. + projection_dim (`int`, *optional*, defaults to 640): + Dimentionality of text and vision projection layers. + temperature_init_value (`float`, *optional*, defaults to 1.0): + The inital value of the *temperature* paramter. Default is used as per the original ALIGN implementation. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + kwargs (*optional*): + Dictionary of keyword arguments. + + Example: + + ```python + >>> from transformers import AlignConfig, AlignModel + + >>> # Initializing a AlignConfig with kakaobrain/align-base style configuration + >>> configuration = AlignConfig() + + >>> # Initializing a AlignModel (with random weights) from the kakaobrain/align-base style configuration + >>> model = AlignModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + + >>> # We can also initialize a AlignConfig from a AlignTextConfig and a AlignVisionConfig + >>> from transformers import AlignTextConfig, AlignVisionConfig + + >>> # Initializing ALIGN Text and Vision configurations + >>> config_text = AlignTextConfig() + >>> config_vision = AlignVisionConfig() + + >>> config = AlignConfig.from_text_vision_configs(config_text, config_vision) + ```""" + + model_type = "align" + is_composition = True + + def __init__( + self, + text_config=None, + vision_config=None, + projection_dim=640, + temperature_init_value=1.0, + initializer_range=0.02, + **kwargs, + ): + super().__init__(**kwargs) + + if text_config is None: + text_config = {} + logger.info("text_config is None. Initializing the AlignTextConfig with default values.") + + if vision_config is None: + vision_config = {} + logger.info("vision_config is None. Initializing the AlignVisionConfig with default values.") + + self.text_config = AlignTextConfig(**text_config) + self.vision_config = AlignVisionConfig(**vision_config) + + self.projection_dim = projection_dim + self.temperature_init_value = temperature_init_value + self.initializer_range = initializer_range + + @classmethod + def from_text_vision_configs(cls, text_config: AlignTextConfig, vision_config: AlignVisionConfig, **kwargs): + r""" + Instantiate a [`AlignConfig`] (or a derived class) from align text model configuration and align vision model + configuration. + + Returns: + [`AlignConfig`]: An instance of a configuration object + """ + + return cls(text_config=text_config.to_dict(), vision_config=vision_config.to_dict(), **kwargs) + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. + + Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + output["text_config"] = self.text_config.to_dict() + output["vision_config"] = self.vision_config.to_dict() + output["model_type"] = self.__class__.model_type + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/convert_align_tf_to_hf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/convert_align_tf_to_hf.py new file mode 100644 index 0000000000000000000000000000000000000000..fbf53844ab9c9cea67f4d576bb0bc865ebfb0dd8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/convert_align_tf_to_hf.py @@ -0,0 +1,387 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert ALIGN checkpoints from the original repository.""" + +import argparse +import os + +import align +import numpy as np +import requests +import tensorflow as tf +import torch +from PIL import Image +from tokenizer import Tokenizer + +from transformers import ( + AlignConfig, + AlignModel, + AlignProcessor, + BertConfig, + BertTokenizer, + EfficientNetConfig, + EfficientNetImageProcessor, +) +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def preprocess(image): + image = tf.image.resize(image, (346, 346)) + image = tf.image.crop_to_bounding_box(image, (346 - 289) // 2, (346 - 289) // 2, 289, 289) + return image + + +def get_align_config(): + vision_config = EfficientNetConfig.from_pretrained("google/efficientnet-b7") + vision_config.image_size = 289 + vision_config.hidden_dim = 640 + vision_config.id2label = {"0": "LABEL_0", "1": "LABEL_1"} + vision_config.label2id = {"LABEL_0": 0, "LABEL_1": 1} + vision_config.depthwise_padding = [] + + text_config = BertConfig() + config = AlignConfig.from_text_vision_configs( + text_config=text_config, vision_config=vision_config, projection_dim=640 + ) + return config + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +def get_processor(): + image_processor = EfficientNetImageProcessor( + do_center_crop=True, + rescale_factor=1 / 127.5, + rescale_offset=True, + do_normalize=False, + include_top=False, + resample=Image.BILINEAR, + ) + tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") + tokenizer.model_max_length = 64 + processor = AlignProcessor(image_processor=image_processor, tokenizer=tokenizer) + return processor + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def rename_keys(original_param_names): + # EfficientNet image encoder + block_names = [v.split("_")[0].split("block")[1] for v in original_param_names if v.startswith("block")] + block_names = list(set(block_names)) + block_names = sorted(block_names) + num_blocks = len(block_names) + block_name_mapping = {b: str(i) for b, i in zip(block_names, range(num_blocks))} + + rename_keys = [] + rename_keys.append(("stem_conv/kernel:0", "embeddings.convolution.weight")) + rename_keys.append(("stem_bn/gamma:0", "embeddings.batchnorm.weight")) + rename_keys.append(("stem_bn/beta:0", "embeddings.batchnorm.bias")) + rename_keys.append(("stem_bn/moving_mean:0", "embeddings.batchnorm.running_mean")) + rename_keys.append(("stem_bn/moving_variance:0", "embeddings.batchnorm.running_var")) + + for b in block_names: + hf_b = block_name_mapping[b] + rename_keys.append((f"block{b}_expand_conv/kernel:0", f"encoder.blocks.{hf_b}.expansion.expand_conv.weight")) + rename_keys.append((f"block{b}_expand_bn/gamma:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.weight")) + rename_keys.append((f"block{b}_expand_bn/beta:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.bias")) + rename_keys.append( + (f"block{b}_expand_bn/moving_mean:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.running_mean") + ) + rename_keys.append( + (f"block{b}_expand_bn/moving_variance:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.running_var") + ) + rename_keys.append( + (f"block{b}_dwconv/depthwise_kernel:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight") + ) + rename_keys.append((f"block{b}_bn/gamma:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight")) + rename_keys.append((f"block{b}_bn/beta:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias")) + rename_keys.append( + (f"block{b}_bn/moving_mean:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean") + ) + rename_keys.append( + (f"block{b}_bn/moving_variance:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var") + ) + + rename_keys.append((f"block{b}_se_reduce/kernel:0", f"encoder.blocks.{hf_b}.squeeze_excite.reduce.weight")) + rename_keys.append((f"block{b}_se_reduce/bias:0", f"encoder.blocks.{hf_b}.squeeze_excite.reduce.bias")) + rename_keys.append((f"block{b}_se_expand/kernel:0", f"encoder.blocks.{hf_b}.squeeze_excite.expand.weight")) + rename_keys.append((f"block{b}_se_expand/bias:0", f"encoder.blocks.{hf_b}.squeeze_excite.expand.bias")) + rename_keys.append( + (f"block{b}_project_conv/kernel:0", f"encoder.blocks.{hf_b}.projection.project_conv.weight") + ) + rename_keys.append((f"block{b}_project_bn/gamma:0", f"encoder.blocks.{hf_b}.projection.project_bn.weight")) + rename_keys.append((f"block{b}_project_bn/beta:0", f"encoder.blocks.{hf_b}.projection.project_bn.bias")) + rename_keys.append( + (f"block{b}_project_bn/moving_mean:0", f"encoder.blocks.{hf_b}.projection.project_bn.running_mean") + ) + rename_keys.append( + (f"block{b}_project_bn/moving_variance:0", f"encoder.blocks.{hf_b}.projection.project_bn.running_var") + ) + + key_mapping = {} + for item in rename_keys: + if item[0] in original_param_names: + key_mapping[item[0]] = "vision_model." + item[1] + + # BERT text encoder + rename_keys = [] + old = "tf_bert_model/bert" + new = "text_model" + for i in range(12): + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/query/kernel:0", + f"{new}.encoder.layer.{i}.attention.self.query.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/query/bias:0", + f"{new}.encoder.layer.{i}.attention.self.query.bias", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/key/kernel:0", + f"{new}.encoder.layer.{i}.attention.self.key.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/key/bias:0", + f"{new}.encoder.layer.{i}.attention.self.key.bias", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/value/kernel:0", + f"{new}.encoder.layer.{i}.attention.self.value.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/self/value/bias:0", + f"{new}.encoder.layer.{i}.attention.self.value.bias", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/output/dense/kernel:0", + f"{new}.encoder.layer.{i}.attention.output.dense.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/output/dense/bias:0", + f"{new}.encoder.layer.{i}.attention.output.dense.bias", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/output/LayerNorm/gamma:0", + f"{new}.encoder.layer.{i}.attention.output.LayerNorm.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/attention/output/LayerNorm/beta:0", + f"{new}.encoder.layer.{i}.attention.output.LayerNorm.bias", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/intermediate/dense/kernel:0", + f"{new}.encoder.layer.{i}.intermediate.dense.weight", + ) + ) + rename_keys.append( + ( + f"{old}/encoder/layer_._{i}/intermediate/dense/bias:0", + f"{new}.encoder.layer.{i}.intermediate.dense.bias", + ) + ) + rename_keys.append( + (f"{old}/encoder/layer_._{i}/output/dense/kernel:0", f"{new}.encoder.layer.{i}.output.dense.weight") + ) + rename_keys.append( + (f"{old}/encoder/layer_._{i}/output/dense/bias:0", f"{new}.encoder.layer.{i}.output.dense.bias") + ) + rename_keys.append( + (f"{old}/encoder/layer_._{i}/output/LayerNorm/gamma:0", f"{new}.encoder.layer.{i}.output.LayerNorm.weight") + ) + rename_keys.append( + (f"{old}/encoder/layer_._{i}/output/LayerNorm/beta:0", f"{new}.encoder.layer.{i}.output.LayerNorm.bias") + ) + + rename_keys.append((f"{old}/embeddings/word_embeddings/weight:0", f"{new}.embeddings.word_embeddings.weight")) + rename_keys.append( + (f"{old}/embeddings/position_embeddings/embeddings:0", f"{new}.embeddings.position_embeddings.weight") + ) + rename_keys.append( + (f"{old}/embeddings/token_type_embeddings/embeddings:0", f"{new}.embeddings.token_type_embeddings.weight") + ) + rename_keys.append((f"{old}/embeddings/LayerNorm/gamma:0", f"{new}.embeddings.LayerNorm.weight")) + rename_keys.append((f"{old}/embeddings/LayerNorm/beta:0", f"{new}.embeddings.LayerNorm.bias")) + + rename_keys.append((f"{old}/pooler/dense/kernel:0", f"{new}.pooler.dense.weight")) + rename_keys.append((f"{old}/pooler/dense/bias:0", f"{new}.pooler.dense.bias")) + rename_keys.append(("dense/kernel:0", "text_projection.weight")) + rename_keys.append(("dense/bias:0", "text_projection.bias")) + rename_keys.append(("dense/bias:0", "text_projection.bias")) + rename_keys.append(("temperature:0", "temperature")) + + for item in rename_keys: + if item[0] in original_param_names: + key_mapping[item[0]] = item[1] + return key_mapping + + +def replace_params(hf_params, tf_params, key_mapping): + list(hf_params.keys()) + + for key, value in tf_params.items(): + if key not in key_mapping: + continue + + hf_key = key_mapping[key] + if "_conv" in key and "kernel" in key: + new_hf_value = torch.from_numpy(value).permute(3, 2, 0, 1) + elif "embeddings" in key: + new_hf_value = torch.from_numpy(value) + elif "depthwise_kernel" in key: + new_hf_value = torch.from_numpy(value).permute(2, 3, 0, 1) + elif "kernel" in key: + new_hf_value = torch.from_numpy(np.transpose(value)) + elif "temperature" in key: + new_hf_value = value + elif "bn/gamma" or "bn/beta" in key: + new_hf_value = torch.from_numpy(np.transpose(value)).squeeze() + else: + new_hf_value = torch.from_numpy(value) + + # Replace HF parameters with original TF model parameters + hf_params[hf_key].copy_(new_hf_value) + + +@torch.no_grad() +def convert_align_checkpoint(checkpoint_path, pytorch_dump_folder_path, save_model, push_to_hub): + """ + Copy/paste/tweak model's weights to our ALIGN structure. + """ + # Load original model + seq_length = 64 + tok = Tokenizer(seq_length) + original_model = align.Align("efficientnet-b7", "bert-base", 640, seq_length, tok.get_vocab_size()) + original_model.compile() + original_model.load_weights(checkpoint_path) + + tf_params = original_model.trainable_variables + tf_non_train_params = original_model.non_trainable_variables + tf_params = {param.name: param.numpy() for param in tf_params} + for param in tf_non_train_params: + tf_params[param.name] = param.numpy() + tf_param_names = list(tf_params.keys()) + + # Load HuggingFace model + config = get_align_config() + hf_model = AlignModel(config).eval() + hf_params = hf_model.state_dict() + + # Create src-to-dst parameter name mapping dictionary + print("Converting parameters...") + key_mapping = rename_keys(tf_param_names) + replace_params(hf_params, tf_params, key_mapping) + + # Initialize processor + processor = get_processor() + inputs = processor( + images=prepare_img(), text="A picture of a cat", padding="max_length", max_length=64, return_tensors="pt" + ) + + # HF model inference + hf_model.eval() + with torch.no_grad(): + outputs = hf_model(**inputs) + + hf_image_features = outputs.image_embeds.detach().numpy() + hf_text_features = outputs.text_embeds.detach().numpy() + + # Original model inference + original_model.trainable = False + tf_image_processor = EfficientNetImageProcessor( + do_center_crop=True, + do_rescale=False, + do_normalize=False, + include_top=False, + resample=Image.BILINEAR, + ) + image = tf_image_processor(images=prepare_img(), return_tensors="tf", data_format="channels_last")["pixel_values"] + text = tok(tf.constant(["A picture of a cat"])) + + image_features = original_model.image_encoder(image, training=False) + text_features = original_model.text_encoder(text, training=False) + + image_features = tf.nn.l2_normalize(image_features, axis=-1) + text_features = tf.nn.l2_normalize(text_features, axis=-1) + + # Check whether original and HF model outputs match -> np.allclose + assert np.allclose(image_features, hf_image_features, atol=1e-3), "The predicted image features are not the same." + assert np.allclose(text_features, hf_text_features, atol=1e-3), "The predicted text features are not the same." + print("Model outputs match!") + + if save_model: + # Create folder to save model + if not os.path.isdir(pytorch_dump_folder_path): + os.mkdir(pytorch_dump_folder_path) + # Save converted model and feature extractor + hf_model.save_pretrained(pytorch_dump_folder_path) + processor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + # Push model and feature extractor to hub + print("Pushing converted ALIGN to the hub...") + processor.push_to_hub("align-base") + hf_model.push_to_hub("align-base") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--checkpoint_path", + default="./weights/model-weights", + type=str, + help="Path to the pretrained TF ALIGN checkpoint.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default="hf_model", + type=str, + help="Path to the output PyTorch model directory.", + ) + parser.add_argument("--save_model", action="store_true", help="Save model to local") + parser.add_argument("--push_to_hub", action="store_true", help="Push model and feature extractor to the hub") + + args = parser.parse_args() + convert_align_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/modeling_align.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/modeling_align.py new file mode 100644 index 0000000000000000000000000000000000000000..09ee6eca62650efad7818c9cfdc8a0a83b8aa4f6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/modeling_align.py @@ -0,0 +1,1642 @@ +# coding=utf-8 +# Copyright 2023 The Google Research Team Authors and The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch ALIGN model.""" + +import math +from dataclasses import dataclass +from typing import Any, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutputWithNoAttention, + BaseModelOutputWithPastAndCrossAttentions, + BaseModelOutputWithPoolingAndCrossAttentions, + BaseModelOutputWithPoolingAndNoAttention, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_align import AlignConfig, AlignTextConfig, AlignVisionConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "kakaobrain/align-base" +_CONFIG_FOR_DOC = "AlignConfig" + + +ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "kakaobrain/align-base", + # See all ALIGN models at https://huggingface.co/models?filter=align +] + + +ALIGN_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`AlignConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +ALIGN_TEXT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +ALIGN_VISION_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`EfficientNetImageProcessor.__call__`] for details. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +ALIGN_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`EfficientNetImageProcessor.__call__`] for details. + return_loss (`bool`, *optional*): + Whether or not to return the contrastive loss. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@dataclass +class AlignVisionModelOutput(ModelOutput): + """ + Base class for vision model's outputs that also contains image embeddings of the pooling of the last hidden states. + + Args: + image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): + The image embeddings obtained by applying the projection layer to the pooler_output. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. + """ + + image_embeds: Optional[torch.FloatTensor] = None + last_hidden_state: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class AlignTextModelOutput(ModelOutput): + """ + Base class for text model's outputs that also contains a pooling of the last hidden states. + + Args: + text_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`): + The text embeddings obtained by applying the projection layer to the pooler_output. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + text_embeds: Optional[torch.FloatTensor] = None + last_hidden_state: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class AlignOutput(ModelOutput): + """ + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): + Contrastive loss for image-text similarity. + logits_per_image:(`torch.FloatTensor` of shape `(image_batch_size, text_batch_size)`): + The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text + similarity scores. + logits_per_text:(`torch.FloatTensor` of shape `(text_batch_size, image_batch_size)`): + The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image + similarity scores. + text_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The text embeddings obtained by applying the projection layer to the pooled output of [`AlignTextModel`]. + image_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The output of [`AlignVisionModel`]. + text_model_output(`BaseModelOutputWithPoolingAndCrossAttentions`): + The output of the [`AlignTextModel`]. + vision_model_output(`BaseModelOutputWithPoolingAndNoAttention`): + The output of the [`AlignVisionModel`]. + """ + + loss: Optional[torch.FloatTensor] = None + logits_per_image: torch.FloatTensor = None + logits_per_text: torch.FloatTensor = None + text_embeds: torch.FloatTensor = None + image_embeds: torch.FloatTensor = None + text_model_output: BaseModelOutputWithPoolingAndCrossAttentions = None + vision_model_output: BaseModelOutputWithPoolingAndNoAttention = None + + def to_tuple(self) -> Tuple[Any]: + return tuple( + self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() + for k in self.keys() + ) + + +# contrastive loss function, adapted from +# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html +def contrastive_loss(logits: torch.Tensor) -> torch.Tensor: + return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device), label_smoothing=0.1) + + +def align_loss(similarity: torch.Tensor) -> torch.Tensor: + caption_loss = contrastive_loss(similarity) + image_loss = contrastive_loss(similarity.t()) + return (caption_loss + image_loss) / 2.0 + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.round_filters with EfficientNet -> AlignVision +def round_filters(config: AlignVisionConfig, num_channels: int): + r""" + Round number of filters based on depth multiplier. + """ + divisor = config.depth_divisor + num_channels *= config.width_coefficient + new_dim = max(divisor, int(num_channels + divisor / 2) // divisor * divisor) + + # Make sure that round down does not go down by more than 10%. + if new_dim < 0.9 * num_channels: + new_dim += divisor + + return int(new_dim) + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.correct_pad +def correct_pad(kernel_size: Union[int, Tuple], adjust: bool = True): + r""" + Utility function to get the tuple padding value for the depthwise convolution. + + Args: + kernel_size (`int` or `tuple`): + Kernel size of the convolution layers. + adjust (`bool`, *optional*, defaults to `True`): + Adjusts padding value to apply to right and bottom sides of the input. + """ + if isinstance(kernel_size, int): + kernel_size = (kernel_size, kernel_size) + + correct = (kernel_size[0] // 2, kernel_size[1] // 2) + if adjust: + return (correct[1] - 1, correct[1], correct[0] - 1, correct[0]) + else: + return (correct[1], correct[1], correct[0], correct[0]) + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.EfficientNetEmbeddings with EfficientNet->AlignVision +class AlignVisionEmbeddings(nn.Module): + r""" + A module that corresponds to the stem module of the original work. + """ + + def __init__(self, config: AlignVisionConfig): + super().__init__() + + self.out_dim = round_filters(config, 32) + self.padding = nn.ZeroPad2d(padding=(0, 1, 0, 1)) + self.convolution = nn.Conv2d( + config.num_channels, self.out_dim, kernel_size=3, stride=2, padding="valid", bias=False + ) + self.batchnorm = nn.BatchNorm2d(self.out_dim, eps=config.batch_norm_eps, momentum=config.batch_norm_momentum) + self.activation = ACT2FN[config.hidden_act] + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + features = self.padding(pixel_values) + features = self.convolution(features) + features = self.batchnorm(features) + features = self.activation(features) + + return features + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.EfficientNetDepthwiseConv2d with EfficientNet->AlignVision +class AlignVisionDepthwiseConv2d(nn.Conv2d): + def __init__( + self, + in_channels, + depth_multiplier=1, + kernel_size=3, + stride=1, + padding=0, + dilation=1, + bias=True, + padding_mode="zeros", + ): + out_channels = in_channels * depth_multiplier + super().__init__( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=in_channels, + bias=bias, + padding_mode=padding_mode, + ) + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.EfficientNetExpansionLayer with EfficientNet->AlignVision +class AlignVisionExpansionLayer(nn.Module): + r""" + This corresponds to the expansion phase of each block in the original implementation. + """ + + def __init__(self, config: AlignVisionConfig, in_dim: int, out_dim: int, stride: int): + super().__init__() + self.expand_conv = nn.Conv2d( + in_channels=in_dim, + out_channels=out_dim, + kernel_size=1, + padding="same", + bias=False, + ) + self.expand_bn = nn.BatchNorm2d(num_features=out_dim, eps=config.batch_norm_eps) + self.expand_act = ACT2FN[config.hidden_act] + + def forward(self, hidden_states: torch.FloatTensor) -> torch.Tensor: + # Expand phase + hidden_states = self.expand_conv(hidden_states) + hidden_states = self.expand_bn(hidden_states) + hidden_states = self.expand_act(hidden_states) + + return hidden_states + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.EfficientNetDepthwiseLayer with with EfficientNet->AlignVision +class AlignVisionDepthwiseLayer(nn.Module): + r""" + This corresponds to the depthwise convolution phase of each block in the original implementation. + """ + + def __init__( + self, + config: AlignVisionConfig, + in_dim: int, + stride: int, + kernel_size: int, + adjust_padding: bool, + ): + super().__init__() + self.stride = stride + conv_pad = "valid" if self.stride == 2 else "same" + padding = correct_pad(kernel_size, adjust=adjust_padding) + + self.depthwise_conv_pad = nn.ZeroPad2d(padding=padding) + self.depthwise_conv = AlignVisionDepthwiseConv2d( + in_dim, kernel_size=kernel_size, stride=stride, padding=conv_pad, bias=False + ) + self.depthwise_norm = nn.BatchNorm2d( + num_features=in_dim, eps=config.batch_norm_eps, momentum=config.batch_norm_momentum + ) + self.depthwise_act = ACT2FN[config.hidden_act] + + def forward(self, hidden_states: torch.FloatTensor) -> torch.Tensor: + # Depthwise convolution + if self.stride == 2: + hidden_states = self.depthwise_conv_pad(hidden_states) + + hidden_states = self.depthwise_conv(hidden_states) + hidden_states = self.depthwise_norm(hidden_states) + hidden_states = self.depthwise_act(hidden_states) + + return hidden_states + + +# Copied from transformers.models.efficientnet.modeling_efficientnet.EfficientNetSqueezeExciteLayer with with EfficientNet->AlignVision +class AlignVisionSqueezeExciteLayer(nn.Module): + r""" + This corresponds to the Squeeze and Excitement phase of each block in the original implementation. + """ + + def __init__(self, config: AlignVisionConfig, in_dim: int, expand_dim: int, expand: bool = False): + super().__init__() + self.dim = expand_dim if expand else in_dim + self.dim_se = max(1, int(in_dim * config.squeeze_expansion_ratio)) + + self.squeeze = nn.AdaptiveAvgPool2d(output_size=1) + self.reduce = nn.Conv2d( + in_channels=self.dim, + out_channels=self.dim_se, + kernel_size=1, + padding="same", + ) + self.expand = nn.Conv2d( + in_channels=self.dim_se, + out_channels=self.dim, + kernel_size=1, + padding="same", + ) + self.act_reduce = ACT2FN[config.hidden_act] + self.act_expand = nn.Sigmoid() + + def forward(self, hidden_states: torch.FloatTensor) -> torch.Tensor: + inputs = hidden_states + hidden_states = self.squeeze(hidden_states) + hidden_states = self.reduce(hidden_states) + hidden_states = self.act_reduce(hidden_states) + + hidden_states = self.expand(hidden_states) + hidden_states = self.act_expand(hidden_states) + hidden_states = torch.mul(inputs, hidden_states) + + return hidden_states + + +class AlignVisionFinalBlockLayer(nn.Module): + r""" + This corresponds to the final phase of each block in the original implementation. + """ + + def __init__( + self, config: AlignVisionConfig, in_dim: int, out_dim: int, stride: int, drop_rate: float, id_skip: bool + ): + super().__init__() + self.apply_dropout = stride == 1 and not id_skip + self.project_conv = nn.Conv2d( + in_channels=in_dim, + out_channels=out_dim, + kernel_size=1, + padding="same", + bias=False, + ) + self.project_bn = nn.BatchNorm2d( + num_features=out_dim, eps=config.batch_norm_eps, momentum=config.batch_norm_momentum + ) + self.dropout = nn.Dropout(p=drop_rate) + + def forward(self, embeddings: torch.FloatTensor, hidden_states: torch.FloatTensor) -> torch.Tensor: + hidden_states = self.project_conv(hidden_states) + hidden_states = self.project_bn(hidden_states) + + if self.apply_dropout: + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states + embeddings + + return hidden_states + + +class AlignVisionBlock(nn.Module): + r""" + This corresponds to the block module of original the EfficientNet vision encoder implementation. + + Args: + config ([`AlignVisionConfig`]): + Model configuration class. + in_dim (`int`): + Number of input channels. + out_dim (`int`): + Number of output channels. + stride (`int`): + Stride size to be used in convolution layers. + expand_ratio (`int`): + Expand ratio to set the output dimensions for the expansion and squeeze-excite layers. + kernel_size (`int`): + Kernel size for the depthwise convolution layer. + drop_rate (`float`): + Dropout rate to be used in the final phase of each block. + id_skip (`bool`): + Whether to apply dropout and sum the final hidden states with the input embeddings during the final phase + of each block. Set to `True` for the first block of each stage. + adjust_padding (`bool`): + Whether to apply padding to only right and bottom side of the input kernel before the depthwise convolution + operation, set to `True` for inputs with odd input sizes. + """ + + def __init__( + self, + config: AlignVisionConfig, + in_dim: int, + out_dim: int, + stride: int, + expand_ratio: int, + kernel_size: int, + drop_rate: float, + id_skip: bool, + adjust_padding: bool, + ): + super().__init__() + self.expand_ratio = expand_ratio + self.expand = True if self.expand_ratio != 1 else False + expand_in_dim = in_dim * expand_ratio + + if self.expand: + self.expansion = AlignVisionExpansionLayer( + config=config, in_dim=in_dim, out_dim=expand_in_dim, stride=stride + ) + + self.depthwise_conv = AlignVisionDepthwiseLayer( + config=config, + in_dim=expand_in_dim if self.expand else in_dim, + stride=stride, + kernel_size=kernel_size, + adjust_padding=adjust_padding, + ) + self.squeeze_excite = AlignVisionSqueezeExciteLayer( + config=config, in_dim=in_dim, expand_dim=expand_in_dim, expand=self.expand + ) + self.projection = AlignVisionFinalBlockLayer( + config=config, + in_dim=expand_in_dim if self.expand else in_dim, + out_dim=out_dim, + stride=stride, + drop_rate=drop_rate, + id_skip=id_skip, + ) + + def forward(self, hidden_states: torch.FloatTensor) -> torch.Tensor: + embeddings = hidden_states + # Expansion and depthwise convolution phase + if self.expand_ratio != 1: + hidden_states = self.expansion(hidden_states) + hidden_states = self.depthwise_conv(hidden_states) + + # Squeeze and excite phase + hidden_states = self.squeeze_excite(hidden_states) + hidden_states = self.projection(embeddings, hidden_states) + return hidden_states + + +class AlignVisionEncoder(nn.Module): + r""" + Forward propogates the embeddings through each vision encoder (EfficientNet) block. + + Args: + config ([`AlignVisionConfig`]): + Model configuration class. + """ + + def __init__(self, config: AlignVisionConfig): + super().__init__() + self.depth_coefficient = config.depth_coefficient + + def round_repeats(repeats): + # Round number of block repeats based on depth multiplier. + return int(math.ceil(self.depth_coefficient * repeats)) + + num_base_blocks = len(config.in_channels) + num_blocks = sum(round_repeats(n) for n in config.num_block_repeats) + + curr_block_num = 0 + blocks = [] + for i in range(num_base_blocks): + in_dim = round_filters(config, config.in_channels[i]) + out_dim = round_filters(config, config.out_channels[i]) + stride = config.strides[i] + kernel_size = config.kernel_sizes[i] + expand_ratio = config.expand_ratios[i] + + for j in range(round_repeats(config.num_block_repeats[i])): + id_skip = True if j == 0 else False + stride = 1 if j > 0 else stride + in_dim = out_dim if j > 0 else in_dim + adjust_padding = False if curr_block_num in config.depthwise_padding else True + drop_rate = config.drop_connect_rate * curr_block_num / num_blocks + + block = AlignVisionBlock( + config=config, + in_dim=in_dim, + out_dim=out_dim, + stride=stride, + kernel_size=kernel_size, + expand_ratio=expand_ratio, + drop_rate=drop_rate, + id_skip=id_skip, + adjust_padding=adjust_padding, + ) + blocks.append(block) + curr_block_num += 1 + + self.blocks = nn.ModuleList(blocks) + + def forward( + self, + hidden_states: torch.FloatTensor, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> BaseModelOutputWithPoolingAndNoAttention: + all_hidden_states = (hidden_states,) if output_hidden_states else None + + for block in self.blocks: + hidden_states = block(hidden_states) + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states] if v is not None) + + return BaseModelOutputWithNoAttention( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + ) + + +# Copied from transformers.models.bert.modeling_bert.BertEmbeddings with Bert->AlignText +class AlignTextEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + +# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->AlignText +class AlignTextSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in AlignTextModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->AlignText +class AlignTextSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->AlignText +class AlignTextAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = AlignTextSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = AlignTextSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self( + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->AlignText +class AlignTextIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertOutput with Bert->AlignText +class AlignTextOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertLayer with Bert->AlignText +class AlignTextLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = AlignTextAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = AlignTextAttention(config, position_embedding_type="absolute") + self.intermediate = AlignTextIntermediate(config) + self.output = AlignTextOutput(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +# Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->AlignText +class AlignTextEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([AlignTextLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.bert.modeling_bert.BertPooler with Bert -> AlignText +class AlignTextPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +class AlignPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = AlignConfig + base_model_prefix = "align" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, AlignModel): + nn.init.xavier_uniform_(module.text_projection.weight) + module.text_projection.bias.data.zero_() + module.text_projection._is_hf_initialized = True + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + if isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (AlignTextModel, AlignVisionModel)): + module.gradient_checkpointing = value + + +@add_start_docstrings( + """The text model from ALIGN without any head or projection on top.""", + ALIGN_START_DOCSTRING, +) +class AlignTextModel(AlignPreTrainedModel): + config_class = AlignTextConfig + + def __init__(self, config: AlignTextConfig, add_pooling_layer: bool = True): + super().__init__(config) + self.config = config + + self.embeddings = AlignTextEmbeddings(config) + self.encoder = AlignTextEncoder(config) + + self.pooler = AlignTextPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + @add_start_docstrings_to_model_forward(ALIGN_TEXT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPoolingAndCrossAttentions, config_class=AlignTextConfig) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoTokenizer, AlignTextModel + + >>> model = AlignTextModel.from_pretrained("kakaobrain/align-base") + >>> tokenizer = AutoTokenizer.from_pretrained("kakaobrain/align-base") + + >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt") + + >>> outputs = model(**inputs) + >>> last_hidden_state = outputs.last_hidden_state + >>> pooled_output = outputs.pooler_output # pooled (EOS token) states + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + ) + encoder_outputs = self.encoder( + embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +@add_start_docstrings( + """The vision model from ALIGN without any head or projection on top.""", + ALIGN_START_DOCSTRING, +) +class AlignVisionModel(AlignPreTrainedModel): + config_class = AlignVisionConfig + main_input_name = "pixel_values" + + def __init__(self, config: AlignVisionConfig): + super().__init__(config) + self.config = config + self.embeddings = AlignVisionEmbeddings(config) + self.encoder = AlignVisionEncoder(config) + + # Final pooling layer + if config.pooling_type == "mean": + self.pooler = nn.AvgPool2d(config.hidden_dim, ceil_mode=True) + elif config.pooling_type == "max": + self.pooler = nn.MaxPool2d(config.hidden_dim, ceil_mode=True) + else: + raise ValueError(f"config.pooling must be one of ['mean', 'max'] got {config.pooling}") + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.vision_model.embeddings.convolution + + @add_start_docstrings_to_model_forward(ALIGN_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPoolingAndNoAttention, config_class=AlignVisionConfig) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPoolingAndNoAttention]: + r""" + Returns: + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AlignVisionModel + + >>> model = AlignVisionModel.from_pretrained("kakaobrain/align-base") + >>> processor = AutoProcessor.from_pretrained("kakaobrain/align-base") + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> inputs = processor(images=image, return_tensors="pt") + + >>> outputs = model(**inputs) + >>> last_hidden_state = outputs.last_hidden_state + >>> pooled_output = outputs.pooler_output # pooled CLS states + ```""" + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + embedding_output = self.embeddings(pixel_values) + encoder_outputs = self.encoder( + embedding_output, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # Apply pooling + last_hidden_state = encoder_outputs[0] + pooled_output = self.pooler(last_hidden_state) + # Reshape (batch_size, projection_dim, 1 , 1) -> (batch_size, projection_dim) + pooled_output = pooled_output.reshape(pooled_output.shape[:2]) + + if not return_dict: + return (last_hidden_state, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndNoAttention( + last_hidden_state=last_hidden_state, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + ) + + +@add_start_docstrings(ALIGN_START_DOCSTRING) +class AlignModel(AlignPreTrainedModel): + config_class = AlignConfig + + def __init__(self, config: AlignConfig): + super().__init__(config) + + if not isinstance(config.text_config, AlignTextConfig): + raise ValueError( + "config.text_config is expected to be of type AlignTextConfig but is of type" + f" {type(config.text_config)}." + ) + + if not isinstance(config.vision_config, AlignVisionConfig): + raise ValueError( + "config.vision_config is expected to be of type AlignVisionConfig but is of type" + f" {type(config.vision_config)}." + ) + + text_config = config.text_config + vision_config = config.vision_config + + self.projection_dim = config.projection_dim + self.text_embed_dim = text_config.hidden_size + + self.text_model = AlignTextModel(text_config) + self.vision_model = AlignVisionModel(vision_config) + + self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim) + self.temperature = nn.Parameter(torch.ones([]) * self.config.temperature_init_value) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALIGN_TEXT_INPUTS_DOCSTRING) + def get_text_features( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + text_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The text embeddings obtained by + applying the projection layer to the pooled output of [`AlignTextModel`]. + + Examples: + + ```python + >>> from transformers import AutoTokenizer, AlignModel + + >>> model = AlignModel.from_pretrained("kakaobrain/align-base") + >>> tokenizer = AutoTokenizer.from_pretrained("kakaobrain/align-base") + + >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt") + >>> text_features = model.get_text_features(**inputs) + ```""" + # Use ALIGN model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_state = text_outputs[0][:, 0, :] + text_features = self.text_projection(last_hidden_state) + + return text_features + + @add_start_docstrings_to_model_forward(ALIGN_VISION_INPUTS_DOCSTRING) + def get_image_features( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + image_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The image embeddings obtained by + applying the projection layer to the pooled output of [`AlignVisionModel`]. + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AlignModel + + >>> model = AlignModel.from_pretrained("kakaobrain/align-base") + >>> processor = AutoProcessor.from_pretrained("kakaobrain/align-base") + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> inputs = processor(images=image, return_tensors="pt") + + >>> image_features = model.get_image_features(**inputs) + ```""" + # Use ALIGN model's config for some fields (if specified) instead of those of vision & text components. + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + image_features = vision_outputs[1] # pooled_output + + return image_features + + @add_start_docstrings_to_model_forward(ALIGN_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=AlignOutput, config_class=AlignConfig) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + return_loss: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, AlignOutput]: + r""" + Returns: + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AlignModel + + >>> model = AlignModel.from_pretrained("kakaobrain/align-base") + >>> processor = AutoProcessor.from_pretrained("kakaobrain/align-base") + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> inputs = processor( + ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True + ... ) + + >>> outputs = model(**inputs) + >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score + >>> probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities + ```""" + # Use ALIGN model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + image_embeds = vision_outputs[1] + text_embeds = text_outputs[0][:, 0, :] + text_embeds = self.text_projection(text_embeds) + + # normalized features + image_embeds = image_embeds / image_embeds.norm(p=2, dim=-1, keepdim=True) + text_embeds = text_embeds / text_embeds.norm(p=2, dim=-1, keepdim=True) + + # cosine similarity as logits + logits_per_text = torch.matmul(text_embeds, image_embeds.t()) / self.temperature + logits_per_image = logits_per_text.t() + + loss = None + if return_loss: + loss = align_loss(logits_per_text) + + if not return_dict: + output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) + return ((loss,) + output) if loss is not None else output + + return AlignOutput( + loss=loss, + logits_per_image=logits_per_image, + logits_per_text=logits_per_text, + text_embeds=text_embeds, + image_embeds=image_embeds, + text_model_output=text_outputs, + vision_model_output=vision_outputs, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/processing_align.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/processing_align.py new file mode 100644 index 0000000000000000000000000000000000000000..0863c11310e318cc1535a38f3e5251bee28e99e6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/align/processing_align.py @@ -0,0 +1,122 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Image/Text processor class for ALIGN +""" + + +from ...processing_utils import ProcessorMixin +from ...tokenization_utils_base import BatchEncoding + + +class AlignProcessor(ProcessorMixin): + r""" + Constructs an ALIGN processor which wraps [`EfficientNetImageProcessor`] and + [`BertTokenizer`]/[`BertTokenizerFast`] into a single processor that interits both the image processor and + tokenizer functionalities. See the [`~AlignProcessor.__call__`] and [`~OwlViTProcessor.decode`] for more + information. + + Args: + image_processor ([`EfficientNetImageProcessor`]): + The image processor is a required input. + tokenizer ([`BertTokenizer`, `BertTokenizerFast`]): + The tokenizer is a required input. + """ + + attributes = ["image_processor", "tokenizer"] + image_processor_class = "EfficientNetImageProcessor" + tokenizer_class = ("BertTokenizer", "BertTokenizerFast") + + def __init__(self, image_processor, tokenizer): + super().__init__(image_processor, tokenizer) + + def __call__(self, text=None, images=None, padding="max_length", max_length=64, return_tensors=None, **kwargs): + """ + Main method to prepare text(s) and image(s) to be fed as input to the model. This method forwards the `text` + and `kwargs` arguments to BertTokenizerFast's [`~BertTokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the image(s), this method forwards the `images` and `kwargs` arguments to + EfficientNetImageProcessor's [`~EfficientNetImageProcessor.__call__`] if `images` is not `None`. Please refer + to the doctsring of the above two methods for more information. + + Args: + text (`str`, `List[str]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. In case of a NumPy array/PyTorch tensor, each image should be of shape (C, H, W), where C is a + number of channels, H and W are image height and width. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `max_length`): + Activates and controls padding for tokenization of input text. Choose between [`True` or `'longest'`, + `'max_length'`, `False` or `'do_not_pad'`] + max_length (`int`, *optional*, defaults to `max_length`): + Maximum padding value to use to pad the input text during tokenization. + + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`. + """ + if text is None and images is None: + raise ValueError("You have to specify either text or images. Both cannot be none.") + + if text is not None: + encoding = self.tokenizer( + text, padding=padding, max_length=max_length, return_tensors=return_tensors, **kwargs + ) + + if images is not None: + image_features = self.image_processor(images, return_tensors=return_tensors, **kwargs) + + if text is not None and images is not None: + encoding["pixel_values"] = image_features.pixel_values + return encoding + elif text is not None: + return encoding + else: + return BatchEncoding(data=dict(**image_features), tensor_type=return_tensors) + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to BertTokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to BertTokenizerFast's [`~PreTrainedTokenizer.decode`]. Please refer to + the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + image_processor_input_names = self.image_processor.model_input_names + return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5fc02b192b256b620d9e590a22ff0e1ca8dbd6d6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/__init__.py @@ -0,0 +1,71 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tokenizers_available, is_torch_available + + +_import_structure = { + "configuration_altclip": [ + "ALTCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP", + "AltCLIPConfig", + "AltCLIPTextConfig", + "AltCLIPVisionConfig", + ], + "processing_altclip": ["AltCLIPProcessor"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_altclip"] = [ + "ALTCLIP_PRETRAINED_MODEL_ARCHIVE_LIST", + "AltCLIPPreTrainedModel", + "AltCLIPModel", + "AltCLIPTextModel", + "AltCLIPVisionModel", + ] + + +if TYPE_CHECKING: + from .configuration_altclip import ( + ALTCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP, + AltCLIPConfig, + AltCLIPTextConfig, + AltCLIPVisionConfig, + ) + from .processing_altclip import AltCLIPProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_altclip import ( + ALTCLIP_PRETRAINED_MODEL_ARCHIVE_LIST, + AltCLIPModel, + AltCLIPPreTrainedModel, + AltCLIPTextModel, + AltCLIPVisionModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/configuration_altclip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/configuration_altclip.py new file mode 100644 index 0000000000000000000000000000000000000000..4ddbb5ec81606ac23b1851aa3d8a0984139ff65c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/configuration_altclip.py @@ -0,0 +1,405 @@ +# coding=utf-8 +# Copyright 2022 WenXiang ZhongzhiCheng LedellWu LiuGuang BoWenZhang and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" AltCLIP model configuration""" +import copy +import os +from typing import Union + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +ALTCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "BAAI/AltCLIP": "https://huggingface.co/BAAI/AltCLIP/resolve/main/config.json", + # See all AltCLIP models at https://huggingface.co/models?filter=altclip +} + + +class AltCLIPTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AltCLIPTextModel`]. It is used to instantiate a + AltCLIP text model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the AltCLIP + [BAAI/AltCLIP](https://huggingface.co/BAAI/AltCLIP) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 250002): + Vocabulary size of the AltCLIP model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`AltCLIPTextModel`]. + hidden_size (`int`, *optional*, defaults to 1024): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 4096): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 514): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`AltCLIPTextModel`] + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-5): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + project_dim (`int`, *optional*, defaults to 768): + The dimentions of the teacher model before the mapping layer. + + Examples: + + ```python + >>> from transformers import AltCLIPTextModel, AltCLIPTextConfig + + >>> # Initializing a AltCLIPTextConfig with BAAI/AltCLIP style configuration + >>> configuration = AltCLIPTextConfig() + + >>> # Initializing a AltCLIPTextModel (with random weights) from the BAAI/AltCLIP style configuration + >>> model = AltCLIPTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "altclip_text_model" + + def __init__( + self, + vocab_size=250002, + hidden_size=1024, + num_hidden_layers=24, + num_attention_heads=16, + intermediate_size=4096, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=514, + type_vocab_size=1, + initializer_range=0.02, + initializer_factor=0.02, + layer_norm_eps=1e-05, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + position_embedding_type="absolute", + use_cache=True, + project_dim=768, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.initializer_factor = initializer_factor + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.project_dim = project_dim + + +class AltCLIPVisionConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AltCLIPModel`]. It is used to instantiate an + AltCLIP model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of the AltCLIP + [BAAI/AltCLIP](https://huggingface.co/BAAI/AltCLIP) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + image_size (`int`, *optional*, defaults to 224): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 32): + The size (resolution) of each patch. + hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported. + layer_norm_eps (`float`, *optional*, defaults to 1e-5): + The epsilon used by the layer normalization layers. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + initializer_factor (`float``, *optional*, defaults to 1): + A factor for initializing all weight matrices (should be kept to 1, used internally for initialization + testing). + + Example: + + ```python + >>> from transformers import AltCLIPVisionConfig, AltCLIPVisionModel + + >>> # Initializing a AltCLIPVisionConfig with BAAI/AltCLIP style configuration + >>> configuration = AltCLIPVisionConfig() + + >>> # Initializing a AltCLIPVisionModel (with random weights) from the BAAI/AltCLIP style configuration + >>> model = AltCLIPVisionModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "altclip_vision_model" + + def __init__( + self, + hidden_size=768, + intermediate_size=3072, + projection_dim=512, + num_hidden_layers=12, + num_attention_heads=12, + num_channels=3, + image_size=224, + patch_size=32, + hidden_act="quick_gelu", + layer_norm_eps=1e-5, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.num_channels = num_channels + self.patch_size = patch_size + self.image_size = image_size + self.initializer_range = initializer_range + self.initializer_factor = initializer_factor + self.attention_dropout = attention_dropout + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig": + config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs) + + # get the vision config dict if we are loading from AltCLIPConfig + if config_dict.get("model_type") == "altclip": + config_dict = config_dict["vision_config"] + + if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type: + logger.warning( + f"You are using a model of type {config_dict['model_type']} to instantiate a model of type " + f"{cls.model_type}. This is not supported for all configurations of models and can yield errors." + ) + + return cls.from_dict(config_dict, **kwargs) + + +class AltCLIPConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`AltCLIPModel`]. It is used to instantiate an + AltCLIP model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of the AltCLIP + [BAAI/AltCLIP](https://huggingface.co/BAAI/AltCLIP) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + text_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`AltCLIPTextConfig`]. + vision_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`AltCLIPVisionConfig`]. + projection_dim (`int`, *optional*, defaults to 512): + Dimentionality of text and vision projection layers. + logit_scale_init_value (`float`, *optional*, defaults to 2.6592): + The inital value of the *logit_scale* paramter. Default is used as per the original CLIP implementation. + kwargs (*optional*): + Dictionary of keyword arguments. + + Example: + + ```python + >>> from transformers import AltCLIPConfig, AltCLIPModel + + >>> # Initializing a AltCLIPConfig with BAAI/AltCLIP style configuration + >>> configuration = AltCLIPConfig() + + >>> # Initializing a AltCLIPModel (with random weights) from the BAAI/AltCLIP style configuration + >>> model = AltCLIPModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + + >>> # We can also initialize a AltCLIPConfig from a AltCLIPTextConfig and a AltCLIPVisionConfig + + >>> # Initializing a AltCLIPText and AltCLIPVision configuration + >>> config_text = AltCLIPTextConfig() + >>> config_vision = AltCLIPVisionConfig() + + >>> config = AltCLIPConfig.from_text_vision_configs(config_text, config_vision) + ```""" + + model_type = "altclip" + is_composition = True + + def __init__( + self, text_config=None, vision_config=None, projection_dim=768, logit_scale_init_value=2.6592, **kwargs + ): + # If `_config_dict` exist, we use them for the backward compatibility. + # We pop out these 2 attributes before calling `super().__init__` to avoid them being saved (which causes a lot + # of confusion!). + text_config_dict = kwargs.pop("text_config_dict", None) + vision_config_dict = kwargs.pop("vision_config_dict", None) + + super().__init__(**kwargs) + + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if text_config_dict is not None: + if text_config is None: + text_config = {} + + # This is the complete result when using `text_config_dict`. + _text_config_dict = AltCLIPTextConfig(**text_config_dict).to_dict() + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key not in ["transformers_version"]: + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `AltCLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overriden.' + ) + logger.warning(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + + if vision_config_dict is not None: + if vision_config is None: + vision_config = {} + + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = AltCLIPVisionConfig(**vision_config_dict).to_dict() + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key not in ["transformers_version"]: + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `AltCLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overriden.' + ) + logger.warning(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + + if text_config is None: + text_config = {} + logger.info("`text_config` is `None`. Initializing the `AltCLIPTextConfig` with default values.") + + if vision_config is None: + vision_config = {} + logger.info("`vision_config` is `None`. initializing the `AltCLIPVisionConfig` with default values.") + + self.text_config = AltCLIPTextConfig(**text_config) + self.vision_config = AltCLIPVisionConfig(**vision_config) + + self.projection_dim = projection_dim + self.logit_scale_init_value = logit_scale_init_value + self.initializer_factor = 1.0 + + @classmethod + def from_text_vision_configs(cls, text_config: AltCLIPTextConfig, vision_config: AltCLIPVisionConfig, **kwargs): + r""" + Instantiate a [`AltCLIPConfig`] (or a derived class) from altclip text model configuration and altclip vision + model configuration. + + Returns: + [`AltCLIPConfig`]: An instance of a configuration object + """ + + return cls(text_config=text_config.to_dict(), vision_config=vision_config.to_dict(), **kwargs) + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. + + Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + output["text_config"] = self.text_config.to_dict() + output["vision_config"] = self.vision_config.to_dict() + output["model_type"] = self.__class__.model_type + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/modeling_altclip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/modeling_altclip.py new file mode 100644 index 0000000000000000000000000000000000000000..26b3f59280810b144356be4b43344f9ec9d17ed4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/modeling_altclip.py @@ -0,0 +1,1712 @@ +# coding=utf-8 +# Copyright 2022 The BAAI Teams Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch AltCLIP model.""" +import math +from dataclasses import dataclass +from typing import Any, List, Optional, Tuple, Union + +import torch +import torch.nn as nn +import torch.utils.checkpoint + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPastAndCrossAttentions, + BaseModelOutputWithPooling, + BaseModelOutputWithPoolingAndCrossAttentions, + BaseModelOutputWithPoolingAndProjection, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ModelOutput, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_altclip import AltCLIPConfig, AltCLIPTextConfig, AltCLIPVisionConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "BAAI/AltCLIP" +_CONFIG_FOR_DOC = "AltCLIPConfig" + +ALTCLIP_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "BAAI/AltCLIP", + # See all AltCLIP models at https://huggingface.co/models?filter=altclip +] + + +ALTCLIP_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`CLIPConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +ALTCLIP_TEXT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +ALTCLIP_VISION_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +ALTCLIP_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. + return_loss (`bool`, *optional*): + Whether or not to return the contrastive loss. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# contrastive loss function, adapted from +# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html +def contrastive_loss(logits: torch.Tensor) -> torch.Tensor: + return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device)) + + +def clip_loss(similarity: torch.Tensor) -> torch.Tensor: + caption_loss = contrastive_loss(similarity) + image_loss = contrastive_loss(similarity.t()) + return (caption_loss + image_loss) / 2.0 + + +@dataclass +# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP +class AltCLIPOutput(ModelOutput): + """ + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): + Contrastive loss for image-text similarity. + logits_per_image:(`torch.FloatTensor` of shape `(image_batch_size, text_batch_size)`): + The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text + similarity scores. + logits_per_text:(`torch.FloatTensor` of shape `(text_batch_size, image_batch_size)`): + The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image + similarity scores. + text_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The text embeddings obtained by applying the projection layer to the pooled output of [`AltCLIPTextModel`]. + image_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The image embeddings obtained by applying the projection layer to the pooled output of + [`AltCLIPVisionModel`]. + text_model_output(`BaseModelOutputWithPooling`): + The output of the [`AltCLIPTextModel`]. + vision_model_output(`BaseModelOutputWithPooling`): + The output of the [`AltCLIPVisionModel`]. + """ + + loss: Optional[torch.FloatTensor] = None + logits_per_image: torch.FloatTensor = None + logits_per_text: torch.FloatTensor = None + text_embeds: torch.FloatTensor = None + image_embeds: torch.FloatTensor = None + text_model_output: BaseModelOutputWithPooling = None + vision_model_output: BaseModelOutputWithPooling = None + + def to_tuple(self) -> Tuple[Any]: + return tuple( + self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple() + for k in self.keys() + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->AltRoberta +class AltRobertaEmbeddings(nn.Module): + """ + Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. + """ + + # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # End copy + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 + ): + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + def create_position_ids_from_inputs_embeds(self, inputs_embeds): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->AltRoberta +class AltRobertaSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in AltRobertaModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput +class AltRobertaSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaAttention with Roberta->AltRoberta +class AltRobertaAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = AltRobertaSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = AltRobertaSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self( + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate with Roberta->AltRoberta +class AltRobertaIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaOutput +class AltRobertaOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaLayer with Roberta->AltRoberta +class AltRobertaLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = AltRobertaAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = AltRobertaAttention(config, position_embedding_type="absolute") + self.intermediate = AltRobertaIntermediate(config) + self.output = AltRobertaOutput(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->AltRoberta +class AltRobertaEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([AltRobertaLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaPooler +class AltRobertaPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +# Copied from transformers.models.clip.modeling_clip.CLIPAttention with CLIP->AltCLIP +class AltCLIPAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.num_heads = config.num_attention_heads + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {self.num_heads})." + ) + self.scale = self.head_dim**-0.5 + self.dropout = config.attention_dropout + + self.k_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.v_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.q_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.out_proj = nn.Linear(self.embed_dim, self.embed_dim) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + bsz, tgt_len, embed_dim = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scale + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + # apply the causal_attention_mask first + if causal_attention_mask is not None: + if causal_attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {causal_attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + causal_attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if output_attentions: + # this operation is a bit akward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + attn_output = attn_output.reshape(bsz, tgt_len, embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped + + +# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->AltCLIP +class AltCLIPMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.activation_fn = ACT2FN[config.hidden_act] + self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size) + self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.fc1(hidden_states) + hidden_states = self.activation_fn(hidden_states) + hidden_states = self.fc2(hidden_states) + return hidden_states + + +# Copied from transformers.models.clip.modeling_clip.CLIPEncoderLayer with CLIP->AltCLIP +class AltCLIPEncoderLayer(nn.Module): + def __init__(self, config: AltCLIPConfig): + super().__init__() + self.embed_dim = config.hidden_size + self.self_attn = AltCLIPAttention(config) + self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.mlp = AltCLIPMLP(config) + self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + causal_attention_mask: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.FloatTensor]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + `(config.encoder_attention_heads,)`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + hidden_states = self.layer_norm1(hidden_states) + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + causal_attention_mask=causal_attention_mask, + output_attentions=output_attentions, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.layer_norm2(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +# Copied from transformers.models.clip.modeling_clip.CLIPEncoder with CLIP->AltCLIP +class AltCLIPEncoder(nn.Module): + """ + Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a + [`AltCLIPEncoderLayer`]. + + Args: + config: AltCLIPConfig + """ + + def __init__(self, config: AltCLIPConfig): + super().__init__() + self.config = config + self.layers = nn.ModuleList([AltCLIPEncoderLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + inputs_embeds, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + causal_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Causal mask for the text model. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + hidden_states = inputs_embeds + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + attention_mask, + causal_attention_mask, + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + causal_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +# Copied from transformers.models.clip.modeling_clip.CLIPVisionEmbeddings with CLIP->AltCLIP +class AltCLIPVisionEmbeddings(nn.Module): + def __init__(self, config: AltCLIPVisionConfig): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.image_size = config.image_size + self.patch_size = config.patch_size + + self.class_embedding = nn.Parameter(torch.randn(self.embed_dim)) + + self.patch_embedding = nn.Conv2d( + in_channels=config.num_channels, + out_channels=self.embed_dim, + kernel_size=self.patch_size, + stride=self.patch_size, + bias=False, + ) + + self.num_patches = (self.image_size // self.patch_size) ** 2 + self.num_positions = self.num_patches + 1 + self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim) + self.register_buffer("position_ids", torch.arange(self.num_positions).expand((1, -1))) + + def forward(self, pixel_values: torch.FloatTensor) -> torch.Tensor: + batch_size = pixel_values.shape[0] + patch_embeds = self.patch_embedding(pixel_values) # shape = [*, width, grid, grid] + patch_embeds = patch_embeds.flatten(2).transpose(1, 2) + + class_embeds = self.class_embedding.expand(batch_size, 1, -1) + embeddings = torch.cat([class_embeds, patch_embeds], dim=1) + embeddings = embeddings + self.position_embedding(self.position_ids) + return embeddings + + +class AltCLIPPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = AltCLIPConfig + base_model_prefix = "altclip" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + factor = self.config.initializer_factor + if isinstance(module, AltCLIPVisionEmbeddings): + factor = self.config.initializer_factor + nn.init.normal_(module.class_embedding, mean=0.0, std=module.embed_dim**-0.5 * factor) + nn.init.normal_(module.patch_embedding.weight, std=module.config.initializer_range * factor) + nn.init.normal_(module.position_embedding.weight, std=module.config.initializer_range * factor) + elif isinstance(module, AltCLIPAttention): + factor = self.config.initializer_factor + in_proj_std = (module.embed_dim**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + out_proj_std = (module.embed_dim**-0.5) * factor + nn.init.normal_(module.q_proj.weight, std=in_proj_std) + nn.init.normal_(module.k_proj.weight, std=in_proj_std) + nn.init.normal_(module.v_proj.weight, std=in_proj_std) + nn.init.normal_(module.out_proj.weight, std=out_proj_std) + elif isinstance(module, AltCLIPMLP): + factor = self.config.initializer_factor + in_proj_std = ( + (module.config.hidden_size**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + ) + fc_std = (2 * module.config.hidden_size) ** -0.5 * factor + nn.init.normal_(module.fc1.weight, std=fc_std) + nn.init.normal_(module.fc2.weight, std=in_proj_std) + elif isinstance(module, AltCLIPModel): + nn.init.normal_( + module.text_projection.weight, + std=module.text_embed_dim**-0.5 * self.config.initializer_factor, + ) + module.text_projection._is_hf_initialized = True + nn.init.normal_( + module.visual_projection.weight, + std=module.vision_embed_dim**-0.5 * self.config.initializer_factor, + ) + module.visual_projection._is_hf_initialized = True + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_factor) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_factor) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, AltCLIPEncoder): + module.gradient_checkpointing = value + if isinstance(module, AltRobertaEncoder): + module.gradient_checkpointing = value + + +# Copied from transformers.models.clip.modeling_clip.CLIPVisionTransformer with CLIPVisionTransformer->AltCLIPVisionTransformer,CLIPVisionConfig->AltCLIPVisionConfig,CLIPVisionEmbeddings->AltCLIPVisionEmbeddings,CLIPEncoder->AltCLIPEncoder,CLIP_VISION_INPUTS_DOCSTRING->ALTCLIP_VISION_INPUTS_DOCSTRING +class AltCLIPVisionTransformer(nn.Module): + def __init__(self, config: AltCLIPVisionConfig): + super().__init__() + self.config = config + embed_dim = config.hidden_size + + self.embeddings = AltCLIPVisionEmbeddings(config) + self.pre_layrnorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + self.encoder = AltCLIPEncoder(config) + self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + + @add_start_docstrings_to_model_forward(ALTCLIP_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=AltCLIPVisionConfig) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + hidden_states = self.embeddings(pixel_values) + hidden_states = self.pre_layrnorm(hidden_states) + + encoder_outputs = self.encoder( + inputs_embeds=hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_state = encoder_outputs[0] + pooled_output = last_hidden_state[:, 0, :] + pooled_output = self.post_layernorm(pooled_output) + + if not return_dict: + return (last_hidden_state, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=last_hidden_state, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class AltCLIPVisionModel(AltCLIPPreTrainedModel): + config_class = AltCLIPVisionConfig + main_input_name = "pixel_values" + + def __init__(self, config: AltCLIPVisionConfig): + super().__init__(config) + self.vision_model = AltCLIPVisionTransformer(config) + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.vision_model.embeddings.patch_embedding + + @add_start_docstrings_to_model_forward(ALTCLIP_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=AltCLIPVisionConfig) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AltCLIPVisionModel + + >>> model = AltCLIPVisionModel.from_pretrained("BAAI/AltCLIP") + >>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP") + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> inputs = processor(images=image, return_tensors="pt") + + >>> outputs = model(**inputs) + >>> last_hidden_state = outputs.last_hidden_state + >>> pooled_output = outputs.pooler_output # pooled CLS states + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + return self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +class AltRobertaModel(AltCLIPPreTrainedModel): + """ + + The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of + cross-attention is added between the self-attention layers, following the architecture described in *Attention is + all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz + Kaiser and Illia Polosukhin. + + To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set + to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. + + .. _*Attention is all you need*: https://arxiv.org/abs/1706.03762 + + """ + + config_class = AltCLIPTextConfig + + # Copied from transformers.models.bert.modeling_bert.BertModel.__init__ with Bert->AltRoberta + def __init__(self, config, add_pooling_layer=True): + super().__init__(config) + self.config = config + + self.embeddings = AltRobertaEmbeddings(config) + self.encoder = AltRobertaEncoder(config) + + self.pooler = AltRobertaPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + # Copied from transformers.models.bert.modeling_bert.BertModel.forward + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache + else: + use_cache = False + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.is_decoder and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_extended_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + encoder_outputs = self.encoder( + embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +class AltCLIPTextModel(AltCLIPPreTrainedModel): + config_class = AltCLIPTextConfig + + def __init__(self, config): + super().__init__(config) + self.roberta = AltRobertaModel(config, add_pooling_layer=False) + self.transformation = nn.Linear(config.hidden_size, config.project_dim) + self.pre_LN = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.roberta.embeddings.word_embeddings + + def set_input_embeddings(self, value: nn.Embedding) -> None: + self.roberta.embeddings.word_embeddings = value + + def resize_token_embeddings(self, new_num_tokens: Optional[int] = None) -> nn.Embedding: + return super().resize_token_embeddings(new_num_tokens) + + @add_start_docstrings_to_model_forward(ALTCLIP_TEXT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPoolingAndProjection, config_class=AltCLIPTextConfig) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + return_dict: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + ): + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoProcessor, AltCLIPTextModel + + >>> model = AltCLIPTextModel.from_pretrained("BAAI/AltCLIP") + >>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP") + + >>> texts = ["it's a cat", "it's a dog"] + + >>> inputs = processor(text=texts, padding=True, return_tensors="pt") + + >>> outputs = model(**inputs) + >>> last_hidden_state = outputs.last_hidden_state + >>> pooled_output = outputs.pooler_output # pooled CLS states + ```""" + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + # last module outputs + sequence_output = outputs[0] + + # project every module + sequence_output = self.pre_LN(sequence_output) + + # pooler + projection_state = self.transformation(sequence_output) + pooler_output = projection_state[:, 0] + + if not return_dict: + return (projection_state, pooler_output) + outputs[2:4] + + return BaseModelOutputWithPoolingAndProjection( + last_hidden_state=projection_state, + pooler_output=pooler_output, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class AltCLIPModel(AltCLIPPreTrainedModel): + config_class = AltCLIPConfig + + def __init__(self, config: AltCLIPConfig): + super().__init__(config) + + if not isinstance(config.vision_config, AltCLIPVisionConfig): + raise ValueError( + "config.vision_config is expected to be of type AltCLIPVisionConfig but is of type" + f" {type(config.vision_config)}." + ) + if not isinstance(config.text_config, AltCLIPTextConfig): + raise ValueError( + "config.text_config is expected to be of type AltCLIPTextConfig but is of type" + f" {type(config.text_config)}." + ) + + text_config = config.text_config + vision_config = config.vision_config + + self.projection_dim = config.projection_dim + self.text_embed_dim = text_config.project_dim + self.vision_embed_dim = vision_config.hidden_size + + self.text_model = AltCLIPTextModel(text_config) + self.vision_model = AltCLIPVisionTransformer(vision_config) + + self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False) + self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False) + self.logit_scale = nn.Parameter(torch.ones([]) * self.config.logit_scale_init_value) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ALTCLIP_TEXT_INPUTS_DOCSTRING) + def get_text_features( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + token_type_ids=None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + text_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The text embeddings obtained by + applying the projection layer to the pooled output of [`AltCLIPTextModel`]. + + Examples: + + ```python + >>> from transformers import AutoProcessor, AltCLIPModel + + >>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP") + >>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP") + >>> inputs = processor(text=["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt") + >>> text_features = model.get_text_features(**inputs) + ```""" + # Use AltCLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + token_type_ids=token_type_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + pooled_output = text_outputs[1] + text_features = self.text_projection(pooled_output) + + return text_features + + @add_start_docstrings_to_model_forward(ALTCLIP_VISION_INPUTS_DOCSTRING) + def get_image_features( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + image_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The image embeddings obtained by + applying the projection layer to the pooled output of [`AltCLIPVisionModel`]. + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AltCLIPModel + + >>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP") + >>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP") + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + >>> inputs = processor(images=image, return_tensors="pt") + >>> image_features = model.get_image_features(**inputs) + ```""" + # Use AltCLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = vision_outputs[1] # pooled_output + image_features = self.visual_projection(pooled_output) + + return image_features + + @add_start_docstrings_to_model_forward(ALTCLIP_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=AltCLIPOutput, config_class=AltCLIPConfig) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + token_type_ids=None, + return_loss: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, AltCLIPOutput]: + r""" + Returns: + + Examples: + + ```python + >>> from PIL import Image + >>> import requests + >>> from transformers import AutoProcessor, AltCLIPModel + + >>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP") + >>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP") + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + >>> inputs = processor( + ... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True + ... ) + >>> outputs = model(**inputs) + >>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score + >>> probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities + ```""" + # Use AltCLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + image_embeds = vision_outputs[1] + image_embeds = self.visual_projection(image_embeds) + + text_embeds = text_outputs[1] + text_embeds = self.text_projection(text_embeds) + + # normalized features + image_embeds = image_embeds / image_embeds.norm(p=2, dim=-1, keepdim=True) + text_embeds = text_embeds / text_embeds.norm(p=2, dim=-1, keepdim=True) + + # cosine similarity as logits + logit_scale = self.logit_scale.exp() + logits_per_text = torch.matmul(text_embeds, image_embeds.t()) * logit_scale + logits_per_image = logits_per_text.T + + loss = None + if return_loss: + loss = clip_loss(logits_per_text) + + if not return_dict: + output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs) + return ((loss,) + output) if loss is not None else output + + return AltCLIPOutput( + loss=loss, + logits_per_image=logits_per_image, + logits_per_text=logits_per_text, + text_embeds=text_embeds, + image_embeds=image_embeds, + text_model_output=text_outputs, + vision_model_output=vision_outputs, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids +def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/processing_altclip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/processing_altclip.py new file mode 100644 index 0000000000000000000000000000000000000000..8fe49ad678e9c81efd7d34b7d3f952816bea2752 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/altclip/processing_altclip.py @@ -0,0 +1,130 @@ +# coding=utf-8 +# Copyright 2022 WenXiang ZhongzhiCheng LedellWu LiuGuang BoWenZhang The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Image/Text processor class for AltCLIP +""" +import warnings + +from ...processing_utils import ProcessorMixin +from ...tokenization_utils_base import BatchEncoding + + +class AltCLIPProcessor(ProcessorMixin): + r""" + Constructs a AltCLIP processor which wraps a CLIP image processor and a XLM-Roberta tokenizer into a single + processor. + + [`AltCLIPProcessor`] offers all the functionalities of [`CLIPImageProcessor`] and [`XLMRobertaTokenizerFast`]. See + the [`~AltCLIPProcessor.__call__`] and [`~AltCLIPProcessor.decode`] for more information. + + Args: + image_processor ([`CLIPImageProcessor`]): + The image processor is a required input. + tokenizer ([`XLMRobertaTokenizerFast`]): + The tokenizer is a required input. + """ + attributes = ["image_processor", "tokenizer"] + image_processor_class = "CLIPImageProcessor" + tokenizer_class = ("XLMRobertaTokenizer", "XLMRobertaTokenizerFast") + + def __init__(self, image_processor=None, tokenizer=None, **kwargs): + if "feature_extractor" in kwargs: + warnings.warn( + "The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`" + " instead.", + FutureWarning, + ) + feature_extractor = kwargs.pop("feature_extractor") + + image_processor = image_processor if image_processor is not None else feature_extractor + if image_processor is None: + raise ValueError("You need to specify an `image_processor`.") + if tokenizer is None: + raise ValueError("You need to specify a `tokenizer`.") + + super().__init__(image_processor, tokenizer) + + def __call__(self, text=None, images=None, return_tensors=None, **kwargs): + """ + Main method to prepare for the model one or several sequences(s) and image(s). This method forwards the `text` + and `kwargs` arguments to XLMRobertaTokenizerFast's [`~XLMRobertaTokenizerFast.__call__`] if `text` is not + `None` to encode the text. To prepare the image(s), this method forwards the `images` and `kwrags` arguments to + CLIPImageProcessor's [`~CLIPImageProcessor.__call__`] if `images` is not `None`. Please refer to the doctsring + of the above two methods for more information. + + Args: + text (`str`, `List[str]`, `List[List[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. In case of a NumPy array/PyTorch tensor, each image should be of shape (C, H, W), where C is a + number of channels, H and W are image height and width. + + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`. + """ + + if text is None and images is None: + raise ValueError("You have to specify either text or images. Both cannot be none.") + + if text is not None: + encoding = self.tokenizer(text, return_tensors=return_tensors, **kwargs) + + if images is not None: + image_features = self.image_processor(images, return_tensors=return_tensors, **kwargs) + + if text is not None and images is not None: + encoding["pixel_values"] = image_features.pixel_values + return encoding + elif text is not None: + return encoding + else: + return BatchEncoding(data=dict(**image_features), tensor_type=return_tensors) + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to XLMRobertaTokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. + Please refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to XLMRobertaTokenizerFast's [`~PreTrainedTokenizer.decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + image_processor_input_names = self.image_processor.model_input_names + return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9aa42423cf5fda81a4678532c811a38600275255 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/__init__.py @@ -0,0 +1,78 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_speech_available, is_torch_available + + +_import_structure = { + "configuration_audio_spectrogram_transformer": [ + "AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP", + "ASTConfig", + ] +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_audio_spectrogram_transformer"] = [ + "AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST", + "ASTForAudioClassification", + "ASTModel", + "ASTPreTrainedModel", + ] + +try: + if not is_speech_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_audio_spectrogram_transformer"] = ["ASTFeatureExtractor"] + +if TYPE_CHECKING: + from .configuration_audio_spectrogram_transformer import ( + AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, + ASTConfig, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_audio_spectrogram_transformer import ( + AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST, + ASTForAudioClassification, + ASTModel, + ASTPreTrainedModel, + ) + + try: + if not is_speech_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_audio_spectrogram_transformer import ASTFeatureExtractor + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/configuration_audio_spectrogram_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/configuration_audio_spectrogram_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..22b0ca70ac8520bb8920411009dada8d7abf528d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/configuration_audio_spectrogram_transformer.py @@ -0,0 +1,126 @@ +# coding=utf-8 +# Copyright 2022 Google AI and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Audio Spectogram Transformer (AST) model configuration""" + + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "MIT/ast-finetuned-audioset-10-10-0.4593": ( + "https://huggingface.co/MIT/ast-finetuned-audioset-10-10-0.4593/resolve/main/config.json" + ), +} + + +class ASTConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`ASTModel`]. It is used to instantiate an AST + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the AST + [MIT/ast-finetuned-audioset-10-10-0.4593](https://huggingface.co/MIT/ast-finetuned-audioset-10-10-0.4593) + architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + patch_size (`int`, *optional*, defaults to `16`): + The size (resolution) of each patch. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + frequency_stride (`int`, *optional*, defaults to 10): + Frequency stride to use when patchifying the spectrograms. + time_stride (`int`, *optional*, defaults to 10): + Temporal stride to use when patchifying the spectrograms. + max_length (`int`, *optional*, defaults to 1024): + Temporal dimension of the spectrograms. + num_mel_bins (`int`, *optional*, defaults to 128): + Frequency dimension of the spectrograms (number of Mel-frequency bins). + + Example: + + ```python + >>> from transformers import ASTConfig, ASTModel + + >>> # Initializing a AST MIT/ast-finetuned-audioset-10-10-0.4593 style configuration + >>> configuration = ASTConfig() + + >>> # Initializing a model (with random weights) from the MIT/ast-finetuned-audioset-10-10-0.4593 style configuration + >>> model = ASTModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "audio-spectrogram-transformer" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + patch_size=16, + qkv_bias=True, + frequency_stride=10, + time_stride=10, + max_length=1024, + num_mel_bins=128, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.patch_size = patch_size + self.qkv_bias = qkv_bias + self.frequency_stride = frequency_stride + self.time_stride = time_stride + self.max_length = max_length + self.num_mel_bins = num_mel_bins diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/convert_audio_spectrogram_transformer_original_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/convert_audio_spectrogram_transformer_original_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..32e0f33d04fdb242bc4fc37c3906dee90510ebc4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/convert_audio_spectrogram_transformer_original_to_pytorch.py @@ -0,0 +1,279 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Audio Spectrogram Transformer checkpoints from the original repository. URL: https://github.com/YuanGongND/ast""" + + +import argparse +import json +from pathlib import Path + +import torch +import torchaudio +from datasets import load_dataset +from huggingface_hub import hf_hub_download + +from transformers import ASTConfig, ASTFeatureExtractor, ASTForAudioClassification +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_audio_spectrogram_transformer_config(model_name): + config = ASTConfig() + + if "10-10" in model_name: + pass + elif "speech-commands" in model_name: + config.max_length = 128 + elif "12-12" in model_name: + config.time_stride = 12 + config.frequency_stride = 12 + elif "14-14" in model_name: + config.time_stride = 14 + config.frequency_stride = 14 + elif "16-16" in model_name: + config.time_stride = 16 + config.frequency_stride = 16 + else: + raise ValueError("Model not supported") + + repo_id = "huggingface/label-files" + if "speech-commands" in model_name: + config.num_labels = 35 + filename = "speech-commands-v2-id2label.json" + else: + config.num_labels = 527 + filename = "audioset-id2label.json" + + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + return config + + +def rename_key(name): + if "module.v" in name: + name = name.replace("module.v", "audio_spectrogram_transformer") + if "cls_token" in name: + name = name.replace("cls_token", "embeddings.cls_token") + if "dist_token" in name: + name = name.replace("dist_token", "embeddings.distillation_token") + if "pos_embed" in name: + name = name.replace("pos_embed", "embeddings.position_embeddings") + if "patch_embed.proj" in name: + name = name.replace("patch_embed.proj", "embeddings.patch_embeddings.projection") + # transformer blocks + if "blocks" in name: + name = name.replace("blocks", "encoder.layer") + if "attn.proj" in name: + name = name.replace("attn.proj", "attention.output.dense") + if "attn" in name: + name = name.replace("attn", "attention.self") + if "norm1" in name: + name = name.replace("norm1", "layernorm_before") + if "norm2" in name: + name = name.replace("norm2", "layernorm_after") + if "mlp.fc1" in name: + name = name.replace("mlp.fc1", "intermediate.dense") + if "mlp.fc2" in name: + name = name.replace("mlp.fc2", "output.dense") + # final layernorm + if "audio_spectrogram_transformer.norm" in name: + name = name.replace("audio_spectrogram_transformer.norm", "audio_spectrogram_transformer.layernorm") + # classifier head + if "module.mlp_head.0" in name: + name = name.replace("module.mlp_head.0", "classifier.layernorm") + if "module.mlp_head.1" in name: + name = name.replace("module.mlp_head.1", "classifier.dense") + + return name + + +def convert_state_dict(orig_state_dict, config): + for key in orig_state_dict.copy().keys(): + val = orig_state_dict.pop(key) + + if "qkv" in key: + key_split = key.split(".") + layer_num = int(key_split[3]) + dim = config.hidden_size + if "weight" in key: + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.query.weight" + ] = val[:dim, :] + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.key.weight" + ] = val[dim : dim * 2, :] + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.value.weight" + ] = val[-dim:, :] + else: + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.query.bias" + ] = val[:dim] + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.key.bias" + ] = val[dim : dim * 2] + orig_state_dict[ + f"audio_spectrogram_transformer.encoder.layer.{layer_num}.attention.attention.value.bias" + ] = val[-dim:] + else: + orig_state_dict[rename_key(key)] = val + + return orig_state_dict + + +def remove_keys(state_dict): + ignore_keys = [ + "module.v.head.weight", + "module.v.head.bias", + "module.v.head_dist.weight", + "module.v.head_dist.bias", + ] + for k in ignore_keys: + state_dict.pop(k, None) + + +@torch.no_grad() +def convert_audio_spectrogram_transformer_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub=False): + """ + Copy/paste/tweak model's weights to our Audio Spectrogram Transformer structure. + """ + config = get_audio_spectrogram_transformer_config(model_name) + + model_name_to_url = { + "ast-finetuned-audioset-10-10-0.4593": ( + "https://www.dropbox.com/s/ca0b1v2nlxzyeb4/audioset_10_10_0.4593.pth?dl=1" + ), + "ast-finetuned-audioset-10-10-0.450": ( + "https://www.dropbox.com/s/1tv0hovue1bxupk/audioset_10_10_0.4495.pth?dl=1" + ), + "ast-finetuned-audioset-10-10-0.448": ( + "https://www.dropbox.com/s/6u5sikl4b9wo4u5/audioset_10_10_0.4483.pth?dl=1" + ), + "ast-finetuned-audioset-10-10-0.448-v2": ( + "https://www.dropbox.com/s/kt6i0v9fvfm1mbq/audioset_10_10_0.4475.pth?dl=1" + ), + "ast-finetuned-audioset-12-12-0.447": ( + "https://www.dropbox.com/s/snfhx3tizr4nuc8/audioset_12_12_0.4467.pth?dl=1" + ), + "ast-finetuned-audioset-14-14-0.443": ( + "https://www.dropbox.com/s/z18s6pemtnxm4k7/audioset_14_14_0.4431.pth?dl=1" + ), + "ast-finetuned-audioset-16-16-0.442": ( + "https://www.dropbox.com/s/mdsa4t1xmcimia6/audioset_16_16_0.4422.pth?dl=1" + ), + "ast-finetuned-speech-commands-v2": ( + "https://www.dropbox.com/s/q0tbqpwv44pquwy/speechcommands_10_10_0.9812.pth?dl=1" + ), + } + + # load original state_dict + checkpoint_url = model_name_to_url[model_name] + state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu") + # remove some keys + remove_keys(state_dict) + # rename some keys + new_state_dict = convert_state_dict(state_dict, config) + + # load 🤗 model + model = ASTForAudioClassification(config) + model.eval() + + model.load_state_dict(new_state_dict) + + # verify outputs on dummy input + # source: https://github.com/YuanGongND/ast/blob/79e873b8a54d0a3b330dd522584ff2b9926cd581/src/run.py#L62 + mean = -4.2677393 if "speech-commands" not in model_name else -6.845978 + std = 4.5689974 if "speech-commands" not in model_name else 5.5654526 + max_length = 1024 if "speech-commands" not in model_name else 128 + feature_extractor = ASTFeatureExtractor(mean=mean, std=std, max_length=max_length) + + if "speech-commands" in model_name: + dataset = load_dataset("speech_commands", "v0.02", split="validation") + waveform = dataset[0]["audio"]["array"] + else: + filepath = hf_hub_download( + repo_id="nielsr/audio-spectogram-transformer-checkpoint", + filename="sample_audio.flac", + repo_type="dataset", + ) + + waveform, _ = torchaudio.load(filepath) + waveform = waveform.squeeze().numpy() + + inputs = feature_extractor(waveform, sampling_rate=16000, return_tensors="pt") + + # forward pass + outputs = model(**inputs) + logits = outputs.logits + + if model_name == "ast-finetuned-audioset-10-10-0.4593": + expected_slice = torch.tensor([-0.8760, -7.0042, -8.6602]) + elif model_name == "ast-finetuned-audioset-10-10-0.450": + expected_slice = torch.tensor([-1.1986, -7.0903, -8.2718]) + elif model_name == "ast-finetuned-audioset-10-10-0.448": + expected_slice = torch.tensor([-2.6128, -8.0080, -9.4344]) + elif model_name == "ast-finetuned-audioset-10-10-0.448-v2": + expected_slice = torch.tensor([-1.5080, -7.4534, -8.8917]) + elif model_name == "ast-finetuned-audioset-12-12-0.447": + expected_slice = torch.tensor([-0.5050, -6.5833, -8.0843]) + elif model_name == "ast-finetuned-audioset-14-14-0.443": + expected_slice = torch.tensor([-0.3826, -7.0336, -8.2413]) + elif model_name == "ast-finetuned-audioset-16-16-0.442": + expected_slice = torch.tensor([-1.2113, -6.9101, -8.3470]) + elif model_name == "ast-finetuned-speech-commands-v2": + expected_slice = torch.tensor([6.1589, -8.0566, -8.7984]) + else: + raise ValueError("Unknown model name") + if not torch.allclose(logits[0, :3], expected_slice, atol=1e-4): + raise ValueError("Logits don't match") + print("Looks ok!") + + if pytorch_dump_folder_path is not None: + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + print(f"Saving model {model_name} to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + print("Pushing model and feature extractor to the hub...") + model.push_to_hub(f"MIT/{model_name}") + feature_extractor.push_to_hub(f"MIT/{model_name}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--model_name", + default="ast-finetuned-audioset-10-10-0.4593", + type=str, + help="Name of the Audio Spectrogram Transformer model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + + args = parser.parse_args() + convert_audio_spectrogram_transformer_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..deda2fc7781b2849c0d6e22883f6325727fb022b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py @@ -0,0 +1,197 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Feature extractor class for Audio Spectrogram Transformer. +""" + +from typing import List, Optional, Union + +import numpy as np +import torch +import torchaudio.compliance.kaldi as ta_kaldi + +from ...feature_extraction_sequence_utils import SequenceFeatureExtractor +from ...feature_extraction_utils import BatchFeature +from ...utils import TensorType, logging + + +logger = logging.get_logger(__name__) + + +class ASTFeatureExtractor(SequenceFeatureExtractor): + r""" + Constructs a Audio Spectrogram Transformer (AST) feature extractor. + + This feature extractor inherits from [`~feature_extraction_sequence_utils.SequenceFeatureExtractor`] which contains + most of the main methods. Users should refer to this superclass for more information regarding those methods. + + This class extracts mel-filter bank features from raw speech using TorchAudio, pads/truncates them to a fixed + length and normalizes them using a mean and standard deviation. + + Args: + feature_size (`int`, *optional*, defaults to 1): + The feature dimension of the extracted features. + sampling_rate (`int`, *optional*, defaults to 16000): + The sampling rate at which the audio files should be digitalized expressed in hertz (Hz). + num_mel_bins (`int`, *optional*, defaults to 128): + Number of Mel-frequency bins. + max_length (`int`, *optional*, defaults to 1024): + Maximum length to which to pad/truncate the extracted features. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether or not to normalize the log-Mel features using `mean` and `std`. + mean (`float`, *optional*, defaults to -4.2677393): + The mean value used to normalize the log-Mel features. Uses the AudioSet mean by default. + std (`float`, *optional*, defaults to 4.5689974): + The standard deviation value used to normalize the log-Mel features. Uses the AudioSet standard deviation + by default. + return_attention_mask (`bool`, *optional*, defaults to `False`): + Whether or not [`~ASTFeatureExtractor.__call__`] should return `attention_mask`. + """ + + model_input_names = ["input_values", "attention_mask"] + + def __init__( + self, + feature_size=1, + sampling_rate=16000, + num_mel_bins=128, + max_length=1024, + padding_value=0.0, + do_normalize=True, + mean=-4.2677393, + std=4.5689974, + return_attention_mask=False, + **kwargs, + ): + super().__init__(feature_size=feature_size, sampling_rate=sampling_rate, padding_value=padding_value, **kwargs) + self.num_mel_bins = num_mel_bins + self.max_length = max_length + self.do_normalize = do_normalize + self.mean = mean + self.std = std + self.return_attention_mask = return_attention_mask + + def _extract_fbank_features( + self, + waveform: np.ndarray, + max_length: int, + ) -> np.ndarray: + """ + Get mel-filter bank features using TorchAudio. Note that TorchAudio requires 16-bit signed integers as inputs + and hence the waveform should not be normalized before feature extraction. + """ + # waveform = waveform * (2**15) # Kaldi compliance: 16-bit signed integers + waveform = torch.from_numpy(waveform).unsqueeze(0) + fbank = ta_kaldi.fbank( + waveform, + htk_compat=True, + sample_frequency=self.sampling_rate, + use_energy=False, + window_type="hanning", + num_mel_bins=self.num_mel_bins, + dither=0.0, + frame_shift=10, + ) + + n_frames = fbank.shape[0] + difference = max_length - n_frames + + # pad or truncate, depending on difference + if difference > 0: + pad_module = torch.nn.ZeroPad2d((0, 0, 0, difference)) + fbank = pad_module(fbank) + elif difference < 0: + fbank = fbank[0:max_length, :] + + fbank = fbank.numpy() + + return fbank + + def normalize(self, input_values: np.ndarray) -> np.ndarray: + return (input_values - (self.mean)) / (self.std * 2) + + def __call__( + self, + raw_speech: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]], + sampling_rate: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + **kwargs, + ) -> BatchFeature: + """ + Main method to featurize and prepare for the model one or several sequence(s). + + Args: + raw_speech (`np.ndarray`, `List[float]`, `List[np.ndarray]`, `List[List[float]]`): + The sequence or batch of sequences to be padded. Each sequence can be a numpy array, a list of float + values, a list of numpy arrays or a list of list of float values. + sampling_rate (`int`, *optional*): + The sampling rate at which the `raw_speech` input was sampled. It is strongly recommended to pass + `sampling_rate` at the forward call to prevent silent errors. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + """ + + if sampling_rate is not None: + if sampling_rate != self.sampling_rate: + raise ValueError( + f"The model corresponding to this feature extractor: {self} was trained using a sampling rate of" + f" {self.sampling_rate}. Please make sure that the provided `raw_speech` input was sampled with" + f" {self.sampling_rate} and not {sampling_rate}." + ) + else: + logger.warning( + "It is strongly recommended to pass the `sampling_rate` argument to this function. " + "Failing to do so can result in silent errors that might be hard to debug." + ) + + is_batched = bool( + isinstance(raw_speech, (list, tuple)) + and (isinstance(raw_speech[0], np.ndarray) or isinstance(raw_speech[0], (tuple, list))) + ) + + if is_batched: + raw_speech = [np.asarray(speech, dtype=np.float32) for speech in raw_speech] + elif not is_batched and not isinstance(raw_speech, np.ndarray): + raw_speech = np.asarray(raw_speech, dtype=np.float32) + elif isinstance(raw_speech, np.ndarray) and raw_speech.dtype is np.dtype(np.float64): + raw_speech = raw_speech.astype(np.float32) + + # always return batch + if not is_batched: + raw_speech = [raw_speech] + + # extract fbank features and pad/truncate to max_length + features = [self._extract_fbank_features(waveform, max_length=self.max_length) for waveform in raw_speech] + + # convert into BatchFeature + padded_inputs = BatchFeature({"input_values": features}) + + # make sure list is in array format + input_values = padded_inputs.get("input_values") + if isinstance(input_values[0], list): + padded_inputs["input_values"] = [np.asarray(feature, dtype=np.float32) for feature in input_values] + + # normalization + if self.do_normalize: + padded_inputs["input_values"] = [self.normalize(feature) for feature in input_values] + + if return_tensors is not None: + padded_inputs = padded_inputs.convert_to_tensors(return_tensors) + + return padded_inputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..0f8c045121c74956b4c90a11483d35741ef9552c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/audio_spectrogram_transformer/modeling_audio_spectrogram_transformer.py @@ -0,0 +1,627 @@ +# coding=utf-8 +# Copyright 2022 MIT and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Audio Spectrogram Transformer (AST) model.""" + +import math +from typing import Dict, List, Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, SequenceClassifierOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_audio_spectrogram_transformer import ASTConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "ASTConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "MIT/ast-finetuned-audioset-10-10-0.4593" +_EXPECTED_OUTPUT_SHAPE = [1, 1214, 768] + +# Audio classification docstring +_SEQ_CLASS_CHECKPOINT = "MIT/ast-finetuned-audioset-10-10-0.4593" +_SEQ_CLASS_EXPECTED_OUTPUT = "'Speech'" +_SEQ_CLASS_EXPECTED_LOSS = 0.17 + + +AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "MIT/ast-finetuned-audioset-10-10-0.4593", + # See all Audio Spectrogram Transformer models at https://huggingface.co/models?filter=ast +] + + +class ASTEmbeddings(nn.Module): + """ + Construct the CLS token, position and patch embeddings. + """ + + def __init__(self, config: ASTConfig) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.distillation_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.patch_embeddings = ASTPatchEmbeddings(config) + + frequency_out_dimension, time_out_dimension = self.get_shape(config) + num_patches = frequency_out_dimension * time_out_dimension + self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 2, config.hidden_size)) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.config = config + + def get_shape(self, config): + # see Karpathy's cs231n blog on how to calculate the output dimensions + # https://cs231n.github.io/convolutional-networks/#conv + frequency_out_dimension = (config.num_mel_bins - config.patch_size) // config.frequency_stride + 1 + time_out_dimension = (config.max_length - config.patch_size) // config.time_stride + 1 + + return frequency_out_dimension, time_out_dimension + + def forward(self, input_values: torch.Tensor) -> torch.Tensor: + batch_size = input_values.shape[0] + embeddings = self.patch_embeddings(input_values) + + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + distillation_tokens = self.distillation_token.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, distillation_tokens, embeddings), dim=1) + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings) + + return embeddings + + +class ASTPatchEmbeddings(nn.Module): + """ + This class turns `input_values` into the initial `hidden_states` (patch embeddings) of shape `(batch_size, + seq_length, hidden_size)` to be consumed by a Transformer. + """ + + def __init__(self, config): + super().__init__() + + patch_size = config.patch_size + frequency_stride = config.frequency_stride + time_stride = config.time_stride + + self.projection = nn.Conv2d( + 1, config.hidden_size, kernel_size=(patch_size, patch_size), stride=(frequency_stride, time_stride) + ) + + def forward(self, input_values: torch.Tensor) -> torch.Tensor: + input_values = input_values.unsqueeze(1) + input_values = input_values.transpose(2, 3) + embeddings = self.projection(input_values).flatten(2).transpose(1, 2) + return embeddings + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfAttention with ViT->AST +class ASTSelfAttention(nn.Module): + def __init__(self, config: ASTConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfOutput with ViT->AST +class ASTSelfOutput(nn.Module): + """ + The residual connection is defined in ASTLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTAttention with ViT->AST +class ASTAttention(nn.Module): + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.attention = ASTSelfAttention(config) + self.output = ASTSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTIntermediate with ViT->AST +class ASTIntermediate(nn.Module): + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTOutput with ViT->AST +class ASTOutput(nn.Module): + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTLayer with ViT->AST +class ASTLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = ASTAttention(config) + self.intermediate = ASTIntermediate(config) + self.output = ASTOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in AST, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + hidden_states = attention_output + hidden_states + + # in AST, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTEncoder with ViT->AST +class ASTEncoder(nn.Module): + def __init__(self, config: ASTConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([ASTLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class ASTPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ASTConfig + base_model_prefix = "audio_spectrogram_transformer" + main_input_name = "input_values" + supports_gradient_checkpointing = True + + # Copied from transformers.models.deit.modeling_deit.DeiTPreTrainedModel._init_weights + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Upcast the input in `fp32` and cast it back to desired `dtype` to avoid + # `trunc_normal_cpu` not implemented in `half` issues + module.weight.data = nn.init.trunc_normal_( + module.weight.data.to(torch.float32), mean=0.0, std=self.config.initializer_range + ).to(module.weight.dtype) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + # Copied from transformers.models.vit.modeling_vit.ViTPreTrainedModel._set_gradient_checkpointing with ViT->AST + def _set_gradient_checkpointing(self, module: ASTEncoder, value: bool = False) -> None: + if isinstance(module, ASTEncoder): + module.gradient_checkpointing = value + + +AUDIO_SPECTROGRAM_TRANSFORMER_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`ASTConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +AUDIO_SPECTROGRAM_TRANSFORMER_INPUTS_DOCSTRING = r""" + Args: + input_values (`torch.FloatTensor` of shape `(batch_size, max_length, num_mel_bins)`): + Float values mel features extracted from the raw audio waveform. Raw audio waveform can be obtained by + loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via + the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`AutoFeatureExtractor`] should be used for extracting the mel features, padding and conversion into a + tensor of type `torch.FloatTensor`. See [`~ASTFeatureExtractor.__call__`] + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare AST Model transformer outputting raw hidden-states without any specific head on top.", + AUDIO_SPECTROGRAM_TRANSFORMER_START_DOCSTRING, +) +class ASTModel(ASTPreTrainedModel): + def __init__(self, config: ASTConfig): + super().__init__(config) + self.config = config + + self.embeddings = ASTEmbeddings(config) + self.encoder = ASTEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> ASTPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(AUDIO_SPECTROGRAM_TRANSFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + input_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_values is None: + raise ValueError("You have to specify input_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings(input_values) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + + pooled_output = (sequence_output[:, 0] + sequence_output[:, 1]) / 2 + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class ASTMLPHead(nn.Module): + def __init__(self, config: ASTConfig): + super().__init__() + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dense = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + def forward(self, hidden_state): + hidden_state = self.layernorm(hidden_state) + hidden_state = self.dense(hidden_state) + return hidden_state + + +@add_start_docstrings( + """ + Audio Spectrogram Transformer model with an audio classification head on top (a linear layer on top of the pooled + output) e.g. for datasets like AudioSet, Speech Commands v2. + """, + AUDIO_SPECTROGRAM_TRANSFORMER_START_DOCSTRING, +) +class ASTForAudioClassification(ASTPreTrainedModel): + def __init__(self, config: ASTConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.audio_spectrogram_transformer = ASTModel(config) + + # Classifier head + self.classifier = ASTMLPHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(AUDIO_SPECTROGRAM_TRANSFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_SEQ_CLASS_CHECKPOINT, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_SEQ_CLASS_EXPECTED_OUTPUT, + expected_loss=_SEQ_CLASS_EXPECTED_LOSS, + ) + def forward( + self, + input_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the audio classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.audio_spectrogram_transformer( + input_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7ea870a93317d4a9b2f7fda660345452703d72a7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/__init__.py @@ -0,0 +1,359 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_torch_available, +) + + +_import_structure = { + "auto_factory": ["get_values"], + "configuration_auto": ["ALL_PRETRAINED_CONFIG_ARCHIVE_MAP", "CONFIG_MAPPING", "MODEL_NAMES_MAPPING", "AutoConfig"], + "feature_extraction_auto": ["FEATURE_EXTRACTOR_MAPPING", "AutoFeatureExtractor"], + "image_processing_auto": ["IMAGE_PROCESSOR_MAPPING", "AutoImageProcessor"], + "processing_auto": ["PROCESSOR_MAPPING", "AutoProcessor"], + "tokenization_auto": ["TOKENIZER_MAPPING", "AutoTokenizer"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_auto"] = [ + "MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING", + "MODEL_FOR_AUDIO_XVECTOR_MAPPING", + "MODEL_FOR_BACKBONE_MAPPING", + "MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING", + "MODEL_FOR_CAUSAL_LM_MAPPING", + "MODEL_FOR_CTC_MAPPING", + "MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING", + "MODEL_FOR_DEPTH_ESTIMATION_MAPPING", + "MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING", + "MODEL_FOR_IMAGE_SEGMENTATION_MAPPING", + "MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING", + "MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING", + "MODEL_FOR_MASKED_LM_MAPPING", + "MODEL_FOR_MASK_GENERATION_MAPPING", + "MODEL_FOR_MULTIPLE_CHOICE_MAPPING", + "MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING", + "MODEL_FOR_OBJECT_DETECTION_MAPPING", + "MODEL_FOR_PRETRAINING_MAPPING", + "MODEL_FOR_QUESTION_ANSWERING_MAPPING", + "MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING", + "MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING", + "MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING", + "MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING", + "MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING", + "MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING", + "MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING", + "MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING", + "MODEL_FOR_VISION_2_SEQ_MAPPING", + "MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING", + "MODEL_MAPPING", + "MODEL_WITH_LM_HEAD_MAPPING", + "MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING", + "MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING", + "AutoModel", + "AutoBackbone", + "AutoModelForAudioClassification", + "AutoModelForAudioFrameClassification", + "AutoModelForAudioXVector", + "AutoModelForCausalLM", + "AutoModelForCTC", + "AutoModelForDepthEstimation", + "AutoModelForImageClassification", + "AutoModelForImageSegmentation", + "AutoModelForInstanceSegmentation", + "AutoModelForMaskGeneration", + "AutoModelForMaskedImageModeling", + "AutoModelForMaskedLM", + "AutoModelForMultipleChoice", + "AutoModelForNextSentencePrediction", + "AutoModelForObjectDetection", + "AutoModelForPreTraining", + "AutoModelForQuestionAnswering", + "AutoModelForSemanticSegmentation", + "AutoModelForSeq2SeqLM", + "AutoModelForSequenceClassification", + "AutoModelForSpeechSeq2Seq", + "AutoModelForTableQuestionAnswering", + "AutoModelForTokenClassification", + "AutoModelForUniversalSegmentation", + "AutoModelForVideoClassification", + "AutoModelForVision2Seq", + "AutoModelForVisualQuestionAnswering", + "AutoModelForDocumentQuestionAnswering", + "AutoModelWithLMHead", + "AutoModelForZeroShotImageClassification", + "AutoModelForZeroShotObjectDetection", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_auto"] = [ + "TF_MODEL_FOR_CAUSAL_LM_MAPPING", + "TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING", + "TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING", + "TF_MODEL_FOR_MASKED_LM_MAPPING", + "TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING", + "TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING", + "TF_MODEL_FOR_PRETRAINING_MAPPING", + "TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING", + "TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING", + "TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING", + "TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING", + "TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING", + "TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING", + "TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING", + "TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING", + "TF_MODEL_FOR_VISION_2_SEQ_MAPPING", + "TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING", + "TF_MODEL_MAPPING", + "TF_MODEL_WITH_LM_HEAD_MAPPING", + "TFAutoModel", + "TFAutoModelForCausalLM", + "TFAutoModelForImageClassification", + "TFAutoModelForMaskedLM", + "TFAutoModelForMultipleChoice", + "TFAutoModelForNextSentencePrediction", + "TFAutoModelForPreTraining", + "TFAutoModelForDocumentQuestionAnswering", + "TFAutoModelForQuestionAnswering", + "TFAutoModelForSemanticSegmentation", + "TFAutoModelForSeq2SeqLM", + "TFAutoModelForSequenceClassification", + "TFAutoModelForSpeechSeq2Seq", + "TFAutoModelForTableQuestionAnswering", + "TFAutoModelForTokenClassification", + "TFAutoModelForVision2Seq", + "TFAutoModelForZeroShotImageClassification", + "TFAutoModelWithLMHead", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_auto"] = [ + "FLAX_MODEL_FOR_CAUSAL_LM_MAPPING", + "FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING", + "FLAX_MODEL_FOR_MASKED_LM_MAPPING", + "FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING", + "FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING", + "FLAX_MODEL_FOR_PRETRAINING_MAPPING", + "FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING", + "FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING", + "FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING", + "FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING", + "FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING", + "FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING", + "FLAX_MODEL_MAPPING", + "FlaxAutoModel", + "FlaxAutoModelForCausalLM", + "FlaxAutoModelForImageClassification", + "FlaxAutoModelForMaskedLM", + "FlaxAutoModelForMultipleChoice", + "FlaxAutoModelForNextSentencePrediction", + "FlaxAutoModelForPreTraining", + "FlaxAutoModelForQuestionAnswering", + "FlaxAutoModelForSeq2SeqLM", + "FlaxAutoModelForSequenceClassification", + "FlaxAutoModelForSpeechSeq2Seq", + "FlaxAutoModelForTokenClassification", + "FlaxAutoModelForVision2Seq", + ] + + +if TYPE_CHECKING: + from .auto_factory import get_values + from .configuration_auto import ALL_PRETRAINED_CONFIG_ARCHIVE_MAP, CONFIG_MAPPING, MODEL_NAMES_MAPPING, AutoConfig + from .feature_extraction_auto import FEATURE_EXTRACTOR_MAPPING, AutoFeatureExtractor + from .image_processing_auto import IMAGE_PROCESSOR_MAPPING, AutoImageProcessor + from .processing_auto import PROCESSOR_MAPPING, AutoProcessor + from .tokenization_auto import TOKENIZER_MAPPING, AutoTokenizer + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_auto import ( + MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING, + MODEL_FOR_AUDIO_XVECTOR_MAPPING, + MODEL_FOR_BACKBONE_MAPPING, + MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING, + MODEL_FOR_CAUSAL_LM_MAPPING, + MODEL_FOR_CTC_MAPPING, + MODEL_FOR_DEPTH_ESTIMATION_MAPPING, + MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + MODEL_FOR_IMAGE_SEGMENTATION_MAPPING, + MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING, + MODEL_FOR_MASK_GENERATION_MAPPING, + MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING, + MODEL_FOR_MASKED_LM_MAPPING, + MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING, + MODEL_FOR_OBJECT_DETECTION_MAPPING, + MODEL_FOR_PRETRAINING_MAPPING, + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING, + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, + MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING, + MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING, + MODEL_FOR_VISION_2_SEQ_MAPPING, + MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING, + MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING, + MODEL_MAPPING, + MODEL_WITH_LM_HEAD_MAPPING, + AutoBackbone, + AutoModel, + AutoModelForAudioClassification, + AutoModelForAudioFrameClassification, + AutoModelForAudioXVector, + AutoModelForCausalLM, + AutoModelForCTC, + AutoModelForDepthEstimation, + AutoModelForDocumentQuestionAnswering, + AutoModelForImageClassification, + AutoModelForImageSegmentation, + AutoModelForInstanceSegmentation, + AutoModelForMaskedImageModeling, + AutoModelForMaskedLM, + AutoModelForMaskGeneration, + AutoModelForMultipleChoice, + AutoModelForNextSentencePrediction, + AutoModelForObjectDetection, + AutoModelForPreTraining, + AutoModelForQuestionAnswering, + AutoModelForSemanticSegmentation, + AutoModelForSeq2SeqLM, + AutoModelForSequenceClassification, + AutoModelForSpeechSeq2Seq, + AutoModelForTableQuestionAnswering, + AutoModelForTokenClassification, + AutoModelForUniversalSegmentation, + AutoModelForVideoClassification, + AutoModelForVision2Seq, + AutoModelForVisualQuestionAnswering, + AutoModelForZeroShotImageClassification, + AutoModelForZeroShotObjectDetection, + AutoModelWithLMHead, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_auto import ( + TF_MODEL_FOR_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING, + TF_MODEL_FOR_MASKED_LM_MAPPING, + TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING, + TF_MODEL_FOR_PRETRAINING_MAPPING, + TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING, + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, + TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_VISION_2_SEQ_MAPPING, + TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING, + TF_MODEL_MAPPING, + TF_MODEL_WITH_LM_HEAD_MAPPING, + TFAutoModel, + TFAutoModelForCausalLM, + TFAutoModelForDocumentQuestionAnswering, + TFAutoModelForImageClassification, + TFAutoModelForMaskedLM, + TFAutoModelForMultipleChoice, + TFAutoModelForNextSentencePrediction, + TFAutoModelForPreTraining, + TFAutoModelForQuestionAnswering, + TFAutoModelForSemanticSegmentation, + TFAutoModelForSeq2SeqLM, + TFAutoModelForSequenceClassification, + TFAutoModelForSpeechSeq2Seq, + TFAutoModelForTableQuestionAnswering, + TFAutoModelForTokenClassification, + TFAutoModelForVision2Seq, + TFAutoModelForZeroShotImageClassification, + TFAutoModelWithLMHead, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_auto import ( + FLAX_MODEL_FOR_CAUSAL_LM_MAPPING, + FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + FLAX_MODEL_FOR_MASKED_LM_MAPPING, + FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING, + FLAX_MODEL_FOR_PRETRAINING_MAPPING, + FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, + FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING, + FLAX_MODEL_MAPPING, + FlaxAutoModel, + FlaxAutoModelForCausalLM, + FlaxAutoModelForImageClassification, + FlaxAutoModelForMaskedLM, + FlaxAutoModelForMultipleChoice, + FlaxAutoModelForNextSentencePrediction, + FlaxAutoModelForPreTraining, + FlaxAutoModelForQuestionAnswering, + FlaxAutoModelForSeq2SeqLM, + FlaxAutoModelForSequenceClassification, + FlaxAutoModelForSpeechSeq2Seq, + FlaxAutoModelForTokenClassification, + FlaxAutoModelForVision2Seq, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/auto_factory.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/auto_factory.py new file mode 100644 index 0000000000000000000000000000000000000000..17cc7f95799fae131128037f98a988aba959e0ae --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/auto_factory.py @@ -0,0 +1,670 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Factory function to build auto-model classes.""" +import copy +import importlib +from collections import OrderedDict + +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...utils import copy_func, logging +from .configuration_auto import AutoConfig, model_type_to_module_name, replace_list_option_in_docstrings + + +logger = logging.get_logger(__name__) + + +CLASS_DOCSTRING = """ + This is a generic model class that will be instantiated as one of the model classes of the library when created + with the [`~BaseAutoModelClass.from_pretrained`] class method or the [`~BaseAutoModelClass.from_config`] class + method. + + This class cannot be instantiated directly using `__init__()` (throws an error). +""" + +FROM_CONFIG_DOCSTRING = """ + Instantiates one of the model classes of the library from a configuration. + + Note: + Loading a model from its configuration file does **not** load the model weights. It only affects the + model's configuration. Use [`~BaseAutoModelClass.from_pretrained`] to load the model weights. + + Args: + config ([`PretrainedConfig`]): + The model class to instantiate is selected based on the configuration class: + + List options + + Examples: + + ```python + >>> from transformers import AutoConfig, BaseAutoModelClass + + >>> # Download configuration from huggingface.co and cache. + >>> config = AutoConfig.from_pretrained("checkpoint_placeholder") + >>> model = BaseAutoModelClass.from_config(config) + ``` +""" + +FROM_PRETRAINED_TORCH_DOCSTRING = """ + Instantiate one of the model classes of the library from a pretrained model. + + The model class to instantiate is selected based on the `model_type` property of the config object (either + passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by + falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + The model is set in evaluation mode by default using `model.eval()` (so for instance, dropout modules are + deactivated). To train the model, you should first set it back in training mode with `model.train()` + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing model weights saved using + [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. + - A path or url to a *tensorflow index checkpoint file* (e.g, `./tf_model/model.ckpt.index`). In + this case, `from_tf` should be set to `True` and a configuration object should be provided as + `config` argument. This loading path is slower than converting the TensorFlow checkpoint in a + PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards. + model_args (additional positional arguments, *optional*): + Will be passed along to the underlying model `__init__()` method. + config ([`PretrainedConfig`], *optional*): + Configuration for the model to use instead of an automatically loaded configuration. Configuration can + be automatically loaded when: + + - The model is a model provided by the library (loaded with the *model id* string of a pretrained + model). + - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the + save directory. + - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a + configuration JSON file named *config.json* is found in the directory. + state_dict (*Dict[str, torch.Tensor]*, *optional*): + A state dictionary to use instead of a state dictionary loaded from saved weights file. + + This option can be used if you want to create a model from a pretrained configuration but load your own + weights. In this case though, you should check if using [`~PreTrainedModel.save_pretrained`] and + [`~PreTrainedModel.from_pretrained`] is not a simpler option. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + from_tf (`bool`, *optional*, defaults to `False`): + Load the model weights from a TensorFlow checkpoint save file (see docstring of + `pretrained_model_name_or_path` argument). + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download of the model weights and configuration files, overriding the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + output_loading_info(`bool`, *optional*, defaults to `False`): + Whether ot not to also return a dictionary containing missing keys, unexpected keys and error messages. + local_files_only(`bool`, *optional*, defaults to `False`): + Whether or not to only look at local files (e.g., not try downloading the model). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (additional keyword arguments, *optional*): + Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., + `output_attentions=True`). Behaves differently depending on whether a `config` is provided or + automatically loaded: + + - If a configuration is provided with `config`, `**kwargs` will be directly passed to the + underlying model's `__init__` method (we assume all relevant updates to the configuration have + already been done) + - If a configuration is not provided, `kwargs` will be first passed to the configuration class + initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that + corresponds to a configuration attribute will be used to override said attribute with the + supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute + will be passed to the underlying model's `__init__` function. + + Examples: + + ```python + >>> from transformers import AutoConfig, BaseAutoModelClass + + >>> # Download model and configuration from huggingface.co and cache. + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder") + + >>> # Update configuration during loading + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) + >>> model.config.output_attentions + True + + >>> # Loading from a TF checkpoint file instead of a PyTorch model (slower) + >>> config = AutoConfig.from_pretrained("./tf_model/shortcut_placeholder_tf_model_config.json") + >>> model = BaseAutoModelClass.from_pretrained( + ... "./tf_model/shortcut_placeholder_tf_checkpoint.ckpt.index", from_tf=True, config=config + ... ) + ``` +""" + +FROM_PRETRAINED_TF_DOCSTRING = """ + Instantiate one of the model classes of the library from a pretrained model. + + The model class to instantiate is selected based on the `model_type` property of the config object (either + passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by + falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing model weights saved using + [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. + - A path or url to a *PyTorch state_dict save file* (e.g, `./pt_model/pytorch_model.bin`). In this + case, `from_pt` should be set to `True` and a configuration object should be provided as `config` + argument. This loading path is slower than converting the PyTorch model in a TensorFlow model + using the provided conversion scripts and loading the TensorFlow model afterwards. + model_args (additional positional arguments, *optional*): + Will be passed along to the underlying model `__init__()` method. + config ([`PretrainedConfig`], *optional*): + Configuration for the model to use instead of an automatically loaded configuration. Configuration can + be automatically loaded when: + + - The model is a model provided by the library (loaded with the *model id* string of a pretrained + model). + - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the + save directory. + - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a + configuration JSON file named *config.json* is found in the directory. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + from_pt (`bool`, *optional*, defaults to `False`): + Load the model weights from a PyTorch checkpoint save file (see docstring of + `pretrained_model_name_or_path` argument). + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download of the model weights and configuration files, overriding the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + output_loading_info(`bool`, *optional*, defaults to `False`): + Whether ot not to also return a dictionary containing missing keys, unexpected keys and error messages. + local_files_only(`bool`, *optional*, defaults to `False`): + Whether or not to only look at local files (e.g., not try downloading the model). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (additional keyword arguments, *optional*): + Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., + `output_attentions=True`). Behaves differently depending on whether a `config` is provided or + automatically loaded: + + - If a configuration is provided with `config`, `**kwargs` will be directly passed to the + underlying model's `__init__` method (we assume all relevant updates to the configuration have + already been done) + - If a configuration is not provided, `kwargs` will be first passed to the configuration class + initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that + corresponds to a configuration attribute will be used to override said attribute with the + supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute + will be passed to the underlying model's `__init__` function. + + Examples: + + ```python + >>> from transformers import AutoConfig, BaseAutoModelClass + + >>> # Download model and configuration from huggingface.co and cache. + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder") + + >>> # Update configuration during loading + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) + >>> model.config.output_attentions + True + + >>> # Loading from a PyTorch checkpoint file instead of a TensorFlow model (slower) + >>> config = AutoConfig.from_pretrained("./pt_model/shortcut_placeholder_pt_model_config.json") + >>> model = BaseAutoModelClass.from_pretrained( + ... "./pt_model/shortcut_placeholder_pytorch_model.bin", from_pt=True, config=config + ... ) + ``` +""" + +FROM_PRETRAINED_FLAX_DOCSTRING = """ + Instantiate one of the model classes of the library from a pretrained model. + + The model class to instantiate is selected based on the `model_type` property of the config object (either + passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by + falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing model weights saved using + [`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`. + - A path or url to a *PyTorch state_dict save file* (e.g, `./pt_model/pytorch_model.bin`). In this + case, `from_pt` should be set to `True` and a configuration object should be provided as `config` + argument. This loading path is slower than converting the PyTorch model in a TensorFlow model + using the provided conversion scripts and loading the TensorFlow model afterwards. + model_args (additional positional arguments, *optional*): + Will be passed along to the underlying model `__init__()` method. + config ([`PretrainedConfig`], *optional*): + Configuration for the model to use instead of an automatically loaded configuration. Configuration can + be automatically loaded when: + + - The model is a model provided by the library (loaded with the *model id* string of a pretrained + model). + - The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the + save directory. + - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a + configuration JSON file named *config.json* is found in the directory. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + from_pt (`bool`, *optional*, defaults to `False`): + Load the model weights from a PyTorch checkpoint save file (see docstring of + `pretrained_model_name_or_path` argument). + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download of the model weights and configuration files, overriding the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + output_loading_info(`bool`, *optional*, defaults to `False`): + Whether ot not to also return a dictionary containing missing keys, unexpected keys and error messages. + local_files_only(`bool`, *optional*, defaults to `False`): + Whether or not to only look at local files (e.g., not try downloading the model). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (additional keyword arguments, *optional*): + Can be used to update the configuration object (after it being loaded) and initiate the model (e.g., + `output_attentions=True`). Behaves differently depending on whether a `config` is provided or + automatically loaded: + + - If a configuration is provided with `config`, `**kwargs` will be directly passed to the + underlying model's `__init__` method (we assume all relevant updates to the configuration have + already been done) + - If a configuration is not provided, `kwargs` will be first passed to the configuration class + initialization function ([`~PretrainedConfig.from_pretrained`]). Each key of `kwargs` that + corresponds to a configuration attribute will be used to override said attribute with the + supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute + will be passed to the underlying model's `__init__` function. + + Examples: + + ```python + >>> from transformers import AutoConfig, BaseAutoModelClass + + >>> # Download model and configuration from huggingface.co and cache. + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder") + + >>> # Update configuration during loading + >>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True) + >>> model.config.output_attentions + True + + >>> # Loading from a PyTorch checkpoint file instead of a TensorFlow model (slower) + >>> config = AutoConfig.from_pretrained("./pt_model/shortcut_placeholder_pt_model_config.json") + >>> model = BaseAutoModelClass.from_pretrained( + ... "./pt_model/shortcut_placeholder_pytorch_model.bin", from_pt=True, config=config + ... ) + ``` +""" + + +def _get_model_class(config, model_mapping): + supported_models = model_mapping[type(config)] + if not isinstance(supported_models, (list, tuple)): + return supported_models + + name_to_model = {model.__name__: model for model in supported_models} + architectures = getattr(config, "architectures", []) + for arch in architectures: + if arch in name_to_model: + return name_to_model[arch] + elif f"TF{arch}" in name_to_model: + return name_to_model[f"TF{arch}"] + elif f"Flax{arch}" in name_to_model: + return name_to_model[f"Flax{arch}"] + + # If not architecture is set in the config or match the supported models, the first element of the tuple is the + # defaults. + return supported_models[0] + + +class _BaseAutoModelClass: + # Base class for auto models. + _model_mapping = None + + def __init__(self, *args, **kwargs): + raise EnvironmentError( + f"{self.__class__.__name__} is designed to be instantiated " + f"using the `{self.__class__.__name__}.from_pretrained(pretrained_model_name_or_path)` or " + f"`{self.__class__.__name__}.from_config(config)` methods." + ) + + @classmethod + def from_config(cls, config, **kwargs): + trust_remote_code = kwargs.pop("trust_remote_code", False) + if hasattr(config, "auto_map") and cls.__name__ in config.auto_map: + if not trust_remote_code: + raise ValueError( + "Loading this model requires you to execute the modeling file in that repo " + "on your local machine. Make sure you have read the code there to avoid malicious use, then set " + "the option `trust_remote_code=True` to remove this error." + ) + if kwargs.get("revision", None) is None: + logger.warning( + "Explicitly passing a `revision` is encouraged when loading a model with custom code to ensure " + "no malicious code has been contributed in a newer revision." + ) + class_ref = config.auto_map[cls.__name__] + if "--" in class_ref: + repo_id, class_ref = class_ref.split("--") + else: + repo_id = config.name_or_path + model_class = get_class_from_dynamic_module(class_ref, repo_id, **kwargs) + return model_class._from_config(config, **kwargs) + elif type(config) in cls._model_mapping.keys(): + model_class = _get_model_class(config, cls._model_mapping) + return model_class._from_config(config, **kwargs) + + raise ValueError( + f"Unrecognized configuration class {config.__class__} for this kind of AutoModel: {cls.__name__}.\n" + f"Model type should be one of {', '.join(c.__name__ for c in cls._model_mapping.keys())}." + ) + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): + config = kwargs.pop("config", None) + trust_remote_code = kwargs.pop("trust_remote_code", False) + kwargs["_from_auto"] = True + hub_kwargs_names = [ + "cache_dir", + "force_download", + "local_files_only", + "proxies", + "resume_download", + "revision", + "subfolder", + "use_auth_token", + ] + hub_kwargs = {name: kwargs.pop(name) for name in hub_kwargs_names if name in kwargs} + if not isinstance(config, PretrainedConfig): + kwargs_copy = copy.deepcopy(kwargs) + # ensure not to pollute the config object with torch_dtype="auto" - since it's + # meaningless in the context of the config object - torch.dtype values are acceptable + if kwargs_copy.get("torch_dtype", None) == "auto": + _ = kwargs_copy.pop("torch_dtype") + + config, kwargs = AutoConfig.from_pretrained( + pretrained_model_name_or_path, + return_unused_kwargs=True, + trust_remote_code=trust_remote_code, + **hub_kwargs, + **kwargs_copy, + ) + if hasattr(config, "auto_map") and cls.__name__ in config.auto_map: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the modeling file in that repo " + "on your local machine. Make sure you have read the code there to avoid malicious use, then set " + "the option `trust_remote_code=True` to remove this error." + ) + class_ref = config.auto_map[cls.__name__] + model_class = get_class_from_dynamic_module( + class_ref, pretrained_model_name_or_path, **hub_kwargs, **kwargs + ) + return model_class.from_pretrained( + pretrained_model_name_or_path, *model_args, config=config, **hub_kwargs, **kwargs + ) + elif type(config) in cls._model_mapping.keys(): + model_class = _get_model_class(config, cls._model_mapping) + return model_class.from_pretrained( + pretrained_model_name_or_path, *model_args, config=config, **hub_kwargs, **kwargs + ) + raise ValueError( + f"Unrecognized configuration class {config.__class__} for this kind of AutoModel: {cls.__name__}.\n" + f"Model type should be one of {', '.join(c.__name__ for c in cls._model_mapping.keys())}." + ) + + @classmethod + def register(cls, config_class, model_class): + """ + Register a new model for this class. + + Args: + config_class ([`PretrainedConfig`]): + The configuration corresponding to the model to register. + model_class ([`PreTrainedModel`]): + The model to register. + """ + if hasattr(model_class, "config_class") and model_class.config_class != config_class: + raise ValueError( + "The model class you are passing has a `config_class` attribute that is not consistent with the " + f"config class you passed (model has {model_class.config_class} and you passed {config_class}. Fix " + "one of those so they match!" + ) + cls._model_mapping.register(config_class, model_class) + + +def insert_head_doc(docstring, head_doc=""): + if len(head_doc) > 0: + return docstring.replace( + "one of the model classes of the library ", + f"one of the model classes of the library (with a {head_doc} head) ", + ) + return docstring.replace( + "one of the model classes of the library ", "one of the base model classes of the library " + ) + + +def auto_class_update(cls, checkpoint_for_example="bert-base-cased", head_doc=""): + # Create a new class with the right name from the base class + model_mapping = cls._model_mapping + name = cls.__name__ + class_docstring = insert_head_doc(CLASS_DOCSTRING, head_doc=head_doc) + cls.__doc__ = class_docstring.replace("BaseAutoModelClass", name) + + # Now we need to copy and re-register `from_config` and `from_pretrained` as class methods otherwise we can't + # have a specific docstrings for them. + from_config = copy_func(_BaseAutoModelClass.from_config) + from_config_docstring = insert_head_doc(FROM_CONFIG_DOCSTRING, head_doc=head_doc) + from_config_docstring = from_config_docstring.replace("BaseAutoModelClass", name) + from_config_docstring = from_config_docstring.replace("checkpoint_placeholder", checkpoint_for_example) + from_config.__doc__ = from_config_docstring + from_config = replace_list_option_in_docstrings(model_mapping._model_mapping, use_model_types=False)(from_config) + cls.from_config = classmethod(from_config) + + if name.startswith("TF"): + from_pretrained_docstring = FROM_PRETRAINED_TF_DOCSTRING + elif name.startswith("Flax"): + from_pretrained_docstring = FROM_PRETRAINED_FLAX_DOCSTRING + else: + from_pretrained_docstring = FROM_PRETRAINED_TORCH_DOCSTRING + from_pretrained = copy_func(_BaseAutoModelClass.from_pretrained) + from_pretrained_docstring = insert_head_doc(from_pretrained_docstring, head_doc=head_doc) + from_pretrained_docstring = from_pretrained_docstring.replace("BaseAutoModelClass", name) + from_pretrained_docstring = from_pretrained_docstring.replace("checkpoint_placeholder", checkpoint_for_example) + shortcut = checkpoint_for_example.split("/")[-1].split("-")[0] + from_pretrained_docstring = from_pretrained_docstring.replace("shortcut_placeholder", shortcut) + from_pretrained.__doc__ = from_pretrained_docstring + from_pretrained = replace_list_option_in_docstrings(model_mapping._model_mapping)(from_pretrained) + cls.from_pretrained = classmethod(from_pretrained) + return cls + + +def get_values(model_mapping): + result = [] + for model in model_mapping.values(): + if isinstance(model, (list, tuple)): + result += list(model) + else: + result.append(model) + + return result + + +def getattribute_from_module(module, attr): + if attr is None: + return None + if isinstance(attr, tuple): + return tuple(getattribute_from_module(module, a) for a in attr) + if hasattr(module, attr): + return getattr(module, attr) + # Some of the mappings have entries model_type -> object of another model type. In that case we try to grab the + # object at the top level. + transformers_module = importlib.import_module("transformers") + + if module != transformers_module: + try: + return getattribute_from_module(transformers_module, attr) + except ValueError: + raise ValueError(f"Could not find {attr} neither in {module} nor in {transformers_module}!") + else: + raise ValueError(f"Could not find {attr} in {transformers_module}!") + + +class _LazyAutoMapping(OrderedDict): + """ + " A mapping config to object (model or tokenizer for instance) that will load keys and values when it is accessed. + + Args: + - config_mapping: The map model type to config class + - model_mapping: The map model type to model (or tokenizer) class + """ + + def __init__(self, config_mapping, model_mapping): + self._config_mapping = config_mapping + self._reverse_config_mapping = {v: k for k, v in config_mapping.items()} + self._model_mapping = model_mapping + self._extra_content = {} + self._modules = {} + + def __len__(self): + common_keys = set(self._config_mapping.keys()).intersection(self._model_mapping.keys()) + return len(common_keys) + len(self._extra_content) + + def __getitem__(self, key): + if key in self._extra_content: + return self._extra_content[key] + model_type = self._reverse_config_mapping[key.__name__] + if model_type in self._model_mapping: + model_name = self._model_mapping[model_type] + return self._load_attr_from_module(model_type, model_name) + + # Maybe there was several model types associated with this config. + model_types = [k for k, v in self._config_mapping.items() if v == key.__name__] + for mtype in model_types: + if mtype in self._model_mapping: + model_name = self._model_mapping[mtype] + return self._load_attr_from_module(mtype, model_name) + raise KeyError(key) + + def _load_attr_from_module(self, model_type, attr): + module_name = model_type_to_module_name(model_type) + if module_name not in self._modules: + self._modules[module_name] = importlib.import_module(f".{module_name}", "transformers.models") + return getattribute_from_module(self._modules[module_name], attr) + + def keys(self): + mapping_keys = [ + self._load_attr_from_module(key, name) + for key, name in self._config_mapping.items() + if key in self._model_mapping.keys() + ] + return mapping_keys + list(self._extra_content.keys()) + + def get(self, key, default): + try: + return self.__getitem__(key) + except KeyError: + return default + + def __bool__(self): + return bool(self.keys()) + + def values(self): + mapping_values = [ + self._load_attr_from_module(key, name) + for key, name in self._model_mapping.items() + if key in self._config_mapping.keys() + ] + return mapping_values + list(self._extra_content.values()) + + def items(self): + mapping_items = [ + ( + self._load_attr_from_module(key, self._config_mapping[key]), + self._load_attr_from_module(key, self._model_mapping[key]), + ) + for key in self._model_mapping.keys() + if key in self._config_mapping.keys() + ] + return mapping_items + list(self._extra_content.items()) + + def __iter__(self): + return iter(self.keys()) + + def __contains__(self, item): + if item in self._extra_content: + return True + if not hasattr(item, "__name__") or item.__name__ not in self._reverse_config_mapping: + return False + model_type = self._reverse_config_mapping[item.__name__] + return model_type in self._model_mapping + + def register(self, key, value): + """ + Register a new model in this mapping. + """ + if hasattr(key, "__name__") and key.__name__ in self._reverse_config_mapping: + model_type = self._reverse_config_mapping[key.__name__] + if model_type in self._model_mapping.keys(): + raise ValueError(f"'{key}' is already used by a Transformers model.") + + self._extra_content[key] = value diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/configuration_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/configuration_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..8da4a15b29ee3fa1cd6e4354ee94c3babbf19805 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/configuration_auto.py @@ -0,0 +1,970 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Auto Config class.""" +import importlib +import re +import warnings +from collections import OrderedDict +from typing import List, Union + +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...utils import CONFIG_NAME, logging + + +logger = logging.get_logger(__name__) + +CONFIG_MAPPING_NAMES = OrderedDict( + [ + # Add configs here + ("albert", "AlbertConfig"), + ("align", "AlignConfig"), + ("altclip", "AltCLIPConfig"), + ("audio-spectrogram-transformer", "ASTConfig"), + ("bart", "BartConfig"), + ("beit", "BeitConfig"), + ("bert", "BertConfig"), + ("bert-generation", "BertGenerationConfig"), + ("big_bird", "BigBirdConfig"), + ("bigbird_pegasus", "BigBirdPegasusConfig"), + ("biogpt", "BioGptConfig"), + ("bit", "BitConfig"), + ("blenderbot", "BlenderbotConfig"), + ("blenderbot-small", "BlenderbotSmallConfig"), + ("blip", "BlipConfig"), + ("blip-2", "Blip2Config"), + ("bloom", "BloomConfig"), + ("bridgetower", "BridgeTowerConfig"), + ("camembert", "CamembertConfig"), + ("canine", "CanineConfig"), + ("chinese_clip", "ChineseCLIPConfig"), + ("clap", "ClapConfig"), + ("clip", "CLIPConfig"), + ("clipseg", "CLIPSegConfig"), + ("codegen", "CodeGenConfig"), + ("conditional_detr", "ConditionalDetrConfig"), + ("convbert", "ConvBertConfig"), + ("convnext", "ConvNextConfig"), + ("convnextv2", "ConvNextV2Config"), + ("cpmant", "CpmAntConfig"), + ("ctrl", "CTRLConfig"), + ("cvt", "CvtConfig"), + ("data2vec-audio", "Data2VecAudioConfig"), + ("data2vec-text", "Data2VecTextConfig"), + ("data2vec-vision", "Data2VecVisionConfig"), + ("deberta", "DebertaConfig"), + ("deberta-v2", "DebertaV2Config"), + ("decision_transformer", "DecisionTransformerConfig"), + ("deformable_detr", "DeformableDetrConfig"), + ("deit", "DeiTConfig"), + ("deta", "DetaConfig"), + ("detr", "DetrConfig"), + ("dinat", "DinatConfig"), + ("distilbert", "DistilBertConfig"), + ("donut-swin", "DonutSwinConfig"), + ("dpr", "DPRConfig"), + ("dpt", "DPTConfig"), + ("efficientformer", "EfficientFormerConfig"), + ("efficientnet", "EfficientNetConfig"), + ("electra", "ElectraConfig"), + ("encoder-decoder", "EncoderDecoderConfig"), + ("ernie", "ErnieConfig"), + ("ernie_m", "ErnieMConfig"), + ("esm", "EsmConfig"), + ("flaubert", "FlaubertConfig"), + ("flava", "FlavaConfig"), + ("fnet", "FNetConfig"), + ("focalnet", "FocalNetConfig"), + ("fsmt", "FSMTConfig"), + ("funnel", "FunnelConfig"), + ("git", "GitConfig"), + ("glpn", "GLPNConfig"), + ("gpt-sw3", "GPT2Config"), + ("gpt2", "GPT2Config"), + ("gpt_bigcode", "GPTBigCodeConfig"), + ("gpt_neo", "GPTNeoConfig"), + ("gpt_neox", "GPTNeoXConfig"), + ("gpt_neox_japanese", "GPTNeoXJapaneseConfig"), + ("gptj", "GPTJConfig"), + ("gptsan-japanese", "GPTSanJapaneseConfig"), + ("graphormer", "GraphormerConfig"), + ("groupvit", "GroupViTConfig"), + ("hubert", "HubertConfig"), + ("ibert", "IBertConfig"), + ("imagegpt", "ImageGPTConfig"), + ("informer", "InformerConfig"), + ("jukebox", "JukeboxConfig"), + ("layoutlm", "LayoutLMConfig"), + ("layoutlmv2", "LayoutLMv2Config"), + ("layoutlmv3", "LayoutLMv3Config"), + ("led", "LEDConfig"), + ("levit", "LevitConfig"), + ("lilt", "LiltConfig"), + ("llama", "LlamaConfig"), + ("longformer", "LongformerConfig"), + ("longt5", "LongT5Config"), + ("luke", "LukeConfig"), + ("lxmert", "LxmertConfig"), + ("m2m_100", "M2M100Config"), + ("marian", "MarianConfig"), + ("markuplm", "MarkupLMConfig"), + ("mask2former", "Mask2FormerConfig"), + ("maskformer", "MaskFormerConfig"), + ("maskformer-swin", "MaskFormerSwinConfig"), + ("mbart", "MBartConfig"), + ("mctct", "MCTCTConfig"), + ("mega", "MegaConfig"), + ("megatron-bert", "MegatronBertConfig"), + ("mgp-str", "MgpstrConfig"), + ("mobilebert", "MobileBertConfig"), + ("mobilenet_v1", "MobileNetV1Config"), + ("mobilenet_v2", "MobileNetV2Config"), + ("mobilevit", "MobileViTConfig"), + ("mpnet", "MPNetConfig"), + ("mt5", "MT5Config"), + ("mvp", "MvpConfig"), + ("nat", "NatConfig"), + ("nezha", "NezhaConfig"), + ("nllb-moe", "NllbMoeConfig"), + ("nystromformer", "NystromformerConfig"), + ("oneformer", "OneFormerConfig"), + ("open-llama", "OpenLlamaConfig"), + ("openai-gpt", "OpenAIGPTConfig"), + ("opt", "OPTConfig"), + ("owlvit", "OwlViTConfig"), + ("pegasus", "PegasusConfig"), + ("pegasus_x", "PegasusXConfig"), + ("perceiver", "PerceiverConfig"), + ("pix2struct", "Pix2StructConfig"), + ("plbart", "PLBartConfig"), + ("poolformer", "PoolFormerConfig"), + ("prophetnet", "ProphetNetConfig"), + ("qdqbert", "QDQBertConfig"), + ("rag", "RagConfig"), + ("realm", "RealmConfig"), + ("reformer", "ReformerConfig"), + ("regnet", "RegNetConfig"), + ("rembert", "RemBertConfig"), + ("resnet", "ResNetConfig"), + ("retribert", "RetriBertConfig"), + ("roberta", "RobertaConfig"), + ("roberta-prelayernorm", "RobertaPreLayerNormConfig"), + ("roc_bert", "RoCBertConfig"), + ("roformer", "RoFormerConfig"), + ("rwkv", "RwkvConfig"), + ("sam", "SamConfig"), + ("segformer", "SegformerConfig"), + ("sew", "SEWConfig"), + ("sew-d", "SEWDConfig"), + ("speech-encoder-decoder", "SpeechEncoderDecoderConfig"), + ("speech_to_text", "Speech2TextConfig"), + ("speech_to_text_2", "Speech2Text2Config"), + ("speecht5", "SpeechT5Config"), + ("splinter", "SplinterConfig"), + ("squeezebert", "SqueezeBertConfig"), + ("swin", "SwinConfig"), + ("swin2sr", "Swin2SRConfig"), + ("swinv2", "Swinv2Config"), + ("switch_transformers", "SwitchTransformersConfig"), + ("t5", "T5Config"), + ("table-transformer", "TableTransformerConfig"), + ("tapas", "TapasConfig"), + ("time_series_transformer", "TimeSeriesTransformerConfig"), + ("timesformer", "TimesformerConfig"), + ("trajectory_transformer", "TrajectoryTransformerConfig"), + ("transfo-xl", "TransfoXLConfig"), + ("trocr", "TrOCRConfig"), + ("tvlt", "TvltConfig"), + ("unispeech", "UniSpeechConfig"), + ("unispeech-sat", "UniSpeechSatConfig"), + ("upernet", "UperNetConfig"), + ("van", "VanConfig"), + ("videomae", "VideoMAEConfig"), + ("vilt", "ViltConfig"), + ("vision-encoder-decoder", "VisionEncoderDecoderConfig"), + ("vision-text-dual-encoder", "VisionTextDualEncoderConfig"), + ("visual_bert", "VisualBertConfig"), + ("vit", "ViTConfig"), + ("vit_hybrid", "ViTHybridConfig"), + ("vit_mae", "ViTMAEConfig"), + ("vit_msn", "ViTMSNConfig"), + ("wav2vec2", "Wav2Vec2Config"), + ("wav2vec2-conformer", "Wav2Vec2ConformerConfig"), + ("wavlm", "WavLMConfig"), + ("whisper", "WhisperConfig"), + ("xclip", "XCLIPConfig"), + ("xglm", "XGLMConfig"), + ("xlm", "XLMConfig"), + ("xlm-prophetnet", "XLMProphetNetConfig"), + ("xlm-roberta", "XLMRobertaConfig"), + ("xlm-roberta-xl", "XLMRobertaXLConfig"), + ("xlnet", "XLNetConfig"), + ("xmod", "XmodConfig"), + ("yolos", "YolosConfig"), + ("yoso", "YosoConfig"), + ] +) + +CONFIG_ARCHIVE_MAP_MAPPING_NAMES = OrderedDict( + [ + # Add archive maps here) + ("albert", "ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("align", "ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("altclip", "ALTCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("audio-spectrogram-transformer", "AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bart", "BART_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("beit", "BEIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bert", "BERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("big_bird", "BIG_BIRD_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bigbird_pegasus", "BIGBIRD_PEGASUS_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("biogpt", "BIOGPT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bit", "BIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("blenderbot", "BLENDERBOT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("blenderbot-small", "BLENDERBOT_SMALL_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("blip", "BLIP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("blip-2", "BLIP_2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bloom", "BLOOM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("bridgetower", "BRIDGETOWER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("camembert", "CAMEMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("canine", "CANINE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("chinese_clip", "CHINESE_CLIP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("clap", "CLAP_PRETRAINED_MODEL_ARCHIVE_LIST"), + ("clip", "CLIP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("clipseg", "CLIPSEG_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("codegen", "CODEGEN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("conditional_detr", "CONDITIONAL_DETR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("convbert", "CONVBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("convnext", "CONVNEXT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("convnextv2", "CONVNEXTV2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("cpmant", "CPMANT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("ctrl", "CTRL_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("cvt", "CVT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("data2vec-audio", "DATA2VEC_AUDIO_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("data2vec-text", "DATA2VEC_TEXT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("data2vec-vision", "DATA2VEC_VISION_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("deberta", "DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("deberta-v2", "DEBERTA_V2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("deformable_detr", "DEFORMABLE_DETR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("deit", "DEIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("deta", "DETA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("detr", "DETR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("dinat", "DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("distilbert", "DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("donut-swin", "DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("dpr", "DPR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("dpt", "DPT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("efficientformer", "EFFICIENTFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("efficientnet", "EFFICIENTNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("electra", "ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("ernie", "ERNIE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("ernie_m", "ERNIE_M_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("esm", "ESM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("flaubert", "FLAUBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("flava", "FLAVA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("fnet", "FNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("focalnet", "FOCALNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("fsmt", "FSMT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("funnel", "FUNNEL_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("git", "GIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("glpn", "GLPN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gpt2", "GPT2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gpt_bigcode", "GPT_BIGCODE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gpt_neo", "GPT_NEO_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gpt_neox", "GPT_NEOX_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gpt_neox_japanese", "GPT_NEOX_JAPANESE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gptj", "GPTJ_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("gptsan-japanese", "GPTSAN_JAPANESE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("graphormer", "GRAPHORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("groupvit", "GROUPVIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("hubert", "HUBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("ibert", "IBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("imagegpt", "IMAGEGPT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("informer", "INFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("jukebox", "JUKEBOX_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("layoutlm", "LAYOUTLM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("layoutlmv2", "LAYOUTLMV2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("layoutlmv3", "LAYOUTLMV3_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("led", "LED_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("levit", "LEVIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("lilt", "LILT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("llama", "LLAMA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("longformer", "LONGFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("longt5", "LONGT5_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("luke", "LUKE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("lxmert", "LXMERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("m2m_100", "M2M_100_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("markuplm", "MARKUPLM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mask2former", "MASK2FORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("maskformer", "MASKFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mbart", "MBART_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mctct", "MCTCT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mega", "MEGA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("megatron-bert", "MEGATRON_BERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mgp-str", "MGP_STR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mobilenet_v1", "MOBILENET_V1_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mobilenet_v2", "MOBILENET_V2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mobilevit", "MOBILEVIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mpnet", "MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("mvp", "MVP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("nat", "NAT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("nezha", "NEZHA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("nllb-moe", "NLLB_MOE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("nystromformer", "NYSTROMFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("oneformer", "ONEFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("open-llama", "OPEN_LLAMA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("openai-gpt", "OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("opt", "OPT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("owlvit", "OWLVIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("pegasus", "PEGASUS_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("pegasus_x", "PEGASUS_X_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("perceiver", "PERCEIVER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("pix2struct", "PIX2STRUCT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("plbart", "PLBART_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("poolformer", "POOLFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("prophetnet", "PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("qdqbert", "QDQBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("realm", "REALM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("regnet", "REGNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("rembert", "REMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("resnet", "RESNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("retribert", "RETRIBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("roberta", "ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("roberta-prelayernorm", "ROBERTA_PRELAYERNORM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("roc_bert", "ROC_BERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("roformer", "ROFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("rwkv", "RWKV_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("sam", "SAM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("segformer", "SEGFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("sew", "SEW_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("sew-d", "SEW_D_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("speech_to_text", "SPEECH_TO_TEXT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("speech_to_text_2", "SPEECH_TO_TEXT_2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("speecht5", "SPEECHT5_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("splinter", "SPLINTER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("squeezebert", "SQUEEZEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("swin", "SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("swin2sr", "SWIN2SR_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("swinv2", "SWINV2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("switch_transformers", "SWITCH_TRANSFORMERS_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("t5", "T5_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("table-transformer", "TABLE_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("tapas", "TAPAS_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("time_series_transformer", "TIME_SERIES_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("timesformer", "TIMESFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("transfo-xl", "TRANSFO_XL_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("tvlt", "TVLT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("unispeech", "UNISPEECH_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("unispeech-sat", "UNISPEECH_SAT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("van", "VAN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("videomae", "VIDEOMAE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("vilt", "VILT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("visual_bert", "VISUAL_BERT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("vit", "VIT_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("vit_hybrid", "VIT_HYBRID_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("vit_mae", "VIT_MAE_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("vit_msn", "VIT_MSN_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("wav2vec2", "WAV_2_VEC_2_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("wav2vec2-conformer", "WAV2VEC2_CONFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("whisper", "WHISPER_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xclip", "XCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xglm", "XGLM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xlm", "XLM_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xlm-prophetnet", "XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xlm-roberta", "XLM_ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xlnet", "XLNET_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("xmod", "XMOD_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("yolos", "YOLOS_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ("yoso", "YOSO_PRETRAINED_CONFIG_ARCHIVE_MAP"), + ] +) + +MODEL_NAMES_MAPPING = OrderedDict( + [ + # Add full (and cased) model names here + ("albert", "ALBERT"), + ("align", "ALIGN"), + ("altclip", "AltCLIP"), + ("audio-spectrogram-transformer", "Audio Spectrogram Transformer"), + ("bart", "BART"), + ("barthez", "BARThez"), + ("bartpho", "BARTpho"), + ("beit", "BEiT"), + ("bert", "BERT"), + ("bert-generation", "Bert Generation"), + ("bert-japanese", "BertJapanese"), + ("bertweet", "BERTweet"), + ("big_bird", "BigBird"), + ("bigbird_pegasus", "BigBird-Pegasus"), + ("biogpt", "BioGpt"), + ("bit", "BiT"), + ("blenderbot", "Blenderbot"), + ("blenderbot-small", "BlenderbotSmall"), + ("blip", "BLIP"), + ("blip-2", "BLIP-2"), + ("bloom", "BLOOM"), + ("bort", "BORT"), + ("bridgetower", "BridgeTower"), + ("byt5", "ByT5"), + ("camembert", "CamemBERT"), + ("canine", "CANINE"), + ("chinese_clip", "Chinese-CLIP"), + ("clap", "CLAP"), + ("clip", "CLIP"), + ("clipseg", "CLIPSeg"), + ("codegen", "CodeGen"), + ("conditional_detr", "Conditional DETR"), + ("convbert", "ConvBERT"), + ("convnext", "ConvNeXT"), + ("convnextv2", "ConvNeXTV2"), + ("cpm", "CPM"), + ("cpmant", "CPM-Ant"), + ("ctrl", "CTRL"), + ("cvt", "CvT"), + ("data2vec-audio", "Data2VecAudio"), + ("data2vec-text", "Data2VecText"), + ("data2vec-vision", "Data2VecVision"), + ("deberta", "DeBERTa"), + ("deberta-v2", "DeBERTa-v2"), + ("decision_transformer", "Decision Transformer"), + ("deformable_detr", "Deformable DETR"), + ("deit", "DeiT"), + ("deplot", "DePlot"), + ("deta", "DETA"), + ("detr", "DETR"), + ("dialogpt", "DialoGPT"), + ("dinat", "DiNAT"), + ("distilbert", "DistilBERT"), + ("dit", "DiT"), + ("donut-swin", "DonutSwin"), + ("dpr", "DPR"), + ("dpt", "DPT"), + ("efficientformer", "EfficientFormer"), + ("efficientnet", "EfficientNet"), + ("electra", "ELECTRA"), + ("encoder-decoder", "Encoder decoder"), + ("ernie", "ERNIE"), + ("ernie_m", "ErnieM"), + ("esm", "ESM"), + ("flan-t5", "FLAN-T5"), + ("flan-ul2", "FLAN-UL2"), + ("flaubert", "FlauBERT"), + ("flava", "FLAVA"), + ("fnet", "FNet"), + ("focalnet", "FocalNet"), + ("fsmt", "FairSeq Machine-Translation"), + ("funnel", "Funnel Transformer"), + ("git", "GIT"), + ("glpn", "GLPN"), + ("gpt-sw3", "GPT-Sw3"), + ("gpt2", "OpenAI GPT-2"), + ("gpt_bigcode", "GPTBigCode"), + ("gpt_neo", "GPT Neo"), + ("gpt_neox", "GPT NeoX"), + ("gpt_neox_japanese", "GPT NeoX Japanese"), + ("gptj", "GPT-J"), + ("gptsan-japanese", "GPTSAN-japanese"), + ("graphormer", "Graphormer"), + ("groupvit", "GroupViT"), + ("herbert", "HerBERT"), + ("hubert", "Hubert"), + ("ibert", "I-BERT"), + ("imagegpt", "ImageGPT"), + ("informer", "Informer"), + ("jukebox", "Jukebox"), + ("layoutlm", "LayoutLM"), + ("layoutlmv2", "LayoutLMv2"), + ("layoutlmv3", "LayoutLMv3"), + ("layoutxlm", "LayoutXLM"), + ("led", "LED"), + ("levit", "LeViT"), + ("lilt", "LiLT"), + ("llama", "LLaMA"), + ("longformer", "Longformer"), + ("longt5", "LongT5"), + ("luke", "LUKE"), + ("lxmert", "LXMERT"), + ("m2m_100", "M2M100"), + ("marian", "Marian"), + ("markuplm", "MarkupLM"), + ("mask2former", "Mask2Former"), + ("maskformer", "MaskFormer"), + ("maskformer-swin", "MaskFormerSwin"), + ("matcha", "MatCha"), + ("mbart", "mBART"), + ("mbart50", "mBART-50"), + ("mctct", "M-CTC-T"), + ("mega", "MEGA"), + ("megatron-bert", "Megatron-BERT"), + ("megatron_gpt2", "Megatron-GPT2"), + ("mgp-str", "MGP-STR"), + ("mluke", "mLUKE"), + ("mobilebert", "MobileBERT"), + ("mobilenet_v1", "MobileNetV1"), + ("mobilenet_v2", "MobileNetV2"), + ("mobilevit", "MobileViT"), + ("mpnet", "MPNet"), + ("mt5", "MT5"), + ("mvp", "MVP"), + ("nat", "NAT"), + ("nezha", "Nezha"), + ("nllb", "NLLB"), + ("nllb-moe", "NLLB-MOE"), + ("nystromformer", "Nyströmformer"), + ("oneformer", "OneFormer"), + ("open-llama", "OpenLlama"), + ("openai-gpt", "OpenAI GPT"), + ("opt", "OPT"), + ("owlvit", "OWL-ViT"), + ("pegasus", "Pegasus"), + ("pegasus_x", "PEGASUS-X"), + ("perceiver", "Perceiver"), + ("phobert", "PhoBERT"), + ("pix2struct", "Pix2Struct"), + ("plbart", "PLBart"), + ("poolformer", "PoolFormer"), + ("prophetnet", "ProphetNet"), + ("qdqbert", "QDQBert"), + ("rag", "RAG"), + ("realm", "REALM"), + ("reformer", "Reformer"), + ("regnet", "RegNet"), + ("rembert", "RemBERT"), + ("resnet", "ResNet"), + ("retribert", "RetriBERT"), + ("roberta", "RoBERTa"), + ("roberta-prelayernorm", "RoBERTa-PreLayerNorm"), + ("roc_bert", "RoCBert"), + ("roformer", "RoFormer"), + ("rwkv", "RWKV"), + ("sam", "SAM"), + ("segformer", "SegFormer"), + ("sew", "SEW"), + ("sew-d", "SEW-D"), + ("speech-encoder-decoder", "Speech Encoder decoder"), + ("speech_to_text", "Speech2Text"), + ("speech_to_text_2", "Speech2Text2"), + ("speecht5", "SpeechT5"), + ("splinter", "Splinter"), + ("squeezebert", "SqueezeBERT"), + ("swin", "Swin Transformer"), + ("swin2sr", "Swin2SR"), + ("swinv2", "Swin Transformer V2"), + ("switch_transformers", "SwitchTransformers"), + ("t5", "T5"), + ("t5v1.1", "T5v1.1"), + ("table-transformer", "Table Transformer"), + ("tapas", "TAPAS"), + ("tapex", "TAPEX"), + ("time_series_transformer", "Time Series Transformer"), + ("timesformer", "TimeSformer"), + ("trajectory_transformer", "Trajectory Transformer"), + ("transfo-xl", "Transformer-XL"), + ("trocr", "TrOCR"), + ("tvlt", "TVLT"), + ("ul2", "UL2"), + ("unispeech", "UniSpeech"), + ("unispeech-sat", "UniSpeechSat"), + ("upernet", "UPerNet"), + ("van", "VAN"), + ("videomae", "VideoMAE"), + ("vilt", "ViLT"), + ("vision-encoder-decoder", "Vision Encoder decoder"), + ("vision-text-dual-encoder", "VisionTextDualEncoder"), + ("visual_bert", "VisualBERT"), + ("vit", "ViT"), + ("vit_hybrid", "ViT Hybrid"), + ("vit_mae", "ViTMAE"), + ("vit_msn", "ViTMSN"), + ("wav2vec2", "Wav2Vec2"), + ("wav2vec2-conformer", "Wav2Vec2-Conformer"), + ("wav2vec2_phoneme", "Wav2Vec2Phoneme"), + ("wavlm", "WavLM"), + ("whisper", "Whisper"), + ("xclip", "X-CLIP"), + ("xglm", "XGLM"), + ("xlm", "XLM"), + ("xlm-prophetnet", "XLM-ProphetNet"), + ("xlm-roberta", "XLM-RoBERTa"), + ("xlm-roberta-xl", "XLM-RoBERTa-XL"), + ("xlm-v", "XLM-V"), + ("xlnet", "XLNet"), + ("xls_r", "XLS-R"), + ("xlsr_wav2vec2", "XLSR-Wav2Vec2"), + ("xmod", "X-MOD"), + ("yolos", "YOLOS"), + ("yoso", "YOSO"), + ] +) + +SPECIAL_MODEL_TYPE_TO_MODULE_NAME = OrderedDict( + [ + ("openai-gpt", "openai"), + ("data2vec-audio", "data2vec"), + ("data2vec-text", "data2vec"), + ("data2vec-vision", "data2vec"), + ("donut-swin", "donut"), + ("maskformer-swin", "maskformer"), + ("xclip", "x_clip"), + ] +) + + +def model_type_to_module_name(key): + """Converts a config key to the corresponding module.""" + # Special treatment + if key in SPECIAL_MODEL_TYPE_TO_MODULE_NAME: + return SPECIAL_MODEL_TYPE_TO_MODULE_NAME[key] + + return key.replace("-", "_") + + +def config_class_to_model_type(config): + """Converts a config class name to the corresponding model type""" + for key, cls in CONFIG_MAPPING_NAMES.items(): + if cls == config: + return key + return None + + +class _LazyConfigMapping(OrderedDict): + """ + A dictionary that lazily load its values when they are requested. + """ + + def __init__(self, mapping): + self._mapping = mapping + self._extra_content = {} + self._modules = {} + + def __getitem__(self, key): + if key in self._extra_content: + return self._extra_content[key] + if key not in self._mapping: + raise KeyError(key) + value = self._mapping[key] + module_name = model_type_to_module_name(key) + if module_name not in self._modules: + self._modules[module_name] = importlib.import_module(f".{module_name}", "transformers.models") + if hasattr(self._modules[module_name], value): + return getattr(self._modules[module_name], value) + + # Some of the mappings have entries model_type -> config of another model type. In that case we try to grab the + # object at the top level. + transformers_module = importlib.import_module("transformers") + return getattr(transformers_module, value) + + def keys(self): + return list(self._mapping.keys()) + list(self._extra_content.keys()) + + def values(self): + return [self[k] for k in self._mapping.keys()] + list(self._extra_content.values()) + + def items(self): + return [(k, self[k]) for k in self._mapping.keys()] + list(self._extra_content.items()) + + def __iter__(self): + return iter(list(self._mapping.keys()) + list(self._extra_content.keys())) + + def __contains__(self, item): + return item in self._mapping or item in self._extra_content + + def register(self, key, value): + """ + Register a new configuration in this mapping. + """ + if key in self._mapping.keys(): + raise ValueError(f"'{key}' is already used by a Transformers config, pick another name.") + self._extra_content[key] = value + + +CONFIG_MAPPING = _LazyConfigMapping(CONFIG_MAPPING_NAMES) + + +class _LazyLoadAllMappings(OrderedDict): + """ + A mapping that will load all pairs of key values at the first access (either by indexing, requestions keys, values, + etc.) + + Args: + mapping: The mapping to load. + """ + + def __init__(self, mapping): + self._mapping = mapping + self._initialized = False + self._data = {} + + def _initialize(self): + if self._initialized: + return + warnings.warn( + "ALL_PRETRAINED_CONFIG_ARCHIVE_MAP is deprecated and will be removed in v5 of Transformers. " + "It does not contain all available model checkpoints, far from it. Checkout hf.co/models for that.", + FutureWarning, + ) + + for model_type, map_name in self._mapping.items(): + module_name = model_type_to_module_name(model_type) + module = importlib.import_module(f".{module_name}", "transformers.models") + mapping = getattr(module, map_name) + self._data.update(mapping) + + self._initialized = True + + def __getitem__(self, key): + self._initialize() + return self._data[key] + + def keys(self): + self._initialize() + return self._data.keys() + + def values(self): + self._initialize() + return self._data.values() + + def items(self): + self._initialize() + return self._data.keys() + + def __iter__(self): + self._initialize() + return iter(self._data) + + def __contains__(self, item): + self._initialize() + return item in self._data + + +ALL_PRETRAINED_CONFIG_ARCHIVE_MAP = _LazyLoadAllMappings(CONFIG_ARCHIVE_MAP_MAPPING_NAMES) + + +def _get_class_name(model_class: Union[str, List[str]]): + if isinstance(model_class, (list, tuple)): + return " or ".join([f"[`{c}`]" for c in model_class if c is not None]) + return f"[`{model_class}`]" + + +def _list_model_options(indent, config_to_class=None, use_model_types=True): + if config_to_class is None and not use_model_types: + raise ValueError("Using `use_model_types=False` requires a `config_to_class` dictionary.") + if use_model_types: + if config_to_class is None: + model_type_to_name = {model_type: f"[`{config}`]" for model_type, config in CONFIG_MAPPING_NAMES.items()} + else: + model_type_to_name = { + model_type: _get_class_name(model_class) + for model_type, model_class in config_to_class.items() + if model_type in MODEL_NAMES_MAPPING + } + lines = [ + f"{indent}- **{model_type}** -- {model_type_to_name[model_type]} ({MODEL_NAMES_MAPPING[model_type]} model)" + for model_type in sorted(model_type_to_name.keys()) + ] + else: + config_to_name = { + CONFIG_MAPPING_NAMES[config]: _get_class_name(clas) + for config, clas in config_to_class.items() + if config in CONFIG_MAPPING_NAMES + } + config_to_model_name = { + config: MODEL_NAMES_MAPPING[model_type] for model_type, config in CONFIG_MAPPING_NAMES.items() + } + lines = [ + f"{indent}- [`{config_name}`] configuration class:" + f" {config_to_name[config_name]} ({config_to_model_name[config_name]} model)" + for config_name in sorted(config_to_name.keys()) + ] + return "\n".join(lines) + + +def replace_list_option_in_docstrings(config_to_class=None, use_model_types=True): + def docstring_decorator(fn): + docstrings = fn.__doc__ + lines = docstrings.split("\n") + i = 0 + while i < len(lines) and re.search(r"^(\s*)List options\s*$", lines[i]) is None: + i += 1 + if i < len(lines): + indent = re.search(r"^(\s*)List options\s*$", lines[i]).groups()[0] + if use_model_types: + indent = f"{indent} " + lines[i] = _list_model_options(indent, config_to_class=config_to_class, use_model_types=use_model_types) + docstrings = "\n".join(lines) + else: + raise ValueError( + f"The function {fn} should have an empty 'List options' in its docstring as placeholder, current" + f" docstring is:\n{docstrings}" + ) + fn.__doc__ = docstrings + return fn + + return docstring_decorator + + +class AutoConfig: + r""" + This is a generic configuration class that will be instantiated as one of the configuration classes of the library + when created with the [`~AutoConfig.from_pretrained`] class method. + + This class cannot be instantiated directly using `__init__()` (throws an error). + """ + + def __init__(self): + raise EnvironmentError( + "AutoConfig is designed to be instantiated " + "using the `AutoConfig.from_pretrained(pretrained_model_name_or_path)` method." + ) + + @classmethod + def for_model(cls, model_type: str, *args, **kwargs): + if model_type in CONFIG_MAPPING: + config_class = CONFIG_MAPPING[model_type] + return config_class(*args, **kwargs) + raise ValueError( + f"Unrecognized model identifier: {model_type}. Should contain one of {', '.join(CONFIG_MAPPING.keys())}" + ) + + @classmethod + @replace_list_option_in_docstrings() + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + r""" + Instantiate one of the configuration classes of the library from a pretrained model configuration. + + The configuration class to instantiate is selected based on the `model_type` property of the config object that + is loaded, or when it's missing, by falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a pretrained model configuration hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or + namespaced under a user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing a configuration file saved using the + [`~PretrainedConfig.save_pretrained`] method, or the [`~PreTrainedModel.save_pretrained`] method, + e.g., `./my_model_directory/`. + - A path or url to a saved configuration JSON *file*, e.g., + `./my_model_directory/configuration.json`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download the model weights and configuration files and override the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + return_unused_kwargs (`bool`, *optional*, defaults to `False`): + If `False`, then this function returns just the final configuration object. + + If `True`, then this functions returns a `Tuple(config, unused_kwargs)` where *unused_kwargs* is a + dictionary consisting of the key/value pairs whose keys are not configuration attributes: i.e., the + part of `kwargs` which has not been used to update `config` and is otherwise ignored. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs(additional keyword arguments, *optional*): + The values in kwargs of any keys which are configuration attributes will be used to override the loaded + values. Behavior concerning key/value pairs whose keys are *not* configuration attributes is controlled + by the `return_unused_kwargs` keyword parameter. + + Examples: + + ```python + >>> from transformers import AutoConfig + + >>> # Download configuration from huggingface.co and cache. + >>> config = AutoConfig.from_pretrained("bert-base-uncased") + + >>> # Download configuration from huggingface.co (user-uploaded) and cache. + >>> config = AutoConfig.from_pretrained("dbmdz/bert-base-german-cased") + + >>> # If configuration file is in a directory (e.g., was saved using *save_pretrained('./test/saved_model/')*). + >>> config = AutoConfig.from_pretrained("./test/bert_saved_model/") + + >>> # Load a specific configuration file. + >>> config = AutoConfig.from_pretrained("./test/bert_saved_model/my_configuration.json") + + >>> # Change some config attributes when loading a pretrained config. + >>> config = AutoConfig.from_pretrained("bert-base-uncased", output_attentions=True, foo=False) + >>> config.output_attentions + True + + >>> config, unused_kwargs = AutoConfig.from_pretrained( + ... "bert-base-uncased", output_attentions=True, foo=False, return_unused_kwargs=True + ... ) + >>> config.output_attentions + True + + >>> unused_kwargs + {'foo': False} + ```""" + kwargs["_from_auto"] = True + kwargs["name_or_path"] = pretrained_model_name_or_path + trust_remote_code = kwargs.pop("trust_remote_code", False) + config_dict, unused_kwargs = PretrainedConfig.get_config_dict(pretrained_model_name_or_path, **kwargs) + if "auto_map" in config_dict and "AutoConfig" in config_dict["auto_map"]: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the configuration file in that" + " repo on your local machine. Make sure you have read the code there to avoid malicious use, then" + " set the option `trust_remote_code=True` to remove this error." + ) + class_ref = config_dict["auto_map"]["AutoConfig"] + config_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs) + return config_class.from_pretrained(pretrained_model_name_or_path, **kwargs) + elif "model_type" in config_dict: + config_class = CONFIG_MAPPING[config_dict["model_type"]] + return config_class.from_dict(config_dict, **unused_kwargs) + else: + # Fallback: use pattern matching on the string. + # We go from longer names to shorter names to catch roberta before bert (for instance) + for pattern in sorted(CONFIG_MAPPING.keys(), key=len, reverse=True): + if pattern in str(pretrained_model_name_or_path): + return CONFIG_MAPPING[pattern].from_dict(config_dict, **unused_kwargs) + + raise ValueError( + f"Unrecognized model in {pretrained_model_name_or_path}. " + f"Should have a `model_type` key in its {CONFIG_NAME}, or contain one of the following strings " + f"in its name: {', '.join(CONFIG_MAPPING.keys())}" + ) + + @staticmethod + def register(model_type, config): + """ + Register a new configuration for this class. + + Args: + model_type (`str`): The model type like "bert" or "gpt". + config ([`PretrainedConfig`]): The config to register. + """ + if issubclass(config, PretrainedConfig) and config.model_type != model_type: + raise ValueError( + "The config you are passing has a `model_type` attribute that is not consistent with the model type " + f"you passed (config has {config.model_type} and you passed {model_type}. Fix one of those so they " + "match!" + ) + CONFIG_MAPPING.register(model_type, config) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/feature_extraction_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/feature_extraction_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..0a527ee151759c64a4797bd9c6e0e9bb3a5ac33c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/feature_extraction_auto.py @@ -0,0 +1,364 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" AutoFeatureExtractor class.""" +import importlib +import json +import os +from collections import OrderedDict +from typing import Dict, Optional, Union + +# Build the list of all feature extractors +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...feature_extraction_utils import FeatureExtractionMixin +from ...utils import CONFIG_NAME, FEATURE_EXTRACTOR_NAME, get_file_from_repo, logging +from .auto_factory import _LazyAutoMapping +from .configuration_auto import ( + CONFIG_MAPPING_NAMES, + AutoConfig, + model_type_to_module_name, + replace_list_option_in_docstrings, +) + + +logger = logging.get_logger(__name__) + +FEATURE_EXTRACTOR_MAPPING_NAMES = OrderedDict( + [ + ("audio-spectrogram-transformer", "ASTFeatureExtractor"), + ("beit", "BeitFeatureExtractor"), + ("chinese_clip", "ChineseCLIPFeatureExtractor"), + ("clap", "ClapFeatureExtractor"), + ("clip", "CLIPFeatureExtractor"), + ("clipseg", "ViTFeatureExtractor"), + ("conditional_detr", "ConditionalDetrFeatureExtractor"), + ("convnext", "ConvNextFeatureExtractor"), + ("cvt", "ConvNextFeatureExtractor"), + ("data2vec-audio", "Wav2Vec2FeatureExtractor"), + ("data2vec-vision", "BeitFeatureExtractor"), + ("deformable_detr", "DeformableDetrFeatureExtractor"), + ("deit", "DeiTFeatureExtractor"), + ("detr", "DetrFeatureExtractor"), + ("dinat", "ViTFeatureExtractor"), + ("donut-swin", "DonutFeatureExtractor"), + ("dpt", "DPTFeatureExtractor"), + ("flava", "FlavaFeatureExtractor"), + ("glpn", "GLPNFeatureExtractor"), + ("groupvit", "CLIPFeatureExtractor"), + ("hubert", "Wav2Vec2FeatureExtractor"), + ("imagegpt", "ImageGPTFeatureExtractor"), + ("layoutlmv2", "LayoutLMv2FeatureExtractor"), + ("layoutlmv3", "LayoutLMv3FeatureExtractor"), + ("levit", "LevitFeatureExtractor"), + ("maskformer", "MaskFormerFeatureExtractor"), + ("mctct", "MCTCTFeatureExtractor"), + ("mobilenet_v1", "MobileNetV1FeatureExtractor"), + ("mobilenet_v2", "MobileNetV2FeatureExtractor"), + ("mobilevit", "MobileViTFeatureExtractor"), + ("nat", "ViTFeatureExtractor"), + ("owlvit", "OwlViTFeatureExtractor"), + ("perceiver", "PerceiverFeatureExtractor"), + ("poolformer", "PoolFormerFeatureExtractor"), + ("regnet", "ConvNextFeatureExtractor"), + ("resnet", "ConvNextFeatureExtractor"), + ("segformer", "SegformerFeatureExtractor"), + ("sew", "Wav2Vec2FeatureExtractor"), + ("sew-d", "Wav2Vec2FeatureExtractor"), + ("speech_to_text", "Speech2TextFeatureExtractor"), + ("speecht5", "SpeechT5FeatureExtractor"), + ("swin", "ViTFeatureExtractor"), + ("swinv2", "ViTFeatureExtractor"), + ("table-transformer", "DetrFeatureExtractor"), + ("timesformer", "VideoMAEFeatureExtractor"), + ("tvlt", "TvltFeatureExtractor"), + ("unispeech", "Wav2Vec2FeatureExtractor"), + ("unispeech-sat", "Wav2Vec2FeatureExtractor"), + ("van", "ConvNextFeatureExtractor"), + ("videomae", "VideoMAEFeatureExtractor"), + ("vilt", "ViltFeatureExtractor"), + ("vit", "ViTFeatureExtractor"), + ("vit_mae", "ViTFeatureExtractor"), + ("vit_msn", "ViTFeatureExtractor"), + ("wav2vec2", "Wav2Vec2FeatureExtractor"), + ("wav2vec2-conformer", "Wav2Vec2FeatureExtractor"), + ("wavlm", "Wav2Vec2FeatureExtractor"), + ("whisper", "WhisperFeatureExtractor"), + ("xclip", "CLIPFeatureExtractor"), + ("yolos", "YolosFeatureExtractor"), + ] +) + +FEATURE_EXTRACTOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FEATURE_EXTRACTOR_MAPPING_NAMES) + + +def feature_extractor_class_from_name(class_name: str): + for module_name, extractors in FEATURE_EXTRACTOR_MAPPING_NAMES.items(): + if class_name in extractors: + module_name = model_type_to_module_name(module_name) + + module = importlib.import_module(f".{module_name}", "transformers.models") + try: + return getattr(module, class_name) + except AttributeError: + continue + + for _, extractor in FEATURE_EXTRACTOR_MAPPING._extra_content.items(): + if getattr(extractor, "__name__", None) == class_name: + return extractor + + # We did not fine the class, but maybe it's because a dep is missing. In that case, the class will be in the main + # init and we return the proper dummy to get an appropriate error message. + main_module = importlib.import_module("transformers") + if hasattr(main_module, class_name): + return getattr(main_module, class_name) + + return None + + +def get_feature_extractor_config( + pretrained_model_name_or_path: Union[str, os.PathLike], + cache_dir: Optional[Union[str, os.PathLike]] = None, + force_download: bool = False, + resume_download: bool = False, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, + revision: Optional[str] = None, + local_files_only: bool = False, + **kwargs, +): + """ + Loads the tokenizer configuration from a pretrained model tokenizer configuration. + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained model configuration hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced + under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a configuration file saved using the + [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`. + + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the standard + cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the configuration files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, will only try to load the tokenizer configuration from local files. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Returns: + `Dict`: The configuration of the tokenizer. + + Examples: + + ```python + # Download configuration from huggingface.co and cache. + tokenizer_config = get_tokenizer_config("bert-base-uncased") + # This model does not have a tokenizer config so the result will be an empty dict. + tokenizer_config = get_tokenizer_config("xlm-roberta-base") + + # Save a pretrained tokenizer locally and you can reload its config + from transformers import AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") + tokenizer.save_pretrained("tokenizer-test") + tokenizer_config = get_tokenizer_config("tokenizer-test") + ```""" + resolved_config_file = get_file_from_repo( + pretrained_model_name_or_path, + FEATURE_EXTRACTOR_NAME, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + use_auth_token=use_auth_token, + revision=revision, + local_files_only=local_files_only, + ) + if resolved_config_file is None: + logger.info( + "Could not locate the feature extractor configuration file, will try to use the model config instead." + ) + return {} + + with open(resolved_config_file, encoding="utf-8") as reader: + return json.load(reader) + + +class AutoFeatureExtractor: + r""" + This is a generic feature extractor class that will be instantiated as one of the feature extractor classes of the + library when created with the [`AutoFeatureExtractor.from_pretrained`] class method. + + This class cannot be instantiated directly using `__init__()` (throws an error). + """ + + def __init__(self): + raise EnvironmentError( + "AutoFeatureExtractor is designed to be instantiated " + "using the `AutoFeatureExtractor.from_pretrained(pretrained_model_name_or_path)` method." + ) + + @classmethod + @replace_list_option_in_docstrings(FEATURE_EXTRACTOR_MAPPING_NAMES) + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + r""" + Instantiate one of the feature extractor classes of the library from a pretrained model vocabulary. + + The feature extractor class to instantiate is selected based on the `model_type` property of the config object + (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's + missing, by falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Params: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or + namespaced under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a feature extractor file saved using the + [`~feature_extraction_utils.FeatureExtractionMixin.save_pretrained`] method, e.g., + `./my_model_directory/`. + - a path or url to a saved feature extractor JSON *file*, e.g., + `./my_model_directory/preprocessor_config.json`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model feature extractor should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the feature extractor files and override the cached versions + if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file + exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + return_unused_kwargs (`bool`, *optional*, defaults to `False`): + If `False`, then this function returns just the final feature extractor object. If `True`, then this + functions returns a `Tuple(feature_extractor, unused_kwargs)` where *unused_kwargs* is a dictionary + consisting of the key/value pairs whose keys are not feature extractor attributes: i.e., the part of + `kwargs` which has not been used to update `feature_extractor` and is otherwise ignored. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (`Dict[str, Any]`, *optional*): + The values in kwargs of any keys which are feature extractor attributes will be used to override the + loaded values. Behavior concerning key/value pairs whose keys are *not* feature extractor attributes is + controlled by the `return_unused_kwargs` keyword parameter. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Examples: + + ```python + >>> from transformers import AutoFeatureExtractor + + >>> # Download feature extractor from huggingface.co and cache. + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base-960h") + + >>> # If feature extractor files are in a directory (e.g. feature extractor was saved using *save_pretrained('./test/saved_model/')*) + >>> # feature_extractor = AutoFeatureExtractor.from_pretrained("./test/saved_model/") + ```""" + config = kwargs.pop("config", None) + trust_remote_code = kwargs.pop("trust_remote_code", False) + kwargs["_from_auto"] = True + + config_dict, _ = FeatureExtractionMixin.get_feature_extractor_dict(pretrained_model_name_or_path, **kwargs) + feature_extractor_class = config_dict.get("feature_extractor_type", None) + feature_extractor_auto_map = None + if "AutoFeatureExtractor" in config_dict.get("auto_map", {}): + feature_extractor_auto_map = config_dict["auto_map"]["AutoFeatureExtractor"] + + # If we don't find the feature extractor class in the feature extractor config, let's try the model config. + if feature_extractor_class is None and feature_extractor_auto_map is None: + if not isinstance(config, PretrainedConfig): + config = AutoConfig.from_pretrained(pretrained_model_name_or_path, **kwargs) + # It could be in `config.feature_extractor_type`` + feature_extractor_class = getattr(config, "feature_extractor_type", None) + if hasattr(config, "auto_map") and "AutoFeatureExtractor" in config.auto_map: + feature_extractor_auto_map = config.auto_map["AutoFeatureExtractor"] + + if feature_extractor_class is not None: + # If we have custom code for a feature extractor, we get the proper class. + if feature_extractor_auto_map is not None: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the feature extractor file " + "in that repo on your local machine. Make sure you have read the code there to avoid " + "malicious use, then set the option `trust_remote_code=True` to remove this error." + ) + feature_extractor_class = get_class_from_dynamic_module( + feature_extractor_auto_map, pretrained_model_name_or_path, **kwargs + ) + else: + feature_extractor_class = feature_extractor_class_from_name(feature_extractor_class) + + return feature_extractor_class.from_dict(config_dict, **kwargs) + # Last try: we use the FEATURE_EXTRACTOR_MAPPING. + elif type(config) in FEATURE_EXTRACTOR_MAPPING: + feature_extractor_class = FEATURE_EXTRACTOR_MAPPING[type(config)] + return feature_extractor_class.from_dict(config_dict, **kwargs) + + raise ValueError( + f"Unrecognized feature extractor in {pretrained_model_name_or_path}. Should have a " + f"`feature_extractor_type` key in its {FEATURE_EXTRACTOR_NAME} of {CONFIG_NAME}, or one of the following " + f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in FEATURE_EXTRACTOR_MAPPING_NAMES.keys())}" + ) + + @staticmethod + def register(config_class, feature_extractor_class): + """ + Register a new feature extractor for this class. + + Args: + config_class ([`PretrainedConfig`]): + The configuration corresponding to the model to register. + feature_extractor_class ([`FeatureExtractorMixin`]): The feature extractor to register. + """ + FEATURE_EXTRACTOR_MAPPING.register(config_class, feature_extractor_class) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/image_processing_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/image_processing_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..6445914a395bd66a02272e9df92e281eb8d5dd3d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/image_processing_auto.py @@ -0,0 +1,388 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" AutoImageProcessor class.""" +import importlib +import json +import os +from collections import OrderedDict +from typing import Dict, Optional, Union + +# Build the list of all image processors +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...image_processing_utils import ImageProcessingMixin +from ...utils import CONFIG_NAME, IMAGE_PROCESSOR_NAME, get_file_from_repo, logging +from .auto_factory import _LazyAutoMapping +from .configuration_auto import ( + CONFIG_MAPPING_NAMES, + AutoConfig, + model_type_to_module_name, + replace_list_option_in_docstrings, +) + + +logger = logging.get_logger(__name__) + +IMAGE_PROCESSOR_MAPPING_NAMES = OrderedDict( + [ + ("align", "EfficientNetImageProcessor"), + ("beit", "BeitImageProcessor"), + ("bit", "BitImageProcessor"), + ("blip", "BlipImageProcessor"), + ("blip-2", "BlipImageProcessor"), + ("bridgetower", "BridgeTowerImageProcessor"), + ("chinese_clip", "ChineseCLIPImageProcessor"), + ("clip", "CLIPImageProcessor"), + ("clipseg", "ViTImageProcessor"), + ("conditional_detr", "ConditionalDetrImageProcessor"), + ("convnext", "ConvNextImageProcessor"), + ("convnextv2", "ConvNextImageProcessor"), + ("cvt", "ConvNextImageProcessor"), + ("data2vec-vision", "BeitImageProcessor"), + ("deformable_detr", "DeformableDetrImageProcessor"), + ("deit", "DeiTImageProcessor"), + ("deta", "DetaImageProcessor"), + ("detr", "DetrImageProcessor"), + ("dinat", "ViTImageProcessor"), + ("donut-swin", "DonutImageProcessor"), + ("dpt", "DPTImageProcessor"), + ("efficientformer", "EfficientFormerImageProcessor"), + ("efficientnet", "EfficientNetImageProcessor"), + ("flava", "FlavaImageProcessor"), + ("focalnet", "BitImageProcessor"), + ("git", "CLIPImageProcessor"), + ("glpn", "GLPNImageProcessor"), + ("groupvit", "CLIPImageProcessor"), + ("imagegpt", "ImageGPTImageProcessor"), + ("layoutlmv2", "LayoutLMv2ImageProcessor"), + ("layoutlmv3", "LayoutLMv3ImageProcessor"), + ("levit", "LevitImageProcessor"), + ("mask2former", "Mask2FormerImageProcessor"), + ("maskformer", "MaskFormerImageProcessor"), + ("mgp-str", "ViTImageProcessor"), + ("mobilenet_v1", "MobileNetV1ImageProcessor"), + ("mobilenet_v2", "MobileNetV2ImageProcessor"), + ("mobilenet_v2", "MobileNetV2ImageProcessor"), + ("mobilevit", "MobileViTImageProcessor"), + ("mobilevit", "MobileViTImageProcessor"), + ("nat", "ViTImageProcessor"), + ("oneformer", "OneFormerImageProcessor"), + ("owlvit", "OwlViTImageProcessor"), + ("perceiver", "PerceiverImageProcessor"), + ("pix2struct", "Pix2StructImageProcessor"), + ("poolformer", "PoolFormerImageProcessor"), + ("regnet", "ConvNextImageProcessor"), + ("resnet", "ConvNextImageProcessor"), + ("sam", "SamImageProcessor"), + ("segformer", "SegformerImageProcessor"), + ("swin", "ViTImageProcessor"), + ("swin2sr", "Swin2SRImageProcessor"), + ("swinv2", "ViTImageProcessor"), + ("table-transformer", "DetrImageProcessor"), + ("timesformer", "VideoMAEImageProcessor"), + ("tvlt", "TvltImageProcessor"), + ("upernet", "SegformerImageProcessor"), + ("van", "ConvNextImageProcessor"), + ("videomae", "VideoMAEImageProcessor"), + ("vilt", "ViltImageProcessor"), + ("vit", "ViTImageProcessor"), + ("vit_hybrid", "ViTHybridImageProcessor"), + ("vit_mae", "ViTImageProcessor"), + ("vit_msn", "ViTImageProcessor"), + ("xclip", "CLIPImageProcessor"), + ("yolos", "YolosImageProcessor"), + ] +) + +IMAGE_PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, IMAGE_PROCESSOR_MAPPING_NAMES) + + +def image_processor_class_from_name(class_name: str): + for module_name, extractors in IMAGE_PROCESSOR_MAPPING_NAMES.items(): + if class_name in extractors: + module_name = model_type_to_module_name(module_name) + + module = importlib.import_module(f".{module_name}", "transformers.models") + try: + return getattr(module, class_name) + except AttributeError: + continue + + for _, extractor in IMAGE_PROCESSOR_MAPPING._extra_content.items(): + if getattr(extractor, "__name__", None) == class_name: + return extractor + + # We did not fine the class, but maybe it's because a dep is missing. In that case, the class will be in the main + # init and we return the proper dummy to get an appropriate error message. + main_module = importlib.import_module("transformers") + if hasattr(main_module, class_name): + return getattr(main_module, class_name) + + return None + + +def get_image_processor_config( + pretrained_model_name_or_path: Union[str, os.PathLike], + cache_dir: Optional[Union[str, os.PathLike]] = None, + force_download: bool = False, + resume_download: bool = False, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, + revision: Optional[str] = None, + local_files_only: bool = False, + **kwargs, +): + """ + Loads the image processor configuration from a pretrained model image processor configuration. + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained model configuration hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced + under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a configuration file saved using the + [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`. + + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the standard + cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the configuration files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, will only try to load the image processor configuration from local files. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Returns: + `Dict`: The configuration of the image processor. + + Examples: + + ```python + # Download configuration from huggingface.co and cache. + image_processor_config = get_image_processor_config("bert-base-uncased") + # This model does not have a image processor config so the result will be an empty dict. + image_processor_config = get_image_processor_config("xlm-roberta-base") + + # Save a pretrained image processor locally and you can reload its config + from transformers import AutoTokenizer + + image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") + image_processor.save_pretrained("image-processor-test") + image_processor_config = get_image_processor_config("image-processor-test") + ```""" + resolved_config_file = get_file_from_repo( + pretrained_model_name_or_path, + IMAGE_PROCESSOR_NAME, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + use_auth_token=use_auth_token, + revision=revision, + local_files_only=local_files_only, + ) + if resolved_config_file is None: + logger.info( + "Could not locate the image processor configuration file, will try to use the model config instead." + ) + return {} + + with open(resolved_config_file, encoding="utf-8") as reader: + return json.load(reader) + + +class AutoImageProcessor: + r""" + This is a generic image processor class that will be instantiated as one of the image processor classes of the + library when created with the [`AutoImageProcessor.from_pretrained`] class method. + + This class cannot be instantiated directly using `__init__()` (throws an error). + """ + + def __init__(self): + raise EnvironmentError( + "AutoImageProcessor is designed to be instantiated " + "using the `AutoImageProcessor.from_pretrained(pretrained_model_name_or_path)` method." + ) + + @classmethod + @replace_list_option_in_docstrings(IMAGE_PROCESSOR_MAPPING_NAMES) + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + r""" + Instantiate one of the image processor classes of the library from a pretrained model vocabulary. + + The image processor class to instantiate is selected based on the `model_type` property of the config object + (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's + missing, by falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Params: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained image_processor hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or + namespaced under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a image processor file saved using the + [`~image_processing_utils.ImageProcessingMixin.save_pretrained`] method, e.g., + `./my_model_directory/`. + - a path or url to a saved image processor JSON *file*, e.g., + `./my_model_directory/preprocessor_config.json`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model image processor should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the image processor files and override the cached versions if + they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file + exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + return_unused_kwargs (`bool`, *optional*, defaults to `False`): + If `False`, then this function returns just the final image processor object. If `True`, then this + functions returns a `Tuple(image_processor, unused_kwargs)` where *unused_kwargs* is a dictionary + consisting of the key/value pairs whose keys are not image processor attributes: i.e., the part of + `kwargs` which has not been used to update `image_processor` and is otherwise ignored. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (`Dict[str, Any]`, *optional*): + The values in kwargs of any keys which are image processor attributes will be used to override the + loaded values. Behavior concerning key/value pairs whose keys are *not* image processor attributes is + controlled by the `return_unused_kwargs` keyword parameter. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Examples: + + ```python + >>> from transformers import AutoImageProcessor + + >>> # Download image processor from huggingface.co and cache. + >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") + + >>> # If image processor files are in a directory (e.g. image processor was saved using *save_pretrained('./test/saved_model/')*) + >>> # image_processor = AutoImageProcessor.from_pretrained("./test/saved_model/") + ```""" + config = kwargs.pop("config", None) + trust_remote_code = kwargs.pop("trust_remote_code", False) + kwargs["_from_auto"] = True + + config_dict, _ = ImageProcessingMixin.get_image_processor_dict(pretrained_model_name_or_path, **kwargs) + image_processor_class = config_dict.get("image_processor_type", None) + image_processor_auto_map = None + if "AutoImageProcessor" in config_dict.get("auto_map", {}): + image_processor_auto_map = config_dict["auto_map"]["AutoImageProcessor"] + + # If we still don't have the image processor class, check if we're loading from a previous feature extractor config + # and if so, infer the image processor class from there. + if image_processor_class is None and image_processor_auto_map is None: + feature_extractor_class = config_dict.pop("feature_extractor_type", None) + if feature_extractor_class is not None: + logger.warning( + "Could not find image processor class in the image processor config or the model config. Loading" + " based on pattern matching with the model's feature extractor configuration." + ) + image_processor_class = feature_extractor_class.replace("FeatureExtractor", "ImageProcessor") + if "AutoFeatureExtractor" in config_dict.get("auto_map", {}): + feature_extractor_auto_map = config_dict["auto_map"]["AutoFeatureExtractor"] + image_processor_auto_map = feature_extractor_auto_map.replace("FeatureExtractor", "ImageProcessor") + logger.warning( + "Could not find image processor auto map in the image processor config or the model config." + " Loading based on pattern matching with the model's feature extractor configuration." + ) + + # If we don't find the image processor class in the image processor config, let's try the model config. + if image_processor_class is None and image_processor_auto_map is None: + if not isinstance(config, PretrainedConfig): + config = AutoConfig.from_pretrained(pretrained_model_name_or_path, **kwargs) + # It could be in `config.image_processor_type`` + image_processor_class = getattr(config, "image_processor_type", None) + if hasattr(config, "auto_map") and "AutoImageProcessor" in config.auto_map: + image_processor_auto_map = config.auto_map["AutoImageProcessor"] + + if image_processor_class is not None: + # If we have custom code for a image processor, we get the proper class. + if image_processor_auto_map is not None: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the image processor file " + "in that repo on your local machine. Make sure you have read the code there to avoid " + "malicious use, then set the option `trust_remote_code=True` to remove this error." + ) + image_processor_class = get_class_from_dynamic_module( + image_processor_auto_map, pretrained_model_name_or_path, **kwargs + ) + else: + image_processor_class = image_processor_class_from_name(image_processor_class) + + return image_processor_class.from_dict(config_dict, **kwargs) + # Last try: we use the IMAGE_PROCESSOR_MAPPING. + elif type(config) in IMAGE_PROCESSOR_MAPPING: + image_processor_class = IMAGE_PROCESSOR_MAPPING[type(config)] + return image_processor_class.from_dict(config_dict, **kwargs) + + raise ValueError( + f"Unrecognized image processor in {pretrained_model_name_or_path}. Should have a " + f"`image_processor_type` key in its {IMAGE_PROCESSOR_NAME} of {CONFIG_NAME}, or one of the following " + f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in IMAGE_PROCESSOR_MAPPING_NAMES.keys())}" + ) + + @staticmethod + def register(config_class, image_processor_class): + """ + Register a new image processor for this class. + + Args: + config_class ([`PretrainedConfig`]): + The configuration corresponding to the model to register. + image_processor_class ([`ImageProcessingMixin`]): The image processor to register. + """ + IMAGE_PROCESSOR_MAPPING.register(config_class, image_processor_class) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..8e1835e31f09763785f9da294645b5afcdc4aea2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_auto.py @@ -0,0 +1,1358 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Auto Model class.""" + +import warnings +from collections import OrderedDict + +from ...utils import logging +from .auto_factory import _BaseAutoModelClass, _LazyAutoMapping, auto_class_update +from .configuration_auto import CONFIG_MAPPING_NAMES + + +logger = logging.get_logger(__name__) + + +MODEL_MAPPING_NAMES = OrderedDict( + [ + # Base model mapping + ("albert", "AlbertModel"), + ("align", "AlignModel"), + ("altclip", "AltCLIPModel"), + ("audio-spectrogram-transformer", "ASTModel"), + ("bart", "BartModel"), + ("beit", "BeitModel"), + ("bert", "BertModel"), + ("bert-generation", "BertGenerationEncoder"), + ("big_bird", "BigBirdModel"), + ("bigbird_pegasus", "BigBirdPegasusModel"), + ("biogpt", "BioGptModel"), + ("bit", "BitModel"), + ("blenderbot", "BlenderbotModel"), + ("blenderbot-small", "BlenderbotSmallModel"), + ("blip", "BlipModel"), + ("blip-2", "Blip2Model"), + ("bloom", "BloomModel"), + ("bridgetower", "BridgeTowerModel"), + ("camembert", "CamembertModel"), + ("canine", "CanineModel"), + ("chinese_clip", "ChineseCLIPModel"), + ("clap", "ClapModel"), + ("clip", "CLIPModel"), + ("clipseg", "CLIPSegModel"), + ("codegen", "CodeGenModel"), + ("conditional_detr", "ConditionalDetrModel"), + ("convbert", "ConvBertModel"), + ("convnext", "ConvNextModel"), + ("convnextv2", "ConvNextV2Model"), + ("cpmant", "CpmAntModel"), + ("ctrl", "CTRLModel"), + ("cvt", "CvtModel"), + ("data2vec-audio", "Data2VecAudioModel"), + ("data2vec-text", "Data2VecTextModel"), + ("data2vec-vision", "Data2VecVisionModel"), + ("deberta", "DebertaModel"), + ("deberta-v2", "DebertaV2Model"), + ("decision_transformer", "DecisionTransformerModel"), + ("deformable_detr", "DeformableDetrModel"), + ("deit", "DeiTModel"), + ("deta", "DetaModel"), + ("detr", "DetrModel"), + ("dinat", "DinatModel"), + ("distilbert", "DistilBertModel"), + ("donut-swin", "DonutSwinModel"), + ("dpr", "DPRQuestionEncoder"), + ("dpt", "DPTModel"), + ("efficientformer", "EfficientFormerModel"), + ("efficientnet", "EfficientNetModel"), + ("electra", "ElectraModel"), + ("ernie", "ErnieModel"), + ("ernie_m", "ErnieMModel"), + ("esm", "EsmModel"), + ("flaubert", "FlaubertModel"), + ("flava", "FlavaModel"), + ("fnet", "FNetModel"), + ("focalnet", "FocalNetModel"), + ("fsmt", "FSMTModel"), + ("funnel", ("FunnelModel", "FunnelBaseModel")), + ("git", "GitModel"), + ("glpn", "GLPNModel"), + ("gpt-sw3", "GPT2Model"), + ("gpt2", "GPT2Model"), + ("gpt_bigcode", "GPTBigCodeModel"), + ("gpt_neo", "GPTNeoModel"), + ("gpt_neox", "GPTNeoXModel"), + ("gpt_neox_japanese", "GPTNeoXJapaneseModel"), + ("gptj", "GPTJModel"), + ("gptsan-japanese", "GPTSanJapaneseForConditionalGeneration"), + ("graphormer", "GraphormerModel"), + ("groupvit", "GroupViTModel"), + ("hubert", "HubertModel"), + ("ibert", "IBertModel"), + ("imagegpt", "ImageGPTModel"), + ("informer", "InformerModel"), + ("jukebox", "JukeboxModel"), + ("layoutlm", "LayoutLMModel"), + ("layoutlmv2", "LayoutLMv2Model"), + ("layoutlmv3", "LayoutLMv3Model"), + ("led", "LEDModel"), + ("levit", "LevitModel"), + ("lilt", "LiltModel"), + ("llama", "LlamaModel"), + ("longformer", "LongformerModel"), + ("longt5", "LongT5Model"), + ("luke", "LukeModel"), + ("lxmert", "LxmertModel"), + ("m2m_100", "M2M100Model"), + ("marian", "MarianModel"), + ("markuplm", "MarkupLMModel"), + ("mask2former", "Mask2FormerModel"), + ("maskformer", "MaskFormerModel"), + ("maskformer-swin", "MaskFormerSwinModel"), + ("mbart", "MBartModel"), + ("mctct", "MCTCTModel"), + ("mega", "MegaModel"), + ("megatron-bert", "MegatronBertModel"), + ("mgp-str", "MgpstrForSceneTextRecognition"), + ("mobilebert", "MobileBertModel"), + ("mobilenet_v1", "MobileNetV1Model"), + ("mobilenet_v2", "MobileNetV2Model"), + ("mobilevit", "MobileViTModel"), + ("mpnet", "MPNetModel"), + ("mt5", "MT5Model"), + ("mvp", "MvpModel"), + ("nat", "NatModel"), + ("nezha", "NezhaModel"), + ("nllb-moe", "NllbMoeModel"), + ("nystromformer", "NystromformerModel"), + ("oneformer", "OneFormerModel"), + ("open-llama", "OpenLlamaModel"), + ("openai-gpt", "OpenAIGPTModel"), + ("opt", "OPTModel"), + ("owlvit", "OwlViTModel"), + ("pegasus", "PegasusModel"), + ("pegasus_x", "PegasusXModel"), + ("perceiver", "PerceiverModel"), + ("plbart", "PLBartModel"), + ("poolformer", "PoolFormerModel"), + ("prophetnet", "ProphetNetModel"), + ("qdqbert", "QDQBertModel"), + ("reformer", "ReformerModel"), + ("regnet", "RegNetModel"), + ("rembert", "RemBertModel"), + ("resnet", "ResNetModel"), + ("retribert", "RetriBertModel"), + ("roberta", "RobertaModel"), + ("roberta-prelayernorm", "RobertaPreLayerNormModel"), + ("roc_bert", "RoCBertModel"), + ("roformer", "RoFormerModel"), + ("rwkv", "RwkvModel"), + ("sam", "SamModel"), + ("segformer", "SegformerModel"), + ("sew", "SEWModel"), + ("sew-d", "SEWDModel"), + ("speech_to_text", "Speech2TextModel"), + ("speecht5", "SpeechT5Model"), + ("splinter", "SplinterModel"), + ("squeezebert", "SqueezeBertModel"), + ("swin", "SwinModel"), + ("swin2sr", "Swin2SRModel"), + ("swinv2", "Swinv2Model"), + ("switch_transformers", "SwitchTransformersModel"), + ("t5", "T5Model"), + ("table-transformer", "TableTransformerModel"), + ("tapas", "TapasModel"), + ("time_series_transformer", "TimeSeriesTransformerModel"), + ("timesformer", "TimesformerModel"), + ("trajectory_transformer", "TrajectoryTransformerModel"), + ("transfo-xl", "TransfoXLModel"), + ("tvlt", "TvltModel"), + ("unispeech", "UniSpeechModel"), + ("unispeech-sat", "UniSpeechSatModel"), + ("van", "VanModel"), + ("videomae", "VideoMAEModel"), + ("vilt", "ViltModel"), + ("vision-text-dual-encoder", "VisionTextDualEncoderModel"), + ("visual_bert", "VisualBertModel"), + ("vit", "ViTModel"), + ("vit_hybrid", "ViTHybridModel"), + ("vit_mae", "ViTMAEModel"), + ("vit_msn", "ViTMSNModel"), + ("wav2vec2", "Wav2Vec2Model"), + ("wav2vec2-conformer", "Wav2Vec2ConformerModel"), + ("wavlm", "WavLMModel"), + ("whisper", "WhisperModel"), + ("xclip", "XCLIPModel"), + ("xglm", "XGLMModel"), + ("xlm", "XLMModel"), + ("xlm-prophetnet", "XLMProphetNetModel"), + ("xlm-roberta", "XLMRobertaModel"), + ("xlm-roberta-xl", "XLMRobertaXLModel"), + ("xlnet", "XLNetModel"), + ("xmod", "XmodModel"), + ("yolos", "YolosModel"), + ("yoso", "YosoModel"), + ] +) + +MODEL_FOR_PRETRAINING_MAPPING_NAMES = OrderedDict( + [ + # Model for pre-training mapping + ("albert", "AlbertForPreTraining"), + ("bart", "BartForConditionalGeneration"), + ("bert", "BertForPreTraining"), + ("big_bird", "BigBirdForPreTraining"), + ("bloom", "BloomForCausalLM"), + ("camembert", "CamembertForMaskedLM"), + ("ctrl", "CTRLLMHeadModel"), + ("data2vec-text", "Data2VecTextForMaskedLM"), + ("deberta", "DebertaForMaskedLM"), + ("deberta-v2", "DebertaV2ForMaskedLM"), + ("distilbert", "DistilBertForMaskedLM"), + ("electra", "ElectraForPreTraining"), + ("ernie", "ErnieForPreTraining"), + ("flaubert", "FlaubertWithLMHeadModel"), + ("flava", "FlavaForPreTraining"), + ("fnet", "FNetForPreTraining"), + ("fsmt", "FSMTForConditionalGeneration"), + ("funnel", "FunnelForPreTraining"), + ("gpt-sw3", "GPT2LMHeadModel"), + ("gpt2", "GPT2LMHeadModel"), + ("gpt_bigcode", "GPTBigCodeForCausalLM"), + ("gptsan-japanese", "GPTSanJapaneseForConditionalGeneration"), + ("ibert", "IBertForMaskedLM"), + ("layoutlm", "LayoutLMForMaskedLM"), + ("longformer", "LongformerForMaskedLM"), + ("luke", "LukeForMaskedLM"), + ("lxmert", "LxmertForPreTraining"), + ("mega", "MegaForMaskedLM"), + ("megatron-bert", "MegatronBertForPreTraining"), + ("mobilebert", "MobileBertForPreTraining"), + ("mpnet", "MPNetForMaskedLM"), + ("mvp", "MvpForConditionalGeneration"), + ("nezha", "NezhaForPreTraining"), + ("nllb-moe", "NllbMoeForConditionalGeneration"), + ("openai-gpt", "OpenAIGPTLMHeadModel"), + ("retribert", "RetriBertModel"), + ("roberta", "RobertaForMaskedLM"), + ("roberta-prelayernorm", "RobertaPreLayerNormForMaskedLM"), + ("roc_bert", "RoCBertForPreTraining"), + ("rwkv", "RwkvForCausalLM"), + ("splinter", "SplinterForPreTraining"), + ("squeezebert", "SqueezeBertForMaskedLM"), + ("switch_transformers", "SwitchTransformersForConditionalGeneration"), + ("t5", "T5ForConditionalGeneration"), + ("tapas", "TapasForMaskedLM"), + ("transfo-xl", "TransfoXLLMHeadModel"), + ("tvlt", "TvltForPreTraining"), + ("unispeech", "UniSpeechForPreTraining"), + ("unispeech-sat", "UniSpeechSatForPreTraining"), + ("videomae", "VideoMAEForPreTraining"), + ("visual_bert", "VisualBertForPreTraining"), + ("vit_mae", "ViTMAEForPreTraining"), + ("wav2vec2", "Wav2Vec2ForPreTraining"), + ("wav2vec2-conformer", "Wav2Vec2ConformerForPreTraining"), + ("xlm", "XLMWithLMHeadModel"), + ("xlm-roberta", "XLMRobertaForMaskedLM"), + ("xlm-roberta-xl", "XLMRobertaXLForMaskedLM"), + ("xlnet", "XLNetLMHeadModel"), + ("xmod", "XmodForMaskedLM"), + ] +) + +MODEL_WITH_LM_HEAD_MAPPING_NAMES = OrderedDict( + [ + # Model with LM heads mapping + ("albert", "AlbertForMaskedLM"), + ("bart", "BartForConditionalGeneration"), + ("bert", "BertForMaskedLM"), + ("big_bird", "BigBirdForMaskedLM"), + ("bigbird_pegasus", "BigBirdPegasusForConditionalGeneration"), + ("blenderbot-small", "BlenderbotSmallForConditionalGeneration"), + ("bloom", "BloomForCausalLM"), + ("camembert", "CamembertForMaskedLM"), + ("codegen", "CodeGenForCausalLM"), + ("convbert", "ConvBertForMaskedLM"), + ("cpmant", "CpmAntForCausalLM"), + ("ctrl", "CTRLLMHeadModel"), + ("data2vec-text", "Data2VecTextForMaskedLM"), + ("deberta", "DebertaForMaskedLM"), + ("deberta-v2", "DebertaV2ForMaskedLM"), + ("distilbert", "DistilBertForMaskedLM"), + ("electra", "ElectraForMaskedLM"), + ("encoder-decoder", "EncoderDecoderModel"), + ("ernie", "ErnieForMaskedLM"), + ("esm", "EsmForMaskedLM"), + ("flaubert", "FlaubertWithLMHeadModel"), + ("fnet", "FNetForMaskedLM"), + ("fsmt", "FSMTForConditionalGeneration"), + ("funnel", "FunnelForMaskedLM"), + ("git", "GitForCausalLM"), + ("gpt-sw3", "GPT2LMHeadModel"), + ("gpt2", "GPT2LMHeadModel"), + ("gpt_bigcode", "GPTBigCodeForCausalLM"), + ("gpt_neo", "GPTNeoForCausalLM"), + ("gpt_neox", "GPTNeoXForCausalLM"), + ("gpt_neox_japanese", "GPTNeoXJapaneseForCausalLM"), + ("gptj", "GPTJForCausalLM"), + ("gptsan-japanese", "GPTSanJapaneseForConditionalGeneration"), + ("ibert", "IBertForMaskedLM"), + ("layoutlm", "LayoutLMForMaskedLM"), + ("led", "LEDForConditionalGeneration"), + ("longformer", "LongformerForMaskedLM"), + ("longt5", "LongT5ForConditionalGeneration"), + ("luke", "LukeForMaskedLM"), + ("m2m_100", "M2M100ForConditionalGeneration"), + ("marian", "MarianMTModel"), + ("mega", "MegaForMaskedLM"), + ("megatron-bert", "MegatronBertForCausalLM"), + ("mobilebert", "MobileBertForMaskedLM"), + ("mpnet", "MPNetForMaskedLM"), + ("mvp", "MvpForConditionalGeneration"), + ("nezha", "NezhaForMaskedLM"), + ("nllb-moe", "NllbMoeForConditionalGeneration"), + ("nystromformer", "NystromformerForMaskedLM"), + ("openai-gpt", "OpenAIGPTLMHeadModel"), + ("pegasus_x", "PegasusXForConditionalGeneration"), + ("plbart", "PLBartForConditionalGeneration"), + ("qdqbert", "QDQBertForMaskedLM"), + ("reformer", "ReformerModelWithLMHead"), + ("rembert", "RemBertForMaskedLM"), + ("roberta", "RobertaForMaskedLM"), + ("roberta-prelayernorm", "RobertaPreLayerNormForMaskedLM"), + ("roc_bert", "RoCBertForMaskedLM"), + ("roformer", "RoFormerForMaskedLM"), + ("rwkv", "RwkvForCausalLM"), + ("speech_to_text", "Speech2TextForConditionalGeneration"), + ("squeezebert", "SqueezeBertForMaskedLM"), + ("switch_transformers", "SwitchTransformersForConditionalGeneration"), + ("t5", "T5ForConditionalGeneration"), + ("tapas", "TapasForMaskedLM"), + ("transfo-xl", "TransfoXLLMHeadModel"), + ("wav2vec2", "Wav2Vec2ForMaskedLM"), + ("whisper", "WhisperForConditionalGeneration"), + ("xlm", "XLMWithLMHeadModel"), + ("xlm-roberta", "XLMRobertaForMaskedLM"), + ("xlm-roberta-xl", "XLMRobertaXLForMaskedLM"), + ("xlnet", "XLNetLMHeadModel"), + ("xmod", "XmodForMaskedLM"), + ("yoso", "YosoForMaskedLM"), + ] +) + +MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Causal LM mapping + ("bart", "BartForCausalLM"), + ("bert", "BertLMHeadModel"), + ("bert-generation", "BertGenerationDecoder"), + ("big_bird", "BigBirdForCausalLM"), + ("bigbird_pegasus", "BigBirdPegasusForCausalLM"), + ("biogpt", "BioGptForCausalLM"), + ("blenderbot", "BlenderbotForCausalLM"), + ("blenderbot-small", "BlenderbotSmallForCausalLM"), + ("bloom", "BloomForCausalLM"), + ("camembert", "CamembertForCausalLM"), + ("codegen", "CodeGenForCausalLM"), + ("cpmant", "CpmAntForCausalLM"), + ("ctrl", "CTRLLMHeadModel"), + ("data2vec-text", "Data2VecTextForCausalLM"), + ("electra", "ElectraForCausalLM"), + ("ernie", "ErnieForCausalLM"), + ("git", "GitForCausalLM"), + ("gpt-sw3", "GPT2LMHeadModel"), + ("gpt2", "GPT2LMHeadModel"), + ("gpt_bigcode", "GPTBigCodeForCausalLM"), + ("gpt_neo", "GPTNeoForCausalLM"), + ("gpt_neox", "GPTNeoXForCausalLM"), + ("gpt_neox_japanese", "GPTNeoXJapaneseForCausalLM"), + ("gptj", "GPTJForCausalLM"), + ("llama", "LlamaForCausalLM"), + ("marian", "MarianForCausalLM"), + ("mbart", "MBartForCausalLM"), + ("mega", "MegaForCausalLM"), + ("megatron-bert", "MegatronBertForCausalLM"), + ("mvp", "MvpForCausalLM"), + ("open-llama", "OpenLlamaForCausalLM"), + ("openai-gpt", "OpenAIGPTLMHeadModel"), + ("opt", "OPTForCausalLM"), + ("pegasus", "PegasusForCausalLM"), + ("plbart", "PLBartForCausalLM"), + ("prophetnet", "ProphetNetForCausalLM"), + ("qdqbert", "QDQBertLMHeadModel"), + ("reformer", "ReformerModelWithLMHead"), + ("rembert", "RemBertForCausalLM"), + ("roberta", "RobertaForCausalLM"), + ("roberta-prelayernorm", "RobertaPreLayerNormForCausalLM"), + ("roc_bert", "RoCBertForCausalLM"), + ("roformer", "RoFormerForCausalLM"), + ("rwkv", "RwkvForCausalLM"), + ("speech_to_text_2", "Speech2Text2ForCausalLM"), + ("transfo-xl", "TransfoXLLMHeadModel"), + ("trocr", "TrOCRForCausalLM"), + ("xglm", "XGLMForCausalLM"), + ("xlm", "XLMWithLMHeadModel"), + ("xlm-prophetnet", "XLMProphetNetForCausalLM"), + ("xlm-roberta", "XLMRobertaForCausalLM"), + ("xlm-roberta-xl", "XLMRobertaXLForCausalLM"), + ("xlnet", "XLNetLMHeadModel"), + ("xmod", "XmodForCausalLM"), + ] +) + +MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES = OrderedDict( + [ + ("deit", "DeiTForMaskedImageModeling"), + ("focalnet", "FocalNetForMaskedImageModeling"), + ("swin", "SwinForMaskedImageModeling"), + ("swinv2", "Swinv2ForMaskedImageModeling"), + ("vit", "ViTForMaskedImageModeling"), + ] +) + + +MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES = OrderedDict( + # Model for Causal Image Modeling mapping + [ + ("imagegpt", "ImageGPTForCausalImageModeling"), + ] +) + +MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Image Classification mapping + ("beit", "BeitForImageClassification"), + ("bit", "BitForImageClassification"), + ("convnext", "ConvNextForImageClassification"), + ("convnextv2", "ConvNextV2ForImageClassification"), + ("cvt", "CvtForImageClassification"), + ("data2vec-vision", "Data2VecVisionForImageClassification"), + ("deit", ("DeiTForImageClassification", "DeiTForImageClassificationWithTeacher")), + ("dinat", "DinatForImageClassification"), + ( + "efficientformer", + ( + "EfficientFormerForImageClassification", + "EfficientFormerForImageClassificationWithTeacher", + ), + ), + ("efficientnet", "EfficientNetForImageClassification"), + ("focalnet", "FocalNetForImageClassification"), + ("imagegpt", "ImageGPTForImageClassification"), + ("levit", ("LevitForImageClassification", "LevitForImageClassificationWithTeacher")), + ("mobilenet_v1", "MobileNetV1ForImageClassification"), + ("mobilenet_v2", "MobileNetV2ForImageClassification"), + ("mobilevit", "MobileViTForImageClassification"), + ("nat", "NatForImageClassification"), + ( + "perceiver", + ( + "PerceiverForImageClassificationLearned", + "PerceiverForImageClassificationFourier", + "PerceiverForImageClassificationConvProcessing", + ), + ), + ("poolformer", "PoolFormerForImageClassification"), + ("regnet", "RegNetForImageClassification"), + ("resnet", "ResNetForImageClassification"), + ("segformer", "SegformerForImageClassification"), + ("swin", "SwinForImageClassification"), + ("swinv2", "Swinv2ForImageClassification"), + ("van", "VanForImageClassification"), + ("vit", "ViTForImageClassification"), + ("vit_hybrid", "ViTHybridForImageClassification"), + ("vit_msn", "ViTMSNForImageClassification"), + ] +) + +MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES = OrderedDict( + [ + # Do not add new models here, this class will be deprecated in the future. + # Model for Image Segmentation mapping + ("detr", "DetrForSegmentation"), + ] +) + +MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Semantic Segmentation mapping + ("beit", "BeitForSemanticSegmentation"), + ("data2vec-vision", "Data2VecVisionForSemanticSegmentation"), + ("dpt", "DPTForSemanticSegmentation"), + ("mobilenet_v2", "MobileNetV2ForSemanticSegmentation"), + ("mobilevit", "MobileViTForSemanticSegmentation"), + ("segformer", "SegformerForSemanticSegmentation"), + ("upernet", "UperNetForSemanticSegmentation"), + ] +) + +MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Instance Segmentation mapping + # MaskFormerForInstanceSegmentation can be removed from this mapping in v5 + ("maskformer", "MaskFormerForInstanceSegmentation"), + ] +) + +MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Universal Segmentation mapping + ("detr", "DetrForSegmentation"), + ("mask2former", "Mask2FormerForUniversalSegmentation"), + ("maskformer", "MaskFormerForInstanceSegmentation"), + ("oneformer", "OneFormerForUniversalSegmentation"), + ] +) + +MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + ("timesformer", "TimesformerForVideoClassification"), + ("videomae", "VideoMAEForVideoClassification"), + ] +) + +MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("blip", "BlipForConditionalGeneration"), + ("blip-2", "Blip2ForConditionalGeneration"), + ("vision-encoder-decoder", "VisionEncoderDecoderModel"), + ] +) + +MODEL_FOR_MASKED_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Masked LM mapping + ("albert", "AlbertForMaskedLM"), + ("bart", "BartForConditionalGeneration"), + ("bert", "BertForMaskedLM"), + ("big_bird", "BigBirdForMaskedLM"), + ("camembert", "CamembertForMaskedLM"), + ("convbert", "ConvBertForMaskedLM"), + ("data2vec-text", "Data2VecTextForMaskedLM"), + ("deberta", "DebertaForMaskedLM"), + ("deberta-v2", "DebertaV2ForMaskedLM"), + ("distilbert", "DistilBertForMaskedLM"), + ("electra", "ElectraForMaskedLM"), + ("ernie", "ErnieForMaskedLM"), + ("esm", "EsmForMaskedLM"), + ("flaubert", "FlaubertWithLMHeadModel"), + ("fnet", "FNetForMaskedLM"), + ("funnel", "FunnelForMaskedLM"), + ("ibert", "IBertForMaskedLM"), + ("layoutlm", "LayoutLMForMaskedLM"), + ("longformer", "LongformerForMaskedLM"), + ("luke", "LukeForMaskedLM"), + ("mbart", "MBartForConditionalGeneration"), + ("mega", "MegaForMaskedLM"), + ("megatron-bert", "MegatronBertForMaskedLM"), + ("mobilebert", "MobileBertForMaskedLM"), + ("mpnet", "MPNetForMaskedLM"), + ("mvp", "MvpForConditionalGeneration"), + ("nezha", "NezhaForMaskedLM"), + ("nystromformer", "NystromformerForMaskedLM"), + ("perceiver", "PerceiverForMaskedLM"), + ("qdqbert", "QDQBertForMaskedLM"), + ("reformer", "ReformerForMaskedLM"), + ("rembert", "RemBertForMaskedLM"), + ("roberta", "RobertaForMaskedLM"), + ("roberta-prelayernorm", "RobertaPreLayerNormForMaskedLM"), + ("roc_bert", "RoCBertForMaskedLM"), + ("roformer", "RoFormerForMaskedLM"), + ("squeezebert", "SqueezeBertForMaskedLM"), + ("tapas", "TapasForMaskedLM"), + ("wav2vec2", "Wav2Vec2ForMaskedLM"), + ("xlm", "XLMWithLMHeadModel"), + ("xlm-roberta", "XLMRobertaForMaskedLM"), + ("xlm-roberta-xl", "XLMRobertaXLForMaskedLM"), + ("xmod", "XmodForMaskedLM"), + ("yoso", "YosoForMaskedLM"), + ] +) + +MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES = OrderedDict( + [ + # Model for Object Detection mapping + ("conditional_detr", "ConditionalDetrForObjectDetection"), + ("deformable_detr", "DeformableDetrForObjectDetection"), + ("deta", "DetaForObjectDetection"), + ("detr", "DetrForObjectDetection"), + ("table-transformer", "TableTransformerForObjectDetection"), + ("yolos", "YolosForObjectDetection"), + ] +) + +MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING_NAMES = OrderedDict( + [ + # Model for Zero Shot Object Detection mapping + ("owlvit", "OwlViTForObjectDetection") + ] +) + +MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES = OrderedDict( + [ + # Model for depth estimation mapping + ("dpt", "DPTForDepthEstimation"), + ("glpn", "GLPNForDepthEstimation"), + ] +) +MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Seq2Seq Causal LM mapping + ("bart", "BartForConditionalGeneration"), + ("bigbird_pegasus", "BigBirdPegasusForConditionalGeneration"), + ("blenderbot", "BlenderbotForConditionalGeneration"), + ("blenderbot-small", "BlenderbotSmallForConditionalGeneration"), + ("encoder-decoder", "EncoderDecoderModel"), + ("fsmt", "FSMTForConditionalGeneration"), + ("gptsan-japanese", "GPTSanJapaneseForConditionalGeneration"), + ("led", "LEDForConditionalGeneration"), + ("longt5", "LongT5ForConditionalGeneration"), + ("m2m_100", "M2M100ForConditionalGeneration"), + ("marian", "MarianMTModel"), + ("mbart", "MBartForConditionalGeneration"), + ("mt5", "MT5ForConditionalGeneration"), + ("mvp", "MvpForConditionalGeneration"), + ("nllb-moe", "NllbMoeForConditionalGeneration"), + ("pegasus", "PegasusForConditionalGeneration"), + ("pegasus_x", "PegasusXForConditionalGeneration"), + ("plbart", "PLBartForConditionalGeneration"), + ("prophetnet", "ProphetNetForConditionalGeneration"), + ("switch_transformers", "SwitchTransformersForConditionalGeneration"), + ("t5", "T5ForConditionalGeneration"), + ("xlm-prophetnet", "XLMProphetNetForConditionalGeneration"), + ] +) + +MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("speech-encoder-decoder", "SpeechEncoderDecoderModel"), + ("speech_to_text", "Speech2TextForConditionalGeneration"), + ("speecht5", "SpeechT5ForSpeechToText"), + ("whisper", "WhisperForConditionalGeneration"), + ] +) + +MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Sequence Classification mapping + ("albert", "AlbertForSequenceClassification"), + ("bart", "BartForSequenceClassification"), + ("bert", "BertForSequenceClassification"), + ("big_bird", "BigBirdForSequenceClassification"), + ("bigbird_pegasus", "BigBirdPegasusForSequenceClassification"), + ("biogpt", "BioGptForSequenceClassification"), + ("bloom", "BloomForSequenceClassification"), + ("camembert", "CamembertForSequenceClassification"), + ("canine", "CanineForSequenceClassification"), + ("convbert", "ConvBertForSequenceClassification"), + ("ctrl", "CTRLForSequenceClassification"), + ("data2vec-text", "Data2VecTextForSequenceClassification"), + ("deberta", "DebertaForSequenceClassification"), + ("deberta-v2", "DebertaV2ForSequenceClassification"), + ("distilbert", "DistilBertForSequenceClassification"), + ("electra", "ElectraForSequenceClassification"), + ("ernie", "ErnieForSequenceClassification"), + ("ernie_m", "ErnieMForSequenceClassification"), + ("esm", "EsmForSequenceClassification"), + ("flaubert", "FlaubertForSequenceClassification"), + ("fnet", "FNetForSequenceClassification"), + ("funnel", "FunnelForSequenceClassification"), + ("gpt-sw3", "GPT2ForSequenceClassification"), + ("gpt2", "GPT2ForSequenceClassification"), + ("gpt_bigcode", "GPTBigCodeForSequenceClassification"), + ("gpt_neo", "GPTNeoForSequenceClassification"), + ("gpt_neox", "GPTNeoXForSequenceClassification"), + ("gptj", "GPTJForSequenceClassification"), + ("ibert", "IBertForSequenceClassification"), + ("layoutlm", "LayoutLMForSequenceClassification"), + ("layoutlmv2", "LayoutLMv2ForSequenceClassification"), + ("layoutlmv3", "LayoutLMv3ForSequenceClassification"), + ("led", "LEDForSequenceClassification"), + ("lilt", "LiltForSequenceClassification"), + ("llama", "LlamaForSequenceClassification"), + ("longformer", "LongformerForSequenceClassification"), + ("luke", "LukeForSequenceClassification"), + ("markuplm", "MarkupLMForSequenceClassification"), + ("mbart", "MBartForSequenceClassification"), + ("mega", "MegaForSequenceClassification"), + ("megatron-bert", "MegatronBertForSequenceClassification"), + ("mobilebert", "MobileBertForSequenceClassification"), + ("mpnet", "MPNetForSequenceClassification"), + ("mvp", "MvpForSequenceClassification"), + ("nezha", "NezhaForSequenceClassification"), + ("nystromformer", "NystromformerForSequenceClassification"), + ("open-llama", "OpenLlamaForSequenceClassification"), + ("openai-gpt", "OpenAIGPTForSequenceClassification"), + ("opt", "OPTForSequenceClassification"), + ("perceiver", "PerceiverForSequenceClassification"), + ("plbart", "PLBartForSequenceClassification"), + ("qdqbert", "QDQBertForSequenceClassification"), + ("reformer", "ReformerForSequenceClassification"), + ("rembert", "RemBertForSequenceClassification"), + ("roberta", "RobertaForSequenceClassification"), + ("roberta-prelayernorm", "RobertaPreLayerNormForSequenceClassification"), + ("roc_bert", "RoCBertForSequenceClassification"), + ("roformer", "RoFormerForSequenceClassification"), + ("squeezebert", "SqueezeBertForSequenceClassification"), + ("tapas", "TapasForSequenceClassification"), + ("transfo-xl", "TransfoXLForSequenceClassification"), + ("xlm", "XLMForSequenceClassification"), + ("xlm-roberta", "XLMRobertaForSequenceClassification"), + ("xlm-roberta-xl", "XLMRobertaXLForSequenceClassification"), + ("xlnet", "XLNetForSequenceClassification"), + ("xmod", "XmodForSequenceClassification"), + ("yoso", "YosoForSequenceClassification"), + ] +) + +MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + # Model for Question Answering mapping + ("albert", "AlbertForQuestionAnswering"), + ("bart", "BartForQuestionAnswering"), + ("bert", "BertForQuestionAnswering"), + ("big_bird", "BigBirdForQuestionAnswering"), + ("bigbird_pegasus", "BigBirdPegasusForQuestionAnswering"), + ("bloom", "BloomForQuestionAnswering"), + ("camembert", "CamembertForQuestionAnswering"), + ("canine", "CanineForQuestionAnswering"), + ("convbert", "ConvBertForQuestionAnswering"), + ("data2vec-text", "Data2VecTextForQuestionAnswering"), + ("deberta", "DebertaForQuestionAnswering"), + ("deberta-v2", "DebertaV2ForQuestionAnswering"), + ("distilbert", "DistilBertForQuestionAnswering"), + ("electra", "ElectraForQuestionAnswering"), + ("ernie", "ErnieForQuestionAnswering"), + ("ernie_m", "ErnieMForQuestionAnswering"), + ("flaubert", "FlaubertForQuestionAnsweringSimple"), + ("fnet", "FNetForQuestionAnswering"), + ("funnel", "FunnelForQuestionAnswering"), + ("gpt2", "GPT2ForQuestionAnswering"), + ("gpt_neo", "GPTNeoForQuestionAnswering"), + ("gpt_neox", "GPTNeoXForQuestionAnswering"), + ("gptj", "GPTJForQuestionAnswering"), + ("ibert", "IBertForQuestionAnswering"), + ("layoutlmv2", "LayoutLMv2ForQuestionAnswering"), + ("layoutlmv3", "LayoutLMv3ForQuestionAnswering"), + ("led", "LEDForQuestionAnswering"), + ("lilt", "LiltForQuestionAnswering"), + ("longformer", "LongformerForQuestionAnswering"), + ("luke", "LukeForQuestionAnswering"), + ("lxmert", "LxmertForQuestionAnswering"), + ("markuplm", "MarkupLMForQuestionAnswering"), + ("mbart", "MBartForQuestionAnswering"), + ("mega", "MegaForQuestionAnswering"), + ("megatron-bert", "MegatronBertForQuestionAnswering"), + ("mobilebert", "MobileBertForQuestionAnswering"), + ("mpnet", "MPNetForQuestionAnswering"), + ("mvp", "MvpForQuestionAnswering"), + ("nezha", "NezhaForQuestionAnswering"), + ("nystromformer", "NystromformerForQuestionAnswering"), + ("opt", "OPTForQuestionAnswering"), + ("qdqbert", "QDQBertForQuestionAnswering"), + ("reformer", "ReformerForQuestionAnswering"), + ("rembert", "RemBertForQuestionAnswering"), + ("roberta", "RobertaForQuestionAnswering"), + ("roberta-prelayernorm", "RobertaPreLayerNormForQuestionAnswering"), + ("roc_bert", "RoCBertForQuestionAnswering"), + ("roformer", "RoFormerForQuestionAnswering"), + ("splinter", "SplinterForQuestionAnswering"), + ("squeezebert", "SqueezeBertForQuestionAnswering"), + ("xlm", "XLMForQuestionAnsweringSimple"), + ("xlm-roberta", "XLMRobertaForQuestionAnswering"), + ("xlm-roberta-xl", "XLMRobertaXLForQuestionAnswering"), + ("xlnet", "XLNetForQuestionAnsweringSimple"), + ("xmod", "XmodForQuestionAnswering"), + ("yoso", "YosoForQuestionAnswering"), + ] +) + +MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + # Model for Table Question Answering mapping + ("tapas", "TapasForQuestionAnswering"), + ] +) + +MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + ("vilt", "ViltForQuestionAnswering"), + ] +) + +MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + ("layoutlm", "LayoutLMForQuestionAnswering"), + ("layoutlmv2", "LayoutLMv2ForQuestionAnswering"), + ("layoutlmv3", "LayoutLMv3ForQuestionAnswering"), + ] +) + +MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Token Classification mapping + ("albert", "AlbertForTokenClassification"), + ("bert", "BertForTokenClassification"), + ("big_bird", "BigBirdForTokenClassification"), + ("biogpt", "BioGptForTokenClassification"), + ("bloom", "BloomForTokenClassification"), + ("camembert", "CamembertForTokenClassification"), + ("canine", "CanineForTokenClassification"), + ("convbert", "ConvBertForTokenClassification"), + ("data2vec-text", "Data2VecTextForTokenClassification"), + ("deberta", "DebertaForTokenClassification"), + ("deberta-v2", "DebertaV2ForTokenClassification"), + ("distilbert", "DistilBertForTokenClassification"), + ("electra", "ElectraForTokenClassification"), + ("ernie", "ErnieForTokenClassification"), + ("ernie_m", "ErnieMForTokenClassification"), + ("esm", "EsmForTokenClassification"), + ("flaubert", "FlaubertForTokenClassification"), + ("fnet", "FNetForTokenClassification"), + ("funnel", "FunnelForTokenClassification"), + ("gpt-sw3", "GPT2ForTokenClassification"), + ("gpt2", "GPT2ForTokenClassification"), + ("gpt_bigcode", "GPTBigCodeForTokenClassification"), + ("gpt_neo", "GPTNeoForTokenClassification"), + ("gpt_neox", "GPTNeoXForTokenClassification"), + ("ibert", "IBertForTokenClassification"), + ("layoutlm", "LayoutLMForTokenClassification"), + ("layoutlmv2", "LayoutLMv2ForTokenClassification"), + ("layoutlmv3", "LayoutLMv3ForTokenClassification"), + ("lilt", "LiltForTokenClassification"), + ("longformer", "LongformerForTokenClassification"), + ("luke", "LukeForTokenClassification"), + ("markuplm", "MarkupLMForTokenClassification"), + ("mega", "MegaForTokenClassification"), + ("megatron-bert", "MegatronBertForTokenClassification"), + ("mobilebert", "MobileBertForTokenClassification"), + ("mpnet", "MPNetForTokenClassification"), + ("nezha", "NezhaForTokenClassification"), + ("nystromformer", "NystromformerForTokenClassification"), + ("qdqbert", "QDQBertForTokenClassification"), + ("rembert", "RemBertForTokenClassification"), + ("roberta", "RobertaForTokenClassification"), + ("roberta-prelayernorm", "RobertaPreLayerNormForTokenClassification"), + ("roc_bert", "RoCBertForTokenClassification"), + ("roformer", "RoFormerForTokenClassification"), + ("squeezebert", "SqueezeBertForTokenClassification"), + ("xlm", "XLMForTokenClassification"), + ("xlm-roberta", "XLMRobertaForTokenClassification"), + ("xlm-roberta-xl", "XLMRobertaXLForTokenClassification"), + ("xlnet", "XLNetForTokenClassification"), + ("xmod", "XmodForTokenClassification"), + ("yoso", "YosoForTokenClassification"), + ] +) + +MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES = OrderedDict( + [ + # Model for Multiple Choice mapping + ("albert", "AlbertForMultipleChoice"), + ("bert", "BertForMultipleChoice"), + ("big_bird", "BigBirdForMultipleChoice"), + ("camembert", "CamembertForMultipleChoice"), + ("canine", "CanineForMultipleChoice"), + ("convbert", "ConvBertForMultipleChoice"), + ("data2vec-text", "Data2VecTextForMultipleChoice"), + ("deberta-v2", "DebertaV2ForMultipleChoice"), + ("distilbert", "DistilBertForMultipleChoice"), + ("electra", "ElectraForMultipleChoice"), + ("ernie", "ErnieForMultipleChoice"), + ("ernie_m", "ErnieMForMultipleChoice"), + ("flaubert", "FlaubertForMultipleChoice"), + ("fnet", "FNetForMultipleChoice"), + ("funnel", "FunnelForMultipleChoice"), + ("ibert", "IBertForMultipleChoice"), + ("longformer", "LongformerForMultipleChoice"), + ("luke", "LukeForMultipleChoice"), + ("mega", "MegaForMultipleChoice"), + ("megatron-bert", "MegatronBertForMultipleChoice"), + ("mobilebert", "MobileBertForMultipleChoice"), + ("mpnet", "MPNetForMultipleChoice"), + ("nezha", "NezhaForMultipleChoice"), + ("nystromformer", "NystromformerForMultipleChoice"), + ("qdqbert", "QDQBertForMultipleChoice"), + ("rembert", "RemBertForMultipleChoice"), + ("roberta", "RobertaForMultipleChoice"), + ("roberta-prelayernorm", "RobertaPreLayerNormForMultipleChoice"), + ("roc_bert", "RoCBertForMultipleChoice"), + ("roformer", "RoFormerForMultipleChoice"), + ("squeezebert", "SqueezeBertForMultipleChoice"), + ("xlm", "XLMForMultipleChoice"), + ("xlm-roberta", "XLMRobertaForMultipleChoice"), + ("xlm-roberta-xl", "XLMRobertaXLForMultipleChoice"), + ("xlnet", "XLNetForMultipleChoice"), + ("xmod", "XmodForMultipleChoice"), + ("yoso", "YosoForMultipleChoice"), + ] +) + +MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES = OrderedDict( + [ + ("bert", "BertForNextSentencePrediction"), + ("ernie", "ErnieForNextSentencePrediction"), + ("fnet", "FNetForNextSentencePrediction"), + ("megatron-bert", "MegatronBertForNextSentencePrediction"), + ("mobilebert", "MobileBertForNextSentencePrediction"), + ("nezha", "NezhaForNextSentencePrediction"), + ("qdqbert", "QDQBertForNextSentencePrediction"), + ] +) + +MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Audio Classification mapping + ("audio-spectrogram-transformer", "ASTForAudioClassification"), + ("data2vec-audio", "Data2VecAudioForSequenceClassification"), + ("hubert", "HubertForSequenceClassification"), + ("sew", "SEWForSequenceClassification"), + ("sew-d", "SEWDForSequenceClassification"), + ("unispeech", "UniSpeechForSequenceClassification"), + ("unispeech-sat", "UniSpeechSatForSequenceClassification"), + ("wav2vec2", "Wav2Vec2ForSequenceClassification"), + ("wav2vec2-conformer", "Wav2Vec2ConformerForSequenceClassification"), + ("wavlm", "WavLMForSequenceClassification"), + ("whisper", "WhisperForAudioClassification"), + ] +) + +MODEL_FOR_CTC_MAPPING_NAMES = OrderedDict( + [ + # Model for Connectionist temporal classification (CTC) mapping + ("data2vec-audio", "Data2VecAudioForCTC"), + ("hubert", "HubertForCTC"), + ("mctct", "MCTCTForCTC"), + ("sew", "SEWForCTC"), + ("sew-d", "SEWDForCTC"), + ("unispeech", "UniSpeechForCTC"), + ("unispeech-sat", "UniSpeechSatForCTC"), + ("wav2vec2", "Wav2Vec2ForCTC"), + ("wav2vec2-conformer", "Wav2Vec2ConformerForCTC"), + ("wavlm", "WavLMForCTC"), + ] +) + +MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Audio Classification mapping + ("data2vec-audio", "Data2VecAudioForAudioFrameClassification"), + ("unispeech-sat", "UniSpeechSatForAudioFrameClassification"), + ("wav2vec2", "Wav2Vec2ForAudioFrameClassification"), + ("wav2vec2-conformer", "Wav2Vec2ConformerForAudioFrameClassification"), + ("wavlm", "WavLMForAudioFrameClassification"), + ] +) + +MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES = OrderedDict( + [ + # Model for Audio Classification mapping + ("data2vec-audio", "Data2VecAudioForXVector"), + ("unispeech-sat", "UniSpeechSatForXVector"), + ("wav2vec2", "Wav2Vec2ForXVector"), + ("wav2vec2-conformer", "Wav2Vec2ConformerForXVector"), + ("wavlm", "WavLMForXVector"), + ] +) + +MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Zero Shot Image Classification mapping + ("align", "AlignModel"), + ("altclip", "AltCLIPModel"), + ("blip", "BlipModel"), + ("chinese_clip", "ChineseCLIPModel"), + ("clip", "CLIPModel"), + ("clipseg", "CLIPSegModel"), + ] +) + +MODEL_FOR_BACKBONE_MAPPING_NAMES = OrderedDict( + [ + # Backbone mapping + ("bit", "BitBackbone"), + ("convnext", "ConvNextBackbone"), + ("convnextv2", "ConvNextV2Backbone"), + ("dinat", "DinatBackbone"), + ("focalnet", "FocalNetBackbone"), + ("maskformer-swin", "MaskFormerSwinBackbone"), + ("nat", "NatBackbone"), + ("resnet", "ResNetBackbone"), + ("swin", "SwinBackbone"), + ] +) + +MODEL_FOR_MASK_GENERATION_MAPPING_NAMES = OrderedDict( + [ + ("sam", "SamModel"), + ] +) + +MODEL_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_MAPPING_NAMES) +MODEL_FOR_PRETRAINING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_PRETRAINING_MAPPING_NAMES) +MODEL_WITH_LM_HEAD_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_WITH_LM_HEAD_MAPPING_NAMES) +MODEL_FOR_CAUSAL_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) +MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES +) +MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_IMAGE_SEGMENTATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_IMAGE_SEGMENTATION_MAPPING_NAMES +) +MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES +) +MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING_NAMES +) +MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING_NAMES +) +MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_VISION_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) +MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING_NAMES +) +MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES +) +MODEL_FOR_MASKED_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_MASKED_LM_MAPPING_NAMES) +MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES +) +MODEL_FOR_OBJECT_DETECTION_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_OBJECT_DETECTION_MAPPING_NAMES) +MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING_NAMES +) +MODEL_FOR_DEPTH_ESTIMATION_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES) +MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES +) +MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES +) +MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES +) +MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_MULTIPLE_CHOICE_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES) +MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES +) +MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_CTC_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_CTC_MAPPING_NAMES) +MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES) +MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING_NAMES +) +MODEL_FOR_AUDIO_XVECTOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES) + +MODEL_FOR_BACKBONE_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_BACKBONE_MAPPING_NAMES) + +MODEL_FOR_MASK_GENERATION_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, MODEL_FOR_MASK_GENERATION_MAPPING_NAMES) + + +class AutoModelForMaskGeneration(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_MASK_GENERATION_MAPPING + + +class AutoModel(_BaseAutoModelClass): + _model_mapping = MODEL_MAPPING + + +AutoModel = auto_class_update(AutoModel) + + +class AutoModelForPreTraining(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_PRETRAINING_MAPPING + + +AutoModelForPreTraining = auto_class_update(AutoModelForPreTraining, head_doc="pretraining") + + +# Private on purpose, the public class will add the deprecation warnings. +class _AutoModelWithLMHead(_BaseAutoModelClass): + _model_mapping = MODEL_WITH_LM_HEAD_MAPPING + + +_AutoModelWithLMHead = auto_class_update(_AutoModelWithLMHead, head_doc="language modeling") + + +class AutoModelForCausalLM(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_CAUSAL_LM_MAPPING + + +AutoModelForCausalLM = auto_class_update(AutoModelForCausalLM, head_doc="causal language modeling") + + +class AutoModelForMaskedLM(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_MASKED_LM_MAPPING + + +AutoModelForMaskedLM = auto_class_update(AutoModelForMaskedLM, head_doc="masked language modeling") + + +class AutoModelForSeq2SeqLM(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + + +AutoModelForSeq2SeqLM = auto_class_update( + AutoModelForSeq2SeqLM, head_doc="sequence-to-sequence language modeling", checkpoint_for_example="t5-base" +) + + +class AutoModelForSequenceClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + + +AutoModelForSequenceClassification = auto_class_update( + AutoModelForSequenceClassification, head_doc="sequence classification" +) + + +class AutoModelForQuestionAnswering(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_QUESTION_ANSWERING_MAPPING + + +AutoModelForQuestionAnswering = auto_class_update(AutoModelForQuestionAnswering, head_doc="question answering") + + +class AutoModelForTableQuestionAnswering(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING + + +AutoModelForTableQuestionAnswering = auto_class_update( + AutoModelForTableQuestionAnswering, + head_doc="table question answering", + checkpoint_for_example="google/tapas-base-finetuned-wtq", +) + + +class AutoModelForVisualQuestionAnswering(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING + + +AutoModelForVisualQuestionAnswering = auto_class_update( + AutoModelForVisualQuestionAnswering, + head_doc="visual question answering", + checkpoint_for_example="dandelin/vilt-b32-finetuned-vqa", +) + + +class AutoModelForDocumentQuestionAnswering(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING + + +AutoModelForDocumentQuestionAnswering = auto_class_update( + AutoModelForDocumentQuestionAnswering, + head_doc="document question answering", + checkpoint_for_example='impira/layoutlm-document-qa", revision="52e01b3', +) + + +class AutoModelForTokenClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + + +AutoModelForTokenClassification = auto_class_update(AutoModelForTokenClassification, head_doc="token classification") + + +class AutoModelForMultipleChoice(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_MULTIPLE_CHOICE_MAPPING + + +AutoModelForMultipleChoice = auto_class_update(AutoModelForMultipleChoice, head_doc="multiple choice") + + +class AutoModelForNextSentencePrediction(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING + + +AutoModelForNextSentencePrediction = auto_class_update( + AutoModelForNextSentencePrediction, head_doc="next sentence prediction" +) + + +class AutoModelForImageClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + + +AutoModelForImageClassification = auto_class_update(AutoModelForImageClassification, head_doc="image classification") + + +class AutoModelForZeroShotImageClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + + +AutoModelForZeroShotImageClassification = auto_class_update( + AutoModelForZeroShotImageClassification, head_doc="zero-shot image classification" +) + + +class AutoModelForImageSegmentation(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_IMAGE_SEGMENTATION_MAPPING + + +AutoModelForImageSegmentation = auto_class_update(AutoModelForImageSegmentation, head_doc="image segmentation") + + +class AutoModelForSemanticSegmentation(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING + + +AutoModelForSemanticSegmentation = auto_class_update( + AutoModelForSemanticSegmentation, head_doc="semantic segmentation" +) + + +class AutoModelForUniversalSegmentation(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING + + +AutoModelForUniversalSegmentation = auto_class_update( + AutoModelForUniversalSegmentation, head_doc="universal image segmentation" +) + + +class AutoModelForInstanceSegmentation(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING + + +AutoModelForInstanceSegmentation = auto_class_update( + AutoModelForInstanceSegmentation, head_doc="instance segmentation" +) + + +class AutoModelForObjectDetection(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_OBJECT_DETECTION_MAPPING + + +AutoModelForObjectDetection = auto_class_update(AutoModelForObjectDetection, head_doc="object detection") + + +class AutoModelForZeroShotObjectDetection(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING + + +AutoModelForZeroShotObjectDetection = auto_class_update( + AutoModelForZeroShotObjectDetection, head_doc="zero-shot object detection" +) + + +class AutoModelForDepthEstimation(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_DEPTH_ESTIMATION_MAPPING + + +AutoModelForDepthEstimation = auto_class_update(AutoModelForDepthEstimation, head_doc="depth estimation") + + +class AutoModelForVideoClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING + + +AutoModelForVideoClassification = auto_class_update(AutoModelForVideoClassification, head_doc="video classification") + + +class AutoModelForVision2Seq(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_VISION_2_SEQ_MAPPING + + +AutoModelForVision2Seq = auto_class_update(AutoModelForVision2Seq, head_doc="vision-to-text modeling") + + +class AutoModelForAudioClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING + + +AutoModelForAudioClassification = auto_class_update(AutoModelForAudioClassification, head_doc="audio classification") + + +class AutoModelForCTC(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_CTC_MAPPING + + +AutoModelForCTC = auto_class_update(AutoModelForCTC, head_doc="connectionist temporal classification") + + +class AutoModelForSpeechSeq2Seq(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING + + +AutoModelForSpeechSeq2Seq = auto_class_update( + AutoModelForSpeechSeq2Seq, head_doc="sequence-to-sequence speech-to-text modeling" +) + + +class AutoModelForAudioFrameClassification(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_AUDIO_FRAME_CLASSIFICATION_MAPPING + + +AutoModelForAudioFrameClassification = auto_class_update( + AutoModelForAudioFrameClassification, head_doc="audio frame (token) classification" +) + + +class AutoModelForAudioXVector(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_AUDIO_XVECTOR_MAPPING + + +class AutoBackbone(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_BACKBONE_MAPPING + + +AutoModelForAudioXVector = auto_class_update(AutoModelForAudioXVector, head_doc="audio retrieval via x-vector") + + +class AutoModelForMaskedImageModeling(_BaseAutoModelClass): + _model_mapping = MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING + + +AutoModelForMaskedImageModeling = auto_class_update(AutoModelForMaskedImageModeling, head_doc="masked image modeling") + + +class AutoModelWithLMHead(_AutoModelWithLMHead): + @classmethod + def from_config(cls, config): + warnings.warn( + "The class `AutoModelWithLMHead` is deprecated and will be removed in a future version. Please use " + "`AutoModelForCausalLM` for causal language models, `AutoModelForMaskedLM` for masked language models and " + "`AutoModelForSeq2SeqLM` for encoder-decoder models.", + FutureWarning, + ) + return super().from_config(config) + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): + warnings.warn( + "The class `AutoModelWithLMHead` is deprecated and will be removed in a future version. Please use " + "`AutoModelForCausalLM` for causal language models, `AutoModelForMaskedLM` for masked language models and " + "`AutoModelForSeq2SeqLM` for encoder-decoder models.", + FutureWarning, + ) + return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_flax_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_flax_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..e3b8d9cf5b52376c44d94ea8fd78cd7199e2ea77 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_flax_auto.py @@ -0,0 +1,369 @@ +# coding=utf-8 +# Copyright 2018 The Google Flax Team Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Auto Model class.""" + + +from collections import OrderedDict + +from ...utils import logging +from .auto_factory import _BaseAutoModelClass, _LazyAutoMapping, auto_class_update +from .configuration_auto import CONFIG_MAPPING_NAMES + + +logger = logging.get_logger(__name__) + + +FLAX_MODEL_MAPPING_NAMES = OrderedDict( + [ + # Base model mapping + ("albert", "FlaxAlbertModel"), + ("bart", "FlaxBartModel"), + ("beit", "FlaxBeitModel"), + ("bert", "FlaxBertModel"), + ("big_bird", "FlaxBigBirdModel"), + ("blenderbot", "FlaxBlenderbotModel"), + ("blenderbot-small", "FlaxBlenderbotSmallModel"), + ("clip", "FlaxCLIPModel"), + ("distilbert", "FlaxDistilBertModel"), + ("electra", "FlaxElectraModel"), + ("gpt-sw3", "FlaxGPT2Model"), + ("gpt2", "FlaxGPT2Model"), + ("gpt_neo", "FlaxGPTNeoModel"), + ("gptj", "FlaxGPTJModel"), + ("longt5", "FlaxLongT5Model"), + ("marian", "FlaxMarianModel"), + ("mbart", "FlaxMBartModel"), + ("mt5", "FlaxMT5Model"), + ("opt", "FlaxOPTModel"), + ("pegasus", "FlaxPegasusModel"), + ("regnet", "FlaxRegNetModel"), + ("resnet", "FlaxResNetModel"), + ("roberta", "FlaxRobertaModel"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormModel"), + ("roformer", "FlaxRoFormerModel"), + ("t5", "FlaxT5Model"), + ("vision-text-dual-encoder", "FlaxVisionTextDualEncoderModel"), + ("vit", "FlaxViTModel"), + ("wav2vec2", "FlaxWav2Vec2Model"), + ("whisper", "FlaxWhisperModel"), + ("xglm", "FlaxXGLMModel"), + ("xlm-roberta", "FlaxXLMRobertaModel"), + ] +) + +FLAX_MODEL_FOR_PRETRAINING_MAPPING_NAMES = OrderedDict( + [ + # Model for pre-training mapping + ("albert", "FlaxAlbertForPreTraining"), + ("bart", "FlaxBartForConditionalGeneration"), + ("bert", "FlaxBertForPreTraining"), + ("big_bird", "FlaxBigBirdForPreTraining"), + ("electra", "FlaxElectraForPreTraining"), + ("longt5", "FlaxLongT5ForConditionalGeneration"), + ("mbart", "FlaxMBartForConditionalGeneration"), + ("mt5", "FlaxMT5ForConditionalGeneration"), + ("roberta", "FlaxRobertaForMaskedLM"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMaskedLM"), + ("roformer", "FlaxRoFormerForMaskedLM"), + ("t5", "FlaxT5ForConditionalGeneration"), + ("wav2vec2", "FlaxWav2Vec2ForPreTraining"), + ("whisper", "FlaxWhisperForConditionalGeneration"), + ("xlm-roberta", "FlaxXLMRobertaForMaskedLM"), + ] +) + +FLAX_MODEL_FOR_MASKED_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Masked LM mapping + ("albert", "FlaxAlbertForMaskedLM"), + ("bart", "FlaxBartForConditionalGeneration"), + ("bert", "FlaxBertForMaskedLM"), + ("big_bird", "FlaxBigBirdForMaskedLM"), + ("distilbert", "FlaxDistilBertForMaskedLM"), + ("electra", "FlaxElectraForMaskedLM"), + ("mbart", "FlaxMBartForConditionalGeneration"), + ("roberta", "FlaxRobertaForMaskedLM"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMaskedLM"), + ("roformer", "FlaxRoFormerForMaskedLM"), + ("xlm-roberta", "FlaxXLMRobertaForMaskedLM"), + ] +) + +FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Seq2Seq Causal LM mapping + ("bart", "FlaxBartForConditionalGeneration"), + ("blenderbot", "FlaxBlenderbotForConditionalGeneration"), + ("blenderbot-small", "FlaxBlenderbotSmallForConditionalGeneration"), + ("encoder-decoder", "FlaxEncoderDecoderModel"), + ("longt5", "FlaxLongT5ForConditionalGeneration"), + ("marian", "FlaxMarianMTModel"), + ("mbart", "FlaxMBartForConditionalGeneration"), + ("mt5", "FlaxMT5ForConditionalGeneration"), + ("pegasus", "FlaxPegasusForConditionalGeneration"), + ("t5", "FlaxT5ForConditionalGeneration"), + ] +) + +FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Image-classsification + ("beit", "FlaxBeitForImageClassification"), + ("regnet", "FlaxRegNetForImageClassification"), + ("resnet", "FlaxResNetForImageClassification"), + ("vit", "FlaxViTForImageClassification"), + ] +) + +FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("vision-encoder-decoder", "FlaxVisionEncoderDecoderModel"), + ] +) + +FLAX_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Causal LM mapping + ("bart", "FlaxBartForCausalLM"), + ("bert", "FlaxBertForCausalLM"), + ("big_bird", "FlaxBigBirdForCausalLM"), + ("electra", "FlaxElectraForCausalLM"), + ("gpt-sw3", "FlaxGPT2LMHeadModel"), + ("gpt2", "FlaxGPT2LMHeadModel"), + ("gpt_neo", "FlaxGPTNeoForCausalLM"), + ("gptj", "FlaxGPTJForCausalLM"), + ("opt", "FlaxOPTForCausalLM"), + ("roberta", "FlaxRobertaForCausalLM"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForCausalLM"), + ("xglm", "FlaxXGLMForCausalLM"), + ("xlm-roberta", "FlaxXLMRobertaForCausalLM"), + ] +) + +FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Sequence Classification mapping + ("albert", "FlaxAlbertForSequenceClassification"), + ("bart", "FlaxBartForSequenceClassification"), + ("bert", "FlaxBertForSequenceClassification"), + ("big_bird", "FlaxBigBirdForSequenceClassification"), + ("distilbert", "FlaxDistilBertForSequenceClassification"), + ("electra", "FlaxElectraForSequenceClassification"), + ("mbart", "FlaxMBartForSequenceClassification"), + ("roberta", "FlaxRobertaForSequenceClassification"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForSequenceClassification"), + ("roformer", "FlaxRoFormerForSequenceClassification"), + ("xlm-roberta", "FlaxXLMRobertaForSequenceClassification"), + ] +) + +FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + # Model for Question Answering mapping + ("albert", "FlaxAlbertForQuestionAnswering"), + ("bart", "FlaxBartForQuestionAnswering"), + ("bert", "FlaxBertForQuestionAnswering"), + ("big_bird", "FlaxBigBirdForQuestionAnswering"), + ("distilbert", "FlaxDistilBertForQuestionAnswering"), + ("electra", "FlaxElectraForQuestionAnswering"), + ("mbart", "FlaxMBartForQuestionAnswering"), + ("roberta", "FlaxRobertaForQuestionAnswering"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForQuestionAnswering"), + ("roformer", "FlaxRoFormerForQuestionAnswering"), + ("xlm-roberta", "FlaxXLMRobertaForQuestionAnswering"), + ] +) + +FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Token Classification mapping + ("albert", "FlaxAlbertForTokenClassification"), + ("bert", "FlaxBertForTokenClassification"), + ("big_bird", "FlaxBigBirdForTokenClassification"), + ("distilbert", "FlaxDistilBertForTokenClassification"), + ("electra", "FlaxElectraForTokenClassification"), + ("roberta", "FlaxRobertaForTokenClassification"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForTokenClassification"), + ("roformer", "FlaxRoFormerForTokenClassification"), + ("xlm-roberta", "FlaxXLMRobertaForTokenClassification"), + ] +) + +FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES = OrderedDict( + [ + # Model for Multiple Choice mapping + ("albert", "FlaxAlbertForMultipleChoice"), + ("bert", "FlaxBertForMultipleChoice"), + ("big_bird", "FlaxBigBirdForMultipleChoice"), + ("distilbert", "FlaxDistilBertForMultipleChoice"), + ("electra", "FlaxElectraForMultipleChoice"), + ("roberta", "FlaxRobertaForMultipleChoice"), + ("roberta-prelayernorm", "FlaxRobertaPreLayerNormForMultipleChoice"), + ("roformer", "FlaxRoFormerForMultipleChoice"), + ("xlm-roberta", "FlaxXLMRobertaForMultipleChoice"), + ] +) + +FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES = OrderedDict( + [ + ("bert", "FlaxBertForNextSentencePrediction"), + ] +) + +FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("speech-encoder-decoder", "FlaxSpeechEncoderDecoderModel"), + ("whisper", "FlaxWhisperForConditionalGeneration"), + ] +) + +FLAX_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + ("whisper", "FlaxWhisperForAudioClassification"), + ] +) + +FLAX_MODEL_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_MAPPING_NAMES) +FLAX_MODEL_FOR_PRETRAINING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_PRETRAINING_MAPPING_NAMES) +FLAX_MODEL_FOR_MASKED_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_MASKED_LM_MAPPING_NAMES) +FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES +) +FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES +) +FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) +FLAX_MODEL_FOR_CAUSAL_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) +FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES +) +FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES +) +FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES +) +FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES +) +FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES +) +FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES +) + + +class FlaxAutoModel(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_MAPPING + + +FlaxAutoModel = auto_class_update(FlaxAutoModel) + + +class FlaxAutoModelForPreTraining(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_PRETRAINING_MAPPING + + +FlaxAutoModelForPreTraining = auto_class_update(FlaxAutoModelForPreTraining, head_doc="pretraining") + + +class FlaxAutoModelForCausalLM(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_CAUSAL_LM_MAPPING + + +FlaxAutoModelForCausalLM = auto_class_update(FlaxAutoModelForCausalLM, head_doc="causal language modeling") + + +class FlaxAutoModelForMaskedLM(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_MASKED_LM_MAPPING + + +FlaxAutoModelForMaskedLM = auto_class_update(FlaxAutoModelForMaskedLM, head_doc="masked language modeling") + + +class FlaxAutoModelForSeq2SeqLM(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + + +FlaxAutoModelForSeq2SeqLM = auto_class_update( + FlaxAutoModelForSeq2SeqLM, head_doc="sequence-to-sequence language modeling", checkpoint_for_example="t5-base" +) + + +class FlaxAutoModelForSequenceClassification(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + + +FlaxAutoModelForSequenceClassification = auto_class_update( + FlaxAutoModelForSequenceClassification, head_doc="sequence classification" +) + + +class FlaxAutoModelForQuestionAnswering(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING + + +FlaxAutoModelForQuestionAnswering = auto_class_update(FlaxAutoModelForQuestionAnswering, head_doc="question answering") + + +class FlaxAutoModelForTokenClassification(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + + +FlaxAutoModelForTokenClassification = auto_class_update( + FlaxAutoModelForTokenClassification, head_doc="token classification" +) + + +class FlaxAutoModelForMultipleChoice(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING + + +FlaxAutoModelForMultipleChoice = auto_class_update(FlaxAutoModelForMultipleChoice, head_doc="multiple choice") + + +class FlaxAutoModelForNextSentencePrediction(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING + + +FlaxAutoModelForNextSentencePrediction = auto_class_update( + FlaxAutoModelForNextSentencePrediction, head_doc="next sentence prediction" +) + + +class FlaxAutoModelForImageClassification(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + + +FlaxAutoModelForImageClassification = auto_class_update( + FlaxAutoModelForImageClassification, head_doc="image classification" +) + + +class FlaxAutoModelForVision2Seq(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING + + +FlaxAutoModelForVision2Seq = auto_class_update(FlaxAutoModelForVision2Seq, head_doc="vision-to-text modeling") + + +class FlaxAutoModelForSpeechSeq2Seq(_BaseAutoModelClass): + _model_mapping = FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING + + +FlaxAutoModelForSpeechSeq2Seq = auto_class_update( + FlaxAutoModelForSpeechSeq2Seq, head_doc="sequence-to-sequence speech-to-text modeling" +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_tf_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_tf_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..5d637271f98d69af787f965aef0ac4cb38f98f9a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/modeling_tf_auto.py @@ -0,0 +1,668 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Auto Model class.""" + + +import warnings +from collections import OrderedDict + +from ...utils import logging +from .auto_factory import _BaseAutoModelClass, _LazyAutoMapping, auto_class_update +from .configuration_auto import CONFIG_MAPPING_NAMES + + +logger = logging.get_logger(__name__) + + +TF_MODEL_MAPPING_NAMES = OrderedDict( + [ + # Base model mapping + ("albert", "TFAlbertModel"), + ("bart", "TFBartModel"), + ("bert", "TFBertModel"), + ("blenderbot", "TFBlenderbotModel"), + ("blenderbot-small", "TFBlenderbotSmallModel"), + ("blip", "TFBlipModel"), + ("camembert", "TFCamembertModel"), + ("clip", "TFCLIPModel"), + ("convbert", "TFConvBertModel"), + ("convnext", "TFConvNextModel"), + ("ctrl", "TFCTRLModel"), + ("cvt", "TFCvtModel"), + ("data2vec-vision", "TFData2VecVisionModel"), + ("deberta", "TFDebertaModel"), + ("deberta-v2", "TFDebertaV2Model"), + ("deit", "TFDeiTModel"), + ("distilbert", "TFDistilBertModel"), + ("dpr", "TFDPRQuestionEncoder"), + ("electra", "TFElectraModel"), + ("esm", "TFEsmModel"), + ("flaubert", "TFFlaubertModel"), + ("funnel", ("TFFunnelModel", "TFFunnelBaseModel")), + ("gpt-sw3", "TFGPT2Model"), + ("gpt2", "TFGPT2Model"), + ("gptj", "TFGPTJModel"), + ("groupvit", "TFGroupViTModel"), + ("hubert", "TFHubertModel"), + ("layoutlm", "TFLayoutLMModel"), + ("layoutlmv3", "TFLayoutLMv3Model"), + ("led", "TFLEDModel"), + ("longformer", "TFLongformerModel"), + ("lxmert", "TFLxmertModel"), + ("marian", "TFMarianModel"), + ("mbart", "TFMBartModel"), + ("mobilebert", "TFMobileBertModel"), + ("mobilevit", "TFMobileViTModel"), + ("mpnet", "TFMPNetModel"), + ("mt5", "TFMT5Model"), + ("openai-gpt", "TFOpenAIGPTModel"), + ("opt", "TFOPTModel"), + ("pegasus", "TFPegasusModel"), + ("regnet", "TFRegNetModel"), + ("rembert", "TFRemBertModel"), + ("resnet", "TFResNetModel"), + ("roberta", "TFRobertaModel"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormModel"), + ("roformer", "TFRoFormerModel"), + ("segformer", "TFSegformerModel"), + ("speech_to_text", "TFSpeech2TextModel"), + ("swin", "TFSwinModel"), + ("t5", "TFT5Model"), + ("tapas", "TFTapasModel"), + ("transfo-xl", "TFTransfoXLModel"), + ("vision-text-dual-encoder", "TFVisionTextDualEncoderModel"), + ("vit", "TFViTModel"), + ("vit_mae", "TFViTMAEModel"), + ("wav2vec2", "TFWav2Vec2Model"), + ("whisper", "TFWhisperModel"), + ("xglm", "TFXGLMModel"), + ("xlm", "TFXLMModel"), + ("xlm-roberta", "TFXLMRobertaModel"), + ("xlnet", "TFXLNetModel"), + ] +) + +TF_MODEL_FOR_PRETRAINING_MAPPING_NAMES = OrderedDict( + [ + # Model for pre-training mapping + ("albert", "TFAlbertForPreTraining"), + ("bart", "TFBartForConditionalGeneration"), + ("bert", "TFBertForPreTraining"), + ("camembert", "TFCamembertForMaskedLM"), + ("ctrl", "TFCTRLLMHeadModel"), + ("distilbert", "TFDistilBertForMaskedLM"), + ("electra", "TFElectraForPreTraining"), + ("flaubert", "TFFlaubertWithLMHeadModel"), + ("funnel", "TFFunnelForPreTraining"), + ("gpt-sw3", "TFGPT2LMHeadModel"), + ("gpt2", "TFGPT2LMHeadModel"), + ("layoutlm", "TFLayoutLMForMaskedLM"), + ("lxmert", "TFLxmertForPreTraining"), + ("mobilebert", "TFMobileBertForPreTraining"), + ("mpnet", "TFMPNetForMaskedLM"), + ("openai-gpt", "TFOpenAIGPTLMHeadModel"), + ("roberta", "TFRobertaForMaskedLM"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), + ("t5", "TFT5ForConditionalGeneration"), + ("tapas", "TFTapasForMaskedLM"), + ("transfo-xl", "TFTransfoXLLMHeadModel"), + ("vit_mae", "TFViTMAEForPreTraining"), + ("xlm", "TFXLMWithLMHeadModel"), + ("xlm-roberta", "TFXLMRobertaForMaskedLM"), + ("xlnet", "TFXLNetLMHeadModel"), + ] +) + +TF_MODEL_WITH_LM_HEAD_MAPPING_NAMES = OrderedDict( + [ + # Model with LM heads mapping + ("albert", "TFAlbertForMaskedLM"), + ("bart", "TFBartForConditionalGeneration"), + ("bert", "TFBertForMaskedLM"), + ("camembert", "TFCamembertForMaskedLM"), + ("convbert", "TFConvBertForMaskedLM"), + ("ctrl", "TFCTRLLMHeadModel"), + ("distilbert", "TFDistilBertForMaskedLM"), + ("electra", "TFElectraForMaskedLM"), + ("esm", "TFEsmForMaskedLM"), + ("flaubert", "TFFlaubertWithLMHeadModel"), + ("funnel", "TFFunnelForMaskedLM"), + ("gpt-sw3", "TFGPT2LMHeadModel"), + ("gpt2", "TFGPT2LMHeadModel"), + ("gptj", "TFGPTJForCausalLM"), + ("layoutlm", "TFLayoutLMForMaskedLM"), + ("led", "TFLEDForConditionalGeneration"), + ("longformer", "TFLongformerForMaskedLM"), + ("marian", "TFMarianMTModel"), + ("mobilebert", "TFMobileBertForMaskedLM"), + ("mpnet", "TFMPNetForMaskedLM"), + ("openai-gpt", "TFOpenAIGPTLMHeadModel"), + ("rembert", "TFRemBertForMaskedLM"), + ("roberta", "TFRobertaForMaskedLM"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), + ("roformer", "TFRoFormerForMaskedLM"), + ("speech_to_text", "TFSpeech2TextForConditionalGeneration"), + ("t5", "TFT5ForConditionalGeneration"), + ("tapas", "TFTapasForMaskedLM"), + ("transfo-xl", "TFTransfoXLLMHeadModel"), + ("whisper", "TFWhisperForConditionalGeneration"), + ("xlm", "TFXLMWithLMHeadModel"), + ("xlm-roberta", "TFXLMRobertaForMaskedLM"), + ("xlnet", "TFXLNetLMHeadModel"), + ] +) + +TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Causal LM mapping + ("bert", "TFBertLMHeadModel"), + ("camembert", "TFCamembertForCausalLM"), + ("ctrl", "TFCTRLLMHeadModel"), + ("gpt-sw3", "TFGPT2LMHeadModel"), + ("gpt2", "TFGPT2LMHeadModel"), + ("gptj", "TFGPTJForCausalLM"), + ("openai-gpt", "TFOpenAIGPTLMHeadModel"), + ("opt", "TFOPTForCausalLM"), + ("rembert", "TFRemBertForCausalLM"), + ("roberta", "TFRobertaForCausalLM"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForCausalLM"), + ("roformer", "TFRoFormerForCausalLM"), + ("transfo-xl", "TFTransfoXLLMHeadModel"), + ("xglm", "TFXGLMForCausalLM"), + ("xlm", "TFXLMWithLMHeadModel"), + ("xlm-roberta", "TFXLMRobertaForCausalLM"), + ("xlnet", "TFXLNetLMHeadModel"), + ] +) + +TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES = OrderedDict( + [ + ("deit", "TFDeiTForMaskedImageModeling"), + ("swin", "TFSwinForMaskedImageModeling"), + ] +) + +TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Image-classsification + ("convnext", "TFConvNextForImageClassification"), + ("cvt", "TFCvtForImageClassification"), + ("data2vec-vision", "TFData2VecVisionForImageClassification"), + ("deit", ("TFDeiTForImageClassification", "TFDeiTForImageClassificationWithTeacher")), + ("mobilevit", "TFMobileViTForImageClassification"), + ("regnet", "TFRegNetForImageClassification"), + ("resnet", "TFResNetForImageClassification"), + ("segformer", "TFSegformerForImageClassification"), + ("swin", "TFSwinForImageClassification"), + ("vit", "TFViTForImageClassification"), + ] +) + + +TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Zero Shot Image Classification mapping + ("blip", "TFBlipModel"), + ("clip", "TFCLIPModel"), + ] +) + + +TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Semantic Segmentation mapping + ("data2vec-vision", "TFData2VecVisionForSemanticSegmentation"), + ("mobilevit", "TFMobileViTForSemanticSegmentation"), + ("segformer", "TFSegformerForSemanticSegmentation"), + ] +) + +TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("blip", "TFBlipForConditionalGeneration"), + ("vision-encoder-decoder", "TFVisionEncoderDecoderModel"), + ] +) + +TF_MODEL_FOR_MASKED_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Masked LM mapping + ("albert", "TFAlbertForMaskedLM"), + ("bert", "TFBertForMaskedLM"), + ("camembert", "TFCamembertForMaskedLM"), + ("convbert", "TFConvBertForMaskedLM"), + ("deberta", "TFDebertaForMaskedLM"), + ("deberta-v2", "TFDebertaV2ForMaskedLM"), + ("distilbert", "TFDistilBertForMaskedLM"), + ("electra", "TFElectraForMaskedLM"), + ("esm", "TFEsmForMaskedLM"), + ("flaubert", "TFFlaubertWithLMHeadModel"), + ("funnel", "TFFunnelForMaskedLM"), + ("layoutlm", "TFLayoutLMForMaskedLM"), + ("longformer", "TFLongformerForMaskedLM"), + ("mobilebert", "TFMobileBertForMaskedLM"), + ("mpnet", "TFMPNetForMaskedLM"), + ("rembert", "TFRemBertForMaskedLM"), + ("roberta", "TFRobertaForMaskedLM"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForMaskedLM"), + ("roformer", "TFRoFormerForMaskedLM"), + ("tapas", "TFTapasForMaskedLM"), + ("xlm", "TFXLMWithLMHeadModel"), + ("xlm-roberta", "TFXLMRobertaForMaskedLM"), + ] +) + +TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES = OrderedDict( + [ + # Model for Seq2Seq Causal LM mapping + ("bart", "TFBartForConditionalGeneration"), + ("blenderbot", "TFBlenderbotForConditionalGeneration"), + ("blenderbot-small", "TFBlenderbotSmallForConditionalGeneration"), + ("encoder-decoder", "TFEncoderDecoderModel"), + ("led", "TFLEDForConditionalGeneration"), + ("marian", "TFMarianMTModel"), + ("mbart", "TFMBartForConditionalGeneration"), + ("mt5", "TFMT5ForConditionalGeneration"), + ("pegasus", "TFPegasusForConditionalGeneration"), + ("t5", "TFT5ForConditionalGeneration"), + ] +) + +TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = OrderedDict( + [ + ("speech_to_text", "TFSpeech2TextForConditionalGeneration"), + ("whisper", "TFWhisperForConditionalGeneration"), + ] +) + +TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Sequence Classification mapping + ("albert", "TFAlbertForSequenceClassification"), + ("bart", "TFBartForSequenceClassification"), + ("bert", "TFBertForSequenceClassification"), + ("camembert", "TFCamembertForSequenceClassification"), + ("convbert", "TFConvBertForSequenceClassification"), + ("ctrl", "TFCTRLForSequenceClassification"), + ("deberta", "TFDebertaForSequenceClassification"), + ("deberta-v2", "TFDebertaV2ForSequenceClassification"), + ("distilbert", "TFDistilBertForSequenceClassification"), + ("electra", "TFElectraForSequenceClassification"), + ("esm", "TFEsmForSequenceClassification"), + ("flaubert", "TFFlaubertForSequenceClassification"), + ("funnel", "TFFunnelForSequenceClassification"), + ("gpt-sw3", "TFGPT2ForSequenceClassification"), + ("gpt2", "TFGPT2ForSequenceClassification"), + ("gptj", "TFGPTJForSequenceClassification"), + ("layoutlm", "TFLayoutLMForSequenceClassification"), + ("layoutlmv3", "TFLayoutLMv3ForSequenceClassification"), + ("longformer", "TFLongformerForSequenceClassification"), + ("mobilebert", "TFMobileBertForSequenceClassification"), + ("mpnet", "TFMPNetForSequenceClassification"), + ("openai-gpt", "TFOpenAIGPTForSequenceClassification"), + ("rembert", "TFRemBertForSequenceClassification"), + ("roberta", "TFRobertaForSequenceClassification"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForSequenceClassification"), + ("roformer", "TFRoFormerForSequenceClassification"), + ("tapas", "TFTapasForSequenceClassification"), + ("transfo-xl", "TFTransfoXLForSequenceClassification"), + ("xlm", "TFXLMForSequenceClassification"), + ("xlm-roberta", "TFXLMRobertaForSequenceClassification"), + ("xlnet", "TFXLNetForSequenceClassification"), + ] +) + +TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + # Model for Question Answering mapping + ("albert", "TFAlbertForQuestionAnswering"), + ("bert", "TFBertForQuestionAnswering"), + ("camembert", "TFCamembertForQuestionAnswering"), + ("convbert", "TFConvBertForQuestionAnswering"), + ("deberta", "TFDebertaForQuestionAnswering"), + ("deberta-v2", "TFDebertaV2ForQuestionAnswering"), + ("distilbert", "TFDistilBertForQuestionAnswering"), + ("electra", "TFElectraForQuestionAnswering"), + ("flaubert", "TFFlaubertForQuestionAnsweringSimple"), + ("funnel", "TFFunnelForQuestionAnswering"), + ("gptj", "TFGPTJForQuestionAnswering"), + ("layoutlmv3", "TFLayoutLMv3ForQuestionAnswering"), + ("longformer", "TFLongformerForQuestionAnswering"), + ("mobilebert", "TFMobileBertForQuestionAnswering"), + ("mpnet", "TFMPNetForQuestionAnswering"), + ("rembert", "TFRemBertForQuestionAnswering"), + ("roberta", "TFRobertaForQuestionAnswering"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForQuestionAnswering"), + ("roformer", "TFRoFormerForQuestionAnswering"), + ("xlm", "TFXLMForQuestionAnsweringSimple"), + ("xlm-roberta", "TFXLMRobertaForQuestionAnswering"), + ("xlnet", "TFXLNetForQuestionAnsweringSimple"), + ] +) +TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES = OrderedDict([("wav2vec2", "TFWav2Vec2ForSequenceClassification")]) + +TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + ("layoutlm", "TFLayoutLMForQuestionAnswering"), + ] +) + + +TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES = OrderedDict( + [ + # Model for Table Question Answering mapping + ("tapas", "TFTapasForQuestionAnswering"), + ] +) + +TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES = OrderedDict( + [ + # Model for Token Classification mapping + ("albert", "TFAlbertForTokenClassification"), + ("bert", "TFBertForTokenClassification"), + ("camembert", "TFCamembertForTokenClassification"), + ("convbert", "TFConvBertForTokenClassification"), + ("deberta", "TFDebertaForTokenClassification"), + ("deberta-v2", "TFDebertaV2ForTokenClassification"), + ("distilbert", "TFDistilBertForTokenClassification"), + ("electra", "TFElectraForTokenClassification"), + ("esm", "TFEsmForTokenClassification"), + ("flaubert", "TFFlaubertForTokenClassification"), + ("funnel", "TFFunnelForTokenClassification"), + ("layoutlm", "TFLayoutLMForTokenClassification"), + ("layoutlmv3", "TFLayoutLMv3ForTokenClassification"), + ("longformer", "TFLongformerForTokenClassification"), + ("mobilebert", "TFMobileBertForTokenClassification"), + ("mpnet", "TFMPNetForTokenClassification"), + ("rembert", "TFRemBertForTokenClassification"), + ("roberta", "TFRobertaForTokenClassification"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForTokenClassification"), + ("roformer", "TFRoFormerForTokenClassification"), + ("xlm", "TFXLMForTokenClassification"), + ("xlm-roberta", "TFXLMRobertaForTokenClassification"), + ("xlnet", "TFXLNetForTokenClassification"), + ] +) + +TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES = OrderedDict( + [ + # Model for Multiple Choice mapping + ("albert", "TFAlbertForMultipleChoice"), + ("bert", "TFBertForMultipleChoice"), + ("camembert", "TFCamembertForMultipleChoice"), + ("convbert", "TFConvBertForMultipleChoice"), + ("distilbert", "TFDistilBertForMultipleChoice"), + ("electra", "TFElectraForMultipleChoice"), + ("flaubert", "TFFlaubertForMultipleChoice"), + ("funnel", "TFFunnelForMultipleChoice"), + ("longformer", "TFLongformerForMultipleChoice"), + ("mobilebert", "TFMobileBertForMultipleChoice"), + ("mpnet", "TFMPNetForMultipleChoice"), + ("rembert", "TFRemBertForMultipleChoice"), + ("roberta", "TFRobertaForMultipleChoice"), + ("roberta-prelayernorm", "TFRobertaPreLayerNormForMultipleChoice"), + ("roformer", "TFRoFormerForMultipleChoice"), + ("xlm", "TFXLMForMultipleChoice"), + ("xlm-roberta", "TFXLMRobertaForMultipleChoice"), + ("xlnet", "TFXLNetForMultipleChoice"), + ] +) + +TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES = OrderedDict( + [ + ("bert", "TFBertForNextSentencePrediction"), + ("mobilebert", "TFMobileBertForNextSentencePrediction"), + ] +) + +TF_MODEL_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_MAPPING_NAMES) +TF_MODEL_FOR_PRETRAINING_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_PRETRAINING_MAPPING_NAMES) +TF_MODEL_WITH_LM_HEAD_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_WITH_LM_HEAD_MAPPING_NAMES) +TF_MODEL_FOR_CAUSAL_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_CAUSAL_LM_MAPPING_NAMES) +TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES +) +TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES +) +TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES +) +TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES +) +TF_MODEL_FOR_VISION_2_SEQ_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES) +TF_MODEL_FOR_MASKED_LM_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MASKED_LM_MAPPING_NAMES) +TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES +) +TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES +) +TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES +) +TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES +) +TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES +) +TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING_NAMES +) +TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES +) +TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES +) +TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES +) +TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING = _LazyAutoMapping( + CONFIG_MAPPING_NAMES, TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES +) + + +class TFAutoModel(_BaseAutoModelClass): + _model_mapping = TF_MODEL_MAPPING + + +TFAutoModel = auto_class_update(TFAutoModel) + + +class TFAutoModelForAudioClassification(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING + + +TFAutoModelForAudioClassification = auto_class_update( + TFAutoModelForAudioClassification, head_doc="audio classification" +) + + +class TFAutoModelForPreTraining(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_PRETRAINING_MAPPING + + +TFAutoModelForPreTraining = auto_class_update(TFAutoModelForPreTraining, head_doc="pretraining") + + +# Private on purpose, the public class will add the deprecation warnings. +class _TFAutoModelWithLMHead(_BaseAutoModelClass): + _model_mapping = TF_MODEL_WITH_LM_HEAD_MAPPING + + +_TFAutoModelWithLMHead = auto_class_update(_TFAutoModelWithLMHead, head_doc="language modeling") + + +class TFAutoModelForCausalLM(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_CAUSAL_LM_MAPPING + + +TFAutoModelForCausalLM = auto_class_update(TFAutoModelForCausalLM, head_doc="causal language modeling") + + +class TFAutoModelForMaskedImageModeling(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING + + +TFAutoModelForMaskedImageModeling = auto_class_update( + TFAutoModelForMaskedImageModeling, head_doc="masked image modeling" +) + + +class TFAutoModelForImageClassification(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + + +TFAutoModelForImageClassification = auto_class_update( + TFAutoModelForImageClassification, head_doc="image classification" +) + + +class TFAutoModelForZeroShotImageClassification(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + + +TFAutoModelForZeroShotImageClassification = auto_class_update( + TFAutoModelForZeroShotImageClassification, head_doc="zero-shot image classification" +) + + +class TFAutoModelForSemanticSegmentation(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING + + +TF_AutoModelForSemanticSegmentation = auto_class_update( + TFAutoModelForSemanticSegmentation, head_doc="semantic segmentation" +) + + +class TFAutoModelForVision2Seq(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_VISION_2_SEQ_MAPPING + + +TFAutoModelForVision2Seq = auto_class_update(TFAutoModelForVision2Seq, head_doc="vision-to-text modeling") + + +class TFAutoModelForMaskedLM(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_MASKED_LM_MAPPING + + +TFAutoModelForMaskedLM = auto_class_update(TFAutoModelForMaskedLM, head_doc="masked language modeling") + + +class TFAutoModelForSeq2SeqLM(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + + +TFAutoModelForSeq2SeqLM = auto_class_update( + TFAutoModelForSeq2SeqLM, head_doc="sequence-to-sequence language modeling", checkpoint_for_example="t5-base" +) + + +class TFAutoModelForSequenceClassification(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + + +TFAutoModelForSequenceClassification = auto_class_update( + TFAutoModelForSequenceClassification, head_doc="sequence classification" +) + + +class TFAutoModelForQuestionAnswering(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING + + +TFAutoModelForQuestionAnswering = auto_class_update(TFAutoModelForQuestionAnswering, head_doc="question answering") + + +class TFAutoModelForDocumentQuestionAnswering(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING + + +TFAutoModelForDocumentQuestionAnswering = auto_class_update( + TFAutoModelForDocumentQuestionAnswering, + head_doc="document question answering", + checkpoint_for_example='impira/layoutlm-document-qa", revision="52e01b3', +) + + +class TFAutoModelForTableQuestionAnswering(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING + + +TFAutoModelForTableQuestionAnswering = auto_class_update( + TFAutoModelForTableQuestionAnswering, + head_doc="table question answering", + checkpoint_for_example="google/tapas-base-finetuned-wtq", +) + + +class TFAutoModelForTokenClassification(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + + +TFAutoModelForTokenClassification = auto_class_update( + TFAutoModelForTokenClassification, head_doc="token classification" +) + + +class TFAutoModelForMultipleChoice(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING + + +TFAutoModelForMultipleChoice = auto_class_update(TFAutoModelForMultipleChoice, head_doc="multiple choice") + + +class TFAutoModelForNextSentencePrediction(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING + + +TFAutoModelForNextSentencePrediction = auto_class_update( + TFAutoModelForNextSentencePrediction, head_doc="next sentence prediction" +) + + +class TFAutoModelForSpeechSeq2Seq(_BaseAutoModelClass): + _model_mapping = TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING + + +TFAutoModelForSpeechSeq2Seq = auto_class_update( + TFAutoModelForSpeechSeq2Seq, head_doc="sequence-to-sequence speech-to-text modeling" +) + + +class TFAutoModelWithLMHead(_TFAutoModelWithLMHead): + @classmethod + def from_config(cls, config): + warnings.warn( + "The class `TFAutoModelWithLMHead` is deprecated and will be removed in a future version. Please use" + " `TFAutoModelForCausalLM` for causal language models, `TFAutoModelForMaskedLM` for masked language models" + " and `TFAutoModelForSeq2SeqLM` for encoder-decoder models.", + FutureWarning, + ) + return super().from_config(config) + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): + warnings.warn( + "The class `TFAutoModelWithLMHead` is deprecated and will be removed in a future version. Please use" + " `TFAutoModelForCausalLM` for causal language models, `TFAutoModelForMaskedLM` for masked language models" + " and `TFAutoModelForSeq2SeqLM` for encoder-decoder models.", + FutureWarning, + ) + return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/processing_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/processing_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..d96757bc13ad5ef6794c7e2b9b17fc17b1456a2a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/processing_auto.py @@ -0,0 +1,310 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" AutoProcessor class.""" +import importlib +import inspect +import json +from collections import OrderedDict + +# Build the list of all feature extractors +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...feature_extraction_utils import FeatureExtractionMixin +from ...image_processing_utils import ImageProcessingMixin +from ...tokenization_utils import TOKENIZER_CONFIG_FILE +from ...utils import FEATURE_EXTRACTOR_NAME, get_file_from_repo, logging +from .auto_factory import _LazyAutoMapping +from .configuration_auto import ( + CONFIG_MAPPING_NAMES, + AutoConfig, + model_type_to_module_name, + replace_list_option_in_docstrings, +) +from .feature_extraction_auto import AutoFeatureExtractor +from .image_processing_auto import AutoImageProcessor +from .tokenization_auto import AutoTokenizer + + +logger = logging.get_logger(__name__) + +PROCESSOR_MAPPING_NAMES = OrderedDict( + [ + ("align", "AlignProcessor"), + ("altclip", "AltCLIPProcessor"), + ("blip", "BlipProcessor"), + ("blip-2", "Blip2Processor"), + ("bridgetower", "BridgeTowerProcessor"), + ("chinese_clip", "ChineseCLIPProcessor"), + ("clap", "ClapProcessor"), + ("clip", "CLIPProcessor"), + ("clipseg", "CLIPSegProcessor"), + ("flava", "FlavaProcessor"), + ("git", "GitProcessor"), + ("groupvit", "CLIPProcessor"), + ("hubert", "Wav2Vec2Processor"), + ("layoutlmv2", "LayoutLMv2Processor"), + ("layoutlmv3", "LayoutLMv3Processor"), + ("markuplm", "MarkupLMProcessor"), + ("mgp-str", "MgpstrProcessor"), + ("oneformer", "OneFormerProcessor"), + ("owlvit", "OwlViTProcessor"), + ("pix2struct", "Pix2StructProcessor"), + ("sam", "SamProcessor"), + ("sew", "Wav2Vec2Processor"), + ("sew-d", "Wav2Vec2Processor"), + ("speech_to_text", "Speech2TextProcessor"), + ("speech_to_text_2", "Speech2Text2Processor"), + ("speecht5", "SpeechT5Processor"), + ("trocr", "TrOCRProcessor"), + ("tvlt", "TvltProcessor"), + ("unispeech", "Wav2Vec2Processor"), + ("unispeech-sat", "Wav2Vec2Processor"), + ("vilt", "ViltProcessor"), + ("vision-text-dual-encoder", "VisionTextDualEncoderProcessor"), + ("wav2vec2", "Wav2Vec2Processor"), + ("wav2vec2-conformer", "Wav2Vec2Processor"), + ("wavlm", "Wav2Vec2Processor"), + ("whisper", "WhisperProcessor"), + ("xclip", "XCLIPProcessor"), + ] +) + +PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, PROCESSOR_MAPPING_NAMES) + + +def processor_class_from_name(class_name: str): + for module_name, processors in PROCESSOR_MAPPING_NAMES.items(): + if class_name in processors: + module_name = model_type_to_module_name(module_name) + + module = importlib.import_module(f".{module_name}", "transformers.models") + try: + return getattr(module, class_name) + except AttributeError: + continue + + for processor in PROCESSOR_MAPPING._extra_content.values(): + if getattr(processor, "__name__", None) == class_name: + return processor + + # We did not fine the class, but maybe it's because a dep is missing. In that case, the class will be in the main + # init and we return the proper dummy to get an appropriate error message. + main_module = importlib.import_module("transformers") + if hasattr(main_module, class_name): + return getattr(main_module, class_name) + + return None + + +class AutoProcessor: + r""" + This is a generic processor class that will be instantiated as one of the processor classes of the library when + created with the [`AutoProcessor.from_pretrained`] class method. + + This class cannot be instantiated directly using `__init__()` (throws an error). + """ + + def __init__(self): + raise EnvironmentError( + "AutoProcessor is designed to be instantiated " + "using the `AutoProcessor.from_pretrained(pretrained_model_name_or_path)` method." + ) + + @classmethod + @replace_list_option_in_docstrings(PROCESSOR_MAPPING_NAMES) + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + r""" + Instantiate one of the processor classes of the library from a pretrained model vocabulary. + + The processor class to instantiate is selected based on the `model_type` property of the config object (either + passed as an argument or loaded from `pretrained_model_name_or_path` if possible): + + List options + + Params: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or + namespaced under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a processor files saved using the `save_pretrained()` method, + e.g., `./my_model_directory/`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model feature extractor should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the feature extractor files and override the cached versions + if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file + exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + return_unused_kwargs (`bool`, *optional*, defaults to `False`): + If `False`, then this function returns just the final feature extractor object. If `True`, then this + functions returns a `Tuple(feature_extractor, unused_kwargs)` where *unused_kwargs* is a dictionary + consisting of the key/value pairs whose keys are not feature extractor attributes: i.e., the part of + `kwargs` which has not been used to update `feature_extractor` and is otherwise ignored. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (`Dict[str, Any]`, *optional*): + The values in kwargs of any keys which are feature extractor attributes will be used to override the + loaded values. Behavior concerning key/value pairs whose keys are *not* feature extractor attributes is + controlled by the `return_unused_kwargs` keyword parameter. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Examples: + + ```python + >>> from transformers import AutoProcessor + + >>> # Download processor from huggingface.co and cache. + >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h") + + >>> # If processor files are in a directory (e.g. processor was saved using *save_pretrained('./test/saved_model/')*) + >>> # processor = AutoProcessor.from_pretrained("./test/saved_model/") + ```""" + config = kwargs.pop("config", None) + trust_remote_code = kwargs.pop("trust_remote_code", False) + kwargs["_from_auto"] = True + + processor_class = None + processor_auto_map = None + + # First, let's see if we have a preprocessor config. + # Filter the kwargs for `get_file_from_repo`. + get_file_from_repo_kwargs = { + key: kwargs[key] for key in inspect.signature(get_file_from_repo).parameters.keys() if key in kwargs + } + # Let's start by checking whether the processor class is saved in an image processor + preprocessor_config_file = get_file_from_repo( + pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, **get_file_from_repo_kwargs + ) + if preprocessor_config_file is not None: + config_dict, _ = ImageProcessingMixin.get_image_processor_dict(pretrained_model_name_or_path, **kwargs) + processor_class = config_dict.get("processor_class", None) + if "AutoProcessor" in config_dict.get("auto_map", {}): + processor_auto_map = config_dict["auto_map"]["AutoProcessor"] + + # If not found, let's check whether the processor class is saved in a feature extractor config + if preprocessor_config_file is not None and processor_class is None: + config_dict, _ = FeatureExtractionMixin.get_feature_extractor_dict(pretrained_model_name_or_path, **kwargs) + processor_class = config_dict.get("processor_class", None) + if "AutoProcessor" in config_dict.get("auto_map", {}): + processor_auto_map = config_dict["auto_map"]["AutoProcessor"] + + if processor_class is None: + # Next, let's check whether the processor class is saved in a tokenizer + tokenizer_config_file = get_file_from_repo( + pretrained_model_name_or_path, TOKENIZER_CONFIG_FILE, **get_file_from_repo_kwargs + ) + if tokenizer_config_file is not None: + with open(tokenizer_config_file, encoding="utf-8") as reader: + config_dict = json.load(reader) + + processor_class = config_dict.get("processor_class", None) + if "AutoProcessor" in config_dict.get("auto_map", {}): + processor_auto_map = config_dict["auto_map"]["AutoProcessor"] + + if processor_class is None: + # Otherwise, load config, if it can be loaded. + if not isinstance(config, PretrainedConfig): + config = AutoConfig.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + + # And check if the config contains the processor class. + processor_class = getattr(config, "processor_class", None) + if hasattr(config, "auto_map") and "AutoProcessor" in config.auto_map: + processor_auto_map = config.auto_map["AutoProcessor"] + + if processor_class is not None: + # If we have custom code for a feature extractor, we get the proper class. + if processor_auto_map is not None: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the feature extractor file " + "in that repo on your local machine. Make sure you have read the code there to avoid " + "malicious use, then set the option `trust_remote_code=True` to remove this error." + ) + + processor_class = get_class_from_dynamic_module( + processor_auto_map, pretrained_model_name_or_path, **kwargs + ) + else: + processor_class = processor_class_from_name(processor_class) + + return processor_class.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + + # Last try: we use the PROCESSOR_MAPPING. + if type(config) in PROCESSOR_MAPPING: + return PROCESSOR_MAPPING[type(config)].from_pretrained(pretrained_model_name_or_path, **kwargs) + + # At this stage, there doesn't seem to be a `Processor` class available for this model, so let's try a + # tokenizer. + try: + return AutoTokenizer.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + except Exception: + try: + return AutoImageProcessor.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + except Exception: + pass + + try: + return AutoFeatureExtractor.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + except Exception: + pass + + raise ValueError( + f"Unrecognized processing class in {pretrained_model_name_or_path}. Can't instantiate a processor, a " + "tokenizer, an image processor or a feature extractor for this model. Make sure the repository contains" + "the files of at least one of those processing classes." + ) + + @staticmethod + def register(config_class, processor_class): + """ + Register a new processor for this class. + + Args: + config_class ([`PretrainedConfig`]): + The configuration corresponding to the model to register. + processor_class ([`FeatureExtractorMixin`]): The processor to register. + """ + PROCESSOR_MAPPING.register(config_class, processor_class) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/tokenization_auto.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/tokenization_auto.py new file mode 100644 index 0000000000000000000000000000000000000000..cb6c91521de91b8fa1e3d5381a846d27c7ae8b27 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/auto/tokenization_auto.py @@ -0,0 +1,767 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Auto Tokenizer class.""" + +import importlib +import json +import os +from collections import OrderedDict +from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union + +from ...configuration_utils import PretrainedConfig +from ...dynamic_module_utils import get_class_from_dynamic_module +from ...tokenization_utils import PreTrainedTokenizer +from ...tokenization_utils_base import TOKENIZER_CONFIG_FILE +from ...utils import cached_file, extract_commit_hash, is_sentencepiece_available, is_tokenizers_available, logging +from ..encoder_decoder import EncoderDecoderConfig +from .auto_factory import _LazyAutoMapping +from .configuration_auto import ( + CONFIG_MAPPING_NAMES, + AutoConfig, + config_class_to_model_type, + model_type_to_module_name, + replace_list_option_in_docstrings, +) + + +if is_tokenizers_available(): + from ...tokenization_utils_fast import PreTrainedTokenizerFast +else: + PreTrainedTokenizerFast = None + + +logger = logging.get_logger(__name__) + +if TYPE_CHECKING: + # This significantly improves completion suggestion performance when + # the transformers package is used with Microsoft's Pylance language server. + TOKENIZER_MAPPING_NAMES: OrderedDict[str, Tuple[Optional[str], Optional[str]]] = OrderedDict() +else: + TOKENIZER_MAPPING_NAMES = OrderedDict( + [ + ( + "albert", + ( + "AlbertTokenizer" if is_sentencepiece_available() else None, + "AlbertTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("align", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("bart", ("BartTokenizer", "BartTokenizerFast")), + ( + "barthez", + ( + "BarthezTokenizer" if is_sentencepiece_available() else None, + "BarthezTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("bartpho", ("BartphoTokenizer", None)), + ("bert", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("bert-generation", ("BertGenerationTokenizer" if is_sentencepiece_available() else None, None)), + ("bert-japanese", ("BertJapaneseTokenizer", None)), + ("bertweet", ("BertweetTokenizer", None)), + ( + "big_bird", + ( + "BigBirdTokenizer" if is_sentencepiece_available() else None, + "BigBirdTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("bigbird_pegasus", ("PegasusTokenizer", "PegasusTokenizerFast" if is_tokenizers_available() else None)), + ("biogpt", ("BioGptTokenizer", None)), + ("blenderbot", ("BlenderbotTokenizer", "BlenderbotTokenizerFast")), + ("blenderbot-small", ("BlenderbotSmallTokenizer", None)), + ("blip", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("blip-2", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("bloom", (None, "BloomTokenizerFast" if is_tokenizers_available() else None)), + ("bridgetower", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), + ("byt5", ("ByT5Tokenizer", None)), + ( + "camembert", + ( + "CamembertTokenizer" if is_sentencepiece_available() else None, + "CamembertTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("canine", ("CanineTokenizer", None)), + ("chinese_clip", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ( + "clap", + ( + "RobertaTokenizer", + "RobertaTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "clip", + ( + "CLIPTokenizer", + "CLIPTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "clipseg", + ( + "CLIPTokenizer", + "CLIPTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("codegen", ("CodeGenTokenizer", "CodeGenTokenizerFast" if is_tokenizers_available() else None)), + ("convbert", ("ConvBertTokenizer", "ConvBertTokenizerFast" if is_tokenizers_available() else None)), + ( + "cpm", + ( + "CpmTokenizer" if is_sentencepiece_available() else None, + "CpmTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("cpmant", ("CpmAntTokenizer", None)), + ("ctrl", ("CTRLTokenizer", None)), + ("data2vec-text", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), + ("deberta", ("DebertaTokenizer", "DebertaTokenizerFast" if is_tokenizers_available() else None)), + ( + "deberta-v2", + ( + "DebertaV2Tokenizer" if is_sentencepiece_available() else None, + "DebertaV2TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("distilbert", ("DistilBertTokenizer", "DistilBertTokenizerFast" if is_tokenizers_available() else None)), + ( + "dpr", + ( + "DPRQuestionEncoderTokenizer", + "DPRQuestionEncoderTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("electra", ("ElectraTokenizer", "ElectraTokenizerFast" if is_tokenizers_available() else None)), + ("ernie", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("ernie_m", ("ErnieMTokenizer" if is_sentencepiece_available() else None, None)), + ("esm", ("EsmTokenizer", None)), + ("flaubert", ("FlaubertTokenizer", None)), + ("fnet", ("FNetTokenizer", "FNetTokenizerFast" if is_tokenizers_available() else None)), + ("fsmt", ("FSMTTokenizer", None)), + ("funnel", ("FunnelTokenizer", "FunnelTokenizerFast" if is_tokenizers_available() else None)), + ("git", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("gpt-sw3", ("GPTSw3Tokenizer" if is_sentencepiece_available() else None, None)), + ("gpt2", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("gpt_bigcode", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("gpt_neo", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("gpt_neox", (None, "GPTNeoXTokenizerFast" if is_tokenizers_available() else None)), + ("gpt_neox_japanese", ("GPTNeoXJapaneseTokenizer", None)), + ("gptj", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("gptsan-japanese", ("GPTSanJapaneseTokenizer", None)), + ("groupvit", ("CLIPTokenizer", "CLIPTokenizerFast" if is_tokenizers_available() else None)), + ("herbert", ("HerbertTokenizer", "HerbertTokenizerFast" if is_tokenizers_available() else None)), + ("hubert", ("Wav2Vec2CTCTokenizer", None)), + ("ibert", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), + ("jukebox", ("JukeboxTokenizer", None)), + ("layoutlm", ("LayoutLMTokenizer", "LayoutLMTokenizerFast" if is_tokenizers_available() else None)), + ("layoutlmv2", ("LayoutLMv2Tokenizer", "LayoutLMv2TokenizerFast" if is_tokenizers_available() else None)), + ("layoutlmv3", ("LayoutLMv3Tokenizer", "LayoutLMv3TokenizerFast" if is_tokenizers_available() else None)), + ("layoutxlm", ("LayoutXLMTokenizer", "LayoutXLMTokenizerFast" if is_tokenizers_available() else None)), + ("led", ("LEDTokenizer", "LEDTokenizerFast" if is_tokenizers_available() else None)), + ("lilt", ("LayoutLMv3Tokenizer", "LayoutLMv3TokenizerFast" if is_tokenizers_available() else None)), + ( + "llama", + ( + "LlamaTokenizer" if is_sentencepiece_available() else None, + "LlamaTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("longformer", ("LongformerTokenizer", "LongformerTokenizerFast" if is_tokenizers_available() else None)), + ( + "longt5", + ( + "T5Tokenizer" if is_sentencepiece_available() else None, + "T5TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("luke", ("LukeTokenizer", None)), + ("lxmert", ("LxmertTokenizer", "LxmertTokenizerFast" if is_tokenizers_available() else None)), + ("m2m_100", ("M2M100Tokenizer" if is_sentencepiece_available() else None, None)), + ("marian", ("MarianTokenizer" if is_sentencepiece_available() else None, None)), + ( + "mbart", + ( + "MBartTokenizer" if is_sentencepiece_available() else None, + "MBartTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "mbart50", + ( + "MBart50Tokenizer" if is_sentencepiece_available() else None, + "MBart50TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("mega", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), + ("megatron-bert", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("mgp-str", ("MgpstrTokenizer", None)), + ("mluke", ("MLukeTokenizer" if is_sentencepiece_available() else None, None)), + ("mobilebert", ("MobileBertTokenizer", "MobileBertTokenizerFast" if is_tokenizers_available() else None)), + ("mpnet", ("MPNetTokenizer", "MPNetTokenizerFast" if is_tokenizers_available() else None)), + ( + "mt5", + ( + "MT5Tokenizer" if is_sentencepiece_available() else None, + "MT5TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("mvp", ("MvpTokenizer", "MvpTokenizerFast" if is_tokenizers_available() else None)), + ("nezha", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ( + "nllb", + ( + "NllbTokenizer" if is_sentencepiece_available() else None, + "NllbTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "nllb-moe", + ( + "NllbTokenizer" if is_sentencepiece_available() else None, + "NllbTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "nystromformer", + ( + "AlbertTokenizer" if is_sentencepiece_available() else None, + "AlbertTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("oneformer", ("CLIPTokenizer", "CLIPTokenizerFast" if is_tokenizers_available() else None)), + ("openai-gpt", ("OpenAIGPTTokenizer", "OpenAIGPTTokenizerFast" if is_tokenizers_available() else None)), + ("opt", ("GPT2Tokenizer", "GPT2TokenizerFast" if is_tokenizers_available() else None)), + ("owlvit", ("CLIPTokenizer", "CLIPTokenizerFast" if is_tokenizers_available() else None)), + ( + "pegasus", + ( + "PegasusTokenizer" if is_sentencepiece_available() else None, + "PegasusTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "pegasus_x", + ( + "PegasusTokenizer" if is_sentencepiece_available() else None, + "PegasusTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "perceiver", + ( + "PerceiverTokenizer", + None, + ), + ), + ("phobert", ("PhobertTokenizer", None)), + ("pix2struct", ("T5Tokenizer", "T5TokenizerFast" if is_tokenizers_available() else None)), + ("plbart", ("PLBartTokenizer" if is_sentencepiece_available() else None, None)), + ("prophetnet", ("ProphetNetTokenizer", None)), + ("qdqbert", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("rag", ("RagTokenizer", None)), + ("realm", ("RealmTokenizer", "RealmTokenizerFast" if is_tokenizers_available() else None)), + ( + "reformer", + ( + "ReformerTokenizer" if is_sentencepiece_available() else None, + "ReformerTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "rembert", + ( + "RemBertTokenizer" if is_sentencepiece_available() else None, + "RemBertTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("retribert", ("RetriBertTokenizer", "RetriBertTokenizerFast" if is_tokenizers_available() else None)), + ("roberta", ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None)), + ( + "roberta-prelayernorm", + ("RobertaTokenizer", "RobertaTokenizerFast" if is_tokenizers_available() else None), + ), + ("roc_bert", ("RoCBertTokenizer", None)), + ("roformer", ("RoFormerTokenizer", "RoFormerTokenizerFast" if is_tokenizers_available() else None)), + ("rwkv", (None, "GPTNeoXTokenizerFast" if is_tokenizers_available() else None)), + ("speech_to_text", ("Speech2TextTokenizer" if is_sentencepiece_available() else None, None)), + ("speech_to_text_2", ("Speech2Text2Tokenizer", None)), + ("speecht5", ("SpeechT5Tokenizer" if is_sentencepiece_available() else None, None)), + ("splinter", ("SplinterTokenizer", "SplinterTokenizerFast")), + ( + "squeezebert", + ("SqueezeBertTokenizer", "SqueezeBertTokenizerFast" if is_tokenizers_available() else None), + ), + ( + "switch_transformers", + ( + "T5Tokenizer" if is_sentencepiece_available() else None, + "T5TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "t5", + ( + "T5Tokenizer" if is_sentencepiece_available() else None, + "T5TokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("tapas", ("TapasTokenizer", None)), + ("tapex", ("TapexTokenizer", None)), + ("transfo-xl", ("TransfoXLTokenizer", None)), + ("vilt", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("visual_bert", ("BertTokenizer", "BertTokenizerFast" if is_tokenizers_available() else None)), + ("wav2vec2", ("Wav2Vec2CTCTokenizer", None)), + ("wav2vec2-conformer", ("Wav2Vec2CTCTokenizer", None)), + ("wav2vec2_phoneme", ("Wav2Vec2PhonemeCTCTokenizer", None)), + ("whisper", ("WhisperTokenizer", "WhisperTokenizerFast" if is_tokenizers_available() else None)), + ("xclip", ("CLIPTokenizer", "CLIPTokenizerFast" if is_tokenizers_available() else None)), + ( + "xglm", + ( + "XGLMTokenizer" if is_sentencepiece_available() else None, + "XGLMTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ("xlm", ("XLMTokenizer", None)), + ("xlm-prophetnet", ("XLMProphetNetTokenizer" if is_sentencepiece_available() else None, None)), + ( + "xlm-roberta", + ( + "XLMRobertaTokenizer" if is_sentencepiece_available() else None, + "XLMRobertaTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "xlm-roberta-xl", + ( + "XLMRobertaTokenizer" if is_sentencepiece_available() else None, + "XLMRobertaTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "xlnet", + ( + "XLNetTokenizer" if is_sentencepiece_available() else None, + "XLNetTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "xmod", + ( + "XLMRobertaTokenizer" if is_sentencepiece_available() else None, + "XLMRobertaTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ( + "yoso", + ( + "AlbertTokenizer" if is_sentencepiece_available() else None, + "AlbertTokenizerFast" if is_tokenizers_available() else None, + ), + ), + ] + ) + +TOKENIZER_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TOKENIZER_MAPPING_NAMES) + +CONFIG_TO_TYPE = {v: k for k, v in CONFIG_MAPPING_NAMES.items()} + + +def tokenizer_class_from_name(class_name: str): + if class_name == "PreTrainedTokenizerFast": + return PreTrainedTokenizerFast + + for module_name, tokenizers in TOKENIZER_MAPPING_NAMES.items(): + if class_name in tokenizers: + module_name = model_type_to_module_name(module_name) + + module = importlib.import_module(f".{module_name}", "transformers.models") + try: + return getattr(module, class_name) + except AttributeError: + continue + + for config, tokenizers in TOKENIZER_MAPPING._extra_content.items(): + for tokenizer in tokenizers: + if getattr(tokenizer, "__name__", None) == class_name: + return tokenizer + + # We did not fine the class, but maybe it's because a dep is missing. In that case, the class will be in the main + # init and we return the proper dummy to get an appropriate error message. + main_module = importlib.import_module("transformers") + if hasattr(main_module, class_name): + return getattr(main_module, class_name) + + return None + + +def get_tokenizer_config( + pretrained_model_name_or_path: Union[str, os.PathLike], + cache_dir: Optional[Union[str, os.PathLike]] = None, + force_download: bool = False, + resume_download: bool = False, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, + revision: Optional[str] = None, + local_files_only: bool = False, + subfolder: str = "", + **kwargs, +): + """ + Loads the tokenizer configuration from a pretrained model tokenizer configuration. + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained model configuration hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced + under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a configuration file saved using the + [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`. + + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the standard + cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the configuration files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, will only try to load the tokenizer configuration from local files. + subfolder (`str`, *optional*, defaults to `""`): + In case the tokenizer config is located inside a subfolder of the model repo on huggingface.co, you can + specify the folder name here. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Returns: + `Dict`: The configuration of the tokenizer. + + Examples: + + ```python + # Download configuration from huggingface.co and cache. + tokenizer_config = get_tokenizer_config("bert-base-uncased") + # This model does not have a tokenizer config so the result will be an empty dict. + tokenizer_config = get_tokenizer_config("xlm-roberta-base") + + # Save a pretrained tokenizer locally and you can reload its config + from transformers import AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") + tokenizer.save_pretrained("tokenizer-test") + tokenizer_config = get_tokenizer_config("tokenizer-test") + ```""" + commit_hash = kwargs.get("_commit_hash", None) + resolved_config_file = cached_file( + pretrained_model_name_or_path, + TOKENIZER_CONFIG_FILE, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + use_auth_token=use_auth_token, + revision=revision, + local_files_only=local_files_only, + subfolder=subfolder, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + _commit_hash=commit_hash, + ) + if resolved_config_file is None: + logger.info("Could not locate the tokenizer configuration file, will try to use the model config instead.") + return {} + commit_hash = extract_commit_hash(resolved_config_file, commit_hash) + + with open(resolved_config_file, encoding="utf-8") as reader: + result = json.load(reader) + result["_commit_hash"] = commit_hash + return result + + +class AutoTokenizer: + r""" + This is a generic tokenizer class that will be instantiated as one of the tokenizer classes of the library when + created with the [`AutoTokenizer.from_pretrained`] class method. + + This class cannot be instantiated directly using `__init__()` (throws an error). + """ + + def __init__(self): + raise EnvironmentError( + "AutoTokenizer is designed to be instantiated " + "using the `AutoTokenizer.from_pretrained(pretrained_model_name_or_path)` method." + ) + + @classmethod + @replace_list_option_in_docstrings(TOKENIZER_MAPPING_NAMES) + def from_pretrained(cls, pretrained_model_name_or_path, *inputs, **kwargs): + r""" + Instantiate one of the tokenizer classes of the library from a pretrained model vocabulary. + + The tokenizer class to instantiate is selected based on the `model_type` property of the config object (either + passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by + falling back to using pattern matching on `pretrained_model_name_or_path`: + + List options + + Params: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a predefined tokenizer hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing vocabulary files required by the tokenizer, for instance saved + using the [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`. + - A path or url to a single saved vocabulary file if and only if the tokenizer only requires a + single vocabulary file (like Bert or XLNet), e.g.: `./my_model_directory/vocab.txt`. (Not + applicable to all derived classes) + inputs (additional positional arguments, *optional*): + Will be passed along to the Tokenizer `__init__()` method. + config ([`PretrainedConfig`], *optional*) + The configuration object used to dertermine the tokenizer class to instantiate. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download the model weights and configuration files and override the + cached versions if they exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Will attempt to resume the download if such a + file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + subfolder (`str`, *optional*): + In case the relevant files are located inside a subfolder of the model repo on huggingface.co (e.g. for + facebook/rag-token-base), specify it here. + use_fast (`bool`, *optional*, defaults to `True`): + Use a [fast Rust-based tokenizer](https://huggingface.co/docs/tokenizers/index) if it is supported for + a given model. If a fast tokenizer is not available for a given model, a normal Python-based tokenizer + is returned instead. + tokenizer_type (`str`, *optional*): + Tokenizer type to be loaded. + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom models defined on the Hub in their own modeling files. This option + should only be set to `True` for repositories you trust and in which you have read the code, as it will + execute code present on the Hub on your local machine. + kwargs (additional keyword arguments, *optional*): + Will be passed to the Tokenizer `__init__()` method. Can be used to set special tokens like + `bos_token`, `eos_token`, `unk_token`, `sep_token`, `pad_token`, `cls_token`, `mask_token`, + `additional_special_tokens`. See parameters in the `__init__()` for more details. + + Examples: + + ```python + >>> from transformers import AutoTokenizer + + >>> # Download vocabulary from huggingface.co and cache. + >>> tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") + + >>> # Download vocabulary from huggingface.co (user-uploaded) and cache. + >>> tokenizer = AutoTokenizer.from_pretrained("dbmdz/bert-base-german-cased") + + >>> # If vocabulary files are in a directory (e.g. tokenizer was saved using *save_pretrained('./test/saved_model/')*) + >>> # tokenizer = AutoTokenizer.from_pretrained("./test/bert_saved_model/") + + >>> # Download vocabulary from huggingface.co and define model-specific arguments + >>> tokenizer = AutoTokenizer.from_pretrained("roberta-base", add_prefix_space=True) + ```""" + config = kwargs.pop("config", None) + kwargs["_from_auto"] = True + + use_fast = kwargs.pop("use_fast", True) + tokenizer_type = kwargs.pop("tokenizer_type", None) + trust_remote_code = kwargs.pop("trust_remote_code", False) + + # First, let's see whether the tokenizer_type is passed so that we can leverage it + if tokenizer_type is not None: + tokenizer_class = None + tokenizer_class_tuple = TOKENIZER_MAPPING_NAMES.get(tokenizer_type, None) + + if tokenizer_class_tuple is None: + raise ValueError( + f"Passed `tokenizer_type` {tokenizer_type} does not exist. `tokenizer_type` should be one of " + f"{', '.join(c for c in TOKENIZER_MAPPING_NAMES.keys())}." + ) + + tokenizer_class_name, tokenizer_fast_class_name = tokenizer_class_tuple + + if use_fast: + if tokenizer_fast_class_name is not None: + tokenizer_class = tokenizer_class_from_name(tokenizer_fast_class_name) + else: + logger.warning( + "`use_fast` is set to `True` but the tokenizer class does not have a fast version. " + " Falling back to the slow version." + ) + if tokenizer_class is None: + tokenizer_class = tokenizer_class_from_name(tokenizer_class_name) + + if tokenizer_class is None: + raise ValueError(f"Tokenizer class {tokenizer_class_name} is not currently imported.") + + return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs) + + # Next, let's try to use the tokenizer_config file to get the tokenizer class. + tokenizer_config = get_tokenizer_config(pretrained_model_name_or_path, **kwargs) + if "_commit_hash" in tokenizer_config: + kwargs["_commit_hash"] = tokenizer_config["_commit_hash"] + config_tokenizer_class = tokenizer_config.get("tokenizer_class") + tokenizer_auto_map = None + if "auto_map" in tokenizer_config: + if isinstance(tokenizer_config["auto_map"], (tuple, list)): + # Legacy format for dynamic tokenizers + tokenizer_auto_map = tokenizer_config["auto_map"] + else: + tokenizer_auto_map = tokenizer_config["auto_map"].get("AutoTokenizer", None) + + # If that did not work, let's try to use the config. + if config_tokenizer_class is None: + if not isinstance(config, PretrainedConfig): + config = AutoConfig.from_pretrained( + pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs + ) + config_tokenizer_class = config.tokenizer_class + if hasattr(config, "auto_map") and "AutoTokenizer" in config.auto_map: + tokenizer_auto_map = config.auto_map["AutoTokenizer"] + + # If we have the tokenizer class from the tokenizer config or the model config we're good! + if config_tokenizer_class is not None: + tokenizer_class = None + if tokenizer_auto_map is not None: + if not trust_remote_code: + raise ValueError( + f"Loading {pretrained_model_name_or_path} requires you to execute the tokenizer file in that" + " repo on your local machine. Make sure you have read the code there to avoid malicious use," + " then set the option `trust_remote_code=True` to remove this error." + ) + + if use_fast and tokenizer_auto_map[1] is not None: + class_ref = tokenizer_auto_map[1] + else: + class_ref = tokenizer_auto_map[0] + tokenizer_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs) + + elif use_fast and not config_tokenizer_class.endswith("Fast"): + tokenizer_class_candidate = f"{config_tokenizer_class}Fast" + tokenizer_class = tokenizer_class_from_name(tokenizer_class_candidate) + if tokenizer_class is None: + tokenizer_class_candidate = config_tokenizer_class + tokenizer_class = tokenizer_class_from_name(tokenizer_class_candidate) + + if tokenizer_class is None: + raise ValueError( + f"Tokenizer class {tokenizer_class_candidate} does not exist or is not currently imported." + ) + return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs) + + # Otherwise we have to be creative. + # if model is an encoder decoder, the encoder tokenizer class is used by default + if isinstance(config, EncoderDecoderConfig): + if type(config.decoder) is not type(config.encoder): # noqa: E721 + logger.warning( + f"The encoder model config class: {config.encoder.__class__} is different from the decoder model " + f"config class: {config.decoder.__class__}. It is not recommended to use the " + "`AutoTokenizer.from_pretrained()` method in this case. Please use the encoder and decoder " + "specific tokenizer classes." + ) + config = config.encoder + + model_type = config_class_to_model_type(type(config).__name__) + if model_type is not None: + tokenizer_class_py, tokenizer_class_fast = TOKENIZER_MAPPING[type(config)] + if tokenizer_class_fast and (use_fast or tokenizer_class_py is None): + return tokenizer_class_fast.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs) + else: + if tokenizer_class_py is not None: + return tokenizer_class_py.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs) + else: + raise ValueError( + "This tokenizer cannot be instantiated. Please make sure you have `sentencepiece` installed " + "in order to use this tokenizer." + ) + + raise ValueError( + f"Unrecognized configuration class {config.__class__} to build an AutoTokenizer.\n" + f"Model type should be one of {', '.join(c.__name__ for c in TOKENIZER_MAPPING.keys())}." + ) + + def register(config_class, slow_tokenizer_class=None, fast_tokenizer_class=None): + """ + Register a new tokenizer in this mapping. + + + Args: + config_class ([`PretrainedConfig`]): + The configuration corresponding to the model to register. + slow_tokenizer_class ([`PretrainedTokenizer`], *optional*): + The slow tokenizer to register. + slow_tokenizer_class ([`PretrainedTokenizerFast`], *optional*): + The fast tokenizer to register. + """ + if slow_tokenizer_class is None and fast_tokenizer_class is None: + raise ValueError("You need to pass either a `slow_tokenizer_class` or a `fast_tokenizer_class") + if slow_tokenizer_class is not None and issubclass(slow_tokenizer_class, PreTrainedTokenizerFast): + raise ValueError("You passed a fast tokenizer in the `slow_tokenizer_class`.") + if fast_tokenizer_class is not None and issubclass(fast_tokenizer_class, PreTrainedTokenizer): + raise ValueError("You passed a slow tokenizer in the `fast_tokenizer_class`.") + + if ( + slow_tokenizer_class is not None + and fast_tokenizer_class is not None + and issubclass(fast_tokenizer_class, PreTrainedTokenizerFast) + and fast_tokenizer_class.slow_tokenizer_class != slow_tokenizer_class + ): + raise ValueError( + "The fast tokenizer class you are passing has a `slow_tokenizer_class` attribute that is not " + "consistent with the slow tokenizer class you passed (fast tokenizer has " + f"{fast_tokenizer_class.slow_tokenizer_class} and you passed {slow_tokenizer_class}. Fix one of those " + "so they match!" + ) + + # Avoid resetting a set slow/fast tokenizer if we are passing just the other ones. + if config_class in TOKENIZER_MAPPING._extra_content: + existing_slow, existing_fast = TOKENIZER_MAPPING[config_class] + if slow_tokenizer_class is None: + slow_tokenizer_class = existing_slow + if fast_tokenizer_class is None: + fast_tokenizer_class = existing_fast + + TOKENIZER_MAPPING.register(config_class, (slow_tokenizer_class, fast_tokenizer_class)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/configuration_bart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/configuration_bart.py new file mode 100644 index 0000000000000000000000000000000000000000..2a04657f419909bd5f8c3028b27b099ecce2c0d3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/configuration_bart.py @@ -0,0 +1,405 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" BART model configuration""" +import warnings +from collections import OrderedDict +from typing import Any, Mapping, Optional + +from ... import PreTrainedTokenizer +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeq2SeqConfigWithPast +from ...onnx.utils import compute_effective_axis_dimension +from ...utils import TensorType, is_torch_available, logging + + +logger = logging.get_logger(__name__) + +BART_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/bart-large": "https://huggingface.co/facebook/bart-large/resolve/main/config.json", + # See all BART models at https://huggingface.co/models?filter=bart +} + + +class BartConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`BartModel`]. It is used to instantiate a BART + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the BART + [facebook/bart-large](https://huggingface.co/facebook/bart-large) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 50265): + Vocabulary size of the BART model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`BartModel`] or [`TFBartModel`]. + d_model (`int`, *optional*, defaults to 1024): + Dimensionality of the layers and the pooler layer. + encoder_layers (`int`, *optional*, defaults to 12): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 12): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer decoder. + decoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimensionality of the "intermediate" (often named feed-forward) layer in decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimensionality of the "intermediate" (often named feed-forward) layer in decoder. + activation_function (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + classifier_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for classifier. + max_position_embeddings (`int`, *optional*, defaults to 1024): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + encoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + decoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the decoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + scale_embedding (`bool`, *optional*, defaults to `False`): + Scale embeddings by diving by sqrt(d_model). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + num_labels (`int`, *optional*, defaults to 3): + The number of labels to use in [`BartForSequenceClassification`]. + forced_eos_token_id (`int`, *optional*, defaults to 2): + The id of the token to force as the last generated token when `max_length` is reached. Usually set to + `eos_token_id`. + + Example: + + ```python + >>> from transformers import BartConfig, BartModel + + >>> # Initializing a BART facebook/bart-large style configuration + >>> configuration = BartConfig() + + >>> # Initializing a model (with random weights) from the facebook/bart-large style configuration + >>> model = BartModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "bart" + keys_to_ignore_at_inference = ["past_key_values"] + attribute_map = {"num_attention_heads": "encoder_attention_heads", "hidden_size": "d_model"} + + def __init__( + self, + vocab_size=50265, + max_position_embeddings=1024, + encoder_layers=12, + encoder_ffn_dim=4096, + encoder_attention_heads=16, + decoder_layers=12, + decoder_ffn_dim=4096, + decoder_attention_heads=16, + encoder_layerdrop=0.0, + decoder_layerdrop=0.0, + activation_function="gelu", + d_model=1024, + dropout=0.1, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + classifier_dropout=0.0, + scale_embedding=False, + use_cache=True, + num_labels=3, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + is_encoder_decoder=True, + decoder_start_token_id=2, + forced_eos_token_id=2, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.d_model = d_model + self.encoder_ffn_dim = encoder_ffn_dim + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.encoder_layerdrop = encoder_layerdrop + self.decoder_layerdrop = decoder_layerdrop + self.classifier_dropout = classifier_dropout + self.use_cache = use_cache + self.num_hidden_layers = encoder_layers + self.scale_embedding = scale_embedding # scale factor will be sqrt(d_model) if True + + super().__init__( + num_labels=num_labels, + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + is_encoder_decoder=is_encoder_decoder, + decoder_start_token_id=decoder_start_token_id, + forced_eos_token_id=forced_eos_token_id, + **kwargs, + ) + + # ensure backward compatibility for BART CNN models + if self.forced_bos_token_id is None and kwargs.get("force_bos_token_to_be_generated", False): + self.forced_bos_token_id = self.bos_token_id + warnings.warn( + f"Please make sure the config includes `forced_bos_token_id={self.bos_token_id}` in future versions. " + "The config can simply be saved and uploaded again to be fixed." + ) + + +class BartOnnxConfig(OnnxSeq2SeqConfigWithPast): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task in ["default", "seq2seq-lm"]: + common_inputs = OrderedDict( + [ + ("input_ids", {0: "batch", 1: "encoder_sequence"}), + ("attention_mask", {0: "batch", 1: "encoder_sequence"}), + ] + ) + + if self.use_past: + common_inputs["decoder_input_ids"] = {0: "batch"} + common_inputs["decoder_attention_mask"] = {0: "batch", 1: "past_decoder_sequence + sequence"} + else: + common_inputs["decoder_input_ids"] = {0: "batch", 1: "decoder_sequence"} + common_inputs["decoder_attention_mask"] = {0: "batch", 1: "decoder_sequence"} + + if self.use_past: + self.fill_with_past_key_values_(common_inputs, direction="inputs") + elif self.task == "causal-lm": + # TODO: figure this case out. + common_inputs = OrderedDict( + [ + ("input_ids", {0: "batch", 1: "encoder_sequence"}), + ("attention_mask", {0: "batch", 1: "encoder_sequence"}), + ] + ) + if self.use_past: + num_encoder_layers, _ = self.num_layers + for i in range(num_encoder_layers): + common_inputs[f"past_key_values.{i}.key"] = {0: "batch", 2: "past_sequence + sequence"} + common_inputs[f"past_key_values.{i}.value"] = {0: "batch", 2: "past_sequence + sequence"} + else: + common_inputs = OrderedDict( + [ + ("input_ids", {0: "batch", 1: "encoder_sequence"}), + ("attention_mask", {0: "batch", 1: "encoder_sequence"}), + ("decoder_input_ids", {0: "batch", 1: "decoder_sequence"}), + ("decoder_attention_mask", {0: "batch", 1: "decoder_sequence"}), + ] + ) + + return common_inputs + + @property + def outputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task in ["default", "seq2seq-lm"]: + common_outputs = super().outputs + else: + common_outputs = super(OnnxConfigWithPast, self).outputs + if self.use_past: + num_encoder_layers, _ = self.num_layers + for i in range(num_encoder_layers): + common_outputs[f"present.{i}.key"] = {0: "batch", 2: "past_sequence + sequence"} + common_outputs[f"present.{i}.value"] = {0: "batch", 2: "past_sequence + sequence"} + return common_outputs + + def _generate_dummy_inputs_for_default_and_seq2seq_lm( + self, + tokenizer: PreTrainedTokenizer, + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + encoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( + tokenizer, batch_size, seq_length, is_pair, framework + ) + + # Generate decoder inputs + decoder_seq_length = seq_length if not self.use_past else 1 + decoder_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( + tokenizer, batch_size, decoder_seq_length, is_pair, framework + ) + decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} + common_inputs = dict(**encoder_inputs, **decoder_inputs) + + if self.use_past: + if not is_torch_available(): + raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed.") + else: + import torch + batch, encoder_seq_length = common_inputs["input_ids"].shape + decoder_seq_length = common_inputs["decoder_input_ids"].shape[1] + num_encoder_attention_heads, num_decoder_attention_heads = self.num_attention_heads + encoder_shape = ( + batch, + num_encoder_attention_heads, + encoder_seq_length, + self._config.hidden_size // num_encoder_attention_heads, + ) + decoder_past_length = decoder_seq_length + 3 + decoder_shape = ( + batch, + num_decoder_attention_heads, + decoder_past_length, + self._config.hidden_size // num_decoder_attention_heads, + ) + + common_inputs["decoder_attention_mask"] = torch.cat( + [common_inputs["decoder_attention_mask"], torch.ones(batch, decoder_past_length)], dim=1 + ) + + common_inputs["past_key_values"] = [] + # If the number of encoder and decoder layers are present in the model configuration, both are considered + num_encoder_layers, num_decoder_layers = self.num_layers + min_num_layers = min(num_encoder_layers, num_decoder_layers) + max_num_layers = max(num_encoder_layers, num_decoder_layers) - min_num_layers + remaining_side_name = "encoder" if num_encoder_layers > num_decoder_layers else "decoder" + + for _ in range(min_num_layers): + common_inputs["past_key_values"].append( + ( + torch.zeros(decoder_shape), + torch.zeros(decoder_shape), + torch.zeros(encoder_shape), + torch.zeros(encoder_shape), + ) + ) + # TODO: test this. + shape = encoder_shape if remaining_side_name == "encoder" else decoder_shape + for _ in range(min_num_layers, max_num_layers): + common_inputs["past_key_values"].append((torch.zeros(shape), torch.zeros(shape))) + return common_inputs + + def _generate_dummy_inputs_for_causal_lm( + self, + tokenizer: PreTrainedTokenizer, + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( + tokenizer, batch_size, seq_length, is_pair, framework + ) + + if self.use_past: + if not is_torch_available(): + raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed.") + else: + import torch + batch, seqlen = common_inputs["input_ids"].shape + # Not using the same length for past_key_values + past_key_values_length = seqlen + 2 + num_encoder_layers, _ = self.num_layers + num_encoder_attention_heads, _ = self.num_attention_heads + past_shape = ( + batch, + num_encoder_attention_heads, + past_key_values_length, + self._config.hidden_size // num_encoder_attention_heads, + ) + + mask_dtype = common_inputs["attention_mask"].dtype + common_inputs["attention_mask"] = torch.cat( + [common_inputs["attention_mask"], torch.ones(batch, past_key_values_length, dtype=mask_dtype)], dim=1 + ) + common_inputs["past_key_values"] = [ + (torch.zeros(past_shape), torch.zeros(past_shape)) for _ in range(num_encoder_layers) + ] + return common_inputs + + def _generate_dummy_inputs_for_sequence_classification_and_question_answering( + self, + tokenizer: PreTrainedTokenizer, + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + # Copied from OnnxConfig.generate_dummy_inputs + # Did not use super(OnnxConfigWithPast, self).generate_dummy_inputs for code clarity. + # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX + batch_size = compute_effective_axis_dimension( + batch_size, fixed_dimension=OnnxConfig.default_fixed_batch, num_token_to_add=0 + ) + + # If dynamic axis (-1) we forward with a fixed dimension of 8 tokens to avoid optimizations made by ONNX + token_to_add = tokenizer.num_special_tokens_to_add(is_pair) + seq_length = compute_effective_axis_dimension( + seq_length, fixed_dimension=OnnxConfig.default_fixed_sequence, num_token_to_add=token_to_add + ) + + # Generate dummy inputs according to compute batch and sequence + dummy_input = [" ".join([tokenizer.unk_token]) * seq_length] * batch_size + common_inputs = dict(tokenizer(dummy_input, return_tensors=framework)) + return common_inputs + + def generate_dummy_inputs( + self, + tokenizer: PreTrainedTokenizer, + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + if self.task in ["default", "seq2seq-lm"]: + common_inputs = self._generate_dummy_inputs_for_default_and_seq2seq_lm( + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + ) + + elif self.task == "causal-lm": + common_inputs = self._generate_dummy_inputs_for_causal_lm( + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + ) + else: + common_inputs = self._generate_dummy_inputs_for_sequence_classification_and_question_answering( + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + ) + + return common_inputs + + def _flatten_past_key_values_(self, flattened_output, name, idx, t): + if self.task in ["default", "seq2seq-lm"]: + flattened_output = super()._flatten_past_key_values_(flattened_output, name, idx, t) + else: + flattened_output = super(OnnxSeq2SeqConfigWithPast, self)._flatten_past_key_values_( + flattened_output, name, idx, t + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_bart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_bart.py new file mode 100644 index 0000000000000000000000000000000000000000..c1da4eb288e838e1da554444a477854cdf5941f9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_bart.py @@ -0,0 +1,1940 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch BART model.""" +import copy +import math +import random +import warnings +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPastAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + Seq2SeqLMOutput, + Seq2SeqModelOutput, + Seq2SeqQuestionAnsweringModelOutput, + Seq2SeqSequenceClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...utils import ( + add_code_sample_docstrings, + add_end_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_bart import BartConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/bart-base" +_CONFIG_FOR_DOC = "BartConfig" + +# Base model docstring +_EXPECTED_OUTPUT_SHAPE = [1, 8, 768] + +# SequenceClassification docstring +_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION = "valhalla/bart-large-sst2" +_SEQ_CLASS_EXPECTED_LOSS = 0.0 +_SEQ_CLASS_EXPECTED_OUTPUT = "'POSITIVE'" + +# QuestionAsnwering docstring +_CHECKPOINT_FOR_QA = "valhalla/bart-large-finetuned-squadv1" +_QA_EXPECTED_LOSS = 0.59 +_QA_EXPECTED_OUTPUT = "' nice puppet'" + + +BART_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/bart-large", + # see all BART models at https://huggingface.co/models?filter=bart +] + + +def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): + """ + Shift input ids one token to the right. + """ + shifted_input_ids = input_ids.new_zeros(input_ids.shape) + shifted_input_ids[:, 1:] = input_ids[:, :-1].clone() + shifted_input_ids[:, 0] = decoder_start_token_id + + if pad_token_id is None: + raise ValueError("self.model.config.pad_token_id has to be defined.") + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id) + + return shifted_input_ids + + +def _make_causal_mask( + input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0 +): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz, tgt_len = input_ids_shape + mask = torch.full((tgt_len, tgt_len), torch.tensor(torch.finfo(dtype).min, device=device), device=device) + mask_cond = torch.arange(mask.size(-1), device=device) + mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0) + mask = mask.to(dtype) + + if past_key_values_length > 0: + mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1) + return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length) + + +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + bsz, src_len = mask.size() + tgt_len = tgt_len if tgt_len is not None else src_len + + expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min) + + +class BartLearnedPositionalEmbedding(nn.Embedding): + """ + This module learns positional embeddings up to a fixed maximum size. + """ + + def __init__(self, num_embeddings: int, embedding_dim: int): + # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 + # and adjust num_embeddings appropriately. Other models don't have this hack + self.offset = 2 + super().__init__(num_embeddings + self.offset, embedding_dim) + + def forward(self, input_ids: torch.Tensor, past_key_values_length: int = 0): + """`input_ids' shape is expected to be [bsz x seqlen].""" + + bsz, seq_len = input_ids.shape[:2] + positions = torch.arange( + past_key_values_length, past_key_values_length + seq_len, dtype=torch.long, device=self.weight.device + ).expand(bsz, -1) + + return super().forward(positions + self.offset) + + +class BartAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states: torch.Tensor, + key_value_states: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + + bsz, tgt_len, _ = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + # `past_key_value[0].shape[2] == key_value_states.shape[1]` + # is checking that the `sequence_length` of the `past_key_value` is the same as + # the provided `key_value_states` to support prefix tuning + if ( + is_cross_attention + and past_key_value is not None + and past_key_value[0].shape[2] == key_value_states.shape[1] + ): + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = torch.cat([past_key_value[0], key_states], dim=2) + value_states = torch.cat([past_key_value[1], value_states], dim=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.reshape(*proj_shape) + value_states = value_states.reshape(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if layer_head_mask is not None: + if layer_head_mask.size() != (self.num_heads,): + raise ValueError( + f"Head mask for a single layer should be of size {(self.num_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to be reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz * self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + + # Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be + # partitioned across GPUs when using tensor-parallelism. + attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped, past_key_value + + +class BartEncoderLayer(nn.Module): + def __init__(self, config: BartConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = BartAttention( + embed_dim=self.embed_dim, + num_heads=config.encoder_attention_heads, + dropout=config.attention_dropout, + ) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.FloatTensor, + attention_mask: torch.FloatTensor, + layer_head_mask: torch.FloatTensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.FloatTensor, Optional[torch.FloatTensor]]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states, attn_weights, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + if hidden_states.dtype == torch.float16 and ( + torch.isinf(hidden_states).any() or torch.isnan(hidden_states).any() + ): + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class BartDecoderLayer(nn.Module): + def __init__(self, config: BartConfig): + super().__init__() + self.embed_dim = config.d_model + + self.self_attn = BartAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.encoder_attn = BartAttention( + self.embed_dim, + config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim) + self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + cross_attn_layer_head_mask: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + output_attentions: Optional[bool] = False, + use_cache: Optional[bool] = True, + ) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(batch, seq_len, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of + size `(decoder_attention_heads,)`. + past_key_value (`Tuple(torch.FloatTensor)`): cached past key and value projection states + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + if use_cache: + outputs += (present_key_value,) + + return outputs + + +class BartClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__( + self, + input_dim: int, + inner_dim: int, + num_classes: int, + pooler_dropout: float, + ): + super().__init__() + self.dense = nn.Linear(input_dim, inner_dim) + self.dropout = nn.Dropout(p=pooler_dropout) + self.out_proj = nn.Linear(inner_dim, num_classes) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dropout(hidden_states) + hidden_states = self.dense(hidden_states) + hidden_states = torch.tanh(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +class BartPretrainedModel(PreTrainedModel): + config_class = BartConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_unexpected = [r"encoder.version", r"decoder.version"] + _no_split_modules = [r"BartEncoderLayer", r"BartDecoderLayer"] + + def _init_weights(self, module): + std = self.config.init_std + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (BartDecoder, BartEncoder)): + module.gradient_checkpointing = value + + @property + def dummy_inputs(self): + pad_token = self.config.pad_token_id + input_ids = torch.tensor([[0, 6, 10, 4, 2], [0, 8, 12, 2, pad_token]], device=self.device) + dummy_inputs = { + "attention_mask": input_ids.ne(pad_token), + "input_ids": input_ids, + } + return dummy_inputs + + +class PretrainedBartModel(BartPretrainedModel): + def __init_subclass__(self): + warnings.warn( + "The class `PretrainedBartModel` has been depreciated, please use `BartPretrainedModel` instead.", + FutureWarning, + ) + + +BART_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`BartConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +BART_GENERATION_EXAMPLE = r""" + Summarization example: + + ```python + >>> from transformers import AutoTokenizer, BartForConditionalGeneration + + >>> model = BartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") + + >>> ARTICLE_TO_SUMMARIZE = ( + ... "PG&E stated it scheduled the blackouts in response to forecasts for high winds " + ... "amid dry conditions. The aim is to reduce the risk of wildfires. Nearly 800 thousand customers were " + ... "scheduled to be affected by the shutoffs which were expected to last through at least midday tomorrow." + ... ) + >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="pt") + + >>> # Generate Summary + >>> summary_ids = model.generate(inputs["input_ids"], num_beams=2, min_length=0, max_length=20) + >>> tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] + 'PG&E scheduled the blackouts in response to forecasts for high winds amid dry conditions' + ``` + + Mask filling example: + + ```python + >>> from transformers import AutoTokenizer, BartForConditionalGeneration + + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-base") + >>> model = BartForConditionalGeneration.from_pretrained("facebook/bart-base") + + >>> TXT = "My friends are but they eat too many carbs." + >>> input_ids = tokenizer([TXT], return_tensors="pt")["input_ids"] + >>> logits = model(input_ids).logits + + >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero().item() + >>> probs = logits[0, masked_index].softmax(dim=0) + >>> values, predictions = probs.topk(5) + + >>> tokenizer.decode(predictions).split() + ['not', 'good', 'healthy', 'great', 'very'] + ``` +""" + +BART_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values` + is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`). + + For translation and summarization training, `decoder_input_ids` should be provided. If no + `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right + for denoising pre-training following the paper. + decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + + If you want to change padding behavior, you should read [`modeling_bart._prepare_decoder_attention_mask`] + and modify to your needs. See diagram 1 in [the paper](https://arxiv.org/abs/1910.13461) for more + information on the default strategy. + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + decoder_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules in the decoder. Mask values selected in `[0, + 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape + `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention + blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`torch.FloatTensor` of shape + `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing `input_ids` you + can choose to directly pass an embedded representation. This is useful if you want more control over how to + convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. + decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded + representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be + input (see `past_key_values`). This is useful if you want more control over how to convert + `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. + + If `decoder_input_ids` and `decoder_inputs_embeds` are both unset, `decoder_inputs_embeds` takes the value + of `inputs_embeds`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class BartEncoder(BartPretrainedModel): + """ + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`BartEncoderLayer`]. + + Args: + config: BartConfig + embed_tokens (nn.Embedding): output embedding + """ + + def __init__(self, config: BartConfig, embed_tokens: Optional[nn.Embedding] = None): + super().__init__(config) + + self.dropout = config.dropout + self.layerdrop = config.encoder_layerdrop + + embed_dim = config.d_model + self.padding_idx = config.pad_token_id + self.max_source_positions = config.max_position_embeddings + self.embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0 + + self.embed_tokens = nn.Embedding(config.vocab_size, embed_dim, self.padding_idx) + + if embed_tokens is not None: + self.embed_tokens.weight = embed_tokens.weight + + self.embed_positions = BartLearnedPositionalEmbedding( + config.max_position_embeddings, + embed_dim, + ) + self.layers = nn.ModuleList([BartEncoderLayer(config) for _ in range(config.encoder_layers)]) + self.layernorm_embedding = nn.LayerNorm(embed_dim) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embed_tokens + + def set_input_embeddings(self, value): + self.embed_tokens = value + + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input = input_ids + input_ids = input_ids.view(-1, input_ids.shape[-1]) + elif inputs_embeds is not None: + input = inputs_embeds[:, :, -1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + embed_pos = self.embed_positions(input) + embed_pos = embed_pos.to(inputs_embeds.device) + + hidden_states = inputs_embeds + embed_pos + hidden_states = self.layernorm_embedding(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + # expand attention_mask + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _expand_mask(attention_mask, inputs_embeds.dtype) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + # check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + if head_mask.size()[0] != (len(self.layers)): + raise ValueError( + f"The head_mask should be specified for {len(self.layers)} layers, but it is for" + f" {head_mask.size()[0]}." + ) + + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): # skip the layer + layer_outputs = (None, None) + else: + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + attention_mask, + (head_mask[idx] if head_mask is not None else None), + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class BartDecoder(BartPretrainedModel): + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`BartDecoderLayer`] + + Args: + config: BartConfig + embed_tokens (nn.Embedding): output embedding + """ + + def __init__(self, config: BartConfig, embed_tokens: Optional[nn.Embedding] = None): + super().__init__(config) + self.dropout = config.dropout + self.layerdrop = config.decoder_layerdrop + self.padding_idx = config.pad_token_id + self.max_target_positions = config.max_position_embeddings + self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 + + self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model, self.padding_idx) + + if embed_tokens is not None: + self.embed_tokens.weight = embed_tokens.weight + + self.embed_positions = BartLearnedPositionalEmbedding( + config.max_position_embeddings, + config.d_model, + ) + self.layers = nn.ModuleList([BartDecoderLayer(config) for _ in range(config.decoder_layers)]) + self.layernorm_embedding = nn.LayerNorm(config.d_model) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embed_tokens + + def set_input_embeddings(self, value): + self.embed_tokens = value + + def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length): + # create causal mask + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + combined_attention_mask = None + if input_shape[-1] > 1: + combined_attention_mask = _make_causal_mask( + input_shape, + inputs_embeds.dtype, + device=inputs_embeds.device, + past_key_values_length=past_key_values_length, + ) + + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]).to( + inputs_embeds.device + ) + combined_attention_mask = ( + expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask + ) + + return combined_attention_mask + + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPastAndCrossAttentions]: + r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values + selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules in the decoder to avoid performing + cross-attention on hidden heads. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of + shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of + shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the + cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those + that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of + all `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`torch.FloatTensor` of + shape `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing + `input_ids` you can choose to directly pass an embedded representation. This is useful if you want more + control over how to convert `input_ids` indices into associated vectors than the model's internal + embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") + elif input_ids is not None: + input = input_ids + input_shape = input.shape + input_ids = input_ids.view(-1, input_shape[-1]) + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + input = inputs_embeds[:, :, -1] + else: + raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input) * self.embed_scale + + attention_mask = self._prepare_decoder_attention_mask( + attention_mask, input_shape, inputs_embeds, past_key_values_length + ) + + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _expand_mask(encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) + + # embed positions + positions = self.embed_positions(input, past_key_values_length) + positions = positions.to(inputs_embeds.device) + + hidden_states = inputs_embeds + positions + hidden_states = self.layernorm_embedding(hidden_states) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + next_decoder_cache = () if use_cache else None + + # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired + for attn_mask, mask_name in zip([head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]): + if attn_mask is not None: + if attn_mask.size()[0] != (len(self.layers)): + raise ValueError( + f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for" + f" {head_mask.size()[0]}." + ) + + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + # None for past_key_value + return module(*inputs, output_attentions, use_cache) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + head_mask[idx] if head_mask is not None else None, + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=( + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None + ), + past_key_value=past_key_value, + output_attentions=output_attentions, + use_cache=use_cache, + ) + hidden_states = layer_outputs[0] + + if use_cache: + next_decoder_cache += (layer_outputs[3 if output_attentions else 1],) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + next_cache = next_decoder_cache if use_cache else None + if not return_dict: + return tuple( + v + for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_cache, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + "The bare BART Model outputting raw hidden-states without any specific head on top.", + BART_START_DOCSTRING, +) +class BartModel(BartPretrainedModel): + _keys_to_ignore_on_load_missing = ["encoder.embed_tokens.weight", "decoder.embed_tokens.weight"] + + def __init__(self, config: BartConfig): + super().__init__(config) + + padding_idx, vocab_size = config.pad_token_id, config.vocab_size + self.shared = nn.Embedding(vocab_size, config.d_model, padding_idx) + + self.encoder = BartEncoder(config, self.shared) + self.decoder = BartDecoder(config, self.shared) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.shared + + def set_input_embeddings(self, value): + self.shared = value + self.encoder.embed_tokens = self.shared + self.decoder.embed_tokens = self.shared + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=Seq2SeqModelOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[List[torch.FloatTensor]] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + decoder_inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Seq2SeqModelOutput]: + # different to other models, Bart automatically creates decoder_input_ids from + # input_ids if no decoder_input_ids are provided + if decoder_input_ids is None and decoder_inputs_embeds is None: + if input_ids is None: + raise ValueError( + "If no `decoder_input_ids` or `decoder_inputs_embeds` are " + "passed, `input_ids` cannot be `None`. Please pass either " + "`input_ids` or `decoder_input_ids` or `decoder_inputs_embeds`." + ) + + decoder_input_ids = shift_tokens_right( + input_ids, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn) + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=attention_mask, + head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return Seq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + past_key_values=decoder_outputs.past_key_values, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + "The BART Model with a language modeling head. Can be used for summarization.", BART_START_DOCSTRING +) +class BartForConditionalGeneration(BartPretrainedModel): + base_model_prefix = "model" + _keys_to_ignore_on_load_missing = [ + r"final_logits_bias", + r"lm_head.weight", + "encoder.embed_tokens.weight", + "decoder.embed_tokens.weight", + ] + + def __init__(self, config: BartConfig): + super().__init__(config) + self.model = BartModel(config) + self.register_buffer("final_logits_bias", torch.zeros((1, self.model.shared.num_embeddings))) + self.lm_head = nn.Linear(config.d_model, self.model.shared.num_embeddings, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_encoder(self): + return self.model.get_encoder() + + def get_decoder(self): + return self.model.get_decoder() + + def resize_token_embeddings(self, new_num_tokens: int) -> nn.Embedding: + new_embeddings = super().resize_token_embeddings(new_num_tokens) + self._resize_final_logits_bias(new_num_tokens) + return new_embeddings + + def _resize_final_logits_bias(self, new_num_tokens: int) -> None: + old_num_tokens = self.final_logits_bias.shape[-1] + if new_num_tokens <= old_num_tokens: + new_bias = self.final_logits_bias[:, :new_num_tokens] + else: + extra_bias = torch.zeros((1, new_num_tokens - old_num_tokens), device=self.final_logits_bias.device) + new_bias = torch.cat([self.final_logits_bias, extra_bias], dim=1) + self.register_buffer("final_logits_bias", new_bias) + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=Seq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + @add_end_docstrings(BART_GENERATION_EXAMPLE) + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[List[torch.FloatTensor]] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + decoder_inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Seq2SeqLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Returns: + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if labels is not None: + if use_cache: + logger.warning("The `use_cache` argument is changed to `False` since `labels` is provided.") + use_cache = False + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + outputs = self.model( + input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + encoder_outputs=encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + lm_logits = self.lm_head(outputs[0]) + lm_logits = lm_logits + self.final_logits_bias.to(lm_logits.device) + + masked_lm_loss = None + if labels is not None: + labels = labels.to(lm_logits.device) + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(lm_logits.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return Seq2SeqLMOutput( + loss=masked_lm_loss, + logits=lm_logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + past_key_values=None, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, + use_cache=None, + encoder_outputs=None, + **kwargs, + ): + # cut decoder_input_ids if past_key_values is used + if past_key_values is not None: + decoder_input_ids = decoder_input_ids[:, -1:] + + return { + "input_ids": None, # encoder_outputs is defined. input_ids not needed + "encoder_outputs": encoder_outputs, + "past_key_values": past_key_values, + "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, + "use_cache": use_cache, # change this to avoid caching (presumably for debugging) + } + + def prepare_decoder_input_ids_from_labels(self, labels: torch.Tensor): + return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) + + @staticmethod + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + # cached cross_attention states don't have to be reordered -> they are always the same + reordered_past += ( + tuple(past_state.index_select(0, beam_idx) for past_state in layer_past[:2]) + layer_past[2:], + ) + return reordered_past + + +@add_start_docstrings( + """ + Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE + tasks. + """, + BART_START_DOCSTRING, +) +class BartForSequenceClassification(BartPretrainedModel): + _keys_to_ignore_on_load_missing = ["encoder.embed_tokens.weight", "decoder.embed_tokens.weight"] + + def __init__(self, config: BartConfig, **kwargs): + super().__init__(config, **kwargs) + self.model = BartModel(config) + self.classification_head = BartClassificationHead( + config.d_model, + config.d_model, + config.num_labels, + config.classifier_dropout, + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_SEQUENCE_CLASSIFICATION, + output_type=Seq2SeqSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_SEQ_CLASS_EXPECTED_OUTPUT, + expected_loss=_SEQ_CLASS_EXPECTED_LOSS, + ) + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + decoder_inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Seq2SeqSequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + if input_ids is None and inputs_embeds is not None: + raise NotImplementedError( + f"Passing input embeddings is currently not supported for {self.__class__.__name__}" + ) + + outputs = self.model( + input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = outputs[0] # last hidden state + + eos_mask = input_ids.eq(self.config.eos_token_id).to(hidden_states.device) + + if len(torch.unique_consecutive(eos_mask.sum(1))) > 1: + raise ValueError("All examples must have the same number of tokens.") + sentence_representation = hidden_states[eos_mask, :].view(hidden_states.size(0), -1, hidden_states.size(-1))[ + :, -1, : + ] + logits = self.classification_head(sentence_representation) + + loss = None + if labels is not None: + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.config.num_labels == 1: + self.config.problem_type = "regression" + elif self.config.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.config.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return Seq2SeqSequenceClassifierOutput( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings( + """ + BART Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layer on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + BART_START_DOCSTRING, +) +class BartForQuestionAnswering(BartPretrainedModel): + _keys_to_ignore_on_load_missing = ["encoder.embed_tokens.weight", "decoder.embed_tokens.weight"] + + def __init__(self, config): + super().__init__(config) + + config.num_labels = 2 + self.num_labels = config.num_labels + + self.model = BartModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_QA, + output_type=Seq2SeqQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + expected_loss=_QA_EXPECTED_LOSS, + expected_output=_QA_EXPECTED_OUTPUT, + ) + def forward( + self, + input_ids: torch.Tensor = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[List[torch.FloatTensor]] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + decoder_inputs_embeds: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Seq2SeqQuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (*sequence_length*). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (*sequence_length*). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if start_positions is not None and end_positions is not None: + use_cache = False + + outputs = self.model( + input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = ( + start_logits, + end_logits, + ) + outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return Seq2SeqQuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +class BartDecoderWrapper(BartPretrainedModel): + """ + This wrapper class is a helper class to correctly load pretrained checkpoints when the causal language model is + used in combination with the [`EncoderDecoderModel`] framework. + """ + + def __init__(self, config): + super().__init__(config) + self.decoder = BartDecoder(config) + + def forward(self, *args, **kwargs): + return self.decoder(*args, **kwargs) + + +@add_start_docstrings( + """ + BART decoder with with a language modeling head on top (linear layer with weights tied to the input embeddings). + """, + BART_START_DOCSTRING, +) +class BartForCausalLM(BartPretrainedModel): + _keys_to_ignore_on_load_missing = ["lm_head.weight"] + + def __init__(self, config): + config = copy.deepcopy(config) + config.is_decoder = True + config.is_encoder_decoder = False + super().__init__(config) + self.model = BartDecoderWrapper(config) + + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.model.decoder.embed_tokens + + def set_input_embeddings(self, value): + self.model.decoder.embed_tokens = value + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def set_decoder(self, decoder): + self.model.decoder = decoder + + def get_decoder(self): + return self.model.decoder + + @replace_return_docstrings(output_type=CausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, CausalLMOutputWithCrossAttentions]: + r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + if the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used + in the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of + shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of + shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. The two additional + tensors are only required when the model is used as a decoder in a Sequence to Sequence model. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the + cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those + that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of + all `decoder_input_ids` of shape `(batch_size, sequence_length)`. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, BartForCausalLM + + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-base") + >>> model = BartForCausalLM.from_pretrained("facebook/bart-base", add_cross_attention=False) + >>> assert model.config.is_decoder, f"{model.__class__} has to be configured as a decoder." + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> logits = outputs.logits + >>> expected_shape = [1, inputs.input_ids.shape[-1], model.config.vocab_size] + >>> list(logits.shape) == expected_shape + True + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs = self.model.decoder( + input_ids=input_ids, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + head_mask=head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + logits = self.lm_head(outputs[0]) + + loss = None + if labels is not None: + labels = labels.to(logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return (loss,) + output if loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + def prepare_inputs_for_generation( + self, input_ids, past_key_values=None, attention_mask=None, use_cache=None, **kwargs + ): + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_ids.shape) + + if past_key_values: + input_ids = input_ids[:, -1:] + # first step, decoder_cached_states are empty + return { + "input_ids": input_ids, # encoder_outputs is defined. input_ids not needed + "attention_mask": attention_mask, + "past_key_values": past_key_values, + "use_cache": use_cache, + } + + @staticmethod + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_flax_bart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_flax_bart.py new file mode 100644 index 0000000000000000000000000000000000000000..ac292cc77707db6dd3430d7e4d037ec1d0a90407 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_flax_bart.py @@ -0,0 +1,1996 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The Google Flax Team Authors And The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Flax Bart model.""" + +import math +import random +from functools import partial +from typing import Callable, Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen import combine_masks, make_causal_mask +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax +from jax.random import PRNGKey + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutput, + FlaxBaseModelOutputWithPastAndCrossAttentions, + FlaxCausalLMOutputWithCrossAttentions, + FlaxSeq2SeqLMOutput, + FlaxSeq2SeqModelOutput, + FlaxSeq2SeqQuestionAnsweringModelOutput, + FlaxSeq2SeqSequenceClassifierOutput, +) +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_call_sample_docstring, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_bart import BartConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/bart-base" +_CONFIG_FOR_DOC = "BartConfig" + + +BART_START_DOCSTRING = r""" + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a Flax Linen + [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a + regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`BartConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + +BART_INPUTS_DOCSTRING = r""" + Args: + input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + For translation and summarization training, `decoder_input_ids` should be provided. If no + `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right + for denoising pre-training following the paper. + decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + + If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the + paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +BART_ENCODE_INPUTS_DOCSTRING = r""" + Args: + input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +BART_DECODE_INPUTS_DOCSTRING = r""" + Args: + decoder_input_ids (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + For translation and summarization training, `decoder_input_ids` should be provided. If no + `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right + for denoising pre-training following the paper. + encoder_outputs (`tuple(tuple(jnp.ndarray)`): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + encoder_attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_attention_mask (`jnp.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + + If you want to change padding behavior, you should modify to your needs. See diagram 1 in [the + paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + past_key_values (`Dict[str, np.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): + Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast + auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +def shift_tokens_right(input_ids: np.array, pad_token_id: int, decoder_start_token_id: int) -> np.ndarray: + """ + Shift input ids one token to the right. + """ + shifted_input_ids = np.zeros_like(input_ids) + shifted_input_ids[:, 1:] = input_ids[:, :-1] + shifted_input_ids[:, 0] = decoder_start_token_id + + shifted_input_ids = np.where(shifted_input_ids == -100, pad_token_id, shifted_input_ids) + return shifted_input_ids + + +class FlaxBartAttention(nn.Module): + config: BartConfig + embed_dim: int + num_heads: int + dropout: float = 0.0 + causal: bool = False + bias: bool = True + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self) -> None: + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {self.num_heads})." + ) + + dense = partial( + nn.Dense, + self.embed_dim, + use_bias=self.bias, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() + self.out_proj = dense() + + self.dropout_layer = nn.Dropout(rate=self.dropout) + + if self.causal: + self.causal_mask = make_causal_mask( + jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" + ) + + def _split_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) + + def _merge_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) + + @nn.compact + def _concatenate_to_cache(self, key, value, query, attention_mask): + """ + This function takes projected key, value states from a single input token and concatenates the states to cached + states from previous steps. This function is slighly adapted from the official Flax repository: + https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 + """ + # detect if we're initializing by absence of existing cache data. + is_initialized = self.has_variable("cache", "cached_key") + cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) + cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) + cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) + + if is_initialized: + *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape + # update key, value caches with our new 1d spatial slices + cur_index = cache_index.value + indices = (0,) * len(batch_dims) + (cur_index, 0, 0) + key = lax.dynamic_update_slice(cached_key.value, key, indices) + value = lax.dynamic_update_slice(cached_value.value, value, indices) + cached_key.value = key + cached_value.value = value + num_updated_cache_vectors = query.shape[1] + cache_index.value = cache_index.value + num_updated_cache_vectors + # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. + pad_mask = jnp.broadcast_to( + jnp.arange(max_length) < cur_index + num_updated_cache_vectors, + tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), + ) + attention_mask = combine_masks(pad_mask, attention_mask) + return key, value, attention_mask + + def __call__( + self, + hidden_states: jnp.ndarray, + key_value_states: Optional[jnp.ndarray] = None, + attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + batch_size = hidden_states.shape[0] + + # get query proj + query_states = self.q_proj(hidden_states) + # get key, value proj + if is_cross_attention: + # cross_attentions + key_states = self.k_proj(key_value_states) + value_states = self.v_proj(key_value_states) + else: + # self_attention + key_states = self.k_proj(hidden_states) + value_states = self.v_proj(hidden_states) + + query_states = self._split_heads(query_states) + key_states = self._split_heads(key_states) + value_states = self._split_heads(value_states) + + # handle cache prepare causal attention mask + if self.causal: + query_length, key_length = query_states.shape[1], key_states.shape[1] + if self.has_variable("cache", "cached_key"): + mask_shift = self.variables["cache"]["cache_index"] + max_decoder_length = self.variables["cache"]["cached_key"].shape[1] + causal_mask = lax.dynamic_slice( + self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) + ) + else: + causal_mask = self.causal_mask[:, :, :query_length, :key_length] + causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) + + # combine masks if needed + if attention_mask is not None and self.causal: + attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) + attention_mask = combine_masks(attention_mask, causal_mask) + elif self.causal: + attention_mask = causal_mask + elif attention_mask is not None: + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + + # During fast autoregressive decoding, we feed one position at a time, + # and cache the keys and values step by step. + if self.causal and (self.has_variable("cache", "cached_key") or init_cache): + key_states, value_states, attention_mask = self._concatenate_to_cache( + key_states, value_states, query_states, attention_mask + ) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.dropout > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.dropout, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = self._merge_heads(attn_output) + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights + + +class FlaxBartEncoderLayer(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.embed_dim = self.config.d_model + self.self_attn = FlaxBartAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.encoder_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + self.activation_fn = ACT2FN[self.config.activation_function] + self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) + self.fc1 = nn.Dense( + self.config.encoder_ffn_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.fc2 = nn.Dense( + self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + hidden_states: jnp.ndarray, + attention_mask: jnp.ndarray, + output_attentions: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + residual = hidden_states + hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) + + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class FlaxBartEncoderLayerCollection(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxBartEncoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.encoder_layers) + ] + self.layerdrop = self.config.encoder_layerdrop + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + + for encoder_layer in self.layers: + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if not deterministic and (dropout_probability < self.layerdrop): # skip the layer + layer_outputs = (None, None) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + output_attentions, + deterministic, + ) + hidden_states = layer_outputs[0] + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states, all_hidden_states, all_attentions) + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxBartDecoderLayer(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.embed_dim = self.config.d_model + self.self_attn = FlaxBartAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.decoder_attention_heads, + dropout=self.config.attention_dropout, + causal=True, + dtype=self.dtype, + ) + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + self.activation_fn = ACT2FN[self.config.activation_function] + self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) + + self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.encoder_attn = FlaxBartAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.decoder_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.fc1 = nn.Dense( + self.config.decoder_ffn_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.fc2 = nn.Dense( + self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + hidden_states: jnp.ndarray, + attention_mask: jnp.ndarray, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + residual = hidden_states + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Cross-Attention Block + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +class FlaxBartDecoderLayerCollection(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxBartDecoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.decoder_layers) + ] + self.layerdrop = self.config.decoder_layerdrop + + def __call__( + self, + hidden_states, + attention_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + deterministic: bool = True, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + + for decoder_layer in self.layers: + if output_hidden_states: + all_hidden_states += (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if not deterministic and (dropout_probability < self.layerdrop): + layer_outputs = (None, None, None) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + init_cache=init_cache, + output_attentions=output_attentions, + deterministic=deterministic, + ) + + hidden_states = layer_outputs[0] + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +class FlaxBartClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + config: BartConfig + inner_dim: int + num_classes: int + pooler_dropout: float + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.dense = nn.Dense( + self.inner_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.dropout = nn.Dropout(rate=self.pooler_dropout) + self.out_proj = nn.Dense( + self.num_classes, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + def __call__(self, hidden_states: jnp.ndarray, deterministic: bool): + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.dense(hidden_states) + hidden_states = jnp.tanh(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +class FlaxBartEncoder(nn.Module): + config: BartConfig + embed_tokens: nn.Embed + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + + embed_dim = self.config.d_model + self.padding_idx = self.config.pad_token_id + self.max_source_positions = self.config.max_position_embeddings + self.embed_scale = math.sqrt(embed_dim) if self.config.scale_embedding else 1.0 + + # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 + # and adjust num_embeddings appropriately. Other models don't have this hack + self.offset = 2 + self.embed_positions = nn.Embed( + self.config.max_position_embeddings + self.offset, + embed_dim, + embedding_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + self.layers = FlaxBartEncoderLayerCollection(self.config, self.dtype) + self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + input_shape = input_ids.shape + input_ids = input_ids.reshape(-1, input_shape[-1]) + + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + embed_pos = self.embed_positions(position_ids + self.offset) + + hidden_states = inputs_embeds + embed_pos + hidden_states = self.layernorm_embedding(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return outputs + + return FlaxBaseModelOutput( + last_hidden_state=outputs.last_hidden_state, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class FlaxBartDecoder(nn.Module): + config: BartConfig + embed_tokens: nn.Embed + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + + embed_dim = self.config.d_model + self.padding_idx = self.config.pad_token_id + self.max_target_positions = self.config.max_position_embeddings + self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 + + # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 + # and adjust num_embeddings appropriately. Other models don't have this hack + self.offset = 2 + self.embed_positions = nn.Embed( + self.config.max_position_embeddings + self.offset, + embed_dim, + embedding_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + + self.layers = FlaxBartDecoderLayerCollection(self.config, self.dtype) + self.layernorm_embedding = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + input_shape = input_ids.shape + input_ids = input_ids.reshape(-1, input_shape[-1]) + + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + # embed positions + positions = self.embed_positions(position_ids + self.offset) + + hidden_states = inputs_embeds + positions + hidden_states = self.layernorm_embedding(hidden_states) + + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + deterministic=deterministic, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return outputs + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=outputs.last_hidden_state, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +class FlaxBartModule(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.shared = nn.Embed( + self.config.vocab_size, + self.config.d_model, + embedding_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + + self.encoder = FlaxBartEncoder(self.config, dtype=self.dtype, embed_tokens=self.shared) + self.decoder = FlaxBartDecoder(self.config, dtype=self.dtype, embed_tokens=self.shared) + + def _get_encoder_module(self): + return self.encoder + + def _get_decoder_module(self): + return self.decoder + + def __call__( + self, + input_ids, + attention_mask, + decoder_input_ids, + decoder_attention_mask, + position_ids, + decoder_position_ids, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + encoder_outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return FlaxSeq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +class FlaxBartPreTrainedModel(FlaxPreTrainedModel): + config_class = BartConfig + base_model_prefix: str = "model" + module_class: nn.Module = None + + def __init__( + self, + config: BartConfig, + input_shape: Tuple[int] = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + # make sure initialization pass will work for FlaxBartForSequenceClassificationModule + input_ids = input_ids.at[(..., -1)].set(self.config.eos_token_id) + attention_mask = jnp.ones_like(input_ids) + decoder_input_ids = input_ids + decoder_attention_mask = jnp.ones_like(input_ids) + + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init( + rngs, + input_ids, + attention_mask, + decoder_input_ids, + decoder_attention_mask, + position_ids, + decoder_position_ids, + )["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + def init_cache(self, batch_size, max_length, encoder_outputs): + r""" + Args: + batch_size (`int`): + batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. + max_length (`int`): + maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized + cache. + encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): + `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: + `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) + is a sequence of hidden-states at the output of the last layer of the encoder. Used in the + cross-attention of the decoder. + """ + # init input variables to retrieve cache + decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") + decoder_attention_mask = jnp.ones_like(decoder_input_ids) + decoder_position_ids = jnp.broadcast_to( + jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape + ) + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + return decoder_module( + decoder_input_ids, + decoder_attention_mask, + decoder_position_ids, + **kwargs, + ) + + init_variables = self.module.init( + jax.random.PRNGKey(0), + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + init_cache=True, + method=_decoder_forward, # we only need to call the decoder to init the cache + ) + return unfreeze(init_variables["cache"]) + + @add_start_docstrings(BART_ENCODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=BartConfig) + def encode( + self, + input_ids: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + r""" + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration + + >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") + + >>> text = "My friends are cool but they eat too many carbs." + >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") + >>> encoder_outputs = model.encode(**inputs) + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + if position_ids is None: + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + def _encoder_forward(module, input_ids, attention_mask, position_ids, **kwargs): + encode_module = module._get_encoder_module() + return encode_module(input_ids, attention_mask, position_ids, **kwargs) + + return self.module.apply( + {"params": params or self.params}, + input_ids=jnp.array(input_ids, dtype="i4"), + attention_mask=jnp.array(attention_mask, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + method=_encoder_forward, + ) + + @add_start_docstrings(BART_DECODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=BartConfig) + def decode( + self, + decoder_input_ids, + encoder_outputs, + encoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + past_key_values: dict = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + r""" + Returns: + + Example: + + ```python + >>> import jax.numpy as jnp + >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration + + >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") + + >>> text = "My friends are cool but they eat too many carbs." + >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") + >>> encoder_outputs = model.encode(**inputs) + + >>> decoder_start_token_id = model.config.decoder_start_token_id + >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id + + >>> outputs = model.decode(decoder_input_ids, encoder_outputs) + >>> last_decoder_hidden_states = outputs.last_hidden_state + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + encoder_hidden_states = encoder_outputs[0] + if encoder_attention_mask is None: + batch_size, sequence_length = encoder_hidden_states.shape[:2] + encoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + batch_size, sequence_length = decoder_input_ids.shape + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + if decoder_position_ids is None: + if past_key_values is not None: + raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") + + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be + # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that + # it can be changed by FlaxBartAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + return decoder_module( + decoder_input_ids, + decoder_attention_mask, + decoder_position_ids, + **kwargs, + ) + + outputs = self.module.apply( + inputs, + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + method=_decoder_forward, + ) + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs, past = outputs + outputs["past_key_values"] = unfreeze(past["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs, past = outputs + outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] + + return outputs + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + def __call__( + self, + input_ids: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + decoder_input_ids: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # prepare encoder inputs + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + if position_ids is None: + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + # prepare decoder inputs + if decoder_input_ids is None: + decoder_input_ids = shift_tokens_right( + input_ids, self.config.pad_token_id, decoder_start_token_id=self.config.decoder_start_token_id + ) + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones_like(decoder_input_ids) + if decoder_position_ids is None: + batch_size, sequence_length = decoder_input_ids.shape + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + + # Handle any PRNG if needed + rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} + + return self.module.apply( + {"params": params or self.params}, + input_ids=jnp.array(input_ids, dtype="i4"), + attention_mask=jnp.array(attention_mask, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + ) + + +@add_start_docstrings( + "The bare Bart Model transformer outputting raw hidden-states without any specific head on top.", + BART_START_DOCSTRING, +) +class FlaxBartModel(FlaxBartPreTrainedModel): + config: BartConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + module_class = FlaxBartModule + + +append_call_sample_docstring(FlaxBartModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) + + +class FlaxBartForConditionalGenerationModule(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + bias_init: Callable[..., jnp.ndarray] = jax.nn.initializers.zeros + + def setup(self): + self.model = FlaxBartModule(config=self.config, dtype=self.dtype) + self.lm_head = nn.Dense( + self.model.shared.num_embeddings, + use_bias=False, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.final_logits_bias = self.param("final_logits_bias", self.bias_init, (1, self.model.shared.num_embeddings)) + + def _get_encoder_module(self): + return self.model.encoder + + def _get_decoder_module(self): + return self.model.decoder + + def __call__( + self, + input_ids, + attention_mask, + decoder_input_ids, + decoder_attention_mask, + position_ids, + decoder_position_ids, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + position_ids=position_ids, + decoder_position_ids=decoder_position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = self.model.variables["params"]["shared"]["embedding"] + lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = self.lm_head(hidden_states) + + lm_logits += jax.lax.stop_gradient(self.final_logits_bias.astype(self.dtype)) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return output + + return FlaxSeq2SeqLMOutput( + logits=lm_logits, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings( + "The BART Model with a language modeling head. Can be used for summarization.", BART_START_DOCSTRING +) +class FlaxBartForConditionalGeneration(FlaxBartPreTrainedModel): + module_class = FlaxBartForConditionalGenerationModule + dtype: jnp.dtype = jnp.float32 + + @add_start_docstrings(BART_DECODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=BartConfig) + def decode( + self, + decoder_input_ids, + encoder_outputs, + encoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + past_key_values: dict = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + r""" + Returns: + + Example: + + ```python + >>> import jax.numpy as jnp + >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration + + >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") + + >>> text = "My friends are cool but they eat too many carbs." + >>> inputs = tokenizer(text, max_length=1024, return_tensors="jax") + >>> encoder_outputs = model.encode(**inputs) + + >>> decoder_start_token_id = model.config.decoder_start_token_id + >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id + + >>> outputs = model.decode(decoder_input_ids, encoder_outputs) + >>> logits = outputs.logits + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + encoder_hidden_states = encoder_outputs[0] + if encoder_attention_mask is None: + batch_size, sequence_length = encoder_hidden_states.shape[:2] + encoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + batch_size, sequence_length = decoder_input_ids.shape + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + if decoder_position_ids is None: + if past_key_values is not None: + raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") + + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be + # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that + # it can be changed by FlaxBartAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + outputs = decoder_module( + decoder_input_ids, + decoder_attention_mask, + decoder_position_ids, + **kwargs, + ) + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = module.model.variables["params"]["shared"]["embedding"] + lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = module.lm_head(hidden_states) + + lm_logits += module.final_logits_bias.astype(self.dtype) + return lm_logits, outputs + + outputs = self.module.apply( + inputs, + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=jnp.array(encoder_attention_mask, dtype="i4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + method=_decoder_forward, + ) + + if past_key_values is None: + lm_logits, decoder_outputs = outputs + else: + (lm_logits, decoder_outputs), past = outputs + + if return_dict: + outputs = FlaxCausalLMOutputWithCrossAttentions( + logits=lm_logits, + hidden_states=decoder_outputs.hidden_states, + attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + ) + else: + outputs = (lm_logits,) + decoder_outputs[1:] + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs["past_key_values"] = unfreeze(past["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] + + return outputs + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + max_length, + attention_mask: Optional[jnp.DeviceArray] = None, + decoder_attention_mask: Optional[jnp.DeviceArray] = None, + encoder_outputs=None, + **kwargs, + ): + # initializing the cache + batch_size, seq_length = decoder_input_ids.shape + + past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) + # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. + # But since the decoder uses a causal mask, those positions are masked anyways. + # Thus we can create a single static attention_mask here, which is more efficient for compilation + extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") + if decoder_attention_mask is not None: + position_ids = decoder_attention_mask.cumsum(axis=-1) - 1 + extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) + else: + position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) + + return { + "past_key_values": past_key_values, + "encoder_outputs": encoder_outputs, + "encoder_attention_mask": attention_mask, + "decoder_attention_mask": extended_attention_mask, + "decoder_position_ids": position_ids, + } + + def update_inputs_for_generation(self, model_outputs, model_kwargs): + model_kwargs["past_key_values"] = model_outputs.past_key_values + model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 + return model_kwargs + + +FLAX_BART_CONDITIONAL_GENERATION_DOCSTRING = """ + Returns: + + Summarization example: + + ```python + >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration + + >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn") + + >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." + >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="np") + + >>> # Generate Summary + >>> summary_ids = model.generate(inputs["input_ids"]).sequences + >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) + ``` + + Mask filling example: + + ```python + >>> import jax + >>> from transformers import AutoTokenizer, FlaxBartForConditionalGeneration + + >>> model = FlaxBartForConditionalGeneration.from_pretrained("facebook/bart-large") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") + + >>> TXT = "My friends are but they eat too many carbs." + >>> input_ids = tokenizer([TXT], return_tensors="jax")["input_ids"] + + >>> logits = model(input_ids).logits + >>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero()[0].item() + >>> probs = jax.nn.softmax(logits[0, masked_index], axis=0) + >>> values, predictions = jax.lax.top_k(probs, k=1) + + >>> tokenizer.decode(predictions).split() + ``` +""" + +overwrite_call_docstring( + FlaxBartForConditionalGeneration, BART_INPUTS_DOCSTRING + FLAX_BART_CONDITIONAL_GENERATION_DOCSTRING +) +append_replace_return_docstrings( + FlaxBartForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC +) + + +class FlaxBartForSequenceClassificationModule(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + num_labels: Optional[int] = None + + def setup(self): + self.model = FlaxBartModule(config=self.config, dtype=self.dtype) + self.classification_head = FlaxBartClassificationHead( + config=self.config, + inner_dim=self.config.d_model, + num_classes=self.num_labels if self.num_labels is not None else self.config.num_labels, + pooler_dropout=self.config.classifier_dropout, + ) + + def _get_encoder_module(self): + return self.model.encoder + + def _get_decoder_module(self): + return self.model.decoder + + def __call__( + self, + input_ids, + attention_mask, + decoder_input_ids, + decoder_attention_mask, + position_ids, + decoder_position_ids, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + position_ids=position_ids, + decoder_position_ids=decoder_position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + hidden_states = outputs[0] # last hidden state + + eos_mask = jnp.where(input_ids == self.config.eos_token_id, 1, 0) + + # The first condition is necessary to overcome jax._src.errors.ConcretizationTypeError during JIT compilation + if type(eos_mask) != jax.interpreters.partial_eval.DynamicJaxprTracer: + if len(jnp.unique(eos_mask.sum(1))) > 1: + raise ValueError("All examples must have the same number of tokens.") + + if any(eos_mask.sum(1) == 0): + raise ValueError("There are missing tokens in input_ids") + + # Ensure to keep 1 only for the last token for each example + eos_mask_noised = eos_mask + jnp.arange(eos_mask.shape[1]) * 1e-6 + eos_mask = jnp.where(eos_mask_noised == eos_mask_noised.max(1).reshape(-1, 1), 1, 0) + + sentence_representation = jnp.einsum("ijk, ij -> ijk", hidden_states, eos_mask).sum(1) + logits = self.classification_head(sentence_representation, deterministic=deterministic) + + if not return_dict: + output = (logits,) + outputs[1:] + return output + + return FlaxSeq2SeqSequenceClassifierOutput( + logits=logits, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings( + """ + Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE + tasks. + """, + BART_START_DOCSTRING, +) +class FlaxBartForSequenceClassification(FlaxBartPreTrainedModel): + module_class = FlaxBartForSequenceClassificationModule + dtype = jnp.float32 + + +append_call_sample_docstring( + FlaxBartForSequenceClassification, + _CHECKPOINT_FOR_DOC, + FlaxSeq2SeqSequenceClassifierOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxBartForQuestionAnsweringModule(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + num_labels = 2 + + def setup(self): + self.model = FlaxBartModule(config=self.config, dtype=self.dtype) + self.qa_outputs = nn.Dense( + self.num_labels, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + + def _get_encoder_module(self): + return self.model.encoder + + def _get_decoder_module(self): + return self.model.decoder + + def __call__( + self, + input_ids, + attention_mask, + decoder_input_ids, + decoder_attention_mask, + position_ids, + decoder_position_ids, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + position_ids=position_ids, + decoder_position_ids=decoder_position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = jnp.split(logits, logits.shape[-1], axis=-1) + start_logits = start_logits.squeeze(-1) + end_logits = end_logits.squeeze(-1) + + if not return_dict: + output = (start_logits, end_logits) + outputs[1:] + return output + + return FlaxSeq2SeqQuestionAnsweringModelOutput( + start_logits=start_logits, + end_logits=end_logits, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings( + """ + BART Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layer on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + BART_START_DOCSTRING, +) +class FlaxBartForQuestionAnswering(FlaxBartPreTrainedModel): + module_class = FlaxBartForQuestionAnsweringModule + dtype = jnp.float32 + + +append_call_sample_docstring( + FlaxBartForQuestionAnswering, + _CHECKPOINT_FOR_DOC, + FlaxSeq2SeqQuestionAnsweringModelOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxBartDecoderPreTrainedModel(FlaxPreTrainedModel): + config_class = BartConfig + base_model_prefix: str = "model" + module_class: nn.Module = None + + def __init__( + self, + config: BartConfig, + input_shape: Tuple[int] = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + config.is_decoder = True + config.is_encoder_decoder = False + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + attention_mask = jnp.ones_like(input_ids) + + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + encoder_hidden_states = jnp.zeros(input_shape + (self.config.d_model,)) + encoder_attention_mask = attention_mask + module_init_outputs = self.module.init( + rngs, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states, + encoder_attention_mask, + return_dict=False, + ) + return module_init_outputs["params"] + + def init_cache(self, batch_size, max_length): + r""" + Args: + batch_size (`int`): + batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. + max_length (`int`): + maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized + cache. + """ + # init input variables to retrieve cache + input_ids = jnp.ones((batch_size, max_length), dtype="i4") + attention_mask = jnp.ones_like(input_ids, dtype="i4") + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + init_variables = self.module.init( + jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True + ) + return unfreeze(init_variables["cache"]) + + @add_start_docstrings_to_model_forward(BART_DECODE_INPUTS_DOCSTRING) + def __call__( + self, + input_ids: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + past_key_values: dict = None, + dropout_rng: PRNGKey = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + if encoder_hidden_states is not None and encoder_attention_mask is None: + batch_size, sequence_length = encoder_hidden_states.shape[:2] + encoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + # prepare decoder inputs + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + if position_ids is None: + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed + # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be + # changed by FlaxBartAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + outputs = self.module.apply( + inputs, + input_ids=jnp.array(input_ids, dtype="i4"), + attention_mask=jnp.array(attention_mask, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + ) + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs, past_key_values = outputs + outputs["past_key_values"] = unfreeze(past_key_values["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs, past_key_values = outputs + outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] + + return outputs + + +class FlaxBartDecoderWrapper(nn.Module): + """ + This wrapper class is a helper class to correctly load pretrained checkpoints when the causal language model is + used in combination with the [`EncoderDecoderModel`] framework. + """ + + config: BartConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + embed_dim = self.config.d_model + embed_tokens = nn.Embed( + self.config.vocab_size, + embed_dim, + embedding_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + self.decoder = FlaxBartDecoder(config=self.config, embed_tokens=embed_tokens, dtype=self.dtype) + + def __call__(self, *args, **kwargs): + return self.decoder(*args, **kwargs) + + +class FlaxBartForCausalLMModule(nn.Module): + config: BartConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.model = FlaxBartDecoderWrapper(config=self.config, dtype=self.dtype) + self.lm_head = nn.Dense( + self.config.vocab_size, + use_bias=False, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_ids, + attention_mask, + position_ids, + encoder_hidden_states, + encoder_attention_mask, + deterministic=deterministic, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = self.model.variables["params"]["decoder"]["embed_tokens"]["embedding"] + lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = self.lm_head(hidden_states) + + if not return_dict: + return (lm_logits,) + outputs[1:] + + return FlaxCausalLMOutputWithCrossAttentions( + logits=lm_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@add_start_docstrings( + """ + Bart Decoder Model with a language modeling head on top (linear layer with weights tied to the input embeddings) + e.g for autoregressive tasks. + """, + BART_START_DOCSTRING, +) +class FlaxBartForCausalLM(FlaxBartDecoderPreTrainedModel): + module_class = FlaxBartForCausalLMModule + + def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jnp.DeviceArray] = None): + # initializing the cache + batch_size, seq_length = input_ids.shape + + past_key_values = self.init_cache(batch_size, max_length) + # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. + # But since the decoder uses a causal mask, those positions are masked anyway. + # Thus, we can create a single static attention_mask here, which is more efficient for compilation + extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") + if attention_mask is not None: + position_ids = attention_mask.cumsum(axis=-1) - 1 + extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) + else: + position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) + + return { + "past_key_values": past_key_values, + "attention_mask": extended_attention_mask, + "position_ids": position_ids, + } + + def update_inputs_for_generation(self, model_outputs, model_kwargs): + model_kwargs["past_key_values"] = model_outputs.past_key_values + model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 + return model_kwargs + + +append_call_sample_docstring( + FlaxBartForCausalLM, + _CHECKPOINT_FOR_DOC, + FlaxCausalLMOutputWithCrossAttentions, + _CONFIG_FOR_DOC, +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_tf_bart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_tf_bart.py new file mode 100644 index 0000000000000000000000000000000000000000..6e29434c4df15818ec9c4acbe174f2c6417164e6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bart/modeling_tf_bart.py @@ -0,0 +1,1607 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 Bart model.""" + + +import random +from typing import Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFBaseModelOutputWithPastAndCrossAttentions, + TFSeq2SeqLMOutput, + TFSeq2SeqModelOutput, + TFSeq2SeqSequenceClassifierOutput, +) + +# Public API +from ...modeling_tf_utils import ( + DUMMY_INPUTS, + TFCausalLanguageModelingLoss, + TFModelInputType, + TFPreTrainedModel, + TFSequenceClassificationLoss, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + ContextManagers, + add_code_sample_docstrings, + add_end_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_bart import BartConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/bart-large" +_CONFIG_FOR_DOC = "BartConfig" + + +LARGE_NEGATIVE = -1e8 + + +def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): + pad_token_id = tf.cast(pad_token_id, input_ids.dtype) + decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) + start_tokens = tf.fill( + (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) + ) + shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids = tf.where( + shifted_input_ids == -100, + tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), + shifted_input_ids, + ) + + # "Verify that `labels` has only positive values and -100" + assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) + + # Make sure the assertion op is called by wrapping the result in an identity no-op + with tf.control_dependencies([assert_gte0]): + shifted_input_ids = tf.identity(shifted_input_ids) + + return shifted_input_ids + + +def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz = input_ids_shape[0] + tgt_len = input_ids_shape[1] + mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE + mask_cond = tf.range(shape_list(mask)[-1]) + + mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) + + if past_key_values_length > 0: + mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) + + return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) + + +def _expand_mask(mask: tf.Tensor, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + src_len = shape_list(mask)[1] + tgt_len = tgt_len if tgt_len is not None else src_len + one_cst = tf.constant(1.0) + mask = tf.cast(mask, dtype=one_cst.dtype) + expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) + + return (one_cst - expanded_mask) * LARGE_NEGATIVE + + +class TFBartLearnedPositionalEmbedding(tf.keras.layers.Embedding): + """ + This module learns positional embeddings up to a fixed maximum size. + """ + + def __init__(self, num_embeddings: int, embedding_dim: int, **kwargs): + # Bart is set up so that if padding_idx is specified then offset the embedding ids by 2 + # and adjust num_embeddings appropriately. Other models don't have this hack + self.offset = 2 + super().__init__(num_embeddings + self.offset, embedding_dim, **kwargs) + + def call( + self, + input_shape: Optional[tf.TensorShape] = None, + past_key_values_length: int = 0, + position_ids: Optional[tf.Tensor] = None, + ): + """Input is expected to be of size [bsz x seqlen].""" + if position_ids is None: + seq_len = input_shape[1] + position_ids = tf.range(seq_len, delta=1, name="range") + position_ids += past_key_values_length + + offset_dtype = position_ids.dtype if isinstance(position_ids, tf.Tensor) else tf.int32 + return super().call(position_ids + tf.constant(self.offset, dtype=offset_dtype)) + + +class TFBartAttention(tf.keras.layers.Layer): + """Multi-headed attention from "Attention Is All You Need""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + **kwargs, + ): + super().__init__(**kwargs) + self.embed_dim = embed_dim + + self.num_heads = num_heads + self.dropout = tf.keras.layers.Dropout(dropout) + self.head_dim = embed_dim // num_heads + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") + self.q_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") + self.v_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") + self.out_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") + + def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): + return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) + + def call( + self, + hidden_states: tf.Tensor, + key_value_states: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[Tuple[tf.Tensor]]] = None, + attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, Optional[tf.Tensor]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + bsz, tgt_len, embed_dim = shape_list(hidden_states) + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = tf.concat([past_key_value[0], key_states], axis=2) + value_states = tf.concat([past_key_value[1], value_states], axis=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) + key_states = tf.reshape(key_states, proj_shape) + value_states = tf.reshape(value_states, proj_shape) + + src_len = shape_list(key_states)[1] + attn_weights = tf.matmul(query_states, key_states, transpose_b=True) + + tf.debugging.assert_equal( + shape_list(attn_weights), + [bsz * self.num_heads, tgt_len, src_len], + message=( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {shape_list(attn_weights)}" + ), + ) + + if attention_mask is not None: + tf.debugging.assert_equal( + shape_list(attention_mask), + [bsz, 1, tgt_len, src_len], + message=( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {shape_list(attention_mask)}" + ), + ) + + attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) + attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_weights = stable_softmax(attn_weights, axis=-1) + + if layer_head_mask is not None: + tf.debugging.assert_equal( + shape_list(layer_head_mask), + [self.num_heads], + message=( + f"Head mask for a single layer should be of size {(self.num_heads)}, but is" + f" {shape_list(layer_head_mask)}" + ), + ) + + attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( + attn_weights, (bsz, self.num_heads, tgt_len, src_len) + ) + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_probs = self.dropout(attn_weights, training=training) + attn_output = tf.matmul(attn_probs, value_states) + + tf.debugging.assert_equal( + shape_list(attn_output), + [bsz * self.num_heads, tgt_len, self.head_dim], + message=( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {shape_list(attn_output)}" + ), + ) + + attn_output = tf.transpose( + tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) + ) + attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) + + attn_output = self.out_proj(attn_output) + attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + + return attn_output, attn_weights, past_key_value + + +class TFBartEncoderLayer(tf.keras.layers.Layer): + def __init__(self, config: BartConfig, **kwargs): + super().__init__(**kwargs) + self.embed_dim = config.d_model + self.self_attn = TFBartAttention( + self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" + ) + self.self_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation_fn = get_tf_activation(config.activation_function) + self.activation_dropout = tf.keras.layers.Dropout(config.activation_dropout) + self.fc1 = tf.keras.layers.Dense(config.encoder_ffn_dim, name="fc1") + self.fc2 = tf.keras.layers.Dense(self.embed_dim, name="fc2") + self.final_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]], + layer_head_mask: Optional[tf.Tensor], + training: Optional[bool] = False, + ) -> tf.Tensor: + """ + Args: + hidden_states (`tf.Tensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`tf.Tensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)` + """ + residual = hidden_states + hidden_states, self_attn_weights, _ = self.self_attn( + hidden_states=hidden_states, attention_mask=attention_mask, layer_head_mask=layer_head_mask + ) + + tf.debugging.assert_equal( + shape_list(hidden_states), + shape_list(residual), + message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", + ) + + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout(hidden_states, training=training) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + return hidden_states, self_attn_weights + + +class TFBartDecoderLayer(tf.keras.layers.Layer): + def __init__(self, config: BartConfig, **kwargs): + super().__init__(**kwargs) + self.embed_dim = config.d_model + self.self_attn = TFBartAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + name="self_attn", + is_decoder=True, + ) + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation_fn = get_tf_activation(config.activation_function) + self.activation_dropout = tf.keras.layers.Dropout(config.activation_dropout) + + self.self_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") + self.encoder_attn = TFBartAttention( + self.embed_dim, + config.decoder_attention_heads, + dropout=config.attention_dropout, + name="encoder_attn", + is_decoder=True, + ) + self.encoder_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") + self.fc1 = tf.keras.layers.Dense(config.decoder_ffn_dim, name="fc1") + self.fc2 = tf.keras.layers.Dense(self.embed_dim, name="fc2") + self.final_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + layer_head_mask: Optional[tf.Tensor] = None, + cross_attn_layer_head_mask: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, tf.Tensor, Tuple[Tuple[tf.Tensor]]]: + """ + Args: + hidden_states (`tf.Tensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`tf.Tensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + encoder_hidden_states (`tf.Tensor`): + cross attention input to the layer of shape `(seq_len, batch, embed_dim)` + encoder_attention_mask (`tf.Tensor`): encoder attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size + `(decoder_attention_heads,)` + cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. + `(decoder_attention_heads,)` + past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states + """ + residual = hidden_states + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout(hidden_states, training=training) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + return ( + hidden_states, + self_attn_weights, + cross_attn_weights, + present_key_value, + ) + + +class TFBartClassificationHead(tf.keras.layers.Layer): + """Head for sentence-level classification tasks.""" + + def __init__(self, inner_dim: int, num_classes: int, pooler_dropout: float, name: str, **kwargs): + super().__init__(name=name, **kwargs) + self.dense = tf.keras.layers.Dense(inner_dim, name="dense") + self.dropout = tf.keras.layers.Dropout(pooler_dropout) + self.out_proj = tf.keras.layers.Dense(num_classes, name="out_proj") + + def call(self, inputs): + hidden_states = self.dropout(inputs) + hidden_states = self.dense(hidden_states) + hidden_states = tf.keras.activations.tanh(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +class TFBartPretrainedModel(TFPreTrainedModel): + config_class = BartConfig + base_model_prefix = "model" + + @property + def dummy_inputs(self): + pad_token = 1 + input_ids = tf.convert_to_tensor(DUMMY_INPUTS, dtype=tf.int32) + decoder_input_ids = tf.convert_to_tensor(DUMMY_INPUTS, dtype=tf.int32) + dummy_inputs = { + "decoder_input_ids": decoder_input_ids, + "attention_mask": tf.cast(input_ids != pad_token, tf.int32), + "input_ids": input_ids, + } + return dummy_inputs + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + "decoder_input_ids": tf.TensorSpec((None, None), tf.int32, name="decoder_input_ids"), + "decoder_attention_mask": tf.TensorSpec((None, None), tf.int32, name="decoder_attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + +BART_START_DOCSTRING = r""" + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`BartConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + + +BART_GENERATION_EXAMPLE = r""" + Summarization example: + + ```python + >>> from transformers import AutoTokenizer, TFBartForConditionalGeneration + + >>> model = TFBartForConditionalGeneration.from_pretrained("facebook/bart-large") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") + + >>> ARTICLE_TO_SUMMARIZE = "My friends are cool but they eat too many carbs." + >>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="tf") + + >>> # Generate Summary + >>> summary_ids = model.generate(inputs["input_ids"], num_beams=4, max_length=5) + >>> print(tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)) + ``` + + Mask filling example: + + ```python + >>> from transformers import AutoTokenizer, TFBartForConditionalGeneration + + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") + >>> TXT = "My friends are but they eat too many carbs." + + >>> model = TFBartForConditionalGeneration.from_pretrained("facebook/bart-large") + >>> input_ids = tokenizer([TXT], return_tensors="tf")["input_ids"] + >>> logits = model(input_ids).logits + >>> probs = tf.nn.softmax(logits[0]) + >>> # probs[5] is associated with the mask token + ``` +""" + + +BART_INPUTS_DOCSTRING = r""" + Args: + input_ids (`tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`BertTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values` + is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`). + + For translation and summarization training, `decoder_input_ids` should be provided. If no + `decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right + for denoising pre-training following the paper. + decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): + will be made by default and ignore pad tokens. It is not recommended to set this for most use cases. + decoder_position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + encoder_outputs (`tf.FloatTensor`, *optional*): + hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + of shape `(batch_size, sequence_length, hidden_size)` is a sequence of + past_key_values (`Tuple[Tuple[tf.Tensor]]` of length `config.n_layers`) + contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*, defaults to `True`): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). Set to `False` during training, `True` during generation + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@keras_serializable +class TFBartEncoder(tf.keras.layers.Layer): + config_class = BartConfig + """ + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`TFBartEncoderLayer`]. + + Args: + config: BartConfig + """ + + def __init__(self, config: BartConfig, embed_tokens: Optional[tf.keras.layers.Embedding] = None, **kwargs): + super().__init__(**kwargs) + self.config = config + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.layerdrop = config.encoder_layerdrop + self.padding_idx = config.pad_token_id + self.max_source_positions = config.max_position_embeddings + self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 + + self.embed_tokens = embed_tokens + self.embed_positions = TFBartLearnedPositionalEmbedding( + config.max_position_embeddings, + config.d_model, + name="embed_positions", + ) + self.layers = [TFBartEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] + self.layernorm_embedding = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + """ + Args: + input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, `optional): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if inputs_embeds is None: + # if `self.embed_tokens.load_weight_prefix` is set, runs the embedding operation with the correct name + # scope, so that its weights are registered with the desired name for loading/storing. When `tf.name_scope` + # is used with a name ending in `/`, that name replaces the current name scope. + # (embeddings with tf.name_scope: self.embed_tokens.load_weight_prefix/self.embed_tokens.name/embeddings:0) + context = [] + if hasattr(self.embed_tokens, "load_weight_prefix"): + context.append(tf.name_scope(self.embed_tokens.load_weight_prefix + "/")) + with ContextManagers(context): + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.embed_tokens.input_dim, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.embed_tokens.input_dim})" + ), + ) + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + embed_pos = self.embed_positions(input_shape) + hidden_states = inputs_embeds + embed_pos + hidden_states = self.layernorm_embedding(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + + # check attention mask and invert + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + attention_mask = _expand_mask(attention_mask) + else: + attention_mask = None + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + # check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + tf.debugging.assert_equal( + shape_list(head_mask)[0], + len(self.layers), + message=( + f"The head_mask should be specified for {len(self.layers)} layers, but it is for" + f" {shape_list(head_mask)[0]}." + ), + ) + + # encoder layers + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if training and (dropout_probability < self.layerdrop): # skip the layer + continue + + hidden_states, attn = encoder_layer( + hidden_states, + attention_mask, + head_mask[idx] if head_mask is not None else None, + ) + + if output_attentions: + all_attentions += (attn,) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +@keras_serializable +class TFBartDecoder(tf.keras.layers.Layer): + config_class = BartConfig + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFBartDecoderLayer`] + + Args: + config: BartConfig + embed_tokens: output embedding + """ + + def __init__(self, config: BartConfig, embed_tokens: Optional[tf.keras.layers.Embedding] = None, **kwargs): + super().__init__(**kwargs) + self.config = config + self.padding_idx = config.pad_token_id + self.embed_tokens = embed_tokens + self.layerdrop = config.decoder_layerdrop + self.embed_positions = TFBartLearnedPositionalEmbedding( + config.max_position_embeddings, + config.d_model, + name="embed_positions", + ) + self.embed_scale = tf.math.sqrt(float(config.d_model)) if config.scale_embedding else 1.0 + self.layers = [TFBartDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] + self.layernorm_embedding = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layernorm_embedding") + + self.dropout = tf.keras.layers.Dropout(config.dropout) + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutputWithPastAndCrossAttentions, Tuple[tf.Tensor]]: + r""" + Args: + input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values + selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`Tuple[Tuple[tf.Tensor]]` of length `config.n_layers` with each tuple having 2 tuples each of which has 2 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up + decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those + that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of + all `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`tf.Tensor` of shape + `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing `input_ids` + you can choose to directly pass an embedded representation. This is useful if you want more control + over how to convert `input_ids` indices into associated vectors than the model's internal embedding + lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") + + past_key_values_length = shape_list(past_key_values[0][0])[2] if past_key_values is not None else 0 + + # embed positions + if position_ids is None: + positions = self.embed_positions(input_shape, past_key_values_length) + else: + positions = self.embed_positions(input_shape, position_ids=position_ids) + + if inputs_embeds is None: + # if `self.embed_tokens.load_weight_prefix` is set, runs the embedding operation with the correct name + # scope, so that its weights are registered with the desired name for loading/storing. When `tf.name_scope` + # is used with a name ending in `/`, that name replaces the current name scope. + # (embeddings with tf.name_scope: self.embed_tokens.load_weight_prefix/self.embed_tokens.name/embeddings:0) + context = [] + if hasattr(self.embed_tokens, "load_weight_prefix"): + context.append(tf.name_scope(self.embed_tokens.load_weight_prefix + "/")) + with ContextManagers(context): + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.embed_tokens.input_dim, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.embed_tokens.input_dim})" + ), + ) + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + hidden_states = inputs_embeds + + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + if input_shape[-1] > 1: + combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length) + else: + combined_attention_mask = _expand_mask( + tf.ones((input_shape[0], input_shape[1] + past_key_values_length)), tgt_len=input_shape[-1] + ) + + if attention_mask is not None: + combined_attention_mask = combined_attention_mask + _expand_mask(attention_mask, tgt_len=input_shape[-1]) + + if encoder_hidden_states is not None and encoder_attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) + + hidden_states = self.layernorm_embedding(hidden_states + positions) + hidden_states = self.dropout(hidden_states, training=training) + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attns = () if (output_attentions and encoder_hidden_states is not None) else None + present_key_values = () if use_cache else None + + # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired + for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: + if attn_mask is not None: + tf.debugging.assert_equal( + shape_list(attn_mask)[0], + len(self.layers), + message=( + f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" + f" {shape_list(attn_mask)[0]}." + ), + ) + + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + + dropout_probability = random.uniform(0, 1) + + if training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( + hidden_states, + attention_mask=combined_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + layer_head_mask=head_mask[idx] if head_mask is not None else None, + cross_attn_layer_head_mask=cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, + past_key_value=past_key_value, + ) + + if use_cache: + present_key_values += (present_key_value,) + + if output_attentions: + all_self_attns += (layer_self_attn,) + + if encoder_hidden_states is not None: + all_cross_attns += (layer_cross_attn,) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if not return_dict: + return hidden_states, present_key_values, all_hidden_states, all_self_attns, all_cross_attns + else: + return TFBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=present_key_values, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attns, + ) + + +@keras_serializable +class TFBartMainLayer(tf.keras.layers.Layer): + config_class = BartConfig + + def __init__(self, config: BartConfig, load_weight_prefix=None, **kwargs): + super().__init__(**kwargs) + self.config = config + self.shared = tf.keras.layers.Embedding( + input_dim=config.vocab_size, + output_dim=config.d_model, + embeddings_initializer=tf.keras.initializers.TruncatedNormal(stddev=self.config.init_std), + name="model.shared", + ) + # Additional attribute to specify the expected name scope of the layer (for loading/storing weights) + self.shared.load_weight_prefix = "model.shared" if load_weight_prefix is None else load_weight_prefix + + self.encoder = TFBartEncoder(config, self.shared, name="encoder") + self.decoder = TFBartDecoder(config, self.shared, name="decoder") + + def get_input_embeddings(self): + return self.shared + + def set_input_embeddings(self, new_embeddings): + self.shared = new_embeddings + self.encoder.embed_tokens = self.shared + self.decoder.embed_tokens = self.shared + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[Union[Tuple, TFBaseModelOutput]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + **kwargs, + ) -> Union[TFSeq2SeqModelOutput, Tuple[tf.Tensor]]: + # different to other models, Bart automatically creates decoder_input_ids from + # input_ids if no decoder_input_ids are provided + if decoder_input_ids is None and decoder_inputs_embeds is None: + if input_ids is None: + raise ValueError( + "If no `decoder_input_ids` or `decoder_inputs_embeds` are " + "passed, `input_ids` cannot be `None`. Please pass either " + "`input_ids` or `decoder_input_ids` or `decoder_inputs_embeds`." + ) + + decoder_input_ids = shift_tokens_right( + input_ids, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): + encoder_outputs = TFBaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + # If the user passed a TFBaseModelOutput for encoder_outputs, we wrap it in a tuple when return_dict=False + elif not return_dict and not isinstance(encoder_outputs, tuple): + encoder_outputs = encoder_outputs.to_tuple() + + decoder_outputs = self.decoder( + decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=attention_mask, + head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return TFSeq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + past_key_values=decoder_outputs.past_key_values, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + "The bare BART Model outputting raw hidden-states without any specific head on top.", + BART_START_DOCSTRING, +) +class TFBartModel(TFBartPretrainedModel): + _requires_load_weight_prefix = True + + def __init__(self, config: BartConfig, load_weight_prefix=None, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") + + def get_encoder(self): + return self.model.encoder + + def get_decoder(self): + return self.model.decoder + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFSeq2SeqModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[Union[Tuple, TFBaseModelOutput]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + **kwargs, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output): + pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None + dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None + dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None + enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None + enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None + + return TFSeq2SeqModelOutput( + last_hidden_state=output.last_hidden_state, + past_key_values=pkv, + decoder_hidden_states=dec_hs, + decoder_attentions=dec_attns, + cross_attentions=cross_attns, + encoder_last_hidden_state=output.encoder_last_hidden_state, + encoder_hidden_states=enc_hs, + encoder_attentions=enc_attns, + ) + + +class BiasLayer(tf.keras.layers.Layer): + """ + Bias as a layer. It is used for serialization purposes: `tf.keras.Model.save_weights` stores on a per-layer basis, + so all weights have to be registered in a layer. + """ + + def __init__(self, shape, initializer, trainable, name, **kwargs): + super().__init__(name=name, **kwargs) + # Note: the name of this variable will NOT be scoped when serialized, i.e. it will not be in the format of + # "outer_layer/inner_layer/.../name:0". Instead, it will be "name:0". For further details, see: + # https://github.com/huggingface/transformers/pull/18833#issuecomment-1233090214 + self.bias = self.add_weight(name=name, shape=shape, initializer=initializer, trainable=trainable) + + def call(self, x): + return x + self.bias + + +@add_start_docstrings( + "The BART Model with a language modeling head. Can be used for summarization.", + BART_START_DOCSTRING, +) +class TFBartForConditionalGeneration(TFBartPretrainedModel, TFCausalLanguageModelingLoss): + _keys_to_ignore_on_load_missing = [r"final_logits_bias"] + _requires_load_weight_prefix = True + + def __init__(self, config, load_weight_prefix=None, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") + self.use_cache = config.use_cache + # final_bias_logits is registered as a buffer in pytorch, so not trainable for the sake of consistency. + self.bias_layer = BiasLayer( + name="final_logits_bias", shape=[1, config.vocab_size], initializer="zeros", trainable=False + ) + + def get_decoder(self): + return self.model.decoder + + def get_encoder(self): + return self.model.encoder + + def get_output_embeddings(self): + return self.get_input_embeddings() + + def set_output_embeddings(self, value): + self.set_input_embeddings(value) + + def get_bias(self): + return {"final_logits_bias": self.bias_layer.bias} + + def set_bias(self, value): + # Replaces the existing layers containing bias for correct (de)serialization. + vocab_size = value["final_logits_bias"].shape[-1] + self.bias_layer = BiasLayer( + name="final_logits_bias", shape=[1, vocab_size], initializer="zeros", trainable=False + ) + self.bias_layer.bias.assign(value["final_logits_bias"]) + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + @add_end_docstrings(BART_GENERATION_EXAMPLE) + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[TFBaseModelOutput] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Union[TFSeq2SeqLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Returns: + + """ + + if labels is not None: + labels = tf.where( + labels == self.config.pad_token_id, + tf.cast(tf.fill(shape_list(labels), -100), labels.dtype), + labels, + ) + use_cache = False + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + outputs = self.model( + input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + encoder_outputs=encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + lm_logits = tf.matmul(outputs[0], self.model.shared.weights, transpose_b=True) + lm_logits = self.bias_layer(lm_logits) + masked_lm_loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + return TFSeq2SeqLMOutput( + loss=masked_lm_loss, + logits=lm_logits, + past_key_values=outputs.past_key_values, # index 1 of d outputs + decoder_hidden_states=outputs.decoder_hidden_states, # index 2 of d outputs + decoder_attentions=outputs.decoder_attentions, # index 3 of d outputs + cross_attentions=outputs.cross_attentions, # index 4 of d outputs + encoder_last_hidden_state=outputs.encoder_last_hidden_state, # index 0 of encoder outputs + encoder_hidden_states=outputs.encoder_hidden_states, # 1 of e out + encoder_attentions=outputs.encoder_attentions, # 2 of e out + ) + + def serving_output(self, output): + pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None + dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None + dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None + enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None + enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None + + return TFSeq2SeqLMOutput( + logits=output.logits, + past_key_values=pkv, + decoder_hidden_states=dec_hs, + decoder_attentions=dec_attns, + cross_attentions=cross_attns, + encoder_last_hidden_state=output.encoder_last_hidden_state, + encoder_hidden_states=enc_hs, + encoder_attentions=enc_attns, + ) + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + past_key_values=None, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, + use_cache=None, + encoder_outputs=None, + **kwargs, + ): + # cut decoder_input_ids if past_key_values is used + if past_key_values is not None: + decoder_input_ids = decoder_input_ids[:, -1:] + + if decoder_attention_mask is not None: # xla + decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] + elif past_key_values is not None: # no xla + past_key_values + decoder_position_ids = past_key_values[0][0].shape[2] + else: # no xla + no past_key_values + decoder_position_ids = tf.range(decoder_input_ids.shape[1]) + + return { + "input_ids": None, # encoder_outputs is defined. input_ids not needed + "encoder_outputs": encoder_outputs, + "past_key_values": past_key_values, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": decoder_attention_mask, + "decoder_position_ids": decoder_position_ids, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + "cross_attn_head_mask": cross_attn_head_mask, + "use_cache": use_cache, # change this to avoid caching (presumably for debugging) + } + + def prepare_decoder_input_ids_from_labels(self, labels: tf.Tensor): + return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id) + + +@add_start_docstrings( + """ + Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE + tasks. + """, + BART_START_DOCSTRING, +) +class TFBartForSequenceClassification(TFBartPretrainedModel, TFSequenceClassificationLoss): + @property + def dummy_inputs(self): + pad_token = self.config.pad_token_id + input_ids = tf.constant([[0, 6, 10, 4, 2], [0, 8, 12, 2, pad_token]]) + dummy_inputs = { + "attention_mask": tf.cast(tf.math.not_equal(input_ids, (pad_token)), dtype=tf.int32), + "input_ids": input_ids, + } + return dummy_inputs + + def __init__(self, config: BartConfig, load_weight_prefix=None, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.model = TFBartMainLayer(config, load_weight_prefix=load_weight_prefix, name="model") + self.classification_head = TFBartClassificationHead( + config.d_model, config.num_labels, config.classifier_dropout, name="classification_head" + ) + + @add_start_docstrings_to_model_forward(BART_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSeq2SeqSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[TFBaseModelOutput] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Union[TFSeq2SeqSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + + Returns: + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + if input_ids is None and inputs_embeds is not None: + raise NotImplementedError( + f"Passing input embeddings is currently not supported for {self.__class__.__name__}" + ) + + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + last_hidden_state = outputs[0] + eos_mask = tf.equal(input_ids, self.config.eos_token_id) + # out the rows with False where present. Then verify all the final + # entries are True + self_masked = tf.reshape(tf.boolean_mask(eos_mask, eos_mask), (tf.shape(input_ids)[0], -1)) + tf.Assert(tf.reduce_all(self_masked[:, -1]), ["All examples must have the same number of tokens."]) + + masked = tf.reshape( + tf.boolean_mask(last_hidden_state, eos_mask), + (tf.shape(input_ids)[0], tf.shape(self_masked)[1], tf.shape(last_hidden_state)[-1]), + ) + + sentence_representation = masked[:, -1, :] + logits = self.classification_head(sentence_representation) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFSeq2SeqSequenceClassifierOutput( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + def serving_output(self, output): + logits = tf.convert_to_tensor(output.logits) + pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None + dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None + dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None + enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None + enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None + + return TFSeq2SeqSequenceClassifierOutput( + logits=logits, + past_key_values=pkv, + decoder_hidden_states=dec_hs, + decoder_attentions=dec_attns, + cross_attentions=cross_attns, + encoder_last_hidden_state=output.encoder_last_hidden_state, + encoder_hidden_states=enc_hs, + encoder_attentions=enc_attns, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..084cd22bdf1d888efd46b759b91ccf95ee53c656 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/__init__.py @@ -0,0 +1,59 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_sentencepiece_available, is_tokenizers_available + + +_import_structure = {} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_barthez"] = ["BarthezTokenizer"] + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_barthez_fast"] = ["BarthezTokenizerFast"] + + +if TYPE_CHECKING: + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_barthez import BarthezTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_barthez_fast import BarthezTokenizerFast + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/tokenization_barthez_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/tokenization_barthez_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..f53a5acd712c71e13f0321ac53128c1de7c94b39 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/barthez/tokenization_barthez_fast.py @@ -0,0 +1,216 @@ +# coding=utf-8 +# Copyright 2020 Ecole Polytechnique and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +""" Tokenization classes for the BARThez model.""" + + +import os +from shutil import copyfile +from typing import List, Optional, Tuple + +from ...tokenization_utils import AddedToken +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import is_sentencepiece_available, logging + + +if is_sentencepiece_available(): + from .tokenization_barthez import BarthezTokenizer +else: + BarthezTokenizer = None + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "moussaKam/mbarthez": "https://huggingface.co/moussaKam/mbarthez/resolve/main/sentencepiece.bpe.model", + "moussaKam/barthez": "https://huggingface.co/moussaKam/barthez/resolve/main/sentencepiece.bpe.model", + "moussaKam/barthez-orangesum-title": ( + "https://huggingface.co/moussaKam/barthez-orangesum-title/resolve/main/sentencepiece.bpe.model" + ), + }, + "tokenizer_file": { + "moussaKam/mbarthez": "https://huggingface.co/moussaKam/mbarthez/resolve/main/tokenizer.json", + "moussaKam/barthez": "https://huggingface.co/moussaKam/barthez/resolve/main/tokenizer.json", + "moussaKam/barthez-orangesum-title": ( + "https://huggingface.co/moussaKam/barthez-orangesum-title/resolve/main/tokenizer.json" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "moussaKam/mbarthez": 1024, + "moussaKam/barthez": 1024, + "moussaKam/barthez-orangesum-title": 1024, +} + +SPIECE_UNDERLINE = "▁" + + +class BarthezTokenizerFast(PreTrainedTokenizerFast): + """ + Adapted from [`CamembertTokenizer`] and [`BartTokenizer`]. Construct a "fast" BARThez tokenizer. Based on + [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = BarthezTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + mask_token="", + **kwargs, + ): + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + mask_token=mask_token, + **kwargs, + ) + + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A BARThez sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + sep + token_ids_1 + sep + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c20d7370c6566c7046797508eeff6036b3350f57 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/__init__.py @@ -0,0 +1,42 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_sentencepiece_available + + +_import_structure = {} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_bartpho"] = ["BartphoTokenizer"] + +if TYPE_CHECKING: + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_bartpho import BartphoTokenizer + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/tokenization_bartpho.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/tokenization_bartpho.py new file mode 100644 index 0000000000000000000000000000000000000000..1c1ef0b8675b8a607bb42362e959949b9894a0a6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/bartpho/tokenization_bartpho.py @@ -0,0 +1,329 @@ +# coding=utf-8 +# Copyright 2021 VinAI Research and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +""" Tokenization classes for BARTpho-syllable model.""" + + +import os +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as spm + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) + +SPIECE_UNDERLINE = "▁" + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "monolingual_vocab_file": "dict.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "vinai/bartpho-syllable": "https://huggingface.co/vinai/bartpho-syllable/resolve/main/sentencepiece.bpe.model", + }, + "monolingual_vocab_file": { + "vinai/bartpho-syllable": "https://huggingface.co/vinai/bartpho-syllable/resolve/main/dict.txt", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {"vinai/bartpho-syllable": 1024} + + +class BartphoTokenizer(PreTrainedTokenizer): + """ + Adapted from [`XLMRobertaTokenizer`]. Based on [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. This vocabulary is the pre-trained SentencePiece model available from the + multilingual XLM-RoBERTa, also used in mBART, consisting of 250K types. + monolingual_vocab_file (`str`): + Path to the monolingual vocabulary file. This monolingual vocabulary consists of Vietnamese-specialized + types extracted from the multilingual vocabulary vocab_file of 250K types. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + monolingual_vocab_file, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + mask_token="", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + mask_token=mask_token, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + self.vocab_file = vocab_file + self.monolingual_vocab_file = monolingual_vocab_file + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(str(vocab_file)) + + # Load the reduced vocab + + # Keep order of special tokens for backward compatibility + self.fairseq_tokens_to_ids = {} + cnt = 0 + for token in [bos_token, pad_token, eos_token, unk_token, sep_token, cls_token]: + if str(token) not in self.fairseq_tokens_to_ids: + self.fairseq_tokens_to_ids[str(token)] = cnt + cnt += 1 + with open(monolingual_vocab_file, "r", encoding="utf-8") as f: + for line in f.readlines(): + token = line.strip().split()[0] + self.fairseq_tokens_to_ids[token] = len(self.fairseq_tokens_to_ids) + if str(mask_token) not in self.fairseq_tokens_to_ids: + self.fairseq_tokens_to_ids[str(mask_token)] = len(self.fairseq_tokens_to_ids) + + self.fairseq_ids_to_tokens = {v: k for k, v in self.fairseq_tokens_to_ids.items()} + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + state["sp_model_proto"] = self.sp_model.serialized_model_proto() + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.LoadFromSerializedProto(self.sp_model_proto) + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An BARTPho sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return [1] + ([0] * len(token_ids_0)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1, 1] + ([0] * len(token_ids_1)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. BARTPho does not + make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + @property + def vocab_size(self): + return len(self.fairseq_ids_to_tokens) + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def _tokenize(self, text: str) -> List[str]: + return self.sp_model.encode(text, out_type=str) + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + if token in self.fairseq_tokens_to_ids: + return self.fairseq_tokens_to_ids[token] + else: + return self.unk_token_id + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.fairseq_ids_to_tokens[index] + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (strings for sub-words) in a single string.""" + out_string = "".join(tokens).replace(SPIECE_UNDERLINE, " ").strip() + return out_string + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + out_monolingual_vocab_file = os.path.join( + save_directory, + (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["monolingual_vocab_file"], + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + if os.path.abspath(self.monolingual_vocab_file) != os.path.abspath( + out_monolingual_vocab_file + ) and os.path.isfile(self.monolingual_vocab_file): + copyfile(self.monolingual_vocab_file, out_monolingual_vocab_file) + elif not os.path.isfile(self.monolingual_vocab_file): + with open(out_monolingual_vocab_file, "w", encoding="utf-8") as fp: + for token in self.fairseq_tokens_to_ids: + if token not in self.all_special_tokens: + fp.write(f"{str(token)} \n") + + return out_vocab_file, out_monolingual_vocab_file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/feature_extraction_beit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/feature_extraction_beit.py new file mode 100644 index 0000000000000000000000000000000000000000..59dacb4ae51f6e314b96ca8c0e8c368e689c1aa7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/feature_extraction_beit.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for BEiT.""" + +import warnings + +from ...utils import logging +from .image_processing_beit import BeitImageProcessor + + +logger = logging.get_logger(__name__) + + +class BeitFeatureExtractor(BeitImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class BeitFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please" + " use BeitImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/modeling_flax_beit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/modeling_flax_beit.py new file mode 100644 index 0000000000000000000000000000000000000000..0f0dc809e68046f3ae9aee896900eea960642c62 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/beit/modeling_flax_beit.py @@ -0,0 +1,947 @@ +# coding=utf-8 +# Copyright 2021 Microsoft Research and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from typing import Callable, List, Optional, Tuple + +import flax +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutput, + FlaxBaseModelOutputWithPooling, + FlaxMaskedLMOutput, + FlaxSequenceClassifierOutput, +) +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward +from .configuration_beit import BeitConfig + + +@flax.struct.dataclass +class FlaxBeitModelOutputWithPooling(FlaxBaseModelOutputWithPooling): + """ + Class for outputs of [`FlaxBeitModel`]. + + Args: + last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + pooler_output (`jnp.ndarray` of shape `(batch_size, hidden_size)`): + Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if + *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token + will be returned. + hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus + the initial embedding outputs. + attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + +BEIT_START_DOCSTRING = r""" + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading, saving and converting weights from PyTorch models) + + This model is also a Flax Linen [flax.linen.Module](https://flax.readthedocs.io/en/latest/flax.linen.html#module) + subclass. Use it as a regular Flax linen Module and refer to the Flax documentation for all matter related to + general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`BeitConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + +BEIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`AutoImageProcessor.__call__`] for details. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +def relative_position_index_init(window_size: Tuple[int, int]) -> jnp.ndarray: + """ + get pair-wise relative position index for each token inside the window + """ + num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3 + + coords_h = np.arange(window_size[0]) + coords_w = np.arange(window_size[1]) + coords = np.stack(np.meshgrid(coords_h, coords_w, indexing="ij")) # 2, Wh, Ww + coords_flatten = np.reshape(coords, (2, -1)) + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww + relative_coords = np.transpose(relative_coords, (1, 2, 0)) # Wh*Ww, Wh*Ww, 2 + relative_coords[:, :, 0] += window_size[0] - 1 # shift to start from 0 + relative_coords[:, :, 1] += window_size[1] - 1 + relative_coords[:, :, 0] *= 2 * window_size[1] - 1 + + relative_position_index = np.zeros(shape=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype) + relative_position_index[1:, 1:] = relative_coords.sum(-1) # Wh*Ww, Wh*Ww + relative_position_index[0, 0:] = num_relative_distance - 3 + relative_position_index[0:, 0] = num_relative_distance - 2 + relative_position_index[0, 0] = num_relative_distance - 1 + return jnp.array(relative_position_index) + + +def ones_with_scale(key, shape, scale, dtype=jnp.float32): + return jnp.ones(shape, dtype) * scale + + +class FlaxBeitDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + rate: float + + @nn.module.compact + def __call__(self, inputs, deterministic: Optional[bool] = True): + if self.rate == 0.0: + return inputs + keep_prob = 1.0 - self.rate + if deterministic: + return inputs + else: + shape = (inputs.shape[0],) + (1,) * (inputs.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + rng = self.make_rng("droppath") + random_tensor = keep_prob + jax.random.uniform(rng, shape=shape, dtype=inputs.dtype) + binary_tensor = jnp.floor(random_tensor) + output = inputs / keep_prob * binary_tensor + return output + + +class FlaxBeitPatchEmbeddings(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.num_channels = self.config.num_channels + image_size = self.config.image_size + patch_size = self.config.patch_size + num_patches = (image_size // patch_size) * (image_size // patch_size) + patch_shape = (image_size // patch_size, image_size // patch_size) + self.num_patches = num_patches + self.patch_shape = patch_shape + self.projection = nn.Conv( + self.config.hidden_size, + kernel_size=(patch_size, patch_size), + strides=(patch_size, patch_size), + padding="VALID", + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + + def __call__(self, pixel_values): + num_channels = pixel_values.shape[-1] + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + embeddings = self.projection(pixel_values) + batch_size, _, _, channels = embeddings.shape + return jnp.reshape(embeddings, (batch_size, -1, channels)) + + +class FlaxBeitEmbeddings(nn.Module): + """Construct the CLS token, position and patch embeddings.""" + + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.cls_token = self.param("cls_token", nn.initializers.zeros, (1, 1, self.config.hidden_size)) + if self.config.use_mask_token: + self.mask_token = self.param("mask_token", nn.initializers.zeros, (1, 1, self.config.hidden_size)) + self.patch_embeddings = FlaxBeitPatchEmbeddings(self.config, dtype=self.dtype) + num_patches = self.patch_embeddings.num_patches + if self.config.use_absolute_position_embeddings: + self.position_embeddings = self.param( + "position_embeddings", nn.initializers.zeros, (1, num_patches + 1, self.config.hidden_size) + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, pixel_values, bool_masked_pos=None, deterministic=True): + embeddings = self.patch_embeddings(pixel_values) + batch_size, seq_len, _ = embeddings.shape + + cls_tokens = jnp.broadcast_to(self.cls_token, (batch_size, 1, self.config.hidden_size)) + cls_tokens = cls_tokens.astype(embeddings.dtype) + + if bool_masked_pos is not None: + mask_tokens = jnp.broadcast_to(self.mask_token, (batch_size, seq_len, self.config.hidden_size)) + mask_tokens = mask_tokens.astype(embeddings.dtype) + # replace the masked visual tokens by mask_tokens + w = jnp.expand_dims(bool_masked_pos, axis=-1) + embeddings = embeddings * (1 - w) + mask_tokens * w + + embeddings = jnp.concatenate((cls_tokens, embeddings), axis=1) + + if self.config.use_absolute_position_embeddings: + embeddings = embeddings + self.position_embeddings.astype(embeddings.dtype) + + embeddings = self.dropout(embeddings, deterministic=deterministic) + return embeddings + + +class FlaxBeitRelativePositionBias(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + num_relative_distance = (2 * self.window_size[0] - 1) * (2 * self.window_size[1] - 1) + 3 + self.relative_position_bias_table = self.param( + "relative_position_bias_table", + nn.initializers.zeros, + (num_relative_distance, self.config.num_attention_heads), + ) # 2*Wh-1 * 2*Ww-1, nH + # cls to token & token 2 cls & cls to cls + + self.relative_position_index = relative_position_index_init(self.window_size) + + def __call__(self): + index = self.relative_position_index.reshape(-1) + shape = (self.window_size[0] * self.window_size[1] + 1, self.window_size[0] * self.window_size[1] + 1, -1) + relative_position_bias = self.relative_position_bias_table[index].reshape(shape) # Wh*Ww,Wh*Ww,nH + return jnp.transpose(relative_position_bias, (2, 0, 1)) + + +class FlaxBeitSelfAttention(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + if self.config.hidden_size % self.config.num_attention_heads != 0 and not hasattr( + self.config, "embedding_size" + ): + raise ValueError( + f"The hidden size {self.config.hidden_size,} is not a multiple of the number of attention " + f"heads {self.config.num_attention_heads}." + ) + + self.query = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.key = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + use_bias=False, + ) + self.value = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + + self.relative_position_bias = ( + FlaxBeitRelativePositionBias(self.config, window_size=self.window_size, dtype=self.dtype) + if self.window_size + else None + ) + + def __call__( + self, hidden_states, relative_position_bias=None, deterministic: bool = True, output_attentions: bool = False + ): + head_dim = self.config.hidden_size // self.config.num_attention_heads + + query_states = self.query(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + value_states = self.value(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + key_states = self.key(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + + dropout_rng = None + if not deterministic and self.config.attention_probs_dropout_prob > 0.0: + dropout_rng = self.make_rng("dropout") + + attention_bias = jnp.array(0.0, dtype=self.dtype) + # Add relative position bias if present. + if self.relative_position_bias is not None: + attention_bias = jnp.expand_dims(self.relative_position_bias(), 0) + attention_bias = attention_bias.astype(query_states.dtype) + + # Add shared relative position bias if provided. + if relative_position_bias is not None: + attention_bias = attention_bias + relative_position_bias.astype(attention_bias.dtype) + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.config.attention_probs_dropout_prob, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) + + outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) + return outputs + + +class FlaxBeitSelfOutput(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxBeitAttention(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.attention = FlaxBeitSelfAttention(self.config, self.window_size, dtype=self.dtype) + self.output = FlaxBeitSelfOutput(self.config, dtype=self.dtype) + + def __call__( + self, hidden_states, relative_position_bias=None, deterministic=True, output_attentions: bool = False + ): + attn_outputs = self.attention( + hidden_states, relative_position_bias, deterministic=deterministic, output_attentions=output_attentions + ) + attn_output = attn_outputs[0] + attn_output = self.output(attn_output, deterministic=deterministic) + + outputs = (attn_output,) + + if output_attentions: + outputs += (attn_outputs[1],) + + return outputs + + +class FlaxBeitIntermediate(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.intermediate_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.activation = ACT2FN[self.config.hidden_act] + + def __call__(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.activation(hidden_states) + + return hidden_states + + +class FlaxBeitOutput(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + + return hidden_states + + +class FlaxBeitLayer(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + drop_path_rate: float + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.attention = FlaxBeitAttention(self.config, self.window_size, dtype=self.dtype) + self.intermediate = FlaxBeitIntermediate(self.config, dtype=self.dtype) + self.output = FlaxBeitOutput(self.config, dtype=self.dtype) + self.layernorm_before = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.drop_path = FlaxBeitDropPath(rate=self.drop_path_rate) + self.layernorm_after = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + + self.init_values = self.config.layer_scale_init_value + if self.init_values > 0: + self.lambda_1 = self.param("lambda_1", ones_with_scale, (self.config.hidden_size), self.init_values) + self.lambda_2 = self.param("lambda_2", ones_with_scale, (self.config.hidden_size), self.init_values) + else: + self.lambda_1 = None + self.lambda_2 = None + + def __call__( + self, hidden_states, relative_position_bias=None, deterministic: bool = True, output_attentions: bool = False + ): + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in BEiT, layernorm is applied before self-attention + relative_position_bias, + deterministic=deterministic, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + + # apply lambda_1 if present + if self.lambda_1 is not None: + attention_output = self.lambda_1.astype(attention_output.dtype) * attention_output + + # first residual connection + hidden_states = self.drop_path(attention_output, deterministic=deterministic) + hidden_states + + # in BEiT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + + layer_output = self.intermediate(layer_output) + layer_output = self.output(layer_output, deterministic=deterministic) + + # apply lambda_2 if present + if self.lambda_2 is not None: + layer_output = self.lambda_2.astype(layer_output.dtype) * layer_output + + # second residual connection + layer_output = self.drop_path(layer_output, deterministic=deterministic) + hidden_states + + outputs = (layer_output,) + + if output_attentions: + outputs += (self_attention_outputs[1],) + + return outputs + + +class FlaxBeitLayerCollection(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + drop_path_rates: List[float] + relative_position_bias: Callable[[], jnp.ndarray] + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxBeitLayer( + self.config, + window_size=self.window_size if self.config.use_relative_position_bias else None, + drop_path_rate=self.drop_path_rates[i], + name=str(i), + dtype=self.dtype, + ) + for i in range(self.config.num_hidden_layers) + ] + + def __call__( + self, + hidden_states, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states += (hidden_states,) + relative_position_bias = self.relative_position_bias() if self.relative_position_bias is not None else None + layer_outputs = layer( + hidden_states, relative_position_bias, deterministic=deterministic, output_attentions=output_attentions + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions += (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states,) + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxBeitEncoder(nn.Module): + config: BeitConfig + window_size: Tuple[int, int] + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + if self.config.use_shared_relative_position_bias: + self.relative_position_bias = FlaxBeitRelativePositionBias( + config=self.config, window_size=self.window_size, dtype=self.dtype + ) + + # stochastic depth decay rule + drop_path_rates = list(np.linspace(0, self.config.drop_path_rate, self.config.num_hidden_layers)) + self.layer = FlaxBeitLayerCollection( + self.config, + window_size=self.window_size, + drop_path_rates=drop_path_rates, + relative_position_bias=self.relative_position_bias + if self.config.use_shared_relative_position_bias + else None, + dtype=self.dtype, + ) + + def __call__( + self, + hidden_states, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return self.layer( + hidden_states, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +class FlaxBeitPreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = BeitConfig + base_model_prefix = "beit" + main_input_name = "pixel_values" + module_class: nn.Module = None + + def __init__( + self, + config: BeitConfig, + input_shape=None, + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + if input_shape is None: + input_shape = (1, config.image_size, config.image_size, config.num_channels) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + pixel_values = jnp.zeros(input_shape, dtype=self.dtype) + + params_rng, dropout_rng = jax.random.split(rng) + dropout_rng, droppath_rng = jax.random.split(dropout_rng) + rngs = {"params": params_rng, "dropout": dropout_rng, "droppath": droppath_rng} + + random_params = self.module.init(rngs, pixel_values, return_dict=False)["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(BEIT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def __call__( + self, + pixel_values, + bool_masked_pos=None, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + dropout_rng, droppath_rng = jax.random.split(dropout_rng) + rngs["dropout"] = dropout_rng + rngs["droppath"] = droppath_rng + + return self.module.apply( + {"params": params or self.params}, + jnp.array(pixel_values, dtype=jnp.float32), + bool_masked_pos, + not train, + output_attentions, + output_hidden_states, + return_dict, + rngs=rngs, + ) + + +class FlaxBeitPooler(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + if self.config.use_mean_pooling: + self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + + def __call__(self, hidden_states): + if self.config.use_mean_pooling: + # Mean pool the final hidden states of the patch tokens + patch_tokens = hidden_states[:, 1:, :] + pooled_output = self.layernorm(jnp.mean(patch_tokens, axis=1)) + else: + # Pool by simply taking the final hidden state of the [CLS] token + pooled_output = hidden_states[:, 0] + + return pooled_output + + +class FlaxBeitModule(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + add_pooling_layer: bool = True + + def setup(self): + self.embeddings = FlaxBeitEmbeddings(self.config, dtype=self.dtype) + self.encoder = FlaxBeitEncoder( + self.config, window_size=self.embeddings.patch_embeddings.patch_shape, dtype=self.dtype + ) + if not self.config.use_mean_pooling: + self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.pooler = FlaxBeitPooler(self.config, dtype=self.dtype) if self.add_pooling_layer else None + + def __call__( + self, + pixel_values, + bool_masked_pos=None, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + hidden_states = self.embeddings(pixel_values, bool_masked_pos, deterministic=deterministic) + + outputs = self.encoder( + hidden_states, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = outputs[0] + if not self.config.use_mean_pooling: + hidden_states = self.layernorm(hidden_states) + pooled = self.pooler(hidden_states) if self.add_pooling_layer else None + + if not return_dict: + # if pooled is None, don't return it + if pooled is None: + return (hidden_states,) + outputs[1:] + return (hidden_states, pooled) + outputs[1:] + + return FlaxBeitModelOutputWithPooling( + last_hidden_state=hidden_states, + pooler_output=pooled, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + "The bare Beit Model transformer outputting raw hidden-states without any specific head on top.", + BEIT_START_DOCSTRING, +) +class FlaxBeitModel(FlaxBeitPreTrainedModel): + module_class = FlaxBeitModule + + +FLAX_BEIT_MODEL_DOCSTRING = """ + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, FlaxBeitModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224-pt22k-ft22k") + >>> model = FlaxBeitModel.from_pretrained("microsoft/beit-base-patch16-224-pt22k-ft22k") + + >>> inputs = image_processor(images=image, return_tensors="np") + >>> outputs = model(**inputs) + >>> last_hidden_states = outputs.last_hidden_state + ``` +""" + +overwrite_call_docstring(FlaxBeitModel, FLAX_BEIT_MODEL_DOCSTRING) +append_replace_return_docstrings(FlaxBeitModel, output_type=FlaxBeitModelOutputWithPooling, config_class=BeitConfig) + + +class FlaxBeitForMaskedImageModelingModule(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.beit = FlaxBeitModule(self.config, add_pooling_layer=False, dtype=self.dtype) + + # Classifier head + self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.lm_head = nn.Dense( + self.config.vocab_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__( + self, + pixel_values=None, + bool_masked_pos=None, + deterministic: bool = True, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.beit( + pixel_values, + bool_masked_pos, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + sequence_output = self.layernorm(sequence_output) + prediction_scores = self.lm_head(sequence_output[:, 1:]) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return output + + return FlaxMaskedLMOutput( + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + "Beit Model transformer with a 'language' modeling head on top (to predict visual tokens).", + BEIT_START_DOCSTRING, +) +class FlaxBeitForMaskedImageModeling(FlaxBeitPreTrainedModel): + module_class = FlaxBeitForMaskedImageModelingModule + + +FLAX_BEIT_MLM_DOCSTRING = """ + bool_masked_pos (`numpy.ndarray` of shape `(batch_size, num_patches)`): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, BeitForMaskedImageModeling + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224-pt22k") + >>> model = BeitForMaskedImageModeling.from_pretrained("microsoft/beit-base-patch16-224-pt22k") + + >>> inputs = image_processor(images=image, return_tensors="np") + >>> outputs = model(**inputs) + >>> logits = outputs.logits + ``` +""" + +overwrite_call_docstring(FlaxBeitForMaskedImageModeling, FLAX_BEIT_MLM_DOCSTRING) +append_replace_return_docstrings( + FlaxBeitForMaskedImageModeling, output_type=FlaxMaskedLMOutput, config_class=BeitConfig +) + + +class FlaxBeitForImageClassificationModule(nn.Module): + config: BeitConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.beit = FlaxBeitModule(config=self.config, dtype=self.dtype, add_pooling_layer=True) + self.classifier = nn.Dense( + self.config.num_labels, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__( + self, + pixel_values=None, + bool_masked_pos=None, + deterministic: bool = True, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.beit( + pixel_values, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + logits = self.classifier(pooled_output) + + if not return_dict: + output = (logits,) + outputs[2:] + return output + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Beit Model transformer with an image classification head on top (a linear layer on top of the average of the final + hidden states of the patch tokens) e.g. for ImageNet. + """, + BEIT_START_DOCSTRING, +) +class FlaxBeitForImageClassification(FlaxBeitPreTrainedModel): + module_class = FlaxBeitForImageClassificationModule + + +FLAX_BEIT_CLASSIF_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> from transformers import AutoImageProcessor, FlaxBeitForImageClassification + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224") + >>> model = FlaxBeitForImageClassification.from_pretrained("microsoft/beit-base-patch16-224") + + >>> inputs = image_processor(images=image, return_tensors="np") + >>> outputs = model(**inputs) + >>> logits = outputs.logits + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_class_idx = logits.argmax(-1).item() + >>> print("Predicted class:", model.config.id2label[predicted_class_idx]) + ``` +""" + +overwrite_call_docstring(FlaxBeitForImageClassification, FLAX_BEIT_CLASSIF_DOCSTRING) +append_replace_return_docstrings( + FlaxBeitForImageClassification, output_type=FlaxSequenceClassifierOutput, config_class=BeitConfig +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/convnext/image_processing_convnext.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/convnext/image_processing_convnext.py new file mode 100644 index 0000000000000000000000000000000000000000..5e4d30c5c9e85b9a8fdb91c4718c07a32efcb40f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/convnext/image_processing_convnext.py @@ -0,0 +1,307 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for ConvNeXT.""" + +from typing import Dict, List, Optional, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import ( + center_crop, + get_resize_output_image_size, + normalize, + rescale, + resize, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + make_list_of_images, + to_numpy_array, + valid_images, +) +from ...utils import TensorType, is_vision_available, logging + + +if is_vision_available(): + import PIL + + +logger = logging.get_logger(__name__) + + +class ConvNextImageProcessor(BaseImageProcessor): + r""" + Constructs a ConvNeXT image processor. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be overriden + by `do_resize` in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 384}`): + Resolution of the output image after `resize` is applied. If `size["shortest_edge"]` >= 384, the image is + resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the image will + be matched to `int(size["shortest_edge"]/crop_pct)`, after which the image is cropped to + `(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`. Can + be overriden by `size` in the `preprocess` method. + crop_pct (`float` *optional*, defaults to 224 / 256): + Percentage of the image to crop. Only has an effect if `do_resize` is `True` and size < 384. Can be + overriden by `crop_pct` in the `preprocess` method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. Can be overriden by `resample` in the `preprocess` method. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. Can be overriden by `do_rescale` in + the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overriden by `rescale_factor` in the `preprocess` + method. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess` + method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`): + Mean to use if normalizing the image. This is a float or list of floats the length of the number of + channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`): + Standard deviation to use if normalizing the image. This is a float or list of floats the length of the + number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values"] + + def __init__( + self, + do_resize: bool = True, + size: Dict[str, int] = None, + crop_pct: float = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + **kwargs, + ) -> None: + super().__init__(**kwargs) + size = size if size is not None else {"shortest_edge": 384} + size = get_size_dict(size, default_to_square=False) + + self.do_resize = do_resize + self.size = size + # Default value set here for backwards compatibility where the value in config is None + self.crop_pct = crop_pct if crop_pct is not None else 224 / 256 + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_STANDARD_STD + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + crop_pct: float, + resample: PILImageResampling = PILImageResampling.BICUBIC, + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize an image. + + Args: + image (`np.ndarray`): + Image to resize. + size (`Dict[str, int]`): + Dictionary of the form `{"shortest_edge": int}`, specifying the size of the output image. If + `size["shortest_edge"]` >= 384 image is resized to `(size["shortest_edge"], size["shortest_edge"])`. + Otherwise, the smaller edge of the image will be matched to `int(size["shortest_edge"] / crop_pct)`, + after which the image is cropped to `(size["shortest_edge"], size["shortest_edge"])`. + crop_pct (`float`): + Percentage of the image to crop. Only has an effect if size < 384. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use when resizing the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size, default_to_square=False) + if "shortest_edge" not in size: + raise ValueError(f"Size dictionary must contain 'shortest_edge' key. Got {size.keys()}") + shortest_edge = size["shortest_edge"] + + if shortest_edge < 384: + # maintain same ratio, resizing shortest edge to shortest_edge/crop_pct + resize_shortest_edge = int(shortest_edge / crop_pct) + resize_size = get_resize_output_image_size(image, size=resize_shortest_edge, default_to_square=False) + image = resize(image=image, size=resize_size, resample=resample, data_format=data_format, **kwargs) + # then crop to (shortest_edge, shortest_edge) + return center_crop(image=image, size=(shortest_edge, shortest_edge), data_format=data_format, **kwargs) + else: + # warping (no cropping) when evaluated at 384 or larger + return resize( + image, size=(shortest_edge, shortest_edge), resample=resample, data_format=data_format, **kwargs + ) + + def rescale( + self, + image: np.ndarray, + scale: Union[int, float], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ): + """ + Rescale an image by a scale factor. image = image * scale. + + Args: + image (`np.ndarray`): + Image to rescale. + scale (`int` or `float`): + Scale to apply to the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return rescale(image, scale=scale, data_format=data_format, **kwargs) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, List[float]], + std: Union[float, List[float]], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Normalize an image. image = (image - image_mean) / image_std. + + Args: + image (`np.ndarray`): + Image to normalize. + image_mean (`float` or `List[float]`): + Image mean. + image_std (`float` or `List[float]`): + Image standard deviation. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return normalize(image, mean=mean, std=std, data_format=data_format, **kwargs) + + def preprocess( + self, + images: ImageInput, + do_resize: bool = None, + size: Dict[str, int] = None, + crop_pct: float = None, + resample: PILImageResampling = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: ChannelDimension = ChannelDimension.FIRST, + **kwargs, + ) -> PIL.Image.Image: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Size of the output image after `resize` has been applied. If `size["shortest_edge"]` >= 384, the image + is resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the + image will be matched to `int(size["shortest_edge"]/ crop_pct)`, after which the image is cropped to + `(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`. + crop_pct (`float`, *optional*, defaults to `self.crop_pct`): + Percentage of the image to crop if size < 384. + resample (`int`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. This can be one of `PILImageResampling`, filters. Only + has an effect if `do_resize` is set to `True`. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image values between [0 - 1]. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `ChannelDimension.LAST`: image in (height, width, num_channels) format. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + crop_pct = crop_pct if crop_pct is not None else self.crop_pct + resample = resample if resample is not None else self.resample + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + + size = size if size is not None else self.size + size = get_size_dict(size, default_to_square=False) + + images = make_list_of_images(images) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + if do_resize and size is None or resample is None: + raise ValueError("Size and resample must be specified if do_resize is True.") + + if do_resize and size["shortest_edge"] < 384 and crop_pct is None: + raise ValueError("crop_pct must be specified if size < 384.") + + if do_rescale and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_resize: + images = [self.resize(image=image, size=size, crop_pct=crop_pct, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image=image, scale=rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image=image, mean=image_mean, std=image_std) for image in images] + + images = [to_channel_dimension_format(image, data_format) for image in images] + + data = {"pixel_values": images} + return BatchFeature(data=data, tensor_type=return_tensors) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cpmant/modeling_cpmant.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cpmant/modeling_cpmant.py new file mode 100644 index 0000000000000000000000000000000000000000..db0e0f468cefe827f8385a0ee6624e8b817c10ab --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cpmant/modeling_cpmant.py @@ -0,0 +1,880 @@ +# coding=utf-8 +# Copyright 2022 The OpenBMB Team and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch CPMAnt""" + + +import math +from typing import List, Optional, Tuple, Union + +import torch +import torch.nn.functional as F +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast +from ...modeling_utils import PreTrainedModel +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_cpmant import CpmAntConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "openbmb/cpm-ant-10b" +_CONFIG_FOR_DOC = "CpmAntConfig" + +CPMANT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "openbmb/cpm-ant-10b", + # See all CPMAnt models at https://huggingface.co/models?filter=cpmant +] + + +class CpmAntLayerNorm(nn.Module): + """ + We use Root Mean Square (RMS) Layer Normalization, please see https://arxiv.org/abs/1910.07467 for details." + """ + + def __init__(self, config: CpmAntConfig): + super().__init__() + + self.eps = config.eps + self.dim_norm = config.hidden_size + self.weight = nn.Parameter(torch.empty(config.hidden_size)) + + def forward(self, hidden_states: torch.Tensor): + """ + Args: + hidden_states (`torch.Tensor` of shape `(batch, seq_len, dim_in)`) + """ + if hidden_states.size(-1) != self.dim_norm: + raise AssertionError("hidden_states.size(-1) != self.dim_norm") + old_dtype = hidden_states.dtype + variance = hidden_states.to(torch.float32).pow(2).mean(dim=-1, keepdim=True) + hidden_states = (hidden_states * torch.rsqrt(variance + self.eps)).to(old_dtype) * self.weight + return hidden_states + + +class CpmAntAttention(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.dim_model = config.hidden_size + self.num_heads = config.num_attention_heads + self.dim_head = config.dim_head + + self.project_q = nn.Linear(self.dim_model, self.num_heads * self.dim_head, bias=False) + self.project_k = nn.Linear(self.dim_model, self.num_heads * self.dim_head, bias=False) + self.project_v = nn.Linear(self.dim_model, self.num_heads * self.dim_head, bias=False) + + self.attention_out = nn.Linear(self.num_heads * self.dim_head, self.dim_model, bias=False) + + self.softmax = torch.nn.Softmax(dim=-1) + + if config.dropout_p is not None: + self.dropout = torch.nn.Dropout(p=config.dropout_p) + else: + self.dropout = None + + def forward( + self, + hidden_q: torch.Tensor, + hidden_kv: torch.Tensor, + attention_mask: torch.BoolTensor, + position_bias: torch.Tensor, + output_attentions: Optional[bool] = False, + past_key_values: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + use_cache: Optional[bool] = None, + ): + """ + Args: + hidden_q (`torch.Tensor`): + Input of transformer block(self-attention block). It can be the raw embedding of a batch of sequences. + hidden_kv (`torch.Tensor` of shape `(batch, len_k, dim_model)`)): + Tensor *key_value* and *query* of shape `(batch, len_k, dim_model)` + attention_mask (`torch.Tensor` of shape `(batch, len_seq, len_seq)`): + Avoid invalid areas to participate in the calculation of self-attention. + position_bias (`torch.Tensor` of shape `(batch, len_seq, len_seq)`): + Provide positional information to self-attention block. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + past_key_values (`Tuple[torch.Tensor, torch.Tensor]`, *optional*): + Cached past key and value projection states. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + """ + batch_size = hidden_q.size(0) + len_q = hidden_q.size(1) + len_k = hidden_kv.size(1) + + query = self.project_q(hidden_q) + key = self.project_k(hidden_kv) + value = self.project_v(hidden_kv) + + query = query.view(batch_size, len_q, self.num_heads, self.dim_head).permute(0, 2, 1, 3) + key = key.view(batch_size, len_k, self.num_heads, self.dim_head).permute(0, 2, 1, 3) + value = value.view(batch_size, len_k, self.num_heads, self.dim_head).permute(0, 2, 1, 3) + + if past_key_values is not None: + key = torch.cat([past_key_values[0], key], dim=-2) + value = torch.cat([past_key_values[1], value], dim=-2) + len_k = key.size(-2) + + # (batch_size, num_heads, len_q, dim_head) @ (batch_size, num_heads, dim_head, len_k) -> (batch_size, num_heads, len_q, len_k) + score = torch.matmul(query, key.transpose(-1, -2)) / math.sqrt(self.dim_head) + score = score + position_bias + + score = torch.masked_fill( + score, + attention_mask.view(batch_size, 1, len_q, len_k) == torch.tensor(False), + torch.scalar_tensor(float("-inf"), device=score.device, dtype=score.dtype), + ) + score = self.softmax(score) + + score = torch.masked_fill( + score, + attention_mask.view(batch_size, 1, len_q, len_k) == torch.tensor(False), + torch.scalar_tensor(0, device=score.device, dtype=score.dtype), + ) + if output_attentions: + attn_weights = score + else: + attn_weights = None + + if self.dropout is not None: + score = self.dropout(score) + + # (batch_size, num_heads, len_q, len_k) @ (batch_size, num_heads, len_k, dim_head) -> (batch_size, num_heads, len_q, dim_head) + score = torch.matmul(score, value) + + score = score.view(batch_size, self.num_heads, len_q, self.dim_head).permute(0, 2, 1, 3) + score = score.contiguous().view(batch_size, len_q, self.num_heads * self.dim_head) + + score = self.attention_out(score) + + past_key_values = None + if use_cache: + past_key_values = (key, value) + + return score, attn_weights, past_key_values + + +class CpmAntSelfAttentionBlock(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.layernorm_before_attention = CpmAntLayerNorm(config) + self.self_attention = CpmAntAttention(config) + if config.dropout_p: + self.dropout = torch.nn.Dropout(config.dropout_p) + else: + self.dropout = None + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_bias: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + past_key_values: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + use_cache: Optional[bool] = None, + ): + """ + Args: + hidden_states (`torch.Tensor` of shape `(batch, len_seq, dim_model)`): + Input of transformer block(self-attention block). It can be the raw embedding of a batch of sequences. + attention_mask (`torch.Tensor` of shape `(batch, len_seq, len_seq)`): + Avoid invalid areas to participate in the calculation of self-attention. + position_bias (`torch.Tensor` of shape `(batch, len_seq, len_seq)`): + Provide positional information to self-attention block. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + past_key_values (`Tuple(torch.FloatTensor)`, *optional*): + Cached past key and value projection states. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + """ + outputs = self.layernorm_before_attention(hidden_states) + outputs = self.self_attention( + outputs, outputs, attention_mask, position_bias, output_attentions, past_key_values, use_cache + ) + + outputs, attn_weights, current_key_value = outputs + + if self.dropout is not None: + outputs = self.dropout(outputs) + hidden_states = hidden_states + outputs + + return hidden_states, attn_weights, current_key_value + + +class CpmAntDenseGatedACT(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.w_0 = nn.Linear(config.hidden_size, config.dim_ff, bias=False) + self.w_1 = nn.Linear(config.hidden_size, config.dim_ff, bias=False) + self.act = torch.nn.GELU() + + def forward(self, hidden_states: torch.Tensor): + """Transform an input tensor from one feature space to another via a nonlinear operation + + Args: + hidden_states (`torch.Tensor` of shape `(batch, seq_len, dim_in)`) + """ + gate_score = self.act(self.w_0(hidden_states)) + hidden_states = self.w_1(hidden_states) + + hidden_states = gate_score * hidden_states + return hidden_states + + +class CpmAntFeedForward(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.w_in = CpmAntDenseGatedACT(config) + if config.dropout_p is not None: + self.dropout = torch.nn.Dropout(config.dropout_p) + else: + self.dropout = None + + self.w_out = nn.Linear(config.dim_ff, config.hidden_size, bias=False) + + def forward(self, hidden_states: torch.Tensor): + """ + Args: + hidden_states (`torch.Tensor` of shape `(batch, seq_len, dim_in)`) + """ + hidden_states = self.w_in(hidden_states) + + if self.dropout is not None: + hidden_states = self.dropout(hidden_states) + + hidden_states = self.w_out(hidden_states) + + return hidden_states + + +class CpmAntFFNBlock(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.layernorm_before_ffn = CpmAntLayerNorm(config) + self.ffn = CpmAntFeedForward(config) + if config.dropout_p: + self.dropout = torch.nn.Dropout(config.dropout_p) + else: + self.dropout = None + + def forward( + self, + hidden_states: torch.Tensor, + ): + """ + Args: + hidden_states (`torch.Tensor` of shape `(batch, len_seq, dim_model)`): + Hidden states before feed forward layer. + """ + ln_outputs = self.layernorm_before_ffn(hidden_states) + outputs = self.ffn(ln_outputs) + if self.dropout is not None: + outputs = self.dropout(outputs) + hidden_states = hidden_states + outputs + return hidden_states + + +class CpmAntTransformerBlock(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.self_att = CpmAntSelfAttentionBlock(config) + self.ffn = CpmAntFFNBlock(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_bias: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + past_key_values: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + use_cache: Optional[bool] = None, + ): + """ + Args: + hidden_states (`torch.Tensor`): + Input to the layer of shape `(batch, seq_len, dim_model)` + attention_mask (`torch.Tensor`): + Avoid invalid areas to participate in the calculation of shape `(batch, seq_len, seq_len)` + position_bias (`torch.Tensor`): + Provides position information to attention mechanism of shape `(num_heads, seq_len, seq_len)` + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + past_key_values (`Tuple[torch.Tensor, torch.Tensor])`, *optional*): + Cached past key and value projection states + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + """ + hidden_states = self.self_att( + hidden_states, + attention_mask=attention_mask, + position_bias=position_bias, + output_attentions=output_attentions, + past_key_values=past_key_values, + use_cache=use_cache, + ) + + hidden_states, attn_weights, current_key_value = hidden_states + + hidden_states = self.ffn(hidden_states) + + return hidden_states, attn_weights, current_key_value + + +class CpmAntEncoder(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + self.num_layers = config.num_hidden_layers + self.layers = nn.ModuleList([CpmAntTransformerBlock(config) for ith in range(self.num_layers)]) + + self.output_layernorm = CpmAntLayerNorm(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_bias: torch.Tensor, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + past_key_values: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + use_cache: Optional[bool] = None, + ): + """ + Args: + hidden_states (`torch.Tensor`): + Input to the layer of shape `(batch, seq_len, dim_model)` + attention_mask (`torch.Tensor`): + Avoid invalid areas to participate in the calculation of shape `(batch, seq_len, seq_len)` + position_bias (`torch.Tensor`): + Provides position information to attention mechanism of shape `(num_heads, seq_len, seq_len)` + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. + past_key_values (`Tuple[torch.Tensor, torch.Tensor])`, *optional*): + Cached past key and value projection states + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + """ + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + current_key_values = () if use_cache else None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states += (hidden_states,) + layer_outputs = layer( + hidden_states, + attention_mask, + position_bias, + output_attentions=output_attentions, + past_key_values=past_key_values[i] if past_key_values else None, + use_cache=use_cache, + ) + hidden_states, attn_weights, current_key_value = layer_outputs + if output_attentions: + all_self_attns += (attn_weights,) + if current_key_value is not None: + current_key_values = current_key_values + (current_key_value,) + + hidden_states = self.output_layernorm(hidden_states) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + return hidden_states, current_key_values, all_hidden_states, all_self_attns + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->CPMAnt +class CpmAntIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +class CpmAntSegmentPositionEmbedding(nn.Module): + def __init__(self, config: CpmAntConfig): + super().__init__() + + self.num_heads = config.num_attention_heads + self.num_buckets = config.position_bias_num_buckets + self.max_distance = config.position_bias_max_distance + self.num_segments = config.segment_types + + self.relative_attention_bias = nn.Parameter( + torch.empty( + config.segment_types * config.segment_types + config.position_bias_num_buckets, + config.num_attention_heads, + ) + ) + + def forward( + self, + key_pos: torch.Tensor, + query_pos: torch.Tensor, + key_segment: torch.Tensor, + query_segment: torch.Tensor, + ): + with torch.no_grad(): + batch = key_pos.size(0) + keylen = key_pos.size(1) + querylen = query_pos.size(1) + + if key_pos.size(0) != query_pos.size(0): + raise AssertionError( + f"key_pos.size(0) should be equal to query_pos.size(0), but got {key_pos.size(0)} and {query_pos.size(0)}!" + ) + if keylen != key_segment.size(1) or querylen != query_segment.size(1): + raise AssertionError( + f"keylen should be equal to key_segment.size(1), but got {keylen} and {key_segment.size(1)}!" + ) + if querylen != query_segment.size(1): + raise AssertionError( + f"querylen should be equal to query_segment.size(1), but got {querylen} and {query_segment.szie(1)}!" + ) + + key_pos = key_pos.view(batch, -1, keylen) + query_pos = query_pos.view(batch, querylen, -1) + key_segment = key_segment.view(batch, -1, keylen) + query_segment = query_segment.view(batch, querylen, -1) + + relative_position_bucket = self._segment_relative_position_bucket(query_segment, key_segment) + relative_position_bucket = relative_position_bucket + self.num_buckets + + # (batch, len_q, len_k) + absolute_position_bucket = self._position_bucket( + torch.arange(keylen, dtype=torch.int32, device=relative_position_bucket.device)[None, :] + - torch.arange(querylen, dtype=torch.int32, device=relative_position_bucket.device)[:, None], + num_buckets=self.num_buckets, + max_distance=self.max_distance, + ) + relative_position_bucket = torch.where( + (key_segment == query_segment), + absolute_position_bucket[None, :, :], + relative_position_bucket, + ) + + # (batch, len_q, len_k, num_heads) + embeds = F.embedding(relative_position_bucket, self.relative_attention_bias) + # (batch, num_heads, len_q, len_k) + embeds = embeds.permute(0, 3, 1, 2).contiguous() + return embeds + + def _segment_relative_position_bucket(self, query_segment, key_segment): + return query_segment * self.num_segments + key_segment + + def _position_bucket(self, relative_position, num_buckets=32, max_distance=128): + relative_buckets = 0 + # always bidirectional in CPMAnt + num_buckets //= 2 + relative_buckets = (relative_position > 0).to(torch.int32) * num_buckets + relative_position = torch.abs(relative_position) + max_exact = num_buckets // 2 + is_small = relative_position < max_exact + relative_postion_if_large = max_exact + ( + torch.log(relative_position.float() / max_exact) + / math.log(max_distance / max_exact) + * (num_buckets - max_exact) + ).to(torch.int32) + relative_postion_if_large = torch.min( + relative_postion_if_large, + torch.full_like(relative_postion_if_large, num_buckets - 1), + ) + relative_buckets += torch.where(is_small, relative_position.to(torch.int32), relative_postion_if_large) + return relative_buckets + + +# Copied from transformers.models.bert.modeling_bert.BertOutput with Bert->CPMAnt +class CpmAntOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class CpmAntPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = CpmAntConfig + base_model_prefix = "cpmant" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.init_std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.init_std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, CpmAntLayerNorm): + module.weight.data.fill_(1.0) + elif isinstance(module, CpmAntSegmentPositionEmbedding): + module.relative_attention_bias.data.normal_(mean=0.0, std=self.config.init_std) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, CpmAntEncoder): + module.gradient_checkpointing = value + + +CPMANT_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters + config ([`~CpmAntConfig`]): Model configuration class with all the parameters of the + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +CPMANT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.Tensor` of shape `(batch_size, seq_len)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`CPMAntTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention + blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare CPMAnt Model outputting raw hidden-states without any specific head on top.", + CPMANT_START_DOCSTRING, +) +class CpmAntModel(CpmAntPreTrainedModel): + def __init__(self, config: CpmAntConfig): + super().__init__(config) + self.encoder = CpmAntEncoder(config) + self.segment_embedding = nn.Embedding(config.segment_types, config.hidden_size) + self.input_embedding = nn.Embedding( + config.vocab_size + config.prompt_types * config.prompt_length, config.hidden_size + ) + self.position_bias = CpmAntSegmentPositionEmbedding(config) + self.prompt_length = config.prompt_length + self.vocab_size = config.vocab_size + + self.post_init() + + def get_input_embeddings(self): + return self.input_embedding + + def set_input_embeddings(self, embeddings, **kwargs): + self.input_embedding = embeddings + + def _prepare_attention_mask(self, input_ids, span, context, length): + batch = input_ids.size(0) + seqlen = input_ids.size(1) + device = input_ids.device + directional_mask_2d = torch.arange(seqlen, device=device) <= torch.arange(seqlen, device=device).view(-1, 1) + attention_mask = context[:, None, :] | ( + context[:, :, None].logical_not() & directional_mask_2d.view(1, seqlen, seqlen) + ) + attention_mask = attention_mask & (span[:, None, :] == span[:, :, None]) + # mask for left padding + mask_1d = ( + torch.tensor(list(range(seqlen - self.prompt_length))[::-1], device=device)[None, :].repeat(batch, 1) + < length[:, None] + ) + mask_1d = torch.cat((torch.ones(batch, self.prompt_length, device=device).bool(), mask_1d), dim=1) + attention_mask = mask_1d.view(batch, seqlen, 1) & mask_1d.view(batch, 1, seqlen) & attention_mask + return attention_mask + + @add_start_docstrings_to_model_forward(CPMANT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPast, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + use_cache: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + use_cache = use_cache if use_cache is not None else self.config.use_cache + + # add prompts ahead + if input_ids.dtype != torch.int32: + input_ids = input_ids.to(torch.int32) + dtype, device = input_ids.dtype, input_ids.device + segment = torch.where(input_ids != 0, 2, 0).to(dtype=dtype, device=device) + length = (segment != 0).sum(-1).to(dtype=dtype, device=device) + input_ids = torch.cat( + ( + torch.arange( + self.prompt_length * 2 + self.vocab_size, + self.prompt_length * 3 + self.vocab_size, + dtype=dtype, + device=device, + ).repeat(input_ids.size(0), 1), + input_ids, + ), + dim=1, + ) + batch, seq_length = input_ids.size() + segment = torch.cat((torch.zeros(batch, self.prompt_length, dtype=dtype, device=device), segment), dim=1) + context = torch.full((batch, seq_length), 1, dtype=dtype, device=device) + position = torch.arange(seq_length, dtype=dtype, device=device).repeat(batch, 1) + span = torch.full((batch, seq_length), 0, dtype=dtype, device=device) + + if past_key_values is None: + past_length = 0 + past_key_values = tuple([None] * self.encoder.num_layers) + input_ids = input_ids.contiguous() + hidden_states = self.input_embedding(input_ids) + segment_states = self.segment_embedding(segment) + hidden_states = hidden_states + segment_states + else: + past_length = past_key_values[0][0].size(-2) + segment_states = self.segment_embedding(segment) + hidden_states = self.input_embedding(input_ids) + segment_states[:, -1:, :] + + attention_mask = self._prepare_attention_mask(input_ids, span, context, length) + position_bias = self.position_bias(position, position, segment, segment) + + attention_mask = attention_mask[:, past_length:, :] + position_bias = position_bias[:, :, past_length:, :] + hidden_states = hidden_states[:, past_length:, :] + + hidden_states, present_key_values, all_hidden_states, all_attentions = self.encoder( + hidden_states, + attention_mask, + position_bias, + output_attentions, + output_hidden_states, + past_key_values, + use_cache, + ) + + if past_length == 0: + hidden_states = hidden_states[:, self.prompt_length :, :] + # drop the prompt + if all_attentions is not None: + new_attentions = () + for attention in all_attentions: + new_attentions += (attention[:, :, self.prompt_length :, self.prompt_length :],) + all_attentions = new_attentions + if all_hidden_states is not None: + new_hidden_states = () + for hidden_state in all_hidden_states: + new_hidden_states += (hidden_state[:, self.prompt_length :, :],) + all_hidden_states = new_hidden_states + + if not return_dict: + return tuple( + v for v in [hidden_states, present_key_values, all_hidden_states, all_attentions] if v is not None + ) + + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=present_key_values, + hidden_states=all_hidden_states, + attentions=all_attentions, + ) + + +@add_start_docstrings( + """ + The CPMAnt Model with a language modeling head on top (linear layer with weights tied to the input embeddings). + """, + CPMANT_START_DOCSTRING, +) +class CpmAntForCausalLM(CpmAntPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"lm_head.weight"] + + def __init__(self, config: CpmAntConfig): + super().__init__(config) + self.cpmant = CpmAntModel(config) + + # lm_head.weight is tied to cpmant.input_embedding.weight + self.lm_head = nn.Linear( + config.hidden_size, config.vocab_size + config.prompt_types * config.prompt_length, bias=False + ) + self.post_init() + + @add_start_docstrings_to_model_forward(CPMANT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=CausalLMOutputWithPast, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + past_key_values: Optional[List[Tuple[torch.Tensor, torch.Tensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + return_dict: Optional[bool] = None, + attention_mask: Optional[torch.Tensor] = None, # dummy parameter for text-generation pipeline + **kwargs, + ) -> Union[Tuple, CausalLMOutputWithPast]: + r""" + Args: + input_ids (`torch.Tensor` of shape `(batch_size, seq_len)`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`CPMAntTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the + cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding + (see `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. + labels (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + CPMAnt will process attention mask automatically, this parameter is a dummy parameter for + text-generation pipeline. + + Example: + + Text Generation with CpmAntForCausalLM. + ```python + >>> from transformers import CPMAntTokenizer, CpmAntForCausalLM + + >>> texts = "今天天气不错," + >>> model = CpmAntForCausalLM.from_pretrained("openbmb/cpm-ant-10b") + >>> tokenizer = CPMAntTokenizer.from_pretrained("openbmb/cpm-ant-10b") + >>> input_ids = tokenizer(texts, return_tensors="pt") + >>> outputs = model.generate(**input_ids) + >>> output_texts = tokenizer.batch_decode(outputs) + >>> print(output_texts) + ['今天天气不错,阳光明媚,我和妈妈一起去超市买东西。\n在超市里,我看到了一个很好玩的玩具,它的名字叫“机器人”。它有一个圆圆的脑袋,两只圆圆的眼睛,还有一个圆圆的'] + ``` + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + model_output = self.cpmant( + input_ids, output_attentions, output_hidden_states, past_key_values, use_cache, return_dict + ) + hidden_states = model_output.last_hidden_state if return_dict else model_output[0] + + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + loss_func = CrossEntropyLoss() + loss = loss_func(logits.view(-1, logits.size(-1)), labels.view(-1)) + + if not return_dict: + output = (logits,) + model_output[1:] + return ((loss,) + output) if loss is not None else output + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=model_output.past_key_values, + hidden_states=model_output.hidden_states, + attentions=model_output.attentions, + ) + + def get_input_embeddings(self): + return self.cpmant.input_embedding + + def set_input_embeddings(self, embeddings): + self.cpmant.input_embedding = embeddings + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def prepare_inputs_for_generation(self, input_ids, **kwargs): + input_ids = input_ids.int() + # save the memory usage of dummy attention mask + if "attention_mask" in kwargs: + kwargs["attention_mask"] = torch.zeros(1, 1) + + return { + "input_ids": input_ids, + "use_cache": kwargs["use_cache"], + "past_key_values": kwargs.get("past_key_values", None), + } + + def _reorder_cache(self, past_key_values, beam_idx): + past_key_values = [list(each) if each is not None else each for each in past_key_values] + for key_value_layer in past_key_values: + key_value_layer[0] = key_value_layer[0][beam_idx] + key_value_layer[1] = key_value_layer[1][beam_idx] + return past_key_values diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5241bb5a5f3a7a5ace9c7786926e1ff212e751fe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/__init__.py @@ -0,0 +1,81 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tf_available, is_torch_available + + +_import_structure = {"configuration_cvt": ["CVT_PRETRAINED_CONFIG_ARCHIVE_MAP", "CvtConfig"]} + + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_cvt"] = [ + "CVT_PRETRAINED_MODEL_ARCHIVE_LIST", + "CvtForImageClassification", + "CvtModel", + "CvtPreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_cvt"] = [ + "TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFCvtForImageClassification", + "TFCvtModel", + "TFCvtPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_cvt import CVT_PRETRAINED_CONFIG_ARCHIVE_MAP, CvtConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_cvt import ( + CVT_PRETRAINED_MODEL_ARCHIVE_LIST, + CvtForImageClassification, + CvtModel, + CvtPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_cvt import ( + TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST, + TFCvtForImageClassification, + TFCvtModel, + TFCvtPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..30a65beb7e963c0b76fdec37285d94739b268e3d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/cvt/convert_cvt_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,362 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert CvT checkpoints from the original repository. + +URL: https://github.com/microsoft/CvT""" + + +import argparse +import json +from collections import OrderedDict + +import torch +from huggingface_hub import cached_download, hf_hub_url + +from transformers import AutoFeatureExtractor, CvtConfig, CvtForImageClassification + + +def embeddings(idx): + """ + The function helps in renaming embedding layer weights. + + Args: + idx: stage number in original model + """ + embed = [] + embed.append( + ( + f"cvt.encoder.stages.{idx}.embedding.convolution_embeddings.projection.weight", + f"stage{idx}.patch_embed.proj.weight", + ) + ) + embed.append( + ( + f"cvt.encoder.stages.{idx}.embedding.convolution_embeddings.projection.bias", + f"stage{idx}.patch_embed.proj.bias", + ) + ) + embed.append( + ( + f"cvt.encoder.stages.{idx}.embedding.convolution_embeddings.normalization.weight", + f"stage{idx}.patch_embed.norm.weight", + ) + ) + embed.append( + ( + f"cvt.encoder.stages.{idx}.embedding.convolution_embeddings.normalization.bias", + f"stage{idx}.patch_embed.norm.bias", + ) + ) + return embed + + +def attention(idx, cnt): + """ + The function helps in renaming attention block layers weights. + + Args: + idx: stage number in original model + cnt: count of blocks in each stage + """ + attention_weights = [] + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.convolution.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.conv.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.normalization.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.bn.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.normalization.bias", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.bn.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.normalization.running_mean", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.bn.running_mean", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.normalization.running_var", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.bn.running_var", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_query.convolution_projection.normalization.num_batches_tracked", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_q.bn.num_batches_tracked", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.convolution.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.conv.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.normalization.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.bn.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.normalization.bias", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.bn.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.normalization.running_mean", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.bn.running_mean", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.normalization.running_var", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.bn.running_var", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_key.convolution_projection.normalization.num_batches_tracked", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_k.bn.num_batches_tracked", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.convolution.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.conv.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.normalization.weight", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.bn.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.normalization.bias", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.bn.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.normalization.running_mean", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.bn.running_mean", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.normalization.running_var", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.bn.running_var", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.convolution_projection_value.convolution_projection.normalization.num_batches_tracked", + f"stage{idx}.blocks.{cnt}.attn.conv_proj_v.bn.num_batches_tracked", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_query.weight", + f"stage{idx}.blocks.{cnt}.attn.proj_q.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_query.bias", + f"stage{idx}.blocks.{cnt}.attn.proj_q.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_key.weight", + f"stage{idx}.blocks.{cnt}.attn.proj_k.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_key.bias", + f"stage{idx}.blocks.{cnt}.attn.proj_k.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_value.weight", + f"stage{idx}.blocks.{cnt}.attn.proj_v.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.attention.projection_value.bias", + f"stage{idx}.blocks.{cnt}.attn.proj_v.bias", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.output.dense.weight", + f"stage{idx}.blocks.{cnt}.attn.proj.weight", + ) + ) + attention_weights.append( + ( + f"cvt.encoder.stages.{idx}.layers.{cnt}.attention.output.dense.bias", + f"stage{idx}.blocks.{cnt}.attn.proj.bias", + ) + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.intermediate.dense.weight", f"stage{idx}.blocks.{cnt}.mlp.fc1.weight") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.intermediate.dense.bias", f"stage{idx}.blocks.{cnt}.mlp.fc1.bias") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.output.dense.weight", f"stage{idx}.blocks.{cnt}.mlp.fc2.weight") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.output.dense.bias", f"stage{idx}.blocks.{cnt}.mlp.fc2.bias") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.layernorm_before.weight", f"stage{idx}.blocks.{cnt}.norm1.weight") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.layernorm_before.bias", f"stage{idx}.blocks.{cnt}.norm1.bias") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.layernorm_after.weight", f"stage{idx}.blocks.{cnt}.norm2.weight") + ) + attention_weights.append( + (f"cvt.encoder.stages.{idx}.layers.{cnt}.layernorm_after.bias", f"stage{idx}.blocks.{cnt}.norm2.bias") + ) + return attention_weights + + +def cls_token(idx): + """ + Function helps in renaming cls_token weights + """ + token = [] + token.append((f"cvt.encoder.stages.{idx}.cls_token", "stage2.cls_token")) + return token + + +def final(): + """ + Function helps in renaming final classification layer + """ + head = [] + head.append(("layernorm.weight", "norm.weight")) + head.append(("layernorm.bias", "norm.bias")) + head.append(("classifier.weight", "head.weight")) + head.append(("classifier.bias", "head.bias")) + return head + + +def convert_cvt_checkpoint(cvt_model, image_size, cvt_file_name, pytorch_dump_folder): + """ + Fucntion to convert the microsoft cvt checkpoint to huggingface checkpoint + """ + img_labels_file = "imagenet-1k-id2label.json" + num_labels = 1000 + + repo_id = "huggingface/label-files" + num_labels = num_labels + id2label = json.load(open(cached_download(hf_hub_url(repo_id, img_labels_file, repo_type="dataset")), "r")) + id2label = {int(k): v for k, v in id2label.items()} + + id2label = id2label + label2id = {v: k for k, v in id2label.items()} + + config = config = CvtConfig(num_labels=num_labels, id2label=id2label, label2id=label2id) + + # For depth size 13 (13 = 1+2+10) + if cvt_model.rsplit("/", 1)[-1][4:6] == "13": + config.depth = [1, 2, 10] + + # For depth size 21 (21 = 1+4+16) + elif cvt_model.rsplit("/", 1)[-1][4:6] == "21": + config.depth = [1, 4, 16] + + # For wide cvt (similar to wide-resnet) depth size 24 (w24 = 2 + 2 20) + else: + config.depth = [2, 2, 20] + config.num_heads = [3, 12, 16] + config.embed_dim = [192, 768, 1024] + + model = CvtForImageClassification(config) + feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/convnext-base-224-22k-1k") + feature_extractor.size["shortest_edge"] = image_size + original_weights = torch.load(cvt_file_name, map_location=torch.device("cpu")) + + huggingface_weights = OrderedDict() + list_of_state_dict = [] + + for idx in range(len(config.depth)): + if config.cls_token[idx]: + list_of_state_dict = list_of_state_dict + cls_token(idx) + list_of_state_dict = list_of_state_dict + embeddings(idx) + for cnt in range(config.depth[idx]): + list_of_state_dict = list_of_state_dict + attention(idx, cnt) + + list_of_state_dict = list_of_state_dict + final() + for gg in list_of_state_dict: + print(gg) + for i in range(len(list_of_state_dict)): + huggingface_weights[list_of_state_dict[i][0]] = original_weights[list_of_state_dict[i][1]] + + model.load_state_dict(huggingface_weights) + model.save_pretrained(pytorch_dump_folder) + feature_extractor.save_pretrained(pytorch_dump_folder) + + +# Download the weights from zoo: https://1drv.ms/u/s!AhIXJn_J-blW9RzF3rMW7SsLHa8h?e=blQ0Al + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--cvt_model", + default="cvt-w24", + type=str, + help="Name of the cvt model you'd like to convert.", + ) + parser.add_argument( + "--image_size", + default=384, + type=int, + help="Input Image Size", + ) + parser.add_argument( + "--cvt_file_name", + default=r"cvtmodels\CvT-w24-384x384-IN-22k.pth", + type=str, + help="Input Image Size", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + + args = parser.parse_args() + convert_cvt_checkpoint(args.cvt_model, args.image_size, args.cvt_file_name, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_audio.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_audio.py new file mode 100644 index 0000000000000000000000000000000000000000..2ec526924f36ebe589b4b1f52e60b52547618f4e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_audio.py @@ -0,0 +1,284 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Data2VecText configuration""" + +import math + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DATA2VEC_AUDIO_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/data2vec-base-960h": "https://huggingface.co/facebook/data2vec-audio-base-960h/resolve/main/config.json", + # See all Data2VecAudio models at https://huggingface.co/models?filter=data2vec-audio +} + + +class Data2VecAudioConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Data2VecAudioModel`]. It is used to instantiate + an Data2VecAudio model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the Data2VecAudio + [facebook/data2vec-audio-base-960h](https://huggingface.co/facebook/data2vec-audio-base-960h) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 32): + Vocabulary size of the Data2VecAudio model. Defines the number of different tokens that can be represented + by the `inputs_ids` passed when calling [`Data2VecAudioModel`] or [`TFData2VecAudioModel`]. Vocabulary size + of the model. Defines the different tokens that can be represented by the *inputs_ids* passed to the + forward method of [`Data2VecAudioModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + final_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for the final projection layer of [`Data2VecAudioForCTC`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + feat_proj_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for output of the feature encoder. + feat_extract_activation (`str, `optional`, defaults to `"gelu"`): + The non-linear activation function (function or string) in the 1D convolutional layers of the feature + extractor. If string, `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` are supported. + conv_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 512, 512, 512)`): + A tuple of integers defining the number of input and output channels of each 1D convolutional layer in the + feature encoder. The length of *conv_dim* defines the number of 1D convolutional layers. + conv_stride (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 2, 2, 2, 2, 2, 2)`): + A tuple of integers defining the stride of each 1D convolutional layer in the feature encoder. The length + of *conv_stride* defines the number of convolutional layers and has to match the length of *conv_dim*. + conv_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(10, 3, 3, 3, 3, 3, 3)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the feature encoder. The + length of *conv_kernel* defines the number of convolutional layers and has to match the length of + *conv_dim*. + conv_bias (`bool`, *optional*, defaults to `False`): + Whether the 1D convolutional layers have a bias. + num_conv_pos_embeddings (`int`, *optional*, defaults to 128): + Number of convolutional positional embeddings. Defines the kernel size of 1D convolutional positional + embeddings layer. + num_conv_pos_embedding_groups (`int`, *optional*, defaults to 16): + Number of groups of 1D convolutional positional embeddings layer. + mask_time_prob (`float`, *optional*, defaults to 0.05): + Percentage (between 0 and 1) of all feature vectors along the time axis which will be masked. The masking + procecure generates ''mask_time_prob*len(time_axis)/mask_time_length'' independent masks over the axis. If + reasoning from the propability of each feature vector to be chosen as the start of the vector span to be + masked, *mask_time_prob* should be `prob_vector_start*mask_time_length`. Note that overlap may decrease the + mask_time_length (`int`, *optional*, defaults to 10): + Length of vector span along the time axis. + mask_time_min_masks (`int`, *optional*, defaults to 2),: + The minimum number of masks of length `mask_feature_length` generated along the time axis, each time step, + irrespectively of `mask_feature_prob`. Only relevant if ''mask_time_prob*len(time_axis)/mask_time_length < + mask_time_min_masks'' + mask_feature_prob (`float`, *optional*, defaults to 0.0): + Percentage (between 0 and 1) of all feature vectors along the feature axis which will be masked. The + masking procecure generates ''mask_feature_prob*len(feature_axis)/mask_time_length'' independent masks over + the axis. If reasoning from the propability of each feature vector to be chosen as the start of the vector + span to be masked, *mask_feature_prob* should be `prob_vector_start*mask_feature_length`. Note that overlap + may decrease the actual percentage of masked vectors. This is only relevant if `apply_spec_augment is + True`. + mask_feature_length (`int`, *optional*, defaults to 10): + Length of vector span along the feature axis. + mask_feature_min_masks (`int`, *optional*, defaults to 0),: + The minimum number of masks of length `mask_feature_length` generated along the feature axis, each time + step, irrespectively of `mask_feature_prob`. Only relevant if + ''mask_feature_prob*len(feature_axis)/mask_feature_length < mask_feature_min_masks'' + ctc_loss_reduction (`str`, *optional*, defaults to `"sum"`): + Specifies the reduction to apply to the output of `torch.nn.CTCLoss`. Only relevant when training an + instance of [`Data2VecAudioForCTC`]. + ctc_zero_infinity (`bool`, *optional*, defaults to `False`): + Whether to zero infinite losses and the associated gradients of `torch.nn.CTCLoss`. Infinite losses mainly + occur when the inputs are too short to be aligned to the targets. Only relevant when training an instance + of [`Data2VecAudioForCTC`]. + use_weighted_layer_sum (`bool`, *optional*, defaults to `False`): + Whether to use a weighted average of layer outputs with learned weights. Only relevant when using an + instance of [`Data2VecAudioForSequenceClassification`]. + classifier_proj_size (`int`, *optional*, defaults to 256): + Dimensionality of the projection before token mean-pooling for classification. + tdnn_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 1500)`): + A tuple of integers defining the number of output channels of each 1D convolutional layer in the *TDNN* + module of the *XVector* model. The length of *tdnn_dim* defines the number of *TDNN* layers. + tdnn_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 3, 3, 1, 1)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the *TDNN* module of the + *XVector* model. The length of *tdnn_kernel* has to match the length of *tdnn_dim*. + tdnn_dilation (`Tuple[int]` or `List[int]`, *optional*, defaults to `(1, 2, 3, 1, 1)`): + A tuple of integers defining the dilation factor of each 1D convolutional layer in *TDNN* module of the + *XVector* model. The length of *tdnn_dilation* has to match the length of *tdnn_dim*. + xvector_output_dim (`int`, *optional*, defaults to 512): + Dimensionality of the *XVector* embedding vectors. + add_adapter (`bool`, *optional*, defaults to `False`): + Whether a convolutional network should be stacked on top of the Data2VecAudio Encoder. Can be very useful + for warm-starting Data2VecAudio for SpeechEncoderDecoder models. + adapter_kernel_size (`int`, *optional*, defaults to 3): + Kernel size of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + adapter_stride (`int`, *optional*, defaults to 2): + Stride of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + num_adapter_layers (`int`, *optional*, defaults to 3): + Number of convolutional layers that should be used in the adapter network. Only relevant if `add_adapter is + True`. + output_hidden_size (`int`, *optional*): + Dimensionality of the encoder output layer. If not defined, this defaults to *hidden-size*. Only relevant + if `add_adapter is True`. + + Example: + + ```python + >>> from transformers import Data2VecAudioConfig, Data2VecAudioModel + + >>> # Initializing a Data2VecAudio facebook/data2vec-audio-base-960h style configuration + >>> configuration = Data2VecAudioConfig() + + >>> # Initializing a model (with random weights) from the facebook/data2vec-audio-base-960h style configuration + >>> model = Data2VecAudioModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "data2vec-audio" + + def __init__( + self, + vocab_size=32, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout=0.1, + activation_dropout=0.1, + attention_dropout=0.1, + feat_proj_dropout=0.0, + final_dropout=0.1, + layerdrop=0.1, + initializer_range=0.02, + layer_norm_eps=1e-5, + feat_extract_activation="gelu", + conv_dim=(512, 512, 512, 512, 512, 512, 512), + conv_stride=(5, 2, 2, 2, 2, 2, 2), + conv_kernel=(10, 3, 3, 3, 3, 2, 2), + conv_bias=False, + num_conv_pos_embedding_groups=16, + conv_pos_kernel_size=19, + num_conv_pos_embeddings=5, + mask_time_prob=0.05, + mask_time_length=10, + mask_time_min_masks=2, + mask_feature_prob=0.0, + mask_feature_length=10, + mask_feature_min_masks=0, + ctc_loss_reduction="sum", + ctc_zero_infinity=False, + use_weighted_layer_sum=False, + classifier_proj_size=256, + tdnn_dim=(512, 512, 512, 512, 1500), + tdnn_kernel=(5, 3, 3, 1, 1), + tdnn_dilation=(1, 2, 3, 1, 1), + xvector_output_dim=512, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + add_adapter=False, + adapter_kernel_size=3, + adapter_stride=2, + num_adapter_layers=3, + output_hidden_size=None, + **kwargs, + ): + super().__init__(**kwargs, pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id) + self.hidden_size = hidden_size + self.feat_extract_activation = feat_extract_activation + self.conv_dim = list(conv_dim) + self.conv_stride = list(conv_stride) + self.conv_kernel = list(conv_kernel) + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.conv_pos_kernel_size = conv_pos_kernel_size + self.num_feat_extract_layers = len(self.conv_dim) + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_attention_heads = num_attention_heads + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.feat_proj_dropout = feat_proj_dropout + self.final_dropout = final_dropout + self.layerdrop = layerdrop + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.use_weighted_layer_sum = use_weighted_layer_sum + + if ( + (len(self.conv_stride) != self.num_feat_extract_layers) + or (len(self.conv_kernel) != self.num_feat_extract_layers) + or (len(self.conv_dim) != self.num_feat_extract_layers) + ): + raise ValueError( + "Configuration for convolutional layers is incorrect. It is required that `len(config.conv_dim)` ==" + " `len(config.conv_stride)` == `len(config.conv_kernel)`, but is `len(config.conv_dim) =" + f" {len(self.conv_dim)}`, `len(config.conv_stride) = {len(self.conv_stride)}`," + f" `len(config.conv_kernel) = {len(self.conv_kernel)}`." + ) + + # fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779 + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.mask_time_min_masks = mask_time_min_masks + self.mask_feature_prob = mask_feature_prob + self.mask_feature_length = mask_feature_length + self.mask_feature_min_masks = mask_feature_min_masks + + # ctc loss + self.ctc_loss_reduction = ctc_loss_reduction + self.ctc_zero_infinity = ctc_zero_infinity + + # adapter + self.add_adapter = add_adapter + self.adapter_kernel_size = adapter_kernel_size + self.adapter_stride = adapter_stride + self.num_adapter_layers = num_adapter_layers + self.output_hidden_size = output_hidden_size or hidden_size + + # SequenceClassification-specific parameter. Feel free to ignore for other classes. + self.classifier_proj_size = classifier_proj_size + + # XVector-specific parameters. Feel free to ignore for other classes. + self.tdnn_dim = list(tdnn_dim) + self.tdnn_kernel = list(tdnn_kernel) + self.tdnn_dilation = list(tdnn_dilation) + self.xvector_output_dim = xvector_output_dim + + @property + def inputs_to_logits_ratio(self): + return math.prod(self.conv_stride) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_text.py new file mode 100644 index 0000000000000000000000000000000000000000..305a3ea5e4ffa4b3e9026855601b6f85100b13de --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/configuration_data2vec_text.py @@ -0,0 +1,153 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Data2VecText configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DATA2VEC_TEXT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/data2vec-text-base": "https://huggingface.co/data2vec/resolve/main/config.json", +} + + +class Data2VecTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Data2VecTextModel`] and [`Data2VecTextModel`]. It + is used to instantiate a Data2VecText model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the Data2VecText + [facebook/data2vec-text-base](https://huggingface.co/facebook/data2vec-text-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the DATA2VEC model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`Data2VecModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`Data2VecModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + is_decoder (`bool`, *optional*, defaults to `False`): + Whether the model is used as a decoder or not. If `False`, the model is used as an encoder. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + classifier_dropout (`float`, *optional*): + The dropout ratio for the classification head. + + Examples: + + ```python + >>> from transformers import Data2VecTextConfig, Data2VecTextModel + + >>> # Initializing a Data2VecText facebook/data2vec-text-base style configuration + >>> configuration = Data2VecTextConfig() + + >>> # Initializing a model (with random weights) from the facebook/data2vec-text-base style configuration + >>> model = Data2VecTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "data2vec-text" + + def __init__( + self, + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + position_embedding_type="absolute", + use_cache=True, + classifier_dropout=None, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.classifier_dropout = classifier_dropout + + +class Data2VecTextOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..8ff8c1b910f0b438927873bfdab5c46361f063e1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python3 +import argparse +import json + +import torch +from huggingface_hub import hf_hub_download +from PIL import Image +from timm.models import create_model + +from transformers import ( + BeitFeatureExtractor, + Data2VecVisionConfig, + Data2VecVisionForImageClassification, + Data2VecVisionModel, +) + + +def create_rename_keys(config, has_lm_head=False, is_semantic=False, hf_prefix="data2vec."): + prefix = "backbone." if is_semantic else "" + + rename_keys = [] + for i in range(config.num_hidden_layers): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append( + (f"{prefix}blocks.{i}.norm1.weight", f"{hf_prefix}encoder.layer.{i}.layernorm_before.weight") + ) + rename_keys.append((f"{prefix}blocks.{i}.norm1.bias", f"{hf_prefix}encoder.layer.{i}.layernorm_before.bias")) + rename_keys.append( + (f"{prefix}blocks.{i}.attn.proj.weight", f"{hf_prefix}encoder.layer.{i}.attention.output.dense.weight") + ) + rename_keys.append( + (f"{prefix}blocks.{i}.attn.proj.bias", f"{hf_prefix}encoder.layer.{i}.attention.output.dense.bias") + ) + rename_keys.append( + (f"{prefix}blocks.{i}.norm2.weight", f"{hf_prefix}encoder.layer.{i}.layernorm_after.weight") + ) + rename_keys.append((f"{prefix}blocks.{i}.norm2.bias", f"{hf_prefix}encoder.layer.{i}.layernorm_after.bias")) + rename_keys.append( + (f"{prefix}blocks.{i}.mlp.fc1.weight", f"{hf_prefix}encoder.layer.{i}.intermediate.dense.weight") + ) + rename_keys.append( + (f"{prefix}blocks.{i}.mlp.fc1.bias", f"{hf_prefix}encoder.layer.{i}.intermediate.dense.bias") + ) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.weight", f"{hf_prefix}encoder.layer.{i}.output.dense.weight")) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.bias", f"{hf_prefix}encoder.layer.{i}.output.dense.bias")) + + # projection layer + position embeddings + rename_keys.extend( + [ + (f"{prefix}cls_token", f"{hf_prefix}embeddings.cls_token"), + (f"{prefix}patch_embed.proj.weight", f"{hf_prefix}embeddings.patch_embeddings.projection.weight"), + (f"{prefix}patch_embed.proj.bias", f"{hf_prefix}embeddings.patch_embeddings.projection.bias"), + ] + ) + + if has_lm_head: + # mask token + shared relative position bias + layernorm + rename_keys.extend( + [ + ("mask_token", f"{hf_prefix}embeddings.mask_token"), + ( + "rel_pos_bias.relative_position_bias_table", + f"{hf_prefix}encoder.relative_position_bias.relative_position_bias_table", + ), + ( + "rel_pos_bias.relative_position_index", + f"{hf_prefix}encoder.relative_position_bias.relative_position_index", + ), + ("norm.weight", "layernorm.weight"), + ("norm.bias", "layernorm.bias"), + ] + ) + elif is_semantic: + # semantic segmentation classification heads + rename_keys.extend( + [ + ("decode_head.conv_seg.weight", "decode_head.classifier.weight"), + ("decode_head.conv_seg.bias", "decode_head.classifier.bias"), + ("auxiliary_head.conv_seg.weight", "auxiliary_head.classifier.weight"), + ("auxiliary_head.conv_seg.bias", "auxiliary_head.classifier.bias"), + ] + ) + else: + # layernorm + classification head + rename_keys.extend( + [ + ("fc_norm.weight", f"{hf_prefix}pooler.layernorm.weight"), + ("fc_norm.bias", f"{hf_prefix}pooler.layernorm.bias"), + ("head.weight", "classifier.weight"), + ("head.bias", "classifier.bias"), + ] + ) + + return rename_keys + + +def read_in_q_k_v(state_dict, config, has_lm_head=False, is_semantic=False, hf_prefix="data2vec_vision."): + for i in range(config.num_hidden_layers): + prefix = "backbone." if is_semantic else "" + # queries, keys and values + in_proj_weight = state_dict.pop(f"{prefix}blocks.{i}.attn.qkv.weight") + q_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.q_bias") + v_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.v_bias") + + state_dict[f"{hf_prefix}encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[ + : config.hidden_size, : + ] + state_dict[f"{hf_prefix}encoder.layer.{i}.attention.attention.query.bias"] = q_bias + state_dict[f"{hf_prefix}encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"{hf_prefix}encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[ + -config.hidden_size :, : + ] + state_dict[f"{hf_prefix}encoder.layer.{i}.attention.attention.value.bias"] = v_bias + + # gamma_1 and gamma_2 + # we call them lambda because otherwise they are renamed when using .from_pretrained + gamma_1 = state_dict.pop(f"{prefix}blocks.{i}.gamma_1") + gamma_2 = state_dict.pop(f"{prefix}blocks.{i}.gamma_2") + + state_dict[f"{hf_prefix}encoder.layer.{i}.lambda_1"] = gamma_1 + state_dict[f"{hf_prefix}encoder.layer.{i}.lambda_2"] = gamma_2 + + # relative_position bias table + index + if not has_lm_head: + # each layer has its own relative position bias + table = state_dict.pop(f"{prefix}blocks.{i}.attn.relative_position_bias_table") + index = state_dict.pop(f"{prefix}blocks.{i}.attn.relative_position_index") + + state_dict[ + f"{hf_prefix}encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_bias_table" + ] = table + state_dict[ + f"{hf_prefix}encoder.layer.{i}.attention.attention.relative_position_bias.relative_position_index" + ] = index + + +def get_args(): + parser = argparse.ArgumentParser( + "Convert Data2VecVision to HF for image classification and pretraining", add_help=False + ) + parser.add_argument("--hf_checkpoint_name", type=str) + parser.add_argument("--input_size", default=224, type=int, help="images input size") + parser.add_argument("--beit_checkpoint", default="", help="beit checkpoint") + + return parser.parse_args() + + +def load_beit_model(args, is_finetuned, is_large): + def load_state_dict(model, state_dict, prefix="", ignore_missing="relative_position_index"): + missing_keys = [] + unexpected_keys = [] + error_msgs = [] + # copy state_dict so _load_from_state_dict can modify it + metadata = getattr(state_dict, "_metadata", None) + state_dict = state_dict.copy() + if metadata is not None: + state_dict._metadata = metadata + + def load(module, prefix=""): + local_metadata = {} if metadata is None else metadata.get(prefix[:-1], {}) + module._load_from_state_dict( + state_dict, prefix, local_metadata, True, missing_keys, unexpected_keys, error_msgs + ) + for name, child in module._modules.items(): + if child is not None: + load(child, prefix + name + ".") + + load(model, prefix=prefix) + + warn_missing_keys = [] + ignore_missing_keys = [] + for key in missing_keys: + keep_flag = True + for ignore_key in ignore_missing.split("|"): + if ignore_key in key: + keep_flag = False + break + if keep_flag: + warn_missing_keys.append(key) + else: + ignore_missing_keys.append(key) + + missing_keys = warn_missing_keys + + if len(missing_keys) > 0: + print( + "Weights of {} not initialized from pretrained model: {}".format( + model.__class__.__name__, missing_keys + ) + ) + if len(unexpected_keys) > 0: + print("Weights from pretrained model not used in {}: {}".format(model.__class__.__name__, unexpected_keys)) + if len(ignore_missing_keys) > 0: + print( + "Ignored weights of {} not initialized from pretrained model: {}".format( + model.__class__.__name__, ignore_missing_keys + ) + ) + if len(error_msgs) > 0: + print("\n".join(error_msgs)) + + model_kwargs = { + "pretrained": False, + "use_shared_rel_pos_bias": True, + "use_abs_pos_emb": False, + "init_values": 0.1, + } + + if is_finetuned: + model_kwargs.update( + { + "num_classes": 1000, + "use_mean_pooling": True, + "init_scale": 0.001, + "use_rel_pos_bias": True, + } + ) + + model = create_model( + "beit_large_patch16_224" if is_large else "beit_base_patch16_224", + **model_kwargs, + ) + patch_size = model.patch_embed.patch_size + args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1]) + checkpoint = torch.load(args.beit_checkpoint, map_location="cpu") + + print(f"Load ckpt from {args.beit_checkpoint}") + checkpoint_model = None + for model_key in ("model", "module"): + if model_key in checkpoint: + checkpoint_model = checkpoint[model_key] + print(f"Load state_dict by model_key = {model_key}") + break + + all_keys = list(checkpoint_model.keys()) + for key in all_keys: + if "relative_position_index" in key: + checkpoint_model.pop(key) + + if "relative_position_bias_table" in key: + rel_pos_bias = checkpoint_model[key] + src_num_pos, num_attn_heads = rel_pos_bias.size() + dst_num_pos, _ = model.state_dict()[key].size() + dst_patch_shape = model.patch_embed.patch_shape + if dst_patch_shape[0] != dst_patch_shape[1]: + raise NotImplementedError() + + load_state_dict(model, checkpoint_model, prefix="") + + return model + + +def main(): + args = get_args() + + is_finetuned = "ft1k" in args.hf_checkpoint_name + is_large = "large" in args.hf_checkpoint_name + + if is_finetuned: + # To convert Beit's data2vec_vision to HF you need to copy + # https://github.com/facebookresearch/data2vec_vision/blob/main/beit/modeling_finetune.py + # into this folder. + import modeling_finetune # noqa: F401 + else: + # To convert Beit's data2vec_vision to HF you need to copy + # https://github.com/facebookresearch/data2vec_vision/blob/main/beit/modeling_cyclical.py + # into this folder + # IMPORTANT: Note that for now we've only converted the down-stream + # model and not the full pretrained model. This means for the integration + # test you need to add a `return x` after the following line: + # https://github.com/facebookresearch/data2vec_vision/blob/af9a36349aaed59ae66e69b5dabeef2d62fdc5da/beit/modeling_cyclical.py#L197 + # to make the integration test pass. + import modeling_cyclical # noqa: F401 + + # 1. Create model config + config = Data2VecVisionConfig() + if is_finetuned: + config.use_relative_position_bias = True + config.use_shared_relative_position_bias = False + config.use_mean_pooling = True + config.num_labels = 1000 + + repo_id = "huggingface/label-files" + filename = "imagenet-1k-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + else: + config.use_relative_position_bias = False + config.use_shared_relative_position_bias = True + config.use_mean_pooling = False + + if is_large: + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + + # 2. Load Beit model + orig_model = load_beit_model(args, is_finetuned, is_large) + orig_model.eval() + + # 3. Forward Beit model + feature_extractor = BeitFeatureExtractor(size=config.image_size, do_center_crop=False) + image = Image.open("../../../../tests/fixtures/tests_samples/COCO/000000039769.png") + encoding = feature_extractor(images=image, return_tensors="pt") + pixel_values = encoding["pixel_values"] + + orig_args = (pixel_values,) if is_finetuned else (pixel_values, None) + with torch.no_grad(): + orig_model_output = orig_model(*orig_args) + + # 4. Load HF Data2VecVision model + if is_finetuned: + hf_model = Data2VecVisionForImageClassification(config) + hf_model.eval() + has_lm_head = False + hf_prefix = "data2vec_vision." + else: + hf_model = Data2VecVisionModel(config) + hf_model.eval() + has_lm_head = True + hf_prefix = "" + + rename_keys = create_rename_keys(config, hf_prefix=hf_prefix, has_lm_head=has_lm_head) + state_dict = orig_model.state_dict() + for src, dest in rename_keys: + val = state_dict.pop(src) + state_dict[dest] = val + + read_in_q_k_v(state_dict, config, hf_prefix=hf_prefix, has_lm_head=has_lm_head) + missing_keys, unexpected_keys = hf_model.load_state_dict(state_dict, strict=False) + print("HF missing", missing_keys) + print("HF unexpected_keys", unexpected_keys) + + # 5. Forward HF Data2VecVision model + with torch.no_grad(): + hf_model_output = hf_model(pixel_values) + + hf_output = hf_model_output.logits if is_finetuned else hf_model_output.last_hidden_state + + # 6. Compare + max_absolute_diff = torch.max(torch.abs(hf_output - orig_model_output)).item() + + print(f"max_absolute_diff = {max_absolute_diff}") + success = torch.allclose(hf_output, orig_model_output, atol=1e-3) + print("Do both models output the same tensors?", "🔥" if success else "💩") + if not success: + raise Exception("Something went wRoNg") + + # 7. Save + print(f"Saving to {args.hf_checkpoint_name}") + hf_model.save_pretrained(args.hf_checkpoint_name) + feature_extractor.save_pretrained(args.hf_checkpoint_name) + + +if __name__ == "__main__": + main() + # Run the following to convert checkpoints + # python ./convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py \ + # --beit_checkpoint ./pretrained_base.pt \ + # --hf_checkpoint_name "./data2vec-vision-base" + # python ./convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py \ + # --beit_checkpoint ./finetuned_base.pt \ + # --hf_checkpoint_name "./data2vec-vision-base-ft1k" + # python ./convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py \ + # --beit_checkpoint ./pretrained_large.pt \ + # --hf_checkpoint_name "./data2vec-vision-large" + # python ./convert_data2vec_vision_original_pytorch_checkpoint_to_pytorch.py \ + # --beit_checkpoint ./finetuned_large.pt \ + # --hf_checkpoint_name "./data2vec-vision-large-ft1k" diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_data2vec_vision.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_data2vec_vision.py new file mode 100644 index 0000000000000000000000000000000000000000..d238dd05d2164baf3e11a2b70ee942f1335c5e9f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_data2vec_vision.py @@ -0,0 +1,1218 @@ +# coding=utf-8 +# Copyright 2022 Meta Platforms and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Data2VecVision model.""" + + +import collections.abc +import math +from dataclasses import dataclass +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPooling, + ImageClassifierOutput, + SemanticSegmenterOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, meshgrid, prune_linear_layer +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_data2vec_vision import Data2VecVisionConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "Data2VecVisionConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/data2vec-vision-base" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "facebook/data2vec-vision-base-ft1k" +_IMAGE_CLASS_EXPECTED_OUTPUT = "remote control, remote" + +DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/data2vec-vision-base-ft1k", + # See all Data2VecVision models at https://huggingface.co/models?filter=data2vec-vision +] + + +@dataclass +# Copied from transformers.models.beit.modeling_beit.BeitModelOutputWithPooling with Beit->Data2VecVision +class Data2VecVisionModelOutputWithPooling(BaseModelOutputWithPooling): + """ + Class for outputs of [`Data2VecVisionModel`]. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`): + Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if + *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token + will be returned. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + +# Copied from transformers.models.beit.modeling_beit.drop_path +def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor: + """ + Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, + however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the + layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the + argument. + """ + if drop_prob == 0.0 or not training: + return input + keep_prob = 1 - drop_prob + shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device) + random_tensor.floor_() # binarize + output = input.div(keep_prob) * random_tensor + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitDropPath with Beit->Data2VecVision +class Data2VecVisionDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob: Optional[float] = None) -> None: + super().__init__() + self.drop_prob = drop_prob + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + return drop_path(hidden_states, self.drop_prob, self.training) + + def extra_repr(self) -> str: + return "p={}".format(self.drop_prob) + + +# Copied from transformers.models.beit.modeling_beit.BeitEmbeddings with Beit->Data2VecVision +class Data2VecVisionEmbeddings(nn.Module): + """ + Construct the CLS token, position and patch embeddings. Optionally, also the mask token. + + """ + + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + if config.use_mask_token: + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + else: + self.mask_token = None + self.patch_embeddings = Data2VecVisionPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + if config.use_absolute_position_embeddings: + self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 1, config.hidden_size)) + else: + self.position_embeddings = None + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, pixel_values: torch.Tensor, bool_masked_pos: Optional[torch.BoolTensor] = None) -> torch.Tensor: + embeddings = self.patch_embeddings(pixel_values) + batch_size, seq_len, _ = embeddings.size() + + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + if bool_masked_pos is not None: + mask_tokens = self.mask_token.expand(batch_size, seq_len, -1) + # replace the masked visual tokens by mask_tokens + w = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1 - w) + mask_tokens * w + + embeddings = torch.cat((cls_tokens, embeddings), dim=1) + if self.position_embeddings is not None: + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings) + + return embeddings + + +# Copied from transformers.models.beit.modeling_beit.BeitPatchEmbeddings with Beit->Data2VecVision +class Data2VecVisionPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + patch_shape = (image_size[0] // patch_size[0], image_size[1] // patch_size[1]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + self.patch_shape = patch_shape + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model ({self.image_size[0]}*{self.image_size[1]})." + ) + embeddings = self.projection(pixel_values).flatten(2).transpose(1, 2) + + return embeddings + + +# Copied from transformers.models.beit.modeling_beit.BeitSelfAttention with Beit->Data2VecVision +class Data2VecVisionSelfAttention(nn.Module): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=False) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + if window_size: + self.relative_position_bias = Data2VecVisionRelativePositionBias(config, window_size=window_size) + else: + self.relative_position_bias = None + + def transpose_for_scores(self, x): + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(*new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + relative_position_bias: Optional["Data2VecVisionRelativePositionBias"] = None, + ) -> Union[Tuple[torch.Tensor], Tuple[torch.Tensor, torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Add relative position bias if present. + if self.relative_position_bias is not None: + attention_scores = attention_scores + self.relative_position_bias().unsqueeze(0) + + # Add shared relative position bias if provided. + if relative_position_bias is not None: + attention_scores = attention_scores + relative_position_bias + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(*new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.beit.modeling_beit.BeitSelfOutput with Beit->Data2VecVision +class Data2VecVisionSelfOutput(nn.Module): + """ + The residual connection is defined in Data2VecVisionLayer instead of here (as is the case with other models), due + to the layernorm applied before each block. + """ + + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor, gamma=None) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.beit.modeling_beit.BeitAttention with Beit->Data2VecVision +class Data2VecVisionAttention(nn.Module): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None) -> None: + super().__init__() + self.attention = Data2VecVisionSelfAttention(config, window_size=window_size) + self.output = Data2VecVisionSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + relative_position_bias: Optional["Data2VecVisionRelativePositionBias"] = None, + ) -> Union[Tuple[torch.Tensor], Tuple[torch.Tensor, torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions, relative_position_bias) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.beit.modeling_beit.BeitIntermediate with Beit->Data2VecVision +class Data2VecVisionIntermediate(nn.Module): + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.beit.modeling_beit.BeitOutput with Beit->Data2VecVision +class Data2VecVisionOutput(nn.Module): + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.beit.modeling_beit.BeitLayer with Beit->Data2VecVision,BEiT->Data2VecVision +class Data2VecVisionLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__( + self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None, drop_path_rate: float = 0.0 + ) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = Data2VecVisionAttention(config, window_size=window_size) + self.intermediate = Data2VecVisionIntermediate(config) + self.output = Data2VecVisionOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.drop_path = Data2VecVisionDropPath(drop_path_rate) if drop_path_rate > 0.0 else nn.Identity() + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + init_values = config.layer_scale_init_value + if init_values > 0: + self.lambda_1 = nn.Parameter(init_values * torch.ones((config.hidden_size)), requires_grad=True) + self.lambda_2 = nn.Parameter(init_values * torch.ones((config.hidden_size)), requires_grad=True) + else: + self.lambda_1, self.lambda_2 = None, None + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + relative_position_bias: Optional["Data2VecVisionRelativePositionBias"] = None, + ) -> Union[Tuple[torch.Tensor], Tuple[torch.Tensor, torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in Data2VecVision, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + relative_position_bias=relative_position_bias, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # apply lambda_1 if present + if self.lambda_1 is not None: + attention_output = self.lambda_1 * attention_output + + # first residual connection + hidden_states = self.drop_path(attention_output) + hidden_states + + # in Data2VecVision, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + + layer_output = self.intermediate(layer_output) + layer_output = self.output(layer_output) + + if self.lambda_2 is not None: + layer_output = self.lambda_2 * layer_output + + # second residual connection + layer_output = self.drop_path(layer_output) + hidden_states + + outputs = (layer_output,) + outputs + + return outputs + + +# Copied from transformers.models.beit.modeling_beit.BeitRelativePositionBias with Beit->Data2VecVision +class Data2VecVisionRelativePositionBias(nn.Module): + def __init__(self, config: Data2VecVisionConfig, window_size: tuple) -> None: + super().__init__() + self.window_size = window_size + self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3 + self.relative_position_bias_table = nn.Parameter( + torch.zeros(self.num_relative_distance, config.num_attention_heads) + ) # 2*Wh-1 * 2*Ww-1, nH + # cls to token & token 2 cls & cls to cls + + # get pair-wise relative position index for each token inside the window + coords_h = torch.arange(window_size[0]) + coords_w = torch.arange(window_size[1]) + coords = torch.stack(meshgrid([coords_h, coords_w], indexing="ij")) # 2, Wh, Ww + coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww + relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 + relative_coords[:, :, 0] += window_size[0] - 1 # shift to start from 0 + relative_coords[:, :, 1] += window_size[1] - 1 + relative_coords[:, :, 0] *= 2 * window_size[1] - 1 + relative_position_index = torch.zeros( + size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype + ) + relative_position_index[1:, 1:] = relative_coords.sum(-1) # Wh*Ww, Wh*Ww + relative_position_index[0, 0:] = self.num_relative_distance - 3 + relative_position_index[0:, 0] = self.num_relative_distance - 2 + relative_position_index[0, 0] = self.num_relative_distance - 1 + + self.register_buffer("relative_position_index", relative_position_index) + + def forward(self) -> torch.Tensor: + relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( + self.window_size[0] * self.window_size[1] + 1, self.window_size[0] * self.window_size[1] + 1, -1 + ) # Wh*Ww,Wh*Ww,nH + + return relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww + + +# Copied from transformers.models.beit.modeling_beit.BeitEncoder with Beit->Data2VecVision +class Data2VecVisionEncoder(nn.Module): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None) -> None: + super().__init__() + self.config = config + if config.use_shared_relative_position_bias: + self.relative_position_bias = Data2VecVisionRelativePositionBias(config, window_size=window_size) + else: + self.relative_position_bias = None + + # stochastic depth decay rule + dpr = [x.item() for x in torch.linspace(0, config.drop_path_rate, config.num_hidden_layers)] + self.layer = nn.ModuleList( + [ + Data2VecVisionLayer( + config, + window_size=window_size if config.use_relative_position_bias else None, + drop_path_rate=dpr[i], + ) + for i in range(config.num_hidden_layers) + ] + ) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + relative_position_bias = ( + self.relative_position_bias() if self.relative_position_bias is not None else None + ) + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions, relative_position_bias) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +# Copied from transformers.models.beit.modeling_beit.BeitPreTrainedModel with Beit->Data2VecVision,beit->data2vec_vision +class Data2VecVisionPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Data2VecVisionConfig + base_model_prefix = "data2vec_vision" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, Data2VecVisionEncoder): + module.gradient_checkpointing = value + + +DATA2VEC_VISION_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`Data2VecVisionConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DATA2VEC_VISION_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`BeitImageProcessor.__call__`] for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Data2VecVision Model transformer outputting raw hidden-states without any specific head on top.", + DATA2VEC_VISION_START_DOCSTRING, +) +# Copied from transformers.models.beit.modeling_beit.BeitModel with BEIT->DATA2VEC_VISION,Beit->Data2VecVision,True->False +class Data2VecVisionModel(Data2VecVisionPreTrainedModel): + def __init__(self, config: Data2VecVisionConfig, add_pooling_layer: bool = False) -> None: + super().__init__(config) + self.config = config + + self.embeddings = Data2VecVisionEmbeddings(config) + self.encoder = Data2VecVisionEncoder(config, window_size=self.embeddings.patch_embeddings.patch_shape) + + self.layernorm = ( + nn.Identity() if config.use_mean_pooling else nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + ) + self.pooler = Data2VecVisionPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=Data2VecVisionModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, Data2VecVisionModelOutputWithPooling]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings(pixel_values, bool_masked_pos) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return Data2VecVisionModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Copied from transformers.models.beit.modeling_beit.BeitPooler with Beit->Data2VecVision +class Data2VecVisionPooler(nn.Module): + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + self.layernorm = ( + nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) if config.use_mean_pooling else None + ) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + if self.layernorm is not None: + # Mean pool the final hidden states of the patch tokens + patch_tokens = hidden_states[:, 1:, :] + pooled_output = self.layernorm(patch_tokens.mean(1)) + else: + # Pool by simply taking the final hidden state of the [CLS] token + pooled_output = hidden_states[:, 0] + + return pooled_output + + +@add_start_docstrings( + """ + Data2VecVision Model transformer with an image classification head on top (a linear layer on top of the average of + the final hidden states of the patch tokens) e.g. for ImageNet. + """, + DATA2VEC_VISION_START_DOCSTRING, +) +# Copied from transformers.models.beit.modeling_beit.BeitForImageClassification with BEIT->DATA2VEC_VISION,Beit->Data2VecVision,beit->data2vec_vision +class Data2VecVisionForImageClassification(Data2VecVisionPreTrainedModel): + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.data2vec_vision = Data2VecVisionModel(config, add_pooling_layer=True) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=ImageClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + outputs = self.data2vec_vision( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs.pooler_output if return_dict else outputs[1] + + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.beit.modeling_beit.BeitConvModule with Beit->Data2VecVision +class Data2VecVisionConvModule(nn.Module): + """ + A convolutional block that bundles conv/norm/activation layers. This block simplifies the usage of convolution + layers, which are commonly used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU). + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__( + self, + in_channels: int, + out_channels: int, + kernel_size: Union[int, Tuple[int, int]], + padding: Union[int, Tuple[int, int], str] = 0, + bias: bool = False, + dilation: Union[int, Tuple[int, int]] = 1, + ) -> None: + super().__init__() + self.conv = nn.Conv2d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + padding=padding, + bias=bias, + dilation=dilation, + ) + self.bn = nn.BatchNorm2d(out_channels) + self.activation = nn.ReLU() + + def forward(self, input: torch.Tensor) -> torch.Tensor: + output = self.conv(input) + output = self.bn(output) + output = self.activation(output) + + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitPyramidPoolingBlock with Beit->Data2VecVision +class Data2VecVisionPyramidPoolingBlock(nn.Module): + def __init__(self, pool_scale: int, in_channels: int, channels: int) -> None: + super().__init__() + self.layers = [ + nn.AdaptiveAvgPool2d(pool_scale), + Data2VecVisionConvModule(in_channels, channels, kernel_size=1), + ] + for i, layer in enumerate(self.layers): + self.add_module(str(i), layer) + + def forward(self, input: torch.Tensor) -> torch.Tensor: + hidden_state = input + for layer in self.layers: + hidden_state = layer(hidden_state) + return hidden_state + + +# Copied from transformers.models.beit.modeling_beit.BeitPyramidPoolingModule with Beit->Data2VecVision +class Data2VecVisionPyramidPoolingModule(nn.Module): + """ + Pyramid Pooling Module (PPM) used in PSPNet. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module. + in_channels (int): Input channels. + channels (int): Channels after modules, before conv_seg. + align_corners (bool): align_corners argument of F.interpolate. + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__(self, pool_scales: Tuple[int, ...], in_channels: int, channels: int, align_corners: bool) -> None: + super().__init__() + self.pool_scales = pool_scales + self.align_corners = align_corners + self.in_channels = in_channels + self.channels = channels + self.blocks = [] + for i, pool_scale in enumerate(pool_scales): + block = Data2VecVisionPyramidPoolingBlock( + pool_scale=pool_scale, in_channels=in_channels, channels=channels + ) + self.blocks.append(block) + self.add_module(str(i), block) + + def forward(self, x: torch.Tensor) -> List[torch.Tensor]: + ppm_outs = [] + for ppm in self.blocks: + ppm_out = ppm(x) + upsampled_ppm_out = nn.functional.interpolate( + ppm_out, size=x.size()[2:], mode="bilinear", align_corners=self.align_corners + ) + ppm_outs.append(upsampled_ppm_out) + return ppm_outs + + +# Copied from transformers.models.beit.modeling_beit.BeitUperHead with Beit->Data2VecVision +class Data2VecVisionUperHead(nn.Module): + """ + Unified Perceptual Parsing for Scene Understanding. This head is the implementation of + [UPerNet](https://arxiv.org/abs/1807.10221). + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__() + + self.pool_scales = config.pool_scales # e.g. (1, 2, 3, 6) + self.in_channels = [config.hidden_size] * 4 # e.g. [768, 768, 768, 768] + self.channels = config.hidden_size + self.align_corners = False + self.classifier = nn.Conv2d(self.channels, config.num_labels, kernel_size=1) + + # PSP Module + self.psp_modules = Data2VecVisionPyramidPoolingModule( + self.pool_scales, + self.in_channels[-1], + self.channels, + align_corners=self.align_corners, + ) + self.bottleneck = Data2VecVisionConvModule( + self.in_channels[-1] + len(self.pool_scales) * self.channels, + self.channels, + kernel_size=3, + padding=1, + ) + # FPN Module + self.lateral_convs = nn.ModuleList() + self.fpn_convs = nn.ModuleList() + for in_channels in self.in_channels[:-1]: # skip the top layer + l_conv = Data2VecVisionConvModule(in_channels, self.channels, kernel_size=1) + fpn_conv = Data2VecVisionConvModule(self.channels, self.channels, kernel_size=3, padding=1) + self.lateral_convs.append(l_conv) + self.fpn_convs.append(fpn_conv) + + self.fpn_bottleneck = Data2VecVisionConvModule( + len(self.in_channels) * self.channels, + self.channels, + kernel_size=3, + padding=1, + ) + + def psp_forward(self, inputs): + x = inputs[-1] + psp_outs = [x] + psp_outs.extend(self.psp_modules(x)) + psp_outs = torch.cat(psp_outs, dim=1) + output = self.bottleneck(psp_outs) + + return output + + def forward(self, encoder_hidden_states: torch.Tensor) -> torch.Tensor: + # build laterals + laterals = [lateral_conv(encoder_hidden_states[i]) for i, lateral_conv in enumerate(self.lateral_convs)] + + laterals.append(self.psp_forward(encoder_hidden_states)) + + # build top-down path + used_backbone_levels = len(laterals) + for i in range(used_backbone_levels - 1, 0, -1): + prev_shape = laterals[i - 1].shape[2:] + laterals[i - 1] = laterals[i - 1] + nn.functional.interpolate( + laterals[i], size=prev_shape, mode="bilinear", align_corners=self.align_corners + ) + + # build outputs + fpn_outs = [self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels - 1)] + # append psp feature + fpn_outs.append(laterals[-1]) + + for i in range(used_backbone_levels - 1, 0, -1): + fpn_outs[i] = nn.functional.interpolate( + fpn_outs[i], size=fpn_outs[0].shape[2:], mode="bilinear", align_corners=self.align_corners + ) + fpn_outs = torch.cat(fpn_outs, dim=1) + output = self.fpn_bottleneck(fpn_outs) + output = self.classifier(output) + + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitFCNHead with Beit->Data2VecVision +class Data2VecVisionFCNHead(nn.Module): + """ + Fully Convolution Networks for Semantic Segmentation. This head is implemented of + [FCNNet](https://arxiv.org/abs/1411.4038>). + + Args: + config (Data2VecVisionConfig): Configuration. + in_channels + kernel_size (int): The kernel size for convs in the head. Default: 3. + dilation (int): The dilation rate for convs in the head. Default: 1. + + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__( + self, + config: Data2VecVisionConfig, + in_index: int = 2, + kernel_size: int = 3, + dilation: Union[int, Tuple[int, int]] = 1, + ) -> None: + super().__init__() + self.in_channels = config.hidden_size + self.channels = config.auxiliary_channels + self.num_convs = config.auxiliary_num_convs + self.concat_input = config.auxiliary_concat_input + self.in_index = in_index + + conv_padding = (kernel_size // 2) * dilation + convs = [] + convs.append( + Data2VecVisionConvModule( + self.in_channels, self.channels, kernel_size=kernel_size, padding=conv_padding, dilation=dilation + ) + ) + for i in range(self.num_convs - 1): + convs.append( + Data2VecVisionConvModule( + self.channels, self.channels, kernel_size=kernel_size, padding=conv_padding, dilation=dilation + ) + ) + if self.num_convs == 0: + self.convs = nn.Identity() + else: + self.convs = nn.Sequential(*convs) + if self.concat_input: + self.conv_cat = Data2VecVisionConvModule( + self.in_channels + self.channels, self.channels, kernel_size=kernel_size, padding=kernel_size // 2 + ) + + self.classifier = nn.Conv2d(self.channels, config.num_labels, kernel_size=1) + + def forward(self, encoder_hidden_states: torch.Tensor) -> torch.Tensor: + # just take the relevant feature maps + hidden_states = encoder_hidden_states[self.in_index] + output = self.convs(hidden_states) + if self.concat_input: + output = self.conv_cat(torch.cat([hidden_states, output], dim=1)) + output = self.classifier(output) + return output + + +@add_start_docstrings( + """ + Data2VecVision Model transformer with a semantic segmentation head on top e.g. for ADE20k, CityScapes. + """, + DATA2VEC_VISION_START_DOCSTRING, +) +# Copied from transformers.models.beit.modeling_beit.BeitForSemanticSegmentation with BEIT->DATA2VEC_VISION,Beit->Data2VecVision,microsoft/beit-base-finetuned-ade-640-640->facebook/data2vec-vision-base,beit->data2vec_vision +class Data2VecVisionForSemanticSegmentation(Data2VecVisionPreTrainedModel): + def __init__(self, config: Data2VecVisionConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.data2vec_vision = Data2VecVisionModel(config, add_pooling_layer=False) + + # FPNs + self.fpn1 = nn.Sequential( + nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2), + nn.BatchNorm2d(config.hidden_size), + nn.GELU(), + nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2), + ) + self.fpn2 = nn.Sequential( + nn.ConvTranspose2d(config.hidden_size, config.hidden_size, kernel_size=2, stride=2), + ) + self.fpn3 = nn.Identity() + self.fpn4 = nn.MaxPool2d(kernel_size=2, stride=2) + + # Semantic segmentation head(s) + self.decode_head = Data2VecVisionUperHead(config) + self.auxiliary_head = Data2VecVisionFCNHead(config) if config.use_auxiliary_head else None + + # Initialize weights and apply final processing + self.post_init() + + def compute_loss(self, logits, auxiliary_logits, labels): + # upsample logits to the images' original size + upsampled_logits = nn.functional.interpolate( + logits, size=labels.shape[-2:], mode="bilinear", align_corners=False + ) + if auxiliary_logits is not None: + upsampled_auxiliary_logits = nn.functional.interpolate( + auxiliary_logits, size=labels.shape[-2:], mode="bilinear", align_corners=False + ) + # compute weighted loss + loss_fct = CrossEntropyLoss(ignore_index=self.config.semantic_loss_ignore_index) + main_loss = loss_fct(upsampled_logits, labels) + auxiliary_loss = loss_fct(upsampled_auxiliary_logits, labels) + loss = main_loss + self.config.auxiliary_loss_weight * auxiliary_loss + + return loss + + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=SemanticSegmenterOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, SemanticSegmenterOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*): + Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, Data2VecVisionForSemanticSegmentation + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/data2vec-vision-base") + >>> model = Data2VecVisionForSemanticSegmentation.from_pretrained("facebook/data2vec-vision-base") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + >>> # logits are of shape (batch_size, num_labels, height, width) + >>> logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + + outputs = self.data2vec_vision( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=True, # we need the intermediate hidden states + return_dict=return_dict, + ) + + encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1] + + # only keep certain features, and reshape + # note that we do +1 as the encoder_hidden_states also includes the initial embeddings + features = [feature for idx, feature in enumerate(encoder_hidden_states) if idx + 1 in self.config.out_indices] + batch_size = pixel_values.shape[0] + patch_resolution = self.config.image_size // self.config.patch_size + features = [ + x[:, 1:, :].permute(0, 2, 1).reshape(batch_size, -1, patch_resolution, patch_resolution) for x in features + ] + + # apply FPNs + ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4] + for i in range(len(features)): + features[i] = ops[i](features[i]) + + logits = self.decode_head(features) + + auxiliary_logits = None + if self.auxiliary_head is not None: + auxiliary_logits = self.auxiliary_head(features) + + loss = None + if labels is not None: + if self.config.num_labels == 1: + raise ValueError("The number of labels should be greater than one") + else: + loss = self.compute_loss(logits, auxiliary_logits, labels) + + if not return_dict: + if output_hidden_states: + output = (logits,) + outputs[1:] + else: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SemanticSegmenterOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states if output_hidden_states else None, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py new file mode 100644 index 0000000000000000000000000000000000000000..06a6f010dd74632ab973495c0efaa8543774e56e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/data2vec/modeling_tf_data2vec_vision.py @@ -0,0 +1,1480 @@ +# coding=utf-8 +# Copyright 2022 Meta Platforms and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 Data2Vec Vision model.""" + +import collections.abc +import math +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFBaseModelOutputWithPooling, + TFSemanticSegmenterOutput, + TFSequenceClassifierOutput, +) +from ...modeling_tf_utils import ( + TFModelInputType, + TFPreTrainedModel, + TFSequenceClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_data2vec_vision import Data2VecVisionConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "Data2VecVisionConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/data2vec-vision-base" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "facebook/data2vec-vision-base-ft1k" +_IMAGE_CLASS_EXPECTED_OUTPUT = "remote control, remote" + +TF_DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/data2vec-vision-base-ft1k", + # See all Data2VecVision models at https://huggingface.co/models?filter=data2vec-vision +] + + +@dataclass +class TFData2VecVisionModelOutputWithPooling(TFBaseModelOutputWithPooling): + """ + Class for outputs of [`TFData2VecVisionModel`]. + + Args: + last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + pooler_output (`tf.Tensor` of shape `(batch_size, hidden_size)`): + Average of the last layer hidden states of the patch tokens (excluding the *[CLS]* token) if + *config.use_mean_pooling* is set to True. If set to False, then the final hidden state of the *[CLS]* token + will be returned. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + last_hidden_state: tf.Tensor = None + pooler_output: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +class TFData2VecVisionDropPath(tf.keras.layers.Layer): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + References: + (1) github.com:rwightman/pytorch-image-models + """ + + def __init__(self, drop_path, **kwargs): + super().__init__(**kwargs) + self.drop_path = drop_path + + def call(self, x, training=None): + if training: + keep_prob = 1 - self.drop_path + shape = (tf.shape(x)[0],) + (1,) * (len(tf.shape(x)) - 1) + random_tensor = keep_prob + tf.random.uniform(shape, 0, 1) + random_tensor = tf.floor(random_tensor) + return (x / keep_prob) * random_tensor + return x + + +class TFData2VecVisionEmbeddings(tf.keras.layers.Layer): + """ + Construct the CLS token, position and patch embeddings. Optionally, also the mask token. + + """ + + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + + self.patch_embeddings = TFData2VecVisionPatchEmbeddings(config, name="patch_embeddings") + self.num_patches = self.patch_embeddings.num_patches + self.config = config + + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) + + def build(self, input_shape: tf.TensorShape): + self.cls_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), + trainable=True, + name="cls_token", + ) + if self.config.use_mask_token: + self.mask_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), + trainable=True, + name="mask_token", + ) + else: + self.mask_token = None + + if self.config.use_absolute_position_embeddings: + self.position_embeddings = self.add_weight( + shape=(1, self.num_patches + 1, self.config.hidden_size), + initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), + trainable=True, + name="position_embeddings", + ) + else: + self.position_embeddings = None + + super().build(input_shape) + + def call(self, pixel_values: tf.Tensor, bool_masked_pos: Optional[tf.Tensor] = None) -> tf.Tensor: + embeddings = self.patch_embeddings(pixel_values) + batch_size, seq_len, projection_dim = shape_list(embeddings) + + cls_tokens = tf.tile(self.cls_token, (batch_size, 1, 1)) + + if bool_masked_pos is not None: + mask_tokens = tf.broadcast_to(self.mask_token, (batch_size, seq_len, projection_dim)) + # replace the masked visual tokens by mask_tokens + w = bool_masked_pos[..., None] + w = tf.cast(w, mask_tokens.dtype) + # since TF doesn't support eager tensor assignment + embeddings = embeddings * (1 - w) + mask_tokens * w + + embeddings = tf.concat([cls_tokens, embeddings], axis=1) + if self.position_embeddings is not None: + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings) + + return embeddings + + +class TFData2VecVisionPatchEmbeddings(tf.keras.layers.Layer): + """ + Image to Patch Embedding. + """ + + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + patch_shape = (image_size[0] // patch_size[0], image_size[1] // patch_size[1]) + self.image_size = image_size + self.patch_size = patch_size + self.num_patches = num_patches + self.patch_shape = patch_shape + self.num_channels = num_channels + + self.projection = tf.keras.layers.Conv2D( + filters=hidden_size, + kernel_size=patch_size, + strides=patch_size, + padding="valid", + data_format="channels_last", + kernel_initializer="glorot_uniform", # following torch.nn.Linear + bias_initializer="zeros", + name="projection", + ) + + def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: + batch_size, num_channels, height, width = shape_list(pixel_values) + if tf.executing_eagerly(): + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the" + " configuration." + ) + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + + # When running on CPU, `tf.keras.layers.Conv2D` doesn't support `NCHW` format. + # So change the input format from `NCHW` to `NHWC`. + # shape = (batch_size, in_height, in_width, in_channels=num_channels) + pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) + + projection = self.projection(pixel_values) + + # Change the 2D spatial dimensions to a single temporal dimension. + # shape = (batch_size, num_patches, out_channels=embed_dim) + num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) + + return tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) + + +class TFData2VecVisionSelfAttention(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="key", + use_bias=False, + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + + if window_size: + self.relative_position_bias = TFData2VecVisionRelativePositionBias( + config, window_size=window_size, name="relative_position_bias" + ) + else: + self.relative_position_bias = None + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + relative_position_bias: Optional["TFData2VecVisionRelativePositionBias"] = None, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(hidden_states)[0] + mixed_query_layer = self.query(inputs=hidden_states) + mixed_key_layer = self.key(inputs=hidden_states) + mixed_value_layer = self.value(inputs=hidden_states) + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) + value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + attention_scores = attention_scores / self.sqrt_att_head_size + + # Add relative position bias if present. + if self.relative_position_bias is not None: + # Passing `0.0` to the `relative_position_bias()` layer because otherwise Keras + # might complain about `Layer.call()` not being invoked properly. In this case this input + # i.e., 0.0 is not going to be used in any calculations so we're safe. + attention_scores = attention_scores + self.relative_position_bias(0.0)[None, ...] + + # Add shared relative position bias if provided. + if relative_position_bias is not None: + attention_scores = attention_scores + relative_position_bias + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + attention_output = tf.matmul(attention_probs, value_layer) + attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) + outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) + + return outputs + + +class TFData2VecVisionSelfOutput(tf.keras.layers.Layer): + """ + The residual connection is defined in TFData2VecVisionLayer instead of here (as is the case with other models), due + to the layernorm applied before each block. + """ + + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, gamma=None, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + + return hidden_states + + +class TFData2VecVisionAttention(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None, **kwargs): + super().__init__(**kwargs) + + self.attention = TFData2VecVisionSelfAttention(config, window_size=window_size, name="attention") + self.dense_output = TFData2VecVisionSelfOutput(config, name="output") + + def prune_heads(self, heads): + raise NotImplementedError + + def call( + self, + input_tensor: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + relative_position_bias: Optional["TFData2VecVisionRelativePositionBias"] = None, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.attention( + hidden_states=input_tensor, + head_mask=head_mask, + output_attentions=output_attentions, + relative_position_bias=relative_position_bias, + training=training, + ) + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=input_tensor, training=training + ) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->Data2VecVision +class TFData2VecVisionIntermediate(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +class TFData2VecVisionOutput(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + + return hidden_states + + +class TFData2VecVisionLayer(tf.keras.layers.Layer): + """This corresponds to the Block class in the timm implementation.""" + + def __init__( + self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None, drop_path_rate: float = 0.0, **kwargs + ): + super().__init__(**kwargs) + self.config = config + + self.attention = TFData2VecVisionAttention(config, window_size=window_size, name="attention") + self.intermediate = TFData2VecVisionIntermediate(config, name="intermediate") + self.data2vec_output = TFData2VecVisionOutput(config, name="output") + + self.layernorm_before = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_before" + ) + self.layernorm_after = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_after" + ) + # Using `layers.Activation` instead of `tf.identity` to better control `training` + # behaviour. + self.drop_path = ( + TFData2VecVisionDropPath(drop_path_rate, name="drop_path") + if drop_path_rate > 0.0 + else tf.keras.layers.Activation("linear", name="drop_path") + ) + self.init_values = config.layer_scale_init_value + + def build(self, input_shape: tf.TensorShape): + if self.init_values > 0: + self.lambda_1 = self.add_weight( + shape=(self.config.hidden_size), + initializer="ones", + trainable=True, + name="lambda_1", + ) + self.lambda_2 = self.add_weight( + shape=(self.config.hidden_size), + initializer="ones", + trainable=True, + name="lambda_2", + ) + self.lambda_1.assign(self.init_values * tf.ones((self.config.hidden_size))) + self.lambda_2.assign(self.init_values * tf.ones((self.config.hidden_size))) + else: + self.lambda_1, self.lambda_2 = None, None + + super().build(input_shape) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + relative_position_bias: Optional["TFData2VecVisionRelativePositionBias"] = None, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_attention_outputs = self.attention( + # in Data2VecVision, layernorm is applied before self-attention + input_tensor=self.layernorm_before(inputs=hidden_states), + head_mask=head_mask, + output_attentions=output_attentions, + relative_position_bias=relative_position_bias, + training=training, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # apply lambda_1 if present + if self.lambda_1 is not None: + attention_output = self.lambda_1 * attention_output + + # first residual connection + hidden_states = self.drop_path(attention_output) + hidden_states + + # in Data2VecVision, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + + layer_output = self.intermediate(layer_output) + layer_output = self.data2vec_output(layer_output) + + if self.lambda_2 is not None: + layer_output = self.lambda_2 * layer_output + + # second residual connection + layer_output = self.drop_path(layer_output) + hidden_states + + outputs = (layer_output,) + outputs + + return outputs + + +# Taken and modified from here: +# https://github.com/leondgarse/keras_cv_attention_models/blob/main/keras_cv_attention_models/beit/beit.py#L28 +class TFData2VecVisionRelativePositionBias(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, window_size: tuple, **kwargs) -> None: + super().__init__(**kwargs) + self.config = config + + self.window_size = window_size + # +3 for cls_token_pos_len + # window_size can be something like (14, 14) + self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3 + + self.relative_position_index = self.get_position_index() + + def build(self, input_shape): + self.relative_position_bias_table = self.add_weight( + shape=(self.num_relative_distance, self.config.num_attention_heads), + initializer="zeros", + trainable=True, + name="relative_position_bias_table", + ) # [2*Wh-1 * 2*Ww-1, nH] + # cls to token & token 2 cls & cls to cls + + super().build(input_shape) + + def get_position_index(self): + # get pair-wise relative position index for each token inside the window + xx, yy = tf.meshgrid(range(self.window_size[0]), range(self.window_size[1])) + coords = tf.stack([yy, xx], axis=0) # [2, Wh, Ww] + coords_flatten = tf.reshape(coords, [2, -1]) # [2, Wh*Ww] + + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # [2, Wh*Ww, Wh*Ww] + relative_coords = tf.transpose(relative_coords, perm=[1, 2, 0]) # [Wh*Ww, Wh*Ww, 2] + + xx = (relative_coords[:, :, 0] + self.window_size[0] - 1) * (2 * self.window_size[1] - 1) + yy = relative_coords[:, :, 1] + self.window_size[1] - 1 + relative_coords = tf.stack([xx, yy], axis=-1) + + relative_position_index = tf.reduce_sum(relative_coords, axis=-1) # [Wh*Ww, Wh*Ww] + + top = tf.ones((1, relative_position_index.shape[1]), dtype=relative_position_index.dtype) * ( + self.num_relative_distance - 3 + ) + left = tf.ones((relative_position_index.shape[0], 1), dtype=relative_position_index.dtype) * ( + self.num_relative_distance - 2 + ) + corner = tf.ones((1, 1), dtype=relative_position_index.dtype) * (self.num_relative_distance - 1) + + left_corner = tf.concat([corner, left], axis=0) + relative_position_index = tf.concat([top, relative_position_index], axis=0) + relative_position_index = tf.concat([left_corner, relative_position_index], axis=1) # [Wh*Ww + 1, Wh*Ww + 1] + return relative_position_index + + def call(self, inputs=None) -> tf.Tensor: + relative_position_bias = tf.gather(self.relative_position_bias_table, self.relative_position_index, axis=0) + return tf.transpose(relative_position_bias, [2, 0, 1]) + + +class TFData2VecVisionEncoder(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, window_size: Optional[tuple] = None, **kwargs): + super().__init__(**kwargs) + self.config = config + if config.use_shared_relative_position_bias: + self.relative_position_bias = TFData2VecVisionRelativePositionBias( + config, window_size=window_size, name="relative_position_bias" + ) + else: + self.relative_position_bias = None + + # stochastic depth decay rule + dpr = list(tf.linspace(0.0, config.drop_path_rate, config.num_hidden_layers)) + self.layer = [ + TFData2VecVisionLayer( + config, + window_size=window_size if config.use_relative_position_bias else None, + drop_path_rate=dpr[i], + name=f"layer_._{i}", + ) + for i in range(config.num_hidden_layers) + ] + + def call( + self, + hidden_states: tf.Tensor, + head_mask: Optional[tf.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, TFBaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + # Passing `0.0` to the `relative_position_bias()` layer because otherwise Keras + # might complain about `Layer.call()` not being invoked properly. In this case this input + # i.e., 0.0 is not going to be used in any calculations so we're safe. + relative_position_bias = ( + self.relative_position_bias(0.0) if self.relative_position_bias is not None else None + ) + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions, relative_position_bias) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +@keras_serializable +class TFData2VecVisionMainLayer(tf.keras.layers.Layer): + config_class = Data2VecVisionConfig + + def __init__(self, config: Data2VecVisionConfig, add_pooling_layer: bool = True, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.add_pooling_layer = add_pooling_layer + + self.embeddings = TFData2VecVisionEmbeddings(config, name="embeddings") + self.encoder = TFData2VecVisionEncoder( + config, window_size=self.embeddings.patch_embeddings.patch_shape, name="encoder" + ) + self.layernorm = ( + tf.identity + if config.use_mean_pooling + else tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") + ) + + # We are setting the `data_format` like so because from here on we will revert to the + # NCHW output format + self.pooler = TFData2VecVisionPooler(config, name="pooler") if add_pooling_layer else None + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + bool_masked_pos: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[tuple, TFData2VecVisionModelOutputWithPooling]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + embedding_output = self.embeddings(pixel_values, bool_masked_pos, training=training) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return TFData2VecVisionModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class TFData2VecVisionPooler(tf.keras.layers.Layer): + def __init__(self, config: Data2VecVisionConfig, **kwargs): + super().__init__(**kwargs) + self.layernorm = ( + tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") + if config.use_mean_pooling + else None + ) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + if self.layernorm is not None: + # Mean pool the final hidden states of the patch tokens + patch_tokens = hidden_states[:, 1:, :] + pooled_output = self.layernorm(tf.reduce_mean(patch_tokens, axis=1)) + else: + # Pool by simply taking the final hidden state of the [CLS] token + pooled_output = hidden_states[:, 0] + + return pooled_output + + +class TFData2VecVisionPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Data2VecVisionConfig + base_model_prefix = "data2vec_vision" + main_input_name = "pixel_values" + _keys_to_ignore_on_load_unexpected = [r"relative_position_index"] + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + """ + Dummy inputs to build the network. Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + VISION_DUMMY_INPUTS = tf.random.uniform( + shape=(3, self.config.num_channels, self.config.image_size, self.config.image_size), + dtype=tf.float32, + ) + return {"pixel_values": tf.constant(VISION_DUMMY_INPUTS)} + + @tf.function( + input_signature=[ + { + "pixel_values": tf.TensorSpec((None, None, None, None), tf.float32, name="pixel_values"), + } + ] + ) + def serving(self, inputs): + """ + Method used for serving the model. + + Args: + inputs (`Dict[str, tf.Tensor]`): + The input of the saved model as a dictionary of tensors. + """ + output = self.call(inputs) + return self.serving_output(output) + + +DATA2VEC_VISION_START_DOCSTRING = r""" + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.). + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`Data2VecVisionConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DATA2VEC_VISION_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` `Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`BeitImageProcessor.__call__`] for details. + + head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. This argument can be used + in eager mode, in graph mode the value will always be set to True. + + training (`bool`, *optional*, defaults to `False``): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare Data2VecVision Model transformer outputting raw hidden-states without any specific head on top.", + DATA2VEC_VISION_START_DOCSTRING, +) +class TFData2VecVisionModel(TFData2VecVisionPreTrainedModel): + def __init__(self, config: Data2VecVisionConfig, add_pooling_layer: bool = False, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.config = config + + self.data2vec_vision = TFData2VecVisionMainLayer( + config, add_pooling_layer=add_pooling_layer, name="data2vec_vision" + ) + + def get_input_embeddings(self): + return self.data2vec_vision.get_input_embeddings() + + @unpack_inputs + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFData2VecVisionModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + bool_masked_pos: Optional[tf.Tensor] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[tuple, TFData2VecVisionModelOutputWithPooling]: + r""" + bool_masked_pos (`tf.Tensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + outputs = self.data2vec_vision( + pixel_values=pixel_values, + bool_masked_pos=bool_masked_pos, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFData2VecVisionModelOutputWithPooling) -> TFData2VecVisionModelOutputWithPooling: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFData2VecVisionModelOutputWithPooling( + last_hidden_state=output.last_hidden_state, + pooler_output=output.pooler_output, + hidden_states=hidden_states, + attentions=attentions, + ) + + +@add_start_docstrings( + """ + Data2VecVision Model transformer with an image classification head on top (a linear layer on top of the average of + the final hidden states of the patch tokens) e.g. for ImageNet. + """, + DATA2VEC_VISION_START_DOCSTRING, +) +class TFData2VecVisionForImageClassification(TFData2VecVisionPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config: Data2VecVisionConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + self.data2vec_vision = TFData2VecVisionMainLayer(config, add_pooling_layer=True, name="data2vec_vision") + + # Classifier head + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, + kernel_initializer=get_initializer(config.initializer_range), + name="classifier", + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, tuple]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.data2vec_vision( + pixel_values=pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + pooled_output = outputs.pooler_output if return_dict else outputs[1] + logits = self.classifier(pooled_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hidden_states, attentions=attentions) + + +class TFData2VecVisionConvModule(tf.keras.layers.Layer): + """ + A convolutional block that bundles conv/norm/activation layers. This block simplifies the usage of convolution + layers, which are commonly used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU). + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__( + self, + out_channels: int, + kernel_size: Union[int, Tuple[int, int]], + padding: str = "valid", + bias: bool = False, + dilation: Union[int, Tuple[int, int]] = 1, + **kwargs, + ) -> None: + super().__init__(**kwargs) + self.conv = tf.keras.layers.Conv2D( + filters=out_channels, + kernel_size=kernel_size, + padding=padding, + use_bias=bias, + dilation_rate=dilation, + name="conv", + ) + self.bn = tf.keras.layers.BatchNormalization(name="bn", momentum=0.9, epsilon=1e-5) + self.activation = tf.nn.relu + + def call(self, input: tf.Tensor) -> tf.Tensor: + output = self.conv(input) + output = self.bn(output) + output = self.activation(output) + return output + + +# Copied from: +# https://gist.github.com/Rocketknight1/43abbe6e73f1008e6e459486e01e0ceb +class TFAdaptiveAvgPool1D(tf.keras.layers.Layer): + def __init__(self, output_dim, mode="dense", **kwargs): + super().__init__(**kwargs) + self.output_dim = output_dim + self.mode = mode + self.map = None + + def build(self, input_shape): + super().build(input_shape) + """We pre-compute the sparse matrix for the build() step once. The below code comes + from https://stackoverflow.com/questions/53841509/how-does-adaptive-pooling-in-pytorch-work/63603993#63603993.""" + + def get_kernels(ind, outd) -> List: + """Returns a List [(kernel_offset_start,kernel_length)] defining all the pooling kernels for a 1-D adaptive + pooling layer that takes an input of dimension `ind` and yields an output of dimension `outd`""" + + def start_index(a, b, c): + return math.floor((float(a) * float(c)) / b) + + def end_index(a, b, c): + return math.ceil((float(a + 1) * float(c)) / b) + + results = [] + for ow in range(outd): + start = start_index(ow, outd, ind) + end = end_index(ow, outd, ind) + sz = end - start + results.append((start, sz)) + return results + + in_dim = int(input_shape[-1]) + kernels = get_kernels(in_dim, self.output_dim) + sparse_map = np.zeros((in_dim, self.output_dim), dtype=np.float32) + for i, kernel in enumerate(kernels): + sparse_map[kernel[0] : kernel[0] + kernel[1], i] = 1 / kernel[1] + if self.mode == "dense": + self.map = tf.constant(sparse_map) + else: + self.map = tf.sparse.from_dense(sparse_map) + + def call(self, inputs): + if self.mode == "dense": + return inputs @ self.map + else: + input_dims = inputs.shape + input_matrix = tf.reshape(inputs, (-1, input_dims[-1])) + out = tf.sparse.sparse_dense_matmul(input_matrix, self.map) + return tf.reshape(out, input_dims[:-1].as_list() + [-1]) + + def get_config(self): + config = super().get_config() + config.update({"output_dim": self.output_dim, "mode": self.mode}) + return config + + +class TFAdaptiveAvgPool2D(tf.keras.layers.Layer): + def __init__(self, output_shape, mode="dense", **kwargs): + super().__init__(**kwargs) + self.mode = mode + self.h_pool = TFAdaptiveAvgPool1D(output_shape[0], mode=mode, name="h_pool") + self.w_pool = TFAdaptiveAvgPool1D(output_shape[1], mode=mode, name="w_pool") + + def call(self, inputs): + # Rearrange from NHWC -> NCHW + inputs = tf.transpose(inputs, perm=[0, 3, 1, 2]) + # Perform W-pooling + inputs = self.w_pool(inputs) + # Rearrange NCHW -> NCWH + inputs = tf.transpose(inputs, perm=[0, 1, 3, 2]) + # Perform H-pooling + inputs = self.h_pool(inputs) + # Rearrange from NCWH -> NHWC + inputs = tf.transpose(inputs, perm=[0, 3, 2, 1]) + return inputs + + def get_config(self): + config = super().get_config() + config.update({"mode": self.mode}) + return config + + +class TFData2VecVisionPyramidPoolingModule(tf.keras.layers.Layer): + """ + Pyramid Pooling Module (PPM) used in PSPNet. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module. + channels (int): Channels after modules, before conv_seg. + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__(self, pool_scales: Tuple[int, ...], channels: int, **kwargs) -> None: + super().__init__(**kwargs) + self.pool_scales = pool_scales + self.channels = channels + + self.layer_list = [] + for idx, pool_scale in enumerate(pool_scales): + pool_scale = pool_scale if isinstance(pool_scale, collections.abc.Iterable) else (pool_scale, pool_scale) + self.layer_list.append( + [ + TFAdaptiveAvgPool2D(output_shape=pool_scale), + TFData2VecVisionConvModule(out_channels=self.channels, kernel_size=1, name=f"{idx}.1"), + ] + ) + + def call(self, x: tf.Tensor) -> List[tf.Tensor]: + ppm_outs = [] + inputs = x + + for ppm in self.layer_list: + for layer_module in ppm: + ppm_out = layer_module(x) + x = ppm_out + + upsampled_ppm_out = tf.image.resize(ppm_out, size=shape_list(inputs)[1:-1], method="bilinear") + ppm_outs.append(upsampled_ppm_out) + return ppm_outs + + +class TFData2VecVisionUperHead(tf.keras.layers.Layer): + """ + Unified Perceptual Parsing for Scene Understanding. This head is the implementation of + [UPerNet](https://arxiv.org/abs/1807.10221). + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__(self, config: Data2VecVisionConfig, **kwargs) -> None: + super().__init__(**kwargs) + + self.pool_scales = config.pool_scales # e.g. (1, 2, 3, 6) + self.in_channels = [config.hidden_size] * 4 # e.g. [768, 768, 768, 768] + self.channels = config.hidden_size + self.classifier = tf.keras.layers.Conv2D(config.num_labels, kernel_size=1, name="classifier") + + # PSP Module + self.psp_modules = TFData2VecVisionPyramidPoolingModule(self.pool_scales, self.channels, name="psp_modules") + self.bottleneck = TFData2VecVisionConvModule(self.channels, kernel_size=3, padding="same", name="bottleneck") + # FPN Module + self.lateral_convs = [] + self.fpn_convs = [] + for idx, _ in enumerate(self.in_channels[:-1]): # skip the top layer + l_conv = TFData2VecVisionConvModule(out_channels=self.channels, kernel_size=1, name=f"lateral_convs.{idx}") + fpn_conv = TFData2VecVisionConvModule( + out_channels=self.channels, kernel_size=3, padding="same", name=f"fpn_convs.{idx}" + ) + self.lateral_convs.append(l_conv) + self.fpn_convs.append(fpn_conv) + + self.fpn_bottleneck = TFData2VecVisionConvModule( + out_channels=self.channels, kernel_size=3, padding="same", name="fpn_bottleneck" + ) + + def psp_forward(self, inputs): + x = inputs[-1] + psp_outs = [x] + psp_outs.extend(self.psp_modules(x)) + psp_outs = tf.concat(psp_outs, axis=-1) + output = self.bottleneck(psp_outs) + + return output + + def call(self, encoder_hidden_states: tf.Tensor) -> tf.Tensor: + # build laterals + laterals = [lateral_conv(encoder_hidden_states[i]) for i, lateral_conv in enumerate(self.lateral_convs)] + + laterals.append(self.psp_forward(encoder_hidden_states)) + + # build top-down path + used_backbone_levels = len(laterals) + for i in range(used_backbone_levels - 1, 0, -1): + prev_shape = shape_list(laterals[i - 1])[1:-1] + laterals[i - 1] = laterals[i - 1] + tf.image.resize(laterals[i], size=prev_shape, method="bilinear") + + # build outputs + fpn_outs = [self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels - 1)] + # append psp feature + fpn_outs.append(laterals[-1]) + + for i in range(used_backbone_levels - 1, 0, -1): + fpn_outs[i] = tf.image.resize(fpn_outs[i], size=shape_list(fpn_outs[0])[1:-1], method="bilinear") + fpn_outs = tf.concat(fpn_outs, axis=-1) + output = self.fpn_bottleneck(fpn_outs) + output = self.classifier(output) + + return output + + +class TFData2VecVisionFCNHead(tf.keras.layers.Layer): + """ + Fully Convolution Networks for Semantic Segmentation. This head is implemented from + [FCNNet](https://arxiv.org/abs/1411.4038). + + Args: + config (Data2VecVisionConfig): Configuration. + kernel_size (int): The kernel size for convs in the head. Default: 3. + dilation (int): The dilation rate for convs in the head. Default: 1. + + + Based on OpenMMLab's implementation, found in https://github.com/open-mmlab/mmsegmentation. + """ + + def __init__( + self, + config: Data2VecVisionConfig, + in_index: int = 2, + kernel_size: int = 3, + dilation: Union[int, Tuple[int, int]] = 1, + **kwargs, + ) -> None: + super().__init__(**kwargs) + self.in_channels = config.hidden_size + self.channels = config.auxiliary_channels + self.num_convs = config.auxiliary_num_convs + self.concat_input = config.auxiliary_concat_input + self.in_index = in_index + + convs = [] + convs.append( + TFData2VecVisionConvModule( + out_channels=self.channels, + kernel_size=kernel_size, + padding="same", + dilation=dilation, + name="convs.0", + ) + ) + for i in range(self.num_convs - 1): + convs.append( + TFData2VecVisionConvModule( + out_channels=self.channels, + kernel_size=kernel_size, + padding="same", + dilation=dilation, + name=f"conv_module_{i+2}", + ) + ) + if self.num_convs == 0: + self.convs = [tf.identity] + else: + self.convs = convs + if self.concat_input: + self.conv_cat = TFData2VecVisionConvModule( + out_channels=self.channels, kernel_size=kernel_size, padding="same", name="conv_cat" + ) + + self.classifier = tf.keras.layers.Conv2D(config.num_labels, kernel_size=1, name="classifier") + + def call(self, encoder_hidden_states: tf.Tensor) -> tf.Tensor: + # just take the relevant feature maps + hidden_states = encoder_hidden_states[self.in_index] + output = hidden_states + for layer_module in self.convs: + output = layer_module(output) + if self.concat_input: + output = self.conv_cat(tf.concat([hidden_states, output], axis=-1)) + output = self.classifier(output) + return output + + +@add_start_docstrings( + """ + Data2VecVision Model transformer with a semantic segmentation head on top e.g. for ADE20k, CityScapes. + """, + DATA2VEC_VISION_START_DOCSTRING, +) +class TFData2VecVisionForSemanticSegmentation(TFData2VecVisionPreTrainedModel): + def __init__(self, config: Data2VecVisionConfig, *inputs, **kwargs) -> None: + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + self.data2vec_vision = TFData2VecVisionMainLayer(config, add_pooling_layer=False, name="data2vec_vision") + + # FPNs + self.fpn1 = [ + tf.keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn1.0"), + tf.keras.layers.BatchNormalization(name="fpn1.1", momentum=0.9, epsilon=1e-5), + tf.keras.layers.Activation("gelu"), + tf.keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn1.3"), + ] + self.fpn2 = [tf.keras.layers.Conv2DTranspose(config.hidden_size, kernel_size=2, strides=2, name="fpn2.0")] + + self.fpn3 = tf.identity + self.fpn4 = tf.keras.layers.MaxPool2D(pool_size=2, strides=2) + + # Semantic segmentation head(s) + self.decode_head = TFData2VecVisionUperHead(config, name="decode_head") + self.auxiliary_head = ( + TFData2VecVisionFCNHead(config, name="auxiliary_head") if config.use_auxiliary_head else None + ) + + def compute_loss(self, logits, auxiliary_logits, labels): + # upsample logits to the images' original size + if len(shape_list(labels)) > 3: + label_interp_shape = shape_list(labels)[1:-1] + else: + label_interp_shape = shape_list(labels)[-2:] + + upsampled_logits = tf.image.resize(logits, size=label_interp_shape, method="bilinear") + if auxiliary_logits is not None: + upsampled_auxiliary_logits = tf.image.resize(auxiliary_logits, size=label_interp_shape, method="bilinear") + # compute weighted loss + loss_fct = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction="none") + + # Copied from https://www.tensorflow.org/text/tutorials/transformer#loss_and_metrics. + # Utility to mask the index to ignore during computing the loss. + def masked_loss(real, pred): + mask = tf.math.logical_not(tf.math.equal(real, self.config.semantic_loss_ignore_index)) + loss_ = loss_fct(real, pred) + mask = tf.cast(mask, dtype=loss_.dtype) + loss_ *= mask + reduced_masked_loss = tf.reduce_sum(loss_) / tf.reduce_sum(mask) + return tf.reshape(reduced_masked_loss, (1,)) + + main_loss = masked_loss(labels, upsampled_logits) + auxiliary_loss = masked_loss(labels, upsampled_auxiliary_logits) + loss = main_loss + self.config.auxiliary_loss_weight * auxiliary_loss + + return loss + + @unpack_inputs + @add_start_docstrings_to_model_forward(DATA2VEC_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSemanticSegmenterOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + labels: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, TFSemanticSegmenterOutput]: + r""" + labels (`tf.Tensor` of shape `(batch_size, height, width)`, *optional*): + Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, TFData2VecVisionForSemanticSegmentation + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/data2vec-vision-base") + >>> model = TFData2VecVisionForSemanticSegmentation.from_pretrained("facebook/data2vec-vision-base") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + >>> # logits are of shape (batch_size, num_labels, height, width) + >>> logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + + outputs = self.data2vec_vision( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=True, # we need the intermediate hidden states + return_dict=return_dict, + ) + encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1] + + # only keep certain features, and reshape + # note that we do +1 as the encoder_hidden_states also includes the initial embeddings + features = [feature for idx, feature in enumerate(encoder_hidden_states) if idx + 1 in self.config.out_indices] + batch_size = shape_list(pixel_values)[0] + patch_resolution = self.config.image_size // self.config.patch_size + + def reshape_features(x): + x = tf.reshape(x, (batch_size, patch_resolution, patch_resolution, -1)) + return x + + features = [reshape_features(x[:, 1:, :]) for x in features] + + # apply FPNs + ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4] + for module in ops[0]: + features[0] = module(features[0]) + features[1] = ops[1][0](features[1]) + for i in range(len(features[2:])): + features[i + 2] = ops[i + 2](features[i + 2]) + + logits = self.decode_head(features) + # Tranpose the logits to maintain consistency in the output formats. + transposed_logits = tf.transpose(logits, perm=[0, 3, 1, 2]) + + auxiliary_logits = None + if self.auxiliary_head is not None: + auxiliary_logits = self.auxiliary_head(features) + + loss = None + if labels is not None: + if self.config.num_labels == 1: + raise ValueError("The number of labels should be greater than one") + else: + loss = self.compute_loss(logits, auxiliary_logits, labels) + + if not return_dict: + if output_hidden_states: + output = (logits,) + outputs[1:] + else: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFSemanticSegmenterOutput( + loss=loss, + logits=transposed_logits, + hidden_states=outputs.hidden_states if output_hidden_states else None, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFSemanticSegmenterOutput) -> TFSemanticSegmenterOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSemanticSegmenterOutput(logits=output.logits, hidden_states=hidden_states, attentions=attentions) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/configuration_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/configuration_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..94ea91cd3a0888228764e10b0e69d2a56536cb1e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/configuration_deberta.py @@ -0,0 +1,198 @@ +# coding=utf-8 +# Copyright 2020, Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DeBERTa model configuration""" +from collections import OrderedDict +from typing import TYPE_CHECKING, Any, Mapping, Optional, Union + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +if TYPE_CHECKING: + from ... import FeatureExtractionMixin, PreTrainedTokenizerBase, TensorType + + +logger = logging.get_logger(__name__) + +DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "microsoft/deberta-base": "https://huggingface.co/microsoft/deberta-base/resolve/main/config.json", + "microsoft/deberta-large": "https://huggingface.co/microsoft/deberta-large/resolve/main/config.json", + "microsoft/deberta-xlarge": "https://huggingface.co/microsoft/deberta-xlarge/resolve/main/config.json", + "microsoft/deberta-base-mnli": "https://huggingface.co/microsoft/deberta-base-mnli/resolve/main/config.json", + "microsoft/deberta-large-mnli": "https://huggingface.co/microsoft/deberta-large-mnli/resolve/main/config.json", + "microsoft/deberta-xlarge-mnli": "https://huggingface.co/microsoft/deberta-xlarge-mnli/resolve/main/config.json", +} + + +class DebertaConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DebertaModel`] or a [`TFDebertaModel`]. It is + used to instantiate a DeBERTa model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the DeBERTa + [microsoft/deberta-base](https://huggingface.co/microsoft/deberta-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Arguments: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the DeBERTa model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`DebertaModel`] or [`TFDebertaModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"`, `"gelu"`, `"tanh"`, `"gelu_fast"`, `"mish"`, `"linear"`, `"sigmoid"` and `"gelu_new"` + are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`DebertaModel`] or [`TFDebertaModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + relative_attention (`bool`, *optional*, defaults to `False`): + Whether use relative position encoding. + max_relative_positions (`int`, *optional*, defaults to 1): + The range of relative positions `[-max_position_embeddings, max_position_embeddings]`. Use the same value + as `max_position_embeddings`. + pad_token_id (`int`, *optional*, defaults to 0): + The value used to pad input_ids. + position_biased_input (`bool`, *optional*, defaults to `True`): + Whether add absolute position embedding to content embedding. + pos_att_type (`List[str]`, *optional*): + The type of relative position attention, it can be a combination of `["p2c", "c2p"]`, e.g. `["p2c"]`, + `["p2c", "c2p"]`. + layer_norm_eps (`float`, optional, defaults to 1e-12): + The epsilon used by the layer normalization layers. + + Example: + + ```python + >>> from transformers import DebertaConfig, DebertaModel + + >>> # Initializing a DeBERTa microsoft/deberta-base style configuration + >>> configuration = DebertaConfig() + + >>> # Initializing a model (with random weights) from the microsoft/deberta-base style configuration + >>> model = DebertaModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "deberta" + + def __init__( + self, + vocab_size=50265, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=0, + initializer_range=0.02, + layer_norm_eps=1e-7, + relative_attention=False, + max_relative_positions=-1, + pad_token_id=0, + position_biased_input=True, + pos_att_type=None, + pooler_dropout=0, + pooler_hidden_act="gelu", + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.relative_attention = relative_attention + self.max_relative_positions = max_relative_positions + self.pad_token_id = pad_token_id + self.position_biased_input = position_biased_input + + # Backwards compatibility + if type(pos_att_type) == str: + pos_att_type = [x.strip() for x in pos_att_type.lower().split("|")] + + self.pos_att_type = pos_att_type + self.vocab_size = vocab_size + self.layer_norm_eps = layer_norm_eps + + self.pooler_hidden_size = kwargs.get("pooler_hidden_size", hidden_size) + self.pooler_dropout = pooler_dropout + self.pooler_hidden_act = pooler_hidden_act + + +# Copied from transformers.models.deberta_v2.configuration_deberta_v2.DebertaV2OnnxConfig +class DebertaOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + if self._config.type_vocab_size > 0: + return OrderedDict( + [("input_ids", dynamic_axis), ("attention_mask", dynamic_axis), ("token_type_ids", dynamic_axis)] + ) + else: + return OrderedDict([("input_ids", dynamic_axis), ("attention_mask", dynamic_axis)]) + + @property + def default_onnx_opset(self) -> int: + return 12 + + def generate_dummy_inputs( + self, + preprocessor: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin"], + batch_size: int = -1, + seq_length: int = -1, + num_choices: int = -1, + is_pair: bool = False, + framework: Optional["TensorType"] = None, + num_channels: int = 3, + image_width: int = 40, + image_height: int = 40, + tokenizer: "PreTrainedTokenizerBase" = None, + ) -> Mapping[str, Any]: + dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor, framework=framework) + if self._config.type_vocab_size == 0 and "token_type_ids" in dummy_inputs: + del dummy_inputs["token_type_ids"] + return dummy_inputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..7c98a2d0d49dd50bdf2d747f781d80977a6db348 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_deberta.py @@ -0,0 +1,1446 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the Hugging Face Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DeBERTa model.""" + +from collections.abc import Sequence +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + MaskedLMOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import softmax_backward_data +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_deberta import DebertaConfig + + +logger = logging.get_logger(__name__) +_CONFIG_FOR_DOC = "DebertaConfig" +_CHECKPOINT_FOR_DOC = "microsoft/deberta-base" + +# Masked LM docstring +_CHECKPOINT_FOR_MASKED_LM = "lsanochkin/deberta-large-feedback" +_MASKED_LM_EXPECTED_OUTPUT = "' Paris'" +_MASKED_LM_EXPECTED_LOSS = "0.54" + +# QuestionAnswering docstring +_CHECKPOINT_FOR_QA = "Palak/microsoft_deberta-large_squad" +_QA_EXPECTED_OUTPUT = "' a nice puppet'" +_QA_EXPECTED_LOSS = 0.14 +_QA_TARGET_START_INDEX = 12 +_QA_TARGET_END_INDEX = 14 + + +DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "microsoft/deberta-base", + "microsoft/deberta-large", + "microsoft/deberta-xlarge", + "microsoft/deberta-base-mnli", + "microsoft/deberta-large-mnli", + "microsoft/deberta-xlarge-mnli", +] + + +class ContextPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.pooler_hidden_size, config.pooler_hidden_size) + self.dropout = StableDropout(config.pooler_dropout) + self.config = config + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + + context_token = hidden_states[:, 0] + context_token = self.dropout(context_token) + pooled_output = self.dense(context_token) + pooled_output = ACT2FN[self.config.pooler_hidden_act](pooled_output) + return pooled_output + + @property + def output_dim(self): + return self.config.hidden_size + + +class XSoftmax(torch.autograd.Function): + """ + Masked Softmax which is optimized for saving memory + + Args: + input (`torch.tensor`): The input tensor that will apply softmax. + mask (`torch.IntTensor`): + The mask matrix where 0 indicate that element will be ignored in the softmax calculation. + dim (int): The dimension that will apply softmax + + Example: + + ```python + >>> import torch + >>> from transformers.models.deberta.modeling_deberta import XSoftmax + + >>> # Make a tensor + >>> x = torch.randn([4, 20, 100]) + + >>> # Create a mask + >>> mask = (x > 0).int() + + >>> # Specify the dimension to apply softmax + >>> dim = -1 + + >>> y = XSoftmax.apply(x, mask, dim) + ```""" + + @staticmethod + def forward(self, input, mask, dim): + self.dim = dim + rmask = ~(mask.to(torch.bool)) + + output = input.masked_fill(rmask, torch.tensor(torch.finfo(input.dtype).min)) + output = torch.softmax(output, self.dim) + output.masked_fill_(rmask, 0) + self.save_for_backward(output) + return output + + @staticmethod + def backward(self, grad_output): + (output,) = self.saved_tensors + inputGrad = softmax_backward_data(self, grad_output, output, self.dim, output) + return inputGrad, None, None + + @staticmethod + def symbolic(g, self, mask, dim): + import torch.onnx.symbolic_helper as sym_help + from torch.onnx.symbolic_opset9 import masked_fill, softmax + + mask_cast_value = g.op("Cast", mask, to_i=sym_help.cast_pytorch_to_onnx["Long"]) + r_mask = g.op( + "Cast", + g.op("Sub", g.op("Constant", value_t=torch.tensor(1, dtype=torch.int64)), mask_cast_value), + to_i=sym_help.cast_pytorch_to_onnx["Byte"], + ) + output = masked_fill( + g, self, r_mask, g.op("Constant", value_t=torch.tensor(torch.finfo(self.type().dtype()).min)) + ) + output = softmax(g, output, dim) + return masked_fill(g, output, r_mask, g.op("Constant", value_t=torch.tensor(0, dtype=torch.bool))) + + +class DropoutContext(object): + def __init__(self): + self.dropout = 0 + self.mask = None + self.scale = 1 + self.reuse_mask = True + + +def get_mask(input, local_context): + if not isinstance(local_context, DropoutContext): + dropout = local_context + mask = None + else: + dropout = local_context.dropout + dropout *= local_context.scale + mask = local_context.mask if local_context.reuse_mask else None + + if dropout > 0 and mask is None: + mask = (1 - torch.empty_like(input).bernoulli_(1 - dropout)).to(torch.bool) + + if isinstance(local_context, DropoutContext): + if local_context.mask is None: + local_context.mask = mask + + return mask, dropout + + +class XDropout(torch.autograd.Function): + """Optimized dropout function to save computation and memory by using mask operation instead of multiplication.""" + + @staticmethod + def forward(ctx, input, local_ctx): + mask, dropout = get_mask(input, local_ctx) + ctx.scale = 1.0 / (1 - dropout) + if dropout > 0: + ctx.save_for_backward(mask) + return input.masked_fill(mask, 0) * ctx.scale + else: + return input + + @staticmethod + def backward(ctx, grad_output): + if ctx.scale > 1: + (mask,) = ctx.saved_tensors + return grad_output.masked_fill(mask, 0) * ctx.scale, None + else: + return grad_output, None + + @staticmethod + def symbolic(g: torch._C.Graph, input: torch._C.Value, local_ctx: Union[float, DropoutContext]) -> torch._C.Value: + from torch.onnx import symbolic_opset12 + + dropout_p = local_ctx + if isinstance(local_ctx, DropoutContext): + dropout_p = local_ctx.dropout + # StableDropout only calls this function when training. + train = True + # TODO: We should check if the opset_version being used to export + # is > 12 here, but there's no good way to do that. As-is, if the + # opset_version < 12, export will fail with a CheckerError. + # Once https://github.com/pytorch/pytorch/issues/78391 is fixed, do something like: + # if opset_version < 12: + # return torch.onnx.symbolic_opset9.dropout(g, input, dropout_p, train) + return symbolic_opset12.dropout(g, input, dropout_p, train) + + +class StableDropout(nn.Module): + """ + Optimized dropout module for stabilizing the training + + Args: + drop_prob (float): the dropout probabilities + """ + + def __init__(self, drop_prob): + super().__init__() + self.drop_prob = drop_prob + self.count = 0 + self.context_stack = None + + def forward(self, x): + """ + Call the module + + Args: + x (`torch.tensor`): The input tensor to apply dropout + """ + if self.training and self.drop_prob > 0: + return XDropout.apply(x, self.get_context()) + return x + + def clear_context(self): + self.count = 0 + self.context_stack = None + + def init_context(self, reuse_mask=True, scale=1): + if self.context_stack is None: + self.context_stack = [] + self.count = 0 + for c in self.context_stack: + c.reuse_mask = reuse_mask + c.scale = scale + + def get_context(self): + if self.context_stack is not None: + if self.count >= len(self.context_stack): + self.context_stack.append(DropoutContext()) + ctx = self.context_stack[self.count] + ctx.dropout = self.drop_prob + self.count += 1 + return ctx + else: + return self.drop_prob + + +class DebertaLayerNorm(nn.Module): + """LayerNorm module in the TF style (epsilon inside the square root).""" + + def __init__(self, size, eps=1e-12): + super().__init__() + self.weight = nn.Parameter(torch.ones(size)) + self.bias = nn.Parameter(torch.zeros(size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_type = hidden_states.dtype + hidden_states = hidden_states.float() + mean = hidden_states.mean(-1, keepdim=True) + variance = (hidden_states - mean).pow(2).mean(-1, keepdim=True) + hidden_states = (hidden_states - mean) / torch.sqrt(variance + self.variance_epsilon) + hidden_states = hidden_states.to(input_type) + y = self.weight * hidden_states + self.bias + return y + + +class DebertaSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = DebertaLayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class DebertaAttention(nn.Module): + def __init__(self, config): + super().__init__() + self.self = DisentangledSelfAttention(config) + self.output = DebertaSelfOutput(config) + self.config = config + + def forward( + self, + hidden_states, + attention_mask, + output_attentions=False, + query_states=None, + relative_pos=None, + rel_embeddings=None, + ): + self_output = self.self( + hidden_states, + attention_mask, + output_attentions, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + ) + if output_attentions: + self_output, att_matrix = self_output + if query_states is None: + query_states = hidden_states + attention_output = self.output(self_output, query_states) + + if output_attentions: + return (attention_output, att_matrix) + else: + return attention_output + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->Deberta +class DebertaIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +class DebertaOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = DebertaLayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + self.config = config + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class DebertaLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.attention = DebertaAttention(config) + self.intermediate = DebertaIntermediate(config) + self.output = DebertaOutput(config) + + def forward( + self, + hidden_states, + attention_mask, + query_states=None, + relative_pos=None, + rel_embeddings=None, + output_attentions=False, + ): + attention_output = self.attention( + hidden_states, + attention_mask, + output_attentions=output_attentions, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + ) + if output_attentions: + attention_output, att_matrix = attention_output + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + if output_attentions: + return (layer_output, att_matrix) + else: + return layer_output + + +class DebertaEncoder(nn.Module): + """Modified BertEncoder with relative position bias support""" + + def __init__(self, config): + super().__init__() + self.layer = nn.ModuleList([DebertaLayer(config) for _ in range(config.num_hidden_layers)]) + self.relative_attention = getattr(config, "relative_attention", False) + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + self.rel_embeddings = nn.Embedding(self.max_relative_positions * 2, config.hidden_size) + self.gradient_checkpointing = False + + def get_rel_embedding(self): + rel_embeddings = self.rel_embeddings.weight if self.relative_attention else None + return rel_embeddings + + def get_attention_mask(self, attention_mask): + if attention_mask.dim() <= 2: + extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2) + attention_mask = extended_attention_mask * extended_attention_mask.squeeze(-2).unsqueeze(-1) + attention_mask = attention_mask.byte() + elif attention_mask.dim() == 3: + attention_mask = attention_mask.unsqueeze(1) + + return attention_mask + + def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): + if self.relative_attention and relative_pos is None: + q = query_states.size(-2) if query_states is not None else hidden_states.size(-2) + relative_pos = build_relative_position(q, hidden_states.size(-2), hidden_states.device) + return relative_pos + + def forward( + self, + hidden_states, + attention_mask, + output_hidden_states=True, + output_attentions=False, + query_states=None, + relative_pos=None, + return_dict=True, + ): + attention_mask = self.get_attention_mask(attention_mask) + relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) + + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[0] + else: + next_kv = hidden_states + rel_embeddings = self.get_rel_embedding() + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + next_kv, + attention_mask, + query_states, + relative_pos, + rel_embeddings, + ) + else: + hidden_states = layer_module( + next_kv, + attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + ) + + if output_attentions: + hidden_states, att_m = hidden_states + + if query_states is not None: + query_states = hidden_states + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[i + 1] if i + 1 < len(self.layer) else None + else: + next_kv = hidden_states + + if output_attentions: + all_attentions = all_attentions + (att_m,) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +def build_relative_position(query_size, key_size, device): + """ + Build relative position according to the query and key + + We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key + \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - + P_k\\) + + Args: + query_size (int): the length of query + key_size (int): the length of key + + Return: + `torch.LongTensor`: A tensor with shape [1, query_size, key_size] + + """ + + q_ids = torch.arange(query_size, dtype=torch.long, device=device) + k_ids = torch.arange(key_size, dtype=torch.long, device=device) + rel_pos_ids = q_ids[:, None] - k_ids.view(1, -1).repeat(query_size, 1) + rel_pos_ids = rel_pos_ids[:query_size, :] + rel_pos_ids = rel_pos_ids.unsqueeze(0) + return rel_pos_ids + + +@torch.jit.script +def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): + return c2p_pos.expand([query_layer.size(0), query_layer.size(1), query_layer.size(2), relative_pos.size(-1)]) + + +@torch.jit.script +def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): + return c2p_pos.expand([query_layer.size(0), query_layer.size(1), key_layer.size(-2), key_layer.size(-2)]) + + +@torch.jit.script +def pos_dynamic_expand(pos_index, p2c_att, key_layer): + return pos_index.expand(p2c_att.size()[:2] + (pos_index.size(-2), key_layer.size(-2))) + + +class DisentangledSelfAttention(nn.Module): + """ + Disentangled self-attention module + + Parameters: + config (`str`): + A model config class instance with the configuration to build a new model. The schema is similar to + *BertConfig*, for more details, please refer [`DebertaConfig`] + + """ + + def __init__(self, config): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.in_proj = nn.Linear(config.hidden_size, self.all_head_size * 3, bias=False) + self.q_bias = nn.Parameter(torch.zeros((self.all_head_size), dtype=torch.float)) + self.v_bias = nn.Parameter(torch.zeros((self.all_head_size), dtype=torch.float)) + self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] + + self.relative_attention = getattr(config, "relative_attention", False) + self.talking_head = getattr(config, "talking_head", False) + + if self.talking_head: + self.head_logits_proj = nn.Linear(config.num_attention_heads, config.num_attention_heads, bias=False) + self.head_weights_proj = nn.Linear(config.num_attention_heads, config.num_attention_heads, bias=False) + + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + self.pos_dropout = StableDropout(config.hidden_dropout_prob) + + if "c2p" in self.pos_att_type: + self.pos_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=False) + if "p2c" in self.pos_att_type: + self.pos_q_proj = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = StableDropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x): + new_x_shape = x.size()[:-1] + (self.num_attention_heads, -1) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states, + attention_mask, + output_attentions=False, + query_states=None, + relative_pos=None, + rel_embeddings=None, + ): + """ + Call the module + + Args: + hidden_states (`torch.FloatTensor`): + Input states to the module usually the output from previous layer, it will be the Q,K and V in + *Attention(Q,K,V)* + + attention_mask (`torch.ByteTensor`): + An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum + sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* + th token. + + output_attentions (`bool`, optional): + Whether return the attention matrix. + + query_states (`torch.FloatTensor`, optional): + The *Q* state in *Attention(Q,K,V)*. + + relative_pos (`torch.LongTensor`): + The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with + values ranging in [*-max_relative_positions*, *max_relative_positions*]. + + rel_embeddings (`torch.FloatTensor`): + The embedding of relative distances. It's a tensor of shape [\\(2 \\times + \\text{max_relative_positions}\\), *hidden_size*]. + + + """ + if query_states is None: + qp = self.in_proj(hidden_states) # .split(self.all_head_size, dim=-1) + query_layer, key_layer, value_layer = self.transpose_for_scores(qp).chunk(3, dim=-1) + else: + + def linear(w, b, x): + if b is not None: + return torch.matmul(x, w.t()) + b.t() + else: + return torch.matmul(x, w.t()) # + b.t() + + ws = self.in_proj.weight.chunk(self.num_attention_heads * 3, dim=0) + qkvw = [torch.cat([ws[i * 3 + k] for i in range(self.num_attention_heads)], dim=0) for k in range(3)] + qkvb = [None] * 3 + + q = linear(qkvw[0], qkvb[0], query_states.to(dtype=qkvw[0].dtype)) + k, v = [linear(qkvw[i], qkvb[i], hidden_states.to(dtype=qkvw[i].dtype)) for i in range(1, 3)] + query_layer, key_layer, value_layer = [self.transpose_for_scores(x) for x in [q, k, v]] + + query_layer = query_layer + self.transpose_for_scores(self.q_bias[None, None, :]) + value_layer = value_layer + self.transpose_for_scores(self.v_bias[None, None, :]) + + rel_att = None + # Take the dot product between "query" and "key" to get the raw attention scores. + scale_factor = 1 + len(self.pos_att_type) + scale = torch.sqrt(torch.tensor(query_layer.size(-1), dtype=torch.float) * scale_factor) + query_layer = query_layer / scale.to(dtype=query_layer.dtype) + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + if self.relative_attention: + rel_embeddings = self.pos_dropout(rel_embeddings) + rel_att = self.disentangled_att_bias(query_layer, key_layer, relative_pos, rel_embeddings, scale_factor) + + if rel_att is not None: + attention_scores = attention_scores + rel_att + + # bxhxlxd + if self.talking_head: + attention_scores = self.head_logits_proj(attention_scores.permute(0, 2, 3, 1)).permute(0, 3, 1, 2) + + attention_probs = XSoftmax.apply(attention_scores, attention_mask, -1) + attention_probs = self.dropout(attention_probs) + if self.talking_head: + attention_probs = self.head_weights_proj(attention_probs.permute(0, 2, 3, 1)).permute(0, 3, 1, 2) + + context_layer = torch.matmul(attention_probs, value_layer) + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (-1,) + context_layer = context_layer.view(new_context_layer_shape) + if output_attentions: + return (context_layer, attention_probs) + else: + return context_layer + + def disentangled_att_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): + if relative_pos is None: + q = query_layer.size(-2) + relative_pos = build_relative_position(q, key_layer.size(-2), query_layer.device) + if relative_pos.dim() == 2: + relative_pos = relative_pos.unsqueeze(0).unsqueeze(0) + elif relative_pos.dim() == 3: + relative_pos = relative_pos.unsqueeze(1) + # bxhxqxk + elif relative_pos.dim() != 4: + raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {relative_pos.dim()}") + + att_span = min(max(query_layer.size(-2), key_layer.size(-2)), self.max_relative_positions) + relative_pos = relative_pos.long().to(query_layer.device) + rel_embeddings = rel_embeddings[ + self.max_relative_positions - att_span : self.max_relative_positions + att_span, : + ].unsqueeze(0) + + score = 0 + + # content->position + if "c2p" in self.pos_att_type: + pos_key_layer = self.pos_proj(rel_embeddings) + pos_key_layer = self.transpose_for_scores(pos_key_layer) + c2p_att = torch.matmul(query_layer, pos_key_layer.transpose(-1, -2)) + c2p_pos = torch.clamp(relative_pos + att_span, 0, att_span * 2 - 1) + c2p_att = torch.gather(c2p_att, dim=-1, index=c2p_dynamic_expand(c2p_pos, query_layer, relative_pos)) + score += c2p_att + + # position->content + if "p2c" in self.pos_att_type: + pos_query_layer = self.pos_q_proj(rel_embeddings) + pos_query_layer = self.transpose_for_scores(pos_query_layer) + pos_query_layer /= torch.sqrt(torch.tensor(pos_query_layer.size(-1), dtype=torch.float) * scale_factor) + if query_layer.size(-2) != key_layer.size(-2): + r_pos = build_relative_position(key_layer.size(-2), key_layer.size(-2), query_layer.device) + else: + r_pos = relative_pos + p2c_pos = torch.clamp(-r_pos + att_span, 0, att_span * 2 - 1) + p2c_att = torch.matmul(key_layer, pos_query_layer.transpose(-1, -2).to(dtype=key_layer.dtype)) + p2c_att = torch.gather( + p2c_att, dim=-1, index=p2c_dynamic_expand(p2c_pos, query_layer, key_layer) + ).transpose(-1, -2) + + if query_layer.size(-2) != key_layer.size(-2): + pos_index = relative_pos[:, :, :, 0].unsqueeze(-1) + p2c_att = torch.gather(p2c_att, dim=-2, index=pos_dynamic_expand(pos_index, p2c_att, key_layer)) + score += p2c_att + + return score + + +class DebertaEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + pad_token_id = getattr(config, "pad_token_id", 0) + self.embedding_size = getattr(config, "embedding_size", config.hidden_size) + self.word_embeddings = nn.Embedding(config.vocab_size, self.embedding_size, padding_idx=pad_token_id) + + self.position_biased_input = getattr(config, "position_biased_input", True) + if not self.position_biased_input: + self.position_embeddings = None + else: + self.position_embeddings = nn.Embedding(config.max_position_embeddings, self.embedding_size) + + if config.type_vocab_size > 0: + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, self.embedding_size) + + if self.embedding_size != config.hidden_size: + self.embed_proj = nn.Linear(self.embedding_size, config.hidden_size, bias=False) + self.LayerNorm = DebertaLayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + self.config = config + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + + def forward(self, input_ids=None, token_type_ids=None, position_ids=None, mask=None, inputs_embeds=None): + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, :seq_length] + + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + + if self.position_embeddings is not None: + position_embeddings = self.position_embeddings(position_ids.long()) + else: + position_embeddings = torch.zeros_like(inputs_embeds) + + embeddings = inputs_embeds + if self.position_biased_input: + embeddings += position_embeddings + if self.config.type_vocab_size > 0: + token_type_embeddings = self.token_type_embeddings(token_type_ids) + embeddings += token_type_embeddings + + if self.embedding_size != self.config.hidden_size: + embeddings = self.embed_proj(embeddings) + + embeddings = self.LayerNorm(embeddings) + + if mask is not None: + if mask.dim() != embeddings.dim(): + if mask.dim() == 4: + mask = mask.squeeze(1).squeeze(1) + mask = mask.unsqueeze(2) + mask = mask.to(embeddings.dtype) + + embeddings = embeddings * mask + + embeddings = self.dropout(embeddings) + return embeddings + + +class DebertaPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DebertaConfig + base_model_prefix = "deberta" + _keys_to_ignore_on_load_missing = ["position_ids"] + _keys_to_ignore_on_load_unexpected = ["position_embeddings"] + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DebertaEncoder): + module.gradient_checkpointing = value + + +DEBERTA_START_DOCSTRING = r""" + The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled + Attention](https://arxiv.org/abs/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build + on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two + improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + + Parameters: + config ([`DebertaConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert *input_ids* indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", + DEBERTA_START_DOCSTRING, +) +class DebertaModel(DebertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.embeddings = DebertaEmbeddings(config) + self.encoder = DebertaEncoder(config) + self.z_steps = 0 + self.config = config + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, new_embeddings): + self.embeddings.word_embeddings = new_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError("The prune function is not implemented in DeBERTa model.") + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + embedding_output = self.embeddings( + input_ids=input_ids, + token_type_ids=token_type_ids, + position_ids=position_ids, + mask=attention_mask, + inputs_embeds=inputs_embeds, + ) + + encoder_outputs = self.encoder( + embedding_output, + attention_mask, + output_hidden_states=True, + output_attentions=output_attentions, + return_dict=return_dict, + ) + encoded_layers = encoder_outputs[1] + + if self.z_steps > 1: + hidden_states = encoded_layers[-2] + layers = [self.encoder.layer[-1] for _ in range(self.z_steps)] + query_states = encoded_layers[-1] + rel_embeddings = self.encoder.get_rel_embedding() + attention_mask = self.encoder.get_attention_mask(attention_mask) + rel_pos = self.encoder.get_rel_pos(embedding_output) + for layer in layers[1:]: + query_states = layer( + hidden_states, + attention_mask, + output_attentions=False, + query_states=query_states, + relative_pos=rel_pos, + rel_embeddings=rel_embeddings, + ) + encoded_layers.append(query_states) + + sequence_output = encoded_layers[-1] + + if not return_dict: + return (sequence_output,) + encoder_outputs[(1 if output_hidden_states else 2) :] + + return BaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states if output_hidden_states else None, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) +class DebertaForMaskedLM(DebertaPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"predictions.decoder.bias", "cls.predictions.decoder.weight"] + + def __init__(self, config): + super().__init__(config) + + self.deberta = DebertaModel(config) + self.cls = DebertaOnlyMLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.cls.predictions.decoder + + def set_output_embeddings(self, new_embeddings): + self.cls.predictions.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_MASKED_LM, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="[MASK]", + expected_output=_MASKED_LM_EXPECTED_OUTPUT, + expected_loss=_MASKED_LM_EXPECTED_LOSS, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.cls(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() # -100 index = padding token + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[1:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# copied from transformers.models.bert.BertPredictionHeadTransform with bert -> deberta +class DebertaPredictionHeadTransform(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + if isinstance(config.hidden_act, str): + self.transform_act_fn = ACT2FN[config.hidden_act] + else: + self.transform_act_fn = config.hidden_act + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + return hidden_states + + +# copied from transformers.models.bert.BertLMPredictionHead with bert -> deberta +class DebertaLMPredictionHead(nn.Module): + def __init__(self, config): + super().__init__() + self.transform = DebertaPredictionHeadTransform(config) + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + + # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, hidden_states): + hidden_states = self.transform(hidden_states) + hidden_states = self.decoder(hidden_states) + return hidden_states + + +# copied from transformers.models.bert.BertOnlyMLMHead with bert -> deberta +class DebertaOnlyMLMHead(nn.Module): + def __init__(self, config): + super().__init__() + self.predictions = DebertaLMPredictionHead(config) + + def forward(self, sequence_output): + prediction_scores = self.predictions(sequence_output) + return prediction_scores + + +@add_start_docstrings( + """ + DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DEBERTA_START_DOCSTRING, +) +class DebertaForSequenceClassification(DebertaPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + num_labels = getattr(config, "num_labels", 2) + self.num_labels = num_labels + + self.deberta = DebertaModel(config) + self.pooler = ContextPooler(config) + output_dim = self.pooler.output_dim + + self.classifier = nn.Linear(output_dim, num_labels) + drop_out = getattr(config, "cls_dropout", None) + drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out + self.dropout = StableDropout(drop_out) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.deberta.get_input_embeddings() + + def set_input_embeddings(self, new_embeddings): + self.deberta.set_input_embeddings(new_embeddings) + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + token_type_ids=token_type_ids, + attention_mask=attention_mask, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + encoder_layer = outputs[0] + pooled_output = self.pooler(encoder_layer) + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + # regression task + loss_fn = nn.MSELoss() + logits = logits.view(-1).to(labels.dtype) + loss = loss_fn(logits, labels.view(-1)) + elif labels.dim() == 1 or labels.size(-1) == 1: + label_index = (labels >= 0).nonzero() + labels = labels.long() + if label_index.size(0) > 0: + labeled_logits = torch.gather( + logits, 0, label_index.expand(label_index.size(0), logits.size(1)) + ) + labels = torch.gather(labels, 0, label_index.view(-1)) + loss_fct = CrossEntropyLoss() + loss = loss_fct(labeled_logits.view(-1, self.num_labels).float(), labels.view(-1)) + else: + loss = torch.tensor(0).to(logits) + else: + log_softmax = nn.LogSoftmax(-1) + loss = -((log_softmax(logits) * labels).sum(-1)).mean() + elif self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + DEBERTA_START_DOCSTRING, +) +class DebertaForTokenClassification(DebertaPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.deberta = DebertaModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DEBERTA_START_DOCSTRING, +) +class DebertaForQuestionAnswering(DebertaPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.deberta = DebertaModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_QA, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_QA_EXPECTED_OUTPUT, + expected_loss=_QA_EXPECTED_LOSS, + qa_target_start_index=_QA_TARGET_START_INDEX, + qa_target_end_index=_QA_TARGET_END_INDEX, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_tf_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_tf_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..016ce15db618255c5acf428b05dd48ae0b88424f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/modeling_tf_deberta.py @@ -0,0 +1,1465 @@ +# coding=utf-8 +# Copyright 2021 Microsoft and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 DeBERTa model.""" + + +import math +from typing import Dict, Optional, Sequence, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFMaskedLMOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFMaskedLanguageModelingLoss, + TFModelInputType, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFTokenClassificationLoss, + get_initializer, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_deberta import DebertaConfig + + +logger = logging.get_logger(__name__) + + +_CONFIG_FOR_DOC = "DebertaConfig" +_CHECKPOINT_FOR_DOC = "kamalkraj/deberta-base" + +TF_DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "kamalkraj/deberta-base", + # See all DeBERTa models at https://huggingface.co/models?filter=DeBERTa +] + + +class TFDebertaContextPooler(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + self.dense = tf.keras.layers.Dense(config.pooler_hidden_size, name="dense") + self.dropout = TFDebertaStableDropout(config.pooler_dropout, name="dropout") + self.config = config + + def call(self, hidden_states, training: bool = False): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + context_token = hidden_states[:, 0] + context_token = self.dropout(context_token, training=training) + pooled_output = self.dense(context_token) + pooled_output = get_tf_activation(self.config.pooler_hidden_act)(pooled_output) + return pooled_output + + @property + def output_dim(self) -> int: + return self.config.hidden_size + + +class TFDebertaXSoftmax(tf.keras.layers.Layer): + """ + Masked Softmax which is optimized for saving memory + + Args: + input (`tf.Tensor`): The input tensor that will apply softmax. + mask (`tf.Tensor`): The mask matrix where 0 indicate that element will be ignored in the softmax calculation. + dim (int): The dimension that will apply softmax + """ + + def __init__(self, axis=-1, **kwargs): + super().__init__(**kwargs) + self.axis = axis + + def call(self, inputs: tf.Tensor, mask: tf.Tensor): + rmask = tf.logical_not(tf.cast(mask, tf.bool)) + output = tf.where(rmask, float("-inf"), inputs) + output = stable_softmax(output, self.axis) + output = tf.where(rmask, 0.0, output) + return output + + +class TFDebertaStableDropout(tf.keras.layers.Layer): + """ + Optimized dropout module for stabilizing the training + + Args: + drop_prob (float): the dropout probabilities + """ + + def __init__(self, drop_prob, **kwargs): + super().__init__(**kwargs) + self.drop_prob = drop_prob + + @tf.custom_gradient + def xdropout(self, inputs): + """ + Applies dropout to the inputs, as vanilla dropout, but also scales the remaining elements up by 1/drop_prob. + """ + mask = tf.cast( + 1 + - tf.compat.v1.distributions.Bernoulli(probs=1.0 - self.drop_prob).sample(sample_shape=shape_list(inputs)), + tf.bool, + ) + scale = tf.convert_to_tensor(1.0 / (1 - self.drop_prob), dtype=tf.float32) + if self.drop_prob > 0: + inputs = tf.where(mask, 0.0, inputs) * scale + + def grad(upstream): + if self.drop_prob > 0: + return tf.where(mask, 0.0, upstream) * scale + else: + return upstream + + return inputs, grad + + def call(self, inputs: tf.Tensor, training: tf.Tensor = False): + if training: + return self.xdropout(inputs) + return inputs + + +class TFDebertaLayerNorm(tf.keras.layers.Layer): + """LayerNorm module in the TF style (epsilon inside the square root).""" + + def __init__(self, size, eps=1e-12, **kwargs): + super().__init__(**kwargs) + self.size = size + self.eps = eps + + def build(self, input_shape): + self.gamma = self.add_weight(shape=[self.size], initializer=tf.ones_initializer(), name="weight") + self.beta = self.add_weight(shape=[self.size], initializer=tf.zeros_initializer(), name="bias") + return super().build(input_shape) + + def call(self, x: tf.Tensor) -> tf.Tensor: + mean = tf.reduce_mean(x, axis=[-1], keepdims=True) + variance = tf.reduce_mean(tf.square(x - mean), axis=[-1], keepdims=True) + std = tf.math.sqrt(variance + self.eps) + return self.gamma * (x - mean) / std + self.beta + + +class TFDebertaSelfOutput(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + self.dense = tf.keras.layers.Dense(config.hidden_size, name="dense") + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") + + def call(self, hidden_states, input_tensor, training: bool = False): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class TFDebertaAttention(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + self.self = TFDebertaDisentangledSelfAttention(config, name="self") + self.dense_output = TFDebertaSelfOutput(config, name="output") + self.config = config + + def call( + self, + input_tensor: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self( + hidden_states=input_tensor, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + if query_states is None: + query_states = input_tensor + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=query_states, training=training + ) + + output = (attention_output,) + self_outputs[1:] + + return output + + +class TFDebertaIntermediate(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +class TFDebertaOutput(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + + return hidden_states + + +class TFDebertaLayer(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFDebertaAttention(config, name="attention") + self.intermediate = TFDebertaIntermediate(config, name="intermediate") + self.bert_output = TFDebertaOutput(config, name="output") + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + input_tensor=hidden_states, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + attention_output = attention_outputs[0] + intermediate_output = self.intermediate(hidden_states=attention_output) + layer_output = self.bert_output( + hidden_states=intermediate_output, input_tensor=attention_output, training=training + ) + outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them + + return outputs + + +class TFDebertaEncoder(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.layer = [TFDebertaLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + self.relative_attention = getattr(config, "relative_attention", False) + self.config = config + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + + def build(self, input_shape): + if self.relative_attention: + self.rel_embeddings = self.add_weight( + name="rel_embeddings.weight", + shape=[self.max_relative_positions * 2, self.config.hidden_size], + initializer=get_initializer(self.config.initializer_range), + ) + return super().build(input_shape) + + def get_rel_embedding(self): + rel_embeddings = self.rel_embeddings if self.relative_attention else None + return rel_embeddings + + def get_attention_mask(self, attention_mask): + if len(shape_list(attention_mask)) <= 2: + extended_attention_mask = tf.expand_dims(tf.expand_dims(attention_mask, 1), 2) + attention_mask = extended_attention_mask * tf.expand_dims(tf.squeeze(extended_attention_mask, -2), -1) + attention_mask = tf.cast(attention_mask, tf.uint8) + elif len(shape_list(attention_mask)) == 3: + attention_mask = tf.expand_dims(attention_mask, 1) + + return attention_mask + + def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): + if self.relative_attention and relative_pos is None: + q = shape_list(query_states)[-2] if query_states is not None else shape_list(hidden_states)[-2] + relative_pos = build_relative_position(q, shape_list(hidden_states)[-2]) + return relative_pos + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + attention_mask = self.get_attention_mask(attention_mask) + relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) + + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[0] + else: + next_kv = hidden_states + + rel_embeddings = self.get_rel_embedding() + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states=next_kv, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if query_states is not None: + query_states = hidden_states + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[i + 1] if i + 1 < len(self.layer) else None + else: + next_kv = hidden_states + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +def build_relative_position(query_size, key_size): + """ + Build relative position according to the query and key + + We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key + \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - + P_k\\) + + Args: + query_size (int): the length of query + key_size (int): the length of key + + Return: + `tf.Tensor`: A tensor with shape [1, query_size, key_size] + + """ + q_ids = tf.range(query_size, dtype=tf.int32) + k_ids = tf.range(key_size, dtype=tf.int32) + rel_pos_ids = q_ids[:, None] - tf.tile(tf.reshape(k_ids, [1, -1]), [query_size, 1]) + rel_pos_ids = rel_pos_ids[:query_size, :] + rel_pos_ids = tf.expand_dims(rel_pos_ids, axis=0) + return tf.cast(rel_pos_ids, tf.int64) + + +def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): + shapes = [ + shape_list(query_layer)[0], + shape_list(query_layer)[1], + shape_list(query_layer)[2], + shape_list(relative_pos)[-1], + ] + return tf.broadcast_to(c2p_pos, shapes) + + +def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): + shapes = [ + shape_list(query_layer)[0], + shape_list(query_layer)[1], + shape_list(key_layer)[-2], + shape_list(key_layer)[-2], + ] + return tf.broadcast_to(c2p_pos, shapes) + + +def pos_dynamic_expand(pos_index, p2c_att, key_layer): + shapes = shape_list(p2c_att)[:2] + [shape_list(pos_index)[-2], shape_list(key_layer)[-2]] + return tf.broadcast_to(pos_index, shapes) + + +def torch_gather(x, indices, gather_axis): + if gather_axis < 0: + gather_axis = tf.rank(x) + gather_axis + + if gather_axis != tf.rank(x) - 1: + pre_roll = tf.rank(x) - 1 - gather_axis + permutation = tf.roll(tf.range(tf.rank(x)), pre_roll, axis=0) + x = tf.transpose(x, perm=permutation) + indices = tf.transpose(indices, perm=permutation) + else: + pre_roll = 0 + + flat_x = tf.reshape(x, (-1, tf.shape(x)[-1])) + flat_indices = tf.reshape(indices, (-1, tf.shape(indices)[-1])) + gathered = tf.gather(flat_x, flat_indices, batch_dims=1) + gathered = tf.reshape(gathered, tf.shape(indices)) + + if pre_roll != 0: + permutation = tf.roll(tf.range(tf.rank(x)), -pre_roll, axis=0) + gathered = tf.transpose(gathered, perm=permutation) + + return gathered + + +class TFDebertaDisentangledSelfAttention(tf.keras.layers.Layer): + """ + Disentangled self-attention module + + Parameters: + config (`str`): + A model config class instance with the configuration to build a new model. The schema is similar to + *BertConfig*, for more details, please refer [`DebertaConfig`] + + """ + + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.in_proj = tf.keras.layers.Dense( + self.all_head_size * 3, + kernel_initializer=get_initializer(config.initializer_range), + name="in_proj", + use_bias=False, + ) + self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] + + self.relative_attention = getattr(config, "relative_attention", False) + self.talking_head = getattr(config, "talking_head", False) + + if self.talking_head: + self.head_logits_proj = tf.keras.layers.Dense( + self.num_attention_heads, + kernel_initializer=get_initializer(config.initializer_range), + name="head_logits_proj", + use_bias=False, + ) + self.head_weights_proj = tf.keras.layers.Dense( + self.num_attention_heads, + kernel_initializer=get_initializer(config.initializer_range), + name="head_weights_proj", + use_bias=False, + ) + + self.softmax = TFDebertaXSoftmax(axis=-1) + + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + self.pos_dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="pos_dropout") + if "c2p" in self.pos_att_type: + self.pos_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="pos_proj", + use_bias=False, + ) + if "p2c" in self.pos_att_type: + self.pos_q_proj = tf.keras.layers.Dense( + self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="pos_q_proj" + ) + + self.dropout = TFDebertaStableDropout(config.attention_probs_dropout_prob, name="dropout") + + def build(self, input_shape): + self.q_bias = self.add_weight( + name="q_bias", shape=(self.all_head_size), initializer=tf.keras.initializers.Zeros() + ) + self.v_bias = self.add_weight( + name="v_bias", shape=(self.all_head_size), initializer=tf.keras.initializers.Zeros() + ) + return super().build(input_shape) + + def transpose_for_scores(self, tensor: tf.Tensor) -> tf.Tensor: + shape = shape_list(tensor)[:-1] + [self.num_attention_heads, -1] + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=shape) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + """ + Call the module + + Args: + hidden_states (`tf.Tensor`): + Input states to the module usually the output from previous layer, it will be the Q,K and V in + *Attention(Q,K,V)* + + attention_mask (`tf.Tensor`): + An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum + sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* + th token. + + return_att (`bool`, optional): + Whether return the attention matrix. + + query_states (`tf.Tensor`, optional): + The *Q* state in *Attention(Q,K,V)*. + + relative_pos (`tf.Tensor`): + The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with + values ranging in [*-max_relative_positions*, *max_relative_positions*]. + + rel_embeddings (`tf.Tensor`): + The embedding of relative distances. It's a tensor of shape [\\(2 \\times + \\text{max_relative_positions}\\), *hidden_size*]. + + + """ + if query_states is None: + qp = self.in_proj(hidden_states) # .split(self.all_head_size, dim=-1) + query_layer, key_layer, value_layer = tf.split( + self.transpose_for_scores(qp), num_or_size_splits=3, axis=-1 + ) + else: + + def linear(w, b, x): + return tf.cond( + b is not None, + lambda: tf.matmul(x, w, transpose_b=True) + tf.transpose(b), + lambda: tf.matmul(x, w, transpose_b=True), + ) + + ws = tf.split( + tf.transpose(self.in_proj.weight[0]), num_or_size_splits=self.num_attention_heads * 3, axis=0 + ) + qkvw = tf.TensorArray(dtype=tf.float32, size=3) + for k in tf.range(3): + qkvw_inside = tf.TensorArray(dtype=tf.float32, size=self.num_attention_heads) + for i in tf.range(self.num_attention_heads): + qkvw_inside = qkvw_inside.write(i, ws[i * 3 + k]) + qkvw = qkvw.write(k, qkvw_inside.concat()) + qkvb = [None] * 3 + + q = linear(qkvw[0], qkvb[0], query_states) + k = linear(qkvw[1], qkvb[1], hidden_states) + v = linear(qkvw[2], qkvb[2], hidden_states) + query_layer = self.transpose_for_scores(q) + key_layer = self.transpose_for_scores(k) + value_layer = self.transpose_for_scores(v) + + query_layer = query_layer + self.transpose_for_scores(self.q_bias[None, None, :]) + value_layer = value_layer + self.transpose_for_scores(self.v_bias[None, None, :]) + + rel_att = None + # Take the dot product between "query" and "key" to get the raw attention scores. + scale_factor = 1 + len(self.pos_att_type) + scale = math.sqrt(shape_list(query_layer)[-1] * scale_factor) + query_layer = query_layer / scale + + attention_scores = tf.matmul(query_layer, tf.transpose(key_layer, [0, 1, 3, 2])) + if self.relative_attention: + rel_embeddings = self.pos_dropout(rel_embeddings, training=training) + rel_att = self.disentangled_att_bias(query_layer, key_layer, relative_pos, rel_embeddings, scale_factor) + + if rel_att is not None: + attention_scores = attention_scores + rel_att + + if self.talking_head: + attention_scores = tf.transpose( + self.head_logits_proj(tf.transpose(attention_scores, [0, 2, 3, 1])), [0, 3, 1, 2] + ) + + attention_probs = self.softmax(attention_scores, attention_mask) + attention_probs = self.dropout(attention_probs, training=training) + if self.talking_head: + attention_probs = tf.transpose( + self.head_weights_proj(tf.transpose(attention_probs, [0, 2, 3, 1])), [0, 3, 1, 2] + ) + + context_layer = tf.matmul(attention_probs, value_layer) + context_layer = tf.transpose(context_layer, [0, 2, 1, 3]) + context_layer_shape = shape_list(context_layer) + # Set the final dimension here explicitly. + # Calling tf.reshape(context_layer, (*context_layer_shape[:-2], -1)) raises an error when executing + # the model in graph mode as context_layer is reshaped to (None, 7, None) and Dense layer in TFDebertaV2SelfOutput + # requires final input dimension to be defined + new_context_layer_shape = context_layer_shape[:-2] + [context_layer_shape[-2] * context_layer_shape[-1]] + context_layer = tf.reshape(context_layer, new_context_layer_shape) + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + return outputs + + def disentangled_att_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): + if relative_pos is None: + q = shape_list(query_layer)[-2] + relative_pos = build_relative_position(q, shape_list(key_layer)[-2]) + shape_list_pos = shape_list(relative_pos) + if len(shape_list_pos) == 2: + relative_pos = tf.expand_dims(tf.expand_dims(relative_pos, 0), 0) + elif len(shape_list_pos) == 3: + relative_pos = tf.expand_dims(relative_pos, 1) + # bxhxqxk + elif len(shape_list_pos) != 4: + raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {len(shape_list_pos)}") + + att_span = tf.cast( + tf.minimum( + tf.maximum(shape_list(query_layer)[-2], shape_list(key_layer)[-2]), self.max_relative_positions + ), + tf.int64, + ) + rel_embeddings = tf.expand_dims( + rel_embeddings[self.max_relative_positions - att_span : self.max_relative_positions + att_span, :], 0 + ) + + score = 0 + + # content->position + if "c2p" in self.pos_att_type: + pos_key_layer = self.pos_proj(rel_embeddings) + pos_key_layer = self.transpose_for_scores(pos_key_layer) + c2p_att = tf.matmul(query_layer, tf.transpose(pos_key_layer, [0, 1, 3, 2])) + c2p_pos = tf.clip_by_value(relative_pos + att_span, 0, att_span * 2 - 1) + c2p_att = torch_gather(c2p_att, c2p_dynamic_expand(c2p_pos, query_layer, relative_pos), -1) + score += c2p_att + + # position->content + if "p2c" in self.pos_att_type: + pos_query_layer = self.pos_q_proj(rel_embeddings) + pos_query_layer = self.transpose_for_scores(pos_query_layer) + pos_query_layer /= tf.math.sqrt(tf.cast(shape_list(pos_query_layer)[-1] * scale_factor, dtype=tf.float32)) + if shape_list(query_layer)[-2] != shape_list(key_layer)[-2]: + r_pos = build_relative_position(shape_list(key_layer)[-2], shape_list(key_layer)[-2]) + else: + r_pos = relative_pos + p2c_pos = tf.clip_by_value(-r_pos + att_span, 0, att_span * 2 - 1) + p2c_att = tf.matmul(key_layer, tf.transpose(pos_query_layer, [0, 1, 3, 2])) + p2c_att = tf.transpose( + torch_gather(p2c_att, p2c_dynamic_expand(p2c_pos, query_layer, key_layer), -1), [0, 1, 3, 2] + ) + if shape_list(query_layer)[-2] != shape_list(key_layer)[-2]: + pos_index = tf.expand_dims(relative_pos[:, :, :, 0], -1) + p2c_att = torch_gather(p2c_att, pos_dynamic_expand(pos_index, p2c_att, key_layer), -2) + score += p2c_att + + return score + + +class TFDebertaEmbeddings(tf.keras.layers.Layer): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.embedding_size = getattr(config, "embedding_size", config.hidden_size) + self.hidden_size = config.hidden_size + self.max_position_embeddings = config.max_position_embeddings + self.position_biased_input = getattr(config, "position_biased_input", True) + self.initializer_range = config.initializer_range + if self.embedding_size != config.hidden_size: + self.embed_proj = tf.keras.layers.Dense(config.hidden_size, use_bias=False) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaStableDropout(config.hidden_dropout_prob, name="dropout") + + def build(self, input_shape: tf.TensorShape): + with tf.name_scope("word_embeddings"): + self.weight = self.add_weight( + name="weight", + shape=[self.config.vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("token_type_embeddings"): + if self.config.type_vocab_size > 0: + self.token_type_embeddings = self.add_weight( + name="embeddings", + shape=[self.config.type_vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + else: + self.token_type_embeddings = None + + with tf.name_scope("position_embeddings"): + if self.position_biased_input: + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.hidden_size], + initializer=get_initializer(self.initializer_range), + ) + else: + self.position_embeddings = None + + super().build(input_shape) + + def call( + self, + input_ids: tf.Tensor = None, + position_ids: tf.Tensor = None, + token_type_ids: tf.Tensor = None, + inputs_embeds: tf.Tensor = None, + mask: tf.Tensor = None, + training: bool = False, + ) -> tf.Tensor: + """ + Applies embedding based on inputs tensor. + + Returns: + final_embeddings (`tf.Tensor`): output embedding tensor. + """ + if input_ids is None and inputs_embeds is None: + raise ValueError("Need to provide either `input_ids` or `input_embeds`.") + + if input_ids is not None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.config.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.config.vocab_size})" + ), + ) + inputs_embeds = tf.gather(params=self.weight, indices=input_ids) + + input_shape = shape_list(inputs_embeds)[:-1] + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + if position_ids is None: + position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) + + final_embeddings = inputs_embeds + if self.position_biased_input: + position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) + final_embeddings += position_embeds + if self.config.type_vocab_size > 0: + token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) + final_embeddings += token_type_embeds + + if self.embedding_size != self.hidden_size: + final_embeddings = self.embed_proj(final_embeddings) + + final_embeddings = self.LayerNorm(final_embeddings) + + if mask is not None: + if len(shape_list(mask)) != len(shape_list(final_embeddings)): + if len(shape_list(mask)) == 4: + mask = tf.squeeze(tf.squeeze(mask, axis=1), axis=1) + mask = tf.cast(tf.expand_dims(mask, axis=2), tf.float32) + + final_embeddings = final_embeddings * mask + + final_embeddings = self.dropout(final_embeddings, training=training) + + return final_embeddings + + +class TFDebertaPredictionHeadTransform(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + name="dense", + ) + + if isinstance(config.hidden_act, str): + self.transform_act_fn = get_tf_activation(config.hidden_act) + else: + self.transform_act_fn = config.hidden_act + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + + return hidden_states + + +class TFDebertaLMPredictionHead(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, input_embeddings: tf.keras.layers.Layer, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.hidden_size = config.hidden_size + + self.transform = TFDebertaPredictionHeadTransform(config, name="transform") + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.input_embeddings = input_embeddings + + def build(self, input_shape: tf.TensorShape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + + super().build(input_shape) + + def get_output_embeddings(self) -> tf.keras.layers.Layer: + return self.input_embeddings + + def set_output_embeddings(self, value: tf.Variable): + self.input_embeddings.weight = value + self.input_embeddings.vocab_size = shape_list(value)[0] + + def get_bias(self) -> Dict[str, tf.Variable]: + return {"bias": self.bias} + + def set_bias(self, value: tf.Variable): + self.bias = value["bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.transform(hidden_states=hidden_states) + seq_length = shape_list(hidden_states)[1] + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) + hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) + hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) + + return hidden_states + + +class TFDebertaOnlyMLMHead(tf.keras.layers.Layer): + def __init__(self, config: DebertaConfig, input_embeddings: tf.keras.layers.Layer, **kwargs): + super().__init__(**kwargs) + self.predictions = TFDebertaLMPredictionHead(config, input_embeddings, name="predictions") + + def call(self, sequence_output: tf.Tensor) -> tf.Tensor: + prediction_scores = self.predictions(hidden_states=sequence_output) + + return prediction_scores + + +# @keras_serializable +class TFDebertaMainLayer(tf.keras.layers.Layer): + config_class = DebertaConfig + + def __init__(self, config: DebertaConfig, **kwargs): + super().__init__(**kwargs) + + self.config = config + + self.embeddings = TFDebertaEmbeddings(config, name="embeddings") + self.encoder = TFDebertaEncoder(config, name="encoder") + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings + + def set_input_embeddings(self, value: tf.Variable): + self.embeddings.weight = value + self.embeddings.vocab_size = shape_list(value)[0] + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = tf.fill(dims=input_shape, value=1) + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + mask=attention_mask, + training=training, + ) + + encoder_outputs = self.encoder( + hidden_states=embedding_output, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + + if not return_dict: + return (sequence_output,) + encoder_outputs[1:] + + return TFBaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class TFDebertaPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DebertaConfig + base_model_prefix = "deberta" + + +DEBERTA_START_DOCSTRING = r""" + The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled + Attention](https://arxiv.org/abs/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build + on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two + improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`DebertaConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` ``Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert *input_ids* indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput``] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", + DEBERTA_START_DOCSTRING, +) +class TFDebertaModel(TFDebertaPreTrainedModel): + def __init__(self, config: DebertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.deberta = TFDebertaMainLayer(config, name="deberta") + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFBaseModelOutput) -> TFBaseModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutput(last_hidden_state=output.last_hidden_state, hidden_states=hs, attentions=attns) + + +@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) +class TFDebertaForMaskedLM(TFDebertaPreTrainedModel, TFMaskedLanguageModelingLoss): + def __init__(self, config: DebertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + if config.is_decoder: + logger.warning( + "If you want to use `TFDebertaForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.deberta = TFDebertaMainLayer(config, name="deberta") + self.mlm = TFDebertaOnlyMLMHead(config, input_embeddings=self.deberta.embeddings, name="cls") + + def get_lm_head(self) -> tf.keras.layers.Layer: + return self.mlm.predictions + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMaskedLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + prediction_scores = self.mlm(sequence_output=sequence_output, training=training) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFMaskedLMOutput( + loss=loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedLMOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DEBERTA_START_DOCSTRING, +) +class TFDebertaForSequenceClassification(TFDebertaPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config: DebertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaMainLayer(config, name="deberta") + self.pooler = TFDebertaContextPooler(config, name="pooler") + + drop_out = getattr(config, "cls_dropout", None) + drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out + self.dropout = TFDebertaStableDropout(drop_out, name="cls_dropout") + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, + kernel_initializer=get_initializer(config.initializer_range), + name="classifier", + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + pooled_output = self.pooler(sequence_output, training=training) + pooled_output = self.dropout(pooled_output, training=training) + logits = self.classifier(pooled_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[1:] + + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + DEBERTA_START_DOCSTRING, +) +class TFDebertaForTokenClassification(TFDebertaPreTrainedModel, TFTokenClassificationLoss): + def __init__(self, config: DebertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaMainLayer(config, name="deberta") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + sequence_output = self.dropout(sequence_output, training=training) + logits = self.classifier(inputs=sequence_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DEBERTA_START_DOCSTRING, +) +class TFDebertaForQuestionAnswering(TFDebertaPreTrainedModel, TFQuestionAnsweringLoss): + def __init__(self, config: DebertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaMainLayer(config, name="deberta") + self.qa_outputs = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + logits = self.qa_outputs(inputs=sequence_output) + start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) + start_logits = tf.squeeze(input=start_logits, axis=-1) + end_logits = tf.squeeze(input=end_logits, axis=-1) + loss = None + + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..8a778a947cfbca7c17e1ed8809cc8827e95c3c53 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta.py @@ -0,0 +1,444 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization class for model DeBERTa.""" + +import json +import os +from typing import TYPE_CHECKING, List, Optional, Tuple + +import regex as re + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import logging + + +if TYPE_CHECKING: + from transformers.pipelines.conversational import Conversation + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "microsoft/deberta-base": "https://huggingface.co/microsoft/deberta-base/resolve/main/vocab.json", + "microsoft/deberta-large": "https://huggingface.co/microsoft/deberta-large/resolve/main/vocab.json", + "microsoft/deberta-xlarge": "https://huggingface.co/microsoft/deberta-xlarge/resolve/main/vocab.json", + "microsoft/deberta-base-mnli": "https://huggingface.co/microsoft/deberta-base-mnli/resolve/main/vocab.json", + "microsoft/deberta-large-mnli": "https://huggingface.co/microsoft/deberta-large-mnli/resolve/main/vocab.json", + "microsoft/deberta-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-xlarge-mnli/resolve/main/vocab.json" + ), + }, + "merges_file": { + "microsoft/deberta-base": "https://huggingface.co/microsoft/deberta-base/resolve/main/merges.txt", + "microsoft/deberta-large": "https://huggingface.co/microsoft/deberta-large/resolve/main/merges.txt", + "microsoft/deberta-xlarge": "https://huggingface.co/microsoft/deberta-xlarge/resolve/main/merges.txt", + "microsoft/deberta-base-mnli": "https://huggingface.co/microsoft/deberta-base-mnli/resolve/main/merges.txt", + "microsoft/deberta-large-mnli": "https://huggingface.co/microsoft/deberta-large-mnli/resolve/main/merges.txt", + "microsoft/deberta-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-xlarge-mnli/resolve/main/merges.txt" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "microsoft/deberta-base": 512, + "microsoft/deberta-large": 512, + "microsoft/deberta-xlarge": 512, + "microsoft/deberta-base-mnli": 512, + "microsoft/deberta-large-mnli": 512, + "microsoft/deberta-xlarge-mnli": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "microsoft/deberta-base": {"do_lower_case": False}, + "microsoft/deberta-large": {"do_lower_case": False}, +} + + +# Copied from transformers.models.gpt2.tokenization_gpt2.bytes_to_unicode +def bytes_to_unicode(): + """ + Returns list of utf-8 byte and a mapping to unicode strings. We specifically avoids mapping to whitespace/control + characters the bpe code barfs on. + + The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab + if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for + decent coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup + tables between utf-8 bytes and unicode strings. + """ + bs = ( + list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1)) + ) + cs = bs[:] + n = 0 + for b in range(2**8): + if b not in bs: + bs.append(b) + cs.append(2**8 + n) + n += 1 + cs = [chr(n) for n in cs] + return dict(zip(bs, cs)) + + +# Copied from transformers.models.gpt2.tokenization_gpt2.get_pairs +def get_pairs(word): + """ + Return set of symbol pairs in a word. + + Word is represented as tuple of symbols (symbols being variable-length strings). + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +class DebertaTokenizer(PreTrainedTokenizer): + """ + Construct a DeBERTa tokenizer. Based on byte-level Byte-Pair-Encoding. + + This tokenizer has been trained to treat spaces like parts of the tokens (a bit like sentencepiece) so a word will + be encoded differently whether it is at the beginning of the sentence (without space) or not: + + ```python + >>> from transformers import DebertaTokenizer + + >>> tokenizer = DebertaTokenizer.from_pretrained("microsoft/deberta-base") + >>> tokenizer("Hello world")["input_ids"] + [1, 31414, 232, 2] + + >>> tokenizer(" Hello world")["input_ids"] + [1, 20920, 232, 2] + ``` + + You can get around that behavior by passing `add_prefix_space=True` when instantiating this tokenizer or when you + call it on some text, but since the model was not pretrained this way, it might yield a decrease in performance. + + + + When used with `is_split_into_words=True`, this tokenizer will add a space before each word (even the first one). + + + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + merges_file (`str`): + Path to the merges file. + errors (`str`, *optional*, defaults to `"replace"`): + Paradigm to follow when decoding bytes to UTF-8. See + [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information. + bos_token (`str`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token. + eos_token (`str`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + add_prefix_space (`bool`, *optional*, defaults to `False`): + Whether or not to add an initial space to the input. This allows to treat the leading word just as any + other word. (Deberta tokenizer detect beginning of words by the preceding space). + add_bos_token (`bool`, *optional*, defaults to `False`): + Whether or not to add an initial <|endoftext|> to the input. This allows to treat the leading word just as + any other word. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask", "token_type_ids"] + + def __init__( + self, + vocab_file, + merges_file, + errors="replace", + bos_token="[CLS]", + eos_token="[SEP]", + sep_token="[SEP]", + cls_token="[CLS]", + unk_token="[UNK]", + pad_token="[PAD]", + mask_token="[MASK]", + add_prefix_space=False, + add_bos_token=False, + **kwargs, + ): + bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token + eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token + sep_token = AddedToken(sep_token, lstrip=False, rstrip=False) if isinstance(sep_token, str) else sep_token + cls_token = AddedToken(cls_token, lstrip=False, rstrip=False) if isinstance(cls_token, str) else cls_token + unk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_token + pad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_token + + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + super().__init__( + errors=errors, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + mask_token=mask_token, + add_prefix_space=add_prefix_space, + add_bos_token=add_bos_token, + **kwargs, + ) + self.add_bos_token = add_bos_token + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + self.decoder = {v: k for k, v in self.encoder.items()} + self.errors = errors # how to handle errors in decoding + self.byte_encoder = bytes_to_unicode() + self.byte_decoder = {v: k for k, v in self.byte_encoder.items()} + with open(merges_file, encoding="utf-8") as merges_handle: + bpe_merges = merges_handle.read().split("\n")[1:-1] + bpe_merges = [tuple(merge.split()) for merge in bpe_merges] + self.bpe_ranks = dict(zip(bpe_merges, range(len(bpe_merges)))) + self.cache = {} + self.add_prefix_space = add_prefix_space + + # Should have added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions + self.pat = re.compile(r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+""") + + @property + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.vocab_size + def vocab_size(self): + return len(self.encoder) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.get_vocab + def get_vocab(self): + return dict(self.encoder, **self.added_tokens_encoder) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.bpe + def bpe(self, token): + if token in self.cache: + return self.cache[token] + word = tuple(token) + pairs = get_pairs(word) + + if not pairs: + return token + + while True: + bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf"))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + except ValueError: + new_word.extend(word[i:]) + break + else: + new_word.extend(word[i:j]) + i = j + + if word[i] == first and i < len(word) - 1 and word[i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = " ".join(word) + self.cache[token] = word + return word + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A DeBERTa sequence has the following format: + + - single sequence: [CLS] X [SEP] + - pair of sequences: [CLS] A [SEP] B [SEP] + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieves sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` or `encode_plus` methods. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return [1] + ([0] * len(token_ids_0)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A DeBERTa + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._tokenize + def _tokenize(self, text): + """Tokenize a string.""" + bpe_tokens = [] + for token in re.findall(self.pat, text): + token = "".join( + self.byte_encoder[b] for b in token.encode("utf-8") + ) # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case) + bpe_tokens.extend(bpe_token for bpe_token in self.bpe(token).split(" ")) + return bpe_tokens + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_token_to_id + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_id_to_token + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.decoder.get(index) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.convert_tokens_to_string + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + text = "".join(tokens) + text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors) + return text + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.save_vocabulary + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + merge_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + index = 0 + with open(merge_file, "w", encoding="utf-8") as writer: + writer.write("#version: 0.2\n") + for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]): + if index != token_index: + logger.warning( + f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive." + " Please check that the tokenizer is not corrupted!" + ) + index = token_index + writer.write(" ".join(bpe_tokens) + "\n") + index += 1 + + return vocab_file, merge_file + + def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): + add_prefix_space = kwargs.pop("add_prefix_space", self.add_prefix_space) + if (is_split_into_words or add_prefix_space) and (len(text) > 0 and not text[0].isspace()): + text = " " + text + return (text, kwargs) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._build_conversation_input_ids + def _build_conversation_input_ids(self, conversation: "Conversation") -> List[int]: + input_ids = [] + for is_user, text in conversation.iter_texts(): + input_ids.extend(self.encode(text, add_special_tokens=False) + [self.eos_token_id]) + if len(input_ids) > self.model_max_length: + input_ids = input_ids[-self.model_max_length :] + return input_ids diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..c05cf257611ebf7c5c14886a5a9c6b1455ab062a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta/tokenization_deberta_fast.py @@ -0,0 +1,301 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Fast Tokenization class for model DeBERTa.""" + +import json +from typing import TYPE_CHECKING, List, Optional, Tuple + +from tokenizers import pre_tokenizers + +from ...tokenization_utils_base import AddedToken, BatchEncoding +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging +from .tokenization_deberta import DebertaTokenizer + + +if TYPE_CHECKING: + from transformers.pipelines.conversational import Conversation + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "microsoft/deberta-base": "https://huggingface.co/microsoft/deberta-base/resolve/main/vocab.json", + "microsoft/deberta-large": "https://huggingface.co/microsoft/deberta-large/resolve/main/vocab.json", + "microsoft/deberta-xlarge": "https://huggingface.co/microsoft/deberta-xlarge/resolve/main/vocab.json", + "microsoft/deberta-base-mnli": "https://huggingface.co/microsoft/deberta-base-mnli/resolve/main/vocab.json", + "microsoft/deberta-large-mnli": "https://huggingface.co/microsoft/deberta-large-mnli/resolve/main/vocab.json", + "microsoft/deberta-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-xlarge-mnli/resolve/main/vocab.json" + ), + }, + "merges_file": { + "microsoft/deberta-base": "https://huggingface.co/microsoft/deberta-base/resolve/main/merges.txt", + "microsoft/deberta-large": "https://huggingface.co/microsoft/deberta-large/resolve/main/merges.txt", + "microsoft/deberta-xlarge": "https://huggingface.co/microsoft/deberta-xlarge/resolve/main/merges.txt", + "microsoft/deberta-base-mnli": "https://huggingface.co/microsoft/deberta-base-mnli/resolve/main/merges.txt", + "microsoft/deberta-large-mnli": "https://huggingface.co/microsoft/deberta-large-mnli/resolve/main/merges.txt", + "microsoft/deberta-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-xlarge-mnli/resolve/main/merges.txt" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "microsoft/deberta-base": 512, + "microsoft/deberta-large": 512, + "microsoft/deberta-xlarge": 512, + "microsoft/deberta-base-mnli": 512, + "microsoft/deberta-large-mnli": 512, + "microsoft/deberta-xlarge-mnli": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "microsoft/deberta-base": {"do_lower_case": False}, + "microsoft/deberta-large": {"do_lower_case": False}, +} + + +class DebertaTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" DeBERTa tokenizer (backed by HuggingFace's *tokenizers* library). Based on byte-level + Byte-Pair-Encoding. + + This tokenizer has been trained to treat spaces like parts of the tokens (a bit like sentencepiece) so a word will + be encoded differently whether it is at the beginning of the sentence (without space) or not: + + ```python + >>> from transformers import DebertaTokenizerFast + + >>> tokenizer = DebertaTokenizerFast.from_pretrained("microsoft/deberta-base") + >>> tokenizer("Hello world")["input_ids"] + [1, 31414, 232, 2] + + >>> tokenizer(" Hello world")["input_ids"] + [1, 20920, 232, 2] + ``` + + You can get around that behavior by passing `add_prefix_space=True` when instantiating this tokenizer, but since + the model was not pretrained this way, it might yield a decrease in performance. + + + + When used with `is_split_into_words=True`, this tokenizer needs to be instantiated with `add_prefix_space=True`. + + + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + merges_file (`str`): + Path to the merges file. + tokenizer_file (`str`, *optional*): + The path to a tokenizer file to use instead of the vocab file. + errors (`str`, *optional*, defaults to `"replace"`): + Paradigm to follow when decoding bytes to UTF-8. See + [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information. + bos_token (`str`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token. + eos_token (`str`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + add_prefix_space (`bool`, *optional*, defaults to `False`): + Whether or not to add an initial space to the input. This allows to treat the leading word just as any + other word. (Deberta tokenizer detect beginning of words by the preceding space). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask", "token_type_ids"] + slow_tokenizer_class = DebertaTokenizer + + def __init__( + self, + vocab_file=None, + merges_file=None, + tokenizer_file=None, + errors="replace", + bos_token="[CLS]", + eos_token="[SEP]", + sep_token="[SEP]", + cls_token="[CLS]", + unk_token="[UNK]", + pad_token="[PAD]", + mask_token="[MASK]", + add_prefix_space=False, + **kwargs, + ): + super().__init__( + vocab_file, + merges_file, + tokenizer_file=tokenizer_file, + errors=errors, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + mask_token=mask_token, + add_prefix_space=add_prefix_space, + **kwargs, + ) + self.add_bos_token = kwargs.pop("add_bos_token", False) + + pre_tok_state = json.loads(self.backend_tokenizer.pre_tokenizer.__getstate__()) + if pre_tok_state.get("add_prefix_space", add_prefix_space) != add_prefix_space: + pre_tok_class = getattr(pre_tokenizers, pre_tok_state.pop("type")) + pre_tok_state["add_prefix_space"] = add_prefix_space + self.backend_tokenizer.pre_tokenizer = pre_tok_class(**pre_tok_state) + + self.add_prefix_space = add_prefix_space + + @property + def mask_token(self) -> str: + """ + `str`: Mask token, to use when training a model with masked-language modeling. Log an error if used while not + having been set. + + Deberta tokenizer has a special mask token to be used in the fill-mask pipeline. The mask token will greedily + comprise the space before the *[MASK]*. + """ + if self._mask_token is None: + if self.verbose: + logger.error("Using mask_token, but it is not set yet.") + return None + return str(self._mask_token) + + @mask_token.setter + def mask_token(self, value): + """ + Overriding the default behavior of the mask token to have it eat the space before it. + """ + # Mask token behave like a normal word, i.e. include the space before it + # So we set lstrip to True + value = AddedToken(value, lstrip=True, rstrip=False) if isinstance(value, str) else value + self._mask_token = value + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A DeBERTa sequence has the following format: + + - single sequence: [CLS] X [SEP] + - pair of sequences: [CLS] A [SEP] B [SEP] + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + token_ids_1 + sep + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A DeBERTa + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast._batch_encode_plus + def _batch_encode_plus(self, *args, **kwargs) -> BatchEncoding: + is_split_into_words = kwargs.get("is_split_into_words", False) + assert self.add_prefix_space or not is_split_into_words, ( + f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True " + "to use it with pretokenized inputs." + ) + + return super()._batch_encode_plus(*args, **kwargs) + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast._encode_plus + def _encode_plus(self, *args, **kwargs) -> BatchEncoding: + is_split_into_words = kwargs.get("is_split_into_words", False) + + assert self.add_prefix_space or not is_split_into_words, ( + f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True " + "to use it with pretokenized inputs." + ) + + return super()._encode_plus(*args, **kwargs) + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast.save_vocabulary + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + files = self._tokenizer.model.save(save_directory, name=filename_prefix) + return tuple(files) + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast._build_conversation_input_ids + def _build_conversation_input_ids(self, conversation: "Conversation") -> List[int]: + """This corresponds to DialoGPT variants of models.""" + input_ids = [] + for is_user, text in conversation.iter_texts(): + input_ids.extend(self.encode(text, add_special_tokens=False) + [self.eos_token_id]) + + if len(input_ids) > self.model_max_length: + input_ids = input_ids[-self.model_max_length :] + return input_ids diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2c5bf57572536b2f72fd27d1e8931d83bd901bb6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/__init__.py @@ -0,0 +1,125 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_deberta_v2": ["DEBERTA_V2_PRETRAINED_CONFIG_ARCHIVE_MAP", "DebertaV2Config", "DebertaV2OnnxConfig"], + "tokenization_deberta_v2": ["DebertaV2Tokenizer"], +} + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_deberta_v2_fast"] = ["DebertaV2TokenizerFast"] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_deberta_v2"] = [ + "TF_DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFDebertaV2ForMaskedLM", + "TFDebertaV2ForQuestionAnswering", + "TFDebertaV2ForSequenceClassification", + "TFDebertaV2ForTokenClassification", + "TFDebertaV2Model", + "TFDebertaV2PreTrainedModel", + ] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_deberta_v2"] = [ + "DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST", + "DebertaV2ForMaskedLM", + "DebertaV2ForMultipleChoice", + "DebertaV2ForQuestionAnswering", + "DebertaV2ForSequenceClassification", + "DebertaV2ForTokenClassification", + "DebertaV2Model", + "DebertaV2PreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_deberta_v2 import ( + DEBERTA_V2_PRETRAINED_CONFIG_ARCHIVE_MAP, + DebertaV2Config, + DebertaV2OnnxConfig, + ) + from .tokenization_deberta_v2 import DebertaV2Tokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_deberta_v2_fast import DebertaV2TokenizerFast + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_deberta_v2 import ( + TF_DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST, + TFDebertaV2ForMaskedLM, + TFDebertaV2ForQuestionAnswering, + TFDebertaV2ForSequenceClassification, + TFDebertaV2ForTokenClassification, + TFDebertaV2Model, + TFDebertaV2PreTrainedModel, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_deberta_v2 import ( + DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST, + DebertaV2ForMaskedLM, + DebertaV2ForMultipleChoice, + DebertaV2ForQuestionAnswering, + DebertaV2ForSequenceClassification, + DebertaV2ForTokenClassification, + DebertaV2Model, + DebertaV2PreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/configuration_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/configuration_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..d55486cd5633814492d61607494b547680904ed8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/configuration_deberta_v2.py @@ -0,0 +1,199 @@ +# coding=utf-8 +# Copyright 2020, Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DeBERTa-v2 model configuration""" +from collections import OrderedDict +from typing import TYPE_CHECKING, Any, Mapping, Optional, Union + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +if TYPE_CHECKING: + from ... import FeatureExtractionMixin, PreTrainedTokenizerBase, TensorType + + +logger = logging.get_logger(__name__) + +DEBERTA_V2_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "microsoft/deberta-v2-xlarge": "https://huggingface.co/microsoft/deberta-v2-xlarge/resolve/main/config.json", + "microsoft/deberta-v2-xxlarge": "https://huggingface.co/microsoft/deberta-v2-xxlarge/resolve/main/config.json", + "microsoft/deberta-v2-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xlarge-mnli/resolve/main/config.json" + ), + "microsoft/deberta-v2-xxlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xxlarge-mnli/resolve/main/config.json" + ), +} + + +class DebertaV2Config(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DebertaV2Model`]. It is used to instantiate a + DeBERTa-v2 model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the DeBERTa + [microsoft/deberta-v2-xlarge](https://huggingface.co/microsoft/deberta-v2-xlarge) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Arguments: + vocab_size (`int`, *optional*, defaults to 128100): + Vocabulary size of the DeBERTa-v2 model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`DebertaV2Model`]. + hidden_size (`int`, *optional*, defaults to 1536): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 24): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 6144): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"`, `"gelu"`, `"tanh"`, `"gelu_fast"`, `"mish"`, `"linear"`, `"sigmoid"` and `"gelu_new"` + are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 0): + The vocabulary size of the `token_type_ids` passed when calling [`DebertaModel`] or [`TFDebertaModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-7): + The epsilon used by the layer normalization layers. + relative_attention (`bool`, *optional*, defaults to `True`): + Whether use relative position encoding. + max_relative_positions (`int`, *optional*, defaults to -1): + The range of relative positions `[-max_position_embeddings, max_position_embeddings]`. Use the same value + as `max_position_embeddings`. + pad_token_id (`int`, *optional*, defaults to 0): + The value used to pad input_ids. + position_biased_input (`bool`, *optional*, defaults to `False`): + Whether add absolute position embedding to content embedding. + pos_att_type (`List[str]`, *optional*): + The type of relative position attention, it can be a combination of `["p2c", "c2p"]`, e.g. `["p2c"]`, + `["p2c", "c2p"]`, `["p2c", "c2p"]`. + layer_norm_eps (`float`, optional, defaults to 1e-12): + The epsilon used by the layer normalization layers. + + Example: + + ```python + >>> from transformers import DebertaV2Config, DebertaV2Model + + >>> # Initializing a DeBERTa-v2 microsoft/deberta-v2-xlarge style configuration + >>> configuration = DebertaV2Config() + + >>> # Initializing a model (with random weights) from the microsoft/deberta-v2-xlarge style configuration + >>> model = DebertaV2Model(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "deberta-v2" + + def __init__( + self, + vocab_size=128100, + hidden_size=1536, + num_hidden_layers=24, + num_attention_heads=24, + intermediate_size=6144, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=0, + initializer_range=0.02, + layer_norm_eps=1e-7, + relative_attention=False, + max_relative_positions=-1, + pad_token_id=0, + position_biased_input=True, + pos_att_type=None, + pooler_dropout=0, + pooler_hidden_act="gelu", + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.relative_attention = relative_attention + self.max_relative_positions = max_relative_positions + self.pad_token_id = pad_token_id + self.position_biased_input = position_biased_input + + # Backwards compatibility + if type(pos_att_type) == str: + pos_att_type = [x.strip() for x in pos_att_type.lower().split("|")] + + self.pos_att_type = pos_att_type + self.vocab_size = vocab_size + self.layer_norm_eps = layer_norm_eps + + self.pooler_hidden_size = kwargs.get("pooler_hidden_size", hidden_size) + self.pooler_dropout = pooler_dropout + self.pooler_hidden_act = pooler_hidden_act + + +class DebertaV2OnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + if self._config.type_vocab_size > 0: + return OrderedDict( + [("input_ids", dynamic_axis), ("attention_mask", dynamic_axis), ("token_type_ids", dynamic_axis)] + ) + else: + return OrderedDict([("input_ids", dynamic_axis), ("attention_mask", dynamic_axis)]) + + @property + def default_onnx_opset(self) -> int: + return 12 + + def generate_dummy_inputs( + self, + preprocessor: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin"], + batch_size: int = -1, + seq_length: int = -1, + num_choices: int = -1, + is_pair: bool = False, + framework: Optional["TensorType"] = None, + num_channels: int = 3, + image_width: int = 40, + image_height: int = 40, + tokenizer: "PreTrainedTokenizerBase" = None, + ) -> Mapping[str, Any]: + dummy_inputs = super().generate_dummy_inputs(preprocessor=preprocessor, framework=framework) + if self._config.type_vocab_size == 0 and "token_type_ids" in dummy_inputs: + del dummy_inputs["token_type_ids"] + return dummy_inputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..cd6e6318e3d426aeed6fa5e8595dcfc7a07b90a5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_deberta_v2.py @@ -0,0 +1,1648 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the Hugging Face Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DeBERTa-v2 model.""" + +from collections.abc import Sequence +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, LayerNorm, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import softmax_backward_data +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_deberta_v2 import DebertaV2Config + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DebertaV2Config" +_CHECKPOINT_FOR_DOC = "microsoft/deberta-v2-xlarge" +_QA_TARGET_START_INDEX = 2 +_QA_TARGET_END_INDEX = 9 + +DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "microsoft/deberta-v2-xlarge", + "microsoft/deberta-v2-xxlarge", + "microsoft/deberta-v2-xlarge-mnli", + "microsoft/deberta-v2-xxlarge-mnli", +] + + +# Copied from transformers.models.deberta.modeling_deberta.ContextPooler +class ContextPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.pooler_hidden_size, config.pooler_hidden_size) + self.dropout = StableDropout(config.pooler_dropout) + self.config = config + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + + context_token = hidden_states[:, 0] + context_token = self.dropout(context_token) + pooled_output = self.dense(context_token) + pooled_output = ACT2FN[self.config.pooler_hidden_act](pooled_output) + return pooled_output + + @property + def output_dim(self): + return self.config.hidden_size + + +# Copied from transformers.models.deberta.modeling_deberta.XSoftmax with deberta->deberta_v2 +class XSoftmax(torch.autograd.Function): + """ + Masked Softmax which is optimized for saving memory + + Args: + input (`torch.tensor`): The input tensor that will apply softmax. + mask (`torch.IntTensor`): + The mask matrix where 0 indicate that element will be ignored in the softmax calculation. + dim (int): The dimension that will apply softmax + + Example: + + ```python + >>> import torch + >>> from transformers.models.deberta_v2.modeling_deberta_v2 import XSoftmax + + >>> # Make a tensor + >>> x = torch.randn([4, 20, 100]) + + >>> # Create a mask + >>> mask = (x > 0).int() + + >>> # Specify the dimension to apply softmax + >>> dim = -1 + + >>> y = XSoftmax.apply(x, mask, dim) + ```""" + + @staticmethod + def forward(self, input, mask, dim): + self.dim = dim + rmask = ~(mask.to(torch.bool)) + + output = input.masked_fill(rmask, torch.tensor(torch.finfo(input.dtype).min)) + output = torch.softmax(output, self.dim) + output.masked_fill_(rmask, 0) + self.save_for_backward(output) + return output + + @staticmethod + def backward(self, grad_output): + (output,) = self.saved_tensors + inputGrad = softmax_backward_data(self, grad_output, output, self.dim, output) + return inputGrad, None, None + + @staticmethod + def symbolic(g, self, mask, dim): + import torch.onnx.symbolic_helper as sym_help + from torch.onnx.symbolic_opset9 import masked_fill, softmax + + mask_cast_value = g.op("Cast", mask, to_i=sym_help.cast_pytorch_to_onnx["Long"]) + r_mask = g.op( + "Cast", + g.op("Sub", g.op("Constant", value_t=torch.tensor(1, dtype=torch.int64)), mask_cast_value), + to_i=sym_help.cast_pytorch_to_onnx["Byte"], + ) + output = masked_fill( + g, self, r_mask, g.op("Constant", value_t=torch.tensor(torch.finfo(self.type().dtype()).min)) + ) + output = softmax(g, output, dim) + return masked_fill(g, output, r_mask, g.op("Constant", value_t=torch.tensor(0, dtype=torch.bool))) + + +# Copied from transformers.models.deberta.modeling_deberta.DropoutContext +class DropoutContext(object): + def __init__(self): + self.dropout = 0 + self.mask = None + self.scale = 1 + self.reuse_mask = True + + +# Copied from transformers.models.deberta.modeling_deberta.get_mask +def get_mask(input, local_context): + if not isinstance(local_context, DropoutContext): + dropout = local_context + mask = None + else: + dropout = local_context.dropout + dropout *= local_context.scale + mask = local_context.mask if local_context.reuse_mask else None + + if dropout > 0 and mask is None: + mask = (1 - torch.empty_like(input).bernoulli_(1 - dropout)).to(torch.bool) + + if isinstance(local_context, DropoutContext): + if local_context.mask is None: + local_context.mask = mask + + return mask, dropout + + +# Copied from transformers.models.deberta.modeling_deberta.XDropout +class XDropout(torch.autograd.Function): + """Optimized dropout function to save computation and memory by using mask operation instead of multiplication.""" + + @staticmethod + def forward(ctx, input, local_ctx): + mask, dropout = get_mask(input, local_ctx) + ctx.scale = 1.0 / (1 - dropout) + if dropout > 0: + ctx.save_for_backward(mask) + return input.masked_fill(mask, 0) * ctx.scale + else: + return input + + @staticmethod + def backward(ctx, grad_output): + if ctx.scale > 1: + (mask,) = ctx.saved_tensors + return grad_output.masked_fill(mask, 0) * ctx.scale, None + else: + return grad_output, None + + @staticmethod + def symbolic(g: torch._C.Graph, input: torch._C.Value, local_ctx: Union[float, DropoutContext]) -> torch._C.Value: + from torch.onnx import symbolic_opset12 + + dropout_p = local_ctx + if isinstance(local_ctx, DropoutContext): + dropout_p = local_ctx.dropout + # StableDropout only calls this function when training. + train = True + # TODO: We should check if the opset_version being used to export + # is > 12 here, but there's no good way to do that. As-is, if the + # opset_version < 12, export will fail with a CheckerError. + # Once https://github.com/pytorch/pytorch/issues/78391 is fixed, do something like: + # if opset_version < 12: + # return torch.onnx.symbolic_opset9.dropout(g, input, dropout_p, train) + return symbolic_opset12.dropout(g, input, dropout_p, train) + + +# Copied from transformers.models.deberta.modeling_deberta.StableDropout +class StableDropout(nn.Module): + """ + Optimized dropout module for stabilizing the training + + Args: + drop_prob (float): the dropout probabilities + """ + + def __init__(self, drop_prob): + super().__init__() + self.drop_prob = drop_prob + self.count = 0 + self.context_stack = None + + def forward(self, x): + """ + Call the module + + Args: + x (`torch.tensor`): The input tensor to apply dropout + """ + if self.training and self.drop_prob > 0: + return XDropout.apply(x, self.get_context()) + return x + + def clear_context(self): + self.count = 0 + self.context_stack = None + + def init_context(self, reuse_mask=True, scale=1): + if self.context_stack is None: + self.context_stack = [] + self.count = 0 + for c in self.context_stack: + c.reuse_mask = reuse_mask + c.scale = scale + + def get_context(self): + if self.context_stack is not None: + if self.count >= len(self.context_stack): + self.context_stack.append(DropoutContext()) + ctx = self.context_stack[self.count] + ctx.dropout = self.drop_prob + self.count += 1 + return ctx + else: + return self.drop_prob + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaSelfOutput with DebertaLayerNorm->LayerNorm +class DebertaV2SelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaAttention with Deberta->DebertaV2 +class DebertaV2Attention(nn.Module): + def __init__(self, config): + super().__init__() + self.self = DisentangledSelfAttention(config) + self.output = DebertaV2SelfOutput(config) + self.config = config + + def forward( + self, + hidden_states, + attention_mask, + output_attentions=False, + query_states=None, + relative_pos=None, + rel_embeddings=None, + ): + self_output = self.self( + hidden_states, + attention_mask, + output_attentions, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + ) + if output_attentions: + self_output, att_matrix = self_output + if query_states is None: + query_states = hidden_states + attention_output = self.output(self_output, query_states) + + if output_attentions: + return (attention_output, att_matrix) + else: + return attention_output + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->DebertaV2 +class DebertaV2Intermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaOutput with DebertaLayerNorm->LayerNorm +class DebertaV2Output(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + self.config = config + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaLayer with Deberta->DebertaV2 +class DebertaV2Layer(nn.Module): + def __init__(self, config): + super().__init__() + self.attention = DebertaV2Attention(config) + self.intermediate = DebertaV2Intermediate(config) + self.output = DebertaV2Output(config) + + def forward( + self, + hidden_states, + attention_mask, + query_states=None, + relative_pos=None, + rel_embeddings=None, + output_attentions=False, + ): + attention_output = self.attention( + hidden_states, + attention_mask, + output_attentions=output_attentions, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + ) + if output_attentions: + attention_output, att_matrix = attention_output + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + if output_attentions: + return (layer_output, att_matrix) + else: + return layer_output + + +class ConvLayer(nn.Module): + def __init__(self, config): + super().__init__() + kernel_size = getattr(config, "conv_kernel_size", 3) + groups = getattr(config, "conv_groups", 1) + self.conv_act = getattr(config, "conv_act", "tanh") + self.conv = nn.Conv1d( + config.hidden_size, config.hidden_size, kernel_size, padding=(kernel_size - 1) // 2, groups=groups + ) + self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + self.config = config + + def forward(self, hidden_states, residual_states, input_mask): + out = self.conv(hidden_states.permute(0, 2, 1).contiguous()).permute(0, 2, 1).contiguous() + rmask = (1 - input_mask).bool() + out.masked_fill_(rmask.unsqueeze(-1).expand(out.size()), 0) + out = ACT2FN[self.conv_act](self.dropout(out)) + + layer_norm_input = residual_states + out + output = self.LayerNorm(layer_norm_input).to(layer_norm_input) + + if input_mask is None: + output_states = output + else: + if input_mask.dim() != layer_norm_input.dim(): + if input_mask.dim() == 4: + input_mask = input_mask.squeeze(1).squeeze(1) + input_mask = input_mask.unsqueeze(2) + + input_mask = input_mask.to(output.dtype) + output_states = output * input_mask + + return output_states + + +class DebertaV2Encoder(nn.Module): + """Modified BertEncoder with relative position bias support""" + + def __init__(self, config): + super().__init__() + + self.layer = nn.ModuleList([DebertaV2Layer(config) for _ in range(config.num_hidden_layers)]) + self.relative_attention = getattr(config, "relative_attention", False) + + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + + self.position_buckets = getattr(config, "position_buckets", -1) + pos_ebd_size = self.max_relative_positions * 2 + + if self.position_buckets > 0: + pos_ebd_size = self.position_buckets * 2 + + self.rel_embeddings = nn.Embedding(pos_ebd_size, config.hidden_size) + + self.norm_rel_ebd = [x.strip() for x in getattr(config, "norm_rel_ebd", "none").lower().split("|")] + + if "layer_norm" in self.norm_rel_ebd: + self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps, elementwise_affine=True) + + self.conv = ConvLayer(config) if getattr(config, "conv_kernel_size", 0) > 0 else None + self.gradient_checkpointing = False + + def get_rel_embedding(self): + rel_embeddings = self.rel_embeddings.weight if self.relative_attention else None + if rel_embeddings is not None and ("layer_norm" in self.norm_rel_ebd): + rel_embeddings = self.LayerNorm(rel_embeddings) + return rel_embeddings + + def get_attention_mask(self, attention_mask): + if attention_mask.dim() <= 2: + extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2) + attention_mask = extended_attention_mask * extended_attention_mask.squeeze(-2).unsqueeze(-1) + attention_mask = attention_mask.byte() + elif attention_mask.dim() == 3: + attention_mask = attention_mask.unsqueeze(1) + + return attention_mask + + def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): + if self.relative_attention and relative_pos is None: + q = query_states.size(-2) if query_states is not None else hidden_states.size(-2) + relative_pos = build_relative_position( + q, + hidden_states.size(-2), + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + device=hidden_states.device, + ) + return relative_pos + + def forward( + self, + hidden_states, + attention_mask, + output_hidden_states=True, + output_attentions=False, + query_states=None, + relative_pos=None, + return_dict=True, + ): + if attention_mask.dim() <= 2: + input_mask = attention_mask + else: + input_mask = (attention_mask.sum(-2) > 0).byte() + attention_mask = self.get_attention_mask(attention_mask) + relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) + + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[0] + else: + next_kv = hidden_states + rel_embeddings = self.get_rel_embedding() + output_states = next_kv + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (output_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + output_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + next_kv, + attention_mask, + query_states, + relative_pos, + rel_embeddings, + ) + else: + output_states = layer_module( + next_kv, + attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + ) + + if output_attentions: + output_states, att_m = output_states + + if i == 0 and self.conv is not None: + output_states = self.conv(hidden_states, output_states, input_mask) + + if query_states is not None: + query_states = output_states + if isinstance(hidden_states, Sequence): + next_kv = hidden_states[i + 1] if i + 1 < len(self.layer) else None + else: + next_kv = output_states + + if output_attentions: + all_attentions = all_attentions + (att_m,) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (output_states,) + + if not return_dict: + return tuple(v for v in [output_states, all_hidden_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=output_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +def make_log_bucket_position(relative_pos, bucket_size, max_position): + sign = torch.sign(relative_pos) + mid = bucket_size // 2 + abs_pos = torch.where( + (relative_pos < mid) & (relative_pos > -mid), + torch.tensor(mid - 1).type_as(relative_pos), + torch.abs(relative_pos), + ) + log_pos = ( + torch.ceil(torch.log(abs_pos / mid) / torch.log(torch.tensor((max_position - 1) / mid)) * (mid - 1)) + mid + ) + bucket_pos = torch.where(abs_pos <= mid, relative_pos.type_as(log_pos), log_pos * sign) + return bucket_pos + + +def build_relative_position(query_size, key_size, bucket_size=-1, max_position=-1, device=None): + """ + Build relative position according to the query and key + + We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key + \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - + P_k\\) + + Args: + query_size (int): the length of query + key_size (int): the length of key + bucket_size (int): the size of position bucket + max_position (int): the maximum allowed absolute position + device (`torch.device`): the device on which tensors will be created. + + Return: + `torch.LongTensor`: A tensor with shape [1, query_size, key_size] + """ + + q_ids = torch.arange(0, query_size, device=device) + k_ids = torch.arange(0, key_size, device=device) + rel_pos_ids = q_ids[:, None] - k_ids[None, :] + if bucket_size > 0 and max_position > 0: + rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position) + rel_pos_ids = rel_pos_ids.to(torch.long) + rel_pos_ids = rel_pos_ids[:query_size, :] + rel_pos_ids = rel_pos_ids.unsqueeze(0) + return rel_pos_ids + + +@torch.jit.script +# Copied from transformers.models.deberta.modeling_deberta.c2p_dynamic_expand +def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): + return c2p_pos.expand([query_layer.size(0), query_layer.size(1), query_layer.size(2), relative_pos.size(-1)]) + + +@torch.jit.script +# Copied from transformers.models.deberta.modeling_deberta.p2c_dynamic_expand +def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): + return c2p_pos.expand([query_layer.size(0), query_layer.size(1), key_layer.size(-2), key_layer.size(-2)]) + + +@torch.jit.script +# Copied from transformers.models.deberta.modeling_deberta.pos_dynamic_expand +def pos_dynamic_expand(pos_index, p2c_att, key_layer): + return pos_index.expand(p2c_att.size()[:2] + (pos_index.size(-2), key_layer.size(-2))) + + +class DisentangledSelfAttention(nn.Module): + """ + Disentangled self-attention module + + Parameters: + config (`DebertaV2Config`): + A model config class instance with the configuration to build a new model. The schema is similar to + *BertConfig*, for more details, please refer [`DebertaV2Config`] + + """ + + def __init__(self, config): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.num_attention_heads = config.num_attention_heads + _attention_head_size = config.hidden_size // config.num_attention_heads + self.attention_head_size = getattr(config, "attention_head_size", _attention_head_size) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.query_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True) + self.key_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True) + self.value_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True) + + self.share_att_key = getattr(config, "share_att_key", False) + self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] + self.relative_attention = getattr(config, "relative_attention", False) + + if self.relative_attention: + self.position_buckets = getattr(config, "position_buckets", -1) + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + self.pos_ebd_size = self.max_relative_positions + if self.position_buckets > 0: + self.pos_ebd_size = self.position_buckets + + self.pos_dropout = StableDropout(config.hidden_dropout_prob) + + if not self.share_att_key: + if "c2p" in self.pos_att_type: + self.pos_key_proj = nn.Linear(config.hidden_size, self.all_head_size, bias=True) + if "p2c" in self.pos_att_type: + self.pos_query_proj = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = StableDropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x, attention_heads): + new_x_shape = x.size()[:-1] + (attention_heads, -1) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3).contiguous().view(-1, x.size(1), x.size(-1)) + + def forward( + self, + hidden_states, + attention_mask, + output_attentions=False, + query_states=None, + relative_pos=None, + rel_embeddings=None, + ): + """ + Call the module + + Args: + hidden_states (`torch.FloatTensor`): + Input states to the module usually the output from previous layer, it will be the Q,K and V in + *Attention(Q,K,V)* + + attention_mask (`torch.ByteTensor`): + An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum + sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* + th token. + + output_attentions (`bool`, optional): + Whether return the attention matrix. + + query_states (`torch.FloatTensor`, optional): + The *Q* state in *Attention(Q,K,V)*. + + relative_pos (`torch.LongTensor`): + The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with + values ranging in [*-max_relative_positions*, *max_relative_positions*]. + + rel_embeddings (`torch.FloatTensor`): + The embedding of relative distances. It's a tensor of shape [\\(2 \\times + \\text{max_relative_positions}\\), *hidden_size*]. + + + """ + if query_states is None: + query_states = hidden_states + query_layer = self.transpose_for_scores(self.query_proj(query_states), self.num_attention_heads) + key_layer = self.transpose_for_scores(self.key_proj(hidden_states), self.num_attention_heads) + value_layer = self.transpose_for_scores(self.value_proj(hidden_states), self.num_attention_heads) + + rel_att = None + # Take the dot product between "query" and "key" to get the raw attention scores. + scale_factor = 1 + if "c2p" in self.pos_att_type: + scale_factor += 1 + if "p2c" in self.pos_att_type: + scale_factor += 1 + scale = torch.sqrt(torch.tensor(query_layer.size(-1), dtype=torch.float) * scale_factor) + attention_scores = torch.bmm(query_layer, key_layer.transpose(-1, -2)) / scale.to(dtype=query_layer.dtype) + if self.relative_attention: + rel_embeddings = self.pos_dropout(rel_embeddings) + rel_att = self.disentangled_attention_bias( + query_layer, key_layer, relative_pos, rel_embeddings, scale_factor + ) + + if rel_att is not None: + attention_scores = attention_scores + rel_att + attention_scores = attention_scores + attention_scores = attention_scores.view( + -1, self.num_attention_heads, attention_scores.size(-2), attention_scores.size(-1) + ) + + # bsz x height x length x dimension + attention_probs = XSoftmax.apply(attention_scores, attention_mask, -1) + attention_probs = self.dropout(attention_probs) + context_layer = torch.bmm( + attention_probs.view(-1, attention_probs.size(-2), attention_probs.size(-1)), value_layer + ) + context_layer = ( + context_layer.view(-1, self.num_attention_heads, context_layer.size(-2), context_layer.size(-1)) + .permute(0, 2, 1, 3) + .contiguous() + ) + new_context_layer_shape = context_layer.size()[:-2] + (-1,) + context_layer = context_layer.view(new_context_layer_shape) + if output_attentions: + return (context_layer, attention_probs) + else: + return context_layer + + def disentangled_attention_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): + if relative_pos is None: + q = query_layer.size(-2) + relative_pos = build_relative_position( + q, + key_layer.size(-2), + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + device=query_layer.device, + ) + if relative_pos.dim() == 2: + relative_pos = relative_pos.unsqueeze(0).unsqueeze(0) + elif relative_pos.dim() == 3: + relative_pos = relative_pos.unsqueeze(1) + # bsz x height x query x key + elif relative_pos.dim() != 4: + raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {relative_pos.dim()}") + + att_span = self.pos_ebd_size + relative_pos = relative_pos.long().to(query_layer.device) + + rel_embeddings = rel_embeddings[0 : att_span * 2, :].unsqueeze(0) + if self.share_att_key: + pos_query_layer = self.transpose_for_scores( + self.query_proj(rel_embeddings), self.num_attention_heads + ).repeat(query_layer.size(0) // self.num_attention_heads, 1, 1) + pos_key_layer = self.transpose_for_scores(self.key_proj(rel_embeddings), self.num_attention_heads).repeat( + query_layer.size(0) // self.num_attention_heads, 1, 1 + ) + else: + if "c2p" in self.pos_att_type: + pos_key_layer = self.transpose_for_scores( + self.pos_key_proj(rel_embeddings), self.num_attention_heads + ).repeat( + query_layer.size(0) // self.num_attention_heads, 1, 1 + ) # .split(self.all_head_size, dim=-1) + if "p2c" in self.pos_att_type: + pos_query_layer = self.transpose_for_scores( + self.pos_query_proj(rel_embeddings), self.num_attention_heads + ).repeat( + query_layer.size(0) // self.num_attention_heads, 1, 1 + ) # .split(self.all_head_size, dim=-1) + + score = 0 + # content->position + if "c2p" in self.pos_att_type: + scale = torch.sqrt(torch.tensor(pos_key_layer.size(-1), dtype=torch.float) * scale_factor) + c2p_att = torch.bmm(query_layer, pos_key_layer.transpose(-1, -2)) + c2p_pos = torch.clamp(relative_pos + att_span, 0, att_span * 2 - 1) + c2p_att = torch.gather( + c2p_att, + dim=-1, + index=c2p_pos.squeeze(0).expand([query_layer.size(0), query_layer.size(1), relative_pos.size(-1)]), + ) + score += c2p_att / scale.to(dtype=c2p_att.dtype) + + # position->content + if "p2c" in self.pos_att_type: + scale = torch.sqrt(torch.tensor(pos_query_layer.size(-1), dtype=torch.float) * scale_factor) + if key_layer.size(-2) != query_layer.size(-2): + r_pos = build_relative_position( + key_layer.size(-2), + key_layer.size(-2), + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + device=query_layer.device, + ) + r_pos = r_pos.unsqueeze(0) + else: + r_pos = relative_pos + + p2c_pos = torch.clamp(-r_pos + att_span, 0, att_span * 2 - 1) + p2c_att = torch.bmm(key_layer, pos_query_layer.transpose(-1, -2)) + p2c_att = torch.gather( + p2c_att, + dim=-1, + index=p2c_pos.squeeze(0).expand([query_layer.size(0), key_layer.size(-2), key_layer.size(-2)]), + ).transpose(-1, -2) + score += p2c_att / scale.to(dtype=p2c_att.dtype) + + return score + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaEmbeddings with DebertaLayerNorm->LayerNorm +class DebertaV2Embeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + pad_token_id = getattr(config, "pad_token_id", 0) + self.embedding_size = getattr(config, "embedding_size", config.hidden_size) + self.word_embeddings = nn.Embedding(config.vocab_size, self.embedding_size, padding_idx=pad_token_id) + + self.position_biased_input = getattr(config, "position_biased_input", True) + if not self.position_biased_input: + self.position_embeddings = None + else: + self.position_embeddings = nn.Embedding(config.max_position_embeddings, self.embedding_size) + + if config.type_vocab_size > 0: + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, self.embedding_size) + + if self.embedding_size != config.hidden_size: + self.embed_proj = nn.Linear(self.embedding_size, config.hidden_size, bias=False) + self.LayerNorm = LayerNorm(config.hidden_size, config.layer_norm_eps) + self.dropout = StableDropout(config.hidden_dropout_prob) + self.config = config + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + + def forward(self, input_ids=None, token_type_ids=None, position_ids=None, mask=None, inputs_embeds=None): + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, :seq_length] + + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + + if self.position_embeddings is not None: + position_embeddings = self.position_embeddings(position_ids.long()) + else: + position_embeddings = torch.zeros_like(inputs_embeds) + + embeddings = inputs_embeds + if self.position_biased_input: + embeddings += position_embeddings + if self.config.type_vocab_size > 0: + token_type_embeddings = self.token_type_embeddings(token_type_ids) + embeddings += token_type_embeddings + + if self.embedding_size != self.config.hidden_size: + embeddings = self.embed_proj(embeddings) + + embeddings = self.LayerNorm(embeddings) + + if mask is not None: + if mask.dim() != embeddings.dim(): + if mask.dim() == 4: + mask = mask.squeeze(1).squeeze(1) + mask = mask.unsqueeze(2) + mask = mask.to(embeddings.dtype) + + embeddings = embeddings * mask + + embeddings = self.dropout(embeddings) + return embeddings + + +# Copied from transformers.models.deberta.modeling_deberta.DebertaPreTrainedModel with Deberta->DebertaV2 +class DebertaV2PreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DebertaV2Config + base_model_prefix = "deberta" + _keys_to_ignore_on_load_missing = ["position_ids"] + _keys_to_ignore_on_load_unexpected = ["position_embeddings"] + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DebertaV2Encoder): + module.gradient_checkpointing = value + + +DEBERTA_START_DOCSTRING = r""" + The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled + Attention](https://arxiv.org/abs/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build + on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two + improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + + Parameters: + config ([`DebertaV2Config`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert *input_ids* indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_deberta.DebertaModel with Deberta->DebertaV2 +class DebertaV2Model(DebertaV2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.embeddings = DebertaV2Embeddings(config) + self.encoder = DebertaV2Encoder(config) + self.z_steps = 0 + self.config = config + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, new_embeddings): + self.embeddings.word_embeddings = new_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError("The prune function is not implemented in DeBERTa model.") + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + embedding_output = self.embeddings( + input_ids=input_ids, + token_type_ids=token_type_ids, + position_ids=position_ids, + mask=attention_mask, + inputs_embeds=inputs_embeds, + ) + + encoder_outputs = self.encoder( + embedding_output, + attention_mask, + output_hidden_states=True, + output_attentions=output_attentions, + return_dict=return_dict, + ) + encoded_layers = encoder_outputs[1] + + if self.z_steps > 1: + hidden_states = encoded_layers[-2] + layers = [self.encoder.layer[-1] for _ in range(self.z_steps)] + query_states = encoded_layers[-1] + rel_embeddings = self.encoder.get_rel_embedding() + attention_mask = self.encoder.get_attention_mask(attention_mask) + rel_pos = self.encoder.get_rel_pos(embedding_output) + for layer in layers[1:]: + query_states = layer( + hidden_states, + attention_mask, + output_attentions=False, + query_states=query_states, + relative_pos=rel_pos, + rel_embeddings=rel_embeddings, + ) + encoded_layers.append(query_states) + + sequence_output = encoded_layers[-1] + + if not return_dict: + return (sequence_output,) + encoder_outputs[(1 if output_hidden_states else 2) :] + + return BaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states if output_hidden_states else None, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) +class DebertaV2ForMaskedLM(DebertaV2PreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"predictions.decoder.bias", "cls.predictions.decoder.weight"] + + def __init__(self, config): + super().__init__(config) + + self.deberta = DebertaV2Model(config) + self.cls = DebertaV2OnlyMLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.cls.predictions.decoder + + def set_output_embeddings(self, new_embeddings): + self.cls.predictions.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="[MASK]", + ) + # Copied from transformers.models.deberta.modeling_deberta.DebertaForMaskedLM.forward with Deberta->DebertaV2 + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.cls(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() # -100 index = padding token + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[1:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# copied from transformers.models.bert.BertPredictionHeadTransform with bert -> deberta +class DebertaV2PredictionHeadTransform(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + if isinstance(config.hidden_act, str): + self.transform_act_fn = ACT2FN[config.hidden_act] + else: + self.transform_act_fn = config.hidden_act + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + return hidden_states + + +# copied from transformers.models.bert.BertLMPredictionHead with bert -> deberta +class DebertaV2LMPredictionHead(nn.Module): + def __init__(self, config): + super().__init__() + self.transform = DebertaV2PredictionHeadTransform(config) + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + + # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, hidden_states): + hidden_states = self.transform(hidden_states) + hidden_states = self.decoder(hidden_states) + return hidden_states + + +# copied from transformers.models.bert.BertOnlyMLMHead with bert -> deberta +class DebertaV2OnlyMLMHead(nn.Module): + def __init__(self, config): + super().__init__() + self.predictions = DebertaV2LMPredictionHead(config) + + def forward(self, sequence_output): + prediction_scores = self.predictions(sequence_output) + return prediction_scores + + +@add_start_docstrings( + """ + DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DEBERTA_START_DOCSTRING, +) +class DebertaV2ForSequenceClassification(DebertaV2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + num_labels = getattr(config, "num_labels", 2) + self.num_labels = num_labels + + self.deberta = DebertaV2Model(config) + self.pooler = ContextPooler(config) + output_dim = self.pooler.output_dim + + self.classifier = nn.Linear(output_dim, num_labels) + drop_out = getattr(config, "cls_dropout", None) + drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out + self.dropout = StableDropout(drop_out) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.deberta.get_input_embeddings() + + def set_input_embeddings(self, new_embeddings): + self.deberta.set_input_embeddings(new_embeddings) + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + # Copied from transformers.models.deberta.modeling_deberta.DebertaForSequenceClassification.forward with Deberta->DebertaV2 + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + token_type_ids=token_type_ids, + attention_mask=attention_mask, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + encoder_layer = outputs[0] + pooled_output = self.pooler(encoder_layer) + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + # regression task + loss_fn = nn.MSELoss() + logits = logits.view(-1).to(labels.dtype) + loss = loss_fn(logits, labels.view(-1)) + elif labels.dim() == 1 or labels.size(-1) == 1: + label_index = (labels >= 0).nonzero() + labels = labels.long() + if label_index.size(0) > 0: + labeled_logits = torch.gather( + logits, 0, label_index.expand(label_index.size(0), logits.size(1)) + ) + labels = torch.gather(labels, 0, label_index.view(-1)) + loss_fct = CrossEntropyLoss() + loss = loss_fct(labeled_logits.view(-1, self.num_labels).float(), labels.view(-1)) + else: + loss = torch.tensor(0).to(logits) + else: + log_softmax = nn.LogSoftmax(-1) + loss = -((log_softmax(logits) * labels).sum(-1)).mean() + elif self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_deberta.DebertaForTokenClassification with Deberta->DebertaV2 +class DebertaV2ForTokenClassification(DebertaV2PreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.deberta = DebertaV2Model(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DEBERTA_START_DOCSTRING, +) +class DebertaV2ForQuestionAnswering(DebertaV2PreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.deberta = DebertaV2Model(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + qa_target_start_index=_QA_TARGET_START_INDEX, + qa_target_end_index=_QA_TARGET_END_INDEX, + ) + # Copied from transformers.models.deberta.modeling_deberta.DebertaForQuestionAnswering.forward with Deberta->DebertaV2 + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + DeBERTa Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + DEBERTA_START_DOCSTRING, +) +class DebertaV2ForMultipleChoice(DebertaV2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + num_labels = getattr(config, "num_labels", 2) + self.num_labels = num_labels + + self.deberta = DebertaV2Model(config) + self.pooler = ContextPooler(config) + output_dim = self.pooler.output_dim + + self.classifier = nn.Linear(output_dim, 1) + drop_out = getattr(config, "cls_dropout", None) + drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out + self.dropout = StableDropout(drop_out) + + self.init_weights() + + def get_input_embeddings(self): + return self.deberta.get_input_embeddings() + + def set_input_embeddings(self, new_embeddings): + self.deberta.set_input_embeddings(new_embeddings) + + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.deberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + inputs_embeds=flat_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + encoder_layer = outputs[0] + pooled_output = self.pooler(encoder_layer) + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..015eb392574087dca17a1477dd1795f5e018c8df --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/modeling_tf_deberta_v2.py @@ -0,0 +1,1563 @@ +# coding=utf-8 +# Copyright 2021 Microsoft and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 DeBERTa-v2 model.""" + + +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFMaskedLMOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFMaskedLanguageModelingLoss, + TFModelInputType, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFTokenClassificationLoss, + get_initializer, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_deberta_v2 import DebertaV2Config + + +logger = logging.get_logger(__name__) + + +_CONFIG_FOR_DOC = "DebertaV2Config" +_CHECKPOINT_FOR_DOC = "kamalkraj/deberta-v2-xlarge" + +TF_DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "kamalkraj/deberta-v2-xlarge", + # See all DeBERTa models at https://huggingface.co/models?filter=deberta-v2 +] + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaContextPooler with Deberta->DebertaV2 +class TFDebertaV2ContextPooler(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + self.dense = tf.keras.layers.Dense(config.pooler_hidden_size, name="dense") + self.dropout = TFDebertaV2StableDropout(config.pooler_dropout, name="dropout") + self.config = config + + def call(self, hidden_states, training: bool = False): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + context_token = hidden_states[:, 0] + context_token = self.dropout(context_token, training=training) + pooled_output = self.dense(context_token) + pooled_output = get_tf_activation(self.config.pooler_hidden_act)(pooled_output) + return pooled_output + + @property + def output_dim(self) -> int: + return self.config.hidden_size + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaXSoftmax with Deberta->DebertaV2 +class TFDebertaV2XSoftmax(tf.keras.layers.Layer): + """ + Masked Softmax which is optimized for saving memory + + Args: + input (`tf.Tensor`): The input tensor that will apply softmax. + mask (`tf.Tensor`): The mask matrix where 0 indicate that element will be ignored in the softmax calculation. + dim (int): The dimension that will apply softmax + """ + + def __init__(self, axis=-1, **kwargs): + super().__init__(**kwargs) + self.axis = axis + + def call(self, inputs: tf.Tensor, mask: tf.Tensor): + rmask = tf.logical_not(tf.cast(mask, tf.bool)) + output = tf.where(rmask, float("-inf"), inputs) + output = stable_softmax(output, self.axis) + output = tf.where(rmask, 0.0, output) + return output + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaStableDropout with Deberta->DebertaV2 +class TFDebertaV2StableDropout(tf.keras.layers.Layer): + """ + Optimized dropout module for stabilizing the training + + Args: + drop_prob (float): the dropout probabilities + """ + + def __init__(self, drop_prob, **kwargs): + super().__init__(**kwargs) + self.drop_prob = drop_prob + + @tf.custom_gradient + def xdropout(self, inputs): + """ + Applies dropout to the inputs, as vanilla dropout, but also scales the remaining elements up by 1/drop_prob. + """ + mask = tf.cast( + 1 + - tf.compat.v1.distributions.Bernoulli(probs=1.0 - self.drop_prob).sample(sample_shape=shape_list(inputs)), + tf.bool, + ) + scale = tf.convert_to_tensor(1.0 / (1 - self.drop_prob), dtype=tf.float32) + if self.drop_prob > 0: + inputs = tf.where(mask, 0.0, inputs) * scale + + def grad(upstream): + if self.drop_prob > 0: + return tf.where(mask, 0.0, upstream) * scale + else: + return upstream + + return inputs, grad + + def call(self, inputs: tf.Tensor, training: tf.Tensor = False): + if training: + return self.xdropout(inputs) + return inputs + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaSelfOutput with Deberta->DebertaV2 +class TFDebertaV2SelfOutput(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + self.dense = tf.keras.layers.Dense(config.hidden_size, name="dense") + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") + + def call(self, hidden_states, input_tensor, training: bool = False): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaAttention with Deberta->DebertaV2 +class TFDebertaV2Attention(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + self.self = TFDebertaV2DisentangledSelfAttention(config, name="self") + self.dense_output = TFDebertaV2SelfOutput(config, name="output") + self.config = config + + def call( + self, + input_tensor: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self( + hidden_states=input_tensor, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + if query_states is None: + query_states = input_tensor + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=query_states, training=training + ) + + output = (attention_output,) + self_outputs[1:] + + return output + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaIntermediate with Deberta->DebertaV2 +class TFDebertaV2Intermediate(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaOutput with Deberta->DebertaV2 +class TFDebertaV2Output(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + + return hidden_states + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaLayer with Deberta->DebertaV2 +class TFDebertaV2Layer(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.attention = TFDebertaV2Attention(config, name="attention") + self.intermediate = TFDebertaV2Intermediate(config, name="intermediate") + self.bert_output = TFDebertaV2Output(config, name="output") + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + input_tensor=hidden_states, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + attention_output = attention_outputs[0] + intermediate_output = self.intermediate(hidden_states=attention_output) + layer_output = self.bert_output( + hidden_states=intermediate_output, input_tensor=attention_output, training=training + ) + outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them + + return outputs + + +class TFDebertaV2ConvLayer(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.kernel_size = getattr(config, "conv_kernel_size", 3) + # groups = getattr(config, "conv_groups", 1) + self.conv_act = get_tf_activation(getattr(config, "conv_act", "tanh")) + self.padding = (self.kernel_size - 1) // 2 + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") + self.config = config + + def build(self, input_shape): + with tf.name_scope("conv"): + self.conv_kernel = self.add_weight( + name="kernel", + shape=[self.kernel_size, self.config.hidden_size, self.config.hidden_size], + initializer=get_initializer(self.config.initializer_range), + ) + self.conv_bias = self.add_weight( + name="bias", shape=[self.config.hidden_size], initializer=tf.zeros_initializer() + ) + return super().build(input_shape) + + def call( + self, hidden_states: tf.Tensor, residual_states: tf.Tensor, input_mask: tf.Tensor, training: bool = False + ) -> tf.Tensor: + out = tf.nn.conv2d( + tf.expand_dims(hidden_states, 1), + tf.expand_dims(self.conv_kernel, 0), + strides=1, + padding=[[0, 0], [0, 0], [self.padding, self.padding], [0, 0]], + ) + out = tf.squeeze(tf.nn.bias_add(out, self.conv_bias), 1) + rmask = tf.cast(1 - input_mask, tf.bool) + out = tf.where(tf.broadcast_to(tf.expand_dims(rmask, -1), shape_list(out)), 0.0, out) + out = self.dropout(out, training=training) + out = self.conv_act(out) + + layer_norm_input = residual_states + out + output = self.LayerNorm(layer_norm_input) + + if input_mask is None: + output_states = output + else: + if len(shape_list(input_mask)) != len(shape_list(layer_norm_input)): + if len(shape_list(input_mask)) == 4: + input_mask = tf.squeeze(tf.squeeze(input_mask, axis=1), axis=1) + input_mask = tf.cast(tf.expand_dims(input_mask, axis=2), tf.float32) + + output_states = output * input_mask + + return output_states + + +class TFDebertaV2Encoder(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.layer = [TFDebertaV2Layer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + self.relative_attention = getattr(config, "relative_attention", False) + self.config = config + if self.relative_attention: + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + + self.position_buckets = getattr(config, "position_buckets", -1) + self.pos_ebd_size = self.max_relative_positions * 2 + + if self.position_buckets > 0: + self.pos_ebd_size = self.position_buckets * 2 + + self.norm_rel_ebd = [x.strip() for x in getattr(config, "norm_rel_ebd", "none").lower().split("|")] + + if "layer_norm" in self.norm_rel_ebd: + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + + self.conv = TFDebertaV2ConvLayer(config, name="conv") if getattr(config, "conv_kernel_size", 0) > 0 else None + + def build(self, input_shape): + if self.relative_attention: + self.rel_embeddings = self.add_weight( + name="rel_embeddings.weight", + shape=[self.pos_ebd_size, self.config.hidden_size], + initializer=get_initializer(self.config.initializer_range), + ) + return super().build(input_shape) + + def get_rel_embedding(self): + rel_embeddings = self.rel_embeddings if self.relative_attention else None + if rel_embeddings is not None and ("layer_norm" in self.norm_rel_ebd): + rel_embeddings = self.LayerNorm(rel_embeddings) + return rel_embeddings + + def get_attention_mask(self, attention_mask): + if len(shape_list(attention_mask)) <= 2: + extended_attention_mask = tf.expand_dims(tf.expand_dims(attention_mask, 1), 2) + attention_mask = extended_attention_mask * tf.expand_dims(tf.squeeze(extended_attention_mask, -2), -1) + attention_mask = tf.cast(attention_mask, tf.uint8) + elif len(shape_list(attention_mask)) == 3: + attention_mask = tf.expand_dims(attention_mask, 1) + + return attention_mask + + def get_rel_pos(self, hidden_states, query_states=None, relative_pos=None): + if self.relative_attention and relative_pos is None: + q = shape_list(query_states)[-2] if query_states is not None else shape_list(hidden_states)[-2] + relative_pos = build_relative_position( + q, + shape_list(hidden_states)[-2], + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + ) + return relative_pos + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + if len(shape_list(attention_mask)) <= 2: + input_mask = attention_mask + else: + input_mask = tf.cast(tf.math.reduce_sum(attention_mask, axis=-2) > 0, dtype=tf.uint8) + + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + attention_mask = self.get_attention_mask(attention_mask) + relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos) + + next_kv = hidden_states + + rel_embeddings = self.get_rel_embedding() + output_states = next_kv + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (output_states,) + + layer_outputs = layer_module( + hidden_states=next_kv, + attention_mask=attention_mask, + query_states=query_states, + relative_pos=relative_pos, + rel_embeddings=rel_embeddings, + output_attentions=output_attentions, + training=training, + ) + output_states = layer_outputs[0] + + if i == 0 and self.conv is not None: + output_states = self.conv(hidden_states, output_states, input_mask) + + next_kv = output_states + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (output_states,) + + if not return_dict: + return tuple(v for v in [output_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=output_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +def make_log_bucket_position(relative_pos, bucket_size, max_position): + sign = tf.math.sign(relative_pos) + mid = bucket_size // 2 + abs_pos = tf.where((relative_pos < mid) & (relative_pos > -mid), mid - 1, tf.math.abs(relative_pos)) + log_pos = ( + tf.math.ceil( + tf.cast(tf.math.log(abs_pos / mid), tf.float32) / tf.math.log((max_position - 1) / mid) * (mid - 1) + ) + + mid + ) + bucket_pos = tf.cast( + tf.where(abs_pos <= mid, tf.cast(relative_pos, tf.float32), log_pos * tf.cast(sign, tf.float32)), tf.int32 + ) + return bucket_pos + + +def build_relative_position(query_size, key_size, bucket_size=-1, max_position=-1): + """ + Build relative position according to the query and key + + We assume the absolute position of query \\(P_q\\) is range from (0, query_size) and the absolute position of key + \\(P_k\\) is range from (0, key_size), The relative positions from query to key is \\(R_{q \\rightarrow k} = P_q - + P_k\\) + + Args: + query_size (int): the length of query + key_size (int): the length of key + bucket_size (int): the size of position bucket + max_position (int): the maximum allowed absolute position + + Return: + `tf.Tensor`: A tensor with shape [1, query_size, key_size] + + """ + q_ids = tf.range(query_size, dtype=tf.int32) + k_ids = tf.range(key_size, dtype=tf.int32) + rel_pos_ids = q_ids[:, None] - tf.tile(tf.expand_dims(k_ids, axis=0), [shape_list(q_ids)[0], 1]) + if bucket_size > 0 and max_position > 0: + rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position) + rel_pos_ids = rel_pos_ids[:query_size, :] + rel_pos_ids = tf.expand_dims(rel_pos_ids, axis=0) + return tf.cast(rel_pos_ids, tf.int64) + + +def c2p_dynamic_expand(c2p_pos, query_layer, relative_pos): + shapes = [ + shape_list(query_layer)[0], + shape_list(query_layer)[1], + shape_list(query_layer)[2], + shape_list(relative_pos)[-1], + ] + return tf.broadcast_to(c2p_pos, shapes) + + +def p2c_dynamic_expand(c2p_pos, query_layer, key_layer): + shapes = [ + shape_list(query_layer)[0], + shape_list(query_layer)[1], + shape_list(key_layer)[-2], + shape_list(key_layer)[-2], + ] + return tf.broadcast_to(c2p_pos, shapes) + + +def pos_dynamic_expand(pos_index, p2c_att, key_layer): + shapes = shape_list(p2c_att)[:2] + [shape_list(pos_index)[-2], shape_list(key_layer)[-2]] + return tf.broadcast_to(pos_index, shapes) + + +def take_along_axis(x, indices): + # Only a valid port of np.take_along_axis when the gather axis is -1 + + # TPU + gathers and reshapes don't go along well -- see https://github.com/huggingface/transformers/issues/18239 + if isinstance(tf.distribute.get_strategy(), tf.distribute.TPUStrategy): + # [B, S, P] -> [B, S, P, D] + one_hot_indices = tf.one_hot(indices, depth=x.shape[-1], dtype=x.dtype) + + # if we ignore the first two dims, this is equivalent to multiplying a matrix (one hot) by a vector (x) + # grossly abusing notation: [B, S, P, D] . [B, S, D] = [B, S, P] + gathered = tf.einsum("ijkl,ijl->ijk", one_hot_indices, x) + + # GPUs, on the other hand, prefer gathers instead of large one-hot+matmuls + else: + gathered = tf.gather(x, indices, batch_dims=2) + + return gathered + + +class TFDebertaV2DisentangledSelfAttention(tf.keras.layers.Layer): + """ + Disentangled self-attention module + + Parameters: + config (`DebertaV2Config`): + A model config class instance with the configuration to build a new model. The schema is similar to + *BertConfig*, for more details, please refer [`DebertaV2Config`] + + """ + + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + self.num_attention_heads = config.num_attention_heads + _attention_head_size = config.hidden_size // config.num_attention_heads + self.attention_head_size = getattr(config, "attention_head_size", _attention_head_size) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.query_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="query_proj", + use_bias=True, + ) + self.key_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="key_proj", + use_bias=True, + ) + self.value_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="value_proj", + use_bias=True, + ) + + self.share_att_key = getattr(config, "share_att_key", False) + self.pos_att_type = config.pos_att_type if config.pos_att_type is not None else [] + self.relative_attention = getattr(config, "relative_attention", False) + + if self.relative_attention: + self.position_buckets = getattr(config, "position_buckets", -1) + self.max_relative_positions = getattr(config, "max_relative_positions", -1) + if self.max_relative_positions < 1: + self.max_relative_positions = config.max_position_embeddings + self.pos_ebd_size = self.max_relative_positions + if self.position_buckets > 0: + self.pos_ebd_size = self.position_buckets + + self.pos_dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="pos_dropout") + + if not self.share_att_key: + if "c2p" in self.pos_att_type: + self.pos_key_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="pos_proj", + use_bias=True, + ) + if "p2c" in self.pos_att_type: + self.pos_query_proj = tf.keras.layers.Dense( + self.all_head_size, + kernel_initializer=get_initializer(config.initializer_range), + name="pos_q_proj", + ) + self.softmax = TFDebertaV2XSoftmax(axis=-1) + self.dropout = TFDebertaV2StableDropout(config.attention_probs_dropout_prob, name="dropout") + + def transpose_for_scores(self, tensor: tf.Tensor, attention_heads: int) -> tf.Tensor: + tensor_shape = shape_list(tensor) + # In graph mode mode, we can't reshape with -1 as the final dimension if the first dimension (batch size) is None + shape = tensor_shape[:-1] + [attention_heads, tensor_shape[-1] // attention_heads] + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=shape) + tensor = tf.transpose(tensor, perm=[0, 2, 1, 3]) + x_shape = shape_list(tensor) + tensor = tf.reshape(tensor, shape=[-1, x_shape[-2], x_shape[-1]]) + return tensor + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + query_states: tf.Tensor = None, + relative_pos: tf.Tensor = None, + rel_embeddings: tf.Tensor = None, + output_attentions: bool = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + """ + Call the module + + Args: + hidden_states (`tf.Tensor`): + Input states to the module usually the output from previous layer, it will be the Q,K and V in + *Attention(Q,K,V)* + + attention_mask (`tf.Tensor`): + An attention mask matrix of shape [*B*, *N*, *N*] where *B* is the batch size, *N* is the maximum + sequence length in which element [i,j] = *1* means the *i* th token in the input can attend to the *j* + th token. + + return_att (`bool`, optional): + Whether return the attention matrix. + + query_states (`tf.Tensor`, optional): + The *Q* state in *Attention(Q,K,V)*. + + relative_pos (`tf.Tensor`): + The relative position encoding between the tokens in the sequence. It's of shape [*B*, *N*, *N*] with + values ranging in [*-max_relative_positions*, *max_relative_positions*]. + + rel_embeddings (`tf.Tensor`): + The embedding of relative distances. It's a tensor of shape [\\(2 \\times + \\text{max_relative_positions}\\), *hidden_size*]. + + + """ + if query_states is None: + query_states = hidden_states + query_layer = self.transpose_for_scores(self.query_proj(query_states), self.num_attention_heads) + key_layer = self.transpose_for_scores(self.key_proj(hidden_states), self.num_attention_heads) + value_layer = self.transpose_for_scores(self.value_proj(hidden_states), self.num_attention_heads) + + rel_att = None + # Take the dot product between "query" and "key" to get the raw attention scores. + scale_factor = 1 + if "c2p" in self.pos_att_type: + scale_factor += 1 + if "p2c" in self.pos_att_type: + scale_factor += 1 + scale = tf.math.sqrt(tf.cast(shape_list(query_layer)[-1] * scale_factor, tf.float32)) + attention_scores = tf.matmul(query_layer, tf.transpose(key_layer, [0, 2, 1])) / scale + if self.relative_attention: + rel_embeddings = self.pos_dropout(rel_embeddings) + rel_att = self.disentangled_att_bias(query_layer, key_layer, relative_pos, rel_embeddings, scale_factor) + + if rel_att is not None: + attention_scores = attention_scores + rel_att + attention_scores = tf.reshape( + attention_scores, + (-1, self.num_attention_heads, shape_list(attention_scores)[-2], shape_list(attention_scores)[-1]), + ) + + # bsz x height x length x dimension + attention_probs = self.softmax(attention_scores, attention_mask) + attention_probs = self.dropout(attention_probs, training=training) + context_layer = tf.matmul( + tf.reshape(attention_probs, [-1, shape_list(attention_probs)[-2], shape_list(attention_probs)[-1]]), + value_layer, + ) + context_layer = tf.transpose( + tf.reshape( + context_layer, + [-1, self.num_attention_heads, shape_list(context_layer)[-2], shape_list(context_layer)[-1]], + ), + [0, 2, 1, 3], + ) + # Set the final dimension here explicitly. + # Calling tf.reshape(context_layer, (*context_layer_shape[:-2], -1)) raises an error when executing + # the model in graph mode as context_layer is reshaped to (None, 7, None) and Dense layer in TFDebertaV2SelfOutput + # requires final input dimension to be defined + context_layer_shape = shape_list(context_layer) + new_context_layer_shape = context_layer_shape[:-2] + [context_layer_shape[-2] * context_layer_shape[-1]] + context_layer = tf.reshape(context_layer, new_context_layer_shape) + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + return outputs + + def disentangled_att_bias(self, query_layer, key_layer, relative_pos, rel_embeddings, scale_factor): + if relative_pos is None: + q = shape_list(query_layer)[-2] + relative_pos = build_relative_position( + q, + shape_list(key_layer)[-2], + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + ) + shape_list_pos = shape_list(relative_pos) + if len(shape_list_pos) == 2: + relative_pos = tf.expand_dims(tf.expand_dims(relative_pos, 0), 0) + elif len(shape_list_pos) == 3: + relative_pos = tf.expand_dims(relative_pos, 1) + # bsz x height x query x key + elif len(shape_list_pos) != 4: + raise ValueError(f"Relative position ids must be of dim 2 or 3 or 4. {len(shape_list_pos)}") + + att_span = self.pos_ebd_size + rel_embeddings = tf.expand_dims( + rel_embeddings[self.pos_ebd_size - att_span : self.pos_ebd_size + att_span, :], 0 + ) + if self.share_att_key: + pos_query_layer = tf.tile( + self.transpose_for_scores(self.query_proj(rel_embeddings), self.num_attention_heads), + [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], + ) + pos_key_layer = tf.tile( + self.transpose_for_scores(self.key_proj(rel_embeddings), self.num_attention_heads), + [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], + ) + else: + if "c2p" in self.pos_att_type: + pos_key_layer = tf.tile( + self.transpose_for_scores(self.pos_key_proj(rel_embeddings), self.num_attention_heads), + [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], + ) # .split(self.all_head_size, dim=-1) + if "p2c" in self.pos_att_type: + pos_query_layer = tf.tile( + self.transpose_for_scores(self.pos_query_proj(rel_embeddings), self.num_attention_heads), + [shape_list(query_layer)[0] // self.num_attention_heads, 1, 1], + ) # .split(self.all_head_size, dim=-1) + + score = 0 + # content->position + if "c2p" in self.pos_att_type: + scale = tf.math.sqrt(tf.cast(shape_list(pos_key_layer)[-1] * scale_factor, tf.float32)) + c2p_att = tf.matmul(query_layer, tf.transpose(pos_key_layer, [0, 2, 1])) + c2p_pos = tf.clip_by_value(relative_pos + att_span, 0, att_span * 2 - 1) + c2p_att = take_along_axis( + c2p_att, + tf.broadcast_to( + tf.squeeze(c2p_pos, 0), + [shape_list(query_layer)[0], shape_list(query_layer)[1], shape_list(relative_pos)[-1]], + ), + ) + score += c2p_att / scale + + # position->content + if "p2c" in self.pos_att_type: + scale = tf.math.sqrt(tf.cast(shape_list(pos_query_layer)[-1] * scale_factor, tf.float32)) + if shape_list(key_layer)[-2] != shape_list(query_layer)[-2]: + r_pos = build_relative_position( + shape_list(key_layer)[-2], + shape_list(key_layer)[-2], + bucket_size=self.position_buckets, + max_position=self.max_relative_positions, + ) + r_pos = tf.expand_dims(r_pos, 0) + else: + r_pos = relative_pos + + p2c_pos = tf.clip_by_value(-r_pos + att_span, 0, att_span * 2 - 1) + + p2c_att = tf.matmul(key_layer, tf.transpose(pos_query_layer, [0, 2, 1])) + p2c_att = tf.transpose( + take_along_axis( + p2c_att, + tf.broadcast_to( + tf.squeeze(p2c_pos, 0), + [shape_list(query_layer)[0], shape_list(key_layer)[-2], shape_list(key_layer)[-2]], + ), + ), + [0, 2, 1], + ) + score += p2c_att / scale + + return score + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaEmbeddings Deberta->DebertaV2 +class TFDebertaV2Embeddings(tf.keras.layers.Layer): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.embedding_size = getattr(config, "embedding_size", config.hidden_size) + self.hidden_size = config.hidden_size + self.max_position_embeddings = config.max_position_embeddings + self.position_biased_input = getattr(config, "position_biased_input", True) + self.initializer_range = config.initializer_range + if self.embedding_size != config.hidden_size: + self.embed_proj = tf.keras.layers.Dense(config.hidden_size, use_bias=False) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = TFDebertaV2StableDropout(config.hidden_dropout_prob, name="dropout") + + def build(self, input_shape: tf.TensorShape): + with tf.name_scope("word_embeddings"): + self.weight = self.add_weight( + name="weight", + shape=[self.config.vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("token_type_embeddings"): + if self.config.type_vocab_size > 0: + self.token_type_embeddings = self.add_weight( + name="embeddings", + shape=[self.config.type_vocab_size, self.embedding_size], + initializer=get_initializer(self.initializer_range), + ) + else: + self.token_type_embeddings = None + + with tf.name_scope("position_embeddings"): + if self.position_biased_input: + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.hidden_size], + initializer=get_initializer(self.initializer_range), + ) + else: + self.position_embeddings = None + + super().build(input_shape) + + def call( + self, + input_ids: tf.Tensor = None, + position_ids: tf.Tensor = None, + token_type_ids: tf.Tensor = None, + inputs_embeds: tf.Tensor = None, + mask: tf.Tensor = None, + training: bool = False, + ) -> tf.Tensor: + """ + Applies embedding based on inputs tensor. + + Returns: + final_embeddings (`tf.Tensor`): output embedding tensor. + """ + if input_ids is None and inputs_embeds is None: + raise ValueError("Need to provide either `input_ids` or `input_embeds`.") + + if input_ids is not None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.config.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.config.vocab_size})" + ), + ) + inputs_embeds = tf.gather(params=self.weight, indices=input_ids) + + input_shape = shape_list(inputs_embeds)[:-1] + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + if position_ids is None: + position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) + + final_embeddings = inputs_embeds + if self.position_biased_input: + position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) + final_embeddings += position_embeds + if self.config.type_vocab_size > 0: + token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) + final_embeddings += token_type_embeds + + if self.embedding_size != self.hidden_size: + final_embeddings = self.embed_proj(final_embeddings) + + final_embeddings = self.LayerNorm(final_embeddings) + + if mask is not None: + if len(shape_list(mask)) != len(shape_list(final_embeddings)): + if len(shape_list(mask)) == 4: + mask = tf.squeeze(tf.squeeze(mask, axis=1), axis=1) + mask = tf.cast(tf.expand_dims(mask, axis=2), tf.float32) + + final_embeddings = final_embeddings * mask + + final_embeddings = self.dropout(final_embeddings, training=training) + + return final_embeddings + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaPredictionHeadTransform with Deberta->DebertaV2 +class TFDebertaV2PredictionHeadTransform(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + name="dense", + ) + + if isinstance(config.hidden_act, str): + self.transform_act_fn = get_tf_activation(config.hidden_act) + else: + self.transform_act_fn = config.hidden_act + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + + return hidden_states + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaLMPredictionHead with Deberta->DebertaV2 +class TFDebertaV2LMPredictionHead(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, input_embeddings: tf.keras.layers.Layer, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.hidden_size = config.hidden_size + + self.transform = TFDebertaV2PredictionHeadTransform(config, name="transform") + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.input_embeddings = input_embeddings + + def build(self, input_shape: tf.TensorShape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + + super().build(input_shape) + + def get_output_embeddings(self) -> tf.keras.layers.Layer: + return self.input_embeddings + + def set_output_embeddings(self, value: tf.Variable): + self.input_embeddings.weight = value + self.input_embeddings.vocab_size = shape_list(value)[0] + + def get_bias(self) -> Dict[str, tf.Variable]: + return {"bias": self.bias} + + def set_bias(self, value: tf.Variable): + self.bias = value["bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.transform(hidden_states=hidden_states) + seq_length = shape_list(hidden_states)[1] + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) + hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) + hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) + + return hidden_states + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaOnlyMLMHead with Deberta->DebertaV2 +class TFDebertaV2OnlyMLMHead(tf.keras.layers.Layer): + def __init__(self, config: DebertaV2Config, input_embeddings: tf.keras.layers.Layer, **kwargs): + super().__init__(**kwargs) + self.predictions = TFDebertaV2LMPredictionHead(config, input_embeddings, name="predictions") + + def call(self, sequence_output: tf.Tensor) -> tf.Tensor: + prediction_scores = self.predictions(hidden_states=sequence_output) + + return prediction_scores + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaMainLayer with Deberta->DebertaV2 +class TFDebertaV2MainLayer(tf.keras.layers.Layer): + config_class = DebertaV2Config + + def __init__(self, config: DebertaV2Config, **kwargs): + super().__init__(**kwargs) + + self.config = config + + self.embeddings = TFDebertaV2Embeddings(config, name="embeddings") + self.encoder = TFDebertaV2Encoder(config, name="encoder") + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings + + def set_input_embeddings(self, value: tf.Variable): + self.embeddings.weight = value + self.embeddings.vocab_size = shape_list(value)[0] + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = tf.fill(dims=input_shape, value=1) + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + mask=attention_mask, + training=training, + ) + + encoder_outputs = self.encoder( + hidden_states=embedding_output, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + + if not return_dict: + return (sequence_output,) + encoder_outputs[1:] + + return TFBaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaPreTrainedModel with Deberta->DebertaV2 +class TFDebertaV2PreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DebertaV2Config + base_model_prefix = "deberta" + + +DEBERTA_START_DOCSTRING = r""" + The DeBERTa model was proposed in [DeBERTa: Decoding-enhanced BERT with Disentangled + Attention](https://arxiv.org/abs/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen. It's build + on top of BERT/RoBERTa with two improvements, i.e. disentangled attention and enhanced mask decoder. With those two + improvements, it out perform BERT/RoBERTa on a majority of tasks with 80GB pretraining data. + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`DebertaV2Config`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` ``Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert *input_ids* indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput``] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeBERTa Model transformer outputting raw hidden-states without any specific head on top.", + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaModel with Deberta->DebertaV2 +class TFDebertaV2Model(TFDebertaV2PreTrainedModel): + def __init__(self, config: DebertaV2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.deberta = TFDebertaV2MainLayer(config, name="deberta") + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFBaseModelOutput) -> TFBaseModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutput(last_hidden_state=output.last_hidden_state, hidden_states=hs, attentions=attns) + + +@add_start_docstrings("""DeBERTa Model with a `language modeling` head on top.""", DEBERTA_START_DOCSTRING) +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForMaskedLM with Deberta->DebertaV2 +class TFDebertaV2ForMaskedLM(TFDebertaV2PreTrainedModel, TFMaskedLanguageModelingLoss): + def __init__(self, config: DebertaV2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + if config.is_decoder: + logger.warning( + "If you want to use `TFDebertaV2ForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.deberta = TFDebertaV2MainLayer(config, name="deberta") + self.mlm = TFDebertaV2OnlyMLMHead(config, input_embeddings=self.deberta.embeddings, name="cls") + + def get_lm_head(self) -> tf.keras.layers.Layer: + return self.mlm.predictions + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMaskedLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + prediction_scores = self.mlm(sequence_output=sequence_output, training=training) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=prediction_scores) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFMaskedLMOutput( + loss=loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedLMOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForSequenceClassification with Deberta->DebertaV2 +class TFDebertaV2ForSequenceClassification(TFDebertaV2PreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config: DebertaV2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaV2MainLayer(config, name="deberta") + self.pooler = TFDebertaV2ContextPooler(config, name="pooler") + + drop_out = getattr(config, "cls_dropout", None) + drop_out = self.config.hidden_dropout_prob if drop_out is None else drop_out + self.dropout = TFDebertaV2StableDropout(drop_out, name="cls_dropout") + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, + kernel_initializer=get_initializer(config.initializer_range), + name="classifier", + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + pooled_output = self.pooler(sequence_output, training=training) + pooled_output = self.dropout(pooled_output, training=training) + logits = self.classifier(pooled_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[1:] + + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForTokenClassification with Deberta->DebertaV2 +class TFDebertaV2ForTokenClassification(TFDebertaV2PreTrainedModel, TFTokenClassificationLoss): + def __init__(self, config: DebertaV2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaV2MainLayer(config, name="deberta") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + sequence_output = self.dropout(sequence_output, training=training) + logits = self.classifier(inputs=sequence_output) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DeBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DEBERTA_START_DOCSTRING, +) +# Copied from transformers.models.deberta.modeling_tf_deberta.TFDebertaForQuestionAnswering with Deberta->DebertaV2 +class TFDebertaV2ForQuestionAnswering(TFDebertaV2PreTrainedModel, TFQuestionAnsweringLoss): + def __init__(self, config: DebertaV2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + + self.deberta = TFDebertaV2MainLayer(config, name="deberta") + self.qa_outputs = tf.keras.layers.Dense( + units=config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + outputs = self.deberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + logits = self.qa_outputs(inputs=sequence_output) + start_logits, end_logits = tf.split(value=logits, num_or_size_splits=2, axis=-1) + start_logits = tf.squeeze(input=start_logits, axis=-1) + end_logits = tf.squeeze(input=end_logits, axis=-1) + loss = None + + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels=labels, logits=(start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..b2a0d844f1625d71cdc4905d43851a47563f2746 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2.py @@ -0,0 +1,550 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization class for model DeBERTa.""" + +import os +import unicodedata +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as sp + +from ...tokenization_utils import PreTrainedTokenizer + + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "microsoft/deberta-v2-xlarge": "https://huggingface.co/microsoft/deberta-v2-xlarge/resolve/main/spm.model", + "microsoft/deberta-v2-xxlarge": "https://huggingface.co/microsoft/deberta-v2-xxlarge/resolve/main/spm.model", + "microsoft/deberta-v2-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xlarge-mnli/resolve/main/spm.model" + ), + "microsoft/deberta-v2-xxlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xxlarge-mnli/resolve/main/spm.model" + ), + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "microsoft/deberta-v2-xlarge": 512, + "microsoft/deberta-v2-xxlarge": 512, + "microsoft/deberta-v2-xlarge-mnli": 512, + "microsoft/deberta-v2-xxlarge-mnli": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "microsoft/deberta-v2-xlarge": {"do_lower_case": False}, + "microsoft/deberta-v2-xxlarge": {"do_lower_case": False}, + "microsoft/deberta-v2-xlarge-mnli": {"do_lower_case": False}, + "microsoft/deberta-v2-xxlarge-mnli": {"do_lower_case": False}, +} + +VOCAB_FILES_NAMES = {"vocab_file": "spm.model"} + + +class DebertaV2Tokenizer(PreTrainedTokenizer): + r""" + Constructs a DeBERTa-v2 tokenizer. Based on [SentencePiece](https://github.com/google/sentencepiece). + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `False`): + Whether or not to lowercase the input when tokenizing. + bos_token (`string`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token that was used during pre-training. Can be used a sequence classifier token. + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + eos_token (`string`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. When building a sequence using special tokens, this is not the token that is + used for the end of sequence. The token used is the `sep_token`. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + + def __init__( + self, + vocab_file, + do_lower_case=False, + split_by_punct=False, + bos_token="[CLS]", + eos_token="[SEP]", + unk_token="[UNK]", + sep_token="[SEP]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + do_lower_case=do_lower_case, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + split_by_punct=split_by_punct, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + if not os.path.isfile(vocab_file): + raise ValueError( + f"Can't find a vocabulary file at path '{vocab_file}'. To load the vocabulary from a Google pretrained" + " model use `tokenizer = AutoTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`" + ) + self.do_lower_case = do_lower_case + self.split_by_punct = split_by_punct + self.vocab_file = vocab_file + self._tokenizer = SPMTokenizer( + vocab_file, self.all_special_tokens, split_by_punct=split_by_punct, sp_model_kwargs=self.sp_model_kwargs + ) + + @property + def vocab_size(self): + return len(self.vocab) + + @property + def vocab(self): + return self._tokenizer.vocab + + def get_vocab(self): + vocab = self.vocab.copy() + vocab.update(self.get_added_vocab()) + return vocab + + def _tokenize(self, text: str) -> List[str]: + """Take as input a string and return a list of strings (tokens) for words/sub-words""" + if self.do_lower_case: + text = text.lower() + return self._tokenizer.tokenize(text) + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self._tokenizer.spm.PieceToId(token) + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self._tokenizer.spm.IdToPiece(index) if index < self.vocab_size else self.unk_token + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + return self._tokenizer.decode(tokens) + + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A DeBERTa sequence has the following format: + + - single sequence: [CLS] X [SEP] + - pair of sequences: [CLS] A [SEP] B [SEP] + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + token_ids_1 + sep + + def get_special_tokens_mask(self, token_ids_0, token_ids_1=None, already_has_special_tokens=False): + """ + Retrieves sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` or `encode_plus` methods. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + + def create_token_type_ids_from_sequences(self, token_ids_0, token_ids_1=None): + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A DeBERTa + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): + add_prefix_space = kwargs.pop("add_prefix_space", False) + if is_split_into_words or add_prefix_space: + text = " " + text + return (text, kwargs) + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + return self._tokenizer.save_pretrained(save_directory, filename_prefix=filename_prefix) + + +class SPMTokenizer: + r""" + Constructs a tokenizer based on [SentencePiece](https://github.com/google/sentencepiece). + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + """ + + def __init__( + self, vocab_file, special_tokens, split_by_punct=False, sp_model_kwargs: Optional[Dict[str, Any]] = None + ): + self.split_by_punct = split_by_punct + self.vocab_file = vocab_file + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + spm = sp.SentencePieceProcessor(**self.sp_model_kwargs) + if not os.path.exists(vocab_file): + raise FileNotFoundError(f"{vocab_file} does not exist!") + spm.load(vocab_file) + bpe_vocab_size = spm.GetPieceSize() + # Token map + # 0+1 + # 1+1 + # 2+1 + self.vocab = {spm.IdToPiece(i): i for i in range(bpe_vocab_size)} + self.ids_to_tokens = [spm.IdToPiece(i) for i in range(bpe_vocab_size)] + # self.vocab['[PAD]'] = 0 + # self.vocab['[CLS]'] = 1 + # self.vocab['[SEP]'] = 2 + # self.vocab['[UNK]'] = 3 + + self.spm = spm + self.special_tokens = special_tokens + + def __getstate__(self): + state = self.__dict__.copy() + state["spm"] = None + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.spm = sp.SentencePieceProcessor(**self.sp_model_kwargs) + self.spm.Load(self.vocab_file) + + def tokenize(self, text): + return self._encode_as_pieces(text) + + def convert_ids_to_tokens(self, ids): + tokens = [] + for i in ids: + tokens.append(self.ids_to_tokens[i]) + return tokens + + def decode(self, tokens, start=-1, end=-1, raw_text=None): + if raw_text is None: + current_sub_tokens = [] + out_string = "" + prev_is_special = False + for token in tokens: + # make sure that special tokens are not decoded using sentencepiece model + if token in self.special_tokens: + if not prev_is_special: + out_string += " " + out_string += self.spm.decode_pieces(current_sub_tokens) + token + prev_is_special = True + current_sub_tokens = [] + else: + current_sub_tokens.append(token) + prev_is_special = False + out_string += self.spm.decode_pieces(current_sub_tokens) + return out_string.strip() + else: + words = self.split_to_words(raw_text) + word_tokens = [self.tokenize(w) for w in words] + token2words = [0] * len(tokens) + tid = 0 + for i, w in enumerate(word_tokens): + for k, t in enumerate(w): + token2words[tid] = i + tid += 1 + word_start = token2words[start] + word_end = token2words[end] if end < len(tokens) else len(words) + text = "".join(words[word_start:word_end]) + return text + + def add_special_token(self, token): + if token not in self.special_tokens: + self.special_tokens.append(token) + if token not in self.vocab: + self.vocab[token] = len(self.vocab) - 1 + self.ids_to_tokens.append(token) + return self.id(token) + + def part_of_whole_word(self, token, is_bos=False): + if is_bos: + return True + if ( + len(token) == 1 + and (_is_whitespace(list(token)[0]) or _is_control(list(token)[0]) or _is_punctuation(list(token)[0])) + ) or token in self.special_tokens: + return False + + word_start = b"\xe2\x96\x81".decode("utf-8") + return not token.startswith(word_start) + + def pad(self): + return "[PAD]" + + def bos(self): + return "[CLS]" + + def eos(self): + return "[SEP]" + + def unk(self): + return "[UNK]" + + def mask(self): + return "[MASK]" + + def sym(self, id): + return self.ids_to_tokens[id] + + def id(self, sym): + return self.vocab[sym] if sym in self.vocab else 1 + + def _encode_as_pieces(self, text): + text = convert_to_unicode(text) + if self.split_by_punct: + words = self._run_split_on_punc(text) + pieces = [self.spm.encode(w, out_type=str) for w in words] + return [p for w in pieces for p in w] + else: + return self.spm.encode(text, out_type=str) + + def split_to_words(self, text): + pieces = self._encode_as_pieces(text) + word_start = b"\xe2\x96\x81".decode("utf-8") + words = [] + offset = 0 + prev_end = 0 + for i, p in enumerate(pieces): + if p.startswith(word_start): + if offset > prev_end: + words.append(text[prev_end:offset]) + prev_end = offset + w = p.replace(word_start, "") + else: + w = p + try: + s = text.index(w, offset) + pn = "" + k = i + 1 + while k < len(pieces): + pn = pieces[k].replace(word_start, "") + if len(pn) > 0: + break + k += 1 + + if len(pn) > 0 and pn in text[offset:s]: + offset = offset + 1 + else: + offset = s + len(w) + except Exception: + offset = offset + 1 + + if prev_end < offset: + words.append(text[prev_end:offset]) + + return words + + def _run_strip_accents(self, text): + """Strips accents from a piece of text.""" + text = unicodedata.normalize("NFD", text) + output = [] + for char in text: + cat = unicodedata.category(char) + if cat == "Mn": + continue + output.append(char) + return "".join(output) + + def _run_split_on_punc(self, text): + """Splits punctuation on a piece of text.""" + chars = list(text) + i = 0 + start_new_word = True + output = [] + while i < len(chars): + char = chars[i] + if _is_punctuation(char): + output.append([char]) + start_new_word = True + else: + if start_new_word: + output.append([]) + start_new_word = False + output[-1].append(char) + i += 1 + + return ["".join(x) for x in output] + + def save_pretrained(self, path: str, filename_prefix: str = None): + filename = VOCAB_FILES_NAMES[list(VOCAB_FILES_NAMES.keys())[0]] + if filename_prefix is not None: + filename = filename_prefix + "-" + filename + full_path = os.path.join(path, filename) + with open(full_path, "wb") as fs: + fs.write(self.spm.serialized_model_proto()) + return (full_path,) + + +def _is_whitespace(char): + """Checks whether `chars` is a whitespace character.""" + # \t, \n, and \r are technically control characters but we treat them + # as whitespace since they are generally considered as such. + if char == " " or char == "\t" or char == "\n" or char == "\r": + return True + cat = unicodedata.category(char) + if cat == "Zs": + return True + return False + + +def _is_control(char): + """Checks whether `chars` is a control character.""" + # These are technically control characters but we count them as whitespace + # characters. + if char == "\t" or char == "\n" or char == "\r": + return False + cat = unicodedata.category(char) + if cat.startswith("C"): + return True + return False + + +def _is_punctuation(char): + """Checks whether `chars` is a punctuation character.""" + cp = ord(char) + # We treat all non-letter/number ASCII as punctuation. + # Characters such as "^", "$", and "`" are not in the Unicode + # Punctuation class but we treat them as punctuation anyways, for + # consistency. + if (cp >= 33 and cp <= 47) or (cp >= 58 and cp <= 64) or (cp >= 91 and cp <= 96) or (cp >= 123 and cp <= 126): + return True + cat = unicodedata.category(char) + if cat.startswith("P"): + return True + return False + + +def convert_to_unicode(text): + """Converts `text` to Unicode (if it's not already), assuming utf-8 input.""" + if isinstance(text, str): + return text + elif isinstance(text, bytes): + return text.decode("utf-8", "ignore") + else: + raise ValueError(f"Unsupported string type: {type(text)}") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..3f2a90cfa83ea9d58201af76b02756e5c8cf0d25 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deberta_v2/tokenization_deberta_v2_fast.py @@ -0,0 +1,247 @@ +# coding=utf-8 +# Copyright 2020 Microsoft and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Fast Tokenization class for model DeBERTa.""" + +import os +from shutil import copyfile +from typing import Optional, Tuple + +from ...file_utils import is_sentencepiece_available +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging + + +if is_sentencepiece_available(): + from .tokenization_deberta_v2 import DebertaV2Tokenizer +else: + DebertaV2Tokenizer = None + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "spm.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "microsoft/deberta-v2-xlarge": "https://huggingface.co/microsoft/deberta-v2-xlarge/resolve/main/spm.model", + "microsoft/deberta-v2-xxlarge": "https://huggingface.co/microsoft/deberta-v2-xxlarge/resolve/main/spm.model", + "microsoft/deberta-v2-xlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xlarge-mnli/resolve/main/spm.model" + ), + "microsoft/deberta-v2-xxlarge-mnli": ( + "https://huggingface.co/microsoft/deberta-v2-xxlarge-mnli/resolve/main/spm.model" + ), + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "microsoft/deberta-v2-xlarge": 512, + "microsoft/deberta-v2-xxlarge": 512, + "microsoft/deberta-v2-xlarge-mnli": 512, + "microsoft/deberta-v2-xxlarge-mnli": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "microsoft/deberta-v2-xlarge": {"do_lower_case": False}, + "microsoft/deberta-v2-xxlarge": {"do_lower_case": False}, + "microsoft/deberta-v2-xlarge-mnli": {"do_lower_case": False}, + "microsoft/deberta-v2-xxlarge-mnli": {"do_lower_case": False}, +} + + +class DebertaV2TokenizerFast(PreTrainedTokenizerFast): + r""" + Constructs a DeBERTa-v2 fast tokenizer. Based on [SentencePiece](https://github.com/google/sentencepiece). + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `False`): + Whether or not to lowercase the input when tokenizing. + bos_token (`string`, *optional*, defaults to `"[CLS]"`): + The beginning of sequence token that was used during pre-training. Can be used a sequence classifier token. + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + eos_token (`string`, *optional*, defaults to `"[SEP]"`): + The end of sequence token. When building a sequence using special tokens, this is not the token that is + used for the end of sequence. The token used is the `sep_token`. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + slow_tokenizer_class = DebertaV2Tokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + do_lower_case=False, + split_by_punct=False, + bos_token="[CLS]", + eos_token="[SEP]", + unk_token="[UNK]", + sep_token="[SEP]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + **kwargs, + ) -> None: + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + do_lower_case=do_lower_case, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + split_by_punct=split_by_punct, + **kwargs, + ) + + self.do_lower_case = do_lower_case + self.split_by_punct = split_by_punct + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A DeBERTa sequence has the following format: + + - single sequence: [CLS] X [SEP] + - pair of sequences: [CLS] A [SEP] B [SEP] + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + token_ids_1 + sep + + def get_special_tokens_mask(self, token_ids_0, token_ids_1=None, already_has_special_tokens=False): + """ + Retrieves sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` or `encode_plus` methods. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + + def create_token_type_ids_from_sequences(self, token_ids_0, token_ids_1=None): + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A DeBERTa + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..44070229aaa8591cb967a4ca7ff4867873072f8a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/__init__.py @@ -0,0 +1,65 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = { + "configuration_decision_transformer": [ + "DECISION_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP", + "DecisionTransformerConfig", + ], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_decision_transformer"] = [ + "DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST", + "DecisionTransformerGPT2Model", + "DecisionTransformerGPT2PreTrainedModel", + "DecisionTransformerModel", + "DecisionTransformerPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_decision_transformer import ( + DECISION_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, + DecisionTransformerConfig, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_decision_transformer import ( + DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST, + DecisionTransformerGPT2Model, + DecisionTransformerGPT2PreTrainedModel, + DecisionTransformerModel, + DecisionTransformerPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/configuration_decision_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/configuration_decision_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..91ef58665a1f18eb8aa12d95d9936302cf22a5db --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/configuration_decision_transformer.py @@ -0,0 +1,161 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Decision Transformer model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DECISION_TRANSFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "edbeeching/decision-transformer-gym-hopper-medium": ( + "https://huggingface.co/edbeeching/decision-transformer-gym-hopper-medium/resolve/main/config.json" + ), + # See all DecisionTransformer models at https://huggingface.co/models?filter=decision_transformer +} + + +class DecisionTransformerConfig(PretrainedConfig): + """ + This is the configuration class to store the configuration of a [`DecisionTransformerModel`]. It is used to + instantiate a Decision Transformer model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the standard + DecisionTransformer architecture. Many of the config options are used to instatiate the GPT2 model that is used as + part of the architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + state_dim (`int`, *optional*, defaults to 17): + The state size for the RL environment + act_dim (`int`, *optional*, defaults to 4): + The size of the output action space + hidden_size (`int`, *optional*, defaults to 128): + The size of the hidden layers + max_ep_len (`int`, *optional*, defaults to 4096): + The maximum length of an episode in the environment + action_tanh (`bool`, *optional*, defaults to True): + Whether to use a tanh activation on action prediction + vocab_size (`int`, *optional*, defaults to 50257): + Vocabulary size of the GPT-2 model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`DecisionTransformerModel`]. + n_positions (`int`, *optional*, defaults to 1024): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + n_layer (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + n_head (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + n_inner (`int`, *optional*): + Dimensionality of the inner feed-forward layers. If unset, will default to 4 times `n_embd`. + activation_function (`str`, *optional*, defaults to `"gelu"`): + Activation function, to be selected in the list `["relu", "silu", "gelu", "tanh", "gelu_new"]`. + resid_pdrop (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + embd_pdrop (`int`, *optional*, defaults to 0.1): + The dropout ratio for the embeddings. + attn_pdrop (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention. + layer_norm_epsilon (`float`, *optional*, defaults to 1e-5): + The epsilon to use in the layer normalization layers. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + scale_attn_weights (`bool`, *optional*, defaults to `True`): + Scale attention weights by dividing by sqrt(hidden_size).. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + scale_attn_by_inverse_layer_idx (`bool`, *optional*, defaults to `False`): + Whether to additionally scale attention weights by `1 / layer_idx + 1`. + reorder_and_upcast_attn (`bool`, *optional*, defaults to `False`): + Whether to scale keys (K) prior to computing attention (dot-product) and upcast attention + dot-product/softmax to float() when training with mixed precision. + + Example: + + ```python + >>> from transformers import DecisionTransformerConfig, DecisionTransformerModel + + >>> # Initializing a DecisionTransformer configuration + >>> configuration = DecisionTransformerConfig() + + >>> # Initializing a model (with random weights) from the configuration + >>> model = DecisionTransformerModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "decision_transformer" + keys_to_ignore_at_inference = ["past_key_values"] + attribute_map = { + "max_position_embeddings": "n_positions", + "num_attention_heads": "n_head", + "num_hidden_layers": "n_layer", + } + + def __init__( + self, + state_dim=17, + act_dim=4, + hidden_size=128, + max_ep_len=4096, + action_tanh=True, + vocab_size=1, + n_positions=1024, + n_layer=3, + n_head=1, + n_inner=None, + activation_function="relu", + resid_pdrop=0.1, + embd_pdrop=0.1, + attn_pdrop=0.1, + layer_norm_epsilon=1e-5, + initializer_range=0.02, + scale_attn_weights=True, + use_cache=True, + bos_token_id=50256, + eos_token_id=50256, + scale_attn_by_inverse_layer_idx=False, + reorder_and_upcast_attn=False, + **kwargs, + ): + self.state_dim = state_dim + self.act_dim = act_dim + self.hidden_size = hidden_size + self.max_ep_len = max_ep_len + self.action_tanh = action_tanh + self.vocab_size = vocab_size + self.n_positions = n_positions + self.n_layer = n_layer + self.n_head = n_head + self.n_inner = n_inner + self.activation_function = activation_function + self.resid_pdrop = resid_pdrop + self.embd_pdrop = embd_pdrop + self.attn_pdrop = attn_pdrop + self.layer_norm_epsilon = layer_norm_epsilon + self.initializer_range = initializer_range + self.scale_attn_weights = scale_attn_weights + self.use_cache = use_cache + self.scale_attn_by_inverse_layer_idx = scale_attn_by_inverse_layer_idx + self.reorder_and_upcast_attn = reorder_and_upcast_attn + + self.bos_token_id = bos_token_id + self.eos_token_id = eos_token_id + + super().__init__(bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/modeling_decision_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/modeling_decision_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..0add713d8e878e203b31ecc4bf4ed16f55b5d0e0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/decision_transformer/modeling_decision_transformer.py @@ -0,0 +1,952 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DecisionTransformer model.""" + +import math +import os +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.cuda.amp import autocast + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutputWithPastAndCrossAttentions +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import Conv1D, find_pruneable_heads_and_indices, prune_conv1d_layer +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_decision_transformer import DecisionTransformerConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "edbeeching/decision-transformer-gym-hopper-medium" +_CONFIG_FOR_DOC = "DecisionTransformerConfig" + +DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "edbeeching/decision-transformer-gym-hopper-medium", + # See all DecisionTransformer models at https://huggingface.co/models?filter=decision_transformer +] + + +# Copied from transformers.models.gpt2.modeling_gpt2.load_tf_weights_in_gpt2 +def load_tf_weights_in_gpt2(model, config, gpt2_checkpoint_path): + """Load tf checkpoints in a pytorch model""" + try: + import re + + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(gpt2_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array.squeeze()) + + for name, array in zip(names, arrays): + name = name[6:] # skip "model/" + name = name.split("/") + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+\d+", m_name): + scope_names = re.split(r"(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "w" or scope_names[0] == "g": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "b": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "wpe" or scope_names[0] == "wte": + pointer = getattr(pointer, scope_names[0]) + pointer = getattr(pointer, "weight") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + try: + assert ( + pointer.shape == array.shape + ), f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + return model + + +# Copied from transformers.models.gpt2.modeling_gpt2.GPT2Attention with GPT2->DecisionTransformerGPT2 +class DecisionTransformerGPT2Attention(nn.Module): + def __init__(self, config, is_cross_attention=False, layer_idx=None): + super().__init__() + + max_positions = config.max_position_embeddings + self.register_buffer( + "bias", + torch.tril(torch.ones((max_positions, max_positions), dtype=torch.bool)).view( + 1, 1, max_positions, max_positions + ), + ) + self.register_buffer("masked_bias", torch.tensor(-1e4)) + + self.embed_dim = config.hidden_size + self.num_heads = config.num_attention_heads + self.head_dim = self.embed_dim // self.num_heads + self.split_size = self.embed_dim + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"`embed_dim` must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {self.num_heads})." + ) + + self.scale_attn_weights = config.scale_attn_weights + self.is_cross_attention = is_cross_attention + + # Layer-wise attention scaling, reordering, and upcasting + self.scale_attn_by_inverse_layer_idx = config.scale_attn_by_inverse_layer_idx + self.layer_idx = layer_idx + self.reorder_and_upcast_attn = config.reorder_and_upcast_attn + + if self.is_cross_attention: + self.c_attn = Conv1D(2 * self.embed_dim, self.embed_dim) + self.q_attn = Conv1D(self.embed_dim, self.embed_dim) + else: + self.c_attn = Conv1D(3 * self.embed_dim, self.embed_dim) + self.c_proj = Conv1D(self.embed_dim, self.embed_dim) + + self.attn_dropout = nn.Dropout(config.attn_pdrop) + self.resid_dropout = nn.Dropout(config.resid_pdrop) + + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices(heads, self.num_heads, self.head_dim, self.pruned_heads) + index_attn = torch.cat([index, index + self.split_size, index + (2 * self.split_size)]) + + # Prune conv1d layers + self.c_attn = prune_conv1d_layer(self.c_attn, index_attn, dim=1) + self.c_proj = prune_conv1d_layer(self.c_proj, index, dim=0) + + # Update hyper params + self.split_size = (self.split_size // self.num_heads) * (self.num_heads - len(heads)) + self.num_heads = self.num_heads - len(heads) + self.pruned_heads = self.pruned_heads.union(heads) + + def _attn(self, query, key, value, attention_mask=None, head_mask=None): + attn_weights = torch.matmul(query, key.transpose(-1, -2)) + + if self.scale_attn_weights: + attn_weights = attn_weights / torch.full( + [], value.size(-1) ** 0.5, dtype=attn_weights.dtype, device=attn_weights.device + ) + + # Layer-wise attention scaling + if self.scale_attn_by_inverse_layer_idx: + attn_weights = attn_weights / float(self.layer_idx + 1) + + if not self.is_cross_attention: + # if only "normal" attention layer implements causal mask + query_length, key_length = query.size(-2), key.size(-2) + causal_mask = self.bias[:, :, key_length - query_length : key_length, :key_length] + mask_value = torch.finfo(attn_weights.dtype).min + # Need to be a tensor, otherwise we get error: `RuntimeError: expected scalar type float but found double`. + # Need to be on the same device, otherwise `RuntimeError: ..., x and y to be on the same device` + mask_value = torch.full([], mask_value, dtype=attn_weights.dtype).to(attn_weights.device) + attn_weights = torch.where(causal_mask, attn_weights.to(attn_weights.dtype), mask_value) + + if attention_mask is not None: + # Apply the attention mask + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + # Downcast (if necessary) back to V's dtype (if in mixed-precision) -- No-Op otherwise + attn_weights = attn_weights.type(value.dtype) + attn_weights = self.attn_dropout(attn_weights) + + # Mask heads if we want to + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + + return attn_output, attn_weights + + def _upcast_and_reordered_attn(self, query, key, value, attention_mask=None, head_mask=None): + # Use `torch.baddbmm` (a bit more efficient w/ alpha param for scaling -- from Megatron-LM) + bsz, num_heads, q_seq_len, dk = query.size() + _, _, k_seq_len, _ = key.size() + + # Preallocate attn_weights for `baddbmm` + attn_weights = torch.empty(bsz * num_heads, q_seq_len, k_seq_len, dtype=torch.float32, device=query.device) + + # Compute Scale Factor + scale_factor = 1.0 + if self.scale_attn_weights: + scale_factor /= float(value.size(-1)) ** 0.5 + + if self.scale_attn_by_inverse_layer_idx: + scale_factor /= float(self.layer_idx + 1) + + # Upcast (turn off autocast) and reorder (Scale K by 1 / root(dk)) + with autocast(enabled=False): + q, k = query.reshape(-1, q_seq_len, dk), key.transpose(-1, -2).reshape(-1, dk, k_seq_len) + attn_weights = torch.baddbmm(attn_weights, q.float(), k.float(), beta=0, alpha=scale_factor) + attn_weights = attn_weights.reshape(bsz, num_heads, q_seq_len, k_seq_len) + + if not self.is_cross_attention: + # if only "normal" attention layer implements causal mask + query_length, key_length = query.size(-2), key.size(-2) + causal_mask = self.bias[:, :, key_length - query_length : key_length, :key_length] + mask_value = torch.finfo(attn_weights.dtype).min + # Need to be a tensor, otherwise we get error: `RuntimeError: expected scalar type float but found double`. + # Need to be on the same device, otherwise `RuntimeError: ..., x and y to be on the same device` + mask_value = torch.tensor(mask_value, dtype=attn_weights.dtype).to(attn_weights.device) + attn_weights = torch.where(causal_mask, attn_weights, mask_value) + + if attention_mask is not None: + # Apply the attention mask + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + # Downcast (if necessary) back to V's dtype (if in mixed-precision) -- No-Op if otherwise + if attn_weights.dtype != torch.float32: + raise RuntimeError("Error with upcasting, attn_weights does not have dtype torch.float32") + attn_weights = attn_weights.type(value.dtype) + attn_weights = self.attn_dropout(attn_weights) + + # Mask heads if we want to + if head_mask is not None: + attn_weights = attn_weights * head_mask + + attn_output = torch.matmul(attn_weights, value) + + return attn_output, attn_weights + + def _split_heads(self, tensor, num_heads, attn_head_size): + """ + Splits hidden_size dim into attn_head_size and num_heads + """ + new_shape = tensor.size()[:-1] + (num_heads, attn_head_size) + tensor = tensor.view(new_shape) + return tensor.permute(0, 2, 1, 3) # (batch, head, seq_length, head_features) + + def _merge_heads(self, tensor, num_heads, attn_head_size): + """ + Merges attn_head_size dim and num_attn_heads dim into hidden_size + """ + tensor = tensor.permute(0, 2, 1, 3).contiguous() + new_shape = tensor.size()[:-2] + (num_heads * attn_head_size,) + return tensor.view(new_shape) + + def forward( + self, + hidden_states: Optional[Tuple[torch.FloatTensor]], + layer_past: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = False, + output_attentions: Optional[bool] = False, + ) -> Tuple[Union[torch.Tensor, Tuple[torch.Tensor]], ...]: + if encoder_hidden_states is not None: + if not hasattr(self, "q_attn"): + raise ValueError( + "If class is used as cross attention, the weights `q_attn` have to be defined. " + "Please make sure to instantiate class with `DecisionTransformerGPT2Attention(..., is_cross_attention=True)`." + ) + + query = self.q_attn(hidden_states) + key, value = self.c_attn(encoder_hidden_states).split(self.split_size, dim=2) + attention_mask = encoder_attention_mask + else: + query, key, value = self.c_attn(hidden_states).split(self.split_size, dim=2) + + query = self._split_heads(query, self.num_heads, self.head_dim) + key = self._split_heads(key, self.num_heads, self.head_dim) + value = self._split_heads(value, self.num_heads, self.head_dim) + + if layer_past is not None: + past_key, past_value = layer_past + key = torch.cat((past_key, key), dim=-2) + value = torch.cat((past_value, value), dim=-2) + + if use_cache is True: + present = (key, value) + else: + present = None + + if self.reorder_and_upcast_attn: + attn_output, attn_weights = self._upcast_and_reordered_attn(query, key, value, attention_mask, head_mask) + else: + attn_output, attn_weights = self._attn(query, key, value, attention_mask, head_mask) + + attn_output = self._merge_heads(attn_output, self.num_heads, self.head_dim) + attn_output = self.c_proj(attn_output) + attn_output = self.resid_dropout(attn_output) + + outputs = (attn_output, present) + if output_attentions: + outputs += (attn_weights,) + + return outputs # a, present, (attentions) + + +# Copied from transformers.models.gpt2.modeling_gpt2.GPT2MLP with GPT2->DecisionTransformerGPT2 +class DecisionTransformerGPT2MLP(nn.Module): + def __init__(self, intermediate_size, config): + super().__init__() + embed_dim = config.hidden_size + self.c_fc = Conv1D(intermediate_size, embed_dim) + self.c_proj = Conv1D(embed_dim, intermediate_size) + self.act = ACT2FN[config.activation_function] + self.dropout = nn.Dropout(config.resid_pdrop) + + def forward(self, hidden_states: Optional[Tuple[torch.FloatTensor]]) -> torch.FloatTensor: + hidden_states = self.c_fc(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.c_proj(hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states + + +# Copied from transformers.models.gpt2.modeling_gpt2.GPT2Block with GPT2->DecisionTransformerGPT2 +class DecisionTransformerGPT2Block(nn.Module): + def __init__(self, config, layer_idx=None): + super().__init__() + hidden_size = config.hidden_size + inner_dim = config.n_inner if config.n_inner is not None else 4 * hidden_size + + self.ln_1 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon) + self.attn = DecisionTransformerGPT2Attention(config, layer_idx=layer_idx) + self.ln_2 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon) + + if config.add_cross_attention: + self.crossattention = DecisionTransformerGPT2Attention( + config, is_cross_attention=True, layer_idx=layer_idx + ) + self.ln_cross_attn = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon) + + self.mlp = DecisionTransformerGPT2MLP(inner_dim, config) + + def forward( + self, + hidden_states: Optional[Tuple[torch.FloatTensor]], + layer_past: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = False, + output_attentions: Optional[bool] = False, + ) -> Union[Tuple[torch.Tensor], Optional[Tuple[torch.Tensor, Tuple[torch.FloatTensor, ...]]]]: + residual = hidden_states + hidden_states = self.ln_1(hidden_states) + attn_outputs = self.attn( + hidden_states, + layer_past=layer_past, + attention_mask=attention_mask, + head_mask=head_mask, + use_cache=use_cache, + output_attentions=output_attentions, + ) + attn_output = attn_outputs[0] # output_attn: a, present, (attentions) + outputs = attn_outputs[1:] + # residual connection + hidden_states = attn_output + residual + + if encoder_hidden_states is not None: + # add one self-attention block for cross-attention + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with " + "cross-attention layers by setting `config.add_cross_attention=True`" + ) + residual = hidden_states + hidden_states = self.ln_cross_attn(hidden_states) + cross_attn_outputs = self.crossattention( + hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + ) + attn_output = cross_attn_outputs[0] + # residual connection + hidden_states = residual + attn_output + outputs = outputs + cross_attn_outputs[2:] # add cross attentions if we output attention weights + + residual = hidden_states + hidden_states = self.ln_2(hidden_states) + feed_forward_hidden_states = self.mlp(hidden_states) + # residual connection + hidden_states = residual + feed_forward_hidden_states + + if use_cache: + outputs = (hidden_states,) + outputs + else: + outputs = (hidden_states,) + outputs[1:] + + return outputs # hidden_states, present, (attentions, cross_attentions) + + +class DecisionTransformerGPT2PreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DecisionTransformerConfig + load_tf_weights = load_tf_weights_in_gpt2 + base_model_prefix = "transformer" + is_parallelizable = True + supports_gradient_checkpointing = True + + def __init__(self, *inputs, **kwargs): + super().__init__(*inputs, **kwargs) + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, (nn.Linear, Conv1D)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + # Reinitialize selected weights subject to the OpenAI GPT-2 Paper Scheme: + # > A modified initialization which accounts for the accumulation on the residual path with model depth. Scale + # > the weights of residual layers at initialization by a factor of 1/√N where N is the # of residual layers. + # > -- GPT-2 :: https://openai.com/blog/better-language-models/ + # + # Reference (Megatron-LM): https://github.com/NVIDIA/Megatron-LM/blob/main/megatron/model/gpt_model.py + for name, p in module.named_parameters(): + if "c_proj" in name and "weight" in name: + # Special Scaled Initialization --> There are 2 Layer Norms per Transformer Block + p.data.normal_(mean=0.0, std=(self.config.initializer_range / math.sqrt(2 * self.config.n_layer))) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DecisionTransformerGPT2Model): + module.gradient_checkpointing = value + + +class DecisionTransformerGPT2Model(DecisionTransformerGPT2PreTrainedModel): + _keys_to_ignore_on_load_missing = ["attn.masked_bias"] + + def __init__(self, config): + super().__init__(config) + + self.embed_dim = config.hidden_size + + self.wte = nn.Embedding(config.vocab_size, self.embed_dim) + self.wpe = nn.Embedding(config.max_position_embeddings, self.embed_dim) + + self.drop = nn.Dropout(config.embd_pdrop) + self.h = nn.ModuleList( + [DecisionTransformerGPT2Block(config, layer_idx=i) for i in range(config.num_hidden_layers)] + ) + self.ln_f = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_epsilon) + + # Model parallel + self.model_parallel = False + self.device_map = None + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.wte + + def set_input_embeddings(self, new_embeddings): + self.wte = new_embeddings + + # Copied from transformers.models.gpt2.modeling_gpt2.GPT2Model.forward + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPastAndCrossAttentions]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + input_ids = input_ids.view(-1, input_shape[-1]) + batch_size = input_ids.shape[0] + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + batch_size = inputs_embeds.shape[0] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if token_type_ids is not None: + token_type_ids = token_type_ids.view(-1, input_shape[-1]) + if position_ids is not None: + position_ids = position_ids.view(-1, input_shape[-1]) + + if past_key_values is None: + past_length = 0 + past_key_values = tuple([None] * len(self.h)) + else: + past_length = past_key_values[0][0].size(-2) + if position_ids is None: + position_ids = torch.arange(past_length, input_shape[-1] + past_length, dtype=torch.long, device=device) + position_ids = position_ids.unsqueeze(0).view(-1, input_shape[-1]) + + # GPT2Attention mask. + if attention_mask is not None: + if batch_size <= 0: + raise ValueError("batch_size has to be defined and > 0") + attention_mask = attention_mask.view(batch_size, -1) + # We create a 3D attention mask from a 2D tensor mask. + # Sizes are [batch_size, 1, 1, to_seq_length] + # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] + # this attention mask is more simple than the triangular masking of causal attention + # used in OpenAI GPT, we just need to prepare the broadcast dimension here. + attention_mask = attention_mask[:, None, None, :] + + # Since attention_mask is 1.0 for positions we want to attend and 0.0 for + # masked positions, this operation will create a tensor which is 0.0 for + # positions we want to attend and the dtype's smallest value for masked positions. + # Since we are adding it to the raw scores before the softmax, this is + # effectively the same as removing these entirely. + attention_mask = attention_mask.to(dtype=self.dtype) # fp16 compatibility + attention_mask = (1.0 - attention_mask) * torch.finfo(self.dtype).min + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.add_cross_attention and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # head_mask has shape n_layer x batch x n_heads x N x N + head_mask = self.get_head_mask(head_mask, self.config.n_layer) + + if inputs_embeds is None: + inputs_embeds = self.wte(input_ids) + position_embeds = self.wpe(position_ids) + hidden_states = inputs_embeds + position_embeds + + if token_type_ids is not None: + token_type_embeds = self.wte(token_type_ids) + hidden_states = hidden_states + token_type_embeds + + hidden_states = self.drop(hidden_states) + + output_shape = input_shape + (hidden_states.size(-1),) + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + presents = () if use_cache else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + all_hidden_states = () if output_hidden_states else None + for i, (block, layer_past) in enumerate(zip(self.h, past_key_values)): + # Model parallel + if self.model_parallel: + torch.cuda.set_device(hidden_states.device) + # Ensure layer_past is on same device as hidden_states (might not be correct) + if layer_past is not None: + layer_past = tuple(past_state.to(hidden_states.device) for past_state in layer_past) + # Ensure that attention_mask is always on the same device as hidden_states + if attention_mask is not None: + attention_mask = attention_mask.to(hidden_states.device) + if isinstance(head_mask, torch.Tensor): + head_mask = head_mask.to(hidden_states.device) + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + # None for past_key_value + return module(*inputs, use_cache, output_attentions) + + return custom_forward + + outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(block), + hidden_states, + None, + attention_mask, + head_mask[i], + encoder_hidden_states, + encoder_attention_mask, + ) + else: + outputs = block( + hidden_states, + layer_past=layer_past, + attention_mask=attention_mask, + head_mask=head_mask[i], + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=use_cache, + output_attentions=output_attentions, + ) + + hidden_states = outputs[0] + if use_cache is True: + presents = presents + (outputs[1],) + + if output_attentions: + all_self_attentions = all_self_attentions + (outputs[2 if use_cache else 1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (outputs[3 if use_cache else 2],) + + # Model Parallel: If it's the last layer for that device, put things on the next device + if self.model_parallel: + for k, v in self.device_map.items(): + if i == v[-1] and "cuda:" + str(k) != self.last_device: + hidden_states = hidden_states.to("cuda:" + str(k + 1)) + + hidden_states = self.ln_f(hidden_states) + + hidden_states = hidden_states.view(output_shape) + # Add last hidden state + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [hidden_states, presents, all_hidden_states, all_self_attentions, all_cross_attentions] + if v is not None + ) + + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=presents, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +@dataclass +class DecisionTransformerOutput(ModelOutput): + """ + Base class for model's outputs that also contains a pooling of the last hidden states. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + state_preds (`torch.FloatTensor` of shape `(batch_size, sequence_length, state_dim)`): + Environment state predictions + action_preds (`torch.FloatTensor` of shape `(batch_size, sequence_length, action_dim)`): + Model action predictions + return_preds (`torch.FloatTensor` of shape `(batch_size, sequence_length, 1)`): + Predicted returns for each state + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + state_preds: torch.FloatTensor = None + action_preds: torch.FloatTensor = None + return_preds: torch.FloatTensor = None + hidden_states: torch.FloatTensor = None + attentions: torch.FloatTensor = None + last_hidden_state: torch.FloatTensor = None + + +class DecisionTransformerPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DecisionTransformerConfig + base_model_prefix = "decision_transformer" + main_input_name = "states" + supports_gradient_checkpointing = False + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +DECISION_TRANSFORMER_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`~DecisionTransformerConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DECISION_TRANSFORMER_INPUTS_DOCSTRING = r""" + Args: + states (`torch.FloatTensor` of shape `(batch_size, episode_length, state_dim)`): + The states for each step in the trajectory + actions (`torch.FloatTensor` of shape `(batch_size, episode_length, act_dim)`): + The actions taken by the "expert" policy for the current state, these are masked for auto regressive + prediction + rewards (`torch.FloatTensor` of shape `(batch_size, episode_length, 1)`): + The rewards for each state, action + returns_to_go (`torch.FloatTensor` of shape `(batch_size, episode_length, 1)`): + The returns for each state in the trajectory + timesteps (`torch.LongTensor` of shape `(batch_size, episode_length)`): + The timestep for each step in the trajectory + attention_mask (`torch.LongTensor` of shape `(batch_size, episode_length)`): + Masking, used to mask the actions when performing autoregressive prediction +""" + + +@add_start_docstrings("The Decision Transformer Model", DECISION_TRANSFORMER_START_DOCSTRING) +class DecisionTransformerModel(DecisionTransformerPreTrainedModel): + """ + + The model builds upon the GPT2 architecture to perform autoregressive prediction of actions in an offline RL + setting. Refer to the paper for more details: https://arxiv.org/abs/2106.01345 + + """ + + def __init__(self, config): + super().__init__(config) + self.config = config + self.hidden_size = config.hidden_size + # note: the only difference between this GPT2Model and the default Huggingface version + # is that the positional embeddings are removed (since we'll add those ourselves) + self.encoder = DecisionTransformerGPT2Model(config) + + self.embed_timestep = nn.Embedding(config.max_ep_len, config.hidden_size) + self.embed_return = torch.nn.Linear(1, config.hidden_size) + self.embed_state = torch.nn.Linear(config.state_dim, config.hidden_size) + self.embed_action = torch.nn.Linear(config.act_dim, config.hidden_size) + + self.embed_ln = nn.LayerNorm(config.hidden_size) + + # note: we don't predict states or returns for the paper + self.predict_state = torch.nn.Linear(config.hidden_size, config.state_dim) + self.predict_action = nn.Sequential( + *([nn.Linear(config.hidden_size, config.act_dim)] + ([nn.Tanh()] if config.action_tanh else [])) + ) + self.predict_return = torch.nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DECISION_TRANSFORMER_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=DecisionTransformerOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + states=None, + actions=None, + rewards=None, + returns_to_go=None, + timesteps=None, + attention_mask=None, + output_hidden_states=None, + output_attentions=None, + return_dict=None, + ) -> Union[Tuple, DecisionTransformerOutput]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import DecisionTransformerModel + >>> import torch + + >>> model = DecisionTransformerModel.from_pretrained("edbeeching/decision-transformer-gym-hopper-medium") + >>> # evaluation + >>> model = model.to(device) + >>> model.eval() + + >>> env = gym.make("Hopper-v3") + >>> state_dim = env.observation_space.shape[0] + >>> act_dim = env.action_space.shape[0] + + >>> state = env.reset() + >>> states = torch.from_numpy(state).reshape(1, 1, state_dim).to(device=device, dtype=torch.float32) + >>> actions = torch.zeros((1, 1, act_dim), device=device, dtype=torch.float32) + >>> rewards = torch.zeros(1, 1, device=device, dtype=torch.float32) + >>> target_return = torch.tensor(TARGET_RETURN, dtype=torch.float32).reshape(1, 1) + >>> timesteps = torch.tensor(0, device=device, dtype=torch.long).reshape(1, 1) + >>> attention_mask = torch.zeros(1, 1, device=device, dtype=torch.float32) + + >>> # forward pass + >>> with torch.no_grad(): + ... state_preds, action_preds, return_preds = model( + ... states=states, + ... actions=actions, + ... rewards=rewards, + ... returns_to_go=target_return, + ... timesteps=timesteps, + ... attention_mask=attention_mask, + ... return_dict=False, + ... ) + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, seq_length = states.shape[0], states.shape[1] + + if attention_mask is None: + # attention mask for GPT: 1 if can be attended to, 0 if not + attention_mask = torch.ones((batch_size, seq_length), dtype=torch.long) + + # embed each modality with a different head + state_embeddings = self.embed_state(states) + action_embeddings = self.embed_action(actions) + returns_embeddings = self.embed_return(returns_to_go) + time_embeddings = self.embed_timestep(timesteps) + + # time embeddings are treated similar to positional embeddings + state_embeddings = state_embeddings + time_embeddings + action_embeddings = action_embeddings + time_embeddings + returns_embeddings = returns_embeddings + time_embeddings + + # this makes the sequence look like (R_1, s_1, a_1, R_2, s_2, a_2, ...) + # which works nice in an autoregressive sense since states predict actions + stacked_inputs = ( + torch.stack((returns_embeddings, state_embeddings, action_embeddings), dim=1) + .permute(0, 2, 1, 3) + .reshape(batch_size, 3 * seq_length, self.hidden_size) + ) + stacked_inputs = self.embed_ln(stacked_inputs) + + # to make the attention mask fit the stacked inputs, have to stack it as well + stacked_attention_mask = ( + torch.stack((attention_mask, attention_mask, attention_mask), dim=1) + .permute(0, 2, 1) + .reshape(batch_size, 3 * seq_length) + ) + device = stacked_inputs.device + # we feed in the input embeddings (not word indices as in NLP) to the model + encoder_outputs = self.encoder( + inputs_embeds=stacked_inputs, + attention_mask=stacked_attention_mask, + position_ids=torch.zeros(stacked_attention_mask.shape, device=device, dtype=torch.long), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + x = encoder_outputs[0] + + # reshape x so that the second dimension corresponds to the original + # returns (0), states (1), or actions (2); i.e. x[:,1,t] is the token for s_t + x = x.reshape(batch_size, seq_length, 3, self.hidden_size).permute(0, 2, 1, 3) + + # get predictions + return_preds = self.predict_return(x[:, 2]) # predict next return given state and action + state_preds = self.predict_state(x[:, 2]) # predict next state given state and action + action_preds = self.predict_action(x[:, 1]) # predict next action given state + if not return_dict: + return (state_preds, action_preds, return_preds) + + return DecisionTransformerOutput( + last_hidden_state=encoder_outputs.last_hidden_state, + state_preds=state_preds, + action_preds=action_preds, + return_preds=return_preds, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a560265f4bfcb8d43f88d2b3cd55f751409016ec --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/__init__.py @@ -0,0 +1,75 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available + + +_import_structure = { + "configuration_deformable_detr": ["DEFORMABLE_DETR_PRETRAINED_CONFIG_ARCHIVE_MAP", "DeformableDetrConfig"], +} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_deformable_detr"] = ["DeformableDetrFeatureExtractor"] + _import_structure["image_processing_deformable_detr"] = ["DeformableDetrImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_deformable_detr"] = [ + "DEFORMABLE_DETR_PRETRAINED_MODEL_ARCHIVE_LIST", + "DeformableDetrForObjectDetection", + "DeformableDetrModel", + "DeformableDetrPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_deformable_detr import DEFORMABLE_DETR_PRETRAINED_CONFIG_ARCHIVE_MAP, DeformableDetrConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_deformable_detr import DeformableDetrFeatureExtractor + from .image_processing_deformable_detr import DeformableDetrImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_deformable_detr import ( + DEFORMABLE_DETR_PRETRAINED_MODEL_ARCHIVE_LIST, + DeformableDetrForObjectDetection, + DeformableDetrModel, + DeformableDetrPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/configuration_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/configuration_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..54614eef96f9fdd8a469afa00448ec9e00e3080c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/configuration_deformable_detr.py @@ -0,0 +1,262 @@ +# coding=utf-8 +# Copyright 2022 SenseTime and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Deformable DETR model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging +from ..auto import CONFIG_MAPPING + + +logger = logging.get_logger(__name__) + +DEFORMABLE_DETR_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "SenseTime/deformable-detr": "https://huggingface.co/sensetime/deformable-detr/resolve/main/config.json", + # See all Deformable DETR models at https://huggingface.co/models?filter=deformable-detr +} + + +class DeformableDetrConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DeformableDetrModel`]. It is used to instantiate + a Deformable DETR model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the Deformable DETR + [SenseTime/deformable-detr](https://huggingface.co/SenseTime/deformable-detr) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + use_timm_backbone (`bool`, *optional*, defaults to `True`): + Whether or not to use the `timm` library for the backbone. If set to `False`, will use the [`AutoBackbone`] + API. + backbone_config (`PretrainedConfig` or `dict`, *optional*): + The configuration of the backbone model. Only used in case `use_timm_backbone` is set to `False` in which + case it will default to `ResNetConfig()`. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + num_queries (`int`, *optional*, defaults to 300): + Number of object queries, i.e. detection slots. This is the maximal number of objects + [`DeformableDetrModel`] can detect in a single image. In case `two_stage` is set to `True`, we use + `two_stage_num_proposals` instead. + d_model (`int`, *optional*, defaults to 256): + Dimension of the layers. + encoder_layers (`int`, *optional*, defaults to 6): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 6): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + decoder_ffn_dim (`int`, *optional*, defaults to 1024): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 1024): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + activation_function (`str` or `function`, *optional*, defaults to `"relu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + init_xavier_std (`float`, *optional*, defaults to 1): + The scaling factor used for the Xavier initialization gain in the HM Attention map module. + encoder_layerdrop: (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + auxiliary_loss (`bool`, *optional*, defaults to `False`): + Whether auxiliary decoding losses (loss at each decoder layer) are to be used. + position_embedding_type (`str`, *optional*, defaults to `"sine"`): + Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`. + backbone (`str`, *optional*, defaults to `"resnet50"`): + Name of convolutional backbone to use in case `use_timm_backbone` = `True`. Supports any convolutional + backbone from the timm package. For a list of all available models, see [this + page](https://rwightman.github.io/pytorch-image-models/#load-a-pretrained-model). + use_pretrained_backbone (`bool`, *optional*, defaults to `True`): + Whether to use pretrained weights for the backbone. Only supported when `use_timm_backbone` = `True`. + dilation (`bool`, *optional*, defaults to `False`): + Whether to replace stride with dilation in the last convolutional block (DC5). Only supported when + `use_timm_backbone` = `True`. + class_cost (`float`, *optional*, defaults to 1): + Relative weight of the classification error in the Hungarian matching cost. + bbox_cost (`float`, *optional*, defaults to 5): + Relative weight of the L1 error of the bounding box coordinates in the Hungarian matching cost. + giou_cost (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss of the bounding box in the Hungarian matching cost. + mask_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the Focal loss in the panoptic segmentation loss. + dice_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the DICE/F-1 loss in the panoptic segmentation loss. + bbox_loss_coefficient (`float`, *optional*, defaults to 5): + Relative weight of the L1 bounding box loss in the object detection loss. + giou_loss_coefficient (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss in the object detection loss. + eos_coefficient (`float`, *optional*, defaults to 0.1): + Relative classification weight of the 'no-object' class in the object detection loss. + num_feature_levels (`int`, *optional*, defaults to 4): + The number of input feature levels. + encoder_n_points (`int`, *optional*, defaults to 4): + The number of sampled keys in each feature level for each attention head in the encoder. + decoder_n_points (`int`, *optional*, defaults to 4): + The number of sampled keys in each feature level for each attention head in the decoder. + two_stage (`bool`, *optional*, defaults to `False`): + Whether to apply a two-stage deformable DETR, where the region proposals are also generated by a variant of + Deformable DETR, which are further fed into the decoder for iterative bounding box refinement. + two_stage_num_proposals (`int`, *optional*, defaults to 300): + The number of region proposals to be generated, in case `two_stage` is set to `True`. + with_box_refine (`bool`, *optional*, defaults to `False`): + Whether to apply iterative bounding box refinement, where each decoder layer refines the bounding boxes + based on the predictions from the previous layer. + focal_alpha (`float`, *optional*, defaults to 0.25): + Alpha parameter in the focal loss. + disable_custom_kernels (`bool`, *optional*, defaults to `False`): + Disable the use of custom CUDA and CPU kernels. This option is necessary for the ONNX export, as custom + kernels are not supported by PyTorch ONNX export. + + Examples: + + ```python + >>> from transformers import DeformableDetrConfig, DeformableDetrModel + + >>> # Initializing a Deformable DETR SenseTime/deformable-detr style configuration + >>> configuration = DeformableDetrConfig() + + >>> # Initializing a model (with random weights) from the SenseTime/deformable-detr style configuration + >>> model = DeformableDetrModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "deformable_detr" + attribute_map = { + "hidden_size": "d_model", + "num_attention_heads": "encoder_attention_heads", + } + + def __init__( + self, + use_timm_backbone=True, + backbone_config=None, + num_channels=3, + num_queries=300, + max_position_embeddings=1024, + encoder_layers=6, + encoder_ffn_dim=1024, + encoder_attention_heads=8, + decoder_layers=6, + decoder_ffn_dim=1024, + decoder_attention_heads=8, + encoder_layerdrop=0.0, + is_encoder_decoder=True, + activation_function="relu", + d_model=256, + dropout=0.1, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + init_xavier_std=1.0, + return_intermediate=True, + auxiliary_loss=False, + position_embedding_type="sine", + backbone="resnet50", + use_pretrained_backbone=True, + dilation=False, + num_feature_levels=4, + encoder_n_points=4, + decoder_n_points=4, + two_stage=False, + two_stage_num_proposals=300, + with_box_refine=False, + class_cost=1, + bbox_cost=5, + giou_cost=2, + mask_loss_coefficient=1, + dice_loss_coefficient=1, + bbox_loss_coefficient=5, + giou_loss_coefficient=2, + eos_coefficient=0.1, + focal_alpha=0.25, + disable_custom_kernels=False, + **kwargs, + ): + if backbone_config is not None and use_timm_backbone: + raise ValueError("You can't specify both `backbone_config` and `use_timm_backbone`.") + + if not use_timm_backbone: + if backbone_config is None: + logger.info("`backbone_config` is `None`. Initializing the config with the default `ResNet` backbone.") + backbone_config = CONFIG_MAPPING["resnet"](out_features=["stage4"]) + elif isinstance(backbone_config, dict): + backbone_model_type = backbone_config.get("model_type") + config_class = CONFIG_MAPPING[backbone_model_type] + backbone_config = config_class.from_dict(backbone_config) + self.use_timm_backbone = use_timm_backbone + self.backbone_config = backbone_config + self.num_channels = num_channels + self.num_queries = num_queries + self.max_position_embeddings = max_position_embeddings + self.d_model = d_model + self.encoder_ffn_dim = encoder_ffn_dim + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.init_xavier_std = init_xavier_std + self.encoder_layerdrop = encoder_layerdrop + self.auxiliary_loss = auxiliary_loss + self.position_embedding_type = position_embedding_type + self.backbone = backbone + self.use_pretrained_backbone = use_pretrained_backbone + self.dilation = dilation + # deformable attributes + self.num_feature_levels = num_feature_levels + self.encoder_n_points = encoder_n_points + self.decoder_n_points = decoder_n_points + self.two_stage = two_stage + self.two_stage_num_proposals = two_stage_num_proposals + self.with_box_refine = with_box_refine + if two_stage is True and with_box_refine is False: + raise ValueError("If two_stage is True, with_box_refine must be True.") + # Hungarian matcher + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + # Loss coefficients + self.mask_loss_coefficient = mask_loss_coefficient + self.dice_loss_coefficient = dice_loss_coefficient + self.bbox_loss_coefficient = bbox_loss_coefficient + self.giou_loss_coefficient = giou_loss_coefficient + self.eos_coefficient = eos_coefficient + self.focal_alpha = focal_alpha + self.disable_custom_kernels = disable_custom_kernels + super().__init__(is_encoder_decoder=is_encoder_decoder, **kwargs) + + @property + def num_attention_heads(self) -> int: + return self.encoder_attention_heads + + @property + def hidden_size(self) -> int: + return self.d_model diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/convert_deformable_detr_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/convert_deformable_detr_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..d1fd8bcbe46677ea52df67b11f809d378aeb21bf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/convert_deformable_detr_to_pytorch.py @@ -0,0 +1,237 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Deformable DETR checkpoints.""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import cached_download, hf_hub_url +from PIL import Image + +from transformers import DeformableDetrConfig, DeformableDetrFeatureExtractor, DeformableDetrForObjectDetection +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def rename_key(orig_key): + if "backbone.0.body" in orig_key: + orig_key = orig_key.replace("backbone.0.body", "backbone.conv_encoder.model") + if "transformer" in orig_key: + orig_key = orig_key.replace("transformer.", "") + if "norm1" in orig_key: + if "encoder" in orig_key: + orig_key = orig_key.replace("norm1", "self_attn_layer_norm") + else: + orig_key = orig_key.replace("norm1", "encoder_attn_layer_norm") + if "norm2" in orig_key: + if "encoder" in orig_key: + orig_key = orig_key.replace("norm2", "final_layer_norm") + else: + orig_key = orig_key.replace("norm2", "self_attn_layer_norm") + if "norm3" in orig_key: + orig_key = orig_key.replace("norm3", "final_layer_norm") + if "linear1" in orig_key: + orig_key = orig_key.replace("linear1", "fc1") + if "linear2" in orig_key: + orig_key = orig_key.replace("linear2", "fc2") + if "query_embed" in orig_key: + orig_key = orig_key.replace("query_embed", "query_position_embeddings") + if "cross_attn" in orig_key: + orig_key = orig_key.replace("cross_attn", "encoder_attn") + + return orig_key + + +def read_in_q_k_v(state_dict): + # transformer decoder self-attention layers + for i in range(6): + # read in weights + bias of input projection layer of self-attention + in_proj_weight = state_dict.pop(f"decoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"decoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"decoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :] + state_dict[f"decoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + + return im + + +@torch.no_grad() +def convert_deformable_detr_checkpoint( + checkpoint_path, + single_scale, + dilation, + with_box_refine, + two_stage, + pytorch_dump_folder_path, + push_to_hub, +): + """ + Copy/paste/tweak model's weights to our Deformable DETR structure. + """ + + # load default config + config = DeformableDetrConfig() + # set config attributes + if single_scale: + config.num_feature_levels = 1 + config.dilation = dilation + config.with_box_refine = with_box_refine + config.two_stage = two_stage + # set labels + config.num_labels = 91 + repo_id = "huggingface/label-files" + filename = "coco-detection-id2label.json" + id2label = json.load(open(cached_download(hf_hub_url(repo_id, filename, repo_type="dataset")), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + # load feature extractor + feature_extractor = DeformableDetrFeatureExtractor(format="coco_detection") + + # prepare image + img = prepare_img() + encoding = feature_extractor(images=img, return_tensors="pt") + pixel_values = encoding["pixel_values"] + + logger.info("Converting model...") + + # load original state dict + state_dict = torch.load(checkpoint_path, map_location="cpu")["model"] + # rename keys + for key in state_dict.copy().keys(): + val = state_dict.pop(key) + state_dict[rename_key(key)] = val + # query, key and value matrices need special treatment + read_in_q_k_v(state_dict) + # important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them + prefix = "model." + for key in state_dict.copy().keys(): + if not key.startswith("class_embed") and not key.startswith("bbox_embed"): + val = state_dict.pop(key) + state_dict[prefix + key] = val + # finally, create HuggingFace model and load state dict + model = DeformableDetrForObjectDetection(config) + model.load_state_dict(state_dict) + model.eval() + + device = "cuda" if torch.cuda.is_available() else "cpu" + model.to(device) + # verify our conversion + outputs = model(pixel_values.to(device)) + + expected_logits = torch.tensor( + [[-9.6645, -4.3449, -5.8705], [-9.7035, -3.8504, -5.0724], [-10.5634, -5.3379, -7.5116]] + ) + expected_boxes = torch.tensor([[0.8693, 0.2289, 0.2492], [0.3150, 0.5489, 0.5845], [0.5563, 0.7580, 0.8518]]) + + if single_scale: + expected_logits = torch.tensor( + [[-9.9051, -4.2541, -6.4852], [-9.6947, -4.0854, -6.8033], [-10.0665, -5.8470, -7.7003]] + ) + expected_boxes = torch.tensor([[0.7292, 0.4991, 0.5532], [0.7959, 0.2426, 0.4236], [0.7582, 0.3518, 0.4451]]) + + if single_scale and dilation: + expected_logits = torch.tensor( + [[-8.9652, -4.1074, -5.6635], [-9.0596, -4.9447, -6.6075], [-10.1178, -4.5275, -6.2671]] + ) + expected_boxes = torch.tensor([[0.7665, 0.4130, 0.4769], [0.8364, 0.1841, 0.3391], [0.6261, 0.3895, 0.7978]]) + + if with_box_refine: + expected_logits = torch.tensor( + [[-8.8895, -5.4187, -6.8153], [-8.4706, -6.1668, -7.6184], [-9.0042, -5.5359, -6.9141]] + ) + expected_boxes = torch.tensor([[0.7828, 0.2208, 0.4323], [0.0892, 0.5996, 0.1319], [0.5524, 0.6389, 0.8914]]) + + if with_box_refine and two_stage: + expected_logits = torch.tensor( + [[-6.7108, -4.3213, -6.3777], [-8.9014, -6.1799, -6.7240], [-6.9315, -4.4735, -6.2298]] + ) + expected_boxes = torch.tensor([[0.2583, 0.5499, 0.4683], [0.7652, 0.9068, 0.4882], [0.5490, 0.2763, 0.0564]]) + + print("Logits:", outputs.logits[0, :3, :3]) + + assert torch.allclose(outputs.logits[0, :3, :3], expected_logits.to(device), atol=1e-4) + assert torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes.to(device), atol=1e-4) + + print("Everything ok!") + + # Save model and feature extractor + logger.info(f"Saving PyTorch model and feature extractor to {pytorch_dump_folder_path}...") + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + model.save_pretrained(pytorch_dump_folder_path) + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + # Push to hub + if push_to_hub: + model_name = "deformable-detr" + model_name += "-single-scale" if single_scale else "" + model_name += "-dc5" if dilation else "" + model_name += "-with-box-refine" if with_box_refine else "" + model_name += "-two-stage" if two_stage else "" + print("Pushing model to hub...") + model.push_to_hub(repo_path_or_name=model_name, organization="nielsr", commit_message="Add model") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--checkpoint_path", + type=str, + default="/home/niels/checkpoints/deformable_detr/r50_deformable_detr-checkpoint.pth", + help="Path to Pytorch checkpoint (.pth file) you'd like to convert.", + ) + parser.add_argument("--single_scale", action="store_true", help="Whether to set config.num_features_levels = 1.") + parser.add_argument("--dilation", action="store_true", help="Whether to set config.dilation=True.") + parser.add_argument("--with_box_refine", action="store_true", help="Whether to set config.with_box_refine=True.") + parser.add_argument("--two_stage", action="store_true", help="Whether to set config.two_stage=True.") + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + type=str, + required=True, + help="Path to the folder to output PyTorch model.", + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + args = parser.parse_args() + convert_deformable_detr_checkpoint( + args.checkpoint_path, + args.single_scale, + args.dilation, + args.with_box_refine, + args.two_stage, + args.pytorch_dump_folder_path, + args.push_to_hub, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.cpp b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..388a73d22d4c9b561e2a887b50a1897b8cf2def9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.cpp @@ -0,0 +1,40 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#include + +#include +#include + + +at::Tensor +ms_deform_attn_cpu_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + AT_ERROR("Not implement on cpu"); +} + +std::vector +ms_deform_attn_cpu_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + AT_ERROR("Not implement on cpu"); +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.h new file mode 100644 index 0000000000000000000000000000000000000000..7eac8c8bcd1bf529bb9c13d54d2d4215c9e4c89f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cpu/ms_deform_attn_cpu.h @@ -0,0 +1,32 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#pragma once +#include + +at::Tensor +ms_deform_attn_cpu_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step); + +std::vector +ms_deform_attn_cpu_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step); + diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cu b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cu new file mode 100644 index 0000000000000000000000000000000000000000..8ea1d7fabe2684dbb85f00fae2c47b469687cb2c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cu @@ -0,0 +1,156 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#include +#include "cuda/ms_deform_im2col_cuda.cuh" + +#include +#include +#include +#include + +#pragma once +#include + + +at::Tensor ms_deform_attn_cuda_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto output = at::zeros({batch, num_query, num_heads, channels}, value.options()); + + const int batch_n = im2col_step_; + auto output_n = output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto columns = output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_forward_cuda", ([&] { + ms_deformable_im2col_cuda(at::cuda::getCurrentCUDAStream(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + columns.data()); + + })); + } + + output = output.view({batch, num_query, num_heads*channels}); + + return output; +} + + +std::vector ms_deform_attn_cuda_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + AT_ASSERTM(grad_output.is_contiguous(), "grad_output tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + AT_ASSERTM(grad_output.type().is_cuda(), "grad_output must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto grad_value = at::zeros_like(value); + auto grad_sampling_loc = at::zeros_like(sampling_loc); + auto grad_attn_weight = at::zeros_like(attn_weight); + + const int batch_n = im2col_step_; + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + auto grad_output_n = grad_output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto grad_output_g = grad_output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_backward_cuda", ([&] { + ms_deformable_col2im_cuda(at::cuda::getCurrentCUDAStream(), + grad_output_g.data(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + grad_value.data() + n * im2col_step_ * per_value_size, + grad_sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + grad_attn_weight.data() + n * im2col_step_ * per_attn_weight_size); + + })); + } + + return { + grad_value, grad_sampling_loc, grad_attn_weight + }; +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cuh b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cuh new file mode 100644 index 0000000000000000000000000000000000000000..34f8ae9cb77bbaa8cb4dd25e0cb86632db9ad05d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.cuh @@ -0,0 +1,1467 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#define CUDA_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; \ + i < (n); \ + i += blockDim.x * gridDim.x) + + +at::Tensor ms_deform_attn_cuda_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto output = at::zeros({batch, num_query, num_heads, channels}, value.options()); + + const int batch_n = im2col_step_; + auto output_n = output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto columns = output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_forward_cuda", ([&] { + ms_deformable_im2col_cuda(at::cuda::getCurrentCUDAStream(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + columns.data()); + + })); + } + + output = output.view({batch, num_query, num_heads*channels}); + + return output; +} + + +std::vector ms_deform_attn_cuda_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + AT_ASSERTM(grad_output.is_contiguous(), "grad_output tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + AT_ASSERTM(grad_output.type().is_cuda(), "grad_output must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto grad_value = at::zeros_like(value); + auto grad_sampling_loc = at::zeros_like(sampling_loc); + auto grad_attn_weight = at::zeros_like(attn_weight); + + const int batch_n = im2col_step_; + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + auto grad_output_n = grad_output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto grad_output_g = grad_output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_backward_cuda", ([&] { + ms_deformable_col2im_cuda(at::cuda::getCurrentCUDAStream(), + grad_output_g.data(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + grad_value.data() + n * im2col_step_ * per_value_size, + grad_sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + grad_attn_weight.data() + n * im2col_step_ * per_attn_weight_size); + + })); + } + + return { + grad_value, grad_sampling_loc, grad_attn_weight + }; +} + +const int CUDA_NUM_THREADS = 1024; +inline int GET_BLOCKS(const int N, const int num_threads) +{ + return (N + num_threads - 1) / num_threads; +} + + +template +__device__ scalar_t ms_deform_attn_im2col_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + } + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + return val; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + *grad_attn_weight = top_grad * val; + *grad_sampling_loc = width * grad_w_weight * top_grad_value; + *(grad_sampling_loc + 1) = height * grad_h_weight * top_grad_value; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear_gm(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + atomicAdd(grad_attn_weight, top_grad * val); + atomicAdd(grad_sampling_loc, width * grad_w_weight * top_grad_value); + atomicAdd(grad_sampling_loc + 1, height * grad_h_weight * top_grad_value); +} + + +template +__global__ void ms_deformable_im2col_gpu_kernel(const int n, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *data_col) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + scalar_t *data_col_ptr = data_col + index; + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + scalar_t col = 0; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const scalar_t *data_value_ptr = data_value + (data_value_ptr_init_offset + level_start_id * qid_stride); + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + col += ms_deform_attn_im2col_bilinear(data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col) * weight; + } + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + } + } + *data_col_ptr = col; + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockSize; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockSize/2; s>0; s>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockDim.x; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + atomicAdd(grad_sampling_loc, cache_grad_sampling_loc[0]); + atomicAdd(grad_sampling_loc + 1, cache_grad_sampling_loc[1]); + atomicAdd(grad_attn_weight, cache_grad_attn_weight[0]); + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_gm(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear_gm( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + grad_sampling_loc, grad_attn_weight); + } + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +void ms_deformable_im2col_cuda(cudaStream_t stream, + const scalar_t* data_value, + const int64_t* data_spatial_shapes, + const int64_t* data_level_start_index, + const scalar_t* data_sampling_loc, + const scalar_t* data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* data_col) +{ + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + const int num_threads = CUDA_NUM_THREADS; + ms_deformable_im2col_gpu_kernel + <<>>( + num_kernels, data_value, data_spatial_shapes, data_level_start_index, data_sampling_loc, data_attn_weight, + batch_size, spatial_size, num_heads, channels, num_levels, num_query, num_point, data_col); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_im2col_cuda: %s\n", cudaGetErrorString(err)); + } + +} + +template +void ms_deformable_col2im_cuda(cudaStream_t stream, + const scalar_t* grad_col, + const scalar_t* data_value, + const int64_t * data_spatial_shapes, + const int64_t * data_level_start_index, + const scalar_t * data_sampling_loc, + const scalar_t * data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int num_threads = (channels > CUDA_NUM_THREADS)?CUDA_NUM_THREADS:channels; + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + if (channels > 1024) + { + if ((channels & 1023) == 0) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_gm + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + else{ + switch(channels) + { + case 1: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 2: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 4: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 8: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 16: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 32: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 64: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 128: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 256: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 512: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 1024: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + default: + if (channels < 64) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + } + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_col2im_cuda: %s\n", cudaGetErrorString(err)); + } + +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.h new file mode 100644 index 0000000000000000000000000000000000000000..fbcf4543e66bb1162f42ce2ae57e1bac92243cb4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_attn_cuda.h @@ -0,0 +1,29 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#pragma once +#include + +at::Tensor ms_deform_attn_cuda_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step); + +std::vector ms_deform_attn_cuda_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step); diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_im2col_cuda.cuh b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_im2col_cuda.cuh new file mode 100644 index 0000000000000000000000000000000000000000..c0db0c88c9db2c09d7f601937ea0f6ac480913bf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/cuda/ms_deform_im2col_cuda.cuh @@ -0,0 +1,1327 @@ +/*! +************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************** +* Modified from DCN (https://github.com/msracver/Deformable-ConvNets) +* Copyright (c) 2018 Microsoft +************************************************************************** +*/ + +#include +#include +#include + +#include +#include + +#include + +#define CUDA_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; \ + i < (n); \ + i += blockDim.x * gridDim.x) + +const int CUDA_NUM_THREADS = 1024; +inline int GET_BLOCKS(const int N, const int num_threads) +{ + return (N + num_threads - 1) / num_threads; +} + + +template +__device__ scalar_t ms_deform_attn_im2col_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + } + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + return val; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + *grad_attn_weight = top_grad * val; + *grad_sampling_loc = width * grad_w_weight * top_grad_value; + *(grad_sampling_loc + 1) = height * grad_h_weight * top_grad_value; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear_gm(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + atomicAdd(grad_attn_weight, top_grad * val); + atomicAdd(grad_sampling_loc, width * grad_w_weight * top_grad_value); + atomicAdd(grad_sampling_loc + 1, height * grad_h_weight * top_grad_value); +} + + +template +__global__ void ms_deformable_im2col_gpu_kernel(const int n, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *data_col) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + scalar_t *data_col_ptr = data_col + index; + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + scalar_t col = 0; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const scalar_t *data_value_ptr = data_value + (data_value_ptr_init_offset + level_start_id * qid_stride); + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + col += ms_deform_attn_im2col_bilinear(data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col) * weight; + } + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + } + } + *data_col_ptr = col; + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockSize; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockSize/2; s>0; s>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockDim.x; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + atomicAdd(grad_sampling_loc, cache_grad_sampling_loc[0]); + atomicAdd(grad_sampling_loc + 1, cache_grad_sampling_loc[1]); + atomicAdd(grad_attn_weight, cache_grad_attn_weight[0]); + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_gm(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear_gm( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + grad_sampling_loc, grad_attn_weight); + } + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +void ms_deformable_im2col_cuda(cudaStream_t stream, + const scalar_t* data_value, + const int64_t* data_spatial_shapes, + const int64_t* data_level_start_index, + const scalar_t* data_sampling_loc, + const scalar_t* data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* data_col) +{ + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + const int num_threads = CUDA_NUM_THREADS; + ms_deformable_im2col_gpu_kernel + <<>>( + num_kernels, data_value, data_spatial_shapes, data_level_start_index, data_sampling_loc, data_attn_weight, + batch_size, spatial_size, num_heads, channels, num_levels, num_query, num_point, data_col); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_im2col_cuda: %s\n", cudaGetErrorString(err)); + } + +} + +template +void ms_deformable_col2im_cuda(cudaStream_t stream, + const scalar_t* grad_col, + const scalar_t* data_value, + const int64_t * data_spatial_shapes, + const int64_t * data_level_start_index, + const scalar_t * data_sampling_loc, + const scalar_t * data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int num_threads = (channels > CUDA_NUM_THREADS)?CUDA_NUM_THREADS:channels; + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + if (channels > 1024) + { + if ((channels & 1023) == 0) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_gm + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + else{ + switch(channels) + { + case 1: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 2: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 4: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 8: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 16: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 32: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 64: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 128: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 256: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 512: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 1024: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + default: + if (channels < 64) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + } + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_col2im_cuda: %s\n", cudaGetErrorString(err)); + } + +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/ms_deform_attn.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/ms_deform_attn.h new file mode 100644 index 0000000000000000000000000000000000000000..119b1fa317d1e5fcfb61a4837e560e9248db05f3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/ms_deform_attn.h @@ -0,0 +1,61 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#pragma once + +#include "cpu/ms_deform_attn_cpu.h" + +#ifdef WITH_CUDA +#include "cuda/ms_deform_attn_cuda.h" +#endif + + +at::Tensor +ms_deform_attn_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + if (value.type().is_cuda()) + { +#ifdef WITH_CUDA + return ms_deform_attn_cuda_forward( + value, spatial_shapes, level_start_index, sampling_loc, attn_weight, im2col_step); +#else + AT_ERROR("Not compiled with GPU support"); +#endif + } + AT_ERROR("Not implemented on the CPU"); +} + +std::vector +ms_deform_attn_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + if (value.type().is_cuda()) + { +#ifdef WITH_CUDA + return ms_deform_attn_cuda_backward( + value, spatial_shapes, level_start_index, sampling_loc, attn_weight, grad_output, im2col_step); +#else + AT_ERROR("Not compiled with GPU support"); +#endif + } + AT_ERROR("Not implemented on the CPU"); +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/vision.cpp b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/vision.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ce3875568b9ba8d660c90acc805077cca98f891 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/custom_kernel/vision.cpp @@ -0,0 +1,16 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +#include "ms_deform_attn.h" + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def("ms_deform_attn_forward", &ms_deform_attn_forward, "ms_deform_attn_forward"); + m.def("ms_deform_attn_backward", &ms_deform_attn_backward, "ms_deform_attn_backward"); +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/feature_extraction_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/feature_extraction_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..6f1ca003a007340afd16d70642532e338e4e8178 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/feature_extraction_deformable_detr.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for Deformable DETR.""" + +import warnings + +from ...utils import logging +from .image_processing_deformable_detr import DeformableDetrImageProcessor + + +logger = logging.get_logger(__name__) + + +class DeformableDetrFeatureExtractor(DeformableDetrImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class DeformableDetrFeatureExtractor is deprecated and will be removed in version 5 of Transformers." + " Please use DeformableDetrImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/image_processing_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/image_processing_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..35a18e23edb389c38c8634fb8175c2e203d1815e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/image_processing_deformable_detr.py @@ -0,0 +1,1379 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for Deformable DETR.""" + +import io +import pathlib +from collections import defaultdict +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union + +import numpy as np + +from ...feature_extraction_utils import BatchFeature +from ...image_processing_utils import BaseImageProcessor, get_size_dict +from ...image_transforms import ( + PaddingMode, + center_to_corners_format, + corners_to_center_format, + id_to_rgb, + normalize, + pad, + rescale, + resize, + rgb_to_id, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_DEFAULT_MEAN, + IMAGENET_DEFAULT_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + get_image_size, + infer_channel_dimension_format, + make_list_of_images, + to_numpy_array, + valid_coco_detection_annotations, + valid_coco_panoptic_annotations, + valid_images, +) +from ...utils import ( + ExplicitEnum, + TensorType, + is_flax_available, + is_jax_tensor, + is_scipy_available, + is_tf_available, + is_tf_tensor, + is_torch_available, + is_torch_tensor, + is_vision_available, + logging, +) + + +if is_torch_available(): + import torch + from torch import nn + + +if is_vision_available(): + import PIL + +if is_scipy_available(): + import scipy.special + import scipy.stats + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +AnnotationType = Dict[str, Union[int, str, List[Dict]]] + + +class AnnotionFormat(ExplicitEnum): + COCO_DETECTION = "coco_detection" + COCO_PANOPTIC = "coco_panoptic" + + +SUPPORTED_ANNOTATION_FORMATS = (AnnotionFormat.COCO_DETECTION, AnnotionFormat.COCO_PANOPTIC) + + +# Copied from transformers.models.detr.image_processing_detr.get_size_with_aspect_ratio +def get_size_with_aspect_ratio(image_size, size, max_size=None) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + height, width = image_size + if max_size is not None: + min_original_size = float(min((height, width))) + max_original_size = float(max((height, width))) + if max_original_size / min_original_size * size > max_size: + size = int(round(max_size * min_original_size / max_original_size)) + + if (height <= width and height == size) or (width <= height and width == size): + return height, width + + if width < height: + ow = size + oh = int(size * height / width) + else: + oh = size + ow = int(size * width / height) + return (oh, ow) + + +# Copied from transformers.models.detr.image_processing_detr.get_resize_output_image_size +def get_resize_output_image_size( + input_image: np.ndarray, size: Union[int, Tuple[int, int], List[int]], max_size: Optional[int] = None +) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. If the desired output size + is a tuple or list, the output image size is returned as is. If the desired output size is an integer, the output + image size is computed by keeping the aspect ratio of the input image size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + image_size = get_image_size(input_image) + if isinstance(size, (list, tuple)): + return size + + return get_size_with_aspect_ratio(image_size, size, max_size) + + +# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn +def get_numpy_to_framework_fn(arr) -> Callable: + """ + Returns a function that converts a numpy array to the framework of the input array. + + Args: + arr (`np.ndarray`): The array to convert. + """ + if isinstance(arr, np.ndarray): + return np.array + if is_tf_available() and is_tf_tensor(arr): + import tensorflow as tf + + return tf.convert_to_tensor + if is_torch_available() and is_torch_tensor(arr): + import torch + + return torch.tensor + if is_flax_available() and is_jax_tensor(arr): + import jax.numpy as jnp + + return jnp.array + raise ValueError(f"Cannot convert arrays of type {type(arr)}") + + +# Copied from transformers.models.detr.image_processing_detr.safe_squeeze +def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: + """ + Squeezes an array, but only if the axis specified has dim 1. + """ + if axis is None: + return arr.squeeze() + + try: + return arr.squeeze(axis=axis) + except ValueError: + return arr + + +# Copied from transformers.models.detr.image_processing_detr.normalize_annotation +def normalize_annotation(annotation: Dict, image_size: Tuple[int, int]) -> Dict: + image_height, image_width = image_size + norm_annotation = {} + for key, value in annotation.items(): + if key == "boxes": + boxes = value + boxes = corners_to_center_format(boxes) + boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32) + norm_annotation[key] = boxes + else: + norm_annotation[key] = value + return norm_annotation + + +# Copied from transformers.models.detr.image_processing_detr.max_across_indices +def max_across_indices(values: Iterable[Any]) -> List[Any]: + """ + Return the maximum value across all indices of an iterable of values. + """ + return [max(values_i) for values_i in zip(*values)] + + +# Copied from transformers.models.detr.image_processing_detr.get_max_height_width +def get_max_height_width(images: List[np.ndarray]) -> List[int]: + """ + Get the maximum height and width across all images in a batch. + """ + input_channel_dimension = infer_channel_dimension_format(images[0]) + + if input_channel_dimension == ChannelDimension.FIRST: + _, max_height, max_width = max_across_indices([img.shape for img in images]) + elif input_channel_dimension == ChannelDimension.LAST: + max_height, max_width, _ = max_across_indices([img.shape for img in images]) + else: + raise ValueError(f"Invalid channel dimension format: {input_channel_dimension}") + return (max_height, max_width) + + +# Copied from transformers.models.detr.image_processing_detr.make_pixel_mask +def make_pixel_mask(image: np.ndarray, output_size: Tuple[int, int]) -> np.ndarray: + """ + Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding. + + Args: + image (`np.ndarray`): + Image to make the pixel mask for. + output_size (`Tuple[int, int]`): + Output size of the mask. + """ + input_height, input_width = get_image_size(image) + mask = np.zeros(output_size, dtype=np.int64) + mask[:input_height, :input_width] = 1 + return mask + + +# Copied from transformers.models.detr.image_processing_detr.convert_coco_poly_to_mask +def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray: + """ + Convert a COCO polygon annotation to a mask. + + Args: + segmentations (`List[List[float]]`): + List of polygons, each polygon represented by a list of x-y coordinates. + height (`int`): + Height of the mask. + width (`int`): + Width of the mask. + """ + try: + from pycocotools import mask as coco_mask + except ImportError: + raise ImportError("Pycocotools is not installed in your environment.") + + masks = [] + for polygons in segmentations: + rles = coco_mask.frPyObjects(polygons, height, width) + mask = coco_mask.decode(rles) + if len(mask.shape) < 3: + mask = mask[..., None] + mask = np.asarray(mask, dtype=np.uint8) + mask = np.any(mask, axis=2) + masks.append(mask) + if masks: + masks = np.stack(masks, axis=0) + else: + masks = np.zeros((0, height, width), dtype=np.uint8) + + return masks + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_detection_annotation with DETR->DeformableDetr +def prepare_coco_detection_annotation(image, target, return_segmentation_masks: bool = False): + """ + Convert the target in COCO format into the format expected by DeformableDetr. + """ + image_height, image_width = get_image_size(image) + + image_id = target["image_id"] + image_id = np.asarray([image_id], dtype=np.int64) + + # Get all COCO annotations for the given image. + annotations = target["annotations"] + annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0] + + classes = [obj["category_id"] for obj in annotations] + classes = np.asarray(classes, dtype=np.int64) + + # for conversion to coco api + area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32) + iscrowd = np.asarray([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in annotations], dtype=np.int64) + + boxes = [obj["bbox"] for obj in annotations] + # guard against no boxes via resizing + boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4) + boxes[:, 2:] += boxes[:, :2] + boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width) + boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height) + + keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0]) + + new_target = {} + new_target["image_id"] = image_id + new_target["class_labels"] = classes[keep] + new_target["boxes"] = boxes[keep] + new_target["area"] = area[keep] + new_target["iscrowd"] = iscrowd[keep] + new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64) + + if annotations and "keypoints" in annotations[0]: + keypoints = [obj["keypoints"] for obj in annotations] + keypoints = np.asarray(keypoints, dtype=np.float32) + num_keypoints = keypoints.shape[0] + keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints + new_target["keypoints"] = keypoints[keep] + + if return_segmentation_masks: + segmentation_masks = [obj["segmentation"] for obj in annotations] + masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width) + new_target["masks"] = masks[keep] + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.masks_to_boxes +def masks_to_boxes(masks: np.ndarray) -> np.ndarray: + """ + Compute the bounding boxes around the provided panoptic segmentation masks. + + Args: + masks: masks in format `[number_masks, height, width]` where N is the number of masks + + Returns: + boxes: bounding boxes in format `[number_masks, 4]` in xyxy format + """ + if masks.size == 0: + return np.zeros((0, 4)) + + h, w = masks.shape[-2:] + y = np.arange(0, h, dtype=np.float32) + x = np.arange(0, w, dtype=np.float32) + # see https://github.com/pytorch/pytorch/issues/50276 + y, x = np.meshgrid(y, x, indexing="ij") + + x_mask = masks * np.expand_dims(x, axis=0) + x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1) + x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool))) + x_min = x.filled(fill_value=1e8) + x_min = x_min.reshape(x_min.shape[0], -1).min(-1) + + y_mask = masks * np.expand_dims(y, axis=0) + y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1) + y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool))) + y_min = y.filled(fill_value=1e8) + y_min = y_min.reshape(y_min.shape[0], -1).min(-1) + + return np.stack([x_min, y_min, x_max, y_max], 1) + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_panoptic_annotation with DETR->DeformableDetr +def prepare_coco_panoptic_annotation( + image: np.ndarray, target: Dict, masks_path: Union[str, pathlib.Path], return_masks: bool = True +) -> Dict: + """ + Prepare a coco panoptic annotation for DeformableDetr. + """ + image_height, image_width = get_image_size(image) + annotation_path = pathlib.Path(masks_path) / target["file_name"] + + new_target = {} + new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64) + new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64) + new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64) + + if "segments_info" in target: + masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32) + masks = rgb_to_id(masks) + + ids = np.array([segment_info["id"] for segment_info in target["segments_info"]]) + masks = masks == ids[:, None, None] + masks = masks.astype(np.uint8) + if return_masks: + new_target["masks"] = masks + new_target["boxes"] = masks_to_boxes(masks) + new_target["class_labels"] = np.array( + [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["iscrowd"] = np.asarray( + [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["area"] = np.asarray( + [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32 + ) + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.get_segmentation_image +def get_segmentation_image( + masks: np.ndarray, input_size: Tuple, target_size: Tuple, stuff_equiv_classes, deduplicate=False +): + h, w = input_size + final_h, final_w = target_size + + m_id = scipy.special.softmax(masks.transpose(0, 1), -1) + + if m_id.shape[-1] == 0: + # We didn't detect any mask :( + m_id = np.zeros((h, w), dtype=np.int64) + else: + m_id = m_id.argmax(-1).reshape(h, w) + + if deduplicate: + # Merge the masks corresponding to the same stuff class + for equiv in stuff_equiv_classes.values(): + for eq_id in equiv: + m_id[m_id == eq_id] = equiv[0] + + seg_img = id_to_rgb(m_id) + seg_img = resize(seg_img, (final_w, final_h), resample=PILImageResampling.NEAREST) + return seg_img + + +# Copied from transformers.models.detr.image_processing_detr.get_mask_area +def get_mask_area(seg_img: np.ndarray, target_size: Tuple[int, int], n_classes: int) -> np.ndarray: + final_h, final_w = target_size + np_seg_img = seg_img.astype(np.uint8) + np_seg_img = np_seg_img.reshape(final_h, final_w, 3) + m_id = rgb_to_id(np_seg_img) + area = [(m_id == i).sum() for i in range(n_classes)] + return area + + +# Copied from transformers.models.detr.image_processing_detr.score_labels_from_class_probabilities +def score_labels_from_class_probabilities(logits: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + probs = scipy.special.softmax(logits, axis=-1) + labels = probs.argmax(-1, keepdims=True) + scores = np.take_along_axis(probs, labels, axis=-1) + scores, labels = scores.squeeze(-1), labels.squeeze(-1) + return scores, labels + + +# Copied from transformers.models.detr.image_processing_detr.post_process_panoptic_sample +def post_process_panoptic_sample( + out_logits: np.ndarray, + masks: np.ndarray, + boxes: np.ndarray, + processed_size: Tuple[int, int], + target_size: Tuple[int, int], + is_thing_map: Dict, + threshold=0.85, +) -> Dict: + """ + Converts the output of [`DetrForSegmentation`] into panoptic segmentation predictions for a single sample. + + Args: + out_logits (`torch.Tensor`): + The logits for this sample. + masks (`torch.Tensor`): + The predicted segmentation masks for this sample. + boxes (`torch.Tensor`): + The prediced bounding boxes for this sample. The boxes are in the normalized format `(center_x, center_y, + width, height)` and values between `[0, 1]`, relative to the size the image (disregarding padding). + processed_size (`Tuple[int, int]`): + The processed size of the image `(height, width)`, as returned by the preprocessing step i.e. the size + after data augmentation but before batching. + target_size (`Tuple[int, int]`): + The target size of the image, `(height, width)` corresponding to the requested final size of the + prediction. + is_thing_map (`Dict`): + A dictionary mapping class indices to a boolean value indicating whether the class is a thing or not. + threshold (`float`, *optional*, defaults to 0.85): + The threshold used to binarize the segmentation masks. + """ + # we filter empty queries and detection below threshold + scores, labels = score_labels_from_class_probabilities(out_logits) + keep = (labels != out_logits.shape[-1] - 1) & (scores > threshold) + + cur_scores = scores[keep] + cur_classes = labels[keep] + cur_boxes = center_to_corners_format(boxes[keep]) + + if len(cur_boxes) != len(cur_classes): + raise ValueError("Not as many boxes as there are classes") + + cur_masks = masks[keep] + cur_masks = resize(cur_masks[:, None], processed_size, resample=PILImageResampling.BILINEAR) + cur_masks = safe_squeeze(cur_masks, 1) + b, h, w = cur_masks.shape + + # It may be that we have several predicted masks for the same stuff class. + # In the following, we track the list of masks ids for each stuff class (they are merged later on) + cur_masks = cur_masks.reshape(b, -1) + stuff_equiv_classes = defaultdict(list) + for k, label in enumerate(cur_classes): + if not is_thing_map[label]: + stuff_equiv_classes[label].append(k) + + seg_img = get_segmentation_image(cur_masks, processed_size, target_size, stuff_equiv_classes, deduplicate=True) + area = get_mask_area(cur_masks, processed_size, n_classes=len(cur_scores)) + + # We filter out any mask that is too small + if cur_classes.size() > 0: + # We know filter empty masks as long as we find some + filtered_small = np.array([a <= 4 for a in area], dtype=bool) + while filtered_small.any(): + cur_masks = cur_masks[~filtered_small] + cur_scores = cur_scores[~filtered_small] + cur_classes = cur_classes[~filtered_small] + seg_img = get_segmentation_image(cur_masks, (h, w), target_size, stuff_equiv_classes, deduplicate=True) + area = get_mask_area(seg_img, target_size, n_classes=len(cur_scores)) + filtered_small = np.array([a <= 4 for a in area], dtype=bool) + else: + cur_classes = np.ones((1, 1), dtype=np.int64) + + segments_info = [ + {"id": i, "isthing": is_thing_map[cat], "category_id": int(cat), "area": a} + for i, (cat, a) in enumerate(zip(cur_classes, area)) + ] + del cur_classes + + with io.BytesIO() as out: + PIL.Image.fromarray(seg_img).save(out, format="PNG") + predictions = {"png_string": out.getvalue(), "segments_info": segments_info} + + return predictions + + +# Copied from transformers.models.detr.image_processing_detr.resize_annotation +def resize_annotation( + annotation: Dict[str, Any], + orig_size: Tuple[int, int], + target_size: Tuple[int, int], + threshold: float = 0.5, + resample: PILImageResampling = PILImageResampling.NEAREST, +): + """ + Resizes an annotation to a target size. + + Args: + annotation (`Dict[str, Any]`): + The annotation dictionary. + orig_size (`Tuple[int, int]`): + The original size of the input image. + target_size (`Tuple[int, int]`): + The target size of the image, as returned by the preprocessing `resize` step. + threshold (`float`, *optional*, defaults to 0.5): + The threshold used to binarize the segmentation masks. + resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`): + The resampling filter to use when resizing the masks. + """ + ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size)) + ratio_height, ratio_width = ratios + + new_annotation = {} + new_annotation["size"] = target_size + + for key, value in annotation.items(): + if key == "boxes": + boxes = value + scaled_boxes = boxes * np.asarray([ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32) + new_annotation["boxes"] = scaled_boxes + elif key == "area": + area = value + scaled_area = area * (ratio_width * ratio_height) + new_annotation["area"] = scaled_area + elif key == "masks": + masks = value[:, None] + masks = np.array([resize(mask, target_size, resample=resample) for mask in masks]) + masks = masks.astype(np.float32) + masks = masks[:, 0] > threshold + new_annotation["masks"] = masks + elif key == "size": + new_annotation["size"] = target_size + else: + new_annotation[key] = value + + return new_annotation + + +# Copied from transformers.models.detr.image_processing_detr.binary_mask_to_rle +def binary_mask_to_rle(mask): + """ + Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + mask (`torch.Tensor` or `numpy.array`): + A binary mask tensor of shape `(height, width)` where 0 denotes background and 1 denotes the target + segment_id or class_id. + Returns: + `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE + format. + """ + if is_torch_tensor(mask): + mask = mask.numpy() + + pixels = mask.flatten() + pixels = np.concatenate([[0], pixels, [0]]) + runs = np.where(pixels[1:] != pixels[:-1])[0] + 1 + runs[1::2] -= runs[::2] + return list(runs) + + +# Copied from transformers.models.detr.image_processing_detr.convert_segmentation_to_rle +def convert_segmentation_to_rle(segmentation): + """ + Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + segmentation (`torch.Tensor` or `numpy.array`): + A segmentation map of shape `(height, width)` where each value denotes a segment or class id. + Returns: + `List[List]`: A list of lists, where each list is the run-length encoding of a segment / class id. + """ + segment_ids = torch.unique(segmentation) + + run_length_encodings = [] + for idx in segment_ids: + mask = torch.where(segmentation == idx, 1, 0) + rle = binary_mask_to_rle(mask) + run_length_encodings.append(rle) + + return run_length_encodings + + +# Copied from transformers.models.detr.image_processing_detr.remove_low_and_no_objects +def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels): + """ + Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and + `labels`. + + Args: + masks (`torch.Tensor`): + A tensor of shape `(num_queries, height, width)`. + scores (`torch.Tensor`): + A tensor of shape `(num_queries)`. + labels (`torch.Tensor`): + A tensor of shape `(num_queries)`. + object_mask_threshold (`float`): + A number between 0 and 1 used to binarize the masks. + Raises: + `ValueError`: Raised when the first dimension doesn't match in all input tensors. + Returns: + `Tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region + < `object_mask_threshold`. + """ + if not (masks.shape[0] == scores.shape[0] == labels.shape[0]): + raise ValueError("mask, scores and labels must have the same shape!") + + to_keep = labels.ne(num_labels) & (scores > object_mask_threshold) + + return masks[to_keep], scores[to_keep], labels[to_keep] + + +# Copied from transformers.models.detr.image_processing_detr.check_segment_validity +def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8): + # Get the mask associated with the k class + mask_k = mask_labels == k + mask_k_area = mask_k.sum() + + # Compute the area of all the stuff in query k + original_area = (mask_probs[k] >= mask_threshold).sum() + mask_exists = mask_k_area > 0 and original_area > 0 + + # Eliminate disconnected tiny segments + if mask_exists: + area_ratio = mask_k_area / original_area + if not area_ratio.item() > overlap_mask_area_threshold: + mask_exists = False + + return mask_exists, mask_k + + +# Copied from transformers.models.detr.image_processing_detr.compute_segments +def compute_segments( + mask_probs, + pred_scores, + pred_labels, + mask_threshold: float = 0.5, + overlap_mask_area_threshold: float = 0.8, + label_ids_to_fuse: Optional[Set[int]] = None, + target_size: Tuple[int, int] = None, +): + height = mask_probs.shape[1] if target_size is None else target_size[0] + width = mask_probs.shape[2] if target_size is None else target_size[1] + + segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device) + segments: List[Dict] = [] + + if target_size is not None: + mask_probs = nn.functional.interpolate( + mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False + )[0] + + current_segment_id = 0 + + # Weigh each mask by its prediction score + mask_probs *= pred_scores.view(-1, 1, 1) + mask_labels = mask_probs.argmax(0) # [height, width] + + # Keep track of instances of each class + stuff_memory_list: Dict[str, int] = {} + for k in range(pred_labels.shape[0]): + pred_class = pred_labels[k].item() + should_fuse = pred_class in label_ids_to_fuse + + # Check if mask exists and large enough to be a segment + mask_exists, mask_k = check_segment_validity( + mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold + ) + + if mask_exists: + if pred_class in stuff_memory_list: + current_segment_id = stuff_memory_list[pred_class] + else: + current_segment_id += 1 + + # Add current object segment to final segmentation map + segmentation[mask_k] = current_segment_id + segment_score = round(pred_scores[k].item(), 6) + segments.append( + { + "id": current_segment_id, + "label_id": pred_class, + "was_fused": should_fuse, + "score": segment_score, + } + ) + if should_fuse: + stuff_memory_list[pred_class] = current_segment_id + + return segmentation, segments + + +class DeformableDetrImageProcessor(BaseImageProcessor): + r""" + Constructs a Deformable DETR image processor. + + Args: + format (`str`, *optional*, defaults to `"coco_detection"`): + Data format of the annotations. One of "coco_detection" or "coco_panoptic". + do_resize (`bool`, *optional*, defaults to `True`): + Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be + overridden by the `do_resize` parameter in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 800, "longest_edge": 1333}`): + Size of the image's (height, width) dimensions after resizing. Can be overridden by the `size` parameter in + the `preprocess` method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. + do_rescale (`bool`, *optional*, defaults to `True`): + Controls whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the + `do_rescale` parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize: + Controls whether to normalize the image. Can be overridden by the `do_normalize` parameter in the + `preprocess` method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_MEAN`): + Mean values to use when normalizing the image. Can be a single value or a list of values, one for each + channel. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_STD`): + Standard deviation values to use when normalizing the image. Can be a single value or a list of values, one + for each channel. Can be overridden by the `image_std` parameter in the `preprocess` method. + do_pad (`bool`, *optional*, defaults to `True`): + Controls whether to pad the image to the largest image in a batch and create a pixel mask. Can be + overridden by the `do_pad` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values", "pixel_mask"] + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.__init__ + def __init__( + self, + format: Union[str, AnnotionFormat] = AnnotionFormat.COCO_DETECTION, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Union[float, List[float]] = None, + image_std: Union[float, List[float]] = None, + do_pad: bool = True, + **kwargs, + ) -> None: + if "pad_and_return_pixel_mask" in kwargs: + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None if size is None else 1333 + + size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333} + size = get_size_dict(size, max_size=max_size, default_to_square=False) + + super().__init__(**kwargs) + self.format = format + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_DEFAULT_STD + self.do_pad = do_pad + + @property + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.max_size + def max_size(self): + logger.warning( + "The `max_size` parameter is deprecated and will be removed in v4.27. " + "Please specify in `size['longest_edge'] instead`.", + ) + return self.size["longest_edge"] + + @classmethod + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.from_dict with Detr->DeformableDetr + def from_dict(cls, image_processor_dict: Dict[str, Any], **kwargs): + """ + Overrides the `from_dict` method from the base class to make sure parameters are updated if image processor is + created using from_dict and kwargs e.g. `DeformableDetrImageProcessor.from_pretrained(checkpoint, size=600, + max_size=800)` + """ + image_processor_dict = image_processor_dict.copy() + if "max_size" in kwargs: + image_processor_dict["max_size"] = kwargs.pop("max_size") + if "pad_and_return_pixel_mask" in kwargs: + image_processor_dict["pad_and_return_pixel_mask"] = kwargs.pop("pad_and_return_pixel_mask") + return super().from_dict(image_processor_dict, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_annotation with DETR->DeformableDetr + def prepare_annotation( + self, + image: np.ndarray, + target: Dict, + format: Optional[AnnotionFormat] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + ) -> Dict: + """ + Prepare an annotation for feeding into DeformableDetr model. + """ + format = format if format is not None else self.format + + if format == AnnotionFormat.COCO_DETECTION: + return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_detection_annotation(image, target, return_segmentation_masks) + elif format == AnnotionFormat.COCO_PANOPTIC: + return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_panoptic_annotation( + image, target, masks_path=masks_path, return_masks=return_segmentation_masks + ) + else: + raise ValueError(f"Format {format} is not supported.") + return target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare + def prepare(self, image, target, return_segmentation_masks=None, masks_path=None): + logger.warning_once( + "The `prepare` method is deprecated and will be removed in a future version. " + "Please use `prepare_annotation` instead. Note: the `prepare_annotation` method " + "does not return the image anymore.", + ) + target = self.prepare_annotation(image, target, return_segmentation_masks, masks_path, self.format) + return image, target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.convert_coco_poly_to_mask + def convert_coco_poly_to_mask(self, *args, **kwargs): + logger.warning_once( + "The `convert_coco_poly_to_mask` method is deprecated and will be removed in a future version. " + ) + return convert_coco_poly_to_mask(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_detection + def prepare_coco_detection(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_detection` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_detection_annotation(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_panoptic + def prepare_coco_panoptic(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_panoptic` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_panoptic_annotation(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.resize + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BILINEAR, + data_format: Optional[ChannelDimension] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an + int, smaller edge of the image will be matched to this number. + """ + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None + size = get_size_dict(size, max_size=max_size, default_to_square=False) + if "shortest_edge" in size and "longest_edge" in size: + size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"]) + elif "height" in size and "width" in size: + size = (size["height"], size["width"]) + else: + raise ValueError( + "Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got" + f" {size.keys()}." + ) + image = resize(image, size=size, resample=resample, data_format=data_format) + return image + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.resize_annotation + def resize_annotation( + self, + annotation, + orig_size, + size, + resample: PILImageResampling = PILImageResampling.NEAREST, + ) -> Dict: + """ + Resize the annotation to match the resized image. If size is an int, smaller edge of the mask will be matched + to this number. + """ + return resize_annotation(annotation, orig_size=orig_size, target_size=size, resample=resample) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.rescale + def rescale( + self, image: np.ndarray, rescale_factor: Union[float, int], data_format: Optional[ChannelDimension] = None + ) -> np.ndarray: + """ + Rescale the image by the given factor. + """ + return rescale(image, rescale_factor, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize + def normalize( + self, + image: np.ndarray, + mean: Union[float, Iterable[float]], + std: Union[float, Iterable[float]], + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Normalize the image with the given mean and standard deviation. + """ + return normalize(image, mean=mean, std=std, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize_annotation + def normalize_annotation(self, annotation: Dict, image_size: Tuple[int, int]) -> Dict: + """ + Normalize the boxes in the annotation from `[top_left_x, top_left_y, bottom_right_x, bottom_right_y]` to + `[center_x, center_y, width, height]` format. + """ + return normalize_annotation(annotation, image_size=image_size) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.pad_and_create_pixel_mask + def pad_and_create_pixel_mask( + self, + pixel_values_list: List[ImageInput], + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> BatchFeature: + """ + Pads a batch of images with zeros to the size of largest height and width in the batch and returns their + corresponding pixel mask. + + Args: + images (`List[np.ndarray]`): + Batch of images to pad. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + logger.warning_once("This method is deprecated and will be removed in v4.27.0. Please use pad instead.") + # pad expects a list of np.ndarray, but the previous feature extractors expected torch tensors + images = [to_numpy_array(image) for image in pixel_values_list] + return self.pad( + images=images, + return_pixel_mask=True, + return_tensors=return_tensors, + data_format=data_format, + ) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor._pad_image + def _pad_image( + self, + image: np.ndarray, + output_size: Tuple[int, int], + constant_values: Union[float, Iterable[float]] = 0, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pad an image with zeros to the given size. + """ + input_height, input_width = get_image_size(image) + output_height, output_width = output_size + + pad_bottom = output_height - input_height + pad_right = output_width - input_width + padding = ((0, pad_bottom), (0, pad_right)) + padded_image = pad( + image, padding, mode=PaddingMode.CONSTANT, constant_values=constant_values, data_format=data_format + ) + return padded_image + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.pad + def pad( + self, + images: List[np.ndarray], + constant_values: Union[float, Iterable[float]] = 0, + return_pixel_mask: bool = True, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pads a batch of images to the bottom and right of the image with zeros to the size of largest height and width + in the batch and optionally returns their corresponding pixel mask. + + Args: + image (`np.ndarray`): + Image to pad. + constant_values (`float` or `Iterable[float]`, *optional*): + The value to use for the padding if `mode` is `"constant"`. + return_pixel_mask (`bool`, *optional*, defaults to `True`): + Whether to return a pixel mask. + input_channel_dimension (`ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be inferred from the input image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + pad_size = get_max_height_width(images) + + padded_images = [ + self._pad_image(image, pad_size, constant_values=constant_values, data_format=data_format) + for image in images + ] + data = {"pixel_values": padded_images} + + if return_pixel_mask: + masks = [make_pixel_mask(image=image, output_size=pad_size) for image in images] + data["pixel_mask"] = masks + + return BatchFeature(data=data, tensor_type=return_tensors) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.preprocess + def preprocess( + self, + images: ImageInput, + annotations: Optional[Union[AnnotationType, List[AnnotationType]]] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + do_resize: Optional[bool] = None, + size: Optional[Dict[str, int]] = None, + resample=None, # PILImageResampling + do_rescale: Optional[bool] = None, + rescale_factor: Optional[Union[int, float]] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_pad: Optional[bool] = None, + format: Optional[Union[str, AnnotionFormat]] = None, + return_tensors: Optional[Union[TensorType, str]] = None, + data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> BatchFeature: + """ + Preprocess an image or a batch of images so that it can be used by the model. + + Args: + images (`ImageInput`): + Image or batch of images to preprocess. + annotations (`AnnotationType` or `List[AnnotationType]`, *optional*): + List of annotations associated with the image or batch of images. If annotation is for object + detection, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "annotations" (`List[Dict]`): List of annotations for an image. Each annotation should be a + dictionary. An image can have no annotations, in which case the list should be empty. + If annotation is for segmentation, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "segments_info" (`List[Dict]`): List of segments for an image. Each segment should be a dictionary. + An image can have no segments, in which case the list should be empty. + - "file_name" (`str`): The file name of the image. + return_segmentation_masks (`bool`, *optional*, defaults to self.return_segmentation_masks): + Whether to return segmentation masks. + masks_path (`str` or `pathlib.Path`, *optional*): + Path to the directory containing the segmentation masks. + do_resize (`bool`, *optional*, defaults to self.do_resize): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to self.size): + Size of the image after resizing. + resample (`PILImageResampling`, *optional*, defaults to self.resample): + Resampling filter to use when resizing the image. + do_rescale (`bool`, *optional*, defaults to self.do_rescale): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to self.rescale_factor): + Rescale factor to use when rescaling the image. + do_normalize (`bool`, *optional*, defaults to self.do_normalize): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to self.image_mean): + Mean to use when normalizing the image. + image_std (`float` or `List[float]`, *optional*, defaults to self.image_std): + Standard deviation to use when normalizing the image. + do_pad (`bool`, *optional*, defaults to self.do_pad): + Whether to pad the image. + format (`str` or `AnnotionFormat`, *optional*, defaults to self.format): + Format of the annotations. + return_tensors (`str` or `TensorType`, *optional*, defaults to self.return_tensors): + Type of tensors to return. If `None`, will return the list of images. + data_format (`str` or `ChannelDimension`, *optional*, defaults to self.data_format): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + if "pad_and_return_pixel_mask" in kwargs: + logger.warning_once( + "The `pad_and_return_pixel_mask` argument is deprecated and will be removed in a future version, " + "use `do_pad` instead." + ) + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + max_size = None + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` argument is deprecated and will be removed in a future version, use" + " `size['longest_edge']` instead." + ) + size = kwargs.pop("max_size") + + do_resize = self.do_resize if do_resize is None else do_resize + size = self.size if size is None else size + size = get_size_dict(size=size, max_size=max_size, default_to_square=False) + resample = self.resample if resample is None else resample + do_rescale = self.do_rescale if do_rescale is None else do_rescale + rescale_factor = self.rescale_factor if rescale_factor is None else rescale_factor + do_normalize = self.do_normalize if do_normalize is None else do_normalize + image_mean = self.image_mean if image_mean is None else image_mean + image_std = self.image_std if image_std is None else image_std + do_pad = self.do_pad if do_pad is None else do_pad + format = self.format if format is None else format + + if do_resize is not None and size is None: + raise ValueError("Size and max_size must be specified if do_resize is True.") + + if do_rescale is not None and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize is not None and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + images = make_list_of_images(images) + if annotations is not None and isinstance(annotations, dict): + annotations = [annotations] + + if annotations is not None and len(images) != len(annotations): + raise ValueError( + f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match." + ) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + format = AnnotionFormat(format) + if annotations is not None: + if format == AnnotionFormat.COCO_DETECTION and not valid_coco_detection_annotations(annotations): + raise ValueError( + "Invalid COCO detection annotations. Annotations must a dict (single image) of list of dicts" + "(batch of images) with the following keys: `image_id` and `annotations`, with the latter " + "being a list of annotations in the COCO format." + ) + elif format == AnnotionFormat.COCO_PANOPTIC and not valid_coco_panoptic_annotations(annotations): + raise ValueError( + "Invalid COCO panoptic annotations. Annotations must a dict (single image) of list of dicts " + "(batch of images) with the following keys: `image_id`, `file_name` and `segments_info`, with " + "the latter being a list of annotations in the COCO format." + ) + elif format not in SUPPORTED_ANNOTATION_FORMATS: + raise ValueError( + f"Unsupported annotation format: {format} must be one of {SUPPORTED_ANNOTATION_FORMATS}" + ) + + if ( + masks_path is not None + and format == AnnotionFormat.COCO_PANOPTIC + and not isinstance(masks_path, (pathlib.Path, str)) + ): + raise ValueError( + "The path to the directory containing the mask PNG files should be provided as a" + f" `pathlib.Path` or string object, but is {type(masks_path)} instead." + ) + + # All transformations expect numpy arrays + images = [to_numpy_array(image) for image in images] + + # prepare (COCO annotations as a list of Dict -> DETR target as a single Dict per image) + if annotations is not None: + prepared_images = [] + prepared_annotations = [] + for image, target in zip(images, annotations): + target = self.prepare_annotation( + image, target, format, return_segmentation_masks=return_segmentation_masks, masks_path=masks_path + ) + prepared_images.append(image) + prepared_annotations.append(target) + images = prepared_images + annotations = prepared_annotations + del prepared_images, prepared_annotations + + # transformations + if do_resize: + if annotations is not None: + resized_images, resized_annotations = [], [] + for image, target in zip(images, annotations): + orig_size = get_image_size(image) + resized_image = self.resize(image, size=size, max_size=max_size, resample=resample) + resized_annotation = self.resize_annotation(target, orig_size, get_image_size(resized_image)) + resized_images.append(resized_image) + resized_annotations.append(resized_annotation) + images = resized_images + annotations = resized_annotations + del resized_images, resized_annotations + else: + images = [self.resize(image, size=size, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image, rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image, image_mean, image_std) for image in images] + if annotations is not None: + annotations = [ + self.normalize_annotation(annotation, get_image_size(image)) + for annotation, image in zip(annotations, images) + ] + + if do_pad: + # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...} + data = self.pad(images, return_pixel_mask=True, data_format=data_format) + else: + images = [to_channel_dimension_format(image, data_format) for image in images] + data = {"pixel_values": images} + + encoded_inputs = BatchFeature(data=data, tensor_type=return_tensors) + if annotations is not None: + encoded_inputs["labels"] = [ + BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations + ] + + return encoded_inputs + + # POSTPROCESSING METHODS - TODO: add support for other frameworks + def post_process(self, outputs, target_sizes): + """ + Converts the raw output of [`DeformableDetrForObjectDetection`] into final bounding boxes in (top_left_x, + top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`DeformableDetrObjectDetectionOutput`]): + Raw outputs of the model. + target_sizes (`torch.Tensor` of shape `(batch_size, 2)`): + Tensor containing the size (height, width) of each image of the batch. For evaluation, this must be the + original image size (before any data augmentation). For visualization, this should be the image size + after data augment, but before padding. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process` is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_object_detection`.", + ) + + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if len(out_logits) != len(target_sizes): + raise ValueError("Make sure that you pass in as many target sizes as the batch dimension of the logits") + if target_sizes.shape[1] != 2: + raise ValueError("Each element of target_sizes must contain the size (h, w) of each image of the batch") + + prob = out_logits.sigmoid() + topk_values, topk_indexes = torch.topk(prob.view(out_logits.shape[0], -1), 100, dim=1) + scores = topk_values + topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor") + labels = topk_indexes % out_logits.shape[2] + boxes = center_to_corners_format(out_bbox) + boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4)) + + # and from relative [0, 1] to absolute [0, height] coordinates + img_h, img_w = target_sizes.unbind(1) + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1) + boxes = boxes * scale_fct[:, None, :] + + results = [{"scores": s, "labels": l, "boxes": b} for s, l, b in zip(scores, labels, boxes)] + + return results + + def post_process_object_detection( + self, outputs, threshold: float = 0.5, target_sizes: Union[TensorType, List[Tuple]] = None + ): + """ + Converts the raw output of [`DeformableDetrForObjectDetection`] into final bounding boxes in (top_left_x, + top_left_y, bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`DetrObjectDetectionOutput`]): + Raw outputs of the model. + threshold (`float`, *optional*): + Score threshold to keep object detection predictions. + target_sizes (`torch.Tensor` or `List[Tuple[int, int]]`, *optional*): + Tensor of shape `(batch_size, 2)` or list of tuples (`Tuple[int, int]`) containing the target size + (height, width) of each image in the batch. If left to None, predictions will not be resized. + + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if target_sizes is not None: + if len(out_logits) != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + prob = out_logits.sigmoid() + topk_values, topk_indexes = torch.topk(prob.view(out_logits.shape[0], -1), 100, dim=1) + scores = topk_values + topk_boxes = torch.div(topk_indexes, out_logits.shape[2], rounding_mode="floor") + labels = topk_indexes % out_logits.shape[2] + boxes = center_to_corners_format(out_bbox) + boxes = torch.gather(boxes, 1, topk_boxes.unsqueeze(-1).repeat(1, 1, 4)) + + # and from relative [0, 1] to absolute [0, height] coordinates + if isinstance(target_sizes, List): + img_h = torch.Tensor([i[0] for i in target_sizes]) + img_w = torch.Tensor([i[1] for i in target_sizes]) + else: + img_h, img_w = target_sizes.unbind(1) + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [] + for s, l, b in zip(scores, labels, boxes): + score = s[s > threshold] + label = l[s > threshold] + box = b[s > threshold] + results.append({"scores": score, "labels": label, "boxes": box}) + + return results diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/load_custom.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/load_custom.py new file mode 100644 index 0000000000000000000000000000000000000000..d2a8bc0cb2c07476a8972610247592f89d761c40 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/load_custom.py @@ -0,0 +1,51 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Loading of Deformable DETR's CUDA kernels""" + +import os + + +def load_cuda_kernels(): + from torch.utils.cpp_extension import load + + root = os.path.join(os.path.dirname(os.path.realpath(__file__)), "custom_kernel") + src_files = [ + os.path.join(root, filename) + for filename in [ + "vision.cpp", + os.path.join("cpu", "ms_deform_attn_cpu.cpp"), + os.path.join("cuda", "ms_deform_attn_cuda.cu"), + ] + ] + + load( + "MultiScaleDeformableAttention", + src_files, + # verbose=True, + with_cuda=True, + extra_include_paths=[root], + # build_directory=os.path.dirname(os.path.realpath(__file__)), + extra_cflags=["-DWITH_CUDA=1"], + extra_cuda_cflags=[ + "-DCUDA_HAS_FP16=1", + "-D__CUDA_NO_HALF_OPERATORS__", + "-D__CUDA_NO_HALF_CONVERSIONS__", + "-D__CUDA_NO_HALF2_OPERATORS__", + ], + ) + + import MultiScaleDeformableAttention as MSDA + + return MSDA diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/modeling_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/modeling_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..96de07cb412046c1aff4d49bf32d52138b0b185d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deformable_detr/modeling_deformable_detr.py @@ -0,0 +1,2498 @@ +# coding=utf-8 +# Copyright 2022 SenseTime and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Deformable DETR model.""" + + +import copy +import math +import warnings +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple + +import torch +import torch.nn.functional as F +from torch import Tensor, nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable + +from ...activations import ACT2FN +from ...file_utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + is_scipy_available, + is_timm_available, + is_torch_cuda_available, + is_vision_available, + replace_return_docstrings, + requires_backends, +) +from ...modeling_outputs import BaseModelOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import meshgrid +from ...utils import is_ninja_available, logging +from ..auto import AutoBackbone +from .configuration_deformable_detr import DeformableDetrConfig +from .load_custom import load_cuda_kernels + + +logger = logging.get_logger(__name__) + +# Move this to not compile only when importing, this needs to happen later, like in __init__. +if is_torch_cuda_available() and is_ninja_available(): + logger.info("Loading custom CUDA kernels...") + try: + MultiScaleDeformableAttention = load_cuda_kernels() + except Exception as e: + logger.warning(f"Could not load the custom kernel for multi-scale deformable attention: {e}") + MultiScaleDeformableAttention = None +else: + MultiScaleDeformableAttention = None + +if is_vision_available(): + from transformers.image_transforms import center_to_corners_format + + +class MultiScaleDeformableAttentionFunction(Function): + @staticmethod + def forward( + context, + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + im2col_step, + ): + context.im2col_step = im2col_step + output = MultiScaleDeformableAttention.ms_deform_attn_forward( + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + context.im2col_step, + ) + context.save_for_backward( + value, value_spatial_shapes, value_level_start_index, sampling_locations, attention_weights + ) + return output + + @staticmethod + @once_differentiable + def backward(context, grad_output): + ( + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + ) = context.saved_tensors + grad_value, grad_sampling_loc, grad_attn_weight = MultiScaleDeformableAttention.ms_deform_attn_backward( + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + grad_output, + context.im2col_step, + ) + + return grad_value, None, None, grad_sampling_loc, grad_attn_weight, None + + +if is_scipy_available(): + from scipy.optimize import linear_sum_assignment + +if is_timm_available(): + from timm import create_model + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DeformableDetrConfig" +_CHECKPOINT_FOR_DOC = "sensetime/deformable-detr" + +DEFORMABLE_DETR_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "sensetime/deformable-detr", + # See all Deformable DETR models at https://huggingface.co/models?filter=deformable-detr +] + + +@dataclass +class DeformableDetrDecoderOutput(ModelOutput): + """ + Base class for outputs of the DeformableDetrDecoder. This class adds two attributes to + BaseModelOutputWithCrossAttentions, namely: + - a stacked tensor of intermediate decoder hidden states (i.e. the output of each decoder layer) + - a stacked tensor of intermediate reference points. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, sequence_length, hidden_size)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer + plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + """ + + last_hidden_state: torch.FloatTensor = None + intermediate_hidden_states: torch.FloatTensor = None + intermediate_reference_points: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class DeformableDetrModelOutput(ModelOutput): + """ + Base class for outputs of the Deformable DETR encoder-decoder model. + + Args: + init_reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Initial reference points sent through the Transformer decoder. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, 4)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, num_queries, hidden_size)`. Hidden-states of the decoder at the output of each layer + plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, num_queries, + num_queries)`. Attentions weights of the decoder, after the attention softmax, used to compute the weighted + average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the + weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + enc_outputs_class (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Predicted bounding boxes scores where the top `config.two_stage_num_proposals` scoring bounding boxes are + picked as region proposals in the first stage. Output of bounding box binary classification (i.e. + foreground and background). + enc_outputs_coord_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, 4)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Logits of predicted bounding boxes coordinates in the first stage. + """ + + init_reference_points: torch.FloatTensor = None + last_hidden_state: torch.FloatTensor = None + intermediate_hidden_states: torch.FloatTensor = None + intermediate_reference_points: torch.FloatTensor = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + enc_outputs_class: Optional[torch.FloatTensor] = None + enc_outputs_coord_logits: Optional[torch.FloatTensor] = None + + +@dataclass +class DeformableDetrObjectDetectionOutput(ModelOutput): + """ + Output type of [`DeformableDetrForObjectDetection`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)): + Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a + bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized + scale-invariant IoU loss. + loss_dict (`Dict`, *optional*): + A dictionary containing the individual losses. Useful for logging. + logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`): + Classification logits (including no-object) for all queries. + pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These + values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding + possible padding). You can use [`~DeformableDetrProcessor.post_process_object_detection`] to retrieve the + unnormalized bounding boxes. + auxiliary_outputs (`list[Dict]`, *optional*): + Optional, only returned when auxilary losses are activated (i.e. `config.auxiliary_loss` is set to `True`) + and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and + `pred_boxes`) for each decoder layer. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, num_queries, hidden_size)`. Hidden-states of the decoder at the output of each layer + plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, num_queries, + num_queries)`. Attentions weights of the decoder, after the attention softmax, used to compute the weighted + average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the + weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, sequence_length, num_heads, 4, + 4)`. Attentions weights of the encoder, after the attention softmax, used to compute the weighted average + in the self-attention heads. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, 4)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + init_reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Initial reference points sent through the Transformer decoder. + enc_outputs_class (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Predicted bounding boxes scores where the top `config.two_stage_num_proposals` scoring bounding boxes are + picked as region proposals in the first stage. Output of bounding box binary classification (i.e. + foreground and background). + enc_outputs_coord_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, 4)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Logits of predicted bounding boxes coordinates in the first stage. + """ + + loss: Optional[torch.FloatTensor] = None + loss_dict: Optional[Dict] = None + logits: torch.FloatTensor = None + pred_boxes: torch.FloatTensor = None + auxiliary_outputs: Optional[List[Dict]] = None + init_reference_points: Optional[torch.FloatTensor] = None + last_hidden_state: Optional[torch.FloatTensor] = None + intermediate_hidden_states: Optional[torch.FloatTensor] = None + intermediate_reference_points: Optional[torch.FloatTensor] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + enc_outputs_class: Optional = None + enc_outputs_coord_logits: Optional = None + + +def _get_clones(module, N): + return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) + + +def inverse_sigmoid(x, eps=1e-5): + x = x.clamp(min=0, max=1) + x1 = x.clamp(min=eps) + x2 = (1 - x).clamp(min=eps) + return torch.log(x1 / x2) + + +# Copied from transformers.models.detr.modeling_detr.DetrFrozenBatchNorm2d with Detr->DeformableDetr +class DeformableDetrFrozenBatchNorm2d(nn.Module): + """ + BatchNorm2d where the batch statistics and the affine parameters are fixed. + + Copy-paste from torchvision.misc.ops with added eps before rqsrt, without which any other models than + torchvision.models.resnet[18,34,50,101] produce nans. + """ + + def __init__(self, n): + super().__init__() + self.register_buffer("weight", torch.ones(n)) + self.register_buffer("bias", torch.zeros(n)) + self.register_buffer("running_mean", torch.zeros(n)) + self.register_buffer("running_var", torch.ones(n)) + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + num_batches_tracked_key = prefix + "num_batches_tracked" + if num_batches_tracked_key in state_dict: + del state_dict[num_batches_tracked_key] + + super()._load_from_state_dict( + state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ) + + def forward(self, x): + # move reshapes to the beginning + # to make it user-friendly + weight = self.weight.reshape(1, -1, 1, 1) + bias = self.bias.reshape(1, -1, 1, 1) + running_var = self.running_var.reshape(1, -1, 1, 1) + running_mean = self.running_mean.reshape(1, -1, 1, 1) + epsilon = 1e-5 + scale = weight * (running_var + epsilon).rsqrt() + bias = bias - running_mean * scale + return x * scale + bias + + +# Copied from transformers.models.detr.modeling_detr.replace_batch_norm with Detr->DeformableDetr +def replace_batch_norm(m, name=""): + for attr_str in dir(m): + target_attr = getattr(m, attr_str) + if isinstance(target_attr, nn.BatchNorm2d): + frozen = DeformableDetrFrozenBatchNorm2d(target_attr.num_features) + bn = getattr(m, attr_str) + frozen.weight.data.copy_(bn.weight) + frozen.bias.data.copy_(bn.bias) + frozen.running_mean.data.copy_(bn.running_mean) + frozen.running_var.data.copy_(bn.running_var) + setattr(m, attr_str, frozen) + for n, ch in m.named_children(): + replace_batch_norm(ch, n) + + +class DeformableDetrConvEncoder(nn.Module): + """ + Convolutional backbone, using either the AutoBackbone API or one from the timm library. + + nn.BatchNorm2d layers are replaced by DeformableDetrFrozenBatchNorm2d as defined above. + + """ + + def __init__(self, config): + super().__init__() + + self.config = config + + if config.use_timm_backbone: + requires_backends(self, ["timm"]) + kwargs = {} + if config.dilation: + kwargs["output_stride"] = 16 + backbone = create_model( + config.backbone, + pretrained=config.use_pretrained_backbone, + features_only=True, + out_indices=(2, 3, 4) if config.num_feature_levels > 1 else (4,), + in_chans=config.num_channels, + **kwargs, + ) + else: + backbone = AutoBackbone.from_config(config.backbone_config) + + # replace batch norm by frozen batch norm + with torch.no_grad(): + replace_batch_norm(backbone) + self.model = backbone + self.intermediate_channel_sizes = ( + self.model.feature_info.channels() if config.use_timm_backbone else self.model.channels + ) + + backbone_model_type = config.backbone if config.use_timm_backbone else config.backbone_config.model_type + if "resnet" in backbone_model_type: + for name, parameter in self.model.named_parameters(): + if config.use_timm_backbone: + if "layer2" not in name and "layer3" not in name and "layer4" not in name: + parameter.requires_grad_(False) + else: + if "stage.1" not in name and "stage.2" not in name and "stage.3" not in name: + parameter.requires_grad_(False) + + # Copied from transformers.models.detr.modeling_detr.DetrConvEncoder.forward with Detr->DeformableDetr + def forward(self, pixel_values: torch.Tensor, pixel_mask: torch.Tensor): + # send pixel_values through the model to get list of feature maps + features = self.model(pixel_values) if self.config.use_timm_backbone else self.model(pixel_values).feature_maps + + out = [] + for feature_map in features: + # downsample pixel_mask to match shape of corresponding feature_map + mask = nn.functional.interpolate(pixel_mask[None].float(), size=feature_map.shape[-2:]).to(torch.bool)[0] + out.append((feature_map, mask)) + return out + + +# Copied from transformers.models.detr.modeling_detr.DetrConvModel with Detr->DeformableDetr +class DeformableDetrConvModel(nn.Module): + """ + This module adds 2D position embeddings to all intermediate feature maps of the convolutional encoder. + """ + + def __init__(self, conv_encoder, position_embedding): + super().__init__() + self.conv_encoder = conv_encoder + self.position_embedding = position_embedding + + def forward(self, pixel_values, pixel_mask): + # send pixel_values and pixel_mask through backbone to get list of (feature_map, pixel_mask) tuples + out = self.conv_encoder(pixel_values, pixel_mask) + pos = [] + for feature_map, mask in out: + # position encoding + pos.append(self.position_embedding(feature_map, mask).to(feature_map.dtype)) + + return out, pos + + +# Copied from transformers.models.detr.modeling_detr._expand_mask +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, target_len: Optional[int] = None): + """ + Expands attention_mask from `[batch_size, seq_len]` to `[batch_size, 1, target_seq_len, source_seq_len]`. + """ + batch_size, source_len = mask.size() + target_len = target_len if target_len is not None else source_len + + expanded_mask = mask[:, None, None, :].expand(batch_size, 1, target_len, source_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.bool(), torch.finfo(dtype).min) + + +class DeformableDetrSinePositionEmbedding(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one used by the Attention is all you + need paper, generalized to work on images. + """ + + def __init__(self, embedding_dim=64, temperature=10000, normalize=False, scale=None): + super().__init__() + self.embedding_dim = embedding_dim + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + def forward(self, pixel_values, pixel_mask): + if pixel_mask is None: + raise ValueError("No pixel mask provided") + y_embed = pixel_mask.cumsum(1, dtype=torch.float32) + x_embed = pixel_mask.cumsum(2, dtype=torch.float32) + if self.normalize: + eps = 1e-6 + y_embed = (y_embed - 0.5) / (y_embed[:, -1:, :] + eps) * self.scale + x_embed = (x_embed - 0.5) / (x_embed[:, :, -1:] + eps) * self.scale + + dim_t = torch.arange(self.embedding_dim, dtype=torch.float32, device=pixel_values.device) + dim_t = self.temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / self.embedding_dim) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + return pos + + +# Copied from transformers.models.detr.modeling_detr.DetrLearnedPositionEmbedding +class DeformableDetrLearnedPositionEmbedding(nn.Module): + """ + This module learns positional embeddings up to a fixed maximum size. + """ + + def __init__(self, embedding_dim=256): + super().__init__() + self.row_embeddings = nn.Embedding(50, embedding_dim) + self.column_embeddings = nn.Embedding(50, embedding_dim) + + def forward(self, pixel_values, pixel_mask=None): + height, width = pixel_values.shape[-2:] + width_values = torch.arange(width, device=pixel_values.device) + height_values = torch.arange(height, device=pixel_values.device) + x_emb = self.column_embeddings(width_values) + y_emb = self.row_embeddings(height_values) + pos = torch.cat([x_emb.unsqueeze(0).repeat(height, 1, 1), y_emb.unsqueeze(1).repeat(1, width, 1)], dim=-1) + pos = pos.permute(2, 0, 1) + pos = pos.unsqueeze(0) + pos = pos.repeat(pixel_values.shape[0], 1, 1, 1) + return pos + + +# Copied from transformers.models.detr.modeling_detr.build_position_encoding with Detr->DeformableDetr +def build_position_encoding(config): + n_steps = config.d_model // 2 + if config.position_embedding_type == "sine": + # TODO find a better way of exposing other arguments + position_embedding = DeformableDetrSinePositionEmbedding(n_steps, normalize=True) + elif config.position_embedding_type == "learned": + position_embedding = DeformableDetrLearnedPositionEmbedding(n_steps) + else: + raise ValueError(f"Not supported {config.position_embedding_type}") + + return position_embedding + + +def multi_scale_deformable_attention( + value: Tensor, value_spatial_shapes: Tensor, sampling_locations: Tensor, attention_weights: Tensor +) -> Tensor: + batch_size, _, num_heads, hidden_dim = value.shape + _, num_queries, num_heads, num_levels, num_points, _ = sampling_locations.shape + value_list = value.split([height * width for height, width in value_spatial_shapes], dim=1) + sampling_grids = 2 * sampling_locations - 1 + sampling_value_list = [] + for level_id, (height, width) in enumerate(value_spatial_shapes): + # batch_size, height*width, num_heads, hidden_dim + # -> batch_size, height*width, num_heads*hidden_dim + # -> batch_size, num_heads*hidden_dim, height*width + # -> batch_size*num_heads, hidden_dim, height, width + value_l_ = ( + value_list[level_id].flatten(2).transpose(1, 2).reshape(batch_size * num_heads, hidden_dim, height, width) + ) + # batch_size, num_queries, num_heads, num_points, 2 + # -> batch_size, num_heads, num_queries, num_points, 2 + # -> batch_size*num_heads, num_queries, num_points, 2 + sampling_grid_l_ = sampling_grids[:, :, :, level_id].transpose(1, 2).flatten(0, 1) + # batch_size*num_heads, hidden_dim, num_queries, num_points + sampling_value_l_ = nn.functional.grid_sample( + value_l_, sampling_grid_l_, mode="bilinear", padding_mode="zeros", align_corners=False + ) + sampling_value_list.append(sampling_value_l_) + # (batch_size, num_queries, num_heads, num_levels, num_points) + # -> (batch_size, num_heads, num_queries, num_levels, num_points) + # -> (batch_size, num_heads, 1, num_queries, num_levels*num_points) + attention_weights = attention_weights.transpose(1, 2).reshape( + batch_size * num_heads, 1, num_queries, num_levels * num_points + ) + output = ( + (torch.stack(sampling_value_list, dim=-2).flatten(-2) * attention_weights) + .sum(-1) + .view(batch_size, num_heads * hidden_dim, num_queries) + ) + return output.transpose(1, 2).contiguous() + + +class DeformableDetrMultiscaleDeformableAttention(nn.Module): + """ + Multiscale deformable attention as proposed in Deformable DETR. + """ + + def __init__(self, config: DeformableDetrConfig, num_heads: int, n_points: int): + super().__init__() + if config.d_model % num_heads != 0: + raise ValueError( + f"embed_dim (d_model) must be divisible by num_heads, but got {config.d_model} and {num_heads}" + ) + dim_per_head = config.d_model // num_heads + # check if dim_per_head is power of 2 + if not ((dim_per_head & (dim_per_head - 1) == 0) and dim_per_head != 0): + warnings.warn( + "You'd better set embed_dim (d_model) in DeformableDetrMultiscaleDeformableAttention to make the" + " dimension of each attention head a power of 2 which is more efficient in the authors' CUDA" + " implementation." + ) + + self.im2col_step = 64 + + self.d_model = config.d_model + self.n_levels = config.num_feature_levels + self.n_heads = num_heads + self.n_points = n_points + + self.sampling_offsets = nn.Linear(config.d_model, num_heads * self.n_levels * n_points * 2) + self.attention_weights = nn.Linear(config.d_model, num_heads * self.n_levels * n_points) + self.value_proj = nn.Linear(config.d_model, config.d_model) + self.output_proj = nn.Linear(config.d_model, config.d_model) + + self.disable_custom_kernels = config.disable_custom_kernels + + self._reset_parameters() + + def _reset_parameters(self): + nn.init.constant_(self.sampling_offsets.weight.data, 0.0) + thetas = torch.arange(self.n_heads, dtype=torch.float32) * (2.0 * math.pi / self.n_heads) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = ( + (grid_init / grid_init.abs().max(-1, keepdim=True)[0]) + .view(self.n_heads, 1, 1, 2) + .repeat(1, self.n_levels, self.n_points, 1) + ) + for i in range(self.n_points): + grid_init[:, :, i, :] *= i + 1 + with torch.no_grad(): + self.sampling_offsets.bias = nn.Parameter(grid_init.view(-1)) + nn.init.constant_(self.attention_weights.weight.data, 0.0) + nn.init.constant_(self.attention_weights.bias.data, 0.0) + nn.init.xavier_uniform_(self.value_proj.weight.data) + nn.init.constant_(self.value_proj.bias.data, 0.0) + nn.init.xavier_uniform_(self.output_proj.weight.data) + nn.init.constant_(self.output_proj.bias.data, 0.0) + + def with_pos_embed(self, tensor: torch.Tensor, position_embeddings: Optional[Tensor]): + return tensor if position_embeddings is None else tensor + position_embeddings + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states=None, + encoder_attention_mask=None, + position_embeddings: Optional[torch.Tensor] = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + output_attentions: bool = False, + ): + # add position embeddings to the hidden states before projecting to queries and keys + if position_embeddings is not None: + hidden_states = self.with_pos_embed(hidden_states, position_embeddings) + + batch_size, num_queries, _ = hidden_states.shape + batch_size, sequence_length, _ = encoder_hidden_states.shape + if (spatial_shapes[:, 0] * spatial_shapes[:, 1]).sum() != sequence_length: + raise ValueError( + "Make sure to align the spatial shapes with the sequence length of the encoder hidden states" + ) + + value = self.value_proj(encoder_hidden_states) + if attention_mask is not None: + # we invert the attention_mask + value = value.masked_fill(~attention_mask[..., None], float(0)) + value = value.view(batch_size, sequence_length, self.n_heads, self.d_model // self.n_heads) + sampling_offsets = self.sampling_offsets(hidden_states).view( + batch_size, num_queries, self.n_heads, self.n_levels, self.n_points, 2 + ) + attention_weights = self.attention_weights(hidden_states).view( + batch_size, num_queries, self.n_heads, self.n_levels * self.n_points + ) + attention_weights = F.softmax(attention_weights, -1).view( + batch_size, num_queries, self.n_heads, self.n_levels, self.n_points + ) + # batch_size, num_queries, n_heads, n_levels, n_points, 2 + if reference_points.shape[-1] == 2: + offset_normalizer = torch.stack([spatial_shapes[..., 1], spatial_shapes[..., 0]], -1) + sampling_locations = ( + reference_points[:, :, None, :, None, :] + + sampling_offsets / offset_normalizer[None, None, None, :, None, :] + ) + elif reference_points.shape[-1] == 4: + sampling_locations = ( + reference_points[:, :, None, :, None, :2] + + sampling_offsets / self.n_points * reference_points[:, :, None, :, None, 2:] * 0.5 + ) + else: + raise ValueError(f"Last dim of reference_points must be 2 or 4, but got {reference_points.shape[-1]}") + + if self.disable_custom_kernels: + # PyTorch implementation + output = multi_scale_deformable_attention(value, spatial_shapes, sampling_locations, attention_weights) + else: + try: + # custom kernel + output = MultiScaleDeformableAttentionFunction.apply( + value, + spatial_shapes, + level_start_index, + sampling_locations, + attention_weights, + self.im2col_step, + ) + except Exception: + # PyTorch implementation + output = multi_scale_deformable_attention(value, spatial_shapes, sampling_locations, attention_weights) + output = self.output_proj(output) + + return output, attention_weights + + +class DeformableDetrMultiheadAttention(nn.Module): + """ + Multi-headed attention from 'Attention Is All You Need' paper. + + Here, we add position embeddings to the queries and keys (as explained in the Deformable DETR paper). + """ + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + if self.head_dim * num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, batch_size: int): + return tensor.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def with_pos_embed(self, tensor: torch.Tensor, position_embeddings: Optional[Tensor]): + return tensor if position_embeddings is None else tensor + position_embeddings + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_embeddings: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + batch_size, target_len, embed_dim = hidden_states.size() + # add position embeddings to the hidden states before projecting to queries and keys + if position_embeddings is not None: + hidden_states_original = hidden_states + hidden_states = self.with_pos_embed(hidden_states, position_embeddings) + + # get queries, keys and values + query_states = self.q_proj(hidden_states) * self.scaling + key_states = self._shape(self.k_proj(hidden_states), -1, batch_size) + value_states = self._shape(self.v_proj(hidden_states_original), -1, batch_size) + + proj_shape = (batch_size * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, target_len, batch_size).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + source_len = key_states.size(1) + + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (batch_size * self.num_heads, target_len, source_len): + raise ValueError( + f"Attention weights should be of size {(batch_size * self.num_heads, target_len, source_len)}, but is" + f" {attn_weights.size()}" + ) + + # expand attention_mask + if attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len] + attention_mask = _expand_mask(attention_mask, hidden_states.dtype) + + if attention_mask is not None: + if attention_mask.size() != (batch_size, 1, target_len, source_len): + raise ValueError( + f"Attention mask should be of size {(batch_size, 1, target_len, source_len)}, but is" + f" {attention_mask.size()}" + ) + attn_weights = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attention_mask + attn_weights = attn_weights.view(batch_size * self.num_heads, target_len, source_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attn_weights = attn_weights_reshaped.view(batch_size * self.num_heads, target_len, source_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (batch_size * self.num_heads, target_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(batch_size, self.num_heads, target_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(batch_size, self.num_heads, target_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + attn_output = attn_output.reshape(batch_size, target_len, embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped + + +class DeformableDetrEncoderLayer(nn.Module): + def __init__(self, config: DeformableDetrConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = DeformableDetrMultiscaleDeformableAttention( + config, num_heads=config.encoder_attention_heads, n_points=config.encoder_n_points + ) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_embeddings: torch.Tensor = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + output_attentions: bool = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Input to the layer. + attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Attention mask. + position_embeddings (`torch.FloatTensor`, *optional*): + Position embeddings, to be added to `hidden_states`. + reference_points (`torch.FloatTensor`, *optional*): + Reference points. + spatial_shapes (`torch.LongTensor`, *optional*): + Spatial shapes of the backbone feature maps. + level_start_index (`torch.LongTensor`, *optional*): + Level start index. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Apply Multi-scale Deformable Attention Module on the multi-scale feature maps. + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=hidden_states, + encoder_attention_mask=attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + if self.training: + if torch.isinf(hidden_states).any() or torch.isnan(hidden_states).any(): + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class DeformableDetrDecoderLayer(nn.Module): + def __init__(self, config: DeformableDetrConfig): + super().__init__() + self.embed_dim = config.d_model + + # self-attention + self.self_attn = DeformableDetrMultiheadAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + # cross-attention + self.encoder_attn = DeformableDetrMultiscaleDeformableAttention( + config, + num_heads=config.decoder_attention_heads, + n_points=config.decoder_n_points, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + # feedforward neural networks + self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim) + self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: Optional[torch.Tensor] = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor`): + Input to the layer of shape `(seq_len, batch, embed_dim)`. + position_embeddings (`torch.FloatTensor`, *optional*): + Position embeddings that are added to the queries and keys in the self-attention layer. + reference_points (`torch.FloatTensor`, *optional*): + Reference points. + spatial_shapes (`torch.LongTensor`, *optional*): + Spatial shapes. + level_start_index (`torch.LongTensor`, *optional*): + Level start index. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(seq_len, batch, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative + values. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + second_residual = hidden_states + + # Cross-Attention + cross_attn_weights = None + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + attention_mask=encoder_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = second_residual + hidden_states + + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +# Copied from transformers.models.detr.modeling_detr.DetrClassificationHead +class DeformableDetrClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, input_dim: int, inner_dim: int, num_classes: int, pooler_dropout: float): + super().__init__() + self.dense = nn.Linear(input_dim, inner_dim) + self.dropout = nn.Dropout(p=pooler_dropout) + self.out_proj = nn.Linear(inner_dim, num_classes) + + def forward(self, hidden_states: torch.Tensor): + hidden_states = self.dropout(hidden_states) + hidden_states = self.dense(hidden_states) + hidden_states = torch.tanh(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +class DeformableDetrPreTrainedModel(PreTrainedModel): + config_class = DeformableDetrConfig + base_model_prefix = "model" + main_input_name = "pixel_values" + + def _init_weights(self, module): + std = self.config.init_std + + if isinstance(module, DeformableDetrLearnedPositionEmbedding): + nn.init.uniform_(module.row_embeddings.weight) + nn.init.uniform_(module.column_embeddings.weight) + elif isinstance(module, DeformableDetrMultiscaleDeformableAttention): + module._reset_parameters() + elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + if hasattr(module, "reference_points") and not self.config.two_stage: + nn.init.xavier_uniform_(module.reference_points.weight.data, gain=1.0) + nn.init.constant_(module.reference_points.bias.data, 0.0) + if hasattr(module, "level_embed"): + nn.init.normal_(module.level_embed) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DeformableDetrDecoder): + module.gradient_checkpointing = value + + +DEFORMABLE_DETR_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`DeformableDetrConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEFORMABLE_DETR_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. + + Pixel values can be obtained using [`AutoImageProcessor`]. See [`DeformableDetrImageProcessor.__call__`] + for details. + + pixel_mask (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*): + Mask to avoid performing attention on padding pixel values. Mask values selected in `[0, 1]`: + + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + + [What are attention masks?](../glossary#attention-mask) + + decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, num_queries)`, *optional*): + Not used by default. Can be used to mask object queries. + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you + can choose to directly pass a flattened representation of an image. + decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an + embedded representation. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. +""" + + +class DeformableDetrEncoder(DeformableDetrPreTrainedModel): + """ + Transformer encoder consisting of *config.encoder_layers* deformable attention layers. Each layer is a + [`DeformableDetrEncoderLayer`]. + + The encoder updates the flattened multi-scale feature maps through multiple deformable attention layers. + + Args: + config: DeformableDetrConfig + """ + + def __init__(self, config: DeformableDetrConfig): + super().__init__(config) + + self.dropout = config.dropout + self.layers = nn.ModuleList([DeformableDetrEncoderLayer(config) for _ in range(config.encoder_layers)]) + + # Initialize weights and apply final processing + self.post_init() + + @staticmethod + def get_reference_points(spatial_shapes, valid_ratios, device): + """ + Get reference points for each feature map. Used in decoder. + + Args: + spatial_shapes (`torch.LongTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of each feature map. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`): + Valid ratios of each feature map. + device (`torch.device`): + Device on which to create the tensors. + Returns: + `torch.FloatTensor` of shape `(batch_size, num_queries, num_feature_levels, 2)` + """ + reference_points_list = [] + for level, (height, width) in enumerate(spatial_shapes): + ref_y, ref_x = meshgrid( + torch.linspace(0.5, height - 0.5, height, dtype=torch.float32, device=device), + torch.linspace(0.5, width - 0.5, width, dtype=torch.float32, device=device), + indexing="ij", + ) + # TODO: valid_ratios could be useless here. check https://github.com/fundamentalvision/Deformable-DETR/issues/36 + ref_y = ref_y.reshape(-1)[None] / (valid_ratios[:, None, level, 1] * height) + ref_x = ref_x.reshape(-1)[None] / (valid_ratios[:, None, level, 0] * width) + ref = torch.stack((ref_x, ref_y), -1) + reference_points_list.append(ref) + reference_points = torch.cat(reference_points_list, 1) + reference_points = reference_points[:, :, None] * valid_ratios[:, None] + return reference_points + + def forward( + self, + inputs_embeds=None, + attention_mask=None, + position_embeddings=None, + spatial_shapes=None, + level_start_index=None, + valid_ratios=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Flattened feature map (output of the backbone + projection layer) that is passed to the encoder. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding pixel features. Mask values selected in `[0, 1]`: + - 1 for pixel features that are real (i.e. **not masked**), + - 0 for pixel features that are padding (i.e. **masked**). + [What are attention masks?](../glossary#attention-mask) + position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Position embeddings that are added to the queries and keys in each self-attention layer. + spatial_shapes (`torch.LongTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of each feature map. + level_start_index (`torch.LongTensor` of shape `(num_feature_levels)`): + Starting index of each feature map. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`): + Ratio of valid area in each feature level. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + hidden_states = inputs_embeds + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + reference_points = self.get_reference_points(spatial_shapes, valid_ratios, device=inputs_embeds.device) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + for i, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class DeformableDetrDecoder(DeformableDetrPreTrainedModel): + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`DeformableDetrDecoderLayer`]. + + The decoder updates the query embeddings through multiple self-attention and cross-attention layers. + + Some tweaks for Deformable DETR: + + - `position_embeddings`, `reference_points`, `spatial_shapes` and `valid_ratios` are added to the forward pass. + - it also returns a stack of intermediate outputs and reference points from all decoding layers. + + Args: + config: DeformableDetrConfig + """ + + def __init__(self, config: DeformableDetrConfig): + super().__init__(config) + + self.dropout = config.dropout + self.layers = nn.ModuleList([DeformableDetrDecoderLayer(config) for _ in range(config.decoder_layers)]) + self.gradient_checkpointing = False + + # hack implementation for iterative bounding box refinement and two-stage Deformable DETR + self.bbox_embed = None + self.class_embed = None + + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + inputs_embeds=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + position_embeddings=None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + valid_ratios=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`): + The query embeddings that are passed into the decoder. + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding pixel_values of the encoder. Mask values selected + in `[0, 1]`: + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + position_embeddings (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Position embeddings that are added to the queries and keys in each self-attention layer. + reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)` is `as_two_stage` else `(batch_size, num_queries, 2)` or , *optional*): + Reference point in range `[0, 1]`, top-left (0,0), bottom-right (1, 1), including padding area. + spatial_shapes (`torch.FloatTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of the feature maps. + level_start_index (`torch.LongTensor` of shape `(num_feature_levels)`, *optional*): + Indexes for the start of each feature level. In range `[0, sequence_length]`. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`, *optional*): + Ratio of valid area in each feature level. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if inputs_embeds is not None: + hidden_states = inputs_embeds + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + intermediate = () + intermediate_reference_points = () + + for idx, decoder_layer in enumerate(self.layers): + if reference_points.shape[-1] == 4: + reference_points_input = ( + reference_points[:, :, None] * torch.cat([valid_ratios, valid_ratios], -1)[:, None] + ) + else: + if reference_points.shape[-1] != 2: + raise ValueError("Reference points' last dimension must be of size 2") + reference_points_input = reference_points[:, :, None] * valid_ratios[:, None] + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + encoder_hidden_states, + encoder_attention_mask, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + encoder_hidden_states=encoder_hidden_states, + reference_points=reference_points_input, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + # hack implementation for iterative bounding box refinement + if self.bbox_embed is not None: + tmp = self.bbox_embed[idx](hidden_states) + if reference_points.shape[-1] == 4: + new_reference_points = tmp + inverse_sigmoid(reference_points) + new_reference_points = new_reference_points.sigmoid() + else: + if reference_points.shape[-1] != 2: + raise ValueError( + f"Reference points' last dimension must be of size 2, but is {reference_points.shape[-1]}" + ) + new_reference_points = tmp + new_reference_points[..., :2] = tmp[..., :2] + inverse_sigmoid(reference_points) + new_reference_points = new_reference_points.sigmoid() + reference_points = new_reference_points.detach() + + intermediate += (hidden_states,) + intermediate_reference_points += (reference_points,) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # Keep batch_size as first dimension + intermediate = torch.stack(intermediate, dim=1) + intermediate_reference_points = torch.stack(intermediate_reference_points, dim=1) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + intermediate, + intermediate_reference_points, + all_hidden_states, + all_self_attns, + all_cross_attentions, + ] + if v is not None + ) + return DeformableDetrDecoderOutput( + last_hidden_state=hidden_states, + intermediate_hidden_states=intermediate, + intermediate_reference_points=intermediate_reference_points, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + """ + The bare Deformable DETR Model (consisting of a backbone and encoder-decoder Transformer) outputting raw + hidden-states without any specific head on top. + """, + DEFORMABLE_DETR_START_DOCSTRING, +) +class DeformableDetrModel(DeformableDetrPreTrainedModel): + def __init__(self, config: DeformableDetrConfig): + super().__init__(config) + + # Create backbone + positional encoding + backbone = DeformableDetrConvEncoder(config) + position_embeddings = build_position_encoding(config) + self.backbone = DeformableDetrConvModel(backbone, position_embeddings) + + # Create input projection layers + if config.num_feature_levels > 1: + num_backbone_outs = len(backbone.intermediate_channel_sizes) + input_proj_list = [] + for _ in range(num_backbone_outs): + in_channels = backbone.intermediate_channel_sizes[_] + input_proj_list.append( + nn.Sequential( + nn.Conv2d(in_channels, config.d_model, kernel_size=1), + nn.GroupNorm(32, config.d_model), + ) + ) + for _ in range(config.num_feature_levels - num_backbone_outs): + input_proj_list.append( + nn.Sequential( + nn.Conv2d(in_channels, config.d_model, kernel_size=3, stride=2, padding=1), + nn.GroupNorm(32, config.d_model), + ) + ) + in_channels = config.d_model + self.input_proj = nn.ModuleList(input_proj_list) + else: + self.input_proj = nn.ModuleList( + [ + nn.Sequential( + nn.Conv2d(backbone.intermediate_channel_sizes[-1], config.d_model, kernel_size=1), + nn.GroupNorm(32, config.d_model), + ) + ] + ) + + if not config.two_stage: + self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model * 2) + + self.encoder = DeformableDetrEncoder(config) + self.decoder = DeformableDetrDecoder(config) + + self.level_embed = nn.Parameter(torch.Tensor(config.num_feature_levels, config.d_model)) + + if config.two_stage: + self.enc_output = nn.Linear(config.d_model, config.d_model) + self.enc_output_norm = nn.LayerNorm(config.d_model) + self.pos_trans = nn.Linear(config.d_model * 2, config.d_model * 2) + self.pos_trans_norm = nn.LayerNorm(config.d_model * 2) + else: + self.reference_points = nn.Linear(config.d_model, 2) + + self.post_init() + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + def freeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(False) + + def unfreeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(True) + + def get_valid_ratio(self, mask): + """Get the valid ratio of all feature maps.""" + + _, height, width = mask.shape + valid_height = torch.sum(mask[:, :, 0], 1) + valid_width = torch.sum(mask[:, 0, :], 1) + valid_ratio_heigth = valid_height.float() / height + valid_ratio_width = valid_width.float() / width + valid_ratio = torch.stack([valid_ratio_width, valid_ratio_heigth], -1) + return valid_ratio + + def get_proposal_pos_embed(self, proposals): + """Get the position embedding of the proposals.""" + + num_pos_feats = 128 + temperature = 10000 + scale = 2 * math.pi + + dim_t = torch.arange(num_pos_feats, dtype=torch.float32, device=proposals.device) + dim_t = temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / num_pos_feats) + # batch_size, num_queries, 4 + proposals = proposals.sigmoid() * scale + # batch_size, num_queries, 4, 128 + pos = proposals[:, :, :, None] / dim_t + # batch_size, num_queries, 4, 64, 2 -> batch_size, num_queries, 512 + pos = torch.stack((pos[:, :, :, 0::2].sin(), pos[:, :, :, 1::2].cos()), dim=4).flatten(2) + return pos + + def gen_encoder_output_proposals(self, enc_output, padding_mask, spatial_shapes): + """Generate the encoder output proposals from encoded enc_output. + + Args: + enc_output (Tensor[batch_size, sequence_length, hidden_size]): Output of the encoder. + padding_mask (Tensor[batch_size, sequence_length]): Padding mask for `enc_output`. + spatial_shapes (Tensor[num_feature_levels, 2]): Spatial shapes of the feature maps. + + Returns: + `tuple(torch.FloatTensor)`: A tuple of feature map and bbox prediction. + - object_query (Tensor[batch_size, sequence_length, hidden_size]): Object query features. Later used to + directly predict a bounding box. (without the need of a decoder) + - output_proposals (Tensor[batch_size, sequence_length, 4]): Normalized proposals, after an inverse + sigmoid. + """ + batch_size = enc_output.shape[0] + proposals = [] + _cur = 0 + for level, (height, width) in enumerate(spatial_shapes): + mask_flatten_ = padding_mask[:, _cur : (_cur + height * width)].view(batch_size, height, width, 1) + valid_height = torch.sum(~mask_flatten_[:, :, 0, 0], 1) + valid_width = torch.sum(~mask_flatten_[:, 0, :, 0], 1) + + grid_y, grid_x = meshgrid( + torch.linspace(0, height - 1, height, dtype=torch.float32, device=enc_output.device), + torch.linspace(0, width - 1, width, dtype=torch.float32, device=enc_output.device), + indexing="ij", + ) + grid = torch.cat([grid_x.unsqueeze(-1), grid_y.unsqueeze(-1)], -1) + + scale = torch.cat([valid_width.unsqueeze(-1), valid_height.unsqueeze(-1)], 1).view(batch_size, 1, 1, 2) + grid = (grid.unsqueeze(0).expand(batch_size, -1, -1, -1) + 0.5) / scale + width_heigth = torch.ones_like(grid) * 0.05 * (2.0**level) + proposal = torch.cat((grid, width_heigth), -1).view(batch_size, -1, 4) + proposals.append(proposal) + _cur += height * width + output_proposals = torch.cat(proposals, 1) + output_proposals_valid = ((output_proposals > 0.01) & (output_proposals < 0.99)).all(-1, keepdim=True) + output_proposals = torch.log(output_proposals / (1 - output_proposals)) # inverse sigmoid + output_proposals = output_proposals.masked_fill(padding_mask.unsqueeze(-1), float("inf")) + output_proposals = output_proposals.masked_fill(~output_proposals_valid, float("inf")) + + # assign each pixel as an object query + object_query = enc_output + object_query = object_query.masked_fill(padding_mask.unsqueeze(-1), float(0)) + object_query = object_query.masked_fill(~output_proposals_valid, float(0)) + object_query = self.enc_output_norm(self.enc_output(object_query)) + return object_query, output_proposals + + @add_start_docstrings_to_model_forward(DEFORMABLE_DETR_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DeformableDetrModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DeformableDetrModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("SenseTime/deformable-detr") + >>> model = DeformableDetrModel.from_pretrained("SenseTime/deformable-detr") + + >>> inputs = image_processor(images=image, return_tensors="pt") + + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + [1, 300, 256] + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_channels, height, width = pixel_values.shape + device = pixel_values.device + + if pixel_mask is None: + pixel_mask = torch.ones(((batch_size, height, width)), dtype=torch.long, device=device) + + # Extract multi-scale feature maps of same resolution `config.d_model` (cf Figure 4 in paper) + # First, sent pixel_values + pixel_mask through Backbone to obtain the features + # which is a list of tuples + features, position_embeddings_list = self.backbone(pixel_values, pixel_mask) + + # Then, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default) + sources = [] + masks = [] + for level, (source, mask) in enumerate(features): + sources.append(self.input_proj[level](source)) + masks.append(mask) + if mask is None: + raise ValueError("No attention mask was provided") + + # Lowest resolution feature maps are obtained via 3x3 stride 2 convolutions on the final stage + if self.config.num_feature_levels > len(sources): + _len_sources = len(sources) + for level in range(_len_sources, self.config.num_feature_levels): + if level == _len_sources: + source = self.input_proj[level](features[-1][0]) + else: + source = self.input_proj[level](sources[-1]) + mask = nn.functional.interpolate(pixel_mask[None].float(), size=source.shape[-2:]).to(torch.bool)[0] + pos_l = self.backbone.position_embedding(source, mask).to(source.dtype) + sources.append(source) + masks.append(mask) + position_embeddings_list.append(pos_l) + + # Create queries + query_embeds = None + if not self.config.two_stage: + query_embeds = self.query_position_embeddings.weight + + # Prepare encoder inputs (by flattening) + source_flatten = [] + mask_flatten = [] + lvl_pos_embed_flatten = [] + spatial_shapes = [] + for level, (source, mask, pos_embed) in enumerate(zip(sources, masks, position_embeddings_list)): + batch_size, num_channels, height, width = source.shape + spatial_shape = (height, width) + spatial_shapes.append(spatial_shape) + source = source.flatten(2).transpose(1, 2) + mask = mask.flatten(1) + pos_embed = pos_embed.flatten(2).transpose(1, 2) + lvl_pos_embed = pos_embed + self.level_embed[level].view(1, 1, -1) + lvl_pos_embed_flatten.append(lvl_pos_embed) + source_flatten.append(source) + mask_flatten.append(mask) + source_flatten = torch.cat(source_flatten, 1) + mask_flatten = torch.cat(mask_flatten, 1) + lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1) + spatial_shapes = torch.as_tensor(spatial_shapes, dtype=torch.long, device=source_flatten.device) + level_start_index = torch.cat((spatial_shapes.new_zeros((1,)), spatial_shapes.prod(1).cumsum(0)[:-1])) + valid_ratios = torch.stack([self.get_valid_ratio(m) for m in masks], 1) + valid_ratios = valid_ratios.float() + + # Fourth, sent source_flatten + mask_flatten + lvl_pos_embed_flatten (backbone + proj layer output) through encoder + # Also provide spatial_shapes, level_start_index and valid_ratios + if encoder_outputs is None: + encoder_outputs = self.encoder( + inputs_embeds=source_flatten, + attention_mask=mask_flatten, + position_embeddings=lvl_pos_embed_flatten, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + valid_ratios=valid_ratios, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # Fifth, prepare decoder inputs + batch_size, _, num_channels = encoder_outputs[0].shape + enc_outputs_class = None + enc_outputs_coord_logits = None + if self.config.two_stage: + object_query_embedding, output_proposals = self.gen_encoder_output_proposals( + encoder_outputs[0], ~mask_flatten, spatial_shapes + ) + + # hack implementation for two-stage Deformable DETR + # apply a detection head to each pixel (A.4 in paper) + # linear projection for bounding box binary classification (i.e. foreground and background) + enc_outputs_class = self.decoder.class_embed[-1](object_query_embedding) + # 3-layer FFN to predict bounding boxes coordinates (bbox regression branch) + delta_bbox = self.decoder.bbox_embed[-1](object_query_embedding) + enc_outputs_coord_logits = delta_bbox + output_proposals + + # only keep top scoring `config.two_stage_num_proposals` proposals + topk = self.config.two_stage_num_proposals + topk_proposals = torch.topk(enc_outputs_class[..., 0], topk, dim=1)[1] + topk_coords_logits = torch.gather( + enc_outputs_coord_logits, 1, topk_proposals.unsqueeze(-1).repeat(1, 1, 4) + ) + + topk_coords_logits = topk_coords_logits.detach() + reference_points = topk_coords_logits.sigmoid() + init_reference_points = reference_points + pos_trans_out = self.pos_trans_norm(self.pos_trans(self.get_proposal_pos_embed(topk_coords_logits))) + query_embed, target = torch.split(pos_trans_out, num_channels, dim=2) + else: + query_embed, target = torch.split(query_embeds, num_channels, dim=1) + query_embed = query_embed.unsqueeze(0).expand(batch_size, -1, -1) + target = target.unsqueeze(0).expand(batch_size, -1, -1) + reference_points = self.reference_points(query_embed).sigmoid() + init_reference_points = reference_points + + decoder_outputs = self.decoder( + inputs_embeds=target, + position_embeddings=query_embed, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=mask_flatten, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + valid_ratios=valid_ratios, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + enc_outputs = tuple(value for value in [enc_outputs_class, enc_outputs_coord_logits] if value is not None) + tuple_outputs = (init_reference_points,) + decoder_outputs + encoder_outputs + enc_outputs + + return tuple_outputs + + return DeformableDetrModelOutput( + init_reference_points=init_reference_points, + last_hidden_state=decoder_outputs.last_hidden_state, + intermediate_hidden_states=decoder_outputs.intermediate_hidden_states, + intermediate_reference_points=decoder_outputs.intermediate_reference_points, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + enc_outputs_class=enc_outputs_class, + enc_outputs_coord_logits=enc_outputs_coord_logits, + ) + + +@add_start_docstrings( + """ + Deformable DETR Model (consisting of a backbone and encoder-decoder Transformer) with object detection heads on + top, for tasks such as COCO detection. + """, + DEFORMABLE_DETR_START_DOCSTRING, +) +class DeformableDetrForObjectDetection(DeformableDetrPreTrainedModel): + # When using clones, all layers > 0 will be clones, but layer 0 *is* required + _keys_to_ignore_on_load_missing = [r"bbox_embed\.[1-9]\d*", r"class_embed\.[1-9]\d*"] + + def __init__(self, config: DeformableDetrConfig): + super().__init__(config) + + # Deformable DETR encoder-decoder model + self.model = DeformableDetrModel(config) + + # Detection heads on top + self.class_embed = nn.Linear(config.d_model, config.num_labels) + self.bbox_embed = DeformableDetrMLPPredictionHead( + input_dim=config.d_model, hidden_dim=config.d_model, output_dim=4, num_layers=3 + ) + + prior_prob = 0.01 + bias_value = -math.log((1 - prior_prob) / prior_prob) + self.class_embed.bias.data = torch.ones(config.num_labels) * bias_value + nn.init.constant_(self.bbox_embed.layers[-1].weight.data, 0) + nn.init.constant_(self.bbox_embed.layers[-1].bias.data, 0) + + # if two-stage, the last class_embed and bbox_embed is for region proposal generation + num_pred = (config.decoder_layers + 1) if config.two_stage else config.decoder_layers + if config.with_box_refine: + self.class_embed = _get_clones(self.class_embed, num_pred) + self.bbox_embed = _get_clones(self.bbox_embed, num_pred) + nn.init.constant_(self.bbox_embed[0].layers[-1].bias.data[2:], -2.0) + # hack implementation for iterative bounding box refinement + self.model.decoder.bbox_embed = self.bbox_embed + else: + nn.init.constant_(self.bbox_embed.layers[-1].bias.data[2:], -2.0) + self.class_embed = nn.ModuleList([self.class_embed for _ in range(num_pred)]) + self.bbox_embed = nn.ModuleList([self.bbox_embed for _ in range(num_pred)]) + self.model.decoder.bbox_embed = None + if config.two_stage: + # hack implementation for two-stage + self.model.decoder.class_embed = self.class_embed + for box_embed in self.bbox_embed: + nn.init.constant_(box_embed.layers[-1].bias.data[2:], 0.0) + + # Initialize weights and apply final processing + self.post_init() + + # taken from https://github.com/facebookresearch/detr/blob/master/models/detr.py + @torch.jit.unused + def _set_aux_loss(self, outputs_class, outputs_coord): + # this is a workaround to make torchscript happy, as torchscript + # doesn't support dictionary with non-homogeneous values, such + # as a dict having both a Tensor and a list. + return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])] + + @add_start_docstrings_to_model_forward(DEFORMABLE_DETR_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DeformableDetrObjectDetectionOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + labels=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + labels (`List[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the + following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch + respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes + in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`. + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DeformableDetrForObjectDetection + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("SenseTime/deformable-detr") + >>> model = DeformableDetrForObjectDetection.from_pretrained("SenseTime/deformable-detr") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + + >>> # convert outputs (bounding boxes and class logits) to COCO API + >>> target_sizes = torch.tensor([image.size[::-1]]) + >>> results = image_processor.post_process_object_detection(outputs, threshold=0.5, target_sizes=target_sizes)[ + ... 0 + ... ] + >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]): + ... box = [round(i, 2) for i in box.tolist()] + ... print( + ... f"Detected {model.config.id2label[label.item()]} with confidence " + ... f"{round(score.item(), 3)} at location {box}" + ... ) + Detected cat with confidence 0.8 at location [16.5, 52.84, 318.25, 470.78] + Detected cat with confidence 0.789 at location [342.19, 24.3, 640.02, 372.25] + Detected remote with confidence 0.633 at location [40.79, 72.78, 176.76, 117.25] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # First, sent images through DETR base model to obtain encoder + decoder outputs + outputs = self.model( + pixel_values, + pixel_mask=pixel_mask, + decoder_attention_mask=decoder_attention_mask, + encoder_outputs=encoder_outputs, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs.intermediate_hidden_states if return_dict else outputs[2] + init_reference = outputs.init_reference_points if return_dict else outputs[0] + inter_references = outputs.intermediate_reference_points if return_dict else outputs[3] + + # class logits + predicted bounding boxes + outputs_classes = [] + outputs_coords = [] + + for level in range(hidden_states.shape[1]): + if level == 0: + reference = init_reference + else: + reference = inter_references[:, level - 1] + reference = inverse_sigmoid(reference) + outputs_class = self.class_embed[level](hidden_states[:, level]) + delta_bbox = self.bbox_embed[level](hidden_states[:, level]) + if reference.shape[-1] == 4: + outputs_coord_logits = delta_bbox + reference + elif reference.shape[-1] == 2: + delta_bbox[..., :2] += reference + outputs_coord_logits = delta_bbox + else: + raise ValueError(f"reference.shape[-1] should be 4 or 2, but got {reference.shape[-1]}") + outputs_coord = outputs_coord_logits.sigmoid() + outputs_classes.append(outputs_class) + outputs_coords.append(outputs_coord) + # Keep batch_size as first dimension + outputs_class = torch.stack(outputs_classes, dim=1) + outputs_coord = torch.stack(outputs_coords, dim=1) + + logits = outputs_class[:, -1] + pred_boxes = outputs_coord[:, -1] + + loss, loss_dict, auxiliary_outputs = None, None, None + if labels is not None: + # First: create the matcher + matcher = DeformableDetrHungarianMatcher( + class_cost=self.config.class_cost, bbox_cost=self.config.bbox_cost, giou_cost=self.config.giou_cost + ) + # Second: create the criterion + losses = ["labels", "boxes", "cardinality"] + criterion = DeformableDetrLoss( + matcher=matcher, + num_classes=self.config.num_labels, + focal_alpha=self.config.focal_alpha, + losses=losses, + ) + criterion.to(self.device) + # Third: compute the losses, based on outputs and labels + outputs_loss = {} + outputs_loss["logits"] = logits + outputs_loss["pred_boxes"] = pred_boxes + if self.config.auxiliary_loss: + auxiliary_outputs = self._set_aux_loss(outputs_class, outputs_coord) + outputs_loss["auxiliary_outputs"] = auxiliary_outputs + if self.config.two_stage: + enc_outputs_coord = outputs.enc_outputs_coord_logits.sigmoid() + outputs["enc_outputs"] = {"pred_logits": outputs.enc_outputs_class, "pred_boxes": enc_outputs_coord} + + loss_dict = criterion(outputs_loss, labels) + # Fourth: compute total loss, as a weighted sum of the various losses + weight_dict = {"loss_ce": 1, "loss_bbox": self.config.bbox_loss_coefficient} + weight_dict["loss_giou"] = self.config.giou_loss_coefficient + if self.config.auxiliary_loss: + aux_weight_dict = {} + for i in range(self.config.decoder_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + loss = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) + + if not return_dict: + if auxiliary_outputs is not None: + output = (logits, pred_boxes) + auxiliary_outputs + outputs + else: + output = (logits, pred_boxes) + outputs + tuple_outputs = ((loss, loss_dict) + output) if loss is not None else output + + return tuple_outputs + + dict_outputs = DeformableDetrObjectDetectionOutput( + loss=loss, + loss_dict=loss_dict, + logits=logits, + pred_boxes=pred_boxes, + auxiliary_outputs=auxiliary_outputs, + last_hidden_state=outputs.last_hidden_state, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + intermediate_hidden_states=outputs.intermediate_hidden_states, + intermediate_reference_points=outputs.intermediate_reference_points, + init_reference_points=outputs.init_reference_points, + enc_outputs_class=outputs.enc_outputs_class, + enc_outputs_coord_logits=outputs.enc_outputs_coord_logits, + ) + + return dict_outputs + + +# Copied from transformers.models.detr.modeling_detr.dice_loss +def dice_loss(inputs, targets, num_boxes): + """ + Compute the DICE loss, similar to generalized IOU for masks + + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs (0 for the negative class and 1 for the positive + class). + """ + inputs = inputs.sigmoid() + inputs = inputs.flatten(1) + numerator = 2 * (inputs * targets).sum(1) + denominator = inputs.sum(-1) + targets.sum(-1) + loss = 1 - (numerator + 1) / (denominator + 1) + return loss.sum() / num_boxes + + +# Copied from transformers.models.detr.modeling_detr.sigmoid_focal_loss +def sigmoid_focal_loss(inputs, targets, num_boxes, alpha: float = 0.25, gamma: float = 2): + """ + Loss used in RetinaNet for dense detection: https://arxiv.org/abs/1708.02002. + + Args: + inputs (`torch.FloatTensor` of arbitrary shape): + The predictions for each example. + targets (`torch.FloatTensor` with the same shape as `inputs`) + A tensor storing the binary classification label for each element in the `inputs` (0 for the negative class + and 1 for the positive class). + alpha (`float`, *optional*, defaults to `0.25`): + Optional weighting factor in the range (0,1) to balance positive vs. negative examples. + gamma (`int`, *optional*, defaults to `2`): + Exponent of the modulating factor (1 - p_t) to balance easy vs hard examples. + + Returns: + Loss tensor + """ + prob = inputs.sigmoid() + ce_loss = nn.functional.binary_cross_entropy_with_logits(inputs, targets, reduction="none") + # add modulating factor + p_t = prob * targets + (1 - prob) * (1 - targets) + loss = ce_loss * ((1 - p_t) ** gamma) + + if alpha >= 0: + alpha_t = alpha * targets + (1 - alpha) * (1 - targets) + loss = alpha_t * loss + + return loss.mean(1).sum() / num_boxes + + +class DeformableDetrLoss(nn.Module): + """ + This class computes the losses for `DeformableDetrForObjectDetection`. The process happens in two steps: 1) we + compute hungarian assignment between ground truth boxes and the outputs of the model 2) we supervise each pair of + matched ground-truth / prediction (supervise class and box). + + Args: + matcher (`DeformableDetrHungarianMatcher`): + Module able to compute a matching between targets and proposals. + num_classes (`int`): + Number of object categories, omitting the special no-object category. + focal_alpha (`float`): + Alpha parameter in focal loss. + losses (`List[str]`): + List of all the losses to be applied. See `get_loss` for a list of all available losses. + """ + + def __init__(self, matcher, num_classes, focal_alpha, losses): + super().__init__() + self.matcher = matcher + self.num_classes = num_classes + self.focal_alpha = focal_alpha + self.losses = losses + + # removed logging parameter, which was part of the original implementation + def loss_labels(self, outputs, targets, indices, num_boxes): + """ + Classification loss (Binary focal loss) targets dicts must contain the key "class_labels" containing a tensor + of dim [nb_target_boxes] + """ + if "logits" not in outputs: + raise KeyError("No logits were found in the outputs") + source_logits = outputs["logits"] + + idx = self._get_source_permutation_idx(indices) + target_classes_o = torch.cat([t["class_labels"][J] for t, (_, J) in zip(targets, indices)]) + target_classes = torch.full( + source_logits.shape[:2], self.num_classes, dtype=torch.int64, device=source_logits.device + ) + target_classes[idx] = target_classes_o + + target_classes_onehot = torch.zeros( + [source_logits.shape[0], source_logits.shape[1], source_logits.shape[2] + 1], + dtype=source_logits.dtype, + layout=source_logits.layout, + device=source_logits.device, + ) + target_classes_onehot.scatter_(2, target_classes.unsqueeze(-1), 1) + + target_classes_onehot = target_classes_onehot[:, :, :-1] + loss_ce = ( + sigmoid_focal_loss(source_logits, target_classes_onehot, num_boxes, alpha=self.focal_alpha, gamma=2) + * source_logits.shape[1] + ) + losses = {"loss_ce": loss_ce} + + return losses + + @torch.no_grad() + # Copied from transformers.models.detr.modeling_detr.DetrLoss.loss_cardinality + def loss_cardinality(self, outputs, targets, indices, num_boxes): + """ + Compute the cardinality error, i.e. the absolute error in the number of predicted non-empty boxes. + + This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients. + """ + logits = outputs["logits"] + device = logits.device + target_lengths = torch.as_tensor([len(v["class_labels"]) for v in targets], device=device) + # Count the number of predictions that are NOT "no-object" (which is the last class) + card_pred = (logits.argmax(-1) != logits.shape[-1] - 1).sum(1) + card_err = nn.functional.l1_loss(card_pred.float(), target_lengths.float()) + losses = {"cardinality_error": card_err} + return losses + + # Copied from transformers.models.detr.modeling_detr.DetrLoss.loss_boxes + def loss_boxes(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss. + + Targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]. The target boxes + are expected in format (center_x, center_y, w, h), normalized by the image size. + """ + if "pred_boxes" not in outputs: + raise KeyError("No predicted boxes found in outputs") + idx = self._get_source_permutation_idx(indices) + source_boxes = outputs["pred_boxes"][idx] + target_boxes = torch.cat([t["boxes"][i] for t, (_, i) in zip(targets, indices)], dim=0) + + loss_bbox = nn.functional.l1_loss(source_boxes, target_boxes, reduction="none") + + losses = {} + losses["loss_bbox"] = loss_bbox.sum() / num_boxes + + loss_giou = 1 - torch.diag( + generalized_box_iou(center_to_corners_format(source_boxes), center_to_corners_format(target_boxes)) + ) + losses["loss_giou"] = loss_giou.sum() / num_boxes + return losses + + # Copied from transformers.models.detr.modeling_detr.DetrLoss._get_source_permutation_idx + def _get_source_permutation_idx(self, indices): + # permute predictions following indices + batch_idx = torch.cat([torch.full_like(source, i) for i, (source, _) in enumerate(indices)]) + source_idx = torch.cat([source for (source, _) in indices]) + return batch_idx, source_idx + + # Copied from transformers.models.detr.modeling_detr.DetrLoss._get_target_permutation_idx + def _get_target_permutation_idx(self, indices): + # permute targets following indices + batch_idx = torch.cat([torch.full_like(target, i) for i, (_, target) in enumerate(indices)]) + target_idx = torch.cat([target for (_, target) in indices]) + return batch_idx, target_idx + + def get_loss(self, loss, outputs, targets, indices, num_boxes): + loss_map = { + "labels": self.loss_labels, + "cardinality": self.loss_cardinality, + "boxes": self.loss_boxes, + } + if loss not in loss_map: + raise ValueError(f"Loss {loss} not supported") + return loss_map[loss](outputs, targets, indices, num_boxes) + + def forward(self, outputs, targets): + """ + This performs the loss computation. + + Args: + outputs (`dict`, *optional*): + Dictionary of tensors, see the output specification of the model for the format. + targets (`List[dict]`, *optional*): + List of dicts, such that `len(targets) == batch_size`. The expected keys in each dict depends on the + losses applied, see each loss' doc. + """ + outputs_without_aux = {k: v for k, v in outputs.items() if k != "auxiliary_outputs"} + + # Retrieve the matching between the outputs of the last layer and the targets + indices = self.matcher(outputs_without_aux, targets) + + # Compute the average number of target boxes accross all nodes, for normalization purposes + num_boxes = sum(len(t["class_labels"]) for t in targets) + num_boxes = torch.as_tensor([num_boxes], dtype=torch.float, device=next(iter(outputs.values())).device) + # (Niels): comment out function below, distributed training to be added + # if is_dist_avail_and_initialized(): + # torch.distributed.all_reduce(num_boxes) + # (Niels) in original implementation, num_boxes is divided by get_world_size() + num_boxes = torch.clamp(num_boxes, min=1).item() + + # Compute all the requested losses + losses = {} + for loss in self.losses: + losses.update(self.get_loss(loss, outputs, targets, indices, num_boxes)) + + # In case of auxiliary losses, we repeat this process with the output of each intermediate layer. + if "auxiliary_outputs" in outputs: + for i, auxiliary_outputs in enumerate(outputs["auxiliary_outputs"]): + indices = self.matcher(auxiliary_outputs, targets) + for loss in self.losses: + l_dict = self.get_loss(loss, auxiliary_outputs, targets, indices, num_boxes) + l_dict = {k + f"_{i}": v for k, v in l_dict.items()} + losses.update(l_dict) + + if "enc_outputs" in outputs: + enc_outputs = outputs["enc_outputs"] + bin_targets = copy.deepcopy(targets) + for bt in bin_targets: + bt["labels"] = torch.zeros_like(bt["labels"]) + indices = self.matcher(enc_outputs, bin_targets) + for loss in self.losses: + kwargs = {} + if loss == "labels": + # Logging is enabled only for the last layer + kwargs["log"] = False + l_dict = self.get_loss(loss, enc_outputs, bin_targets, indices, num_boxes, **kwargs) + l_dict = {k + "_enc": v for k, v in l_dict.items()} + losses.update(l_dict) + + return losses + + +# Copied from transformers.models.detr.modeling_detr.DetrMLPPredictionHead +class DeformableDetrMLPPredictionHead(nn.Module): + """ + Very simple multi-layer perceptron (MLP, also called FFN), used to predict the normalized center coordinates, + height and width of a bounding box w.r.t. an image. + + Copied from https://github.com/facebookresearch/detr/blob/master/models/detr.py + + """ + + def __init__(self, input_dim, hidden_dim, output_dim, num_layers): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = nn.functional.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x + + +class DeformableDetrHungarianMatcher(nn.Module): + """ + This class computes an assignment between the targets and the predictions of the network. + + For efficiency reasons, the targets don't include the no_object. Because of this, in general, there are more + predictions than targets. In this case, we do a 1-to-1 matching of the best predictions, while the others are + un-matched (and thus treated as non-objects). + + Args: + class_cost: + The relative weight of the classification error in the matching cost. + bbox_cost: + The relative weight of the L1 error of the bounding box coordinates in the matching cost. + giou_cost: + The relative weight of the giou loss of the bounding box in the matching cost. + """ + + def __init__(self, class_cost: float = 1, bbox_cost: float = 1, giou_cost: float = 1): + super().__init__() + requires_backends(self, ["scipy"]) + + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + if class_cost == 0 and bbox_cost == 0 and giou_cost == 0: + raise ValueError("All costs of the Matcher can't be 0") + + @torch.no_grad() + def forward(self, outputs, targets): + """ + Args: + outputs (`dict`): + A dictionary that contains at least these entries: + * "logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits + * "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates. + targets (`List[dict]`): + A list of targets (len(targets) = batch_size), where each target is a dict containing: + * "class_labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of + ground-truth + objects in the target) containing the class labels + * "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates. + + Returns: + `List[Tuple]`: A list of size `batch_size`, containing tuples of (index_i, index_j) where: + - index_i is the indices of the selected predictions (in order) + - index_j is the indices of the corresponding selected targets (in order) + For each batch element, it holds: len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + batch_size, num_queries = outputs["logits"].shape[:2] + + # We flatten to compute the cost matrices in a batch + out_prob = outputs["logits"].flatten(0, 1).sigmoid() # [batch_size * num_queries, num_classes] + out_bbox = outputs["pred_boxes"].flatten(0, 1) # [batch_size * num_queries, 4] + + # Also concat the target labels and boxes + target_ids = torch.cat([v["class_labels"] for v in targets]) + target_bbox = torch.cat([v["boxes"] for v in targets]) + + # Compute the classification cost. + alpha = 0.25 + gamma = 2.0 + neg_cost_class = (1 - alpha) * (out_prob**gamma) * (-(1 - out_prob + 1e-8).log()) + pos_cost_class = alpha * ((1 - out_prob) ** gamma) * (-(out_prob + 1e-8).log()) + class_cost = pos_cost_class[:, target_ids] - neg_cost_class[:, target_ids] + + # Compute the L1 cost between boxes + bbox_cost = torch.cdist(out_bbox, target_bbox, p=1) + + # Compute the giou cost between boxes + giou_cost = -generalized_box_iou(center_to_corners_format(out_bbox), center_to_corners_format(target_bbox)) + + # Final cost matrix + cost_matrix = self.bbox_cost * bbox_cost + self.class_cost * class_cost + self.giou_cost * giou_cost + cost_matrix = cost_matrix.view(batch_size, num_queries, -1).cpu() + + sizes = [len(v["boxes"]) for v in targets] + indices = [linear_sum_assignment(c[i]) for i, c in enumerate(cost_matrix.split(sizes, -1))] + return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices] + + +# Copied from transformers.models.detr.modeling_detr._upcast +def _upcast(t: Tensor) -> Tensor: + # Protects from numerical overflows in multiplications by upcasting to the equivalent higher type + if t.is_floating_point(): + return t if t.dtype in (torch.float32, torch.float64) else t.float() + else: + return t if t.dtype in (torch.int32, torch.int64) else t.int() + + +# Copied from transformers.models.detr.modeling_detr.box_area +def box_area(boxes: Tensor) -> Tensor: + """ + Computes the area of a set of bounding boxes, which are specified by its (x1, y1, x2, y2) coordinates. + + Args: + boxes (`torch.FloatTensor` of shape `(number_of_boxes, 4)`): + Boxes for which the area will be computed. They are expected to be in (x1, y1, x2, y2) format with `0 <= x1 + < x2` and `0 <= y1 < y2`. + + Returns: + `torch.FloatTensor`: a tensor containing the area for each box. + """ + boxes = _upcast(boxes) + return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) + + +# Copied from transformers.models.detr.modeling_detr.box_iou +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + left_top = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2] + right_bottom = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2] + + width_height = (right_bottom - left_top).clamp(min=0) # [N,M,2] + inter = width_height[:, :, 0] * width_height[:, :, 1] # [N,M] + + union = area1[:, None] + area2 - inter + + iou = inter / union + return iou, union + + +# Copied from transformers.models.detr.modeling_detr.generalized_box_iou +def generalized_box_iou(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/. The boxes should be in [x0, y0, x1, y1] (corner) format. + + Returns: + `torch.FloatTensor`: a [N, M] pairwise matrix, where N = len(boxes1) and M = len(boxes2) + """ + # degenerate boxes gives inf / nan results + # so do an early check + if not (boxes1[:, 2:] >= boxes1[:, :2]).all(): + raise ValueError(f"boxes1 must be in [x0, y0, x1, y1] (corner) format, but got {boxes1}") + if not (boxes2[:, 2:] >= boxes2[:, :2]).all(): + raise ValueError(f"boxes2 must be in [x0, y0, x1, y1] (corner) format, but got {boxes2}") + iou, union = box_iou(boxes1, boxes2) + + top_left = torch.min(boxes1[:, None, :2], boxes2[:, :2]) + bottom_right = torch.max(boxes1[:, None, 2:], boxes2[:, 2:]) + + width_height = (bottom_right - top_left).clamp(min=0) # [N,M,2] + area = width_height[:, :, 0] * width_height[:, :, 1] + + return iou - (area - union) / area + + +# Copied from transformers.models.detr.modeling_detr._max_by_axis +def _max_by_axis(the_list): + # type: (List[List[int]]) -> List[int] + maxes = the_list[0] + for sublist in the_list[1:]: + for index, item in enumerate(sublist): + maxes[index] = max(maxes[index], item) + return maxes + + +# Copied from transformers.models.detr.modeling_detr.NestedTensor +class NestedTensor(object): + def __init__(self, tensors, mask: Optional[Tensor]): + self.tensors = tensors + self.mask = mask + + def to(self, device): + cast_tensor = self.tensors.to(device) + mask = self.mask + if mask is not None: + cast_mask = mask.to(device) + else: + cast_mask = None + return NestedTensor(cast_tensor, cast_mask) + + def decompose(self): + return self.tensors, self.mask + + def __repr__(self): + return str(self.tensors) + + +# Copied from transformers.models.detr.modeling_detr.nested_tensor_from_tensor_list +def nested_tensor_from_tensor_list(tensor_list: List[Tensor]): + if tensor_list[0].ndim == 3: + max_size = _max_by_axis([list(img.shape) for img in tensor_list]) + batch_shape = [len(tensor_list)] + max_size + batch_size, num_channels, height, width = batch_shape + dtype = tensor_list[0].dtype + device = tensor_list[0].device + tensor = torch.zeros(batch_shape, dtype=dtype, device=device) + mask = torch.ones((batch_size, height, width), dtype=torch.bool, device=device) + for img, pad_img, m in zip(tensor_list, tensor, mask): + pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img) + m[: img.shape[1], : img.shape[2]] = False + else: + raise ValueError("Only 3-dimensional tensors are supported") + return NestedTensor(tensor, mask) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a0b44186efbc05bef9faed3a47057fcfe3610862 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/__init__.py @@ -0,0 +1,113 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_tf_available, + is_torch_available, + is_vision_available, +) + + +_import_structure = {"configuration_deit": ["DEIT_PRETRAINED_CONFIG_ARCHIVE_MAP", "DeiTConfig", "DeiTOnnxConfig"]} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_deit"] = ["DeiTFeatureExtractor"] + _import_structure["image_processing_deit"] = ["DeiTImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_deit"] = [ + "DEIT_PRETRAINED_MODEL_ARCHIVE_LIST", + "DeiTForImageClassification", + "DeiTForImageClassificationWithTeacher", + "DeiTForMaskedImageModeling", + "DeiTModel", + "DeiTPreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_deit"] = [ + "TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFDeiTForImageClassification", + "TFDeiTForImageClassificationWithTeacher", + "TFDeiTForMaskedImageModeling", + "TFDeiTModel", + "TFDeiTPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_deit import DEIT_PRETRAINED_CONFIG_ARCHIVE_MAP, DeiTConfig, DeiTOnnxConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_deit import DeiTFeatureExtractor + from .image_processing_deit import DeiTImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_deit import ( + DEIT_PRETRAINED_MODEL_ARCHIVE_LIST, + DeiTForImageClassification, + DeiTForImageClassificationWithTeacher, + DeiTForMaskedImageModeling, + DeiTModel, + DeiTPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_deit import ( + TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST, + TFDeiTForImageClassification, + TFDeiTForImageClassificationWithTeacher, + TFDeiTForMaskedImageModeling, + TFDeiTModel, + TFDeiTPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/configuration_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/configuration_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..b395afdbef5cf38cf16539c63bc49ca5c9e3cf21 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/configuration_deit.py @@ -0,0 +1,145 @@ +# coding=utf-8 +# Copyright 2021 Facebook AI Research (FAIR) and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DeiT model configuration""" + +from collections import OrderedDict +from typing import Mapping + +from packaging import version + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DEIT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/deit-base-distilled-patch16-224": ( + "https://huggingface.co/facebook/deit-base-patch16-224/resolve/main/config.json" + ), + # See all DeiT models at https://huggingface.co/models?filter=deit +} + + +class DeiTConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DeiTModel`]. It is used to instantiate an DeiT + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the DeiT + [facebook/deit-base-distilled-patch16-224](https://huggingface.co/facebook/deit-base-distilled-patch16-224) + architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + image_size (`int`, *optional*, defaults to `224`): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to `16`): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to `3`): + The number of input channels. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + encoder_stride (`int`, `optional`, defaults to 16): + Factor to increase the spatial resolution by in the decoder head for masked image modeling. + + Example: + + ```python + >>> from transformers import DeiTConfig, DeiTModel + + >>> # Initializing a DeiT deit-base-distilled-patch16-224 style configuration + >>> configuration = DeiTConfig() + + >>> # Initializing a model (with random weights) from the deit-base-distilled-patch16-224 style configuration + >>> model = DeiTModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "deit" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + image_size=224, + patch_size=16, + num_channels=3, + qkv_bias=True, + encoder_stride=16, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias + self.encoder_stride = encoder_stride + + +class DeiTOnnxConfig(OnnxConfig): + torch_onnx_minimum_version = version.parse("1.11") + + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + return OrderedDict( + [ + ("pixel_values", {0: "batch", 1: "num_channels", 2: "height", 3: "width"}), + ] + ) + + @property + def atol_for_validation(self) -> float: + return 1e-4 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/convert_deit_timm_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/convert_deit_timm_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..a91702106e0f8c566c619d8449b07ac408316fd2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/convert_deit_timm_to_pytorch.py @@ -0,0 +1,219 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DeiT distilled checkpoints from the timm library.""" + + +import argparse +import json +from pathlib import Path + +import requests +import timm +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import DeiTConfig, DeiTFeatureExtractor, DeiTForImageClassificationWithTeacher +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def create_rename_keys(config, base_model=False): + rename_keys = [] + for i in range(config.num_hidden_layers): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append((f"blocks.{i}.norm1.weight", f"deit.encoder.layer.{i}.layernorm_before.weight")) + rename_keys.append((f"blocks.{i}.norm1.bias", f"deit.encoder.layer.{i}.layernorm_before.bias")) + rename_keys.append((f"blocks.{i}.attn.proj.weight", f"deit.encoder.layer.{i}.attention.output.dense.weight")) + rename_keys.append((f"blocks.{i}.attn.proj.bias", f"deit.encoder.layer.{i}.attention.output.dense.bias")) + rename_keys.append((f"blocks.{i}.norm2.weight", f"deit.encoder.layer.{i}.layernorm_after.weight")) + rename_keys.append((f"blocks.{i}.norm2.bias", f"deit.encoder.layer.{i}.layernorm_after.bias")) + rename_keys.append((f"blocks.{i}.mlp.fc1.weight", f"deit.encoder.layer.{i}.intermediate.dense.weight")) + rename_keys.append((f"blocks.{i}.mlp.fc1.bias", f"deit.encoder.layer.{i}.intermediate.dense.bias")) + rename_keys.append((f"blocks.{i}.mlp.fc2.weight", f"deit.encoder.layer.{i}.output.dense.weight")) + rename_keys.append((f"blocks.{i}.mlp.fc2.bias", f"deit.encoder.layer.{i}.output.dense.bias")) + + # projection layer + position embeddings + rename_keys.extend( + [ + ("cls_token", "deit.embeddings.cls_token"), + ("dist_token", "deit.embeddings.distillation_token"), + ("patch_embed.proj.weight", "deit.embeddings.patch_embeddings.projection.weight"), + ("patch_embed.proj.bias", "deit.embeddings.patch_embeddings.projection.bias"), + ("pos_embed", "deit.embeddings.position_embeddings"), + ] + ) + + if base_model: + # layernorm + pooler + rename_keys.extend( + [ + ("norm.weight", "layernorm.weight"), + ("norm.bias", "layernorm.bias"), + ("pre_logits.fc.weight", "pooler.dense.weight"), + ("pre_logits.fc.bias", "pooler.dense.bias"), + ] + ) + + # if just the base model, we should remove "deit" from all keys that start with "deit" + rename_keys = [(pair[0], pair[1][4:]) if pair[1].startswith("deit") else pair for pair in rename_keys] + else: + # layernorm + classification heads + rename_keys.extend( + [ + ("norm.weight", "deit.layernorm.weight"), + ("norm.bias", "deit.layernorm.bias"), + ("head.weight", "cls_classifier.weight"), + ("head.bias", "cls_classifier.bias"), + ("head_dist.weight", "distillation_classifier.weight"), + ("head_dist.bias", "distillation_classifier.bias"), + ] + ) + + return rename_keys + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_q_k_v(state_dict, config, base_model=False): + for i in range(config.num_hidden_layers): + if base_model: + prefix = "" + else: + prefix = "deit." + # read in weights + bias of input projection layer (in timm, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"blocks.{i}.attn.qkv.weight") + in_proj_bias = state_dict.pop(f"blocks.{i}.attn.qkv.bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[ + : config.hidden_size, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[: config.hidden_size] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[ + config.hidden_size : config.hidden_size * 2 + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[ + -config.hidden_size :, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-config.hidden_size :] + + +def rename_key(dct, old, new): + val = dct.pop(old) + dct[new] = val + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@torch.no_grad() +def convert_deit_checkpoint(deit_name, pytorch_dump_folder_path): + """ + Copy/paste/tweak model's weights to our DeiT structure. + """ + + # define default DeiT configuration + config = DeiTConfig() + # all deit models have fine-tuned heads + base_model = False + # dataset (fine-tuned on ImageNet 2012), patch_size and image_size + config.num_labels = 1000 + repo_id = "huggingface/label-files" + filename = "imagenet-1k-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + config.patch_size = int(deit_name[-6:-4]) + config.image_size = int(deit_name[-3:]) + # size of the architecture + if deit_name[9:].startswith("tiny"): + config.hidden_size = 192 + config.intermediate_size = 768 + config.num_hidden_layers = 12 + config.num_attention_heads = 3 + elif deit_name[9:].startswith("small"): + config.hidden_size = 384 + config.intermediate_size = 1536 + config.num_hidden_layers = 12 + config.num_attention_heads = 6 + if deit_name[9:].startswith("base"): + pass + elif deit_name[4:].startswith("large"): + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + + # load original model from timm + timm_model = timm.create_model(deit_name, pretrained=True) + timm_model.eval() + + # load state_dict of original model, remove and rename some keys + state_dict = timm_model.state_dict() + rename_keys = create_rename_keys(config, base_model) + for src, dest in rename_keys: + rename_key(state_dict, src, dest) + read_in_q_k_v(state_dict, config, base_model) + + # load HuggingFace model + model = DeiTForImageClassificationWithTeacher(config).eval() + model.load_state_dict(state_dict) + + # Check outputs on an image, prepared by DeiTFeatureExtractor + size = int( + (256 / 224) * config.image_size + ) # to maintain same ratio w.r.t. 224 images, see https://github.com/facebookresearch/deit/blob/ab5715372db8c6cad5740714b2216d55aeae052e/datasets.py#L103 + feature_extractor = DeiTFeatureExtractor(size=size, crop_size=config.image_size) + encoding = feature_extractor(images=prepare_img(), return_tensors="pt") + pixel_values = encoding["pixel_values"] + outputs = model(pixel_values) + + timm_logits = timm_model(pixel_values) + assert timm_logits.shape == outputs.logits.shape + assert torch.allclose(timm_logits, outputs.logits, atol=1e-3) + + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + print(f"Saving model {deit_name} to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--deit_name", + default="vit_deit_base_distilled_patch16_224", + type=str, + help="Name of the DeiT timm model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + + args = parser.parse_args() + convert_deit_checkpoint(args.deit_name, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/feature_extraction_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/feature_extraction_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..b66922ea95753a81b93a3f9c99607119017df3f3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/feature_extraction_deit.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for DeiT.""" + +import warnings + +from ...utils import logging +from .image_processing_deit import DeiTImageProcessor + + +logger = logging.get_logger(__name__) + + +class DeiTFeatureExtractor(DeiTImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class DeiTFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please" + " use DeiTImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/image_processing_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/image_processing_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..3f9d5ee2d0aba0a2b191bf6c1cb611428d0fc7ea --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/image_processing_deit.py @@ -0,0 +1,314 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for DeiT.""" + +from typing import Dict, List, Optional, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import center_crop, normalize, rescale, resize, to_channel_dimension_format +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + make_list_of_images, + to_numpy_array, + valid_images, +) +from ...utils import TensorType, is_vision_available, logging + + +if is_vision_available(): + import PIL + + +logger = logging.get_logger(__name__) + + +class DeiTImageProcessor(BaseImageProcessor): + r""" + Constructs a DeiT image processor. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Whether to resize the image's (height, width) dimensions to the specified `size`. Can be overridden by + `do_resize` in `preprocess`. + size (`Dict[str, int]` *optional*, defaults to `{"height": 256, "width": 256}`): + Size of the image after `resize`. Can be overridden by `size` in `preprocess`. + resample (`PILImageResampling` filter, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use if resizing the image. Can be overridden by `resample` in `preprocess`. + do_center_crop (`bool`, *optional*, defaults to `True`): + Whether to center crop the image. If the input size is smaller than `crop_size` along any edge, the image + is padded with 0's and then center cropped. Can be overridden by `do_center_crop` in `preprocess`. + crop_size (`Dict[str, int]`, *optional*, defaults to `{"height": 224, "width": 224}`): + Desired output size when applying center-cropping. Can be overridden by `crop_size` in `preprocess`. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the `do_rescale` + parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess` + method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`): + Mean to use if normalizing the image. This is a float or list of floats the length of the number of + channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`): + Standard deviation to use if normalizing the image. This is a float or list of floats the length of the + number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values"] + + def __init__( + self, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PIL.Image.BICUBIC, + do_center_crop: bool = True, + crop_size: Dict[str, int] = None, + rescale_factor: Union[int, float] = 1 / 255, + do_rescale: bool = True, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + **kwargs, + ) -> None: + super().__init__(**kwargs) + size = size if size is not None else {"height": 256, "width": 256} + size = get_size_dict(size) + crop_size = crop_size if crop_size is not None else {"height": 224, "width": 224} + crop_size = get_size_dict(crop_size, param_name="crop_size") + + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_STANDARD_STD + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PIL.Image.BICUBIC, + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize an image to `(size["height"], size["width"])` using the specified resampling filter. + + Args: + image (`np.ndarray`): + Image to resize. + size (`Dict[str, int]`): + Size of the output image. + resample (`PILImageResampling` filter, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use when resizing the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size) + if "height" not in size or "width" not in size: + raise ValueError(f"The size dictionary must have keys 'height' and 'width'. Got {size.keys()}") + return resize( + image, size=(size["height"], size["width"]), resample=resample, data_format=data_format, **kwargs + ) + + def center_crop( + self, + image: np.ndarray, + size: Dict[str, int], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Center crop an image to `(crop_size["height"], crop_size["width"])`. If the input size is smaller than + `crop_size` along any edge, the image is padded with 0's and then center cropped. + + Args: + image (`np.ndarray`): + Image to center crop. + size (`Dict[str, int]`): + Size of the output image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size) + if "height" not in size or "width" not in size: + raise ValueError(f"The size dictionary must have keys 'height' and 'width'. Got {size.keys()}") + return center_crop(image, size=(size["height"], size["width"]), data_format=data_format, **kwargs) + + def rescale( + self, + image: np.ndarray, + scale: Union[int, float], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ): + """ + Rescale an image by a scale factor. image = image * scale. + + Args: + image (`np.ndarray`): + Image to rescale. + scale (`int` or `float`): + Scale to apply to the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return rescale(image, scale=scale, data_format=data_format, **kwargs) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, List[float]], + std: Union[float, List[float]], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Normalize an image. image = (image - image_mean) / image_std. + + Args: + image (`np.ndarray`): + Image to normalize. + image_mean (`float` or `List[float]`): + Image mean. + image_std (`float` or `List[float]`): + Image standard deviation. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return normalize(image, mean=mean, std=std, data_format=data_format, **kwargs) + + def preprocess( + self, + images: ImageInput, + do_resize: bool = None, + size: Dict[str, int] = None, + resample=None, + do_center_crop: bool = None, + crop_size: Dict[str, int] = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: ChannelDimension = ChannelDimension.FIRST, + **kwargs, + ) -> PIL.Image.Image: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Size of the image after `resize`. + resample (`PILImageResampling`, *optional*, defaults to `self.resample`): + PILImageResampling filter to use if resizing the image Only has an effect if `do_resize` is set to + `True`. + do_center_crop (`bool`, *optional*, defaults to `self.do_center_crop`): + Whether to center crop the image. + crop_size (`Dict[str, int]`, *optional*, defaults to `self.crop_size`): + Size of the image after center crop. If one edge the image is smaller than `crop_size`, it will be + padded with zeros and then cropped + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image values between [0 - 1]. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - `None`: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `ChannelDimension.LAST`: image in (height, width, num_channels) format. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + resample = resample if resample is not None else self.resample + do_center_crop = do_center_crop if do_center_crop is not None else self.do_center_crop + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + + size = size if size is not None else self.size + size = get_size_dict(size) + crop_size = crop_size if crop_size is not None else self.crop_size + crop_size = get_size_dict(crop_size, param_name="crop_size") + + images = make_list_of_images(images) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + if do_resize and size is None or resample is None: + raise ValueError("Size and resample must be specified if do_resize is True.") + + if do_center_crop and crop_size is None: + raise ValueError("Crop size must be specified if do_center_crop is True.") + + if do_rescale and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_resize: + images = [self.resize(image=image, size=size, resample=resample) for image in images] + + if do_center_crop: + images = [self.center_crop(image=image, size=crop_size) for image in images] + + if do_rescale: + images = [self.rescale(image=image, scale=rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image=image, mean=image_mean, std=image_std) for image in images] + + images = [to_channel_dimension_format(image, data_format) for image in images] + + data = {"pixel_values": images} + return BatchFeature(data=data, tensor_type=return_tensors) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..8b03835812fcdf47f4e035b27b027e7395a5320f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_deit.py @@ -0,0 +1,904 @@ +# coding=utf-8 +# Copyright 2021 Facebook AI Research (FAIR), Ross Wightman, The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DeiT model.""" + + +import collections.abc +import math +from dataclasses import dataclass +from typing import Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPooling, + ImageClassifierOutput, + MaskedImageModelingOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_deit import DeiTConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "DeiTConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/deit-base-distilled-patch16-224" +_EXPECTED_OUTPUT_SHAPE = [1, 198, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "facebook/deit-base-distilled-patch16-224" +_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" + + +DEIT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/deit-base-distilled-patch16-224", + # See all DeiT models at https://huggingface.co/models?filter=deit +] + + +class DeiTEmbeddings(nn.Module): + """ + Construct the CLS token, distillation token, position and patch embeddings. Optionally, also the mask token. + """ + + def __init__(self, config: DeiTConfig, use_mask_token: bool = False) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.distillation_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) if use_mask_token else None + self.patch_embeddings = DeiTPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 2, config.hidden_size)) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, pixel_values: torch.Tensor, bool_masked_pos: Optional[torch.BoolTensor] = None) -> torch.Tensor: + embeddings = self.patch_embeddings(pixel_values) + batch_size, seq_length, _ = embeddings.size() + + if bool_masked_pos is not None: + mask_tokens = self.mask_token.expand(batch_size, seq_length, -1) + # replace the masked visual tokens by mask_tokens + mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + distillation_tokens = self.distillation_token.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, distillation_tokens, embeddings), dim=1) + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings) + return embeddings + + +class DeiTPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model ({self.image_size[0]}*{self.image_size[1]})." + ) + x = self.projection(pixel_values).flatten(2).transpose(1, 2) + return x + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfAttention with ViT->DeiT +class DeiTSelfAttention(nn.Module): + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfOutput with ViT->DeiT +class DeiTSelfOutput(nn.Module): + """ + The residual connection is defined in DeiTLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTAttention with ViT->DeiT +class DeiTAttention(nn.Module): + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.attention = DeiTSelfAttention(config) + self.output = DeiTSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTIntermediate with ViT->DeiT +class DeiTIntermediate(nn.Module): + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTOutput with ViT->DeiT +class DeiTOutput(nn.Module): + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTLayer with ViT->DeiT +class DeiTLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = DeiTAttention(config) + self.intermediate = DeiTIntermediate(config) + self.output = DeiTOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in DeiT, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + hidden_states = attention_output + hidden_states + + # in DeiT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTEncoder with ViT->DeiT +class DeiTEncoder(nn.Module): + def __init__(self, config: DeiTConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([DeiTLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class DeiTPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DeiTConfig + base_model_prefix = "deit" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + _no_split_modules = [] + + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Upcast the input in `fp32` and cast it back to desired `dtype` to avoid + # `trunc_normal_cpu` not implemented in `half` issues + module.weight.data = nn.init.trunc_normal_( + module.weight.data.to(torch.float32), mean=0.0, std=self.config.initializer_range + ).to(module.weight.dtype) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module: DeiTEncoder, value: bool = False) -> None: + if isinstance(module, DeiTEncoder): + module.gradient_checkpointing = value + + +DEIT_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`DeiTConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`DeiTImageProcessor.__call__`] for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeiT Model transformer outputting raw hidden-states without any specific head on top.", + DEIT_START_DOCSTRING, +) +class DeiTModel(DeiTPreTrainedModel): + def __init__(self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False) -> None: + super().__init__(config) + self.config = config + + self.embeddings = DeiTEmbeddings(config, use_mask_token=use_mask_token) + self.encoder = DeiTEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.pooler = DeiTPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> DeiTPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + # TODO: maybe have a cleaner way to cast the input (from `ImageProcessor` side?) + expected_dtype = self.embeddings.patch_embeddings.projection.weight.dtype + if pixel_values.dtype != expected_dtype: + pixel_values = pixel_values.to(expected_dtype) + + embedding_output = self.embeddings(pixel_values, bool_masked_pos=bool_masked_pos) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Copied from transformers.models.vit.modeling_vit.ViTPooler with ViT->DeiT +class DeiTPooler(nn.Module): + def __init__(self, config: DeiTConfig): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +@add_start_docstrings( + """DeiT Model with a decoder on top for masked image modeling, as proposed in [SimMIM](https://arxiv.org/abs/2111.09886). + + + + Note that we provide a script to pre-train this model on custom data in our [examples + directory](https://github.com/huggingface/transformers/tree/main/examples/pytorch/image-pretraining). + + + """, + DEIT_START_DOCSTRING, +) +class DeiTForMaskedImageModeling(DeiTPreTrainedModel): + def __init__(self, config: DeiTConfig) -> None: + super().__init__(config) + + self.deit = DeiTModel(config, add_pooling_layer=False, use_mask_token=True) + + self.decoder = nn.Sequential( + nn.Conv2d( + in_channels=config.hidden_size, + out_channels=config.encoder_stride**2 * config.num_channels, + kernel_size=1, + ), + nn.PixelShuffle(config.encoder_stride), + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=MaskedImageModelingOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, MaskedImageModelingOutput]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + + Returns: + + Examples: + ```python + >>> from transformers import AutoImageProcessor, DeiTForMaskedImageModeling + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") + >>> model = DeiTForMaskedImageModeling.from_pretrained("facebook/deit-base-distilled-patch16-224") + + >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2 + >>> pixel_values = image_processor(images=image, return_tensors="pt").pixel_values + >>> # create random boolean mask of shape (batch_size, num_patches) + >>> bool_masked_pos = torch.randint(low=0, high=2, size=(1, num_patches)).bool() + + >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos) + >>> loss, reconstructed_pixel_values = outputs.loss, outputs.reconstruction + >>> list(reconstructed_pixel_values.shape) + [1, 3, 224, 224] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + bool_masked_pos=bool_masked_pos, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + # Reshape to (batch_size, num_channels, height, width) + sequence_output = sequence_output[:, 1:-1] + batch_size, sequence_length, num_channels = sequence_output.shape + height = width = int(sequence_length**0.5) + sequence_output = sequence_output.permute(0, 2, 1).reshape(batch_size, num_channels, height, width) + + # Reconstruct pixel values + reconstructed_pixel_values = self.decoder(sequence_output) + + masked_im_loss = None + if bool_masked_pos is not None: + size = self.config.image_size // self.config.patch_size + bool_masked_pos = bool_masked_pos.reshape(-1, size, size) + mask = ( + bool_masked_pos.repeat_interleave(self.config.patch_size, 1) + .repeat_interleave(self.config.patch_size, 2) + .unsqueeze(1) + .contiguous() + ) + reconstruction_loss = nn.functional.l1_loss(pixel_values, reconstructed_pixel_values, reduction="none") + masked_im_loss = (reconstruction_loss * mask).sum() / (mask.sum() + 1e-5) / self.config.num_channels + + if not return_dict: + output = (reconstructed_pixel_values,) + outputs[1:] + return ((masked_im_loss,) + output) if masked_im_loss is not None else output + + return MaskedImageModelingOutput( + loss=masked_im_loss, + reconstruction=reconstructed_pixel_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + DeiT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of + the [CLS] token) e.g. for ImageNet. + """, + DEIT_START_DOCSTRING, +) +class DeiTForImageClassification(DeiTPreTrainedModel): + def __init__(self, config: DeiTConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.deit = DeiTModel(config, add_pooling_layer=False) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=ImageClassifierOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DeiTForImageClassification + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> torch.manual_seed(3) # doctest: +IGNORE_RESULT + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> # note: we are loading a DeiTForImageClassificationWithTeacher from the hub here, + >>> # so the head will be randomly initialized, hence the predictions will be random + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") + >>> model = DeiTForImageClassification.from_pretrained("facebook/deit-base-distilled-patch16-224") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + >>> logits = outputs.logits + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_class_idx = logits.argmax(-1).item() + >>> print("Predicted class:", model.config.id2label[predicted_class_idx]) + Predicted class: magpie + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output[:, 0, :]) + # we don't use the distillation token + + loss = None + if labels is not None: + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@dataclass +class DeiTForImageClassificationWithTeacherOutput(ModelOutput): + """ + Output type of [`DeiTForImageClassificationWithTeacher`]. + + Args: + logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores as the average of the cls_logits and distillation logits. + cls_logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the classification head (i.e. the linear layer on top of the final hidden state of the + class token). + distillation_logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the distillation head (i.e. the linear layer on top of the final hidden state of the + distillation token). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer + plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + logits: torch.FloatTensor = None + cls_logits: torch.FloatTensor = None + distillation_logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@add_start_docstrings( + """ + DeiT Model transformer with image classification heads on top (a linear layer on top of the final hidden state of + the [CLS] token and a linear layer on top of the final hidden state of the distillation token) e.g. for ImageNet. + + .. warning:: + + This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet + supported. + """, + DEIT_START_DOCSTRING, +) +class DeiTForImageClassificationWithTeacher(DeiTPreTrainedModel): + def __init__(self, config: DeiTConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.deit = DeiTModel(config, add_pooling_layer=False) + + # Classifier heads + self.cls_classifier = ( + nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + ) + self.distillation_classifier = ( + nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=DeiTForImageClassificationWithTeacherOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, DeiTForImageClassificationWithTeacherOutput]: + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + cls_logits = self.cls_classifier(sequence_output[:, 0, :]) + distillation_logits = self.distillation_classifier(sequence_output[:, 1, :]) + + # during inference, return the average of both classifier predictions + logits = (cls_logits + distillation_logits) / 2 + + if not return_dict: + output = (logits, cls_logits, distillation_logits) + outputs[1:] + return output + + return DeiTForImageClassificationWithTeacherOutput( + logits=logits, + cls_logits=cls_logits, + distillation_logits=distillation_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_tf_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_tf_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..a3d487021d4b39df01d54872d6d8edd618c0ba7b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deit/modeling_tf_deit.py @@ -0,0 +1,1069 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI Research (FAIR) and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TensorFlow DeiT model.""" + + +import collections.abc +import math +from dataclasses import dataclass +from typing import Dict, Optional, Tuple, Union + +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFBaseModelOutputWithPooling, + TFImageClassifierOutput, + TFMaskedImageModelingOutput, +) +from ...modeling_tf_utils import ( + TFPreTrainedModel, + TFSequenceClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_deit import DeiTConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "DeiTConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/deit-base-distilled-patch16-224" +_EXPECTED_OUTPUT_SHAPE = [1, 198, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "facebook/deit-base-distilled-patch16-224" +_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" + + +TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/deit-base-distilled-patch16-224", + # See all DeiT models at https://huggingface.co/models?filter=deit +] + + +@dataclass +class TFDeiTForImageClassificationWithTeacherOutput(ModelOutput): + """ + Output type of [`DeiTForImageClassificationWithTeacher`]. + + Args: + logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): + Prediction scores as the average of the cls_logits and distillation logits. + cls_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the classification head (i.e. the linear layer on top of the final hidden state of the + class token). + distillation_logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the distillation head (i.e. the linear layer on top of the final hidden state of the + distillation token). + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus + the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + logits: tf.Tensor = None + cls_logits: tf.Tensor = None + distillation_logits: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +class TFDeiTEmbeddings(tf.keras.layers.Layer): + """ + Construct the CLS token, distillation token, position and patch embeddings. Optionally, also the mask token. + """ + + def __init__(self, config: DeiTConfig, use_mask_token: bool = False, **kwargs) -> None: + super().__init__(**kwargs) + self.config = config + self.use_mask_token = use_mask_token + self.patch_embeddings = TFDeiTPatchEmbeddings(config=config, name="patch_embeddings") + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob, name="dropout") + + def build(self, input_shape: tf.TensorShape): + self.cls_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.keras.initializers.zeros(), + trainable=True, + name="cls_token", + ) + self.distillation_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.keras.initializers.zeros(), + trainable=True, + name="distillation_token", + ) + self.mask_token = None + if self.use_mask_token: + self.mask_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.keras.initializers.zeros(), + trainable=True, + name="mask_token", + ) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = self.add_weight( + shape=(1, num_patches + 2, self.config.hidden_size), + initializer=tf.keras.initializers.zeros(), + trainable=True, + name="position_embeddings", + ) + super().build(input_shape) + + def call( + self, pixel_values: tf.Tensor, bool_masked_pos: Optional[tf.Tensor] = None, training: bool = False + ) -> tf.Tensor: + embeddings = self.patch_embeddings(pixel_values) + batch_size, seq_length, _ = shape_list(embeddings) + + if bool_masked_pos is not None: + mask_tokens = tf.tile(self.mask_token, [batch_size, seq_length, 1]) + # replace the masked visual tokens by mask_tokens + mask = tf.expand_dims(bool_masked_pos, axis=-1) + mask = tf.cast(mask, dtype=mask_tokens.dtype) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + cls_tokens = tf.repeat(self.cls_token, repeats=batch_size, axis=0) + distillation_tokens = tf.repeat(self.distillation_token, repeats=batch_size, axis=0) + embeddings = tf.concat((cls_tokens, distillation_tokens, embeddings), axis=1) + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings, training=training) + return embeddings + + +class TFDeiTPatchEmbeddings(tf.keras.layers.Layer): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config: DeiTConfig, **kwargs) -> None: + super().__init__(**kwargs) + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + + self.projection = tf.keras.layers.Conv2D( + hidden_size, kernel_size=patch_size, strides=patch_size, name="projection" + ) + + def call(self, pixel_values: tf.Tensor) -> tf.Tensor: + batch_size, height, width, num_channels = shape_list(pixel_values) + if tf.executing_eagerly() and num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + if tf.executing_eagerly() and (height != self.image_size[0] or width != self.image_size[1]): + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model ({self.image_size[0]}*{self.image_size[1]})." + ) + x = self.projection(pixel_values) + batch_size, height, width, num_channels = shape_list(x) + x = tf.reshape(x, (batch_size, height * width, num_channels)) + return x + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfAttention with ViT->DeiT +class TFDeiTSelfAttention(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(hidden_states)[0] + mixed_query_layer = self.query(inputs=hidden_states) + mixed_key_layer = self.key(inputs=hidden_states) + mixed_value_layer = self.value(inputs=hidden_states) + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) + value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) + attention_scores = tf.divide(attention_scores, dk) + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + attention_output = tf.matmul(attention_probs, value_layer) + attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) + outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfOutput with ViT->DeiT +class TFDeiTSelfOutput(tf.keras.layers.Layer): + """ + The residual connection is defined in TFDeiTLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTAttention with ViT->DeiT +class TFDeiTAttention(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.self_attention = TFDeiTSelfAttention(config, name="attention") + self.dense_output = TFDeiTSelfOutput(config, name="output") + + def prune_heads(self, heads): + raise NotImplementedError + + def call( + self, + input_tensor: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self_attention( + hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training + ) + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=input_tensor, training=training + ) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->DeiT +class TFDeiTIntermediate(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTOutput with ViT->DeiT +class TFDeiTOutput(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + hidden_states = hidden_states + input_tensor + + return hidden_states + + +class TFDeiTLayer(tf.keras.layers.Layer): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFDeiTAttention(config, name="attention") + self.intermediate = TFDeiTIntermediate(config, name="intermediate") + self.deit_output = TFDeiTOutput(config, name="output") + + self.layernorm_before = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_before" + ) + self.layernorm_after = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_after" + ) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + # in DeiT, layernorm is applied before self-attention + input_tensor=self.layernorm_before(inputs=hidden_states, training=training), + head_mask=head_mask, + output_attentions=output_attentions, + training=training, + ) + attention_output = attention_outputs[0] + + # first residual connection + hidden_states = attention_output + hidden_states + + # in DeiT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(inputs=hidden_states, training=training) + + intermediate_output = self.intermediate(hidden_states=layer_output, training=training) + + # second residual connection is done here + layer_output = self.deit_output( + hidden_states=intermediate_output, input_tensor=hidden_states, training=training + ) + outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTEncoder with ViT->DeiT +class TFDeiTEncoder(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.layer = [TFDeiTLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + output_hidden_states: bool, + return_dict: bool, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states=hidden_states, + head_mask=head_mask[i], + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +@keras_serializable +class TFDeiTMainLayer(tf.keras.layers.Layer): + config_class = DeiTConfig + + def __init__( + self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs + ) -> None: + super().__init__(**kwargs) + self.config = config + + self.embeddings = TFDeiTEmbeddings(config, use_mask_token=use_mask_token, name="embeddings") + self.encoder = TFDeiTEncoder(config, name="encoder") + + self.layernorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") + self.pooler = TFDeiTPooler(config, name="pooler") if add_pooling_layer else None + + def get_input_embeddings(self) -> TFDeiTPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + def get_head_mask(self, head_mask): + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + return head_mask + + @unpack_inputs + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + bool_masked_pos: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor, ...]]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # TF 2.0 image layers can't use NCHW format when running on CPU. + # (batch_size, num_channels, height, width) -> (batch_size, height, width, num_channels) + pixel_values = tf.transpose(pixel_values, (0, 2, 3, 1)) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask) + + embedding_output = self.embeddings(pixel_values, bool_masked_pos=bool_masked_pos, training=training) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output, training=training) + pooled_output = self.pooler(sequence_output, training=training) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return TFBaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTPreTrainedModel with ViT->DeiT all-casing +class TFDeiTPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DeiTConfig + base_model_prefix = "deit" + main_input_name = "pixel_values" + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + """ + Dummy inputs to build the network. + + Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + VISION_DUMMY_INPUTS = tf.random.uniform( + shape=(3, self.config.num_channels, self.config.image_size, self.config.image_size), dtype=tf.float32 + ) + return {"pixel_values": tf.constant(VISION_DUMMY_INPUTS)} + + @tf.function( + input_signature=[ + { + "pixel_values": tf.TensorSpec((None, None, None, None), tf.float32, name="pixel_values"), + } + ] + ) + def serving(self, inputs): + """ + Method used for serving the model. + + Args: + inputs (`Dict[str, tf.Tensor]`): + The input of the saved model as a dictionary of tensors. + """ + output = self.call(inputs) + + return self.serving_output(output) + + +DEIT_START_DOCSTRING = r""" + This model is a TensorFlow + [tf.keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer). Use it as a regular + TensorFlow Module and refer to the TensorFlow documentation for all matter related to general usage and behavior. + + Parameters: + config ([`DeiTConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DEIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`DeiTImageProcessor.__call__`] for details. + + head_mask (`tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DeiT Model transformer outputting raw hidden-states without any specific head on top.", + DEIT_START_DOCSTRING, +) +class TFDeiTModel(TFDeiTPreTrainedModel): + def __init__( + self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False, **kwargs + ) -> None: + super().__init__(config, **kwargs) + + self.deit = TFDeiTMainLayer( + config, add_pooling_layer=add_pooling_layer, use_mask_token=use_mask_token, name="deit" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + bool_masked_pos: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[Tuple, TFBaseModelOutputWithPooling]: + outputs = self.deit( + pixel_values=pixel_values, + bool_masked_pos=bool_masked_pos, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + return outputs + + def serving_output(self, output: TFBaseModelOutputWithPooling) -> TFBaseModelOutputWithPooling: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutputWithPooling( + last_hidden_state=output.last_hidden_state, + pooler_output=output.pooler_output, + hidden_states=hidden_states, + attentions=attentions, + ) + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTPooler with ViT->DeiT +class TFDeiTPooler(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + activation="tanh", + name="dense", + ) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(inputs=first_token_tensor) + + return pooled_output + + +class TFDeitPixelShuffle(tf.keras.layers.Layer): + """TF layer implementation of torch.nn.PixelShuffle""" + + def __init__(self, upscale_factor: int, **kwargs) -> None: + super().__init__(**kwargs) + if not isinstance(upscale_factor, int) or upscale_factor < 2: + raise ValueError(f"upscale_factor must be an integer value >= 2 got {upscale_factor}") + self.upscale_factor = upscale_factor + + def call(self, x: tf.Tensor) -> tf.Tensor: + hidden_states = x + batch_size, _, _, num_input_channels = shape_list(hidden_states) + block_size_squared = self.upscale_factor**2 + output_depth = int(num_input_channels / block_size_squared) + # When the number of output channels >= 2, PyTorch's PixelShuffle and + # TF's depth_to_space differ in their output as the order of channels selected for combining + # is a permutation of the other c.f. + # https://stackoverflow.com/questions/68272502/tf-depth-to-space-not-same-as-torchs-pixelshuffle-when-output-channels-1 + permutation = tf.constant( + [[i + j * block_size_squared for i in range(block_size_squared) for j in range(output_depth)]] + ) + hidden_states = tf.gather(params=hidden_states, indices=tf.tile(permutation, [batch_size, 1]), batch_dims=-1) + hidden_states = tf.nn.depth_to_space(hidden_states, block_size=self.upscale_factor, data_format="NHWC") + return hidden_states + + +class TFDeitDecoder(tf.keras.layers.Layer): + def __init__(self, config: DeiTConfig, **kwargs) -> None: + super().__init__(**kwargs) + self.conv2d = tf.keras.layers.Conv2D( + filters=config.encoder_stride**2 * config.num_channels, kernel_size=1, name="0" + ) + self.pixel_shuffle = TFDeitPixelShuffle(config.encoder_stride, name="1") + + def call(self, inputs: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = inputs + hidden_states = self.conv2d(hidden_states) + hidden_states = self.pixel_shuffle(hidden_states) + return hidden_states + + +@add_start_docstrings( + "DeiT Model with a decoder on top for masked image modeling, as proposed in" + " [SimMIM](https://arxiv.org/abs/2111.09886).", + DEIT_START_DOCSTRING, +) +class TFDeiTForMaskedImageModeling(TFDeiTPreTrainedModel): + def __init__(self, config: DeiTConfig) -> None: + super().__init__(config) + + self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, use_mask_token=True, name="deit") + self.decoder = TFDeitDecoder(config, name="decoder") + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFMaskedImageModelingOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + bool_masked_pos: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[tuple, TFMaskedImageModelingOutput]: + r""" + bool_masked_pos (`tf.Tensor` of type bool and shape `(batch_size, num_patches)`): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + + Returns: + + Examples: + ```python + >>> from transformers import AutoImageProcessor, TFDeiTForMaskedImageModeling + >>> import tensorflow as tf + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") + >>> model = TFDeiTForMaskedImageModeling.from_pretrained("facebook/deit-base-distilled-patch16-224") + + >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2 + >>> pixel_values = image_processor(images=image, return_tensors="tf").pixel_values + >>> # create random boolean mask of shape (batch_size, num_patches) + >>> bool_masked_pos = tf.cast(tf.random.uniform((1, num_patches), minval=0, maxval=2, dtype=tf.int32), tf.bool) + + >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos) + >>> loss, reconstructed_pixel_values = outputs.loss, outputs.reconstruction + >>> list(reconstructed_pixel_values.shape) + [1, 3, 224, 224] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + bool_masked_pos=bool_masked_pos, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + + # Reshape to (batch_size, num_channels, height, width) + sequence_output = sequence_output[:, 1:-1] + batch_size, sequence_length, num_channels = shape_list(sequence_output) + height = width = int(sequence_length**0.5) + sequence_output = tf.reshape(sequence_output, (batch_size, height, width, num_channels)) + + # Reconstruct pixel values + reconstructed_pixel_values = self.decoder(sequence_output, training=training) + # TF 2.0 image layers can't use NCHW format when running on CPU, so intermediate layers use NHWC, + # including the The decoder. We transpose to compute the loss against the pixel values + # (batch_size, height, width, num_channels) -> (batch_size, num_channels, height, width) + reconstructed_pixel_values = tf.transpose(reconstructed_pixel_values, (0, 3, 1, 2)) + + masked_im_loss = None + if bool_masked_pos is not None: + size = self.config.image_size // self.config.patch_size + bool_masked_pos = tf.reshape(bool_masked_pos, (-1, size, size)) + mask = tf.repeat(bool_masked_pos, self.config.patch_size, 1) + mask = tf.repeat(mask, self.config.patch_size, 2) + mask = tf.expand_dims(mask, 1) + mask = tf.cast(mask, tf.float32) + + reconstruction_loss = tf.keras.losses.mean_absolute_error( + # Swap axes as metric calculation reduces over the final dimension + tf.transpose(pixel_values, (1, 2, 3, 0)), + tf.transpose(reconstructed_pixel_values, (1, 2, 3, 0)), + ) + reconstruction_loss = tf.expand_dims(reconstruction_loss, 0) + total_loss = tf.reduce_sum(reconstruction_loss * mask) + num_masked_pixels = (tf.reduce_sum(mask) + 1e-5) * self.config.num_channels + masked_im_loss = total_loss / num_masked_pixels + masked_im_loss = tf.reshape(masked_im_loss, (1,)) + + if not return_dict: + output = (reconstructed_pixel_values,) + outputs[1:] + return ((masked_im_loss,) + output) if masked_im_loss is not None else output + + return TFMaskedImageModelingOutput( + loss=masked_im_loss, + reconstruction=reconstructed_pixel_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFMaskedImageModelingOutput) -> TFMaskedImageModelingOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedImageModelingOutput( + reconstruction=output.reconstruction, hidden_states=hidden_states, attentions=attentions + ) + + +@add_start_docstrings( + """ + DeiT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of + the [CLS] token) e.g. for ImageNet. + """, + DEIT_START_DOCSTRING, +) +class TFDeiTForImageClassification(TFDeiTPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config: DeiTConfig): + super().__init__(config) + + self.num_labels = config.num_labels + self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, name="deit") + + # Classifier head + self.classifier = ( + tf.keras.layers.Dense(config.num_labels, name="classifier") + if config.num_labels > 0 + else tf.keras.layers.Activation("linear", name="classifier") + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFImageClassifierOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + labels: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[tf.Tensor, TFImageClassifierOutput]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, TFDeiTForImageClassification + >>> import tensorflow as tf + >>> from PIL import Image + >>> import requests + + >>> tf.keras.utils.set_random_seed(3) # doctest: +IGNORE_RESULT + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> # note: we are loading a TFDeiTForImageClassificationWithTeacher from the hub here, + >>> # so the head will be randomly initialized, hence the predictions will be random + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/deit-base-distilled-patch16-224") + >>> model = TFDeiTForImageClassification.from_pretrained("facebook/deit-base-distilled-patch16-224") + + >>> inputs = image_processor(images=image, return_tensors="tf") + >>> outputs = model(**inputs) + >>> logits = outputs.logits + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_class_idx = tf.math.argmax(logits, axis=-1)[0] + >>> print("Predicted class:", model.config.id2label[int(predicted_class_idx)]) + Predicted class: little blue heron, Egretta caerulea + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output[:, 0, :]) + # we don't use the distillation token + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFImageClassifierOutput) -> TFImageClassifierOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFImageClassifierOutput(logits=output.logits, hidden_states=hidden_states, attentions=attentions) + + +@add_start_docstrings( + """ + DeiT Model transformer with image classification heads on top (a linear layer on top of the final hidden state of + the [CLS] token and a linear layer on top of the final hidden state of the distillation token) e.g. for ImageNet. + + .. warning:: + + This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet + supported. + """, + DEIT_START_DOCSTRING, +) +class TFDeiTForImageClassificationWithTeacher(TFDeiTPreTrainedModel): + def __init__(self, config: DeiTConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.deit = TFDeiTMainLayer(config, add_pooling_layer=False, name="deit") + + # Classifier heads + self.cls_classifier = ( + tf.keras.layers.Dense(config.num_labels, name="cls_classifier") + if config.num_labels > 0 + else tf.keras.layers.Activation("linear", name="cls_classifier") + ) + self.distillation_classifier = ( + tf.keras.layers.Dense(config.num_labels, name="distillation_classifier") + if config.num_labels > 0 + else tf.keras.layers.Activation("linear", name="distillation_classifier") + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DEIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=TFDeiTForImageClassificationWithTeacherOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def call( + self, + pixel_values: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[tuple, TFDeiTForImageClassificationWithTeacherOutput]: + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.deit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + + cls_logits = self.cls_classifier(sequence_output[:, 0, :]) + distillation_logits = self.distillation_classifier(sequence_output[:, 1, :]) + + # during inference, return the average of both classifier predictions + logits = (cls_logits + distillation_logits) / 2 + + if not return_dict: + output = (logits, cls_logits, distillation_logits) + outputs[1:] + return output + + return TFDeiTForImageClassificationWithTeacherOutput( + logits=logits, + cls_logits=cls_logits, + distillation_logits=distillation_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output( + self, output: TFDeiTForImageClassificationWithTeacherOutput + ) -> TFDeiTForImageClassificationWithTeacherOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFDeiTForImageClassificationWithTeacherOutput( + logits=output.logits, + cls_logits=output.cls_logits, + distillation_logits=output.distillation_logits, + hidden_states=hidden_states, + attentions=attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2d25a6a71602b38a48b23de4ab227969217ae16e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/__init__.py @@ -0,0 +1,73 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available + + +_import_structure = { + "configuration_deta": ["DETA_PRETRAINED_CONFIG_ARCHIVE_MAP", "DetaConfig"], +} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["image_processing_deta"] = ["DetaImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_deta"] = [ + "DETA_PRETRAINED_MODEL_ARCHIVE_LIST", + "DetaForObjectDetection", + "DetaModel", + "DetaPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_deta import DETA_PRETRAINED_CONFIG_ARCHIVE_MAP, DetaConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .image_processing_deta import DetaImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_deta import ( + DETA_PRETRAINED_MODEL_ARCHIVE_LIST, + DetaForObjectDetection, + DetaModel, + DetaPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/configuration_deta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/configuration_deta.py new file mode 100644 index 0000000000000000000000000000000000000000..836e9732e68ed8528fff0516de09b620ed3d7d9c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/configuration_deta.py @@ -0,0 +1,242 @@ +# coding=utf-8 +# Copyright 2022 SenseTime and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DETA model configuration""" + +import copy + +from ...configuration_utils import PretrainedConfig +from ...utils import logging +from ..auto import CONFIG_MAPPING + + +logger = logging.get_logger(__name__) + +DETA_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "ut/deta": "https://huggingface.co/ut/deta/resolve/main/config.json", +} + + +class DetaConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DetaModel`]. It is used to instantiate a DETA + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the DETA + [SenseTime/deformable-detr](https://huggingface.co/SenseTime/deformable-detr) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + backbone_config (`PretrainedConfig` or `dict`, *optional*, defaults to `ResNetConfig()`): + The configuration of the backbone model. + num_queries (`int`, *optional*, defaults to 900): + Number of object queries, i.e. detection slots. This is the maximal number of objects [`DetaModel`] can + detect in a single image. In case `two_stage` is set to `True`, we use `two_stage_num_proposals` instead. + d_model (`int`, *optional*, defaults to 256): + Dimension of the layers. + encoder_layers (`int`, *optional*, defaults to 6): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 6): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + decoder_ffn_dim (`int`, *optional*, defaults to 2048): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 2048): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + activation_function (`str` or `function`, *optional*, defaults to `"relu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + init_xavier_std (`float`, *optional*, defaults to 1): + The scaling factor used for the Xavier initialization gain in the HM Attention map module. + encoder_layerdrop: (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + auxiliary_loss (`bool`, *optional*, defaults to `False`): + Whether auxiliary decoding losses (loss at each decoder layer) are to be used. + position_embedding_type (`str`, *optional*, defaults to `"sine"`): + Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`. + class_cost (`float`, *optional*, defaults to 1): + Relative weight of the classification error in the Hungarian matching cost. + bbox_cost (`float`, *optional*, defaults to 5): + Relative weight of the L1 error of the bounding box coordinates in the Hungarian matching cost. + giou_cost (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss of the bounding box in the Hungarian matching cost. + mask_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the Focal loss in the panoptic segmentation loss. + dice_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the DICE/F-1 loss in the panoptic segmentation loss. + bbox_loss_coefficient (`float`, *optional*, defaults to 5): + Relative weight of the L1 bounding box loss in the object detection loss. + giou_loss_coefficient (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss in the object detection loss. + eos_coefficient (`float`, *optional*, defaults to 0.1): + Relative classification weight of the 'no-object' class in the object detection loss. + num_feature_levels (`int`, *optional*, defaults to 5): + The number of input feature levels. + encoder_n_points (`int`, *optional*, defaults to 4): + The number of sampled keys in each feature level for each attention head in the encoder. + decoder_n_points (`int`, *optional*, defaults to 4): + The number of sampled keys in each feature level for each attention head in the decoder. + two_stage (`bool`, *optional*, defaults to `True`): + Whether to apply a two-stage deformable DETR, where the region proposals are also generated by a variant of + DETA, which are further fed into the decoder for iterative bounding box refinement. + two_stage_num_proposals (`int`, *optional*, defaults to 300): + The number of region proposals to be generated, in case `two_stage` is set to `True`. + with_box_refine (`bool`, *optional*, defaults to `True`): + Whether to apply iterative bounding box refinement, where each decoder layer refines the bounding boxes + based on the predictions from the previous layer. + focal_alpha (`float`, *optional*, defaults to 0.25): + Alpha parameter in the focal loss. + + Examples: + + ```python + >>> from transformers import DetaConfig, DetaModel + + >>> # Initializing a DETA SenseTime/deformable-detr style configuration + >>> configuration = DetaConfig() + + >>> # Initializing a model (with random weights) from the SenseTime/deformable-detr style configuration + >>> model = DetaModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "deta" + attribute_map = { + "hidden_size": "d_model", + "num_attention_heads": "encoder_attention_heads", + } + + def __init__( + self, + backbone_config=None, + num_queries=900, + max_position_embeddings=2048, + encoder_layers=6, + encoder_ffn_dim=2048, + encoder_attention_heads=8, + decoder_layers=6, + decoder_ffn_dim=1024, + decoder_attention_heads=8, + encoder_layerdrop=0.0, + is_encoder_decoder=True, + activation_function="relu", + d_model=256, + dropout=0.1, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + init_xavier_std=1.0, + return_intermediate=True, + auxiliary_loss=False, + position_embedding_type="sine", + num_feature_levels=5, + encoder_n_points=4, + decoder_n_points=4, + two_stage=True, + two_stage_num_proposals=300, + with_box_refine=True, + assign_first_stage=True, + class_cost=1, + bbox_cost=5, + giou_cost=2, + mask_loss_coefficient=1, + dice_loss_coefficient=1, + bbox_loss_coefficient=5, + giou_loss_coefficient=2, + eos_coefficient=0.1, + focal_alpha=0.25, + **kwargs, + ): + if backbone_config is None: + logger.info("`backbone_config` is `None`. Initializing the config with the default `ResNet` backbone.") + backbone_config = CONFIG_MAPPING["resnet"](out_features=["stage2", "stage3", "stage4"]) + else: + if isinstance(backbone_config, dict): + backbone_model_type = backbone_config.pop("model_type") + config_class = CONFIG_MAPPING[backbone_model_type] + backbone_config = config_class.from_dict(backbone_config) + + self.backbone_config = backbone_config + self.num_queries = num_queries + self.max_position_embeddings = max_position_embeddings + self.d_model = d_model + self.encoder_ffn_dim = encoder_ffn_dim + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.init_xavier_std = init_xavier_std + self.encoder_layerdrop = encoder_layerdrop + self.auxiliary_loss = auxiliary_loss + self.position_embedding_type = position_embedding_type + # deformable attributes + self.num_feature_levels = num_feature_levels + self.encoder_n_points = encoder_n_points + self.decoder_n_points = decoder_n_points + self.two_stage = two_stage + self.two_stage_num_proposals = two_stage_num_proposals + self.with_box_refine = with_box_refine + self.assign_first_stage = assign_first_stage + if two_stage is True and with_box_refine is False: + raise ValueError("If two_stage is True, with_box_refine must be True.") + # Hungarian matcher + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + # Loss coefficients + self.mask_loss_coefficient = mask_loss_coefficient + self.dice_loss_coefficient = dice_loss_coefficient + self.bbox_loss_coefficient = bbox_loss_coefficient + self.giou_loss_coefficient = giou_loss_coefficient + self.eos_coefficient = eos_coefficient + self.focal_alpha = focal_alpha + super().__init__(is_encoder_decoder=is_encoder_decoder, **kwargs) + + @property + def num_attention_heads(self) -> int: + return self.encoder_attention_heads + + @property + def hidden_size(self) -> int: + return self.d_model + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + output["backbone_config"] = self.backbone_config.to_dict() + output["model_type"] = self.__class__.model_type + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_resnet_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_resnet_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..cc17568bd64133169b047a3d767bcbf1b2582b25 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_resnet_to_pytorch.py @@ -0,0 +1,320 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DETA checkpoints from the original repository. + +URL: https://github.com/jozhang97/DETA/tree/master""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import cached_download, hf_hub_download, hf_hub_url +from PIL import Image + +from transformers import DetaConfig, DetaForObjectDetection, DetaImageProcessor +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_deta_config(): + config = DetaConfig( + num_queries=900, + encoder_ffn_dim=2048, + decoder_ffn_dim=2048, + num_feature_levels=5, + assign_first_stage=True, + with_box_refine=True, + two_stage=True, + ) + + # set labels + config.num_labels = 91 + repo_id = "huggingface/label-files" + filename = "coco-detection-id2label.json" + id2label = json.load(open(cached_download(hf_hub_url(repo_id, filename, repo_type="dataset")), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + return config + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def create_rename_keys(config): + rename_keys = [] + + # stem + # fmt: off + rename_keys.append(("backbone.0.body.conv1.weight", "model.backbone.model.embedder.embedder.convolution.weight")) + rename_keys.append(("backbone.0.body.bn1.weight", "model.backbone.model.embedder.embedder.normalization.weight")) + rename_keys.append(("backbone.0.body.bn1.bias", "model.backbone.model.embedder.embedder.normalization.bias")) + rename_keys.append(("backbone.0.body.bn1.running_mean", "model.backbone.model.embedder.embedder.normalization.running_mean")) + rename_keys.append(("backbone.0.body.bn1.running_var", "model.backbone.model.embedder.embedder.normalization.running_var")) + # stages + for stage_idx in range(len(config.backbone_config.depths)): + for layer_idx in range(config.backbone_config.depths[stage_idx]): + # shortcut + if layer_idx == 0: + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.0.weight", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.convolution.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.weight", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.bias", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.bias", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_mean", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_mean", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_var", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_var", + ) + ) + # 3 convs + for i in range(3): + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.conv{i+1}.weight", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.convolution.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.weight", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.bias", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.bias", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_mean", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_mean", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_var", + f"model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_var", + ) + ) + # transformer encoder + for i in range(config.encoder_layers): + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.sampling_offsets.weight", f"model.encoder.layers.{i}.self_attn.sampling_offsets.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.sampling_offsets.bias", f"model.encoder.layers.{i}.self_attn.sampling_offsets.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.attention_weights.weight", f"model.encoder.layers.{i}.self_attn.attention_weights.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.attention_weights.bias", f"model.encoder.layers.{i}.self_attn.attention_weights.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.value_proj.weight", f"model.encoder.layers.{i}.self_attn.value_proj.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.value_proj.bias", f"model.encoder.layers.{i}.self_attn.value_proj.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.output_proj.weight", f"model.encoder.layers.{i}.self_attn.output_proj.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.output_proj.bias", f"model.encoder.layers.{i}.self_attn.output_proj.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm1.weight", f"model.encoder.layers.{i}.self_attn_layer_norm.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm1.bias", f"model.encoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.weight", f"model.encoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.bias", f"model.encoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.weight", f"model.encoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.bias", f"model.encoder.layers.{i}.fc2.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.weight", f"model.encoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.bias", f"model.encoder.layers.{i}.final_layer_norm.bias")) + + # transformer decoder + for i in range(config.decoder_layers): + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.sampling_offsets.weight", f"model.decoder.layers.{i}.encoder_attn.sampling_offsets.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.sampling_offsets.bias", f"model.decoder.layers.{i}.encoder_attn.sampling_offsets.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.attention_weights.weight", f"model.decoder.layers.{i}.encoder_attn.attention_weights.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.attention_weights.bias", f"model.decoder.layers.{i}.encoder_attn.attention_weights.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.value_proj.weight", f"model.decoder.layers.{i}.encoder_attn.value_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.value_proj.bias", f"model.decoder.layers.{i}.encoder_attn.value_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.output_proj.weight", f"model.decoder.layers.{i}.encoder_attn.output_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.output_proj.bias", f"model.decoder.layers.{i}.encoder_attn.output_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm1.weight", f"model.decoder.layers.{i}.encoder_attn_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm1.bias", f"model.decoder.layers.{i}.encoder_attn_layer_norm.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.self_attn.out_proj.weight", f"model.decoder.layers.{i}.self_attn.out_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.self_attn.out_proj.bias", f"model.decoder.layers.{i}.self_attn.out_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm2.weight", f"model.decoder.layers.{i}.self_attn_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm2.bias", f"model.decoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.weight", f"model.decoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.bias", f"model.decoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.weight", f"model.decoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.bias", f"model.decoder.layers.{i}.fc2.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.weight", f"model.decoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.bias", f"model.decoder.layers.{i}.final_layer_norm.bias")) + + # fmt: on + + return rename_keys + + +def rename_key(dct, old, new): + val = dct.pop(old) + dct[new] = val + + +def read_in_decoder_q_k_v(state_dict, config): + # transformer decoder self-attention layers + hidden_size = config.d_model + for i in range(config.decoder_layers): + # read in weights + bias of input projection layer of self-attention + in_proj_weight = state_dict.pop(f"transformer.decoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"transformer.decoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"model.decoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:hidden_size, :] + state_dict[f"model.decoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:hidden_size] + state_dict[f"model.decoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[ + hidden_size : hidden_size * 2, : + ] + state_dict[f"model.decoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2] + state_dict[f"model.decoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-hidden_size:, :] + state_dict[f"model.decoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-hidden_size:] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + + return im + + +@torch.no_grad() +def convert_deta_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub): + """ + Copy/paste/tweak model's weights to our DETA structure. + """ + + # load config + config = get_deta_config() + + # load original state dict + if model_name == "deta-resnet-50": + filename = "adet_checkpoint0011.pth" + elif model_name == "deta-resnet-50-24-epochs": + filename = "adet_2x_checkpoint0023.pth" + else: + raise ValueError(f"Model name {model_name} not supported") + checkpoint_path = hf_hub_download(repo_id="nielsr/deta-checkpoints", filename=filename) + state_dict = torch.load(checkpoint_path, map_location="cpu")["model"] + + # rename keys + rename_keys = create_rename_keys(config) + for src, dest in rename_keys: + rename_key(state_dict, src, dest) + read_in_decoder_q_k_v(state_dict, config) + + # fix some prefixes + for key in state_dict.copy().keys(): + if "transformer.decoder.class_embed" in key or "transformer.decoder.bbox_embed" in key: + val = state_dict.pop(key) + state_dict[key.replace("transformer.decoder", "model.decoder")] = val + if "input_proj" in key: + val = state_dict.pop(key) + state_dict["model." + key] = val + if "level_embed" in key or "pos_trans" in key or "pix_trans" in key or "enc_output" in key: + val = state_dict.pop(key) + state_dict[key.replace("transformer", "model")] = val + + # finally, create HuggingFace model and load state dict + model = DetaForObjectDetection(config) + model.load_state_dict(state_dict) + model.eval() + + device = "cuda" if torch.cuda.is_available() else "cpu" + model.to(device) + + # load image processor + processor = DetaImageProcessor(format="coco_detection") + + # verify our conversion on image + img = prepare_img() + encoding = processor(images=img, return_tensors="pt") + pixel_values = encoding["pixel_values"] + outputs = model(pixel_values.to(device)) + + # verify logits + if model_name == "deta-resnet-50": + expected_logits = torch.tensor( + [[-7.3978, -2.5406, -4.1668], [-8.2684, -3.9933, -3.8096], [-7.0515, -3.7973, -5.8516]] + ) + expected_boxes = torch.tensor([[0.5043, 0.4973, 0.9998], [0.2542, 0.5489, 0.4748], [0.5490, 0.2765, 0.0570]]) + elif model_name == "deta-resnet-50-24-epochs": + expected_logits = torch.tensor( + [[-7.1688, -2.4857, -4.8669], [-7.8630, -3.8154, -4.2674], [-7.2730, -4.1865, -5.5323]] + ) + expected_boxes = torch.tensor([[0.5021, 0.4971, 0.9994], [0.2546, 0.5486, 0.4731], [0.1686, 0.1986, 0.2142]]) + + assert torch.allclose(outputs.logits[0, :3, :3], expected_logits.to(device), atol=1e-4) + assert torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes.to(device), atol=1e-4) + print("Everything ok!") + + if pytorch_dump_folder_path: + # Save model and processor + logger.info(f"Saving PyTorch model and processor to {pytorch_dump_folder_path}...") + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + model.save_pretrained(pytorch_dump_folder_path) + processor.save_pretrained(pytorch_dump_folder_path) + + # Push to hub + if push_to_hub: + print("Pushing model and processor to hub...") + model.push_to_hub(f"jozhang97/{model_name}") + processor.push_to_hub(f"jozhang97/{model_name}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--model_name", + type=str, + default="deta-resnet-50", + choices=["deta-resnet-50", "deta-resnet-50-24-epochs"], + help="Name of the model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + type=str, + help="Path to the folder to output PyTorch model.", + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + args = parser.parse_args() + convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_swin_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_swin_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..911bc434e14265f9fe21dc8166b4d9eafb0d9cc0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/convert_deta_swin_to_pytorch.py @@ -0,0 +1,327 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DETA checkpoints from the original repository. + +URL: https://github.com/jozhang97/DETA/tree/master""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import cached_download, hf_hub_download, hf_hub_url +from PIL import Image + +from transformers import DetaConfig, DetaForObjectDetection, DetaImageProcessor, SwinConfig +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_deta_config(model_name): + backbone_config = SwinConfig( + embed_dim=192, + depths=(2, 2, 18, 2), + num_heads=(6, 12, 24, 48), + window_size=12, + out_features=["stage2", "stage3", "stage4"], + ) + + config = DetaConfig( + backbone_config=backbone_config, + num_queries=900, + encoder_ffn_dim=2048, + decoder_ffn_dim=2048, + num_feature_levels=5, + assign_first_stage=True, + with_box_refine=True, + two_stage=True, + ) + + # set labels + repo_id = "huggingface/label-files" + if "o365" in model_name: + num_labels = 366 + filename = "object365-id2label.json" + else: + num_labels = 91 + filename = "coco-detection-id2label.json" + + config.num_labels = num_labels + id2label = json.load(open(cached_download(hf_hub_url(repo_id, filename, repo_type="dataset")), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + return config + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def create_rename_keys(config): + rename_keys = [] + + # stem + # fmt: off + rename_keys.append(("backbone.0.body.patch_embed.proj.weight", "model.backbone.model.embeddings.patch_embeddings.projection.weight")) + rename_keys.append(("backbone.0.body.patch_embed.proj.bias", "model.backbone.model.embeddings.patch_embeddings.projection.bias")) + rename_keys.append(("backbone.0.body.patch_embed.norm.weight", "model.backbone.model.embeddings.norm.weight")) + rename_keys.append(("backbone.0.body.patch_embed.norm.bias", "model.backbone.model.embeddings.norm.bias")) + # stages + for i in range(len(config.backbone_config.depths)): + for j in range(config.backbone_config.depths[i]): + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.norm1.weight", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_before.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.norm1.bias", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_before.bias")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.attn.relative_position_bias_table", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_bias_table")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.attn.relative_position_index", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.relative_position_index")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.attn.proj.weight", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.attn.proj.bias", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.output.dense.bias")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.norm2.weight", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_after.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.norm2.bias", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.layernorm_after.bias")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.mlp.fc1.weight", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.mlp.fc1.bias", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.intermediate.dense.bias")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.mlp.fc2.weight", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.output.dense.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.blocks.{j}.mlp.fc2.bias", f"model.backbone.model.encoder.layers.{i}.blocks.{j}.output.dense.bias")) + + if i < 3: + rename_keys.append((f"backbone.0.body.layers.{i}.downsample.reduction.weight", f"model.backbone.model.encoder.layers.{i}.downsample.reduction.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.downsample.norm.weight", f"model.backbone.model.encoder.layers.{i}.downsample.norm.weight")) + rename_keys.append((f"backbone.0.body.layers.{i}.downsample.norm.bias", f"model.backbone.model.encoder.layers.{i}.downsample.norm.bias")) + + rename_keys.append(("backbone.0.body.norm1.weight", "model.backbone.model.hidden_states_norms.stage2.weight")) + rename_keys.append(("backbone.0.body.norm1.bias", "model.backbone.model.hidden_states_norms.stage2.bias")) + rename_keys.append(("backbone.0.body.norm2.weight", "model.backbone.model.hidden_states_norms.stage3.weight")) + rename_keys.append(("backbone.0.body.norm2.bias", "model.backbone.model.hidden_states_norms.stage3.bias")) + rename_keys.append(("backbone.0.body.norm3.weight", "model.backbone.model.hidden_states_norms.stage4.weight")) + rename_keys.append(("backbone.0.body.norm3.bias", "model.backbone.model.hidden_states_norms.stage4.bias")) + + # transformer encoder + for i in range(config.encoder_layers): + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.sampling_offsets.weight", f"model.encoder.layers.{i}.self_attn.sampling_offsets.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.sampling_offsets.bias", f"model.encoder.layers.{i}.self_attn.sampling_offsets.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.attention_weights.weight", f"model.encoder.layers.{i}.self_attn.attention_weights.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.attention_weights.bias", f"model.encoder.layers.{i}.self_attn.attention_weights.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.value_proj.weight", f"model.encoder.layers.{i}.self_attn.value_proj.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.value_proj.bias", f"model.encoder.layers.{i}.self_attn.value_proj.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.output_proj.weight", f"model.encoder.layers.{i}.self_attn.output_proj.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.self_attn.output_proj.bias", f"model.encoder.layers.{i}.self_attn.output_proj.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm1.weight", f"model.encoder.layers.{i}.self_attn_layer_norm.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm1.bias", f"model.encoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.weight", f"model.encoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.bias", f"model.encoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.weight", f"model.encoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.bias", f"model.encoder.layers.{i}.fc2.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.weight", f"model.encoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.bias", f"model.encoder.layers.{i}.final_layer_norm.bias")) + + # transformer decoder + for i in range(config.decoder_layers): + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.sampling_offsets.weight", f"model.decoder.layers.{i}.encoder_attn.sampling_offsets.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.sampling_offsets.bias", f"model.decoder.layers.{i}.encoder_attn.sampling_offsets.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.attention_weights.weight", f"model.decoder.layers.{i}.encoder_attn.attention_weights.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.attention_weights.bias", f"model.decoder.layers.{i}.encoder_attn.attention_weights.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.value_proj.weight", f"model.decoder.layers.{i}.encoder_attn.value_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.value_proj.bias", f"model.decoder.layers.{i}.encoder_attn.value_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.output_proj.weight", f"model.decoder.layers.{i}.encoder_attn.output_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.cross_attn.output_proj.bias", f"model.decoder.layers.{i}.encoder_attn.output_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm1.weight", f"model.decoder.layers.{i}.encoder_attn_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm1.bias", f"model.decoder.layers.{i}.encoder_attn_layer_norm.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.self_attn.out_proj.weight", f"model.decoder.layers.{i}.self_attn.out_proj.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.self_attn.out_proj.bias", f"model.decoder.layers.{i}.self_attn.out_proj.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm2.weight", f"model.decoder.layers.{i}.self_attn_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm2.bias", f"model.decoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.weight", f"model.decoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.bias", f"model.decoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.weight", f"model.decoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.bias", f"model.decoder.layers.{i}.fc2.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.weight", f"model.decoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.bias", f"model.decoder.layers.{i}.final_layer_norm.bias")) + + # fmt: on + + return rename_keys + + +def rename_key(dct, old, new): + val = dct.pop(old) + dct[new] = val + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_swin_q_k_v(state_dict, backbone_config): + num_features = [int(backbone_config.embed_dim * 2**i) for i in range(len(backbone_config.depths))] + for i in range(len(backbone_config.depths)): + dim = num_features[i] + for j in range(backbone_config.depths[i]): + # fmt: off + # read in weights + bias of input projection layer (in original implementation, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"backbone.0.body.layers.{i}.blocks.{j}.attn.qkv.weight") + in_proj_bias = state_dict.pop(f"backbone.0.body.layers.{i}.blocks.{j}.attn.qkv.bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.query.weight"] = in_proj_weight[:dim, :] + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.query.bias"] = in_proj_bias[: dim] + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.key.weight"] = in_proj_weight[ + dim : dim * 2, : + ] + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.key.bias"] = in_proj_bias[ + dim : dim * 2 + ] + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.value.weight"] = in_proj_weight[ + -dim :, : + ] + state_dict[f"model.backbone.model.encoder.layers.{i}.blocks.{j}.attention.self.value.bias"] = in_proj_bias[-dim :] + # fmt: on + + +def read_in_decoder_q_k_v(state_dict, config): + # transformer decoder self-attention layers + hidden_size = config.d_model + for i in range(config.decoder_layers): + # read in weights + bias of input projection layer of self-attention + in_proj_weight = state_dict.pop(f"transformer.decoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"transformer.decoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"model.decoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:hidden_size, :] + state_dict[f"model.decoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:hidden_size] + state_dict[f"model.decoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[ + hidden_size : hidden_size * 2, : + ] + state_dict[f"model.decoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[hidden_size : hidden_size * 2] + state_dict[f"model.decoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-hidden_size:, :] + state_dict[f"model.decoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-hidden_size:] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + + return im + + +@torch.no_grad() +def convert_deta_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub): + """ + Copy/paste/tweak model's weights to our DETA structure. + """ + + # load config + config = get_deta_config(model_name) + + # load original state dict + if model_name == "deta-swin-large": + checkpoint_path = hf_hub_download(repo_id="nielsr/deta-checkpoints", filename="adet_swin_ft.pth") + elif model_name == "deta-swin-large-o365": + checkpoint_path = hf_hub_download(repo_id="jozhang97/deta-swin-l-o365", filename="deta_swin_pt_o365.pth") + else: + raise ValueError(f"Model name {model_name} not supported") + + state_dict = torch.load(checkpoint_path, map_location="cpu")["model"] + + # original state dict + for name, param in state_dict.items(): + print(name, param.shape) + + # rename keys + rename_keys = create_rename_keys(config) + for src, dest in rename_keys: + rename_key(state_dict, src, dest) + read_in_swin_q_k_v(state_dict, config.backbone_config) + read_in_decoder_q_k_v(state_dict, config) + + # fix some prefixes + for key in state_dict.copy().keys(): + if "transformer.decoder.class_embed" in key or "transformer.decoder.bbox_embed" in key: + val = state_dict.pop(key) + state_dict[key.replace("transformer.decoder", "model.decoder")] = val + if "input_proj" in key: + val = state_dict.pop(key) + state_dict["model." + key] = val + if "level_embed" in key or "pos_trans" in key or "pix_trans" in key or "enc_output" in key: + val = state_dict.pop(key) + state_dict[key.replace("transformer", "model")] = val + + # finally, create HuggingFace model and load state dict + model = DetaForObjectDetection(config) + model.load_state_dict(state_dict) + model.eval() + + device = "cuda" if torch.cuda.is_available() else "cpu" + model.to(device) + + # load image processor + processor = DetaImageProcessor(format="coco_detection") + + # verify our conversion on image + img = prepare_img() + encoding = processor(images=img, return_tensors="pt") + pixel_values = encoding["pixel_values"] + outputs = model(pixel_values.to(device)) + + # verify logits + print("Logits:", outputs.logits[0, :3, :3]) + print("Boxes:", outputs.pred_boxes[0, :3, :3]) + if model_name == "deta-swin-large": + expected_logits = torch.tensor( + [[-7.6308, -2.8485, -5.3737], [-7.2037, -4.5505, -4.8027], [-7.2943, -4.2611, -4.6617]] + ) + expected_boxes = torch.tensor([[0.4987, 0.4969, 0.9999], [0.2549, 0.5498, 0.4805], [0.5498, 0.2757, 0.0569]]) + elif model_name == "deta-swin-large-o365": + expected_logits = torch.tensor( + [[-8.0122, -3.5720, -4.9717], [-8.1547, -3.6886, -4.6389], [-7.6610, -3.6194, -5.0134]] + ) + expected_boxes = torch.tensor([[0.2523, 0.5549, 0.4881], [0.7715, 0.4149, 0.4601], [0.5503, 0.2753, 0.0575]]) + assert torch.allclose(outputs.logits[0, :3, :3], expected_logits.to(device), atol=1e-4) + assert torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes.to(device), atol=1e-4) + print("Everything ok!") + + if pytorch_dump_folder_path: + # Save model and processor + logger.info(f"Saving PyTorch model and processor to {pytorch_dump_folder_path}...") + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + model.save_pretrained(pytorch_dump_folder_path) + processor.save_pretrained(pytorch_dump_folder_path) + + # Push to hub + if push_to_hub: + print("Pushing model and processor to hub...") + model.push_to_hub(f"jozhang97/{model_name}") + processor.push_to_hub(f"jozhang97/{model_name}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--model_name", + type=str, + default="deta-swin-large", + choices=["deta-swin-large", "deta-swin-large-o365"], + help="Name of the model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + type=str, + help="Path to the folder to output PyTorch model.", + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + args = parser.parse_args() + convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/image_processing_deta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/image_processing_deta.py new file mode 100644 index 0000000000000000000000000000000000000000..d60f6f838c9ce80bea3d449ddc69dcaa5b4e94aa --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/image_processing_deta.py @@ -0,0 +1,1017 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for Deformable DETR.""" + +import pathlib +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union + +import numpy as np + +from ...feature_extraction_utils import BatchFeature +from ...image_processing_utils import BaseImageProcessor, get_size_dict +from ...image_transforms import ( + PaddingMode, + center_to_corners_format, + corners_to_center_format, + normalize, + pad, + rescale, + resize, + rgb_to_id, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_DEFAULT_MEAN, + IMAGENET_DEFAULT_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + get_image_size, + infer_channel_dimension_format, + is_batched, + to_numpy_array, + valid_coco_detection_annotations, + valid_coco_panoptic_annotations, + valid_images, +) +from ...utils import ( + is_flax_available, + is_jax_tensor, + is_tf_available, + is_tf_tensor, + is_torch_available, + is_torch_tensor, + is_torchvision_available, + is_vision_available, + logging, +) +from ...utils.generic import ExplicitEnum, TensorType + + +if is_torch_available(): + import torch + + +if is_torchvision_available(): + from torchvision.ops.boxes import batched_nms + +if is_vision_available(): + import PIL + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +class AnnotionFormat(ExplicitEnum): + COCO_DETECTION = "coco_detection" + COCO_PANOPTIC = "coco_panoptic" + + +SUPPORTED_ANNOTATION_FORMATS = (AnnotionFormat.COCO_DETECTION, AnnotionFormat.COCO_PANOPTIC) + + +# Copied from transformers.models.detr.image_processing_detr.get_size_with_aspect_ratio +def get_size_with_aspect_ratio(image_size, size, max_size=None) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + height, width = image_size + if max_size is not None: + min_original_size = float(min((height, width))) + max_original_size = float(max((height, width))) + if max_original_size / min_original_size * size > max_size: + size = int(round(max_size * min_original_size / max_original_size)) + + if (height <= width and height == size) or (width <= height and width == size): + return height, width + + if width < height: + ow = size + oh = int(size * height / width) + else: + oh = size + ow = int(size * width / height) + return (oh, ow) + + +# Copied from transformers.models.detr.image_processing_detr.get_resize_output_image_size +def get_resize_output_image_size( + input_image: np.ndarray, size: Union[int, Tuple[int, int], List[int]], max_size: Optional[int] = None +) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. If the desired output size + is a tuple or list, the output image size is returned as is. If the desired output size is an integer, the output + image size is computed by keeping the aspect ratio of the input image size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + image_size = get_image_size(input_image) + if isinstance(size, (list, tuple)): + return size + + return get_size_with_aspect_ratio(image_size, size, max_size) + + +# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn +def get_numpy_to_framework_fn(arr) -> Callable: + """ + Returns a function that converts a numpy array to the framework of the input array. + + Args: + arr (`np.ndarray`): The array to convert. + """ + if isinstance(arr, np.ndarray): + return np.array + if is_tf_available() and is_tf_tensor(arr): + import tensorflow as tf + + return tf.convert_to_tensor + if is_torch_available() and is_torch_tensor(arr): + import torch + + return torch.tensor + if is_flax_available() and is_jax_tensor(arr): + import jax.numpy as jnp + + return jnp.array + raise ValueError(f"Cannot convert arrays of type {type(arr)}") + + +# Copied from transformers.models.detr.image_processing_detr.safe_squeeze +def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: + """ + Squeezes an array, but only if the axis specified has dim 1. + """ + if axis is None: + return arr.squeeze() + + try: + return arr.squeeze(axis=axis) + except ValueError: + return arr + + +# Copied from transformers.models.detr.image_processing_detr.normalize_annotation +def normalize_annotation(annotation: Dict, image_size: Tuple[int, int]) -> Dict: + image_height, image_width = image_size + norm_annotation = {} + for key, value in annotation.items(): + if key == "boxes": + boxes = value + boxes = corners_to_center_format(boxes) + boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32) + norm_annotation[key] = boxes + else: + norm_annotation[key] = value + return norm_annotation + + +# Copied from transformers.models.detr.image_processing_detr.max_across_indices +def max_across_indices(values: Iterable[Any]) -> List[Any]: + """ + Return the maximum value across all indices of an iterable of values. + """ + return [max(values_i) for values_i in zip(*values)] + + +# Copied from transformers.models.detr.image_processing_detr.get_max_height_width +def get_max_height_width(images: List[np.ndarray]) -> List[int]: + """ + Get the maximum height and width across all images in a batch. + """ + input_channel_dimension = infer_channel_dimension_format(images[0]) + + if input_channel_dimension == ChannelDimension.FIRST: + _, max_height, max_width = max_across_indices([img.shape for img in images]) + elif input_channel_dimension == ChannelDimension.LAST: + max_height, max_width, _ = max_across_indices([img.shape for img in images]) + else: + raise ValueError(f"Invalid channel dimension format: {input_channel_dimension}") + return (max_height, max_width) + + +# Copied from transformers.models.detr.image_processing_detr.make_pixel_mask +def make_pixel_mask(image: np.ndarray, output_size: Tuple[int, int]) -> np.ndarray: + """ + Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding. + + Args: + image (`np.ndarray`): + Image to make the pixel mask for. + output_size (`Tuple[int, int]`): + Output size of the mask. + """ + input_height, input_width = get_image_size(image) + mask = np.zeros(output_size, dtype=np.int64) + mask[:input_height, :input_width] = 1 + return mask + + +# Copied from transformers.models.detr.image_processing_detr.convert_coco_poly_to_mask +def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray: + """ + Convert a COCO polygon annotation to a mask. + + Args: + segmentations (`List[List[float]]`): + List of polygons, each polygon represented by a list of x-y coordinates. + height (`int`): + Height of the mask. + width (`int`): + Width of the mask. + """ + try: + from pycocotools import mask as coco_mask + except ImportError: + raise ImportError("Pycocotools is not installed in your environment.") + + masks = [] + for polygons in segmentations: + rles = coco_mask.frPyObjects(polygons, height, width) + mask = coco_mask.decode(rles) + if len(mask.shape) < 3: + mask = mask[..., None] + mask = np.asarray(mask, dtype=np.uint8) + mask = np.any(mask, axis=2) + masks.append(mask) + if masks: + masks = np.stack(masks, axis=0) + else: + masks = np.zeros((0, height, width), dtype=np.uint8) + + return masks + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_detection_annotation with DETR->DETA +def prepare_coco_detection_annotation(image, target, return_segmentation_masks: bool = False): + """ + Convert the target in COCO format into the format expected by DETA. + """ + image_height, image_width = get_image_size(image) + + image_id = target["image_id"] + image_id = np.asarray([image_id], dtype=np.int64) + + # Get all COCO annotations for the given image. + annotations = target["annotations"] + annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0] + + classes = [obj["category_id"] for obj in annotations] + classes = np.asarray(classes, dtype=np.int64) + + # for conversion to coco api + area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32) + iscrowd = np.asarray([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in annotations], dtype=np.int64) + + boxes = [obj["bbox"] for obj in annotations] + # guard against no boxes via resizing + boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4) + boxes[:, 2:] += boxes[:, :2] + boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width) + boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height) + + keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0]) + + new_target = {} + new_target["image_id"] = image_id + new_target["class_labels"] = classes[keep] + new_target["boxes"] = boxes[keep] + new_target["area"] = area[keep] + new_target["iscrowd"] = iscrowd[keep] + new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64) + + if annotations and "keypoints" in annotations[0]: + keypoints = [obj["keypoints"] for obj in annotations] + keypoints = np.asarray(keypoints, dtype=np.float32) + num_keypoints = keypoints.shape[0] + keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints + new_target["keypoints"] = keypoints[keep] + + if return_segmentation_masks: + segmentation_masks = [obj["segmentation"] for obj in annotations] + masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width) + new_target["masks"] = masks[keep] + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.masks_to_boxes +def masks_to_boxes(masks: np.ndarray) -> np.ndarray: + """ + Compute the bounding boxes around the provided panoptic segmentation masks. + + Args: + masks: masks in format `[number_masks, height, width]` where N is the number of masks + + Returns: + boxes: bounding boxes in format `[number_masks, 4]` in xyxy format + """ + if masks.size == 0: + return np.zeros((0, 4)) + + h, w = masks.shape[-2:] + y = np.arange(0, h, dtype=np.float32) + x = np.arange(0, w, dtype=np.float32) + # see https://github.com/pytorch/pytorch/issues/50276 + y, x = np.meshgrid(y, x, indexing="ij") + + x_mask = masks * np.expand_dims(x, axis=0) + x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1) + x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool))) + x_min = x.filled(fill_value=1e8) + x_min = x_min.reshape(x_min.shape[0], -1).min(-1) + + y_mask = masks * np.expand_dims(y, axis=0) + y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1) + y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool))) + y_min = y.filled(fill_value=1e8) + y_min = y_min.reshape(y_min.shape[0], -1).min(-1) + + return np.stack([x_min, y_min, x_max, y_max], 1) + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_panoptic_annotation with DETR->DETA +def prepare_coco_panoptic_annotation( + image: np.ndarray, target: Dict, masks_path: Union[str, pathlib.Path], return_masks: bool = True +) -> Dict: + """ + Prepare a coco panoptic annotation for DETA. + """ + image_height, image_width = get_image_size(image) + annotation_path = pathlib.Path(masks_path) / target["file_name"] + + new_target = {} + new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64) + new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64) + new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64) + + if "segments_info" in target: + masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32) + masks = rgb_to_id(masks) + + ids = np.array([segment_info["id"] for segment_info in target["segments_info"]]) + masks = masks == ids[:, None, None] + masks = masks.astype(np.uint8) + if return_masks: + new_target["masks"] = masks + new_target["boxes"] = masks_to_boxes(masks) + new_target["class_labels"] = np.array( + [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["iscrowd"] = np.asarray( + [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["area"] = np.asarray( + [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32 + ) + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.resize_annotation +def resize_annotation( + annotation: Dict[str, Any], + orig_size: Tuple[int, int], + target_size: Tuple[int, int], + threshold: float = 0.5, + resample: PILImageResampling = PILImageResampling.NEAREST, +): + """ + Resizes an annotation to a target size. + + Args: + annotation (`Dict[str, Any]`): + The annotation dictionary. + orig_size (`Tuple[int, int]`): + The original size of the input image. + target_size (`Tuple[int, int]`): + The target size of the image, as returned by the preprocessing `resize` step. + threshold (`float`, *optional*, defaults to 0.5): + The threshold used to binarize the segmentation masks. + resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`): + The resampling filter to use when resizing the masks. + """ + ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size)) + ratio_height, ratio_width = ratios + + new_annotation = {} + new_annotation["size"] = target_size + + for key, value in annotation.items(): + if key == "boxes": + boxes = value + scaled_boxes = boxes * np.asarray([ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32) + new_annotation["boxes"] = scaled_boxes + elif key == "area": + area = value + scaled_area = area * (ratio_width * ratio_height) + new_annotation["area"] = scaled_area + elif key == "masks": + masks = value[:, None] + masks = np.array([resize(mask, target_size, resample=resample) for mask in masks]) + masks = masks.astype(np.float32) + masks = masks[:, 0] > threshold + new_annotation["masks"] = masks + elif key == "size": + new_annotation["size"] = target_size + else: + new_annotation[key] = value + + return new_annotation + + +class DetaImageProcessor(BaseImageProcessor): + r""" + Constructs a Deformable DETR image processor. + + Args: + format (`str`, *optional*, defaults to `"coco_detection"`): + Data format of the annotations. One of "coco_detection" or "coco_panoptic". + do_resize (`bool`, *optional*, defaults to `True`): + Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be + overridden by the `do_resize` parameter in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 800, "longest_edge": 1333}`): + Size of the image's (height, width) dimensions after resizing. Can be overridden by the `size` parameter in + the `preprocess` method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. + do_rescale (`bool`, *optional*, defaults to `True`): + Controls whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the + `do_rescale` parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize: + Controls whether to normalize the image. Can be overridden by the `do_normalize` parameter in the + `preprocess` method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_MEAN`): + Mean values to use when normalizing the image. Can be a single value or a list of values, one for each + channel. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_STD`): + Standard deviation values to use when normalizing the image. Can be a single value or a list of values, one + for each channel. Can be overridden by the `image_std` parameter in the `preprocess` method. + do_pad (`bool`, *optional*, defaults to `True`): + Controls whether to pad the image to the largest image in a batch and create a pixel mask. Can be + overridden by the `do_pad` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values", "pixel_mask"] + + def __init__( + self, + format: Union[str, AnnotionFormat] = AnnotionFormat.COCO_DETECTION, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Union[float, List[float]] = None, + image_std: Union[float, List[float]] = None, + do_pad: bool = True, + **kwargs, + ) -> None: + if "pad_and_return_pixel_mask" in kwargs: + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333} + size = get_size_dict(size, default_to_square=False) + + super().__init__(**kwargs) + self.format = format + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_DEFAULT_STD + self.do_pad = do_pad + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_annotation with DETR->DETA + def prepare_annotation( + self, + image: np.ndarray, + target: Dict, + format: Optional[AnnotionFormat] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + ) -> Dict: + """ + Prepare an annotation for feeding into DETA model. + """ + format = format if format is not None else self.format + + if format == AnnotionFormat.COCO_DETECTION: + return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_detection_annotation(image, target, return_segmentation_masks) + elif format == AnnotionFormat.COCO_PANOPTIC: + return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_panoptic_annotation( + image, target, masks_path=masks_path, return_masks=return_segmentation_masks + ) + else: + raise ValueError(f"Format {format} is not supported.") + return target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare + def prepare(self, image, target, return_segmentation_masks=None, masks_path=None): + logger.warning_once( + "The `prepare` method is deprecated and will be removed in a future version. " + "Please use `prepare_annotation` instead. Note: the `prepare_annotation` method " + "does not return the image anymore.", + ) + target = self.prepare_annotation(image, target, return_segmentation_masks, masks_path, self.format) + return image, target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.convert_coco_poly_to_mask + def convert_coco_poly_to_mask(self, *args, **kwargs): + logger.warning_once( + "The `convert_coco_poly_to_mask` method is deprecated and will be removed in a future version. " + ) + return convert_coco_poly_to_mask(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_detection + def prepare_coco_detection(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_detection` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_detection_annotation(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_panoptic + def prepare_coco_panoptic(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_panoptic` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_panoptic_annotation(*args, **kwargs) + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BILINEAR, + data_format: Optional[ChannelDimension] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an + int, smaller edge of the image will be matched to this number. + """ + size = get_size_dict(size, default_to_square=False) + if "shortest_edge" in size and "longest_edge" in size: + size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"]) + elif "height" in size and "width" in size: + size = (size["height"], size["width"]) + else: + raise ValueError( + "Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got" + f" {size.keys()}." + ) + image = resize(image, size=size, resample=resample, data_format=data_format) + return image + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.resize_annotation + def resize_annotation( + self, + annotation, + orig_size, + size, + resample: PILImageResampling = PILImageResampling.NEAREST, + ) -> Dict: + """ + Resize the annotation to match the resized image. If size is an int, smaller edge of the mask will be matched + to this number. + """ + return resize_annotation(annotation, orig_size=orig_size, target_size=size, resample=resample) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.rescale + def rescale( + self, image: np.ndarray, rescale_factor: Union[float, int], data_format: Optional[ChannelDimension] = None + ) -> np.ndarray: + """ + Rescale the image by the given factor. + """ + return rescale(image, rescale_factor, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize + def normalize( + self, + image: np.ndarray, + mean: Union[float, Iterable[float]], + std: Union[float, Iterable[float]], + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Normalize the image with the given mean and standard deviation. + """ + return normalize(image, mean=mean, std=std, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize_annotation + def normalize_annotation(self, annotation: Dict, image_size: Tuple[int, int]) -> Dict: + """ + Normalize the boxes in the annotation from `[top_left_x, top_left_y, bottom_right_x, bottom_right_y]` to + `[center_x, center_y, width, height]` format. + """ + return normalize_annotation(annotation, image_size=image_size) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.pad_and_create_pixel_mask + def pad_and_create_pixel_mask( + self, + pixel_values_list: List[ImageInput], + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> BatchFeature: + """ + Pads a batch of images with zeros to the size of largest height and width in the batch and returns their + corresponding pixel mask. + + Args: + images (`List[np.ndarray]`): + Batch of images to pad. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + logger.warning_once("This method is deprecated and will be removed in v4.27.0. Please use pad instead.") + # pad expects a list of np.ndarray, but the previous feature extractors expected torch tensors + images = [to_numpy_array(image) for image in pixel_values_list] + return self.pad( + images=images, + return_pixel_mask=True, + return_tensors=return_tensors, + data_format=data_format, + ) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor._pad_image + def _pad_image( + self, + image: np.ndarray, + output_size: Tuple[int, int], + constant_values: Union[float, Iterable[float]] = 0, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pad an image with zeros to the given size. + """ + input_height, input_width = get_image_size(image) + output_height, output_width = output_size + + pad_bottom = output_height - input_height + pad_right = output_width - input_width + padding = ((0, pad_bottom), (0, pad_right)) + padded_image = pad( + image, padding, mode=PaddingMode.CONSTANT, constant_values=constant_values, data_format=data_format + ) + return padded_image + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.pad + def pad( + self, + images: List[np.ndarray], + constant_values: Union[float, Iterable[float]] = 0, + return_pixel_mask: bool = True, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pads a batch of images to the bottom and right of the image with zeros to the size of largest height and width + in the batch and optionally returns their corresponding pixel mask. + + Args: + image (`np.ndarray`): + Image to pad. + constant_values (`float` or `Iterable[float]`, *optional*): + The value to use for the padding if `mode` is `"constant"`. + return_pixel_mask (`bool`, *optional*, defaults to `True`): + Whether to return a pixel mask. + input_channel_dimension (`ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be inferred from the input image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + pad_size = get_max_height_width(images) + + padded_images = [ + self._pad_image(image, pad_size, constant_values=constant_values, data_format=data_format) + for image in images + ] + data = {"pixel_values": padded_images} + + if return_pixel_mask: + masks = [make_pixel_mask(image=image, output_size=pad_size) for image in images] + data["pixel_mask"] = masks + + return BatchFeature(data=data, tensor_type=return_tensors) + + def preprocess( + self, + images: ImageInput, + annotations: Optional[Union[List[Dict], List[List[Dict]]]] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + do_resize: Optional[bool] = None, + size: Optional[Dict[str, int]] = None, + resample=None, # PILImageResampling + do_rescale: Optional[bool] = None, + rescale_factor: Optional[Union[int, float]] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_pad: Optional[bool] = None, + format: Optional[Union[str, AnnotionFormat]] = None, + return_tensors: Optional[Union[TensorType, str]] = None, + data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> BatchFeature: + """ + Preprocess an image or a batch of images so that it can be used by the model. + + Args: + images (`ImageInput`): + Image or batch of images to preprocess. + annotations (`List[Dict]` or `List[List[Dict]]`, *optional*): + List of annotations associated with the image or batch of images. If annotionation is for object + detection, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "annotations" (`List[Dict]`): List of annotations for an image. Each annotation should be a + dictionary. An image can have no annotations, in which case the list should be empty. + If annotionation is for segmentation, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "segments_info" (`List[Dict]`): List of segments for an image. Each segment should be a dictionary. + An image can have no segments, in which case the list should be empty. + - "file_name" (`str`): The file name of the image. + return_segmentation_masks (`bool`, *optional*, defaults to self.return_segmentation_masks): + Whether to return segmentation masks. + masks_path (`str` or `pathlib.Path`, *optional*): + Path to the directory containing the segmentation masks. + do_resize (`bool`, *optional*, defaults to self.do_resize): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to self.size): + Size of the image after resizing. + resample (`PILImageResampling`, *optional*, defaults to self.resample): + Resampling filter to use when resizing the image. + do_rescale (`bool`, *optional*, defaults to self.do_rescale): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to self.rescale_factor): + Rescale factor to use when rescaling the image. + do_normalize (`bool`, *optional*, defaults to self.do_normalize): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to self.image_mean): + Mean to use when normalizing the image. + image_std (`float` or `List[float]`, *optional*, defaults to self.image_std): + Standard deviation to use when normalizing the image. + do_pad (`bool`, *optional*, defaults to self.do_pad): + Whether to pad the image. + format (`str` or `AnnotionFormat`, *optional*, defaults to self.format): + Format of the annotations. + return_tensors (`str` or `TensorType`, *optional*, defaults to self.return_tensors): + Type of tensors to return. If `None`, will return the list of images. + data_format (`str` or `ChannelDimension`, *optional*, defaults to self.data_format): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + if "pad_and_return_pixel_mask" in kwargs: + logger.warning_once( + "The `pad_and_return_pixel_mask` argument is deprecated and will be removed in a future version, " + "use `do_pad` instead.", + ) + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + do_resize = self.do_resize if do_resize is None else do_resize + size = self.size if size is None else size + size = get_size_dict(size=size, default_to_square=False) + resample = self.resample if resample is None else resample + do_rescale = self.do_rescale if do_rescale is None else do_rescale + rescale_factor = self.rescale_factor if rescale_factor is None else rescale_factor + do_normalize = self.do_normalize if do_normalize is None else do_normalize + image_mean = self.image_mean if image_mean is None else image_mean + image_std = self.image_std if image_std is None else image_std + do_pad = self.do_pad if do_pad is None else do_pad + format = self.format if format is None else format + + if do_resize is not None and size is None: + raise ValueError("Size and max_size must be specified if do_resize is True.") + + if do_rescale is not None and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize is not None and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + if not is_batched(images): + images = [images] + annotations = [annotations] if annotations is not None else None + + if annotations is not None and len(images) != len(annotations): + raise ValueError( + f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match." + ) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + format = AnnotionFormat(format) + if annotations is not None: + if format == AnnotionFormat.COCO_DETECTION and not valid_coco_detection_annotations(annotations): + raise ValueError( + "Invalid COCO detection annotations. Annotations must a dict (single image) of list of dicts" + "(batch of images) with the following keys: `image_id` and `annotations`, with the latter " + "being a list of annotations in the COCO format." + ) + elif format == AnnotionFormat.COCO_PANOPTIC and not valid_coco_panoptic_annotations(annotations): + raise ValueError( + "Invalid COCO panoptic annotations. Annotations must a dict (single image) of list of dicts " + "(batch of images) with the following keys: `image_id`, `file_name` and `segments_info`, with " + "the latter being a list of annotations in the COCO format." + ) + elif format not in SUPPORTED_ANNOTATION_FORMATS: + raise ValueError( + f"Unsupported annotation format: {format} must be one of {SUPPORTED_ANNOTATION_FORMATS}" + ) + + if ( + masks_path is not None + and format == AnnotionFormat.COCO_PANOPTIC + and not isinstance(masks_path, (pathlib.Path, str)) + ): + raise ValueError( + "The path to the directory containing the mask PNG files should be provided as a" + f" `pathlib.Path` or string object, but is {type(masks_path)} instead." + ) + + # All transformations expect numpy arrays + images = [to_numpy_array(image) for image in images] + + # prepare (COCO annotations as a list of Dict -> DETR target as a single Dict per image) + if annotations is not None: + prepared_images = [] + prepared_annotations = [] + for image, target in zip(images, annotations): + target = self.prepare_annotation( + image, target, format, return_segmentation_masks=return_segmentation_masks, masks_path=masks_path + ) + prepared_images.append(image) + prepared_annotations.append(target) + images = prepared_images + annotations = prepared_annotations + del prepared_images, prepared_annotations + + # transformations + if do_resize: + if annotations is not None: + resized_images, resized_annotations = [], [] + for image, target in zip(images, annotations): + orig_size = get_image_size(image) + resized_image = self.resize(image, size=size, resample=resample) + resized_annotation = self.resize_annotation(target, orig_size, get_image_size(resized_image)) + resized_images.append(resized_image) + resized_annotations.append(resized_annotation) + images = resized_images + annotations = resized_annotations + del resized_images, resized_annotations + else: + images = [self.resize(image, size=size, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image, rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image, image_mean, image_std) for image in images] + if annotations is not None: + annotations = [ + self.normalize_annotation(annotation, get_image_size(image)) + for annotation, image in zip(annotations, images) + ] + + if do_pad: + # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...} + data = self.pad(images, return_pixel_mask=True, data_format=data_format) + else: + images = [to_channel_dimension_format(image, data_format) for image in images] + data = {"pixel_values": images} + + encoded_inputs = BatchFeature(data=data, tensor_type=return_tensors) + if annotations is not None: + encoded_inputs["labels"] = [ + BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations + ] + + return encoded_inputs + + def post_process_object_detection( + self, + outputs, + threshold: float = 0.5, + target_sizes: Union[TensorType, List[Tuple]] = None, + nms_threshold: float = 0.7, + ): + """ + Converts the output of [`DetaForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, + bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`DetrObjectDetectionOutput`]): + Raw outputs of the model. + threshold (`float`, *optional*, defaults to 0.5): + Score threshold to keep object detection predictions. + target_sizes (`torch.Tensor` or `List[Tuple[int, int]]`, *optional*): + Tensor of shape `(batch_size, 2)` or list of tuples (`Tuple[int, int]`) containing the target size + (height, width) of each image in the batch. If left to None, predictions will not be resized. + nms_threshold (`float`, *optional*, defaults to 0.7): + NMS threshold. + + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + batch_size, num_queries, num_labels = out_logits.shape + + if target_sizes is not None: + if len(out_logits) != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + prob = out_logits.sigmoid() + + all_scores = prob.view(batch_size, num_queries * num_labels).to(out_logits.device) + all_indexes = torch.arange(num_queries * num_labels)[None].repeat(batch_size, 1).to(out_logits.device) + all_boxes = torch.div(all_indexes, out_logits.shape[2], rounding_mode="floor") + all_labels = all_indexes % out_logits.shape[2] + + boxes = center_to_corners_format(out_bbox) + boxes = torch.gather(boxes, 1, all_boxes.unsqueeze(-1).repeat(1, 1, 4)) + + # and from relative [0, 1] to absolute [0, height] coordinates + if target_sizes is not None: + if isinstance(target_sizes, List): + img_h = torch.Tensor([i[0] for i in target_sizes]) + img_w = torch.Tensor([i[1] for i in target_sizes]) + else: + img_h, img_w = target_sizes.unbind(1) + + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [] + for b in range(batch_size): + box = boxes[b] + score = all_scores[b] + lbls = all_labels[b] + + pre_topk = score.topk(min(10000, len(score))).indices + box = box[pre_topk] + score = score[pre_topk] + lbls = lbls[pre_topk] + + # apply NMS + keep_inds = batched_nms(box, score, lbls, nms_threshold)[:100] + score = score[keep_inds] + lbls = lbls[keep_inds] + box = box[keep_inds] + + results.append( + { + "scores": score[score > threshold], + "labels": lbls[score > threshold], + "boxes": box[score > threshold], + } + ) + + return results diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/modeling_deta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/modeling_deta.py new file mode 100644 index 0000000000000000000000000000000000000000..2a66def096962bf3ad5f333bad479cf0f9a52786 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/deta/modeling_deta.py @@ -0,0 +1,2754 @@ +# coding=utf-8 +# Copyright 2022 SenseTime and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DETA model.""" + + +import copy +import math +import warnings +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple + +import torch +import torch.nn.functional as F +from torch import Tensor, nn + +from ...activations import ACT2FN +from ...file_utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + is_scipy_available, + is_vision_available, + replace_return_docstrings, +) +from ...modeling_outputs import BaseModelOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import meshgrid +from ...utils import is_torchvision_available, logging, requires_backends +from ..auto import AutoBackbone +from .configuration_deta import DetaConfig + + +logger = logging.get_logger(__name__) + + +if is_vision_available(): + from transformers.image_transforms import center_to_corners_format + +if is_torchvision_available(): + from torchvision.ops.boxes import batched_nms + +if is_scipy_available(): + from scipy.optimize import linear_sum_assignment + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DetaConfig" +_CHECKPOINT_FOR_DOC = "jozhang97/deta-swin-large-o365" + +DETA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "jozhang97/deta-swin-large-o365", + # See all DETA models at https://huggingface.co/models?filter=deta +] + + +@dataclass +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrDecoderOutput with DeformableDetr->Deta +class DetaDecoderOutput(ModelOutput): + """ + Base class for outputs of the DetaDecoder. This class adds two attributes to BaseModelOutputWithCrossAttentions, + namely: + - a stacked tensor of intermediate decoder hidden states (i.e. the output of each decoder layer) + - a stacked tensor of intermediate reference points. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, sequence_length, hidden_size)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer + plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + """ + + last_hidden_state: torch.FloatTensor = None + intermediate_hidden_states: torch.FloatTensor = None + intermediate_reference_points: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModelOutput with DeformableDetr->Deta,Deformable DETR->DETA +class DetaModelOutput(ModelOutput): + """ + Base class for outputs of the Deformable DETR encoder-decoder model. + + Args: + init_reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Initial reference points sent through the Transformer decoder. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, 4)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, num_queries, hidden_size)`. Hidden-states of the decoder at the output of each layer + plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, num_queries, + num_queries)`. Attentions weights of the decoder, after the attention softmax, used to compute the weighted + average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the + weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + enc_outputs_class (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Predicted bounding boxes scores where the top `config.two_stage_num_proposals` scoring bounding boxes are + picked as region proposals in the first stage. Output of bounding box binary classification (i.e. + foreground and background). + enc_outputs_coord_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, 4)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Logits of predicted bounding boxes coordinates in the first stage. + """ + + init_reference_points: torch.FloatTensor = None + last_hidden_state: torch.FloatTensor = None + intermediate_hidden_states: torch.FloatTensor = None + intermediate_reference_points: torch.FloatTensor = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + enc_outputs_class: Optional[torch.FloatTensor] = None + enc_outputs_coord_logits: Optional[torch.FloatTensor] = None + + +@dataclass +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrObjectDetectionOutput with DeformableDetr->Deta +class DetaObjectDetectionOutput(ModelOutput): + """ + Output type of [`DetaForObjectDetection`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)): + Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a + bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized + scale-invariant IoU loss. + loss_dict (`Dict`, *optional*): + A dictionary containing the individual losses. Useful for logging. + logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`): + Classification logits (including no-object) for all queries. + pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These + values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding + possible padding). You can use [`~DetaProcessor.post_process_object_detection`] to retrieve the + unnormalized bounding boxes. + auxiliary_outputs (`list[Dict]`, *optional*): + Optional, only returned when auxilary losses are activated (i.e. `config.auxiliary_loss` is set to `True`) + and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and + `pred_boxes`) for each decoder layer. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, num_queries, hidden_size)`. Hidden-states of the decoder at the output of each layer + plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, num_queries, + num_queries)`. Attentions weights of the decoder, after the attention softmax, used to compute the weighted + average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_queries, num_heads, 4, 4)`. + Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the + weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, sequence_length, num_heads, 4, + 4)`. Attentions weights of the encoder, after the attention softmax, used to compute the weighted average + in the self-attention heads. + intermediate_hidden_states (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, hidden_size)`): + Stacked intermediate hidden states (output of each layer of the decoder). + intermediate_reference_points (`torch.FloatTensor` of shape `(batch_size, config.decoder_layers, num_queries, 4)`): + Stacked intermediate reference points (reference points of each layer of the decoder). + init_reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Initial reference points sent through the Transformer decoder. + enc_outputs_class (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Predicted bounding boxes scores where the top `config.two_stage_num_proposals` scoring bounding boxes are + picked as region proposals in the first stage. Output of bounding box binary classification (i.e. + foreground and background). + enc_outputs_coord_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, 4)`, *optional*, returned when `config.with_box_refine=True` and `config.two_stage=True`): + Logits of predicted bounding boxes coordinates in the first stage. + """ + + loss: Optional[torch.FloatTensor] = None + loss_dict: Optional[Dict] = None + logits: torch.FloatTensor = None + pred_boxes: torch.FloatTensor = None + auxiliary_outputs: Optional[List[Dict]] = None + init_reference_points: Optional[torch.FloatTensor] = None + last_hidden_state: Optional[torch.FloatTensor] = None + intermediate_hidden_states: Optional[torch.FloatTensor] = None + intermediate_reference_points: Optional[torch.FloatTensor] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + enc_outputs_class: Optional = None + enc_outputs_coord_logits: Optional = None + + +def _get_clones(module, N): + return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) + + +def inverse_sigmoid(x, eps=1e-5): + x = x.clamp(min=0, max=1) + x1 = x.clamp(min=eps) + x2 = (1 - x).clamp(min=eps) + return torch.log(x1 / x2) + + +# Copied from transformers.models.detr.modeling_detr.DetrFrozenBatchNorm2d with Detr->Deta +class DetaFrozenBatchNorm2d(nn.Module): + """ + BatchNorm2d where the batch statistics and the affine parameters are fixed. + + Copy-paste from torchvision.misc.ops with added eps before rqsrt, without which any other models than + torchvision.models.resnet[18,34,50,101] produce nans. + """ + + def __init__(self, n): + super().__init__() + self.register_buffer("weight", torch.ones(n)) + self.register_buffer("bias", torch.zeros(n)) + self.register_buffer("running_mean", torch.zeros(n)) + self.register_buffer("running_var", torch.ones(n)) + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + num_batches_tracked_key = prefix + "num_batches_tracked" + if num_batches_tracked_key in state_dict: + del state_dict[num_batches_tracked_key] + + super()._load_from_state_dict( + state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ) + + def forward(self, x): + # move reshapes to the beginning + # to make it user-friendly + weight = self.weight.reshape(1, -1, 1, 1) + bias = self.bias.reshape(1, -1, 1, 1) + running_var = self.running_var.reshape(1, -1, 1, 1) + running_mean = self.running_mean.reshape(1, -1, 1, 1) + epsilon = 1e-5 + scale = weight * (running_var + epsilon).rsqrt() + bias = bias - running_mean * scale + return x * scale + bias + + +# Copied from transformers.models.detr.modeling_detr.replace_batch_norm with Detr->Deta +def replace_batch_norm(m, name=""): + for attr_str in dir(m): + target_attr = getattr(m, attr_str) + if isinstance(target_attr, nn.BatchNorm2d): + frozen = DetaFrozenBatchNorm2d(target_attr.num_features) + bn = getattr(m, attr_str) + frozen.weight.data.copy_(bn.weight) + frozen.bias.data.copy_(bn.bias) + frozen.running_mean.data.copy_(bn.running_mean) + frozen.running_var.data.copy_(bn.running_var) + setattr(m, attr_str, frozen) + for n, ch in m.named_children(): + replace_batch_norm(ch, n) + + +class DetaBackboneWithPositionalEncodings(nn.Module): + """ + Backbone model with positional embeddings. + + nn.BatchNorm2d layers are replaced by DetaFrozenBatchNorm2d as defined above. + """ + + def __init__(self, config): + super().__init__() + + backbone = AutoBackbone.from_config(config.backbone_config) + with torch.no_grad(): + replace_batch_norm(backbone) + self.model = backbone + self.intermediate_channel_sizes = self.model.channels + + # TODO fix this + if config.backbone_config.model_type == "resnet": + for name, parameter in self.model.named_parameters(): + if "stages.1" not in name and "stages.2" not in name and "stages.3" not in name: + parameter.requires_grad_(False) + + self.position_embedding = build_position_encoding(config) + + def forward(self, pixel_values: torch.Tensor, pixel_mask: torch.Tensor): + """ + Outputs feature maps of latter stages C_3 through C_5 in ResNet if `config.num_feature_levels > 1`, otherwise + outputs feature maps of C_5. + """ + # first, send pixel_values through the backbone to get list of feature maps + features = self.model(pixel_values).feature_maps + + # next, create position embeddings + out = [] + pos = [] + for feature_map in features: + # downsample pixel_mask to match shape of corresponding feature_map + mask = nn.functional.interpolate(pixel_mask[None].float(), size=feature_map.shape[-2:]).to(torch.bool)[0] + position_embeddings = self.position_embedding(feature_map, mask).to(feature_map.dtype) + out.append((feature_map, mask)) + pos.append(position_embeddings) + + return out, pos + + +# Copied from transformers.models.detr.modeling_detr._expand_mask +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, target_len: Optional[int] = None): + """ + Expands attention_mask from `[batch_size, seq_len]` to `[batch_size, 1, target_seq_len, source_seq_len]`. + """ + batch_size, source_len = mask.size() + target_len = target_len if target_len is not None else source_len + + expanded_mask = mask[:, None, None, :].expand(batch_size, 1, target_len, source_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.bool(), torch.finfo(dtype).min) + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrSinePositionEmbedding with DeformableDetr->Deta +class DetaSinePositionEmbedding(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one used by the Attention is all you + need paper, generalized to work on images. + """ + + def __init__(self, embedding_dim=64, temperature=10000, normalize=False, scale=None): + super().__init__() + self.embedding_dim = embedding_dim + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + def forward(self, pixel_values, pixel_mask): + if pixel_mask is None: + raise ValueError("No pixel mask provided") + y_embed = pixel_mask.cumsum(1, dtype=torch.float32) + x_embed = pixel_mask.cumsum(2, dtype=torch.float32) + if self.normalize: + eps = 1e-6 + y_embed = (y_embed - 0.5) / (y_embed[:, -1:, :] + eps) * self.scale + x_embed = (x_embed - 0.5) / (x_embed[:, :, -1:] + eps) * self.scale + + dim_t = torch.arange(self.embedding_dim, dtype=torch.float32, device=pixel_values.device) + dim_t = self.temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / self.embedding_dim) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + return pos + + +# Copied from transformers.models.detr.modeling_detr.DetrLearnedPositionEmbedding +class DetaLearnedPositionEmbedding(nn.Module): + """ + This module learns positional embeddings up to a fixed maximum size. + """ + + def __init__(self, embedding_dim=256): + super().__init__() + self.row_embeddings = nn.Embedding(50, embedding_dim) + self.column_embeddings = nn.Embedding(50, embedding_dim) + + def forward(self, pixel_values, pixel_mask=None): + height, width = pixel_values.shape[-2:] + width_values = torch.arange(width, device=pixel_values.device) + height_values = torch.arange(height, device=pixel_values.device) + x_emb = self.column_embeddings(width_values) + y_emb = self.row_embeddings(height_values) + pos = torch.cat([x_emb.unsqueeze(0).repeat(height, 1, 1), y_emb.unsqueeze(1).repeat(1, width, 1)], dim=-1) + pos = pos.permute(2, 0, 1) + pos = pos.unsqueeze(0) + pos = pos.repeat(pixel_values.shape[0], 1, 1, 1) + return pos + + +# Copied from transformers.models.detr.modeling_detr.build_position_encoding with Detr->Deta +def build_position_encoding(config): + n_steps = config.d_model // 2 + if config.position_embedding_type == "sine": + # TODO find a better way of exposing other arguments + position_embedding = DetaSinePositionEmbedding(n_steps, normalize=True) + elif config.position_embedding_type == "learned": + position_embedding = DetaLearnedPositionEmbedding(n_steps) + else: + raise ValueError(f"Not supported {config.position_embedding_type}") + + return position_embedding + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.multi_scale_deformable_attention +def multi_scale_deformable_attention( + value: Tensor, value_spatial_shapes: Tensor, sampling_locations: Tensor, attention_weights: Tensor +) -> Tensor: + batch_size, _, num_heads, hidden_dim = value.shape + _, num_queries, num_heads, num_levels, num_points, _ = sampling_locations.shape + value_list = value.split([height * width for height, width in value_spatial_shapes], dim=1) + sampling_grids = 2 * sampling_locations - 1 + sampling_value_list = [] + for level_id, (height, width) in enumerate(value_spatial_shapes): + # batch_size, height*width, num_heads, hidden_dim + # -> batch_size, height*width, num_heads*hidden_dim + # -> batch_size, num_heads*hidden_dim, height*width + # -> batch_size*num_heads, hidden_dim, height, width + value_l_ = ( + value_list[level_id].flatten(2).transpose(1, 2).reshape(batch_size * num_heads, hidden_dim, height, width) + ) + # batch_size, num_queries, num_heads, num_points, 2 + # -> batch_size, num_heads, num_queries, num_points, 2 + # -> batch_size*num_heads, num_queries, num_points, 2 + sampling_grid_l_ = sampling_grids[:, :, :, level_id].transpose(1, 2).flatten(0, 1) + # batch_size*num_heads, hidden_dim, num_queries, num_points + sampling_value_l_ = nn.functional.grid_sample( + value_l_, sampling_grid_l_, mode="bilinear", padding_mode="zeros", align_corners=False + ) + sampling_value_list.append(sampling_value_l_) + # (batch_size, num_queries, num_heads, num_levels, num_points) + # -> (batch_size, num_heads, num_queries, num_levels, num_points) + # -> (batch_size, num_heads, 1, num_queries, num_levels*num_points) + attention_weights = attention_weights.transpose(1, 2).reshape( + batch_size * num_heads, 1, num_queries, num_levels * num_points + ) + output = ( + (torch.stack(sampling_value_list, dim=-2).flatten(-2) * attention_weights) + .sum(-1) + .view(batch_size, num_heads * hidden_dim, num_queries) + ) + return output.transpose(1, 2).contiguous() + + +class DetaMultiscaleDeformableAttention(nn.Module): + """ + Multiscale deformable attention as proposed in Deformable DETR. + """ + + def __init__(self, embed_dim: int, num_heads: int, n_levels: int, n_points: int): + super().__init__() + if embed_dim % num_heads != 0: + raise ValueError( + f"embed_dim (d_model) must be divisible by num_heads, but got {embed_dim} and {num_heads}" + ) + dim_per_head = embed_dim // num_heads + # check if dim_per_head is power of 2 + if not ((dim_per_head & (dim_per_head - 1) == 0) and dim_per_head != 0): + warnings.warn( + "You'd better set embed_dim (d_model) in DetaMultiscaleDeformableAttention to make the" + " dimension of each attention head a power of 2 which is more efficient in the authors' CUDA" + " implementation." + ) + + self.im2col_step = 64 + + self.d_model = embed_dim + self.n_levels = n_levels + self.n_heads = num_heads + self.n_points = n_points + + self.sampling_offsets = nn.Linear(embed_dim, num_heads * n_levels * n_points * 2) + self.attention_weights = nn.Linear(embed_dim, num_heads * n_levels * n_points) + self.value_proj = nn.Linear(embed_dim, embed_dim) + self.output_proj = nn.Linear(embed_dim, embed_dim) + + self._reset_parameters() + + def _reset_parameters(self): + nn.init.constant_(self.sampling_offsets.weight.data, 0.0) + thetas = torch.arange(self.n_heads, dtype=torch.float32) * (2.0 * math.pi / self.n_heads) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = ( + (grid_init / grid_init.abs().max(-1, keepdim=True)[0]) + .view(self.n_heads, 1, 1, 2) + .repeat(1, self.n_levels, self.n_points, 1) + ) + for i in range(self.n_points): + grid_init[:, :, i, :] *= i + 1 + with torch.no_grad(): + self.sampling_offsets.bias = nn.Parameter(grid_init.view(-1)) + nn.init.constant_(self.attention_weights.weight.data, 0.0) + nn.init.constant_(self.attention_weights.bias.data, 0.0) + nn.init.xavier_uniform_(self.value_proj.weight.data) + nn.init.constant_(self.value_proj.bias.data, 0.0) + nn.init.xavier_uniform_(self.output_proj.weight.data) + nn.init.constant_(self.output_proj.bias.data, 0.0) + + def with_pos_embed(self, tensor: torch.Tensor, position_embeddings: Optional[Tensor]): + return tensor if position_embeddings is None else tensor + position_embeddings + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states=None, + encoder_attention_mask=None, + position_embeddings: Optional[torch.Tensor] = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + output_attentions: bool = False, + ): + # add position embeddings to the hidden states before projecting to queries and keys + if position_embeddings is not None: + hidden_states = self.with_pos_embed(hidden_states, position_embeddings) + + batch_size, num_queries, _ = hidden_states.shape + batch_size, sequence_length, _ = encoder_hidden_states.shape + if (spatial_shapes[:, 0] * spatial_shapes[:, 1]).sum() != sequence_length: + raise ValueError( + "Make sure to align the spatial shapes with the sequence length of the encoder hidden states" + ) + + value = self.value_proj(encoder_hidden_states) + if attention_mask is not None: + # we invert the attention_mask + value = value.masked_fill(~attention_mask[..., None], float(0)) + value = value.view(batch_size, sequence_length, self.n_heads, self.d_model // self.n_heads) + sampling_offsets = self.sampling_offsets(hidden_states).view( + batch_size, num_queries, self.n_heads, self.n_levels, self.n_points, 2 + ) + attention_weights = self.attention_weights(hidden_states).view( + batch_size, num_queries, self.n_heads, self.n_levels * self.n_points + ) + attention_weights = F.softmax(attention_weights, -1).view( + batch_size, num_queries, self.n_heads, self.n_levels, self.n_points + ) + # batch_size, num_queries, n_heads, n_levels, n_points, 2 + if reference_points.shape[-1] == 2: + offset_normalizer = torch.stack([spatial_shapes[..., 1], spatial_shapes[..., 0]], -1) + sampling_locations = ( + reference_points[:, :, None, :, None, :] + + sampling_offsets / offset_normalizer[None, None, None, :, None, :] + ) + elif reference_points.shape[-1] == 4: + sampling_locations = ( + reference_points[:, :, None, :, None, :2] + + sampling_offsets / self.n_points * reference_points[:, :, None, :, None, 2:] * 0.5 + ) + else: + raise ValueError(f"Last dim of reference_points must be 2 or 4, but got {reference_points.shape[-1]}") + # PyTorch implementation (for now) + output = multi_scale_deformable_attention(value, spatial_shapes, sampling_locations, attention_weights) + output = self.output_proj(output) + + return output, attention_weights + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrMultiheadAttention with DeformableDetr->Deta,Deformable DETR->DETA +class DetaMultiheadAttention(nn.Module): + """ + Multi-headed attention from 'Attention Is All You Need' paper. + + Here, we add position embeddings to the queries and keys (as explained in the Deformable DETR paper). + """ + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + if self.head_dim * num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, batch_size: int): + return tensor.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def with_pos_embed(self, tensor: torch.Tensor, position_embeddings: Optional[Tensor]): + return tensor if position_embeddings is None else tensor + position_embeddings + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_embeddings: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + batch_size, target_len, embed_dim = hidden_states.size() + # add position embeddings to the hidden states before projecting to queries and keys + if position_embeddings is not None: + hidden_states_original = hidden_states + hidden_states = self.with_pos_embed(hidden_states, position_embeddings) + + # get queries, keys and values + query_states = self.q_proj(hidden_states) * self.scaling + key_states = self._shape(self.k_proj(hidden_states), -1, batch_size) + value_states = self._shape(self.v_proj(hidden_states_original), -1, batch_size) + + proj_shape = (batch_size * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, target_len, batch_size).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + source_len = key_states.size(1) + + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (batch_size * self.num_heads, target_len, source_len): + raise ValueError( + f"Attention weights should be of size {(batch_size * self.num_heads, target_len, source_len)}, but is" + f" {attn_weights.size()}" + ) + + # expand attention_mask + if attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len] + attention_mask = _expand_mask(attention_mask, hidden_states.dtype) + + if attention_mask is not None: + if attention_mask.size() != (batch_size, 1, target_len, source_len): + raise ValueError( + f"Attention mask should be of size {(batch_size, 1, target_len, source_len)}, but is" + f" {attention_mask.size()}" + ) + attn_weights = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attention_mask + attn_weights = attn_weights.view(batch_size * self.num_heads, target_len, source_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attn_weights = attn_weights_reshaped.view(batch_size * self.num_heads, target_len, source_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (batch_size * self.num_heads, target_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(batch_size, self.num_heads, target_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(batch_size, self.num_heads, target_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + attn_output = attn_output.reshape(batch_size, target_len, embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped + + +class DetaEncoderLayer(nn.Module): + def __init__(self, config: DetaConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = DetaMultiscaleDeformableAttention( + embed_dim=self.embed_dim, + num_heads=config.encoder_attention_heads, + n_levels=config.num_feature_levels, + n_points=config.encoder_n_points, + ) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_embeddings: torch.Tensor = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + output_attentions: bool = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Input to the layer. + attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Attention mask. + position_embeddings (`torch.FloatTensor`, *optional*): + Position embeddings, to be added to `hidden_states`. + reference_points (`torch.FloatTensor`, *optional*): + Reference points. + spatial_shapes (`torch.LongTensor`, *optional*): + Spatial shapes of the backbone feature maps. + level_start_index (`torch.LongTensor`, *optional*): + Level start index. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Apply Multi-scale Deformable Attention Module on the multi-scale feature maps. + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=hidden_states, + encoder_attention_mask=attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + if self.training: + if torch.isinf(hidden_states).any() or torch.isnan(hidden_states).any(): + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class DetaDecoderLayer(nn.Module): + def __init__(self, config: DetaConfig): + super().__init__() + self.embed_dim = config.d_model + + # self-attention + self.self_attn = DetaMultiheadAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + # cross-attention + self.encoder_attn = DetaMultiscaleDeformableAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + n_levels=config.num_feature_levels, + n_points=config.decoder_n_points, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + # feedforward neural networks + self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim) + self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: Optional[torch.Tensor] = None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor`): + Input to the layer of shape `(seq_len, batch, embed_dim)`. + position_embeddings (`torch.FloatTensor`, *optional*): + Position embeddings that are added to the queries and keys in the self-attention layer. + reference_points (`torch.FloatTensor`, *optional*): + Reference points. + spatial_shapes (`torch.LongTensor`, *optional*): + Spatial shapes. + level_start_index (`torch.LongTensor`, *optional*): + Level start index. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(seq_len, batch, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative + values. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + second_residual = hidden_states + + # Cross-Attention + cross_attn_weights = None + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + attention_mask=encoder_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = second_residual + hidden_states + + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +# Copied from transformers.models.detr.modeling_detr.DetrClassificationHead +class DetaClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, input_dim: int, inner_dim: int, num_classes: int, pooler_dropout: float): + super().__init__() + self.dense = nn.Linear(input_dim, inner_dim) + self.dropout = nn.Dropout(p=pooler_dropout) + self.out_proj = nn.Linear(inner_dim, num_classes) + + def forward(self, hidden_states: torch.Tensor): + hidden_states = self.dropout(hidden_states) + hidden_states = self.dense(hidden_states) + hidden_states = torch.tanh(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrPreTrainedModel with DeformableDetr->Deta +class DetaPreTrainedModel(PreTrainedModel): + config_class = DetaConfig + base_model_prefix = "model" + main_input_name = "pixel_values" + + def _init_weights(self, module): + std = self.config.init_std + + if isinstance(module, DetaLearnedPositionEmbedding): + nn.init.uniform_(module.row_embeddings.weight) + nn.init.uniform_(module.column_embeddings.weight) + elif isinstance(module, DetaMultiscaleDeformableAttention): + module._reset_parameters() + elif isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + if hasattr(module, "reference_points") and not self.config.two_stage: + nn.init.xavier_uniform_(module.reference_points.weight.data, gain=1.0) + nn.init.constant_(module.reference_points.bias.data, 0.0) + if hasattr(module, "level_embed"): + nn.init.normal_(module.level_embed) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DetaDecoder): + module.gradient_checkpointing = value + + +DETA_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`DetaConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DETA_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. + + Pixel values can be obtained using [`AutoImageProcessor`]. See [`AutoImageProcessor.__call__`] for details. + + pixel_mask (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*): + Mask to avoid performing attention on padding pixel values. Mask values selected in `[0, 1]`: + + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + + [What are attention masks?](../glossary#attention-mask) + + decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, num_queries)`, *optional*): + Not used by default. Can be used to mask object queries. + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you + can choose to directly pass a flattened representation of an image. + decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an + embedded representation. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrEncoder with DeformableDetr->Deta +class DetaEncoder(DetaPreTrainedModel): + """ + Transformer encoder consisting of *config.encoder_layers* deformable attention layers. Each layer is a + [`DetaEncoderLayer`]. + + The encoder updates the flattened multi-scale feature maps through multiple deformable attention layers. + + Args: + config: DetaConfig + """ + + def __init__(self, config: DetaConfig): + super().__init__(config) + + self.dropout = config.dropout + self.layers = nn.ModuleList([DetaEncoderLayer(config) for _ in range(config.encoder_layers)]) + + # Initialize weights and apply final processing + self.post_init() + + @staticmethod + def get_reference_points(spatial_shapes, valid_ratios, device): + """ + Get reference points for each feature map. Used in decoder. + + Args: + spatial_shapes (`torch.LongTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of each feature map. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`): + Valid ratios of each feature map. + device (`torch.device`): + Device on which to create the tensors. + Returns: + `torch.FloatTensor` of shape `(batch_size, num_queries, num_feature_levels, 2)` + """ + reference_points_list = [] + for level, (height, width) in enumerate(spatial_shapes): + ref_y, ref_x = meshgrid( + torch.linspace(0.5, height - 0.5, height, dtype=torch.float32, device=device), + torch.linspace(0.5, width - 0.5, width, dtype=torch.float32, device=device), + indexing="ij", + ) + # TODO: valid_ratios could be useless here. check https://github.com/fundamentalvision/Deformable-DETR/issues/36 + ref_y = ref_y.reshape(-1)[None] / (valid_ratios[:, None, level, 1] * height) + ref_x = ref_x.reshape(-1)[None] / (valid_ratios[:, None, level, 0] * width) + ref = torch.stack((ref_x, ref_y), -1) + reference_points_list.append(ref) + reference_points = torch.cat(reference_points_list, 1) + reference_points = reference_points[:, :, None] * valid_ratios[:, None] + return reference_points + + def forward( + self, + inputs_embeds=None, + attention_mask=None, + position_embeddings=None, + spatial_shapes=None, + level_start_index=None, + valid_ratios=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Flattened feature map (output of the backbone + projection layer) that is passed to the encoder. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding pixel features. Mask values selected in `[0, 1]`: + - 1 for pixel features that are real (i.e. **not masked**), + - 0 for pixel features that are padding (i.e. **masked**). + [What are attention masks?](../glossary#attention-mask) + position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Position embeddings that are added to the queries and keys in each self-attention layer. + spatial_shapes (`torch.LongTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of each feature map. + level_start_index (`torch.LongTensor` of shape `(num_feature_levels)`): + Starting index of each feature map. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`): + Ratio of valid area in each feature level. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + hidden_states = inputs_embeds + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + reference_points = self.get_reference_points(spatial_shapes, valid_ratios, device=inputs_embeds.device) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + for i, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + position_embeddings=position_embeddings, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrDecoder with DeformableDetr->Deta,Deformable DETR->DETA +class DetaDecoder(DetaPreTrainedModel): + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`DetaDecoderLayer`]. + + The decoder updates the query embeddings through multiple self-attention and cross-attention layers. + + Some tweaks for Deformable DETR: + + - `position_embeddings`, `reference_points`, `spatial_shapes` and `valid_ratios` are added to the forward pass. + - it also returns a stack of intermediate outputs and reference points from all decoding layers. + + Args: + config: DetaConfig + """ + + def __init__(self, config: DetaConfig): + super().__init__(config) + + self.dropout = config.dropout + self.layers = nn.ModuleList([DetaDecoderLayer(config) for _ in range(config.decoder_layers)]) + self.gradient_checkpointing = False + + # hack implementation for iterative bounding box refinement and two-stage Deformable DETR + self.bbox_embed = None + self.class_embed = None + + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + inputs_embeds=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + position_embeddings=None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + valid_ratios=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`): + The query embeddings that are passed into the decoder. + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding pixel_values of the encoder. Mask values selected + in `[0, 1]`: + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + position_embeddings (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Position embeddings that are added to the queries and keys in each self-attention layer. + reference_points (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)` is `as_two_stage` else `(batch_size, num_queries, 2)` or , *optional*): + Reference point in range `[0, 1]`, top-left (0,0), bottom-right (1, 1), including padding area. + spatial_shapes (`torch.FloatTensor` of shape `(num_feature_levels, 2)`): + Spatial shapes of the feature maps. + level_start_index (`torch.LongTensor` of shape `(num_feature_levels)`, *optional*): + Indexes for the start of each feature level. In range `[0, sequence_length]`. + valid_ratios (`torch.FloatTensor` of shape `(batch_size, num_feature_levels, 2)`, *optional*): + Ratio of valid area in each feature level. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if inputs_embeds is not None: + hidden_states = inputs_embeds + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + intermediate = () + intermediate_reference_points = () + + for idx, decoder_layer in enumerate(self.layers): + if reference_points.shape[-1] == 4: + reference_points_input = ( + reference_points[:, :, None] * torch.cat([valid_ratios, valid_ratios], -1)[:, None] + ) + else: + if reference_points.shape[-1] != 2: + raise ValueError("Reference points' last dimension must be of size 2") + reference_points_input = reference_points[:, :, None] * valid_ratios[:, None] + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + encoder_hidden_states, + encoder_attention_mask, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + encoder_hidden_states=encoder_hidden_states, + reference_points=reference_points_input, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + # hack implementation for iterative bounding box refinement + if self.bbox_embed is not None: + tmp = self.bbox_embed[idx](hidden_states) + if reference_points.shape[-1] == 4: + new_reference_points = tmp + inverse_sigmoid(reference_points) + new_reference_points = new_reference_points.sigmoid() + else: + if reference_points.shape[-1] != 2: + raise ValueError( + f"Reference points' last dimension must be of size 2, but is {reference_points.shape[-1]}" + ) + new_reference_points = tmp + new_reference_points[..., :2] = tmp[..., :2] + inverse_sigmoid(reference_points) + new_reference_points = new_reference_points.sigmoid() + reference_points = new_reference_points.detach() + + intermediate += (hidden_states,) + intermediate_reference_points += (reference_points,) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # Keep batch_size as first dimension + intermediate = torch.stack(intermediate, dim=1) + intermediate_reference_points = torch.stack(intermediate_reference_points, dim=1) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + intermediate, + intermediate_reference_points, + all_hidden_states, + all_self_attns, + all_cross_attentions, + ] + if v is not None + ) + return DetaDecoderOutput( + last_hidden_state=hidden_states, + intermediate_hidden_states=intermediate, + intermediate_reference_points=intermediate_reference_points, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + """ + The bare DETA Model (consisting of a backbone and encoder-decoder Transformer) outputting raw hidden-states without + any specific head on top. + """, + DETA_START_DOCSTRING, +) +class DetaModel(DetaPreTrainedModel): + def __init__(self, config: DetaConfig): + super().__init__(config) + + if config.two_stage: + requires_backends(self, ["torchvision"]) + + # Create backbone with positional encoding + self.backbone = DetaBackboneWithPositionalEncodings(config) + intermediate_channel_sizes = self.backbone.intermediate_channel_sizes + + # Create input projection layers + if config.num_feature_levels > 1: + num_backbone_outs = len(intermediate_channel_sizes) + input_proj_list = [] + for _ in range(num_backbone_outs): + in_channels = intermediate_channel_sizes[_] + input_proj_list.append( + nn.Sequential( + nn.Conv2d(in_channels, config.d_model, kernel_size=1), + nn.GroupNorm(32, config.d_model), + ) + ) + for _ in range(config.num_feature_levels - num_backbone_outs): + input_proj_list.append( + nn.Sequential( + nn.Conv2d(in_channels, config.d_model, kernel_size=3, stride=2, padding=1), + nn.GroupNorm(32, config.d_model), + ) + ) + in_channels = config.d_model + self.input_proj = nn.ModuleList(input_proj_list) + else: + self.input_proj = nn.ModuleList( + [ + nn.Sequential( + nn.Conv2d(intermediate_channel_sizes[-1], config.d_model, kernel_size=1), + nn.GroupNorm(32, config.d_model), + ) + ] + ) + + if not config.two_stage: + self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model * 2) + + self.encoder = DetaEncoder(config) + self.decoder = DetaDecoder(config) + + self.level_embed = nn.Parameter(torch.Tensor(config.num_feature_levels, config.d_model)) + + if config.two_stage: + self.enc_output = nn.Linear(config.d_model, config.d_model) + self.enc_output_norm = nn.LayerNorm(config.d_model) + self.pos_trans = nn.Linear(config.d_model * 2, config.d_model * 2) + self.pos_trans_norm = nn.LayerNorm(config.d_model * 2) + self.pix_trans = nn.Linear(config.d_model, config.d_model) + self.pix_trans_norm = nn.LayerNorm(config.d_model) + else: + self.reference_points = nn.Linear(config.d_model, 2) + + self.assign_first_stage = config.assign_first_stage + self.two_stage_num_proposals = config.two_stage_num_proposals + + self.post_init() + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.get_encoder + def get_encoder(self): + return self.encoder + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.get_decoder + def get_decoder(self): + return self.decoder + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.freeze_backbone + def freeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(False) + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.unfreeze_backbone + def unfreeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(True) + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.get_valid_ratio + def get_valid_ratio(self, mask): + """Get the valid ratio of all feature maps.""" + + _, height, width = mask.shape + valid_height = torch.sum(mask[:, :, 0], 1) + valid_width = torch.sum(mask[:, 0, :], 1) + valid_ratio_heigth = valid_height.float() / height + valid_ratio_width = valid_width.float() / width + valid_ratio = torch.stack([valid_ratio_width, valid_ratio_heigth], -1) + return valid_ratio + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrModel.get_proposal_pos_embed + def get_proposal_pos_embed(self, proposals): + """Get the position embedding of the proposals.""" + + num_pos_feats = 128 + temperature = 10000 + scale = 2 * math.pi + + dim_t = torch.arange(num_pos_feats, dtype=torch.float32, device=proposals.device) + dim_t = temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / num_pos_feats) + # batch_size, num_queries, 4 + proposals = proposals.sigmoid() * scale + # batch_size, num_queries, 4, 128 + pos = proposals[:, :, :, None] / dim_t + # batch_size, num_queries, 4, 64, 2 -> batch_size, num_queries, 512 + pos = torch.stack((pos[:, :, :, 0::2].sin(), pos[:, :, :, 1::2].cos()), dim=4).flatten(2) + return pos + + def gen_encoder_output_proposals(self, enc_output, padding_mask, spatial_shapes): + """Generate the encoder output proposals from encoded enc_output. + + Args: + enc_output (Tensor[batch_size, sequence_length, hidden_size]): Output of the encoder. + padding_mask (Tensor[batch_size, sequence_length]): Padding mask for `enc_output`. + spatial_shapes (Tensor[num_feature_levels, 2]): Spatial shapes of the feature maps. + + Returns: + `tuple(torch.FloatTensor)`: A tuple of feature map and bbox prediction. + - object_query (Tensor[batch_size, sequence_length, hidden_size]): Object query features. Later used to + directly predict a bounding box. (without the need of a decoder) + - output_proposals (Tensor[batch_size, sequence_length, 4]): Normalized proposals, after an inverse + sigmoid. + """ + batch_size = enc_output.shape[0] + proposals = [] + _cur = 0 + level_ids = [] + for level, (height, width) in enumerate(spatial_shapes): + mask_flatten_ = padding_mask[:, _cur : (_cur + height * width)].view(batch_size, height, width, 1) + valid_height = torch.sum(~mask_flatten_[:, :, 0, 0], 1) + valid_width = torch.sum(~mask_flatten_[:, 0, :, 0], 1) + + grid_y, grid_x = meshgrid( + torch.linspace(0, height - 1, height, dtype=torch.float32, device=enc_output.device), + torch.linspace(0, width - 1, width, dtype=torch.float32, device=enc_output.device), + indexing="ij", + ) + grid = torch.cat([grid_x.unsqueeze(-1), grid_y.unsqueeze(-1)], -1) + + scale = torch.cat([valid_width.unsqueeze(-1), valid_height.unsqueeze(-1)], 1).view(batch_size, 1, 1, 2) + grid = (grid.unsqueeze(0).expand(batch_size, -1, -1, -1) + 0.5) / scale + width_heigth = torch.ones_like(grid) * 0.05 * (2.0**level) + proposal = torch.cat((grid, width_heigth), -1).view(batch_size, -1, 4) + proposals.append(proposal) + _cur += height * width + level_ids.append(grid.new_ones(height * width, dtype=torch.long) * level) + output_proposals = torch.cat(proposals, 1) + output_proposals_valid = ((output_proposals > 0.01) & (output_proposals < 0.99)).all(-1, keepdim=True) + output_proposals = torch.log(output_proposals / (1 - output_proposals)) # inverse sigmoid + output_proposals = output_proposals.masked_fill(padding_mask.unsqueeze(-1), float("inf")) + output_proposals = output_proposals.masked_fill(~output_proposals_valid, float("inf")) + + # assign each pixel as an object query + object_query = enc_output + object_query = object_query.masked_fill(padding_mask.unsqueeze(-1), float(0)) + object_query = object_query.masked_fill(~output_proposals_valid, float(0)) + object_query = self.enc_output_norm(self.enc_output(object_query)) + level_ids = torch.cat(level_ids) + return object_query, output_proposals, level_ids + + @add_start_docstrings_to_model_forward(DETA_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DetaModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DetaModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("jozhang97/deta-swin-large-o365") + >>> model = DetaModel.from_pretrained("jozhang97/deta-swin-large-o365", two_stage=False) + + >>> inputs = image_processor(images=image, return_tensors="pt") + + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + [1, 900, 256] + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_channels, height, width = pixel_values.shape + device = pixel_values.device + + if pixel_mask is None: + pixel_mask = torch.ones(((batch_size, height, width)), dtype=torch.long, device=device) + + # Extract multi-scale feature maps of same resolution `config.d_model` (cf Figure 4 in paper) + # First, sent pixel_values + pixel_mask through Backbone to obtain the features + # which is a list of tuples + features, position_embeddings_list = self.backbone(pixel_values, pixel_mask) + + # Then, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default) + sources = [] + masks = [] + for level, (source, mask) in enumerate(features): + sources.append(self.input_proj[level](source)) + masks.append(mask) + if mask is None: + raise ValueError("No attention mask was provided") + + # Lowest resolution feature maps are obtained via 3x3 stride 2 convolutions on the final stage + if self.config.num_feature_levels > len(sources): + _len_sources = len(sources) + for level in range(_len_sources, self.config.num_feature_levels): + if level == _len_sources: + source = self.input_proj[level](features[-1][0]) + else: + source = self.input_proj[level](sources[-1]) + mask = nn.functional.interpolate(pixel_mask[None].float(), size=source.shape[-2:]).to(torch.bool)[0] + pos_l = self.backbone.position_embedding(source, mask).to(source.dtype) + sources.append(source) + masks.append(mask) + position_embeddings_list.append(pos_l) + + # Create queries + query_embeds = None + if not self.config.two_stage: + query_embeds = self.query_position_embeddings.weight + + # Prepare encoder inputs (by flattening) + spatial_shapes = [(source.shape[2:]) for source in sources] + source_flatten = [source.flatten(2).transpose(1, 2) for source in sources] + mask_flatten = [mask.flatten(1) for mask in masks] + + lvl_pos_embed_flatten = [] + for level, pos_embed in enumerate(position_embeddings_list): + pos_embed = pos_embed.flatten(2).transpose(1, 2) + lvl_pos_embed = pos_embed + self.level_embed[level].view(1, 1, -1) + lvl_pos_embed_flatten.append(lvl_pos_embed) + + source_flatten = torch.cat(source_flatten, 1) + mask_flatten = torch.cat(mask_flatten, 1) + lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1) + spatial_shapes = torch.as_tensor(spatial_shapes, dtype=torch.long, device=source_flatten.device) + level_start_index = torch.cat((spatial_shapes.new_zeros((1,)), spatial_shapes.prod(1).cumsum(0)[:-1])) + valid_ratios = torch.stack([self.get_valid_ratio(m) for m in masks], 1) + valid_ratios = valid_ratios.float() + + # Fourth, sent source_flatten + mask_flatten + lvl_pos_embed_flatten (backbone + proj layer output) through encoder + # Also provide spatial_shapes, level_start_index and valid_ratios + if encoder_outputs is None: + encoder_outputs = self.encoder( + inputs_embeds=source_flatten, + attention_mask=mask_flatten, + position_embeddings=lvl_pos_embed_flatten, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + valid_ratios=valid_ratios, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # Fifth, prepare decoder inputs + batch_size, _, num_channels = encoder_outputs[0].shape + enc_outputs_class = None + enc_outputs_coord_logits = None + if self.config.two_stage: + object_query_embedding, output_proposals, level_ids = self.gen_encoder_output_proposals( + encoder_outputs[0], ~mask_flatten, spatial_shapes + ) + + # hack implementation for two-stage DETA + # apply a detection head to each pixel (A.4 in paper) + # linear projection for bounding box binary classification (i.e. foreground and background) + enc_outputs_class = self.decoder.class_embed[-1](object_query_embedding) + # 3-layer FFN to predict bounding boxes coordinates (bbox regression branch) + delta_bbox = self.decoder.bbox_embed[-1](object_query_embedding) + enc_outputs_coord_logits = delta_bbox + output_proposals + + # only keep top scoring `config.two_stage_num_proposals` proposals + topk = self.two_stage_num_proposals + proposal_logit = enc_outputs_class[..., 0] + + if self.assign_first_stage: + proposal_boxes = center_to_corners_format(enc_outputs_coord_logits.sigmoid().float()).clamp(0, 1) + topk_proposals = [] + for b in range(batch_size): + prop_boxes_b = proposal_boxes[b] + prop_logits_b = proposal_logit[b] + + # pre-nms per-level topk + pre_nms_topk = 1000 + pre_nms_inds = [] + for lvl in range(len(spatial_shapes)): + lvl_mask = level_ids == lvl + pre_nms_inds.append(torch.topk(prop_logits_b.sigmoid() * lvl_mask, pre_nms_topk)[1]) + pre_nms_inds = torch.cat(pre_nms_inds) + + # nms on topk indices + post_nms_inds = batched_nms( + prop_boxes_b[pre_nms_inds], prop_logits_b[pre_nms_inds], level_ids[pre_nms_inds], 0.9 + ) + keep_inds = pre_nms_inds[post_nms_inds] + + if len(keep_inds) < self.two_stage_num_proposals: + print( + f"[WARNING] nms proposals ({len(keep_inds)}) < {self.two_stage_num_proposals}, running" + " naive topk" + ) + keep_inds = torch.topk(proposal_logit[b], topk)[1] + + # keep top Q/L indices for L levels + q_per_l = topk // len(spatial_shapes) + is_level_ordered = ( + level_ids[keep_inds][None] + == torch.arange(len(spatial_shapes), device=level_ids.device)[:, None] + ) + keep_inds_mask = is_level_ordered & (is_level_ordered.cumsum(1) <= q_per_l) # LS + keep_inds_mask = keep_inds_mask.any(0) # S + + # pad to Q indices (might let ones filtered from pre-nms sneak by... unlikely because we pick high conf anyways) + if keep_inds_mask.sum() < topk: + num_to_add = topk - keep_inds_mask.sum() + pad_inds = (~keep_inds_mask).nonzero()[:num_to_add] + keep_inds_mask[pad_inds] = True + + keep_inds_topk = keep_inds[keep_inds_mask] + topk_proposals.append(keep_inds_topk) + topk_proposals = torch.stack(topk_proposals) + else: + topk_proposals = torch.topk(enc_outputs_class[..., 0], topk, dim=1)[1] + + topk_coords_logits = torch.gather( + enc_outputs_coord_logits, 1, topk_proposals.unsqueeze(-1).repeat(1, 1, 4) + ) + topk_coords_logits = topk_coords_logits.detach() + reference_points = topk_coords_logits.sigmoid() + init_reference_points = reference_points + pos_trans_out = self.pos_trans_norm(self.pos_trans(self.get_proposal_pos_embed(topk_coords_logits))) + query_embed, target = torch.split(pos_trans_out, num_channels, dim=2) + else: + query_embed, target = torch.split(query_embeds, num_channels, dim=1) + query_embed = query_embed.unsqueeze(0).expand(batch_size, -1, -1) + target = target.unsqueeze(0).expand(batch_size, -1, -1) + reference_points = self.reference_points(query_embed).sigmoid() + init_reference_points = reference_points + + decoder_outputs = self.decoder( + inputs_embeds=target, + position_embeddings=query_embed, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=mask_flatten, + reference_points=reference_points, + spatial_shapes=spatial_shapes, + level_start_index=level_start_index, + valid_ratios=valid_ratios, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + enc_outputs = tuple(value for value in [enc_outputs_class, enc_outputs_coord_logits] if value is not None) + tuple_outputs = (init_reference_points,) + decoder_outputs + encoder_outputs + enc_outputs + + return tuple_outputs + + return DetaModelOutput( + init_reference_points=init_reference_points, + last_hidden_state=decoder_outputs.last_hidden_state, + intermediate_hidden_states=decoder_outputs.intermediate_hidden_states, + intermediate_reference_points=decoder_outputs.intermediate_reference_points, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + enc_outputs_class=enc_outputs_class, + enc_outputs_coord_logits=enc_outputs_coord_logits, + ) + + +@add_start_docstrings( + """ + DETA Model (consisting of a backbone and encoder-decoder Transformer) with object detection heads on top, for tasks + such as COCO detection. + """, + DETA_START_DOCSTRING, +) +class DetaForObjectDetection(DetaPreTrainedModel): + # When using clones, all layers > 0 will be clones, but layer 0 *is* required + _keys_to_ignore_on_load_missing = [r"bbox_embed\.[1-9]\d*", r"class_embed\.[1-9]\d*"] + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrForObjectDetection.__init__ with DeformableDetr->Deta + def __init__(self, config: DetaConfig): + super().__init__(config) + + # Deformable DETR encoder-decoder model + self.model = DetaModel(config) + + # Detection heads on top + self.class_embed = nn.Linear(config.d_model, config.num_labels) + self.bbox_embed = DetaMLPPredictionHead( + input_dim=config.d_model, hidden_dim=config.d_model, output_dim=4, num_layers=3 + ) + + prior_prob = 0.01 + bias_value = -math.log((1 - prior_prob) / prior_prob) + self.class_embed.bias.data = torch.ones(config.num_labels) * bias_value + nn.init.constant_(self.bbox_embed.layers[-1].weight.data, 0) + nn.init.constant_(self.bbox_embed.layers[-1].bias.data, 0) + + # if two-stage, the last class_embed and bbox_embed is for region proposal generation + num_pred = (config.decoder_layers + 1) if config.two_stage else config.decoder_layers + if config.with_box_refine: + self.class_embed = _get_clones(self.class_embed, num_pred) + self.bbox_embed = _get_clones(self.bbox_embed, num_pred) + nn.init.constant_(self.bbox_embed[0].layers[-1].bias.data[2:], -2.0) + # hack implementation for iterative bounding box refinement + self.model.decoder.bbox_embed = self.bbox_embed + else: + nn.init.constant_(self.bbox_embed.layers[-1].bias.data[2:], -2.0) + self.class_embed = nn.ModuleList([self.class_embed for _ in range(num_pred)]) + self.bbox_embed = nn.ModuleList([self.bbox_embed for _ in range(num_pred)]) + self.model.decoder.bbox_embed = None + if config.two_stage: + # hack implementation for two-stage + self.model.decoder.class_embed = self.class_embed + for box_embed in self.bbox_embed: + nn.init.constant_(box_embed.layers[-1].bias.data[2:], 0.0) + + # Initialize weights and apply final processing + self.post_init() + + @torch.jit.unused + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrForObjectDetection._set_aux_loss + def _set_aux_loss(self, outputs_class, outputs_coord): + # this is a workaround to make torchscript happy, as torchscript + # doesn't support dictionary with non-homogeneous values, such + # as a dict having both a Tensor and a list. + return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])] + + @add_start_docstrings_to_model_forward(DETA_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DetaObjectDetectionOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + labels=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + labels (`List[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the + following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch + respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes + in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`. + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DetaForObjectDetection + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("jozhang97/deta-swin-large") + >>> model = DetaForObjectDetection.from_pretrained("jozhang97/deta-swin-large") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + + >>> # convert outputs (bounding boxes and class logits) to COCO API + >>> target_sizes = torch.tensor([image.size[::-1]]) + >>> results = image_processor.post_process_object_detection(outputs, threshold=0.5, target_sizes=target_sizes)[ + ... 0 + ... ] + >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]): + ... box = [round(i, 2) for i in box.tolist()] + ... print( + ... f"Detected {model.config.id2label[label.item()]} with confidence " + ... f"{round(score.item(), 3)} at location {box}" + ... ) + Detected cat with confidence 0.683 at location [345.85, 23.68, 639.86, 372.83] + Detected cat with confidence 0.683 at location [8.8, 52.49, 316.93, 473.45] + Detected remote with confidence 0.568 at location [40.02, 73.75, 175.96, 117.33] + Detected remote with confidence 0.546 at location [333.68, 77.13, 370.12, 187.51] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # First, sent images through DETR base model to obtain encoder + decoder outputs + outputs = self.model( + pixel_values, + pixel_mask=pixel_mask, + decoder_attention_mask=decoder_attention_mask, + encoder_outputs=encoder_outputs, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs.intermediate_hidden_states if return_dict else outputs[2] + init_reference = outputs.init_reference_points if return_dict else outputs[0] + inter_references = outputs.intermediate_reference_points if return_dict else outputs[3] + + # class logits + predicted bounding boxes + outputs_classes = [] + outputs_coords = [] + + for level in range(hidden_states.shape[1]): + if level == 0: + reference = init_reference + else: + reference = inter_references[:, level - 1] + reference = inverse_sigmoid(reference) + outputs_class = self.class_embed[level](hidden_states[:, level]) + delta_bbox = self.bbox_embed[level](hidden_states[:, level]) + if reference.shape[-1] == 4: + outputs_coord_logits = delta_bbox + reference + elif reference.shape[-1] == 2: + delta_bbox[..., :2] += reference + outputs_coord_logits = delta_bbox + else: + raise ValueError(f"reference.shape[-1] should be 4 or 2, but got {reference.shape[-1]}") + outputs_coord = outputs_coord_logits.sigmoid() + outputs_classes.append(outputs_class) + outputs_coords.append(outputs_coord) + # Keep batch_size as first dimension + outputs_class = torch.stack(outputs_classes, dim=1) + outputs_coord = torch.stack(outputs_coords, dim=1) + + logits = outputs_class[:, -1] + pred_boxes = outputs_coord[:, -1] + + loss, loss_dict, auxiliary_outputs = None, None, None + if labels is not None: + # First: create the matcher + matcher = DetaHungarianMatcher( + class_cost=self.config.class_cost, bbox_cost=self.config.bbox_cost, giou_cost=self.config.giou_cost + ) + # Second: create the criterion + losses = ["labels", "boxes", "cardinality"] + criterion = DetaLoss( + matcher=matcher, + num_classes=self.config.num_labels, + focal_alpha=self.config.focal_alpha, + losses=losses, + num_queries=self.config.num_queries, + ) + criterion.to(logits.device) + # Third: compute the losses, based on outputs and labels + outputs_loss = {} + outputs_loss["logits"] = logits + outputs_loss["pred_boxes"] = pred_boxes + if self.config.auxiliary_loss: + intermediate = outputs.intermediate_hidden_states if return_dict else outputs[4] + outputs_class = self.class_embed(intermediate) + outputs_coord = self.bbox_embed(intermediate).sigmoid() + auxiliary_outputs = self._set_aux_loss(outputs_class, outputs_coord) + outputs_loss["auxiliary_outputs"] = auxiliary_outputs + if self.config.two_stage: + enc_outputs_coord = outputs.enc_outputs_coord_logits.sigmoid() + outputs["enc_outputs"] = {"pred_logits": outputs.enc_outputs_class, "pred_boxes": enc_outputs_coord} + + loss_dict = criterion(outputs_loss, labels) + # Fourth: compute total loss, as a weighted sum of the various losses + weight_dict = {"loss_ce": 1, "loss_bbox": self.config.bbox_loss_coefficient} + weight_dict["loss_giou"] = self.config.giou_loss_coefficient + if self.config.auxiliary_loss: + aux_weight_dict = {} + for i in range(self.config.decoder_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + loss = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) + + if not return_dict: + if auxiliary_outputs is not None: + output = (logits, pred_boxes) + auxiliary_outputs + outputs + else: + output = (logits, pred_boxes) + outputs + tuple_outputs = ((loss, loss_dict) + output) if loss is not None else output + + return tuple_outputs + + dict_outputs = DetaObjectDetectionOutput( + loss=loss, + loss_dict=loss_dict, + logits=logits, + pred_boxes=pred_boxes, + auxiliary_outputs=auxiliary_outputs, + last_hidden_state=outputs.last_hidden_state, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + intermediate_hidden_states=outputs.intermediate_hidden_states, + intermediate_reference_points=outputs.intermediate_reference_points, + init_reference_points=outputs.init_reference_points, + enc_outputs_class=outputs.enc_outputs_class, + enc_outputs_coord_logits=outputs.enc_outputs_coord_logits, + ) + + return dict_outputs + + +# Copied from transformers.models.detr.modeling_detr.dice_loss +def dice_loss(inputs, targets, num_boxes): + """ + Compute the DICE loss, similar to generalized IOU for masks + + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs (0 for the negative class and 1 for the positive + class). + """ + inputs = inputs.sigmoid() + inputs = inputs.flatten(1) + numerator = 2 * (inputs * targets).sum(1) + denominator = inputs.sum(-1) + targets.sum(-1) + loss = 1 - (numerator + 1) / (denominator + 1) + return loss.sum() / num_boxes + + +# Copied from transformers.models.detr.modeling_detr.sigmoid_focal_loss +def sigmoid_focal_loss(inputs, targets, num_boxes, alpha: float = 0.25, gamma: float = 2): + """ + Loss used in RetinaNet for dense detection: https://arxiv.org/abs/1708.02002. + + Args: + inputs (`torch.FloatTensor` of arbitrary shape): + The predictions for each example. + targets (`torch.FloatTensor` with the same shape as `inputs`) + A tensor storing the binary classification label for each element in the `inputs` (0 for the negative class + and 1 for the positive class). + alpha (`float`, *optional*, defaults to `0.25`): + Optional weighting factor in the range (0,1) to balance positive vs. negative examples. + gamma (`int`, *optional*, defaults to `2`): + Exponent of the modulating factor (1 - p_t) to balance easy vs hard examples. + + Returns: + Loss tensor + """ + prob = inputs.sigmoid() + ce_loss = nn.functional.binary_cross_entropy_with_logits(inputs, targets, reduction="none") + # add modulating factor + p_t = prob * targets + (1 - prob) * (1 - targets) + loss = ce_loss * ((1 - p_t) ** gamma) + + if alpha >= 0: + alpha_t = alpha * targets + (1 - alpha) * (1 - targets) + loss = alpha_t * loss + + return loss.mean(1).sum() / num_boxes + + +class DetaLoss(nn.Module): + """ + This class computes the losses for `DetaForObjectDetection`. The process happens in two steps: 1) we compute + hungarian assignment between ground truth boxes and the outputs of the model 2) we supervise each pair of matched + ground-truth / prediction (supervised class and box). + + Args: + matcher (`DetaHungarianMatcher`): + Module able to compute a matching between targets and proposals. + num_classes (`int`): + Number of object categories, omitting the special no-object category. + focal_alpha (`float`): + Alpha parameter in focal loss. + losses (`List[str]`): + List of all the losses to be applied. See `get_loss` for a list of all available losses. + """ + + def __init__( + self, + matcher, + num_classes, + focal_alpha, + losses, + num_queries, + assign_first_stage=False, + assign_second_stage=False, + ): + super().__init__() + self.matcher = matcher + self.num_classes = num_classes + self.focal_alpha = focal_alpha + self.losses = losses + self.assign_first_stage = assign_first_stage + self.assign_second_stage = assign_second_stage + + if self.assign_first_stage: + self.stg1_assigner = DetaStage1Assigner() + if self.assign_second_stage: + self.stg2_assigner = DetaStage2Assigner(num_queries) + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss.loss_labels + def loss_labels(self, outputs, targets, indices, num_boxes): + """ + Classification loss (Binary focal loss) targets dicts must contain the key "class_labels" containing a tensor + of dim [nb_target_boxes] + """ + if "logits" not in outputs: + raise KeyError("No logits were found in the outputs") + source_logits = outputs["logits"] + + idx = self._get_source_permutation_idx(indices) + target_classes_o = torch.cat([t["class_labels"][J] for t, (_, J) in zip(targets, indices)]) + target_classes = torch.full( + source_logits.shape[:2], self.num_classes, dtype=torch.int64, device=source_logits.device + ) + target_classes[idx] = target_classes_o + + target_classes_onehot = torch.zeros( + [source_logits.shape[0], source_logits.shape[1], source_logits.shape[2] + 1], + dtype=source_logits.dtype, + layout=source_logits.layout, + device=source_logits.device, + ) + target_classes_onehot.scatter_(2, target_classes.unsqueeze(-1), 1) + + target_classes_onehot = target_classes_onehot[:, :, :-1] + loss_ce = ( + sigmoid_focal_loss(source_logits, target_classes_onehot, num_boxes, alpha=self.focal_alpha, gamma=2) + * source_logits.shape[1] + ) + losses = {"loss_ce": loss_ce} + + return losses + + @torch.no_grad() + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss.loss_cardinality + def loss_cardinality(self, outputs, targets, indices, num_boxes): + """ + Compute the cardinality error, i.e. the absolute error in the number of predicted non-empty boxes. + + This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients. + """ + logits = outputs["logits"] + device = logits.device + target_lengths = torch.as_tensor([len(v["class_labels"]) for v in targets], device=device) + # Count the number of predictions that are NOT "no-object" (which is the last class) + card_pred = (logits.argmax(-1) != logits.shape[-1] - 1).sum(1) + card_err = nn.functional.l1_loss(card_pred.float(), target_lengths.float()) + losses = {"cardinality_error": card_err} + return losses + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss.loss_boxes + def loss_boxes(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss. + + Targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]. The target boxes + are expected in format (center_x, center_y, w, h), normalized by the image size. + """ + if "pred_boxes" not in outputs: + raise KeyError("No predicted boxes found in outputs") + idx = self._get_source_permutation_idx(indices) + source_boxes = outputs["pred_boxes"][idx] + target_boxes = torch.cat([t["boxes"][i] for t, (_, i) in zip(targets, indices)], dim=0) + + loss_bbox = nn.functional.l1_loss(source_boxes, target_boxes, reduction="none") + + losses = {} + losses["loss_bbox"] = loss_bbox.sum() / num_boxes + + loss_giou = 1 - torch.diag( + generalized_box_iou(center_to_corners_format(source_boxes), center_to_corners_format(target_boxes)) + ) + losses["loss_giou"] = loss_giou.sum() / num_boxes + return losses + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss._get_source_permutation_idx + def _get_source_permutation_idx(self, indices): + # permute predictions following indices + batch_idx = torch.cat([torch.full_like(source, i) for i, (source, _) in enumerate(indices)]) + source_idx = torch.cat([source for (source, _) in indices]) + return batch_idx, source_idx + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss._get_target_permutation_idx + def _get_target_permutation_idx(self, indices): + # permute targets following indices + batch_idx = torch.cat([torch.full_like(target, i) for i, (_, target) in enumerate(indices)]) + target_idx = torch.cat([target for (_, target) in indices]) + return batch_idx, target_idx + + # Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrLoss.get_loss + def get_loss(self, loss, outputs, targets, indices, num_boxes): + loss_map = { + "labels": self.loss_labels, + "cardinality": self.loss_cardinality, + "boxes": self.loss_boxes, + } + if loss not in loss_map: + raise ValueError(f"Loss {loss} not supported") + return loss_map[loss](outputs, targets, indices, num_boxes) + + def forward(self, outputs, targets): + """ + This performs the loss computation. + + Args: + outputs (`dict`, *optional*): + Dictionary of tensors, see the output specification of the model for the format. + targets (`List[dict]`, *optional*): + List of dicts, such that `len(targets) == batch_size`. The expected keys in each dict depends on the + losses applied, see each loss' doc. + """ + outputs_without_aux = {k: v for k, v in outputs.items() if k != "auxiliary_outputs"} + + # Retrieve the matching between the outputs of the last layer and the targets + if self.assign_second_stage: + indices = self.stg2_assigner(outputs_without_aux, targets) + else: + indices = self.matcher(outputs_without_aux, targets) + + # Compute the average number of target boxes accross all nodes, for normalization purposes + num_boxes = sum(len(t["class_labels"]) for t in targets) + num_boxes = torch.as_tensor([num_boxes], dtype=torch.float, device=next(iter(outputs.values())).device) + # (Niels): comment out function below, distributed training to be added + # if is_dist_avail_and_initialized(): + # torch.distributed.all_reduce(num_boxes) + # (Niels) in original implementation, num_boxes is divided by get_world_size() + num_boxes = torch.clamp(num_boxes, min=1).item() + + # Compute all the requested losses + losses = {} + for loss in self.losses: + losses.update(self.get_loss(loss, outputs, targets, indices, num_boxes)) + + # In case of auxiliary losses, we repeat this process with the output of each intermediate layer. + if "auxiliary_outputs" in outputs: + for i, auxiliary_outputs in enumerate(outputs["auxiliary_outputs"]): + if not self.assign_second_stage: + indices = self.matcher(auxiliary_outputs, targets) + for loss in self.losses: + l_dict = self.get_loss(loss, auxiliary_outputs, targets, indices, num_boxes) + l_dict = {k + f"_{i}": v for k, v in l_dict.items()} + losses.update(l_dict) + + if "enc_outputs" in outputs: + enc_outputs = outputs["enc_outputs"] + bin_targets = copy.deepcopy(targets) + for bt in bin_targets: + bt["labels"] = torch.zeros_like(bt["labels"]) + if self.assign_first_stage: + indices = self.stg1_assigner(enc_outputs, bin_targets) + else: + indices = self.matcher(enc_outputs, bin_targets) + for loss in self.losses: + kwargs = {} + if loss == "labels": + # Logging is enabled only for the last layer + kwargs["log"] = False + l_dict = self.get_loss(loss, enc_outputs, bin_targets, indices, num_boxes, **kwargs) + l_dict = {k + "_enc": v for k, v in l_dict.items()} + losses.update(l_dict) + + return losses + + +# Copied from transformers.models.detr.modeling_detr.DetrMLPPredictionHead +class DetaMLPPredictionHead(nn.Module): + """ + Very simple multi-layer perceptron (MLP, also called FFN), used to predict the normalized center coordinates, + height and width of a bounding box w.r.t. an image. + + Copied from https://github.com/facebookresearch/detr/blob/master/models/detr.py + + """ + + def __init__(self, input_dim, hidden_dim, output_dim, num_layers): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = nn.functional.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x + + +# Copied from transformers.models.deformable_detr.modeling_deformable_detr.DeformableDetrHungarianMatcher with DeformableDetr->Deta +class DetaHungarianMatcher(nn.Module): + """ + This class computes an assignment between the targets and the predictions of the network. + + For efficiency reasons, the targets don't include the no_object. Because of this, in general, there are more + predictions than targets. In this case, we do a 1-to-1 matching of the best predictions, while the others are + un-matched (and thus treated as non-objects). + + Args: + class_cost: + The relative weight of the classification error in the matching cost. + bbox_cost: + The relative weight of the L1 error of the bounding box coordinates in the matching cost. + giou_cost: + The relative weight of the giou loss of the bounding box in the matching cost. + """ + + def __init__(self, class_cost: float = 1, bbox_cost: float = 1, giou_cost: float = 1): + super().__init__() + requires_backends(self, ["scipy"]) + + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + if class_cost == 0 and bbox_cost == 0 and giou_cost == 0: + raise ValueError("All costs of the Matcher can't be 0") + + @torch.no_grad() + def forward(self, outputs, targets): + """ + Args: + outputs (`dict`): + A dictionary that contains at least these entries: + * "logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits + * "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates. + targets (`List[dict]`): + A list of targets (len(targets) = batch_size), where each target is a dict containing: + * "class_labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of + ground-truth + objects in the target) containing the class labels + * "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates. + + Returns: + `List[Tuple]`: A list of size `batch_size`, containing tuples of (index_i, index_j) where: + - index_i is the indices of the selected predictions (in order) + - index_j is the indices of the corresponding selected targets (in order) + For each batch element, it holds: len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + batch_size, num_queries = outputs["logits"].shape[:2] + + # We flatten to compute the cost matrices in a batch + out_prob = outputs["logits"].flatten(0, 1).sigmoid() # [batch_size * num_queries, num_classes] + out_bbox = outputs["pred_boxes"].flatten(0, 1) # [batch_size * num_queries, 4] + + # Also concat the target labels and boxes + target_ids = torch.cat([v["class_labels"] for v in targets]) + target_bbox = torch.cat([v["boxes"] for v in targets]) + + # Compute the classification cost. + alpha = 0.25 + gamma = 2.0 + neg_cost_class = (1 - alpha) * (out_prob**gamma) * (-(1 - out_prob + 1e-8).log()) + pos_cost_class = alpha * ((1 - out_prob) ** gamma) * (-(out_prob + 1e-8).log()) + class_cost = pos_cost_class[:, target_ids] - neg_cost_class[:, target_ids] + + # Compute the L1 cost between boxes + bbox_cost = torch.cdist(out_bbox, target_bbox, p=1) + + # Compute the giou cost between boxes + giou_cost = -generalized_box_iou(center_to_corners_format(out_bbox), center_to_corners_format(target_bbox)) + + # Final cost matrix + cost_matrix = self.bbox_cost * bbox_cost + self.class_cost * class_cost + self.giou_cost * giou_cost + cost_matrix = cost_matrix.view(batch_size, num_queries, -1).cpu() + + sizes = [len(v["boxes"]) for v in targets] + indices = [linear_sum_assignment(c[i]) for i, c in enumerate(cost_matrix.split(sizes, -1))] + return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices] + + +# Copied from transformers.models.detr.modeling_detr._upcast +def _upcast(t: Tensor) -> Tensor: + # Protects from numerical overflows in multiplications by upcasting to the equivalent higher type + if t.is_floating_point(): + return t if t.dtype in (torch.float32, torch.float64) else t.float() + else: + return t if t.dtype in (torch.int32, torch.int64) else t.int() + + +# Copied from transformers.models.detr.modeling_detr.box_area +def box_area(boxes: Tensor) -> Tensor: + """ + Computes the area of a set of bounding boxes, which are specified by its (x1, y1, x2, y2) coordinates. + + Args: + boxes (`torch.FloatTensor` of shape `(number_of_boxes, 4)`): + Boxes for which the area will be computed. They are expected to be in (x1, y1, x2, y2) format with `0 <= x1 + < x2` and `0 <= y1 < y2`. + + Returns: + `torch.FloatTensor`: a tensor containing the area for each box. + """ + boxes = _upcast(boxes) + return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) + + +# Copied from transformers.models.detr.modeling_detr.box_iou +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + left_top = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2] + right_bottom = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2] + + width_height = (right_bottom - left_top).clamp(min=0) # [N,M,2] + inter = width_height[:, :, 0] * width_height[:, :, 1] # [N,M] + + union = area1[:, None] + area2 - inter + + iou = inter / union + return iou, union + + +# Copied from transformers.models.detr.modeling_detr.generalized_box_iou +def generalized_box_iou(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/. The boxes should be in [x0, y0, x1, y1] (corner) format. + + Returns: + `torch.FloatTensor`: a [N, M] pairwise matrix, where N = len(boxes1) and M = len(boxes2) + """ + # degenerate boxes gives inf / nan results + # so do an early check + if not (boxes1[:, 2:] >= boxes1[:, :2]).all(): + raise ValueError(f"boxes1 must be in [x0, y0, x1, y1] (corner) format, but got {boxes1}") + if not (boxes2[:, 2:] >= boxes2[:, :2]).all(): + raise ValueError(f"boxes2 must be in [x0, y0, x1, y1] (corner) format, but got {boxes2}") + iou, union = box_iou(boxes1, boxes2) + + top_left = torch.min(boxes1[:, None, :2], boxes2[:, :2]) + bottom_right = torch.max(boxes1[:, None, 2:], boxes2[:, 2:]) + + width_height = (bottom_right - top_left).clamp(min=0) # [N,M,2] + area = width_height[:, :, 0] * width_height[:, :, 1] + + return iou - (area - union) / area + + +# from https://github.com/facebookresearch/detectron2/blob/cbbc1ce26473cb2a5cc8f58e8ada9ae14cb41052/detectron2/layers/wrappers.py#L100 +def nonzero_tuple(x): + """ + A 'as_tuple=True' version of torch.nonzero to support torchscript. because of + https://github.com/pytorch/pytorch/issues/38718 + """ + if torch.jit.is_scripting(): + if x.dim() == 0: + return x.unsqueeze(0).nonzero().unbind(1) + return x.nonzero().unbind(1) + else: + return x.nonzero(as_tuple=True) + + +# from https://github.com/facebookresearch/detectron2/blob/9921a2caa585d4fa66c4b534b6fab6e74d89b582/detectron2/modeling/matcher.py#L9 +class DetaMatcher(object): + """ + This class assigns to each predicted "element" (e.g., a box) a ground-truth element. Each predicted element will + have exactly zero or one matches; each ground-truth element may be matched to zero or more predicted elements. + + The matching is determined by the MxN match_quality_matrix, that characterizes how well each (ground-truth, + prediction)-pair match each other. For example, if the elements are boxes, this matrix may contain box + intersection-over-union overlap values. + + The matcher returns (a) a vector of length N containing the index of the ground-truth element m in [0, M) that + matches to prediction n in [0, N). (b) a vector of length N containing the labels for each prediction. + """ + + def __init__(self, thresholds: List[float], labels: List[int], allow_low_quality_matches: bool = False): + """ + Args: + thresholds (`list[float]`): + A list of thresholds used to stratify predictions into levels. + labels (`list[int`): + A list of values to label predictions belonging at each level. A label can be one of {-1, 0, 1} + signifying {ignore, negative class, positive class}, respectively. + allow_low_quality_matches (`bool`, *optional*, defaults to `False`): + If `True`, produce additional matches for predictions with maximum match quality lower than + high_threshold. See `set_low_quality_matches_` for more details. + + For example, + thresholds = [0.3, 0.5] labels = [0, -1, 1] All predictions with iou < 0.3 will be marked with 0 and + thus will be considered as false positives while training. All predictions with 0.3 <= iou < 0.5 will + be marked with -1 and thus will be ignored. All predictions with 0.5 <= iou will be marked with 1 and + thus will be considered as true positives. + """ + # Add -inf and +inf to first and last position in thresholds + thresholds = thresholds[:] + if thresholds[0] < 0: + raise ValueError("Thresholds should be positive") + thresholds.insert(0, -float("inf")) + thresholds.append(float("inf")) + # Currently torchscript does not support all + generator + if not all([low <= high for (low, high) in zip(thresholds[:-1], thresholds[1:])]): + raise ValueError("Thresholds should be sorted.") + if not all([l in [-1, 0, 1] for l in labels]): + raise ValueError("All labels should be either -1, 0 or 1") + if len(labels) != len(thresholds) - 1: + raise ValueError("Number of labels should be equal to number of thresholds - 1") + self.thresholds = thresholds + self.labels = labels + self.allow_low_quality_matches = allow_low_quality_matches + + def __call__(self, match_quality_matrix): + """ + Args: + match_quality_matrix (Tensor[float]): an MxN tensor, containing the + pairwise quality between M ground-truth elements and N predicted elements. All elements must be >= 0 + (due to the us of `torch.nonzero` for selecting indices in `set_low_quality_matches_`). + + Returns: + matches (Tensor[int64]): a vector of length N, where matches[i] is a matched + ground-truth index in [0, M) + match_labels (Tensor[int8]): a vector of length N, where pred_labels[i] indicates + whether a prediction is a true or false positive or ignored + """ + assert match_quality_matrix.dim() == 2 + if match_quality_matrix.numel() == 0: + default_matches = match_quality_matrix.new_full((match_quality_matrix.size(1),), 0, dtype=torch.int64) + # When no gt boxes exist, we define IOU = 0 and therefore set labels + # to `self.labels[0]`, which usually defaults to background class 0 + # To choose to ignore instead, can make labels=[-1,0,-1,1] + set appropriate thresholds + default_match_labels = match_quality_matrix.new_full( + (match_quality_matrix.size(1),), self.labels[0], dtype=torch.int8 + ) + return default_matches, default_match_labels + + assert torch.all(match_quality_matrix >= 0) + + # match_quality_matrix is M (gt) x N (predicted) + # Max over gt elements (dim 0) to find best gt candidate for each prediction + matched_vals, matches = match_quality_matrix.max(dim=0) + + match_labels = matches.new_full(matches.size(), 1, dtype=torch.int8) + + for l, low, high in zip(self.labels, self.thresholds[:-1], self.thresholds[1:]): + low_high = (matched_vals >= low) & (matched_vals < high) + match_labels[low_high] = l + + if self.allow_low_quality_matches: + self.set_low_quality_matches_(match_labels, match_quality_matrix) + + return matches, match_labels + + def set_low_quality_matches_(self, match_labels, match_quality_matrix): + """ + Produce additional matches for predictions that have only low-quality matches. Specifically, for each + ground-truth G find the set of predictions that have maximum overlap with it (including ties); for each + prediction in that set, if it is unmatched, then match it to the ground-truth G. + + This function implements the RPN assignment case (i) in Sec. 3.1.2 of :paper:`Faster R-CNN`. + """ + # For each gt, find the prediction with which it has highest quality + highest_quality_foreach_gt, _ = match_quality_matrix.max(dim=1) + # Find the highest quality match available, even if it is low, including ties. + # Note that the matches qualities must be positive due to the use of + # `torch.nonzero`. + _, pred_inds_with_highest_quality = nonzero_tuple(match_quality_matrix == highest_quality_foreach_gt[:, None]) + # If an anchor was labeled positive only due to a low-quality match + # with gt_A, but it has larger overlap with gt_B, it's matched index will still be gt_B. + # This follows the implementation in Detectron, and is found to have no significant impact. + match_labels[pred_inds_with_highest_quality] = 1 + + +# from https://github.com/facebookresearch/detectron2/blob/cbbc1ce26473cb2a5cc8f58e8ada9ae14cb41052/detectron2/modeling/sampling.py#L9 +def subsample_labels(labels: torch.Tensor, num_samples: int, positive_fraction: float, bg_label: int): + """ + Return `num_samples` (or fewer, if not enough found) random samples from `labels` which is a mixture of positives & + negatives. It will try to return as many positives as possible without exceeding `positive_fraction * num_samples`, + and then try to fill the remaining slots with negatives. + + Args: + labels (Tensor): (N, ) label vector with values: + * -1: ignore + * bg_label: background ("negative") class + * otherwise: one or more foreground ("positive") classes + num_samples (int): The total number of labels with value >= 0 to return. + Values that are not sampled will be filled with -1 (ignore). + positive_fraction (float): The number of subsampled labels with values > 0 + is `min(num_positives, int(positive_fraction * num_samples))`. The number of negatives sampled is + `min(num_negatives, num_samples - num_positives_sampled)`. In order words, if there are not enough + positives, the sample is filled with negatives. If there are also not enough negatives, then as many + elements are sampled as is possible. + bg_label (int): label index of background ("negative") class. + + Returns: + pos_idx, neg_idx (Tensor): + 1D vector of indices. The total length of both is `num_samples` or fewer. + """ + positive = nonzero_tuple((labels != -1) & (labels != bg_label))[0] + negative = nonzero_tuple(labels == bg_label)[0] + + num_pos = int(num_samples * positive_fraction) + # protect against not enough positive examples + num_pos = min(positive.numel(), num_pos) + num_neg = num_samples - num_pos + # protect against not enough negative examples + num_neg = min(negative.numel(), num_neg) + + # randomly select positive and negative examples + perm1 = torch.randperm(positive.numel(), device=positive.device)[:num_pos] + perm2 = torch.randperm(negative.numel(), device=negative.device)[:num_neg] + + pos_idx = positive[perm1] + neg_idx = negative[perm2] + return pos_idx, neg_idx + + +def sample_topk_per_gt(pr_inds, gt_inds, iou, k): + if len(gt_inds) == 0: + return pr_inds, gt_inds + # find topk matches for each gt + gt_inds2, counts = gt_inds.unique(return_counts=True) + scores, pr_inds2 = iou[gt_inds2].topk(k, dim=1) + gt_inds2 = gt_inds2[:, None].repeat(1, k) + + # filter to as many matches that gt has + pr_inds3 = torch.cat([pr[:c] for c, pr in zip(counts, pr_inds2)]) + gt_inds3 = torch.cat([gt[:c] for c, gt in zip(counts, gt_inds2)]) + return pr_inds3, gt_inds3 + + +# modified from https://github.com/facebookresearch/detectron2/blob/cbbc1ce26473cb2a5cc8f58e8ada9ae14cb41052/detectron2/modeling/roi_heads/roi_heads.py#L123 +class DetaStage2Assigner(nn.Module): + def __init__(self, num_queries, max_k=4): + super().__init__() + self.positive_fraction = 0.25 + self.bg_label = 400 # number > 91 to filter out later + self.batch_size_per_image = num_queries + self.proposal_matcher = DetaMatcher(thresholds=[0.6], labels=[0, 1], allow_low_quality_matches=True) + self.k = max_k + + def _sample_proposals(self, matched_idxs: torch.Tensor, matched_labels: torch.Tensor, gt_classes: torch.Tensor): + """ + Based on the matching between N proposals and M groundtruth, sample the proposals and set their classification + labels. + + Args: + matched_idxs (Tensor): a vector of length N, each is the best-matched + gt index in [0, M) for each proposal. + matched_labels (Tensor): a vector of length N, the matcher's label + (one of cfg.MODEL.ROI_HEADS.IOU_LABELS) for each proposal. + gt_classes (Tensor): a vector of length M. + + Returns: + Tensor: a vector of indices of sampled proposals. Each is in [0, N). Tensor: a vector of the same length, + the classification label for + each sampled proposal. Each sample is labeled as either a category in [0, num_classes) or the + background (num_classes). + """ + has_gt = gt_classes.numel() > 0 + # Get the corresponding GT for each proposal + if has_gt: + gt_classes = gt_classes[matched_idxs] + # Label unmatched proposals (0 label from matcher) as background (label=num_classes) + gt_classes[matched_labels == 0] = self.bg_label + # Label ignore proposals (-1 label) + gt_classes[matched_labels == -1] = -1 + else: + gt_classes = torch.zeros_like(matched_idxs) + self.bg_label + + sampled_fg_idxs, sampled_bg_idxs = subsample_labels( + gt_classes, self.batch_size_per_image, self.positive_fraction, self.bg_label + ) + + sampled_idxs = torch.cat([sampled_fg_idxs, sampled_bg_idxs], dim=0) + return sampled_idxs, gt_classes[sampled_idxs] + + def forward(self, outputs, targets, return_cost_matrix=False): + # COCO categories are from 1 to 90. They set num_classes=91 and apply sigmoid. + + bs = len(targets) + indices = [] + ious = [] + for b in range(bs): + iou, _ = box_iou( + center_to_corners_format(targets[b]["boxes"]), + center_to_corners_format(outputs["init_reference"][b].detach()), + ) + matched_idxs, matched_labels = self.proposal_matcher( + iou + ) # proposal_id -> highest_iou_gt_id, proposal_id -> [1 if iou > 0.6, 0 ow] + ( + sampled_idxs, + sampled_gt_classes, + ) = self._sample_proposals( # list of sampled proposal_ids, sampled_id -> [0, num_classes)+[bg_label] + matched_idxs, matched_labels, targets[b]["labels"] + ) + pos_pr_inds = sampled_idxs[sampled_gt_classes != self.bg_label] + pos_gt_inds = matched_idxs[pos_pr_inds] + pos_pr_inds, pos_gt_inds = self.postprocess_indices(pos_pr_inds, pos_gt_inds, iou) + indices.append((pos_pr_inds, pos_gt_inds)) + ious.append(iou) + if return_cost_matrix: + return indices, ious + return indices + + def postprocess_indices(self, pr_inds, gt_inds, iou): + return sample_topk_per_gt(pr_inds, gt_inds, iou, self.k) + + +# modified from https://github.com/facebookresearch/detectron2/blob/cbbc1ce26473cb2a5cc8f58e8ada9ae14cb41052/detectron2/modeling/proposal_generator/rpn.py#L181 +class DetaStage1Assigner(nn.Module): + def __init__(self, t_low=0.3, t_high=0.7, max_k=4): + super().__init__() + self.positive_fraction = 0.5 + self.batch_size_per_image = 256 + self.k = max_k + self.t_low = t_low + self.t_high = t_high + self.anchor_matcher = DetaMatcher( + thresholds=[t_low, t_high], labels=[0, -1, 1], allow_low_quality_matches=True + ) + + def _subsample_labels(self, label): + """ + Randomly sample a subset of positive and negative examples, and overwrite the label vector to the ignore value + (-1) for all elements that are not included in the sample. + + Args: + labels (Tensor): a vector of -1, 0, 1. Will be modified in-place and returned. + """ + pos_idx, neg_idx = subsample_labels(label, self.batch_size_per_image, self.positive_fraction, 0) + # Fill with the ignore label (-1), then set positive and negative labels + label.fill_(-1) + label.scatter_(0, pos_idx, 1) + label.scatter_(0, neg_idx, 0) + return label + + def forward(self, outputs, targets): + bs = len(targets) + indices = [] + for b in range(bs): + anchors = outputs["anchors"][b] + if len(targets[b]["boxes"]) == 0: + indices.append( + ( + torch.tensor([], dtype=torch.long, device=anchors.device), + torch.tensor([], dtype=torch.long, device=anchors.device), + ) + ) + continue + iou, _ = box_iou( + center_to_corners_format(targets[b]["boxes"]), + center_to_corners_format(anchors), + ) + matched_idxs, matched_labels = self.anchor_matcher( + iou + ) # proposal_id -> highest_iou_gt_id, proposal_id -> [1 if iou > 0.7, 0 if iou < 0.3, -1 ow] + matched_labels = self._subsample_labels(matched_labels) + + all_pr_inds = torch.arange(len(anchors)) + pos_pr_inds = all_pr_inds[matched_labels == 1] + pos_gt_inds = matched_idxs[pos_pr_inds] + pos_pr_inds, pos_gt_inds = self.postprocess_indices(pos_pr_inds, pos_gt_inds, iou) + pos_pr_inds, pos_gt_inds = pos_pr_inds.to(anchors.device), pos_gt_inds.to(anchors.device) + indices.append((pos_pr_inds, pos_gt_inds)) + return indices + + def postprocess_indices(self, pr_inds, gt_inds, iou): + return sample_topk_per_gt(pr_inds, gt_inds, iou, self.k) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9cbaca9a54581fbe51cbf4bd88adac1660297152 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/__init__.py @@ -0,0 +1,75 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available + + +_import_structure = {"configuration_detr": ["DETR_PRETRAINED_CONFIG_ARCHIVE_MAP", "DetrConfig", "DetrOnnxConfig"]} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_detr"] = ["DetrFeatureExtractor"] + _import_structure["image_processing_detr"] = ["DetrImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_detr"] = [ + "DETR_PRETRAINED_MODEL_ARCHIVE_LIST", + "DetrForObjectDetection", + "DetrForSegmentation", + "DetrModel", + "DetrPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_detr import DETR_PRETRAINED_CONFIG_ARCHIVE_MAP, DetrConfig, DetrOnnxConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_detr import DetrFeatureExtractor + from .image_processing_detr import DetrImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_detr import ( + DETR_PRETRAINED_MODEL_ARCHIVE_LIST, + DetrForObjectDetection, + DetrForSegmentation, + DetrModel, + DetrPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/configuration_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/configuration_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..955b71de1ec57b4cf03e83df3d488b003aedc2ab --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/configuration_detr.py @@ -0,0 +1,281 @@ +# coding=utf-8 +# Copyright 2021 Facebook AI Research and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DETR model configuration""" + +import copy +from collections import OrderedDict +from typing import Dict, Mapping + +from packaging import version + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging +from ..auto import CONFIG_MAPPING + + +logger = logging.get_logger(__name__) + +DETR_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/detr-resnet-50": "https://huggingface.co/facebook/detr-resnet-50/resolve/main/config.json", + # See all DETR models at https://huggingface.co/models?filter=detr +} + + +class DetrConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DetrModel`]. It is used to instantiate a DETR + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the DETR + [facebook/detr-resnet-50](https://huggingface.co/facebook/detr-resnet-50) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + use_timm_backbone (`bool`, *optional*, defaults to `True`): + Whether or not to use the `timm` library for the backbone. If set to `False`, will use the [`AutoBackbone`] + API. + backbone_config (`PretrainedConfig` or `dict`, *optional*): + The configuration of the backbone model. Only used in case `use_timm_backbone` is set to `False` in which + case it will default to `ResNetConfig()`. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + num_queries (`int`, *optional*, defaults to 100): + Number of object queries, i.e. detection slots. This is the maximal number of objects [`DetrModel`] can + detect in a single image. For COCO, we recommend 100 queries. + d_model (`int`, *optional*, defaults to 256): + Dimension of the layers. + encoder_layers (`int`, *optional*, defaults to 6): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 6): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer decoder. + decoder_ffn_dim (`int`, *optional*, defaults to 2048): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 2048): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + activation_function (`str` or `function`, *optional*, defaults to `"relu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + init_xavier_std (`float`, *optional*, defaults to 1): + The scaling factor used for the Xavier initialization gain in the HM Attention map module. + encoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + decoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the decoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + auxiliary_loss (`bool`, *optional*, defaults to `False`): + Whether auxiliary decoding losses (loss at each decoder layer) are to be used. + position_embedding_type (`str`, *optional*, defaults to `"sine"`): + Type of position embeddings to be used on top of the image features. One of `"sine"` or `"learned"`. + backbone (`str`, *optional*, defaults to `"resnet50"`): + Name of convolutional backbone to use in case `use_timm_backbone` = `True`. Supports any convolutional + backbone from the timm package. For a list of all available models, see [this + page](https://rwightman.github.io/pytorch-image-models/#load-a-pretrained-model). + use_pretrained_backbone (`bool`, *optional*, defaults to `True`): + Whether to use pretrained weights for the backbone. Only supported when `use_timm_backbone` = `True`. + dilation (`bool`, *optional*, defaults to `False`): + Whether to replace stride with dilation in the last convolutional block (DC5). Only supported when + `use_timm_backbone` = `True`. + class_cost (`float`, *optional*, defaults to 1): + Relative weight of the classification error in the Hungarian matching cost. + bbox_cost (`float`, *optional*, defaults to 5): + Relative weight of the L1 error of the bounding box coordinates in the Hungarian matching cost. + giou_cost (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss of the bounding box in the Hungarian matching cost. + mask_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the Focal loss in the panoptic segmentation loss. + dice_loss_coefficient (`float`, *optional*, defaults to 1): + Relative weight of the DICE/F-1 loss in the panoptic segmentation loss. + bbox_loss_coefficient (`float`, *optional*, defaults to 5): + Relative weight of the L1 bounding box loss in the object detection loss. + giou_loss_coefficient (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss in the object detection loss. + eos_coefficient (`float`, *optional*, defaults to 0.1): + Relative classification weight of the 'no-object' class in the object detection loss. + + Examples: + + ```python + >>> from transformers import DetrConfig, DetrModel + + >>> # Initializing a DETR facebook/detr-resnet-50 style configuration + >>> configuration = DetrConfig() + + >>> # Initializing a model (with random weights) from the facebook/detr-resnet-50 style configuration + >>> model = DetrModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "detr" + keys_to_ignore_at_inference = ["past_key_values"] + attribute_map = { + "hidden_size": "d_model", + "num_attention_heads": "encoder_attention_heads", + } + + def __init__( + self, + use_timm_backbone=True, + backbone_config=None, + num_channels=3, + num_queries=100, + encoder_layers=6, + encoder_ffn_dim=2048, + encoder_attention_heads=8, + decoder_layers=6, + decoder_ffn_dim=2048, + decoder_attention_heads=8, + encoder_layerdrop=0.0, + decoder_layerdrop=0.0, + is_encoder_decoder=True, + activation_function="relu", + d_model=256, + dropout=0.1, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + init_xavier_std=1.0, + auxiliary_loss=False, + position_embedding_type="sine", + backbone="resnet50", + use_pretrained_backbone=True, + dilation=False, + class_cost=1, + bbox_cost=5, + giou_cost=2, + mask_loss_coefficient=1, + dice_loss_coefficient=1, + bbox_loss_coefficient=5, + giou_loss_coefficient=2, + eos_coefficient=0.1, + **kwargs, + ): + if backbone_config is not None and use_timm_backbone: + raise ValueError("You can't specify both `backbone_config` and `use_timm_backbone`.") + + if not use_timm_backbone: + if backbone_config is None: + logger.info("`backbone_config` is `None`. Initializing the config with the default `ResNet` backbone.") + backbone_config = CONFIG_MAPPING["resnet"](out_features=["stage4"]) + elif isinstance(backbone_config, dict): + backbone_model_type = backbone_config.get("model_type") + config_class = CONFIG_MAPPING[backbone_model_type] + backbone_config = config_class.from_dict(backbone_config) + # set timm attributes to None + dilation, backbone, use_pretrained_backbone = None, None, None + + self.use_timm_backbone = use_timm_backbone + self.backbone_config = backbone_config + self.num_channels = num_channels + self.num_queries = num_queries + self.d_model = d_model + self.encoder_ffn_dim = encoder_ffn_dim + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.init_xavier_std = init_xavier_std + self.encoder_layerdrop = encoder_layerdrop + self.decoder_layerdrop = decoder_layerdrop + self.num_hidden_layers = encoder_layers + self.auxiliary_loss = auxiliary_loss + self.position_embedding_type = position_embedding_type + self.backbone = backbone + self.use_pretrained_backbone = use_pretrained_backbone + self.dilation = dilation + # Hungarian matcher + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + # Loss coefficients + self.mask_loss_coefficient = mask_loss_coefficient + self.dice_loss_coefficient = dice_loss_coefficient + self.bbox_loss_coefficient = bbox_loss_coefficient + self.giou_loss_coefficient = giou_loss_coefficient + self.eos_coefficient = eos_coefficient + super().__init__(is_encoder_decoder=is_encoder_decoder, **kwargs) + + @property + def num_attention_heads(self) -> int: + return self.encoder_attention_heads + + @property + def hidden_size(self) -> int: + return self.d_model + + @classmethod + def from_backbone_config(cls, backbone_config: PretrainedConfig, **kwargs): + """Instantiate a [`DetrConfig`] (or a derived class) from a pre-trained backbone model configuration. + + Args: + backbone_config ([`PretrainedConfig`]): + The backbone configuration. + Returns: + [`DetrConfig`]: An instance of a configuration object + """ + return cls(backbone_config=backbone_config, **kwargs) + + def to_dict(self) -> Dict[str, any]: + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + if output["backbone_config"] is not None: + output["backbone_config"] = self.backbone_config.to_dict() + output["model_type"] = self.__class__.model_type + return output + + +class DetrOnnxConfig(OnnxConfig): + torch_onnx_minimum_version = version.parse("1.11") + + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + return OrderedDict( + [ + ("pixel_values", {0: "batch", 1: "num_channels", 2: "height", 3: "width"}), + ("pixel_mask", {0: "batch"}), + ] + ) + + @property + def atol_for_validation(self) -> float: + return 1e-5 + + @property + def default_onnx_opset(self) -> int: + return 12 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..b6dcc617da7b62e5bb8d5513400b878d989819c5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,278 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DETR checkpoints with timm backbone.""" + + +import argparse +import json +from collections import OrderedDict +from pathlib import Path + +import requests +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import DetrConfig, DetrFeatureExtractor, DetrForObjectDetection, DetrForSegmentation +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +# here we list all keys to be renamed (original name on the left, our name on the right) +rename_keys = [] +for i in range(6): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append( + (f"transformer.encoder.layers.{i}.self_attn.out_proj.weight", f"encoder.layers.{i}.self_attn.out_proj.weight") + ) + rename_keys.append( + (f"transformer.encoder.layers.{i}.self_attn.out_proj.bias", f"encoder.layers.{i}.self_attn.out_proj.bias") + ) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.weight", f"encoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.bias", f"encoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.weight", f"encoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.bias", f"encoder.layers.{i}.fc2.bias")) + rename_keys.append( + (f"transformer.encoder.layers.{i}.norm1.weight", f"encoder.layers.{i}.self_attn_layer_norm.weight") + ) + rename_keys.append((f"transformer.encoder.layers.{i}.norm1.bias", f"encoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.weight", f"encoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.bias", f"encoder.layers.{i}.final_layer_norm.bias")) + # decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms + rename_keys.append( + (f"transformer.decoder.layers.{i}.self_attn.out_proj.weight", f"decoder.layers.{i}.self_attn.out_proj.weight") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.self_attn.out_proj.bias", f"decoder.layers.{i}.self_attn.out_proj.bias") + ) + rename_keys.append( + ( + f"transformer.decoder.layers.{i}.multihead_attn.out_proj.weight", + f"decoder.layers.{i}.encoder_attn.out_proj.weight", + ) + ) + rename_keys.append( + ( + f"transformer.decoder.layers.{i}.multihead_attn.out_proj.bias", + f"decoder.layers.{i}.encoder_attn.out_proj.bias", + ) + ) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.weight", f"decoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.bias", f"decoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.weight", f"decoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.bias", f"decoder.layers.{i}.fc2.bias")) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm1.weight", f"decoder.layers.{i}.self_attn_layer_norm.weight") + ) + rename_keys.append((f"transformer.decoder.layers.{i}.norm1.bias", f"decoder.layers.{i}.self_attn_layer_norm.bias")) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm2.weight", f"decoder.layers.{i}.encoder_attn_layer_norm.weight") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm2.bias", f"decoder.layers.{i}.encoder_attn_layer_norm.bias") + ) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.weight", f"decoder.layers.{i}.final_layer_norm.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.bias", f"decoder.layers.{i}.final_layer_norm.bias")) + +# convolutional projection + query embeddings + layernorm of decoder + class and bounding box heads +rename_keys.extend( + [ + ("input_proj.weight", "input_projection.weight"), + ("input_proj.bias", "input_projection.bias"), + ("query_embed.weight", "query_position_embeddings.weight"), + ("transformer.decoder.norm.weight", "decoder.layernorm.weight"), + ("transformer.decoder.norm.bias", "decoder.layernorm.bias"), + ("class_embed.weight", "class_labels_classifier.weight"), + ("class_embed.bias", "class_labels_classifier.bias"), + ("bbox_embed.layers.0.weight", "bbox_predictor.layers.0.weight"), + ("bbox_embed.layers.0.bias", "bbox_predictor.layers.0.bias"), + ("bbox_embed.layers.1.weight", "bbox_predictor.layers.1.weight"), + ("bbox_embed.layers.1.bias", "bbox_predictor.layers.1.bias"), + ("bbox_embed.layers.2.weight", "bbox_predictor.layers.2.weight"), + ("bbox_embed.layers.2.bias", "bbox_predictor.layers.2.bias"), + ] +) + + +def rename_key(state_dict, old, new): + val = state_dict.pop(old) + state_dict[new] = val + + +def rename_backbone_keys(state_dict): + new_state_dict = OrderedDict() + for key, value in state_dict.items(): + if "backbone.0.body" in key: + new_key = key.replace("backbone.0.body", "backbone.conv_encoder.model") + new_state_dict[new_key] = value + else: + new_state_dict[key] = value + + return new_state_dict + + +def read_in_q_k_v(state_dict, is_panoptic=False): + prefix = "" + if is_panoptic: + prefix = "detr." + + # first: transformer encoder + for i in range(6): + # read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"encoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :] + state_dict[f"encoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256] + state_dict[f"encoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :] + state_dict[f"encoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512] + state_dict[f"encoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :] + state_dict[f"encoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:] + # next: transformer decoder (which is a bit more complex because it also includes cross-attention) + for i in range(6): + # read in weights + bias of input projection layer of self-attention + in_proj_weight = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"decoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :] + state_dict[f"decoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:] + # read in weights + bias of input projection layer of cross-attention + in_proj_weight_cross_attn = state_dict.pop( + f"{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_weight" + ) + in_proj_bias_cross_attn = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_bias") + # next, add query, keys and values (in that order) of cross-attention to the state dict + state_dict[f"decoder.layers.{i}.encoder_attn.q_proj.weight"] = in_proj_weight_cross_attn[:256, :] + state_dict[f"decoder.layers.{i}.encoder_attn.q_proj.bias"] = in_proj_bias_cross_attn[:256] + state_dict[f"decoder.layers.{i}.encoder_attn.k_proj.weight"] = in_proj_weight_cross_attn[256:512, :] + state_dict[f"decoder.layers.{i}.encoder_attn.k_proj.bias"] = in_proj_bias_cross_attn[256:512] + state_dict[f"decoder.layers.{i}.encoder_attn.v_proj.weight"] = in_proj_weight_cross_attn[-256:, :] + state_dict[f"decoder.layers.{i}.encoder_attn.v_proj.bias"] = in_proj_bias_cross_attn[-256:] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + + return im + + +@torch.no_grad() +def convert_detr_checkpoint(model_name, pytorch_dump_folder_path): + """ + Copy/paste/tweak model's weights to our DETR structure. + """ + + # load default config + config = DetrConfig() + # set backbone and dilation attributes + if "resnet101" in model_name: + config.backbone = "resnet101" + if "dc5" in model_name: + config.dilation = True + is_panoptic = "panoptic" in model_name + if is_panoptic: + config.num_labels = 250 + else: + config.num_labels = 91 + repo_id = "huggingface/label-files" + filename = "coco-detection-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + # load feature extractor + format = "coco_panoptic" if is_panoptic else "coco_detection" + feature_extractor = DetrFeatureExtractor(format=format) + + # prepare image + img = prepare_img() + encoding = feature_extractor(images=img, return_tensors="pt") + pixel_values = encoding["pixel_values"] + + logger.info(f"Converting model {model_name}...") + + # load original model from torch hub + detr = torch.hub.load("facebookresearch/detr", model_name, pretrained=True).eval() + state_dict = detr.state_dict() + # rename keys + for src, dest in rename_keys: + if is_panoptic: + src = "detr." + src + rename_key(state_dict, src, dest) + state_dict = rename_backbone_keys(state_dict) + # query, key and value matrices need special treatment + read_in_q_k_v(state_dict, is_panoptic=is_panoptic) + # important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them + prefix = "detr.model." if is_panoptic else "model." + for key in state_dict.copy().keys(): + if is_panoptic: + if ( + key.startswith("detr") + and not key.startswith("class_labels_classifier") + and not key.startswith("bbox_predictor") + ): + val = state_dict.pop(key) + state_dict["detr.model" + key[4:]] = val + elif "class_labels_classifier" in key or "bbox_predictor" in key: + val = state_dict.pop(key) + state_dict["detr." + key] = val + elif key.startswith("bbox_attention") or key.startswith("mask_head"): + continue + else: + val = state_dict.pop(key) + state_dict[prefix + key] = val + else: + if not key.startswith("class_labels_classifier") and not key.startswith("bbox_predictor"): + val = state_dict.pop(key) + state_dict[prefix + key] = val + # finally, create HuggingFace model and load state dict + model = DetrForSegmentation(config) if is_panoptic else DetrForObjectDetection(config) + model.load_state_dict(state_dict) + model.eval() + # verify our conversion + original_outputs = detr(pixel_values) + outputs = model(pixel_values) + assert torch.allclose(outputs.logits, original_outputs["pred_logits"], atol=1e-4) + assert torch.allclose(outputs.pred_boxes, original_outputs["pred_boxes"], atol=1e-4) + if is_panoptic: + assert torch.allclose(outputs.pred_masks, original_outputs["pred_masks"], atol=1e-4) + + # Save model and feature extractor + logger.info(f"Saving PyTorch model and feature extractor to {pytorch_dump_folder_path}...") + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + model.save_pretrained(pytorch_dump_folder_path) + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--model_name", default="detr_resnet50", type=str, help="Name of the DETR model you'd like to convert." + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model." + ) + args = parser.parse_args() + convert_detr_checkpoint(args.model_name, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..a52e592b945d798ed01c457e3864252302eb33a3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/convert_detr_to_pytorch.py @@ -0,0 +1,386 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DETR checkpoints with native (Transformers) backbone.""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import DetrConfig, DetrForObjectDetection, DetrForSegmentation, DetrImageProcessor, ResNetConfig +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_detr_config(model_name): + # initialize config + if "resnet-50" in model_name: + backbone_config = ResNetConfig.from_pretrained("microsoft/resnet-50") + elif "resnet-101" in model_name: + backbone_config = ResNetConfig.from_pretrained("microsoft/resnet-101") + else: + raise ValueError("Model name should include either resnet50 or resnet101") + + config = DetrConfig(use_timm_backbone=False, backbone_config=backbone_config) + + # set label attributes + is_panoptic = "panoptic" in model_name + if is_panoptic: + config.num_labels = 250 + else: + config.num_labels = 91 + repo_id = "huggingface/label-files" + filename = "coco-detection-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + return config, is_panoptic + + +def create_rename_keys(config): + # here we list all keys to be renamed (original name on the left, our name on the right) + rename_keys = [] + + # stem + # fmt: off + rename_keys.append(("backbone.0.body.conv1.weight", "backbone.conv_encoder.model.embedder.embedder.convolution.weight")) + rename_keys.append(("backbone.0.body.bn1.weight", "backbone.conv_encoder.model.embedder.embedder.normalization.weight")) + rename_keys.append(("backbone.0.body.bn1.bias", "backbone.conv_encoder.model.embedder.embedder.normalization.bias")) + rename_keys.append(("backbone.0.body.bn1.running_mean", "backbone.conv_encoder.model.embedder.embedder.normalization.running_mean")) + rename_keys.append(("backbone.0.body.bn1.running_var", "backbone.conv_encoder.model.embedder.embedder.normalization.running_var")) + # stages + for stage_idx in range(len(config.backbone_config.depths)): + for layer_idx in range(config.backbone_config.depths[stage_idx]): + # shortcut + if layer_idx == 0: + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.0.weight", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.convolution.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.weight", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.bias", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.bias", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_mean", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_mean", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_var", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_var", + ) + ) + # 3 convs + for i in range(3): + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.conv{i+1}.weight", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.convolution.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.weight", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.weight", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.bias", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.bias", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_mean", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_mean", + ) + ) + rename_keys.append( + ( + f"backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_var", + f"backbone.conv_encoder.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_var", + ) + ) + # fmt: on + + for i in range(config.encoder_layers): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append( + ( + f"transformer.encoder.layers.{i}.self_attn.out_proj.weight", + f"encoder.layers.{i}.self_attn.out_proj.weight", + ) + ) + rename_keys.append( + (f"transformer.encoder.layers.{i}.self_attn.out_proj.bias", f"encoder.layers.{i}.self_attn.out_proj.bias") + ) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.weight", f"encoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear1.bias", f"encoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.weight", f"encoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.encoder.layers.{i}.linear2.bias", f"encoder.layers.{i}.fc2.bias")) + rename_keys.append( + (f"transformer.encoder.layers.{i}.norm1.weight", f"encoder.layers.{i}.self_attn_layer_norm.weight") + ) + rename_keys.append( + (f"transformer.encoder.layers.{i}.norm1.bias", f"encoder.layers.{i}.self_attn_layer_norm.bias") + ) + rename_keys.append( + (f"transformer.encoder.layers.{i}.norm2.weight", f"encoder.layers.{i}.final_layer_norm.weight") + ) + rename_keys.append((f"transformer.encoder.layers.{i}.norm2.bias", f"encoder.layers.{i}.final_layer_norm.bias")) + # decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms + rename_keys.append( + ( + f"transformer.decoder.layers.{i}.self_attn.out_proj.weight", + f"decoder.layers.{i}.self_attn.out_proj.weight", + ) + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.self_attn.out_proj.bias", f"decoder.layers.{i}.self_attn.out_proj.bias") + ) + rename_keys.append( + ( + f"transformer.decoder.layers.{i}.multihead_attn.out_proj.weight", + f"decoder.layers.{i}.encoder_attn.out_proj.weight", + ) + ) + rename_keys.append( + ( + f"transformer.decoder.layers.{i}.multihead_attn.out_proj.bias", + f"decoder.layers.{i}.encoder_attn.out_proj.bias", + ) + ) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.weight", f"decoder.layers.{i}.fc1.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear1.bias", f"decoder.layers.{i}.fc1.bias")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.weight", f"decoder.layers.{i}.fc2.weight")) + rename_keys.append((f"transformer.decoder.layers.{i}.linear2.bias", f"decoder.layers.{i}.fc2.bias")) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm1.weight", f"decoder.layers.{i}.self_attn_layer_norm.weight") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm1.bias", f"decoder.layers.{i}.self_attn_layer_norm.bias") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm2.weight", f"decoder.layers.{i}.encoder_attn_layer_norm.weight") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm2.bias", f"decoder.layers.{i}.encoder_attn_layer_norm.bias") + ) + rename_keys.append( + (f"transformer.decoder.layers.{i}.norm3.weight", f"decoder.layers.{i}.final_layer_norm.weight") + ) + rename_keys.append((f"transformer.decoder.layers.{i}.norm3.bias", f"decoder.layers.{i}.final_layer_norm.bias")) + + # convolutional projection + query embeddings + layernorm of decoder + class and bounding box heads + rename_keys.extend( + [ + ("input_proj.weight", "input_projection.weight"), + ("input_proj.bias", "input_projection.bias"), + ("query_embed.weight", "query_position_embeddings.weight"), + ("transformer.decoder.norm.weight", "decoder.layernorm.weight"), + ("transformer.decoder.norm.bias", "decoder.layernorm.bias"), + ("class_embed.weight", "class_labels_classifier.weight"), + ("class_embed.bias", "class_labels_classifier.bias"), + ("bbox_embed.layers.0.weight", "bbox_predictor.layers.0.weight"), + ("bbox_embed.layers.0.bias", "bbox_predictor.layers.0.bias"), + ("bbox_embed.layers.1.weight", "bbox_predictor.layers.1.weight"), + ("bbox_embed.layers.1.bias", "bbox_predictor.layers.1.bias"), + ("bbox_embed.layers.2.weight", "bbox_predictor.layers.2.weight"), + ("bbox_embed.layers.2.bias", "bbox_predictor.layers.2.bias"), + ] + ) + + return rename_keys + + +def rename_key(state_dict, old, new): + val = state_dict.pop(old) + state_dict[new] = val + + +def read_in_q_k_v(state_dict, is_panoptic=False): + prefix = "" + if is_panoptic: + prefix = "detr." + + # first: transformer encoder + for i in range(6): + # read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"encoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :] + state_dict[f"encoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256] + state_dict[f"encoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :] + state_dict[f"encoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512] + state_dict[f"encoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :] + state_dict[f"encoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:] + # next: transformer decoder (which is a bit more complex because it also includes cross-attention) + for i in range(6): + # read in weights + bias of input projection layer of self-attention + in_proj_weight = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_weight") + in_proj_bias = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"decoder.layers.{i}.self_attn.q_proj.weight"] = in_proj_weight[:256, :] + state_dict[f"decoder.layers.{i}.self_attn.q_proj.bias"] = in_proj_bias[:256] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.weight"] = in_proj_weight[256:512, :] + state_dict[f"decoder.layers.{i}.self_attn.k_proj.bias"] = in_proj_bias[256:512] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.weight"] = in_proj_weight[-256:, :] + state_dict[f"decoder.layers.{i}.self_attn.v_proj.bias"] = in_proj_bias[-256:] + # read in weights + bias of input projection layer of cross-attention + in_proj_weight_cross_attn = state_dict.pop( + f"{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_weight" + ) + in_proj_bias_cross_attn = state_dict.pop(f"{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_bias") + # next, add query, keys and values (in that order) of cross-attention to the state dict + state_dict[f"decoder.layers.{i}.encoder_attn.q_proj.weight"] = in_proj_weight_cross_attn[:256, :] + state_dict[f"decoder.layers.{i}.encoder_attn.q_proj.bias"] = in_proj_bias_cross_attn[:256] + state_dict[f"decoder.layers.{i}.encoder_attn.k_proj.weight"] = in_proj_weight_cross_attn[256:512, :] + state_dict[f"decoder.layers.{i}.encoder_attn.k_proj.bias"] = in_proj_bias_cross_attn[256:512] + state_dict[f"decoder.layers.{i}.encoder_attn.v_proj.weight"] = in_proj_weight_cross_attn[-256:, :] + state_dict[f"decoder.layers.{i}.encoder_attn.v_proj.bias"] = in_proj_bias_cross_attn[-256:] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + + return im + + +@torch.no_grad() +def convert_detr_checkpoint(model_name, pytorch_dump_folder_path=None, push_to_hub=False): + """ + Copy/paste/tweak model's weights to our DETR structure. + """ + + # load default config + config, is_panoptic = get_detr_config(model_name) + + # load original model from torch hub + model_name_to_original_name = { + "detr-resnet-50": "detr_resnet50", + "detr-resnet-101": "detr_resnet101", + } + logger.info(f"Converting model {model_name}...") + detr = torch.hub.load("facebookresearch/detr", model_name_to_original_name[model_name], pretrained=True).eval() + state_dict = detr.state_dict() + # rename keys + for src, dest in create_rename_keys(config): + if is_panoptic: + src = "detr." + src + rename_key(state_dict, src, dest) + # query, key and value matrices need special treatment + read_in_q_k_v(state_dict, is_panoptic=is_panoptic) + # important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them + prefix = "detr.model." if is_panoptic else "model." + for key in state_dict.copy().keys(): + if is_panoptic: + if ( + key.startswith("detr") + and not key.startswith("class_labels_classifier") + and not key.startswith("bbox_predictor") + ): + val = state_dict.pop(key) + state_dict["detr.model" + key[4:]] = val + elif "class_labels_classifier" in key or "bbox_predictor" in key: + val = state_dict.pop(key) + state_dict["detr." + key] = val + elif key.startswith("bbox_attention") or key.startswith("mask_head"): + continue + else: + val = state_dict.pop(key) + state_dict[prefix + key] = val + else: + if not key.startswith("class_labels_classifier") and not key.startswith("bbox_predictor"): + val = state_dict.pop(key) + state_dict[prefix + key] = val + + # finally, create HuggingFace model and load state dict + model = DetrForSegmentation(config) if is_panoptic else DetrForObjectDetection(config) + model.load_state_dict(state_dict) + model.eval() + + # verify our conversion on an image + format = "coco_panoptic" if is_panoptic else "coco_detection" + processor = DetrImageProcessor(format=format) + + encoding = processor(images=prepare_img(), return_tensors="pt") + pixel_values = encoding["pixel_values"] + + original_outputs = detr(pixel_values) + outputs = model(pixel_values) + + assert torch.allclose(outputs.logits, original_outputs["pred_logits"], atol=1e-3) + assert torch.allclose(outputs.pred_boxes, original_outputs["pred_boxes"], atol=1e-3) + if is_panoptic: + assert torch.allclose(outputs.pred_masks, original_outputs["pred_masks"], atol=1e-4) + print("Looks ok!") + + if pytorch_dump_folder_path is not None: + # Save model and image processor + logger.info(f"Saving PyTorch model and image processor to {pytorch_dump_folder_path}...") + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + model.save_pretrained(pytorch_dump_folder_path) + processor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + # Upload model and image processor to the hub + logger.info("Uploading PyTorch model and image processor to the hub...") + model.push_to_hub(f"nielsr/{model_name}") + processor.push_to_hub(f"nielsr/{model_name}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--model_name", + default="detr-resnet-50", + type=str, + choices=["detr-resnet-50", "detr-resnet-101"], + help="Name of the DETR model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model." + ) + parser.add_argument("--push_to_hub", action="store_true", help="Whether to push the model to the hub or not.") + args = parser.parse_args() + convert_detr_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/feature_extraction_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/feature_extraction_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..b94cf9ff8041320b578b7a1f9fb2dee922a6f464 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/feature_extraction_detr.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for DETR.""" + +import warnings + +from ...utils import logging +from .image_processing_detr import DetrImageProcessor + + +logger = logging.get_logger(__name__) + + +class DetrFeatureExtractor(DetrImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class DetrFeatureExtractor is deprecated and will be removed in version 5 of Transformers." + " Please use DetrImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/image_processing_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/image_processing_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..f39db7b8de5a9e203b8174a836485df249273aab --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/image_processing_detr.py @@ -0,0 +1,1793 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for DETR.""" + +import io +import pathlib +from collections import defaultdict +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import ( + PaddingMode, + center_to_corners_format, + corners_to_center_format, + id_to_rgb, + normalize, + pad, + rescale, + resize, + rgb_to_id, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_DEFAULT_MEAN, + IMAGENET_DEFAULT_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + get_image_size, + infer_channel_dimension_format, + make_list_of_images, + to_numpy_array, + valid_coco_detection_annotations, + valid_coco_panoptic_annotations, + valid_images, +) +from ...utils import ( + ExplicitEnum, + TensorType, + is_flax_available, + is_jax_tensor, + is_scipy_available, + is_tf_available, + is_tf_tensor, + is_torch_available, + is_torch_tensor, + is_vision_available, + logging, +) + + +if is_torch_available(): + import torch + from torch import nn + + +if is_vision_available(): + import PIL + + +if is_scipy_available(): + import scipy.special + import scipy.stats + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +AnnotationType = Dict[str, Union[int, str, List[Dict]]] + + +class AnnotionFormat(ExplicitEnum): + COCO_DETECTION = "coco_detection" + COCO_PANOPTIC = "coco_panoptic" + + +SUPPORTED_ANNOTATION_FORMATS = (AnnotionFormat.COCO_DETECTION, AnnotionFormat.COCO_PANOPTIC) + + +def get_size_with_aspect_ratio(image_size, size, max_size=None) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + height, width = image_size + if max_size is not None: + min_original_size = float(min((height, width))) + max_original_size = float(max((height, width))) + if max_original_size / min_original_size * size > max_size: + size = int(round(max_size * min_original_size / max_original_size)) + + if (height <= width and height == size) or (width <= height and width == size): + return height, width + + if width < height: + ow = size + oh = int(size * height / width) + else: + oh = size + ow = int(size * width / height) + return (oh, ow) + + +def get_resize_output_image_size( + input_image: np.ndarray, size: Union[int, Tuple[int, int], List[int]], max_size: Optional[int] = None +) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. If the desired output size + is a tuple or list, the output image size is returned as is. If the desired output size is an integer, the output + image size is computed by keeping the aspect ratio of the input image size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + image_size = get_image_size(input_image) + if isinstance(size, (list, tuple)): + return size + + return get_size_with_aspect_ratio(image_size, size, max_size) + + +def get_numpy_to_framework_fn(arr) -> Callable: + """ + Returns a function that converts a numpy array to the framework of the input array. + + Args: + arr (`np.ndarray`): The array to convert. + """ + if isinstance(arr, np.ndarray): + return np.array + if is_tf_available() and is_tf_tensor(arr): + import tensorflow as tf + + return tf.convert_to_tensor + if is_torch_available() and is_torch_tensor(arr): + import torch + + return torch.tensor + if is_flax_available() and is_jax_tensor(arr): + import jax.numpy as jnp + + return jnp.array + raise ValueError(f"Cannot convert arrays of type {type(arr)}") + + +def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: + """ + Squeezes an array, but only if the axis specified has dim 1. + """ + if axis is None: + return arr.squeeze() + + try: + return arr.squeeze(axis=axis) + except ValueError: + return arr + + +def normalize_annotation(annotation: Dict, image_size: Tuple[int, int]) -> Dict: + image_height, image_width = image_size + norm_annotation = {} + for key, value in annotation.items(): + if key == "boxes": + boxes = value + boxes = corners_to_center_format(boxes) + boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32) + norm_annotation[key] = boxes + else: + norm_annotation[key] = value + return norm_annotation + + +# Copied from transformers.models.vilt.image_processing_vilt.max_across_indices +def max_across_indices(values: Iterable[Any]) -> List[Any]: + """ + Return the maximum value across all indices of an iterable of values. + """ + return [max(values_i) for values_i in zip(*values)] + + +# Copied from transformers.models.vilt.image_processing_vilt.get_max_height_width +def get_max_height_width(images: List[np.ndarray]) -> List[int]: + """ + Get the maximum height and width across all images in a batch. + """ + input_channel_dimension = infer_channel_dimension_format(images[0]) + + if input_channel_dimension == ChannelDimension.FIRST: + _, max_height, max_width = max_across_indices([img.shape for img in images]) + elif input_channel_dimension == ChannelDimension.LAST: + max_height, max_width, _ = max_across_indices([img.shape for img in images]) + else: + raise ValueError(f"Invalid channel dimension format: {input_channel_dimension}") + return (max_height, max_width) + + +# Copied from transformers.models.vilt.image_processing_vilt.make_pixel_mask +def make_pixel_mask(image: np.ndarray, output_size: Tuple[int, int]) -> np.ndarray: + """ + Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding. + + Args: + image (`np.ndarray`): + Image to make the pixel mask for. + output_size (`Tuple[int, int]`): + Output size of the mask. + """ + input_height, input_width = get_image_size(image) + mask = np.zeros(output_size, dtype=np.int64) + mask[:input_height, :input_width] = 1 + return mask + + +# inspired by https://github.com/facebookresearch/detr/blob/master/datasets/coco.py#L33 +def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray: + """ + Convert a COCO polygon annotation to a mask. + + Args: + segmentations (`List[List[float]]`): + List of polygons, each polygon represented by a list of x-y coordinates. + height (`int`): + Height of the mask. + width (`int`): + Width of the mask. + """ + try: + from pycocotools import mask as coco_mask + except ImportError: + raise ImportError("Pycocotools is not installed in your environment.") + + masks = [] + for polygons in segmentations: + rles = coco_mask.frPyObjects(polygons, height, width) + mask = coco_mask.decode(rles) + if len(mask.shape) < 3: + mask = mask[..., None] + mask = np.asarray(mask, dtype=np.uint8) + mask = np.any(mask, axis=2) + masks.append(mask) + if masks: + masks = np.stack(masks, axis=0) + else: + masks = np.zeros((0, height, width), dtype=np.uint8) + + return masks + + +# inspired by https://github.com/facebookresearch/detr/blob/master/datasets/coco.py#L50 +def prepare_coco_detection_annotation(image, target, return_segmentation_masks: bool = False): + """ + Convert the target in COCO format into the format expected by DETR. + """ + image_height, image_width = get_image_size(image) + + image_id = target["image_id"] + image_id = np.asarray([image_id], dtype=np.int64) + + # Get all COCO annotations for the given image. + annotations = target["annotations"] + annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0] + + classes = [obj["category_id"] for obj in annotations] + classes = np.asarray(classes, dtype=np.int64) + + # for conversion to coco api + area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32) + iscrowd = np.asarray([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in annotations], dtype=np.int64) + + boxes = [obj["bbox"] for obj in annotations] + # guard against no boxes via resizing + boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4) + boxes[:, 2:] += boxes[:, :2] + boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width) + boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height) + + keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0]) + + new_target = {} + new_target["image_id"] = image_id + new_target["class_labels"] = classes[keep] + new_target["boxes"] = boxes[keep] + new_target["area"] = area[keep] + new_target["iscrowd"] = iscrowd[keep] + new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64) + + if annotations and "keypoints" in annotations[0]: + keypoints = [obj["keypoints"] for obj in annotations] + keypoints = np.asarray(keypoints, dtype=np.float32) + num_keypoints = keypoints.shape[0] + keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints + new_target["keypoints"] = keypoints[keep] + + if return_segmentation_masks: + segmentation_masks = [obj["segmentation"] for obj in annotations] + masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width) + new_target["masks"] = masks[keep] + + return new_target + + +def masks_to_boxes(masks: np.ndarray) -> np.ndarray: + """ + Compute the bounding boxes around the provided panoptic segmentation masks. + + Args: + masks: masks in format `[number_masks, height, width]` where N is the number of masks + + Returns: + boxes: bounding boxes in format `[number_masks, 4]` in xyxy format + """ + if masks.size == 0: + return np.zeros((0, 4)) + + h, w = masks.shape[-2:] + y = np.arange(0, h, dtype=np.float32) + x = np.arange(0, w, dtype=np.float32) + # see https://github.com/pytorch/pytorch/issues/50276 + y, x = np.meshgrid(y, x, indexing="ij") + + x_mask = masks * np.expand_dims(x, axis=0) + x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1) + x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool))) + x_min = x.filled(fill_value=1e8) + x_min = x_min.reshape(x_min.shape[0], -1).min(-1) + + y_mask = masks * np.expand_dims(y, axis=0) + y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1) + y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool))) + y_min = y.filled(fill_value=1e8) + y_min = y_min.reshape(y_min.shape[0], -1).min(-1) + + return np.stack([x_min, y_min, x_max, y_max], 1) + + +def prepare_coco_panoptic_annotation( + image: np.ndarray, target: Dict, masks_path: Union[str, pathlib.Path], return_masks: bool = True +) -> Dict: + """ + Prepare a coco panoptic annotation for DETR. + """ + image_height, image_width = get_image_size(image) + annotation_path = pathlib.Path(masks_path) / target["file_name"] + + new_target = {} + new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64) + new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64) + new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64) + + if "segments_info" in target: + masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32) + masks = rgb_to_id(masks) + + ids = np.array([segment_info["id"] for segment_info in target["segments_info"]]) + masks = masks == ids[:, None, None] + masks = masks.astype(np.uint8) + if return_masks: + new_target["masks"] = masks + new_target["boxes"] = masks_to_boxes(masks) + new_target["class_labels"] = np.array( + [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["iscrowd"] = np.asarray( + [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["area"] = np.asarray( + [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32 + ) + + return new_target + + +def get_segmentation_image( + masks: np.ndarray, input_size: Tuple, target_size: Tuple, stuff_equiv_classes, deduplicate=False +): + h, w = input_size + final_h, final_w = target_size + + m_id = scipy.special.softmax(masks.transpose(0, 1), -1) + + if m_id.shape[-1] == 0: + # We didn't detect any mask :( + m_id = np.zeros((h, w), dtype=np.int64) + else: + m_id = m_id.argmax(-1).reshape(h, w) + + if deduplicate: + # Merge the masks corresponding to the same stuff class + for equiv in stuff_equiv_classes.values(): + for eq_id in equiv: + m_id[m_id == eq_id] = equiv[0] + + seg_img = id_to_rgb(m_id) + seg_img = resize(seg_img, (final_w, final_h), resample=PILImageResampling.NEAREST) + return seg_img + + +def get_mask_area(seg_img: np.ndarray, target_size: Tuple[int, int], n_classes: int) -> np.ndarray: + final_h, final_w = target_size + np_seg_img = seg_img.astype(np.uint8) + np_seg_img = np_seg_img.reshape(final_h, final_w, 3) + m_id = rgb_to_id(np_seg_img) + area = [(m_id == i).sum() for i in range(n_classes)] + return area + + +def score_labels_from_class_probabilities(logits: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + probs = scipy.special.softmax(logits, axis=-1) + labels = probs.argmax(-1, keepdims=True) + scores = np.take_along_axis(probs, labels, axis=-1) + scores, labels = scores.squeeze(-1), labels.squeeze(-1) + return scores, labels + + +def post_process_panoptic_sample( + out_logits: np.ndarray, + masks: np.ndarray, + boxes: np.ndarray, + processed_size: Tuple[int, int], + target_size: Tuple[int, int], + is_thing_map: Dict, + threshold=0.85, +) -> Dict: + """ + Converts the output of [`DetrForSegmentation`] into panoptic segmentation predictions for a single sample. + + Args: + out_logits (`torch.Tensor`): + The logits for this sample. + masks (`torch.Tensor`): + The predicted segmentation masks for this sample. + boxes (`torch.Tensor`): + The prediced bounding boxes for this sample. The boxes are in the normalized format `(center_x, center_y, + width, height)` and values between `[0, 1]`, relative to the size the image (disregarding padding). + processed_size (`Tuple[int, int]`): + The processed size of the image `(height, width)`, as returned by the preprocessing step i.e. the size + after data augmentation but before batching. + target_size (`Tuple[int, int]`): + The target size of the image, `(height, width)` corresponding to the requested final size of the + prediction. + is_thing_map (`Dict`): + A dictionary mapping class indices to a boolean value indicating whether the class is a thing or not. + threshold (`float`, *optional*, defaults to 0.85): + The threshold used to binarize the segmentation masks. + """ + # we filter empty queries and detection below threshold + scores, labels = score_labels_from_class_probabilities(out_logits) + keep = (labels != out_logits.shape[-1] - 1) & (scores > threshold) + + cur_scores = scores[keep] + cur_classes = labels[keep] + cur_boxes = center_to_corners_format(boxes[keep]) + + if len(cur_boxes) != len(cur_classes): + raise ValueError("Not as many boxes as there are classes") + + cur_masks = masks[keep] + cur_masks = resize(cur_masks[:, None], processed_size, resample=PILImageResampling.BILINEAR) + cur_masks = safe_squeeze(cur_masks, 1) + b, h, w = cur_masks.shape + + # It may be that we have several predicted masks for the same stuff class. + # In the following, we track the list of masks ids for each stuff class (they are merged later on) + cur_masks = cur_masks.reshape(b, -1) + stuff_equiv_classes = defaultdict(list) + for k, label in enumerate(cur_classes): + if not is_thing_map[label]: + stuff_equiv_classes[label].append(k) + + seg_img = get_segmentation_image(cur_masks, processed_size, target_size, stuff_equiv_classes, deduplicate=True) + area = get_mask_area(cur_masks, processed_size, n_classes=len(cur_scores)) + + # We filter out any mask that is too small + if cur_classes.size() > 0: + # We know filter empty masks as long as we find some + filtered_small = np.array([a <= 4 for a in area], dtype=bool) + while filtered_small.any(): + cur_masks = cur_masks[~filtered_small] + cur_scores = cur_scores[~filtered_small] + cur_classes = cur_classes[~filtered_small] + seg_img = get_segmentation_image(cur_masks, (h, w), target_size, stuff_equiv_classes, deduplicate=True) + area = get_mask_area(seg_img, target_size, n_classes=len(cur_scores)) + filtered_small = np.array([a <= 4 for a in area], dtype=bool) + else: + cur_classes = np.ones((1, 1), dtype=np.int64) + + segments_info = [ + {"id": i, "isthing": is_thing_map[cat], "category_id": int(cat), "area": a} + for i, (cat, a) in enumerate(zip(cur_classes, area)) + ] + del cur_classes + + with io.BytesIO() as out: + PIL.Image.fromarray(seg_img).save(out, format="PNG") + predictions = {"png_string": out.getvalue(), "segments_info": segments_info} + + return predictions + + +def resize_annotation( + annotation: Dict[str, Any], + orig_size: Tuple[int, int], + target_size: Tuple[int, int], + threshold: float = 0.5, + resample: PILImageResampling = PILImageResampling.NEAREST, +): + """ + Resizes an annotation to a target size. + + Args: + annotation (`Dict[str, Any]`): + The annotation dictionary. + orig_size (`Tuple[int, int]`): + The original size of the input image. + target_size (`Tuple[int, int]`): + The target size of the image, as returned by the preprocessing `resize` step. + threshold (`float`, *optional*, defaults to 0.5): + The threshold used to binarize the segmentation masks. + resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`): + The resampling filter to use when resizing the masks. + """ + ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size)) + ratio_height, ratio_width = ratios + + new_annotation = {} + new_annotation["size"] = target_size + + for key, value in annotation.items(): + if key == "boxes": + boxes = value + scaled_boxes = boxes * np.asarray([ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32) + new_annotation["boxes"] = scaled_boxes + elif key == "area": + area = value + scaled_area = area * (ratio_width * ratio_height) + new_annotation["area"] = scaled_area + elif key == "masks": + masks = value[:, None] + masks = np.array([resize(mask, target_size, resample=resample) for mask in masks]) + masks = masks.astype(np.float32) + masks = masks[:, 0] > threshold + new_annotation["masks"] = masks + elif key == "size": + new_annotation["size"] = target_size + else: + new_annotation[key] = value + + return new_annotation + + +# TODO - (Amy) make compatible with other frameworks +def binary_mask_to_rle(mask): + """ + Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + mask (`torch.Tensor` or `numpy.array`): + A binary mask tensor of shape `(height, width)` where 0 denotes background and 1 denotes the target + segment_id or class_id. + Returns: + `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE + format. + """ + if is_torch_tensor(mask): + mask = mask.numpy() + + pixels = mask.flatten() + pixels = np.concatenate([[0], pixels, [0]]) + runs = np.where(pixels[1:] != pixels[:-1])[0] + 1 + runs[1::2] -= runs[::2] + return list(runs) + + +# TODO - (Amy) make compatible with other frameworks +def convert_segmentation_to_rle(segmentation): + """ + Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + segmentation (`torch.Tensor` or `numpy.array`): + A segmentation map of shape `(height, width)` where each value denotes a segment or class id. + Returns: + `List[List]`: A list of lists, where each list is the run-length encoding of a segment / class id. + """ + segment_ids = torch.unique(segmentation) + + run_length_encodings = [] + for idx in segment_ids: + mask = torch.where(segmentation == idx, 1, 0) + rle = binary_mask_to_rle(mask) + run_length_encodings.append(rle) + + return run_length_encodings + + +def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels): + """ + Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and + `labels`. + + Args: + masks (`torch.Tensor`): + A tensor of shape `(num_queries, height, width)`. + scores (`torch.Tensor`): + A tensor of shape `(num_queries)`. + labels (`torch.Tensor`): + A tensor of shape `(num_queries)`. + object_mask_threshold (`float`): + A number between 0 and 1 used to binarize the masks. + Raises: + `ValueError`: Raised when the first dimension doesn't match in all input tensors. + Returns: + `Tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region + < `object_mask_threshold`. + """ + if not (masks.shape[0] == scores.shape[0] == labels.shape[0]): + raise ValueError("mask, scores and labels must have the same shape!") + + to_keep = labels.ne(num_labels) & (scores > object_mask_threshold) + + return masks[to_keep], scores[to_keep], labels[to_keep] + + +def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8): + # Get the mask associated with the k class + mask_k = mask_labels == k + mask_k_area = mask_k.sum() + + # Compute the area of all the stuff in query k + original_area = (mask_probs[k] >= mask_threshold).sum() + mask_exists = mask_k_area > 0 and original_area > 0 + + # Eliminate disconnected tiny segments + if mask_exists: + area_ratio = mask_k_area / original_area + if not area_ratio.item() > overlap_mask_area_threshold: + mask_exists = False + + return mask_exists, mask_k + + +def compute_segments( + mask_probs, + pred_scores, + pred_labels, + mask_threshold: float = 0.5, + overlap_mask_area_threshold: float = 0.8, + label_ids_to_fuse: Optional[Set[int]] = None, + target_size: Tuple[int, int] = None, +): + height = mask_probs.shape[1] if target_size is None else target_size[0] + width = mask_probs.shape[2] if target_size is None else target_size[1] + + segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device) + segments: List[Dict] = [] + + if target_size is not None: + mask_probs = nn.functional.interpolate( + mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False + )[0] + + current_segment_id = 0 + + # Weigh each mask by its prediction score + mask_probs *= pred_scores.view(-1, 1, 1) + mask_labels = mask_probs.argmax(0) # [height, width] + + # Keep track of instances of each class + stuff_memory_list: Dict[str, int] = {} + for k in range(pred_labels.shape[0]): + pred_class = pred_labels[k].item() + should_fuse = pred_class in label_ids_to_fuse + + # Check if mask exists and large enough to be a segment + mask_exists, mask_k = check_segment_validity( + mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold + ) + + if mask_exists: + if pred_class in stuff_memory_list: + current_segment_id = stuff_memory_list[pred_class] + else: + current_segment_id += 1 + + # Add current object segment to final segmentation map + segmentation[mask_k] = current_segment_id + segment_score = round(pred_scores[k].item(), 6) + segments.append( + { + "id": current_segment_id, + "label_id": pred_class, + "was_fused": should_fuse, + "score": segment_score, + } + ) + if should_fuse: + stuff_memory_list[pred_class] = current_segment_id + + return segmentation, segments + + +class DetrImageProcessor(BaseImageProcessor): + r""" + Constructs a Detr image processor. + + Args: + format (`str`, *optional*, defaults to `"coco_detection"`): + Data format of the annotations. One of "coco_detection" or "coco_panoptic". + do_resize (`bool`, *optional*, defaults to `True`): + Controls whether to resize the image's `(height, width)` dimensions to the specified `size`. Can be + overridden by the `do_resize` parameter in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 800, "longest_edge": 1333}`): + Size of the image's `(height, width)` dimensions after resizing. Can be overridden by the `size` parameter + in the `preprocess` method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. + do_rescale (`bool`, *optional*, defaults to `True`): + Controls whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the + `do_rescale` parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize: + Controls whether to normalize the image. Can be overridden by the `do_normalize` parameter in the + `preprocess` method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_MEAN`): + Mean values to use when normalizing the image. Can be a single value or a list of values, one for each + channel. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_STD`): + Standard deviation values to use when normalizing the image. Can be a single value or a list of values, one + for each channel. Can be overridden by the `image_std` parameter in the `preprocess` method. + do_pad (`bool`, *optional*, defaults to `True`): + Controls whether to pad the image to the largest image in a batch and create a pixel mask. Can be + overridden by the `do_pad` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values", "pixel_mask"] + + def __init__( + self, + format: Union[str, AnnotionFormat] = AnnotionFormat.COCO_DETECTION, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Union[float, List[float]] = None, + image_std: Union[float, List[float]] = None, + do_pad: bool = True, + **kwargs, + ) -> None: + if "pad_and_return_pixel_mask" in kwargs: + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None if size is None else 1333 + + size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333} + size = get_size_dict(size, max_size=max_size, default_to_square=False) + + super().__init__(**kwargs) + self.format = format + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_DEFAULT_STD + self.do_pad = do_pad + + @property + def max_size(self): + logger.warning( + "The `max_size` parameter is deprecated and will be removed in v4.27. " + "Please specify in `size['longest_edge'] instead`.", + ) + return self.size["longest_edge"] + + @classmethod + def from_dict(cls, image_processor_dict: Dict[str, Any], **kwargs): + """ + Overrides the `from_dict` method from the base class to make sure parameters are updated if image processor is + created using from_dict and kwargs e.g. `DetrImageProcessor.from_pretrained(checkpoint, size=600, + max_size=800)` + """ + image_processor_dict = image_processor_dict.copy() + if "max_size" in kwargs: + image_processor_dict["max_size"] = kwargs.pop("max_size") + if "pad_and_return_pixel_mask" in kwargs: + image_processor_dict["pad_and_return_pixel_mask"] = kwargs.pop("pad_and_return_pixel_mask") + return super().from_dict(image_processor_dict, **kwargs) + + def prepare_annotation( + self, + image: np.ndarray, + target: Dict, + format: Optional[AnnotionFormat] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + ) -> Dict: + """ + Prepare an annotation for feeding into DETR model. + """ + format = format if format is not None else self.format + + if format == AnnotionFormat.COCO_DETECTION: + return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_detection_annotation(image, target, return_segmentation_masks) + elif format == AnnotionFormat.COCO_PANOPTIC: + return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_panoptic_annotation( + image, target, masks_path=masks_path, return_masks=return_segmentation_masks + ) + else: + raise ValueError(f"Format {format} is not supported.") + return target + + def prepare(self, image, target, return_segmentation_masks=None, masks_path=None): + logger.warning_once( + "The `prepare` method is deprecated and will be removed in a future version. " + "Please use `prepare_annotation` instead. Note: the `prepare_annotation` method " + "does not return the image anymore.", + ) + target = self.prepare_annotation(image, target, return_segmentation_masks, masks_path, self.format) + return image, target + + def convert_coco_poly_to_mask(self, *args, **kwargs): + logger.warning_once( + "The `convert_coco_poly_to_mask` method is deprecated and will be removed in a future version. " + ) + return convert_coco_poly_to_mask(*args, **kwargs) + + def prepare_coco_detection(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_detection` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_detection_annotation(*args, **kwargs) + + def prepare_coco_panoptic(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_panoptic` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_panoptic_annotation(*args, **kwargs) + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BILINEAR, + data_format: Optional[ChannelDimension] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an + int, smaller edge of the image will be matched to this number. + """ + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None + size = get_size_dict(size, max_size=max_size, default_to_square=False) + if "shortest_edge" in size and "longest_edge" in size: + size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"]) + elif "height" in size and "width" in size: + size = (size["height"], size["width"]) + else: + raise ValueError( + "Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got" + f" {size.keys()}." + ) + image = resize(image, size=size, resample=resample, data_format=data_format) + return image + + def resize_annotation( + self, + annotation, + orig_size, + size, + resample: PILImageResampling = PILImageResampling.NEAREST, + ) -> Dict: + """ + Resize the annotation to match the resized image. If size is an int, smaller edge of the mask will be matched + to this number. + """ + return resize_annotation(annotation, orig_size=orig_size, target_size=size, resample=resample) + + def rescale( + self, image: np.ndarray, rescale_factor: Union[float, int], data_format: Optional[ChannelDimension] = None + ) -> np.ndarray: + """ + Rescale the image by the given factor. + """ + return rescale(image, rescale_factor, data_format=data_format) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, Iterable[float]], + std: Union[float, Iterable[float]], + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Normalize the image with the given mean and standard deviation. + """ + return normalize(image, mean=mean, std=std, data_format=data_format) + + def normalize_annotation(self, annotation: Dict, image_size: Tuple[int, int]) -> Dict: + """ + Normalize the boxes in the annotation from `[top_left_x, top_left_y, bottom_right_x, bottom_right_y]` to + `[center_x, center_y, width, height]` format. + """ + return normalize_annotation(annotation, image_size=image_size) + + def pad_and_create_pixel_mask( + self, + pixel_values_list: List[ImageInput], + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> BatchFeature: + """ + Pads a batch of images with zeros to the size of largest height and width in the batch and returns their + corresponding pixel mask. + + Args: + images (`List[np.ndarray]`): + Batch of images to pad. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + logger.warning_once("This method is deprecated and will be removed in v4.27.0. Please use pad instead.") + # pad expects a list of np.ndarray, but the previous feature extractors expected torch tensors + images = [to_numpy_array(image) for image in pixel_values_list] + return self.pad( + images=images, + return_pixel_mask=True, + return_tensors=return_tensors, + data_format=data_format, + ) + + def _pad_image( + self, + image: np.ndarray, + output_size: Tuple[int, int], + constant_values: Union[float, Iterable[float]] = 0, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pad an image with zeros to the given size. + """ + input_height, input_width = get_image_size(image) + output_height, output_width = output_size + + pad_bottom = output_height - input_height + pad_right = output_width - input_width + padding = ((0, pad_bottom), (0, pad_right)) + padded_image = pad( + image, padding, mode=PaddingMode.CONSTANT, constant_values=constant_values, data_format=data_format + ) + return padded_image + + def pad( + self, + images: List[np.ndarray], + constant_values: Union[float, Iterable[float]] = 0, + return_pixel_mask: bool = True, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pads a batch of images to the bottom and right of the image with zeros to the size of largest height and width + in the batch and optionally returns their corresponding pixel mask. + + Args: + image (`np.ndarray`): + Image to pad. + constant_values (`float` or `Iterable[float]`, *optional*): + The value to use for the padding if `mode` is `"constant"`. + return_pixel_mask (`bool`, *optional*, defaults to `True`): + Whether to return a pixel mask. + input_channel_dimension (`ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be inferred from the input image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + pad_size = get_max_height_width(images) + + padded_images = [ + self._pad_image(image, pad_size, constant_values=constant_values, data_format=data_format) + for image in images + ] + data = {"pixel_values": padded_images} + + if return_pixel_mask: + masks = [make_pixel_mask(image=image, output_size=pad_size) for image in images] + data["pixel_mask"] = masks + + return BatchFeature(data=data, tensor_type=return_tensors) + + def preprocess( + self, + images: ImageInput, + annotations: Optional[Union[AnnotationType, List[AnnotationType]]] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + do_resize: Optional[bool] = None, + size: Optional[Dict[str, int]] = None, + resample=None, # PILImageResampling + do_rescale: Optional[bool] = None, + rescale_factor: Optional[Union[int, float]] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_pad: Optional[bool] = None, + format: Optional[Union[str, AnnotionFormat]] = None, + return_tensors: Optional[Union[TensorType, str]] = None, + data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> BatchFeature: + """ + Preprocess an image or a batch of images so that it can be used by the model. + + Args: + images (`ImageInput`): + Image or batch of images to preprocess. + annotations (`AnnotationType` or `List[AnnotationType]`, *optional*): + List of annotations associated with the image or batch of images. If annotation is for object + detection, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "annotations" (`List[Dict]`): List of annotations for an image. Each annotation should be a + dictionary. An image can have no annotations, in which case the list should be empty. + If annotation is for segmentation, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "segments_info" (`List[Dict]`): List of segments for an image. Each segment should be a dictionary. + An image can have no segments, in which case the list should be empty. + - "file_name" (`str`): The file name of the image. + return_segmentation_masks (`bool`, *optional*, defaults to self.return_segmentation_masks): + Whether to return segmentation masks. + masks_path (`str` or `pathlib.Path`, *optional*): + Path to the directory containing the segmentation masks. + do_resize (`bool`, *optional*, defaults to self.do_resize): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to self.size): + Size of the image after resizing. + resample (`PILImageResampling`, *optional*, defaults to self.resample): + Resampling filter to use when resizing the image. + do_rescale (`bool`, *optional*, defaults to self.do_rescale): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to self.rescale_factor): + Rescale factor to use when rescaling the image. + do_normalize (`bool`, *optional*, defaults to self.do_normalize): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to self.image_mean): + Mean to use when normalizing the image. + image_std (`float` or `List[float]`, *optional*, defaults to self.image_std): + Standard deviation to use when normalizing the image. + do_pad (`bool`, *optional*, defaults to self.do_pad): + Whether to pad the image. + format (`str` or `AnnotionFormat`, *optional*, defaults to self.format): + Format of the annotations. + return_tensors (`str` or `TensorType`, *optional*, defaults to self.return_tensors): + Type of tensors to return. If `None`, will return the list of images. + data_format (`str` or `ChannelDimension`, *optional*, defaults to self.data_format): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + if "pad_and_return_pixel_mask" in kwargs: + logger.warning_once( + "The `pad_and_return_pixel_mask` argument is deprecated and will be removed in a future version, " + "use `do_pad` instead." + ) + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + max_size = None + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` argument is deprecated and will be removed in a future version, use" + " `size['longest_edge']` instead." + ) + size = kwargs.pop("max_size") + + do_resize = self.do_resize if do_resize is None else do_resize + size = self.size if size is None else size + size = get_size_dict(size=size, max_size=max_size, default_to_square=False) + resample = self.resample if resample is None else resample + do_rescale = self.do_rescale if do_rescale is None else do_rescale + rescale_factor = self.rescale_factor if rescale_factor is None else rescale_factor + do_normalize = self.do_normalize if do_normalize is None else do_normalize + image_mean = self.image_mean if image_mean is None else image_mean + image_std = self.image_std if image_std is None else image_std + do_pad = self.do_pad if do_pad is None else do_pad + format = self.format if format is None else format + + if do_resize is not None and size is None: + raise ValueError("Size and max_size must be specified if do_resize is True.") + + if do_rescale is not None and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize is not None and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + images = make_list_of_images(images) + if annotations is not None and isinstance(annotations, dict): + annotations = [annotations] + + if annotations is not None and len(images) != len(annotations): + raise ValueError( + f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match." + ) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + format = AnnotionFormat(format) + if annotations is not None: + if format == AnnotionFormat.COCO_DETECTION and not valid_coco_detection_annotations(annotations): + raise ValueError( + "Invalid COCO detection annotations. Annotations must a dict (single image) of list of dicts" + "(batch of images) with the following keys: `image_id` and `annotations`, with the latter " + "being a list of annotations in the COCO format." + ) + elif format == AnnotionFormat.COCO_PANOPTIC and not valid_coco_panoptic_annotations(annotations): + raise ValueError( + "Invalid COCO panoptic annotations. Annotations must a dict (single image) of list of dicts " + "(batch of images) with the following keys: `image_id`, `file_name` and `segments_info`, with " + "the latter being a list of annotations in the COCO format." + ) + elif format not in SUPPORTED_ANNOTATION_FORMATS: + raise ValueError( + f"Unsupported annotation format: {format} must be one of {SUPPORTED_ANNOTATION_FORMATS}" + ) + + if ( + masks_path is not None + and format == AnnotionFormat.COCO_PANOPTIC + and not isinstance(masks_path, (pathlib.Path, str)) + ): + raise ValueError( + "The path to the directory containing the mask PNG files should be provided as a" + f" `pathlib.Path` or string object, but is {type(masks_path)} instead." + ) + + # All transformations expect numpy arrays + images = [to_numpy_array(image) for image in images] + + # prepare (COCO annotations as a list of Dict -> DETR target as a single Dict per image) + if annotations is not None: + prepared_images = [] + prepared_annotations = [] + for image, target in zip(images, annotations): + target = self.prepare_annotation( + image, target, format, return_segmentation_masks=return_segmentation_masks, masks_path=masks_path + ) + prepared_images.append(image) + prepared_annotations.append(target) + images = prepared_images + annotations = prepared_annotations + del prepared_images, prepared_annotations + + # transformations + if do_resize: + if annotations is not None: + resized_images, resized_annotations = [], [] + for image, target in zip(images, annotations): + orig_size = get_image_size(image) + resized_image = self.resize(image, size=size, max_size=max_size, resample=resample) + resized_annotation = self.resize_annotation(target, orig_size, get_image_size(resized_image)) + resized_images.append(resized_image) + resized_annotations.append(resized_annotation) + images = resized_images + annotations = resized_annotations + del resized_images, resized_annotations + else: + images = [self.resize(image, size=size, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image, rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image, image_mean, image_std) for image in images] + if annotations is not None: + annotations = [ + self.normalize_annotation(annotation, get_image_size(image)) + for annotation, image in zip(annotations, images) + ] + + if do_pad: + # Pads images and returns their mask: {'pixel_values': ..., 'pixel_mask': ...} + data = self.pad(images, return_pixel_mask=True, data_format=data_format) + else: + images = [to_channel_dimension_format(image, data_format) for image in images] + data = {"pixel_values": images} + + encoded_inputs = BatchFeature(data=data, tensor_type=return_tensors) + if annotations is not None: + encoded_inputs["labels"] = [ + BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations + ] + + return encoded_inputs + + # POSTPROCESSING METHODS - TODO: add support for other frameworks + # inspired by https://github.com/facebookresearch/detr/blob/master/models/detr.py#L258 + def post_process(self, outputs, target_sizes): + """ + Converts the raw output of [`DetrForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, + bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`DetrObjectDetectionOutput`]): + Raw outputs of the model. + target_sizes (`torch.Tensor` of shape `(batch_size, 2)`): + Tensor containing the size (height, width) of each image of the batch. For evaluation, this must be the + original image size (before any data augmentation). For visualization, this should be the image size + after data augment, but before padding. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process` is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_object_detection`", + ) + + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if len(out_logits) != len(target_sizes): + raise ValueError("Make sure that you pass in as many target sizes as the batch dimension of the logits") + if target_sizes.shape[1] != 2: + raise ValueError("Each element of target_sizes must contain the size (h, w) of each image of the batch") + + prob = nn.functional.softmax(out_logits, -1) + scores, labels = prob[..., :-1].max(-1) + + # convert to [x0, y0, x1, y1] format + boxes = center_to_corners_format(out_bbox) + # and from relative [0, 1] to absolute [0, height] coordinates + img_h, img_w = target_sizes.unbind(1) + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [{"scores": s, "labels": l, "boxes": b} for s, l, b in zip(scores, labels, boxes)] + return results + + def post_process_segmentation(self, outputs, target_sizes, threshold=0.9, mask_threshold=0.5): + """ + Converts the output of [`DetrForSegmentation`] into image segmentation predictions. Only supports PyTorch. + + Args: + outputs ([`DetrSegmentationOutput`]): + Raw outputs of the model. + target_sizes (`torch.Tensor` of shape `(batch_size, 2)` or `List[Tuple]` of length `batch_size`): + Torch Tensor (or list) corresponding to the requested final size (h, w) of each prediction. + threshold (`float`, *optional*, defaults to 0.9): + Threshold to use to filter out queries. + mask_threshold (`float`, *optional*, defaults to 0.5): + Threshold to use when turning the predicted masks into binary values. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels, and masks for an image + in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process_segmentation` is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_semantic_segmentation`.", + ) + out_logits, raw_masks = outputs.logits, outputs.pred_masks + empty_label = out_logits.shape[-1] - 1 + preds = [] + + def to_tuple(tup): + if isinstance(tup, tuple): + return tup + return tuple(tup.cpu().tolist()) + + for cur_logits, cur_masks, size in zip(out_logits, raw_masks, target_sizes): + # we filter empty queries and detection below threshold + cur_scores, cur_labels = cur_logits.softmax(-1).max(-1) + keep = cur_labels.ne(empty_label) & (cur_scores > threshold) + cur_scores = cur_scores[keep] + cur_labels = cur_labels[keep] + cur_masks = cur_masks[keep] + cur_masks = nn.functional.interpolate(cur_masks[:, None], to_tuple(size), mode="bilinear").squeeze(1) + cur_masks = (cur_masks.sigmoid() > mask_threshold) * 1 + + predictions = {"scores": cur_scores, "labels": cur_labels, "masks": cur_masks} + preds.append(predictions) + return preds + + # inspired by https://github.com/facebookresearch/detr/blob/master/models/segmentation.py#L218 + def post_process_instance(self, results, outputs, orig_target_sizes, max_target_sizes, threshold=0.5): + """ + Converts the output of [`DetrForSegmentation`] into actual instance segmentation predictions. Only supports + PyTorch. + + Args: + results (`List[Dict]`): + Results list obtained by [`~DetrFeatureExtractor.post_process`], to which "masks" results will be + added. + outputs ([`DetrSegmentationOutput`]): + Raw outputs of the model. + orig_target_sizes (`torch.Tensor` of shape `(batch_size, 2)`): + Tensor containing the size (h, w) of each image of the batch. For evaluation, this must be the original + image size (before any data augmentation). + max_target_sizes (`torch.Tensor` of shape `(batch_size, 2)`): + Tensor containing the maximum size (h, w) of each image of the batch. For evaluation, this must be the + original image size (before any data augmentation). + threshold (`float`, *optional*, defaults to 0.5): + Threshold to use when turning the predicted masks into binary values. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels, boxes and masks for an + image in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process_instance` is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_instance_segmentation`.", + ) + + if len(orig_target_sizes) != len(max_target_sizes): + raise ValueError("Make sure to pass in as many orig_target_sizes as max_target_sizes") + max_h, max_w = max_target_sizes.max(0)[0].tolist() + outputs_masks = outputs.pred_masks.squeeze(2) + outputs_masks = nn.functional.interpolate( + outputs_masks, size=(max_h, max_w), mode="bilinear", align_corners=False + ) + outputs_masks = (outputs_masks.sigmoid() > threshold).cpu() + + for i, (cur_mask, t, tt) in enumerate(zip(outputs_masks, max_target_sizes, orig_target_sizes)): + img_h, img_w = t[0], t[1] + results[i]["masks"] = cur_mask[:, :img_h, :img_w].unsqueeze(1) + results[i]["masks"] = nn.functional.interpolate( + results[i]["masks"].float(), size=tuple(tt.tolist()), mode="nearest" + ).byte() + + return results + + # inspired by https://github.com/facebookresearch/detr/blob/master/models/segmentation.py#L241 + def post_process_panoptic(self, outputs, processed_sizes, target_sizes=None, is_thing_map=None, threshold=0.85): + """ + Converts the output of [`DetrForSegmentation`] into actual panoptic predictions. Only supports PyTorch. + + Args: + outputs ([`DetrSegmentationOutput`]): + Raw outputs of the model. + processed_sizes (`torch.Tensor` of shape `(batch_size, 2)` or `List[Tuple]` of length `batch_size`): + Torch Tensor (or list) containing the size (h, w) of each image of the batch, i.e. the size after data + augmentation but before batching. + target_sizes (`torch.Tensor` of shape `(batch_size, 2)` or `List[Tuple]` of length `batch_size`, *optional*): + Torch Tensor (or list) corresponding to the requested final size `(height, width)` of each prediction. + If left to None, it will default to the `processed_sizes`. + is_thing_map (`torch.Tensor` of shape `(batch_size, 2)`, *optional*): + Dictionary mapping class indices to either True or False, depending on whether or not they are a thing. + If not set, defaults to the `is_thing_map` of COCO panoptic. + threshold (`float`, *optional*, defaults to 0.85): + Threshold to use to filter out queries. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing a PNG string and segments_info values for + an image in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process_panoptic is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_panoptic_segmentation`.", + ) + if target_sizes is None: + target_sizes = processed_sizes + if len(processed_sizes) != len(target_sizes): + raise ValueError("Make sure to pass in as many processed_sizes as target_sizes") + + if is_thing_map is None: + # default to is_thing_map of COCO panoptic + is_thing_map = {i: i <= 90 for i in range(201)} + + out_logits, raw_masks, raw_boxes = outputs.logits, outputs.pred_masks, outputs.pred_boxes + if not len(out_logits) == len(raw_masks) == len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits and masks" + ) + empty_label = out_logits.shape[-1] - 1 + preds = [] + + def to_tuple(tup): + if isinstance(tup, tuple): + return tup + return tuple(tup.cpu().tolist()) + + for cur_logits, cur_masks, cur_boxes, size, target_size in zip( + out_logits, raw_masks, raw_boxes, processed_sizes, target_sizes + ): + # we filter empty queries and detection below threshold + cur_scores, cur_labels = cur_logits.softmax(-1).max(-1) + keep = cur_labels.ne(empty_label) & (cur_scores > threshold) + cur_scores = cur_scores[keep] + cur_labels = cur_labels[keep] + cur_masks = cur_masks[keep] + cur_masks = nn.functional.interpolate(cur_masks[:, None], to_tuple(size), mode="bilinear").squeeze(1) + cur_boxes = center_to_corners_format(cur_boxes[keep]) + + h, w = cur_masks.shape[-2:] + if len(cur_boxes) != len(cur_labels): + raise ValueError("Not as many boxes as there are classes") + + # It may be that we have several predicted masks for the same stuff class. + # In the following, we track the list of masks ids for each stuff class (they are merged later on) + cur_masks = cur_masks.flatten(1) + stuff_equiv_classes = defaultdict(lambda: []) + for k, label in enumerate(cur_labels): + if not is_thing_map[label.item()]: + stuff_equiv_classes[label.item()].append(k) + + def get_ids_area(masks, scores, dedup=False): + # This helper function creates the final panoptic segmentation image + # It also returns the area of the masks that appears on the image + + m_id = masks.transpose(0, 1).softmax(-1) + + if m_id.shape[-1] == 0: + # We didn't detect any mask :( + m_id = torch.zeros((h, w), dtype=torch.long, device=m_id.device) + else: + m_id = m_id.argmax(-1).view(h, w) + + if dedup: + # Merge the masks corresponding to the same stuff class + for equiv in stuff_equiv_classes.values(): + if len(equiv) > 1: + for eq_id in equiv: + m_id.masked_fill_(m_id.eq(eq_id), equiv[0]) + + final_h, final_w = to_tuple(target_size) + + seg_img = PIL.Image.fromarray(id_to_rgb(m_id.view(h, w).cpu().numpy())) + seg_img = seg_img.resize(size=(final_w, final_h), resample=PILImageResampling.NEAREST) + + np_seg_img = torch.ByteTensor(torch.ByteStorage.from_buffer(seg_img.tobytes())) + np_seg_img = np_seg_img.view(final_h, final_w, 3) + np_seg_img = np_seg_img.numpy() + + m_id = torch.from_numpy(rgb_to_id(np_seg_img)) + + area = [] + for i in range(len(scores)): + area.append(m_id.eq(i).sum().item()) + return area, seg_img + + area, seg_img = get_ids_area(cur_masks, cur_scores, dedup=True) + if cur_labels.numel() > 0: + # We know filter empty masks as long as we find some + while True: + filtered_small = torch.as_tensor( + [area[i] <= 4 for i, c in enumerate(cur_labels)], dtype=torch.bool, device=keep.device + ) + if filtered_small.any().item(): + cur_scores = cur_scores[~filtered_small] + cur_labels = cur_labels[~filtered_small] + cur_masks = cur_masks[~filtered_small] + area, seg_img = get_ids_area(cur_masks, cur_scores) + else: + break + + else: + cur_labels = torch.ones(1, dtype=torch.long, device=cur_labels.device) + + segments_info = [] + for i, a in enumerate(area): + cat = cur_labels[i].item() + segments_info.append({"id": i, "isthing": is_thing_map[cat], "category_id": cat, "area": a}) + del cur_labels + + with io.BytesIO() as out: + seg_img.save(out, format="PNG") + predictions = {"png_string": out.getvalue(), "segments_info": segments_info} + preds.append(predictions) + return preds + + # inspired by https://github.com/facebookresearch/detr/blob/master/models/detr.py#L258 + def post_process_object_detection( + self, outputs, threshold: float = 0.5, target_sizes: Union[TensorType, List[Tuple]] = None + ): + """ + Converts the raw output of [`DetrForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, + bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`DetrObjectDetectionOutput`]): + Raw outputs of the model. + threshold (`float`, *optional*): + Score threshold to keep object detection predictions. + target_sizes (`torch.Tensor` or `List[Tuple[int, int]]`, *optional*): + Tensor of shape `(batch_size, 2)` or list of tuples (`Tuple[int, int]`) containing the target size + `(height, width)` of each image in the batch. If unset, predictions will not be resized. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if target_sizes is not None: + if len(out_logits) != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + prob = nn.functional.softmax(out_logits, -1) + scores, labels = prob[..., :-1].max(-1) + + # Convert to [x0, y0, x1, y1] format + boxes = center_to_corners_format(out_bbox) + + # Convert from relative [0, 1] to absolute [0, height] coordinates + if target_sizes is not None: + if isinstance(target_sizes, List): + img_h = torch.Tensor([i[0] for i in target_sizes]) + img_w = torch.Tensor([i[1] for i in target_sizes]) + else: + img_h, img_w = target_sizes.unbind(1) + + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [] + for s, l, b in zip(scores, labels, boxes): + score = s[s > threshold] + label = l[s > threshold] + box = b[s > threshold] + results.append({"scores": score, "labels": label, "boxes": box}) + + return results + + def post_process_semantic_segmentation(self, outputs, target_sizes: List[Tuple[int, int]] = None): + """ + Converts the output of [`DetrForSegmentation`] into semantic segmentation maps. Only supports PyTorch. + + Args: + outputs ([`DetrForSegmentation`]): + Raw outputs of the model. + target_sizes (`List[Tuple[int, int]]`, *optional*): + A list of tuples (`Tuple[int, int]`) containing the target size (height, width) of each image in the + batch. If unset, predictions will not be resized. + Returns: + `List[torch.Tensor]`: + A list of length `batch_size`, where each item is a semantic segmentation map of shape (height, width) + corresponding to the target_sizes entry (if `target_sizes` is specified). Each entry of each + `torch.Tensor` correspond to a semantic class id. + """ + class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1] + masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width] + + # Remove the null class `[..., :-1]` + masks_classes = class_queries_logits.softmax(dim=-1)[..., :-1] + masks_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width] + + # Semantic segmentation logits of shape (batch_size, num_classes, height, width) + segmentation = torch.einsum("bqc, bqhw -> bchw", masks_classes, masks_probs) + batch_size = class_queries_logits.shape[0] + + # Resize logits and compute semantic segmentation maps + if target_sizes is not None: + if batch_size != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + semantic_segmentation = [] + for idx in range(batch_size): + resized_logits = nn.functional.interpolate( + segmentation[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False + ) + semantic_map = resized_logits[0].argmax(dim=0) + semantic_segmentation.append(semantic_map) + else: + semantic_segmentation = segmentation.argmax(dim=1) + semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])] + + return semantic_segmentation + + # inspired by https://github.com/facebookresearch/detr/blob/master/models/segmentation.py#L218 + def post_process_instance_segmentation( + self, + outputs, + threshold: float = 0.5, + mask_threshold: float = 0.5, + overlap_mask_area_threshold: float = 0.8, + target_sizes: Optional[List[Tuple[int, int]]] = None, + return_coco_annotation: Optional[bool] = False, + ) -> List[Dict]: + """ + Converts the output of [`DetrForSegmentation`] into instance segmentation predictions. Only supports PyTorch. + + Args: + outputs ([`DetrForSegmentation`]): + Raw outputs of the model. + threshold (`float`, *optional*, defaults to 0.5): + The probability score threshold to keep predicted instance masks. + mask_threshold (`float`, *optional*, defaults to 0.5): + Threshold to use when turning the predicted masks into binary values. + overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8): + The overlap mask area threshold to merge or discard small disconnected parts within each binary + instance mask. + target_sizes (`List[Tuple]`, *optional*): + List of length (batch_size), where each list item (`Tuple[int, int]]`) corresponds to the requested + final size (height, width) of each prediction. If unset, predictions will not be resized. + return_coco_annotation (`bool`, *optional*): + Defaults to `False`. If set to `True`, segmentation maps are returned in COCO run-length encoding (RLE) + format. + Returns: + `List[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys: + - **segmentation** -- A tensor of shape `(height, width)` where each pixel represents a `segment_id` or + `List[List]` run-length encoding (RLE) of the segmentation map if return_coco_annotation is set to + `True`. Set to `None` if no mask if found above `threshold`. + - **segments_info** -- A dictionary that contains additional information on each segment. + - **id** -- An integer representing the `segment_id`. + - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`. + - **score** -- Prediction score of segment with `segment_id`. + """ + class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1] + masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width] + + batch_size = class_queries_logits.shape[0] + num_labels = class_queries_logits.shape[-1] - 1 + + mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width] + + # Predicted label and score of each query (batch_size, num_queries) + pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1) + + # Loop over items in batch size + results: List[Dict[str, TensorType]] = [] + + for i in range(batch_size): + mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects( + mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels + ) + + # No mask found + if mask_probs_item.shape[0] <= 0: + height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:] + segmentation = torch.zeros((height, width)) - 1 + results.append({"segmentation": segmentation, "segments_info": []}) + continue + + # Get segmentation map and segment information of batch item + target_size = target_sizes[i] if target_sizes is not None else None + segmentation, segments = compute_segments( + mask_probs=mask_probs_item, + pred_scores=pred_scores_item, + pred_labels=pred_labels_item, + mask_threshold=mask_threshold, + overlap_mask_area_threshold=overlap_mask_area_threshold, + label_ids_to_fuse=[], + target_size=target_size, + ) + + # Return segmentation map in run-length encoding (RLE) format + if return_coco_annotation: + segmentation = convert_segmentation_to_rle(segmentation) + + results.append({"segmentation": segmentation, "segments_info": segments}) + return results + + # inspired by https://github.com/facebookresearch/detr/blob/master/models/segmentation.py#L241 + def post_process_panoptic_segmentation( + self, + outputs, + threshold: float = 0.5, + mask_threshold: float = 0.5, + overlap_mask_area_threshold: float = 0.8, + label_ids_to_fuse: Optional[Set[int]] = None, + target_sizes: Optional[List[Tuple[int, int]]] = None, + ) -> List[Dict]: + """ + Converts the output of [`DetrForSegmentation`] into image panoptic segmentation predictions. Only supports + PyTorch. + + Args: + outputs ([`DetrForSegmentation`]): + The outputs from [`DetrForSegmentation`]. + threshold (`float`, *optional*, defaults to 0.5): + The probability score threshold to keep predicted instance masks. + mask_threshold (`float`, *optional*, defaults to 0.5): + Threshold to use when turning the predicted masks into binary values. + overlap_mask_area_threshold (`float`, *optional*, defaults to 0.8): + The overlap mask area threshold to merge or discard small disconnected parts within each binary + instance mask. + label_ids_to_fuse (`Set[int]`, *optional*): + The labels in this state will have all their instances be fused together. For instance we could say + there can only be one sky in an image, but several persons, so the label ID for sky would be in that + set, but not the one for person. + target_sizes (`List[Tuple]`, *optional*): + List of length (batch_size), where each list item (`Tuple[int, int]]`) corresponds to the requested + final size (height, width) of each prediction in batch. If unset, predictions will not be resized. + Returns: + `List[Dict]`: A list of dictionaries, one per image, each dictionary containing two keys: + - **segmentation** -- a tensor of shape `(height, width)` where each pixel represents a `segment_id` or + `None` if no mask if found above `threshold`. If `target_sizes` is specified, segmentation is resized to + the corresponding `target_sizes` entry. + - **segments_info** -- A dictionary that contains additional information on each segment. + - **id** -- an integer representing the `segment_id`. + - **label_id** -- An integer representing the label / semantic class id corresponding to `segment_id`. + - **was_fused** -- a boolean, `True` if `label_id` was in `label_ids_to_fuse`, `False` otherwise. + Multiple instances of the same class / label were fused and assigned a single `segment_id`. + - **score** -- Prediction score of segment with `segment_id`. + """ + + if label_ids_to_fuse is None: + logger.warning_once("`label_ids_to_fuse` unset. No instance will be fused.") + label_ids_to_fuse = set() + + class_queries_logits = outputs.logits # [batch_size, num_queries, num_classes+1] + masks_queries_logits = outputs.pred_masks # [batch_size, num_queries, height, width] + + batch_size = class_queries_logits.shape[0] + num_labels = class_queries_logits.shape[-1] - 1 + + mask_probs = masks_queries_logits.sigmoid() # [batch_size, num_queries, height, width] + + # Predicted label and score of each query (batch_size, num_queries) + pred_scores, pred_labels = nn.functional.softmax(class_queries_logits, dim=-1).max(-1) + + # Loop over items in batch size + results: List[Dict[str, TensorType]] = [] + + for i in range(batch_size): + mask_probs_item, pred_scores_item, pred_labels_item = remove_low_and_no_objects( + mask_probs[i], pred_scores[i], pred_labels[i], threshold, num_labels + ) + + # No mask found + if mask_probs_item.shape[0] <= 0: + height, width = target_sizes[i] if target_sizes is not None else mask_probs_item.shape[1:] + segmentation = torch.zeros((height, width)) - 1 + results.append({"segmentation": segmentation, "segments_info": []}) + continue + + # Get segmentation map and segment information of batch item + target_size = target_sizes[i] if target_sizes is not None else None + segmentation, segments = compute_segments( + mask_probs=mask_probs_item, + pred_scores=pred_scores_item, + pred_labels=pred_labels_item, + mask_threshold=mask_threshold, + overlap_mask_area_threshold=overlap_mask_area_threshold, + label_ids_to_fuse=label_ids_to_fuse, + target_size=target_size, + ) + + results.append({"segmentation": segmentation, "segments_info": segments}) + return results diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/modeling_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/modeling_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..bd4eae128394e287e8bebe5b9babc5c03f6be983 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/detr/modeling_detr.py @@ -0,0 +1,2344 @@ +# coding=utf-8 +# Copyright 2021 Facebook AI Research The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DETR model.""" + + +import math +import random +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple + +import torch +from torch import Tensor, nn + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithCrossAttentions, Seq2SeqModelOutput +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + is_scipy_available, + is_timm_available, + is_vision_available, + logging, + replace_return_docstrings, + requires_backends, +) +from ..auto import AutoBackbone +from .configuration_detr import DetrConfig + + +if is_scipy_available(): + from scipy.optimize import linear_sum_assignment + +if is_timm_available(): + from timm import create_model + +if is_vision_available(): + from transformers.image_transforms import center_to_corners_format + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DetrConfig" +_CHECKPOINT_FOR_DOC = "facebook/detr-resnet-50" + +DETR_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/detr-resnet-50", + # See all DETR models at https://huggingface.co/models?filter=detr +] + + +@dataclass +class DetrDecoderOutput(BaseModelOutputWithCrossAttentions): + """ + Base class for outputs of the DETR decoder. This class adds one attribute to BaseModelOutputWithCrossAttentions, + namely an optional stack of intermediate decoder activations, i.e. the output of each decoder layer, each of them + gone through a layernorm. This is useful when training the model with auxiliary decoding losses. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer + plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, num_queries, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`): + Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a + layernorm. + """ + + intermediate_hidden_states: Optional[torch.FloatTensor] = None + + +@dataclass +class DetrModelOutput(Seq2SeqModelOutput): + """ + Base class for outputs of the DETR encoder-decoder model. This class adds one attribute to Seq2SeqModelOutput, + namely an optional stack of intermediate decoder activations, i.e. the output of each decoder layer, each of them + gone through a layernorm. This is useful when training the model with auxiliary decoding losses. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the decoder at the output of each + layer plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the encoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + intermediate_hidden_states (`torch.FloatTensor` of shape `(config.decoder_layers, batch_size, sequence_length, hidden_size)`, *optional*, returned when `config.auxiliary_loss=True`): + Intermediate decoder activations, i.e. the output of each decoder layer, each of them gone through a + layernorm. + """ + + intermediate_hidden_states: Optional[torch.FloatTensor] = None + + +@dataclass +class DetrObjectDetectionOutput(ModelOutput): + """ + Output type of [`DetrForObjectDetection`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)): + Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a + bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized + scale-invariant IoU loss. + loss_dict (`Dict`, *optional*): + A dictionary containing the individual losses. Useful for logging. + logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`): + Classification logits (including no-object) for all queries. + pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These + values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding + possible padding). You can use [`~DetrImageProcessor.post_process_object_detection`] to retrieve the + unnormalized bounding boxes. + auxiliary_outputs (`list[Dict]`, *optional*): + Optional, only returned when auxilary losses are activated (i.e. `config.auxiliary_loss` is set to `True`) + and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and + `pred_boxes`) for each decoder layer. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the decoder at the output of each + layer plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the encoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + """ + + loss: Optional[torch.FloatTensor] = None + loss_dict: Optional[Dict] = None + logits: torch.FloatTensor = None + pred_boxes: torch.FloatTensor = None + auxiliary_outputs: Optional[List[Dict]] = None + last_hidden_state: Optional[torch.FloatTensor] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class DetrSegmentationOutput(ModelOutput): + """ + Output type of [`DetrForSegmentation`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)): + Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a + bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized + scale-invariant IoU loss. + loss_dict (`Dict`, *optional*): + A dictionary containing the individual losses. Useful for logging. + logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`): + Classification logits (including no-object) for all queries. + pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These + values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding + possible padding). You can use [`~DetrImageProcessor.post_process_object_detection`] to retrieve the + unnormalized bounding boxes. + pred_masks (`torch.FloatTensor` of shape `(batch_size, num_queries, height/4, width/4)`): + Segmentation masks logits for all queries. See also + [`~DetrImageProcessor.post_process_semantic_segmentation`] or + [`~DetrImageProcessor.post_process_instance_segmentation`] + [`~DetrImageProcessor.post_process_panoptic_segmentation`] to evaluate semantic, instance and panoptic + segmentation masks respectively. + auxiliary_outputs (`list[Dict]`, *optional*): + Optional, only returned when auxiliary losses are activated (i.e. `config.auxiliary_loss` is set to `True`) + and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and + `pred_boxes`) for each decoder layer. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the decoder at the output of each + layer plus the initial embedding outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the decoder's cross-attention layer, after the attention softmax, + used to compute the weighted average in the cross-attention heads. + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the encoder at the output of each + layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights of the encoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + """ + + loss: Optional[torch.FloatTensor] = None + loss_dict: Optional[Dict] = None + logits: torch.FloatTensor = None + pred_boxes: torch.FloatTensor = None + pred_masks: torch.FloatTensor = None + auxiliary_outputs: Optional[List[Dict]] = None + last_hidden_state: Optional[torch.FloatTensor] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +# BELOW: utilities copied from +# https://github.com/facebookresearch/detr/blob/master/backbone.py +class DetrFrozenBatchNorm2d(nn.Module): + """ + BatchNorm2d where the batch statistics and the affine parameters are fixed. + + Copy-paste from torchvision.misc.ops with added eps before rqsrt, without which any other models than + torchvision.models.resnet[18,34,50,101] produce nans. + """ + + def __init__(self, n): + super().__init__() + self.register_buffer("weight", torch.ones(n)) + self.register_buffer("bias", torch.zeros(n)) + self.register_buffer("running_mean", torch.zeros(n)) + self.register_buffer("running_var", torch.ones(n)) + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + num_batches_tracked_key = prefix + "num_batches_tracked" + if num_batches_tracked_key in state_dict: + del state_dict[num_batches_tracked_key] + + super()._load_from_state_dict( + state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ) + + def forward(self, x): + # move reshapes to the beginning + # to make it user-friendly + weight = self.weight.reshape(1, -1, 1, 1) + bias = self.bias.reshape(1, -1, 1, 1) + running_var = self.running_var.reshape(1, -1, 1, 1) + running_mean = self.running_mean.reshape(1, -1, 1, 1) + epsilon = 1e-5 + scale = weight * (running_var + epsilon).rsqrt() + bias = bias - running_mean * scale + return x * scale + bias + + +def replace_batch_norm(m, name=""): + for attr_str in dir(m): + target_attr = getattr(m, attr_str) + if isinstance(target_attr, nn.BatchNorm2d): + frozen = DetrFrozenBatchNorm2d(target_attr.num_features) + bn = getattr(m, attr_str) + frozen.weight.data.copy_(bn.weight) + frozen.bias.data.copy_(bn.bias) + frozen.running_mean.data.copy_(bn.running_mean) + frozen.running_var.data.copy_(bn.running_var) + setattr(m, attr_str, frozen) + for n, ch in m.named_children(): + replace_batch_norm(ch, n) + + +class DetrConvEncoder(nn.Module): + """ + Convolutional backbone, using either the AutoBackbone API or one from the timm library. + + nn.BatchNorm2d layers are replaced by DetrFrozenBatchNorm2d as defined above. + + """ + + def __init__(self, config): + super().__init__() + + self.config = config + + if config.use_timm_backbone: + requires_backends(self, ["timm"]) + kwargs = {} + if config.dilation: + kwargs["output_stride"] = 16 + backbone = create_model( + config.backbone, + pretrained=config.use_pretrained_backbone, + features_only=True, + out_indices=(1, 2, 3, 4), + in_chans=config.num_channels, + **kwargs, + ) + else: + backbone = AutoBackbone.from_config(config.backbone_config) + + # replace batch norm by frozen batch norm + with torch.no_grad(): + replace_batch_norm(backbone) + self.model = backbone + self.intermediate_channel_sizes = ( + self.model.feature_info.channels() if config.use_timm_backbone else self.model.channels + ) + + backbone_model_type = config.backbone if config.use_timm_backbone else config.backbone_config.model_type + if "resnet" in backbone_model_type: + for name, parameter in self.model.named_parameters(): + if config.use_timm_backbone: + if "layer2" not in name and "layer3" not in name and "layer4" not in name: + parameter.requires_grad_(False) + else: + if "stage.1" not in name and "stage.2" not in name and "stage.3" not in name: + parameter.requires_grad_(False) + + def forward(self, pixel_values: torch.Tensor, pixel_mask: torch.Tensor): + # send pixel_values through the model to get list of feature maps + features = self.model(pixel_values) if self.config.use_timm_backbone else self.model(pixel_values).feature_maps + + out = [] + for feature_map in features: + # downsample pixel_mask to match shape of corresponding feature_map + mask = nn.functional.interpolate(pixel_mask[None].float(), size=feature_map.shape[-2:]).to(torch.bool)[0] + out.append((feature_map, mask)) + return out + + +class DetrConvModel(nn.Module): + """ + This module adds 2D position embeddings to all intermediate feature maps of the convolutional encoder. + """ + + def __init__(self, conv_encoder, position_embedding): + super().__init__() + self.conv_encoder = conv_encoder + self.position_embedding = position_embedding + + def forward(self, pixel_values, pixel_mask): + # send pixel_values and pixel_mask through backbone to get list of (feature_map, pixel_mask) tuples + out = self.conv_encoder(pixel_values, pixel_mask) + pos = [] + for feature_map, mask in out: + # position encoding + pos.append(self.position_embedding(feature_map, mask).to(feature_map.dtype)) + + return out, pos + + +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, target_len: Optional[int] = None): + """ + Expands attention_mask from `[batch_size, seq_len]` to `[batch_size, 1, target_seq_len, source_seq_len]`. + """ + batch_size, source_len = mask.size() + target_len = target_len if target_len is not None else source_len + + expanded_mask = mask[:, None, None, :].expand(batch_size, 1, target_len, source_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.bool(), torch.finfo(dtype).min) + + +class DetrSinePositionEmbedding(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one used by the Attention is all you + need paper, generalized to work on images. + """ + + def __init__(self, embedding_dim=64, temperature=10000, normalize=False, scale=None): + super().__init__() + self.embedding_dim = embedding_dim + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + def forward(self, pixel_values, pixel_mask): + if pixel_mask is None: + raise ValueError("No pixel mask provided") + y_embed = pixel_mask.cumsum(1, dtype=torch.float32) + x_embed = pixel_mask.cumsum(2, dtype=torch.float32) + if self.normalize: + y_embed = y_embed / (y_embed[:, -1:, :] + 1e-6) * self.scale + x_embed = x_embed / (x_embed[:, :, -1:] + 1e-6) * self.scale + + dim_t = torch.arange(self.embedding_dim, dtype=torch.float32, device=pixel_values.device) + dim_t = self.temperature ** (2 * torch.div(dim_t, 2, rounding_mode="floor") / self.embedding_dim) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + return pos + + +class DetrLearnedPositionEmbedding(nn.Module): + """ + This module learns positional embeddings up to a fixed maximum size. + """ + + def __init__(self, embedding_dim=256): + super().__init__() + self.row_embeddings = nn.Embedding(50, embedding_dim) + self.column_embeddings = nn.Embedding(50, embedding_dim) + + def forward(self, pixel_values, pixel_mask=None): + height, width = pixel_values.shape[-2:] + width_values = torch.arange(width, device=pixel_values.device) + height_values = torch.arange(height, device=pixel_values.device) + x_emb = self.column_embeddings(width_values) + y_emb = self.row_embeddings(height_values) + pos = torch.cat([x_emb.unsqueeze(0).repeat(height, 1, 1), y_emb.unsqueeze(1).repeat(1, width, 1)], dim=-1) + pos = pos.permute(2, 0, 1) + pos = pos.unsqueeze(0) + pos = pos.repeat(pixel_values.shape[0], 1, 1, 1) + return pos + + +def build_position_encoding(config): + n_steps = config.d_model // 2 + if config.position_embedding_type == "sine": + # TODO find a better way of exposing other arguments + position_embedding = DetrSinePositionEmbedding(n_steps, normalize=True) + elif config.position_embedding_type == "learned": + position_embedding = DetrLearnedPositionEmbedding(n_steps) + else: + raise ValueError(f"Not supported {config.position_embedding_type}") + + return position_embedding + + +class DetrAttention(nn.Module): + """ + Multi-headed attention from 'Attention Is All You Need' paper. + + Here, we add position embeddings to the queries and keys (as explained in the DETR paper). + """ + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + if self.head_dim * num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, batch_size: int): + return tensor.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def with_pos_embed(self, tensor: torch.Tensor, position_embeddings: Optional[Tensor]): + return tensor if position_embeddings is None else tensor + position_embeddings + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_embeddings: Optional[torch.Tensor] = None, + key_value_states: Optional[torch.Tensor] = None, + key_value_position_embeddings: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + batch_size, target_len, embed_dim = hidden_states.size() + + # add position embeddings to the hidden states before projecting to queries and keys + if position_embeddings is not None: + hidden_states_original = hidden_states + hidden_states = self.with_pos_embed(hidden_states, position_embeddings) + + # add key-value position embeddings to the key value states + if key_value_position_embeddings is not None: + key_value_states_original = key_value_states + key_value_states = self.with_pos_embed(key_value_states, key_value_position_embeddings) + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, batch_size) + value_states = self._shape(self.v_proj(key_value_states_original), -1, batch_size) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, batch_size) + value_states = self._shape(self.v_proj(hidden_states_original), -1, batch_size) + + proj_shape = (batch_size * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, target_len, batch_size).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + source_len = key_states.size(1) + + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (batch_size * self.num_heads, target_len, source_len): + raise ValueError( + f"Attention weights should be of size {(batch_size * self.num_heads, target_len, source_len)}, but is" + f" {attn_weights.size()}" + ) + + if attention_mask is not None: + if attention_mask.size() != (batch_size, 1, target_len, source_len): + raise ValueError( + f"Attention mask should be of size {(batch_size, 1, target_len, source_len)}, but is" + f" {attention_mask.size()}" + ) + attn_weights = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attention_mask + attn_weights = attn_weights.view(batch_size * self.num_heads, target_len, source_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(batch_size, self.num_heads, target_len, source_len) + attn_weights = attn_weights_reshaped.view(batch_size * self.num_heads, target_len, source_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (batch_size * self.num_heads, target_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(batch_size, self.num_heads, target_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(batch_size, self.num_heads, target_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + attn_output = attn_output.reshape(batch_size, target_len, embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped + + +class DetrEncoderLayer(nn.Module): + def __init__(self, config: DetrConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = DetrAttention( + embed_dim=self.embed_dim, + num_heads=config.encoder_attention_heads, + dropout=config.attention_dropout, + ) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + position_embeddings: torch.Tensor = None, + output_attentions: bool = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative + values. + position_embeddings (`torch.FloatTensor`, *optional*): position embeddings, to be added to hidden_states. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + if self.training: + if torch.isinf(hidden_states).any() or torch.isnan(hidden_states).any(): + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class DetrDecoderLayer(nn.Module): + def __init__(self, config: DetrConfig): + super().__init__() + self.embed_dim = config.d_model + + self.self_attn = DetrAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.encoder_attn = DetrAttention( + self.embed_dim, + config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim) + self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_embeddings: Optional[torch.Tensor] = None, + query_position_embeddings: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + ): + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative + values. + position_embeddings (`torch.FloatTensor`, *optional*): + position embeddings that are added to the queries and keys + in the cross-attention layer. + query_position_embeddings (`torch.FloatTensor`, *optional*): + position embeddings that are added to the queries and keys + in the self-attention layer. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(seq_len, batch, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, target_len, source_len)` where padding elements are indicated by very large negative + values. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, + position_embeddings=query_position_embeddings, + attention_mask=attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Cross-Attention Block + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + position_embeddings=query_position_embeddings, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + key_value_position_embeddings=position_embeddings, + output_attentions=output_attentions, + ) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # Fully Connected + residual = hidden_states + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +class DetrClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, input_dim: int, inner_dim: int, num_classes: int, pooler_dropout: float): + super().__init__() + self.dense = nn.Linear(input_dim, inner_dim) + self.dropout = nn.Dropout(p=pooler_dropout) + self.out_proj = nn.Linear(inner_dim, num_classes) + + def forward(self, hidden_states: torch.Tensor): + hidden_states = self.dropout(hidden_states) + hidden_states = self.dense(hidden_states) + hidden_states = torch.tanh(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +class DetrPreTrainedModel(PreTrainedModel): + config_class = DetrConfig + base_model_prefix = "model" + main_input_name = "pixel_values" + + def _init_weights(self, module): + std = self.config.init_std + xavier_std = self.config.init_xavier_std + + if isinstance(module, DetrMHAttentionMap): + nn.init.zeros_(module.k_linear.bias) + nn.init.zeros_(module.q_linear.bias) + nn.init.xavier_uniform_(module.k_linear.weight, gain=xavier_std) + nn.init.xavier_uniform_(module.q_linear.weight, gain=xavier_std) + elif isinstance(module, DetrLearnedPositionEmbedding): + nn.init.uniform_(module.row_embeddings.weight) + nn.init.uniform_(module.column_embeddings.weight) + if isinstance(module, (nn.Linear, nn.Conv2d, nn.BatchNorm2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DetrDecoder): + module.gradient_checkpointing = value + + +DETR_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`DetrConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DETR_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. + + Pixel values can be obtained using [`AutoImageProcessor`]. See [`DetrImageProcessor.__call__`] for details. + + pixel_mask (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*): + Mask to avoid performing attention on padding pixel values. Mask values selected in `[0, 1]`: + + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + + [What are attention masks?](../glossary#attention-mask) + + decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, num_queries)`, *optional*): + Not used by default. Can be used to mask object queries. + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you + can choose to directly pass a flattened representation of an image. + decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`, *optional*): + Optionally, instead of initializing the queries with a tensor of zeros, you can choose to directly pass an + embedded representation. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class DetrEncoder(DetrPreTrainedModel): + """ + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`DetrEncoderLayer`]. + + The encoder updates the flattened feature map through multiple self-attention layers. + + Small tweak for DETR: + + - position_embeddings are added to the forward pass. + + Args: + config: DetrConfig + """ + + def __init__(self, config: DetrConfig): + super().__init__(config) + + self.dropout = config.dropout + self.layerdrop = config.encoder_layerdrop + + self.layers = nn.ModuleList([DetrEncoderLayer(config) for _ in range(config.encoder_layers)]) + + # in the original DETR, no layernorm is used at the end of the encoder, as "normalize_before" is set to False by default + + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + inputs_embeds=None, + attention_mask=None, + position_embeddings=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Flattened feature map (output of the backbone + projection layer) that is passed to the encoder. + + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding pixel features. Mask values selected in `[0, 1]`: + + - 1 for pixel features that are real (i.e. **not masked**), + - 0 for pixel features that are padding (i.e. **masked**). + + [What are attention masks?](../glossary#attention-mask) + + position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Position embeddings that are added to the queries and keys in each self-attention layer. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + hidden_states = inputs_embeds + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + # expand attention_mask + if attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len] + attention_mask = _expand_mask(attention_mask, inputs_embeds.dtype) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + for i, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): # skip the layer + layer_outputs = (None, None) + else: + # we add position_embeddings as extra input to the encoder_layer + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class DetrDecoder(DetrPreTrainedModel): + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`DetrDecoderLayer`]. + + The decoder updates the query embeddings through multiple self-attention and cross-attention layers. + + Some small tweaks for DETR: + + - position_embeddings and query_position_embeddings are added to the forward pass. + - if self.config.auxiliary_loss is set to True, also returns a stack of activations from all decoding layers. + + Args: + config: DetrConfig + """ + + def __init__(self, config: DetrConfig): + super().__init__(config) + self.dropout = config.dropout + self.layerdrop = config.decoder_layerdrop + + self.layers = nn.ModuleList([DetrDecoderLayer(config) for _ in range(config.decoder_layers)]) + # in DETR, the decoder uses layernorm after the last decoder layer output + self.layernorm = nn.LayerNorm(config.d_model) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + inputs_embeds=None, + attention_mask=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + position_embeddings=None, + query_position_embeddings=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + The query embeddings that are passed into the decoder. + + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on certain queries. Mask values selected in `[0, 1]`: + + - 1 for queries that are **not masked**, + - 0 for queries that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding pixel_values of the encoder. Mask values selected + in `[0, 1]`: + + - 1 for pixels that are real (i.e. **not masked**), + - 0 for pixels that are padding (i.e. **masked**). + + position_embeddings (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Position embeddings that are added to the queries and keys in each cross-attention layer. + query_position_embeddings (`torch.FloatTensor` of shape `(batch_size, num_queries, hidden_size)`): + , *optional*): Position embeddings that are added to the queries and keys in each self-attention layer. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if inputs_embeds is not None: + hidden_states = inputs_embeds + input_shape = inputs_embeds.size()[:-1] + + combined_attention_mask = None + + if attention_mask is not None and combined_attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len] + combined_attention_mask = combined_attention_mask + _expand_mask( + attention_mask, inputs_embeds.dtype, target_len=input_shape[-1] + ) + + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, target_seq_len, source_seq_len] + encoder_attention_mask = _expand_mask( + encoder_attention_mask, inputs_embeds.dtype, target_len=input_shape[-1] + ) + + # optional intermediate hidden states + intermediate = () if self.config.auxiliary_loss else None + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): + continue + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + combined_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=combined_attention_mask, + position_embeddings=position_embeddings, + query_position_embeddings=query_position_embeddings, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if self.config.auxiliary_loss: + hidden_states = self.layernorm(hidden_states) + intermediate += (hidden_states,) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # finally, apply layernorm + hidden_states = self.layernorm(hidden_states) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + # stack intermediate decoder activations + if self.config.auxiliary_loss: + intermediate = torch.stack(intermediate) + + if not return_dict: + return tuple( + v + for v in [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions, intermediate] + if v is not None + ) + return DetrDecoderOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + intermediate_hidden_states=intermediate, + ) + + +@add_start_docstrings( + """ + The bare DETR Model (consisting of a backbone and encoder-decoder Transformer) outputting raw hidden-states without + any specific head on top. + """, + DETR_START_DOCSTRING, +) +class DetrModel(DetrPreTrainedModel): + def __init__(self, config: DetrConfig): + super().__init__(config) + + # Create backbone + positional encoding + backbone = DetrConvEncoder(config) + position_embeddings = build_position_encoding(config) + self.backbone = DetrConvModel(backbone, position_embeddings) + + # Create projection layer + self.input_projection = nn.Conv2d(backbone.intermediate_channel_sizes[-1], config.d_model, kernel_size=1) + + self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model) + + self.encoder = DetrEncoder(config) + self.decoder = DetrDecoder(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + def freeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(False) + + def unfreeze_backbone(self): + for name, param in self.backbone.conv_encoder.model.named_parameters(): + param.requires_grad_(True) + + @add_start_docstrings_to_model_forward(DETR_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DetrModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DetrModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50") + >>> model = DetrModel.from_pretrained("facebook/detr-resnet-50") + + >>> # prepare image for the model + >>> inputs = image_processor(images=image, return_tensors="pt") + + >>> # forward pass + >>> outputs = model(**inputs) + + >>> # the last hidden states are the final query embeddings of the Transformer decoder + >>> # these are of shape (batch_size, num_queries, hidden_size) + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + [1, 100, 256] + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_channels, height, width = pixel_values.shape + device = pixel_values.device + + if pixel_mask is None: + pixel_mask = torch.ones(((batch_size, height, width)), device=device) + + # First, sent pixel_values + pixel_mask through Backbone to obtain the features + # pixel_values should be of shape (batch_size, num_channels, height, width) + # pixel_mask should be of shape (batch_size, height, width) + features, position_embeddings_list = self.backbone(pixel_values, pixel_mask) + + # get final feature map and downsampled mask + feature_map, mask = features[-1] + + if mask is None: + raise ValueError("Backbone does not return downsampled pixel mask") + + # Second, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default) + projected_feature_map = self.input_projection(feature_map) + + # Third, flatten the feature map + position embeddings of shape NxCxHxW to NxCxHW, and permute it to NxHWxC + # In other words, turn their shape into (batch_size, sequence_length, hidden_size) + flattened_features = projected_feature_map.flatten(2).permute(0, 2, 1) + position_embeddings = position_embeddings_list[-1].flatten(2).permute(0, 2, 1) + + flattened_mask = mask.flatten(1) + + # Fourth, sent flattened_features + flattened_mask + position embeddings through encoder + # flattened_features is a Tensor of shape (batch_size, heigth*width, hidden_size) + # flattened_mask is a Tensor of shape (batch_size, heigth*width) + if encoder_outputs is None: + encoder_outputs = self.encoder( + inputs_embeds=flattened_features, + attention_mask=flattened_mask, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # Fifth, sent query embeddings + position embeddings through the decoder (which is conditioned on the encoder output) + query_position_embeddings = self.query_position_embeddings.weight.unsqueeze(0).repeat(batch_size, 1, 1) + queries = torch.zeros_like(query_position_embeddings) + + # decoder outputs consists of (dec_features, dec_hidden, dec_attn) + decoder_outputs = self.decoder( + inputs_embeds=queries, + attention_mask=None, + position_embeddings=position_embeddings, + query_position_embeddings=query_position_embeddings, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=flattened_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return DetrModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + intermediate_hidden_states=decoder_outputs.intermediate_hidden_states, + ) + + +@add_start_docstrings( + """ + DETR Model (consisting of a backbone and encoder-decoder Transformer) with object detection heads on top, for tasks + such as COCO detection. + """, + DETR_START_DOCSTRING, +) +class DetrForObjectDetection(DetrPreTrainedModel): + def __init__(self, config: DetrConfig): + super().__init__(config) + + # DETR encoder-decoder model + self.model = DetrModel(config) + + # Object detection heads + self.class_labels_classifier = nn.Linear( + config.d_model, config.num_labels + 1 + ) # We add one for the "no object" class + self.bbox_predictor = DetrMLPPredictionHead( + input_dim=config.d_model, hidden_dim=config.d_model, output_dim=4, num_layers=3 + ) + + # Initialize weights and apply final processing + self.post_init() + + # taken from https://github.com/facebookresearch/detr/blob/master/models/detr.py + @torch.jit.unused + def _set_aux_loss(self, outputs_class, outputs_coord): + # this is a workaround to make torchscript happy, as torchscript + # doesn't support dictionary with non-homogeneous values, such + # as a dict having both a Tensor and a list. + return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])] + + @add_start_docstrings_to_model_forward(DETR_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DetrObjectDetectionOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + labels=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + labels (`List[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the + following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch + respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes + in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`. + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, DetrForObjectDetection + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50") + >>> model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + + >>> # convert outputs (bounding boxes and class logits) to COCO API + >>> target_sizes = torch.tensor([image.size[::-1]]) + >>> results = image_processor.post_process_object_detection(outputs, threshold=0.9, target_sizes=target_sizes)[ + ... 0 + ... ] + + >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]): + ... box = [round(i, 2) for i in box.tolist()] + ... print( + ... f"Detected {model.config.id2label[label.item()]} with confidence " + ... f"{round(score.item(), 3)} at location {box}" + ... ) + Detected remote with confidence 0.998 at location [40.16, 70.81, 175.55, 117.98] + Detected remote with confidence 0.996 at location [333.24, 72.55, 368.33, 187.66] + Detected couch with confidence 0.995 at location [-0.02, 1.15, 639.73, 473.76] + Detected cat with confidence 0.999 at location [13.24, 52.05, 314.02, 470.93] + Detected cat with confidence 0.999 at location [345.4, 23.85, 640.37, 368.72] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # First, sent images through DETR base model to obtain encoder + decoder outputs + outputs = self.model( + pixel_values, + pixel_mask=pixel_mask, + decoder_attention_mask=decoder_attention_mask, + encoder_outputs=encoder_outputs, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + # class logits + predicted bounding boxes + logits = self.class_labels_classifier(sequence_output) + pred_boxes = self.bbox_predictor(sequence_output).sigmoid() + + loss, loss_dict, auxiliary_outputs = None, None, None + if labels is not None: + # First: create the matcher + matcher = DetrHungarianMatcher( + class_cost=self.config.class_cost, bbox_cost=self.config.bbox_cost, giou_cost=self.config.giou_cost + ) + # Second: create the criterion + losses = ["labels", "boxes", "cardinality"] + criterion = DetrLoss( + matcher=matcher, + num_classes=self.config.num_labels, + eos_coef=self.config.eos_coefficient, + losses=losses, + ) + criterion.to(self.device) + # Third: compute the losses, based on outputs and labels + outputs_loss = {} + outputs_loss["logits"] = logits + outputs_loss["pred_boxes"] = pred_boxes + if self.config.auxiliary_loss: + intermediate = outputs.intermediate_hidden_states if return_dict else outputs[4] + outputs_class = self.class_labels_classifier(intermediate) + outputs_coord = self.bbox_predictor(intermediate).sigmoid() + auxiliary_outputs = self._set_aux_loss(outputs_class, outputs_coord) + outputs_loss["auxiliary_outputs"] = auxiliary_outputs + + loss_dict = criterion(outputs_loss, labels) + # Fourth: compute total loss, as a weighted sum of the various losses + weight_dict = {"loss_ce": 1, "loss_bbox": self.config.bbox_loss_coefficient} + weight_dict["loss_giou"] = self.config.giou_loss_coefficient + if self.config.auxiliary_loss: + aux_weight_dict = {} + for i in range(self.config.decoder_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + loss = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) + + if not return_dict: + if auxiliary_outputs is not None: + output = (logits, pred_boxes) + auxiliary_outputs + outputs + else: + output = (logits, pred_boxes) + outputs + return ((loss, loss_dict) + output) if loss is not None else output + + return DetrObjectDetectionOutput( + loss=loss, + loss_dict=loss_dict, + logits=logits, + pred_boxes=pred_boxes, + auxiliary_outputs=auxiliary_outputs, + last_hidden_state=outputs.last_hidden_state, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings( + """ + DETR Model (consisting of a backbone and encoder-decoder Transformer) with a segmentation head on top, for tasks + such as COCO panoptic. + + """, + DETR_START_DOCSTRING, +) +class DetrForSegmentation(DetrPreTrainedModel): + def __init__(self, config: DetrConfig): + super().__init__(config) + + # object detection model + self.detr = DetrForObjectDetection(config) + + # segmentation head + hidden_size, number_of_heads = config.d_model, config.encoder_attention_heads + intermediate_channel_sizes = self.detr.model.backbone.conv_encoder.intermediate_channel_sizes + + self.mask_head = DetrMaskHeadSmallConv( + hidden_size + number_of_heads, intermediate_channel_sizes[::-1][-3:], hidden_size + ) + + self.bbox_attention = DetrMHAttentionMap( + hidden_size, hidden_size, number_of_heads, dropout=0.0, std=config.init_xavier_std + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DETR_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DetrSegmentationOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values, + pixel_mask=None, + decoder_attention_mask=None, + encoder_outputs=None, + inputs_embeds=None, + decoder_inputs_embeds=None, + labels=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + labels (`List[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss, DICE/F-1 loss and Focal loss. List of dicts, each + dictionary containing at least the following 3 keys: 'class_labels', 'boxes' and 'masks' (the class labels, + bounding boxes and segmentation masks of an image in the batch respectively). The class labels themselves + should be a `torch.LongTensor` of len `(number of bounding boxes in the image,)`, the boxes a + `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)` and the masks a + `torch.FloatTensor` of shape `(number of bounding boxes in the image, height, width)`. + + Returns: + + Examples: + + ```python + >>> import io + >>> import requests + >>> from PIL import Image + >>> import torch + >>> import numpy + + >>> from transformers import AutoImageProcessor, DetrForSegmentation + >>> from transformers.image_transforms import rgb_to_id + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50-panoptic") + >>> model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50-panoptic") + + >>> # prepare image for the model + >>> inputs = image_processor(images=image, return_tensors="pt") + + >>> # forward pass + >>> outputs = model(**inputs) + + >>> # Use the `post_process_panoptic_segmentation` method of the `image_processor` to retrieve post-processed panoptic segmentation maps + >>> # Segmentation results are returned as a list of dictionaries + >>> result = image_processor.post_process_panoptic_segmentation(outputs, target_sizes=[(300, 500)]) + + >>> # A tensor of shape (height, width) where each value denotes a segment id, filled with -1 if no segment is found + >>> panoptic_seg = result[0]["segmentation"] + >>> # Get prediction score and segment_id to class_id mapping of each segment + >>> panoptic_segments_info = result[0]["segments_info"] + ```""" + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_channels, height, width = pixel_values.shape + device = pixel_values.device + + if pixel_mask is None: + pixel_mask = torch.ones((batch_size, height, width), device=device) + + # First, get list of feature maps and position embeddings + features, position_embeddings_list = self.detr.model.backbone(pixel_values, pixel_mask=pixel_mask) + + # Second, apply 1x1 convolution to reduce the channel dimension to d_model (256 by default) + feature_map, mask = features[-1] + batch_size, num_channels, height, width = feature_map.shape + projected_feature_map = self.detr.model.input_projection(feature_map) + + # Third, flatten the feature map + position embeddings of shape NxCxHxW to NxCxHW, and permute it to NxHWxC + # In other words, turn their shape into (batch_size, sequence_length, hidden_size) + flattened_features = projected_feature_map.flatten(2).permute(0, 2, 1) + position_embeddings = position_embeddings_list[-1].flatten(2).permute(0, 2, 1) + + flattened_mask = mask.flatten(1) + + # Fourth, sent flattened_features + flattened_mask + position embeddings through encoder + # flattened_features is a Tensor of shape (batch_size, heigth*width, hidden_size) + # flattened_mask is a Tensor of shape (batch_size, heigth*width) + if encoder_outputs is None: + encoder_outputs = self.detr.model.encoder( + inputs_embeds=flattened_features, + attention_mask=flattened_mask, + position_embeddings=position_embeddings, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # Fifth, sent query embeddings + position embeddings through the decoder (which is conditioned on the encoder output) + query_position_embeddings = self.detr.model.query_position_embeddings.weight.unsqueeze(0).repeat( + batch_size, 1, 1 + ) + queries = torch.zeros_like(query_position_embeddings) + + # decoder outputs consists of (dec_features, dec_hidden, dec_attn) + decoder_outputs = self.detr.model.decoder( + inputs_embeds=queries, + attention_mask=None, + position_embeddings=position_embeddings, + query_position_embeddings=query_position_embeddings, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=flattened_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = decoder_outputs[0] + + # Sixth, compute logits, pred_boxes and pred_masks + logits = self.detr.class_labels_classifier(sequence_output) + pred_boxes = self.detr.bbox_predictor(sequence_output).sigmoid() + + memory = encoder_outputs[0].permute(0, 2, 1).view(batch_size, self.config.d_model, height, width) + mask = flattened_mask.view(batch_size, height, width) + + # FIXME h_boxes takes the last one computed, keep this in mind + # important: we need to reverse the mask, since in the original implementation the mask works reversed + # bbox_mask is of shape (batch_size, num_queries, number_of_attention_heads in bbox_attention, height/32, width/32) + bbox_mask = self.bbox_attention(sequence_output, memory, mask=~mask) + + seg_masks = self.mask_head(projected_feature_map, bbox_mask, [features[2][0], features[1][0], features[0][0]]) + + pred_masks = seg_masks.view(batch_size, self.detr.config.num_queries, seg_masks.shape[-2], seg_masks.shape[-1]) + + loss, loss_dict, auxiliary_outputs = None, None, None + if labels is not None: + # First: create the matcher + matcher = DetrHungarianMatcher( + class_cost=self.config.class_cost, bbox_cost=self.config.bbox_cost, giou_cost=self.config.giou_cost + ) + # Second: create the criterion + losses = ["labels", "boxes", "cardinality", "masks"] + criterion = DetrLoss( + matcher=matcher, + num_classes=self.config.num_labels, + eos_coef=self.config.eos_coefficient, + losses=losses, + ) + criterion.to(self.device) + # Third: compute the losses, based on outputs and labels + outputs_loss = {} + outputs_loss["logits"] = logits + outputs_loss["pred_boxes"] = pred_boxes + outputs_loss["pred_masks"] = pred_masks + if self.config.auxiliary_loss: + intermediate = decoder_outputs.intermediate_hidden_states if return_dict else decoder_outputs[-1] + outputs_class = self.class_labels_classifier(intermediate) + outputs_coord = self.bbox_predictor(intermediate).sigmoid() + auxiliary_outputs = self._set_aux_loss(outputs_class, outputs_coord) + outputs_loss["auxiliary_outputs"] = auxiliary_outputs + + loss_dict = criterion(outputs_loss, labels) + # Fourth: compute total loss, as a weighted sum of the various losses + weight_dict = {"loss_ce": 1, "loss_bbox": self.config.bbox_loss_coefficient} + weight_dict["loss_giou"] = self.config.giou_loss_coefficient + weight_dict["loss_mask"] = self.config.mask_loss_coefficient + weight_dict["loss_dice"] = self.config.dice_loss_coefficient + if self.config.auxiliary_loss: + aux_weight_dict = {} + for i in range(self.config.decoder_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + loss = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) + + if not return_dict: + if auxiliary_outputs is not None: + output = (logits, pred_boxes, pred_masks) + auxiliary_outputs + decoder_outputs + encoder_outputs + else: + output = (logits, pred_boxes, pred_masks) + decoder_outputs + encoder_outputs + return ((loss, loss_dict) + output) if loss is not None else output + + return DetrSegmentationOutput( + loss=loss, + loss_dict=loss_dict, + logits=logits, + pred_boxes=pred_boxes, + pred_masks=pred_masks, + auxiliary_outputs=auxiliary_outputs, + last_hidden_state=decoder_outputs.last_hidden_state, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +def _expand(tensor, length: int): + return tensor.unsqueeze(1).repeat(1, int(length), 1, 1, 1).flatten(0, 1) + + +# taken from https://github.com/facebookresearch/detr/blob/master/models/segmentation.py +class DetrMaskHeadSmallConv(nn.Module): + """ + Simple convolutional head, using group norm. Upsampling is done using a FPN approach + """ + + def __init__(self, dim, fpn_dims, context_dim): + super().__init__() + + if dim % 8 != 0: + raise ValueError( + "The hidden_size + number of attention heads must be divisible by 8 as the number of groups in" + " GroupNorm is set to 8" + ) + + inter_dims = [dim, context_dim // 2, context_dim // 4, context_dim // 8, context_dim // 16, context_dim // 64] + + self.lay1 = nn.Conv2d(dim, dim, 3, padding=1) + self.gn1 = nn.GroupNorm(8, dim) + self.lay2 = nn.Conv2d(dim, inter_dims[1], 3, padding=1) + self.gn2 = nn.GroupNorm(8, inter_dims[1]) + self.lay3 = nn.Conv2d(inter_dims[1], inter_dims[2], 3, padding=1) + self.gn3 = nn.GroupNorm(8, inter_dims[2]) + self.lay4 = nn.Conv2d(inter_dims[2], inter_dims[3], 3, padding=1) + self.gn4 = nn.GroupNorm(8, inter_dims[3]) + self.lay5 = nn.Conv2d(inter_dims[3], inter_dims[4], 3, padding=1) + self.gn5 = nn.GroupNorm(8, inter_dims[4]) + self.out_lay = nn.Conv2d(inter_dims[4], 1, 3, padding=1) + + self.dim = dim + + self.adapter1 = nn.Conv2d(fpn_dims[0], inter_dims[1], 1) + self.adapter2 = nn.Conv2d(fpn_dims[1], inter_dims[2], 1) + self.adapter3 = nn.Conv2d(fpn_dims[2], inter_dims[3], 1) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_uniform_(m.weight, a=1) + nn.init.constant_(m.bias, 0) + + def forward(self, x: Tensor, bbox_mask: Tensor, fpns: List[Tensor]): + # here we concatenate x, the projected feature map, of shape (batch_size, d_model, heigth/32, width/32) with + # the bbox_mask = the attention maps of shape (batch_size, n_queries, n_heads, height/32, width/32). + # We expand the projected feature map to match the number of heads. + x = torch.cat([_expand(x, bbox_mask.shape[1]), bbox_mask.flatten(0, 1)], 1) + + x = self.lay1(x) + x = self.gn1(x) + x = nn.functional.relu(x) + x = self.lay2(x) + x = self.gn2(x) + x = nn.functional.relu(x) + + cur_fpn = self.adapter1(fpns[0]) + if cur_fpn.size(0) != x.size(0): + cur_fpn = _expand(cur_fpn, x.size(0) // cur_fpn.size(0)) + x = cur_fpn + nn.functional.interpolate(x, size=cur_fpn.shape[-2:], mode="nearest") + x = self.lay3(x) + x = self.gn3(x) + x = nn.functional.relu(x) + + cur_fpn = self.adapter2(fpns[1]) + if cur_fpn.size(0) != x.size(0): + cur_fpn = _expand(cur_fpn, x.size(0) // cur_fpn.size(0)) + x = cur_fpn + nn.functional.interpolate(x, size=cur_fpn.shape[-2:], mode="nearest") + x = self.lay4(x) + x = self.gn4(x) + x = nn.functional.relu(x) + + cur_fpn = self.adapter3(fpns[2]) + if cur_fpn.size(0) != x.size(0): + cur_fpn = _expand(cur_fpn, x.size(0) // cur_fpn.size(0)) + x = cur_fpn + nn.functional.interpolate(x, size=cur_fpn.shape[-2:], mode="nearest") + x = self.lay5(x) + x = self.gn5(x) + x = nn.functional.relu(x) + + x = self.out_lay(x) + return x + + +class DetrMHAttentionMap(nn.Module): + """This is a 2D attention module, which only returns the attention softmax (no multiplication by value)""" + + def __init__(self, query_dim, hidden_dim, num_heads, dropout=0.0, bias=True, std=None): + super().__init__() + self.num_heads = num_heads + self.hidden_dim = hidden_dim + self.dropout = nn.Dropout(dropout) + + self.q_linear = nn.Linear(query_dim, hidden_dim, bias=bias) + self.k_linear = nn.Linear(query_dim, hidden_dim, bias=bias) + + self.normalize_fact = float(hidden_dim / self.num_heads) ** -0.5 + + def forward(self, q, k, mask: Optional[Tensor] = None): + q = self.q_linear(q) + k = nn.functional.conv2d(k, self.k_linear.weight.unsqueeze(-1).unsqueeze(-1), self.k_linear.bias) + queries_per_head = q.view(q.shape[0], q.shape[1], self.num_heads, self.hidden_dim // self.num_heads) + keys_per_head = k.view(k.shape[0], self.num_heads, self.hidden_dim // self.num_heads, k.shape[-2], k.shape[-1]) + weights = torch.einsum("bqnc,bnchw->bqnhw", queries_per_head * self.normalize_fact, keys_per_head) + + if mask is not None: + weights.masked_fill_(mask.unsqueeze(1).unsqueeze(1), torch.finfo(weights.dtype).min) + weights = nn.functional.softmax(weights.flatten(2), dim=-1).view(weights.size()) + weights = self.dropout(weights) + return weights + + +def dice_loss(inputs, targets, num_boxes): + """ + Compute the DICE loss, similar to generalized IOU for masks + + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs (0 for the negative class and 1 for the positive + class). + """ + inputs = inputs.sigmoid() + inputs = inputs.flatten(1) + numerator = 2 * (inputs * targets).sum(1) + denominator = inputs.sum(-1) + targets.sum(-1) + loss = 1 - (numerator + 1) / (denominator + 1) + return loss.sum() / num_boxes + + +def sigmoid_focal_loss(inputs, targets, num_boxes, alpha: float = 0.25, gamma: float = 2): + """ + Loss used in RetinaNet for dense detection: https://arxiv.org/abs/1708.02002. + + Args: + inputs (`torch.FloatTensor` of arbitrary shape): + The predictions for each example. + targets (`torch.FloatTensor` with the same shape as `inputs`) + A tensor storing the binary classification label for each element in the `inputs` (0 for the negative class + and 1 for the positive class). + alpha (`float`, *optional*, defaults to `0.25`): + Optional weighting factor in the range (0,1) to balance positive vs. negative examples. + gamma (`int`, *optional*, defaults to `2`): + Exponent of the modulating factor (1 - p_t) to balance easy vs hard examples. + + Returns: + Loss tensor + """ + prob = inputs.sigmoid() + ce_loss = nn.functional.binary_cross_entropy_with_logits(inputs, targets, reduction="none") + # add modulating factor + p_t = prob * targets + (1 - prob) * (1 - targets) + loss = ce_loss * ((1 - p_t) ** gamma) + + if alpha >= 0: + alpha_t = alpha * targets + (1 - alpha) * (1 - targets) + loss = alpha_t * loss + + return loss.mean(1).sum() / num_boxes + + +# taken from https://github.com/facebookresearch/detr/blob/master/models/detr.py +class DetrLoss(nn.Module): + """ + This class computes the losses for DetrForObjectDetection/DetrForSegmentation. The process happens in two steps: 1) + we compute hungarian assignment between ground truth boxes and the outputs of the model 2) we supervise each pair + of matched ground-truth / prediction (supervise class and box). + + A note on the `num_classes` argument (copied from original repo in detr.py): "the naming of the `num_classes` + parameter of the criterion is somewhat misleading. It indeed corresponds to `max_obj_id` + 1, where `max_obj_id` is + the maximum id for a class in your dataset. For example, COCO has a `max_obj_id` of 90, so we pass `num_classes` to + be 91. As another example, for a dataset that has a single class with `id` 1, you should pass `num_classes` to be 2 + (`max_obj_id` + 1). For more details on this, check the following discussion + https://github.com/facebookresearch/detr/issues/108#issuecomment-650269223" + + + Args: + matcher (`DetrHungarianMatcher`): + Module able to compute a matching between targets and proposals. + num_classes (`int`): + Number of object categories, omitting the special no-object category. + eos_coef (`float`): + Relative classification weight applied to the no-object category. + losses (`List[str]`): + List of all the losses to be applied. See `get_loss` for a list of all available losses. + """ + + def __init__(self, matcher, num_classes, eos_coef, losses): + super().__init__() + self.matcher = matcher + self.num_classes = num_classes + self.eos_coef = eos_coef + self.losses = losses + empty_weight = torch.ones(self.num_classes + 1) + empty_weight[-1] = self.eos_coef + self.register_buffer("empty_weight", empty_weight) + + # removed logging parameter, which was part of the original implementation + def loss_labels(self, outputs, targets, indices, num_boxes): + """ + Classification loss (NLL) targets dicts must contain the key "class_labels" containing a tensor of dim + [nb_target_boxes] + """ + if "logits" not in outputs: + raise KeyError("No logits were found in the outputs") + source_logits = outputs["logits"] + + idx = self._get_source_permutation_idx(indices) + target_classes_o = torch.cat([t["class_labels"][J] for t, (_, J) in zip(targets, indices)]) + target_classes = torch.full( + source_logits.shape[:2], self.num_classes, dtype=torch.int64, device=source_logits.device + ) + target_classes[idx] = target_classes_o + + loss_ce = nn.functional.cross_entropy(source_logits.transpose(1, 2), target_classes, self.empty_weight) + losses = {"loss_ce": loss_ce} + + return losses + + @torch.no_grad() + def loss_cardinality(self, outputs, targets, indices, num_boxes): + """ + Compute the cardinality error, i.e. the absolute error in the number of predicted non-empty boxes. + + This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients. + """ + logits = outputs["logits"] + device = logits.device + target_lengths = torch.as_tensor([len(v["class_labels"]) for v in targets], device=device) + # Count the number of predictions that are NOT "no-object" (which is the last class) + card_pred = (logits.argmax(-1) != logits.shape[-1] - 1).sum(1) + card_err = nn.functional.l1_loss(card_pred.float(), target_lengths.float()) + losses = {"cardinality_error": card_err} + return losses + + def loss_boxes(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss. + + Targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]. The target boxes + are expected in format (center_x, center_y, w, h), normalized by the image size. + """ + if "pred_boxes" not in outputs: + raise KeyError("No predicted boxes found in outputs") + idx = self._get_source_permutation_idx(indices) + source_boxes = outputs["pred_boxes"][idx] + target_boxes = torch.cat([t["boxes"][i] for t, (_, i) in zip(targets, indices)], dim=0) + + loss_bbox = nn.functional.l1_loss(source_boxes, target_boxes, reduction="none") + + losses = {} + losses["loss_bbox"] = loss_bbox.sum() / num_boxes + + loss_giou = 1 - torch.diag( + generalized_box_iou(center_to_corners_format(source_boxes), center_to_corners_format(target_boxes)) + ) + losses["loss_giou"] = loss_giou.sum() / num_boxes + return losses + + def loss_masks(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the masks: the focal loss and the dice loss. + + Targets dicts must contain the key "masks" containing a tensor of dim [nb_target_boxes, h, w]. + """ + if "pred_masks" not in outputs: + raise KeyError("No predicted masks found in outputs") + + source_idx = self._get_source_permutation_idx(indices) + target_idx = self._get_target_permutation_idx(indices) + source_masks = outputs["pred_masks"] + source_masks = source_masks[source_idx] + masks = [t["masks"] for t in targets] + # TODO use valid to mask invalid areas due to padding in loss + target_masks, valid = nested_tensor_from_tensor_list(masks).decompose() + target_masks = target_masks.to(source_masks) + target_masks = target_masks[target_idx] + + # upsample predictions to the target size + source_masks = nn.functional.interpolate( + source_masks[:, None], size=target_masks.shape[-2:], mode="bilinear", align_corners=False + ) + source_masks = source_masks[:, 0].flatten(1) + + target_masks = target_masks.flatten(1) + target_masks = target_masks.view(source_masks.shape) + losses = { + "loss_mask": sigmoid_focal_loss(source_masks, target_masks, num_boxes), + "loss_dice": dice_loss(source_masks, target_masks, num_boxes), + } + return losses + + def _get_source_permutation_idx(self, indices): + # permute predictions following indices + batch_idx = torch.cat([torch.full_like(source, i) for i, (source, _) in enumerate(indices)]) + source_idx = torch.cat([source for (source, _) in indices]) + return batch_idx, source_idx + + def _get_target_permutation_idx(self, indices): + # permute targets following indices + batch_idx = torch.cat([torch.full_like(target, i) for i, (_, target) in enumerate(indices)]) + target_idx = torch.cat([target for (_, target) in indices]) + return batch_idx, target_idx + + def get_loss(self, loss, outputs, targets, indices, num_boxes): + loss_map = { + "labels": self.loss_labels, + "cardinality": self.loss_cardinality, + "boxes": self.loss_boxes, + "masks": self.loss_masks, + } + if loss not in loss_map: + raise ValueError(f"Loss {loss} not supported") + return loss_map[loss](outputs, targets, indices, num_boxes) + + def forward(self, outputs, targets): + """ + This performs the loss computation. + + Args: + outputs (`dict`, *optional*): + Dictionary of tensors, see the output specification of the model for the format. + targets (`List[dict]`, *optional*): + List of dicts, such that `len(targets) == batch_size`. The expected keys in each dict depends on the + losses applied, see each loss' doc. + """ + outputs_without_aux = {k: v for k, v in outputs.items() if k != "auxiliary_outputs"} + + # Retrieve the matching between the outputs of the last layer and the targets + indices = self.matcher(outputs_without_aux, targets) + + # Compute the average number of target boxes across all nodes, for normalization purposes + num_boxes = sum(len(t["class_labels"]) for t in targets) + num_boxes = torch.as_tensor([num_boxes], dtype=torch.float, device=next(iter(outputs.values())).device) + # (Niels): comment out function below, distributed training to be added + # if is_dist_avail_and_initialized(): + # torch.distributed.all_reduce(num_boxes) + # (Niels) in original implementation, num_boxes is divided by get_world_size() + num_boxes = torch.clamp(num_boxes, min=1).item() + + # Compute all the requested losses + losses = {} + for loss in self.losses: + losses.update(self.get_loss(loss, outputs, targets, indices, num_boxes)) + + # In case of auxiliary losses, we repeat this process with the output of each intermediate layer. + if "auxiliary_outputs" in outputs: + for i, auxiliary_outputs in enumerate(outputs["auxiliary_outputs"]): + indices = self.matcher(auxiliary_outputs, targets) + for loss in self.losses: + if loss == "masks": + # Intermediate masks losses are too costly to compute, we ignore them. + continue + l_dict = self.get_loss(loss, auxiliary_outputs, targets, indices, num_boxes) + l_dict = {k + f"_{i}": v for k, v in l_dict.items()} + losses.update(l_dict) + + return losses + + +# taken from https://github.com/facebookresearch/detr/blob/master/models/detr.py +class DetrMLPPredictionHead(nn.Module): + """ + Very simple multi-layer perceptron (MLP, also called FFN), used to predict the normalized center coordinates, + height and width of a bounding box w.r.t. an image. + + Copied from https://github.com/facebookresearch/detr/blob/master/models/detr.py + + """ + + def __init__(self, input_dim, hidden_dim, output_dim, num_layers): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = nn.functional.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x + + +# taken from https://github.com/facebookresearch/detr/blob/master/models/matcher.py +class DetrHungarianMatcher(nn.Module): + """ + This class computes an assignment between the targets and the predictions of the network. + + For efficiency reasons, the targets don't include the no_object. Because of this, in general, there are more + predictions than targets. In this case, we do a 1-to-1 matching of the best predictions, while the others are + un-matched (and thus treated as non-objects). + + Args: + class_cost: + The relative weight of the classification error in the matching cost. + bbox_cost: + The relative weight of the L1 error of the bounding box coordinates in the matching cost. + giou_cost: + The relative weight of the giou loss of the bounding box in the matching cost. + """ + + def __init__(self, class_cost: float = 1, bbox_cost: float = 1, giou_cost: float = 1): + super().__init__() + requires_backends(self, ["scipy"]) + + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + if class_cost == 0 and bbox_cost == 0 and giou_cost == 0: + raise ValueError("All costs of the Matcher can't be 0") + + @torch.no_grad() + def forward(self, outputs, targets): + """ + Args: + outputs (`dict`): + A dictionary that contains at least these entries: + * "logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits + * "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates. + targets (`List[dict]`): + A list of targets (len(targets) = batch_size), where each target is a dict containing: + * "class_labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of + ground-truth + objects in the target) containing the class labels + * "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates. + + Returns: + `List[Tuple]`: A list of size `batch_size`, containing tuples of (index_i, index_j) where: + - index_i is the indices of the selected predictions (in order) + - index_j is the indices of the corresponding selected targets (in order) + For each batch element, it holds: len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + batch_size, num_queries = outputs["logits"].shape[:2] + + # We flatten to compute the cost matrices in a batch + out_prob = outputs["logits"].flatten(0, 1).softmax(-1) # [batch_size * num_queries, num_classes] + out_bbox = outputs["pred_boxes"].flatten(0, 1) # [batch_size * num_queries, 4] + + # Also concat the target labels and boxes + target_ids = torch.cat([v["class_labels"] for v in targets]) + target_bbox = torch.cat([v["boxes"] for v in targets]) + + # Compute the classification cost. Contrary to the loss, we don't use the NLL, + # but approximate it in 1 - proba[target class]. + # The 1 is a constant that doesn't change the matching, it can be ommitted. + class_cost = -out_prob[:, target_ids] + + # Compute the L1 cost between boxes + bbox_cost = torch.cdist(out_bbox, target_bbox, p=1) + + # Compute the giou cost between boxes + giou_cost = -generalized_box_iou(center_to_corners_format(out_bbox), center_to_corners_format(target_bbox)) + + # Final cost matrix + cost_matrix = self.bbox_cost * bbox_cost + self.class_cost * class_cost + self.giou_cost * giou_cost + cost_matrix = cost_matrix.view(batch_size, num_queries, -1).cpu() + + sizes = [len(v["boxes"]) for v in targets] + indices = [linear_sum_assignment(c[i]) for i, c in enumerate(cost_matrix.split(sizes, -1))] + return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices] + + +# below: bounding box utilities taken from https://github.com/facebookresearch/detr/blob/master/util/box_ops.py + + +def _upcast(t: Tensor) -> Tensor: + # Protects from numerical overflows in multiplications by upcasting to the equivalent higher type + if t.is_floating_point(): + return t if t.dtype in (torch.float32, torch.float64) else t.float() + else: + return t if t.dtype in (torch.int32, torch.int64) else t.int() + + +def box_area(boxes: Tensor) -> Tensor: + """ + Computes the area of a set of bounding boxes, which are specified by its (x1, y1, x2, y2) coordinates. + + Args: + boxes (`torch.FloatTensor` of shape `(number_of_boxes, 4)`): + Boxes for which the area will be computed. They are expected to be in (x1, y1, x2, y2) format with `0 <= x1 + < x2` and `0 <= y1 < y2`. + + Returns: + `torch.FloatTensor`: a tensor containing the area for each box. + """ + boxes = _upcast(boxes) + return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) + + +# modified from torchvision to also return the union +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + left_top = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2] + right_bottom = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2] + + width_height = (right_bottom - left_top).clamp(min=0) # [N,M,2] + inter = width_height[:, :, 0] * width_height[:, :, 1] # [N,M] + + union = area1[:, None] + area2 - inter + + iou = inter / union + return iou, union + + +def generalized_box_iou(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/. The boxes should be in [x0, y0, x1, y1] (corner) format. + + Returns: + `torch.FloatTensor`: a [N, M] pairwise matrix, where N = len(boxes1) and M = len(boxes2) + """ + # degenerate boxes gives inf / nan results + # so do an early check + if not (boxes1[:, 2:] >= boxes1[:, :2]).all(): + raise ValueError(f"boxes1 must be in [x0, y0, x1, y1] (corner) format, but got {boxes1}") + if not (boxes2[:, 2:] >= boxes2[:, :2]).all(): + raise ValueError(f"boxes2 must be in [x0, y0, x1, y1] (corner) format, but got {boxes2}") + iou, union = box_iou(boxes1, boxes2) + + top_left = torch.min(boxes1[:, None, :2], boxes2[:, :2]) + bottom_right = torch.max(boxes1[:, None, 2:], boxes2[:, 2:]) + + width_height = (bottom_right - top_left).clamp(min=0) # [N,M,2] + area = width_height[:, :, 0] * width_height[:, :, 1] + + return iou - (area - union) / area + + +# below: taken from https://github.com/facebookresearch/detr/blob/master/util/misc.py#L306 +def _max_by_axis(the_list): + # type: (List[List[int]]) -> List[int] + maxes = the_list[0] + for sublist in the_list[1:]: + for index, item in enumerate(sublist): + maxes[index] = max(maxes[index], item) + return maxes + + +class NestedTensor(object): + def __init__(self, tensors, mask: Optional[Tensor]): + self.tensors = tensors + self.mask = mask + + def to(self, device): + cast_tensor = self.tensors.to(device) + mask = self.mask + if mask is not None: + cast_mask = mask.to(device) + else: + cast_mask = None + return NestedTensor(cast_tensor, cast_mask) + + def decompose(self): + return self.tensors, self.mask + + def __repr__(self): + return str(self.tensors) + + +def nested_tensor_from_tensor_list(tensor_list: List[Tensor]): + if tensor_list[0].ndim == 3: + max_size = _max_by_axis([list(img.shape) for img in tensor_list]) + batch_shape = [len(tensor_list)] + max_size + batch_size, num_channels, height, width = batch_shape + dtype = tensor_list[0].dtype + device = tensor_list[0].device + tensor = torch.zeros(batch_shape, dtype=dtype, device=device) + mask = torch.ones((batch_size, height, width), dtype=torch.bool, device=device) + for img, pad_img, m in zip(tensor_list, tensor, mask): + pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img) + m[: img.shape[1], : img.shape[2]] = False + else: + raise ValueError("Only 3-dimensional tensors are supported") + return NestedTensor(tensor, mask) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dialogpt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dialogpt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dialogpt/convert_dialogpt_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dialogpt/convert_dialogpt_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..fbf34012924b901f3a074d36ed9be7b1fc32913b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dialogpt/convert_dialogpt_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,46 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os + +import torch + +from transformers.utils import WEIGHTS_NAME + + +DIALOGPT_MODELS = ["small", "medium", "large"] + +OLD_KEY = "lm_head.decoder.weight" +NEW_KEY = "lm_head.weight" + + +def convert_dialogpt_checkpoint(checkpoint_path: str, pytorch_dump_folder_path: str): + d = torch.load(checkpoint_path) + d[NEW_KEY] = d.pop(OLD_KEY) + os.makedirs(pytorch_dump_folder_path, exist_ok=True) + torch.save(d, os.path.join(pytorch_dump_folder_path, WEIGHTS_NAME)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--dialogpt_path", default=".", type=str) + args = parser.parse_args() + for MODEL in DIALOGPT_MODELS: + checkpoint_path = os.path.join(args.dialogpt_path, f"{MODEL}_ft.pkl") + pytorch_dump_folder_path = f"./DialoGPT-{MODEL}" + convert_dialogpt_checkpoint( + checkpoint_path, + pytorch_dump_folder_path, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..88470f1ca9f9bd68a2f89691cfe5b9031e3cae66 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/__init__.py @@ -0,0 +1,56 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = {"configuration_dinat": ["DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP", "DinatConfig"]} + + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_dinat"] = [ + "DINAT_PRETRAINED_MODEL_ARCHIVE_LIST", + "DinatForImageClassification", + "DinatModel", + "DinatPreTrainedModel", + "DinatBackbone", + ] + +if TYPE_CHECKING: + from .configuration_dinat import DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP, DinatConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_dinat import ( + DINAT_PRETRAINED_MODEL_ARCHIVE_LIST, + DinatBackbone, + DinatForImageClassification, + DinatModel, + DinatPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/configuration_dinat.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/configuration_dinat.py new file mode 100644 index 0000000000000000000000000000000000000000..963c72f29bd407f611a9b1815b1378aacf8d2496 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/configuration_dinat.py @@ -0,0 +1,151 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Dilated Neighborhood Attention Transformer model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging +from ...utils.backbone_utils import BackboneConfigMixin, get_aligned_output_features_output_indices + + +logger = logging.get_logger(__name__) + +DINAT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "shi-labs/dinat-mini-in1k-224": "https://huggingface.co/shi-labs/dinat-mini-in1k-224/resolve/main/config.json", + # See all Dinat models at https://huggingface.co/models?filter=dinat +} + + +class DinatConfig(BackboneConfigMixin, PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DinatModel`]. It is used to instantiate a Dinat + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the Dinat + [shi-labs/dinat-mini-in1k-224](https://huggingface.co/shi-labs/dinat-mini-in1k-224) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + patch_size (`int`, *optional*, defaults to 4): + The size (resolution) of each patch. NOTE: Only patch size of 4 is supported at the moment. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + embed_dim (`int`, *optional*, defaults to 64): + Dimensionality of patch embedding. + depths (`List[int]`, *optional*, defaults to `[2, 2, 6, 2]`): + Number of layers in each level of the encoder. + num_heads (`List[int]`, *optional*, defaults to `[3, 6, 12, 24]`): + Number of attention heads in each layer of the Transformer encoder. + kernel_size (`int`, *optional*, defaults to 7): + Neighborhood Attention kernel size. + dilations (`List[List[int]]`, *optional*, defaults to `[[1, 8, 1], [1, 4, 1, 4], [1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1]]`): + Dilation value of each NA layer in the Transformer encoder. + mlp_ratio (`float`, *optional*, defaults to 3.0): + Ratio of MLP hidden dimensionality to embedding dimensionality. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether or not a learnable bias should be added to the queries, keys and values. + hidden_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout probability for all fully connected layers in the embeddings and encoder. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + drop_path_rate (`float`, *optional*, defaults to 0.1): + Stochastic depth rate. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder. If string, `"gelu"`, `"relu"`, + `"selu"` and `"gelu_new"` are supported. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + layer_scale_init_value (`float`, *optional*, defaults to 0.0): + The initial value for the layer scale. Disabled if <=0. + out_features (`List[str]`, *optional*): + If used as backbone, list of features to output. Can be any of `"stem"`, `"stage1"`, `"stage2"`, etc. + (depending on how many stages the model has). If unset and `out_indices` is set, will default to the + corresponding stages. If unset and `out_indices` is unset, will default to the last stage. + out_indices (`List[int]`, *optional*): + If used as backbone, list of indices of features to output. Can be any of 0, 1, 2, etc. (depending on how + many stages the model has). If unset and `out_features` is set, will default to the corresponding stages. + If unset and `out_features` is unset, will default to the last stage. + + Example: + + ```python + >>> from transformers import DinatConfig, DinatModel + + >>> # Initializing a Dinat shi-labs/dinat-mini-in1k-224 style configuration + >>> configuration = DinatConfig() + + >>> # Initializing a model (with random weights) from the shi-labs/dinat-mini-in1k-224 style configuration + >>> model = DinatModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "dinat" + + attribute_map = { + "num_attention_heads": "num_heads", + "num_hidden_layers": "num_layers", + } + + def __init__( + self, + patch_size=4, + num_channels=3, + embed_dim=64, + depths=[3, 4, 6, 5], + num_heads=[2, 4, 8, 16], + kernel_size=7, + dilations=[[1, 8, 1], [1, 4, 1, 4], [1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1]], + mlp_ratio=3.0, + qkv_bias=True, + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + drop_path_rate=0.1, + hidden_act="gelu", + initializer_range=0.02, + layer_norm_eps=1e-5, + layer_scale_init_value=0.0, + out_features=None, + out_indices=None, + **kwargs, + ): + super().__init__(**kwargs) + + self.patch_size = patch_size + self.num_channels = num_channels + self.embed_dim = embed_dim + self.depths = depths + self.num_layers = len(depths) + self.num_heads = num_heads + self.kernel_size = kernel_size + self.dilations = dilations + self.mlp_ratio = mlp_ratio + self.qkv_bias = qkv_bias + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.drop_path_rate = drop_path_rate + self.hidden_act = hidden_act + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + # we set the hidden_size attribute in order to make Dinat work with VisionEncoderDecoderModel + # this indicates the channel dimension after the last stage of the model + self.hidden_size = int(embed_dim * 2 ** (len(depths) - 1)) + self.layer_scale_init_value = layer_scale_init_value + self.stage_names = ["stem"] + [f"stage{idx}" for idx in range(1, len(depths) + 1)] + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + out_features=out_features, out_indices=out_indices, stage_names=self.stage_names + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/modeling_dinat.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/modeling_dinat.py new file mode 100644 index 0000000000000000000000000000000000000000..7e3809c1a3033daf9cc3fdbd8bea3c707d80f904 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dinat/modeling_dinat.py @@ -0,0 +1,986 @@ +# coding=utf-8 +# Copyright 2022 SHI Labs and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Dilated Neighborhood Attention Transformer model.""" + + +import math +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import BackboneOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + OptionalDependencyNotAvailable, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + is_natten_available, + logging, + replace_return_docstrings, + requires_backends, +) +from ...utils.backbone_utils import BackboneMixin, get_aligned_output_features_output_indices +from .configuration_dinat import DinatConfig + + +if is_natten_available(): + from natten.functional import natten2dav, natten2dqkrpb +else: + + def natten2dqkrpb(*args, **kwargs): + raise OptionalDependencyNotAvailable() + + def natten2dav(*args, **kwargs): + raise OptionalDependencyNotAvailable() + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "DinatConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "shi-labs/dinat-mini-in1k-224" +_EXPECTED_OUTPUT_SHAPE = [1, 7, 7, 512] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "shi-labs/dinat-mini-in1k-224" +_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" + + +DINAT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "shi-labs/dinat-mini-in1k-224", + # See all Dinat models at https://huggingface.co/models?filter=dinat +] + +# drop_path and DinatDropPath are from the timm library. + + +@dataclass +# Copied from transformers.models.nat.modeling_nat.NatEncoderOutput with Nat->Dinat +class DinatEncoderOutput(ModelOutput): + """ + Dinat encoder's outputs, with potential hidden states and attentions. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, hidden_size, height, width)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to + include the spatial dimensions. + """ + + last_hidden_state: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + reshaped_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +# Copied from transformers.models.nat.modeling_nat.NatModelOutput with Nat->Dinat +class DinatModelOutput(ModelOutput): + """ + Dinat model's outputs that also contains a pooling of the last hidden states. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`, *optional*, returned when `add_pooling_layer=True` is passed): + Average pooling of the last layer hidden-state. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, hidden_size, height, width)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to + include the spatial dimensions. + """ + + last_hidden_state: torch.FloatTensor = None + pooler_output: Optional[torch.FloatTensor] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + reshaped_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +# Copied from transformers.models.nat.modeling_nat.NatImageClassifierOutput with Nat->Dinat +class DinatImageClassifierOutput(ModelOutput): + """ + Dinat outputs for image classification. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Classification (or regression if config.num_labels==1) loss. + logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Classification (or regression if config.num_labels==1) scores (before SoftMax). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, hidden_size, height, width)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to + include the spatial dimensions. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + reshaped_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +# Copied from transformers.models.nat.modeling_nat.NatEmbeddings with Nat->Dinat +class DinatEmbeddings(nn.Module): + """ + Construct the patch and position embeddings. + """ + + def __init__(self, config): + super().__init__() + + self.patch_embeddings = DinatPatchEmbeddings(config) + + self.norm = nn.LayerNorm(config.embed_dim) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, pixel_values: Optional[torch.FloatTensor]) -> Tuple[torch.Tensor]: + embeddings = self.patch_embeddings(pixel_values) + embeddings = self.norm(embeddings) + + embeddings = self.dropout(embeddings) + + return embeddings + + +# Copied from transformers.models.nat.modeling_nat.NatPatchEmbeddings with Nat->Dinat +class DinatPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, height, width, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + patch_size = config.patch_size + num_channels, hidden_size = config.num_channels, config.embed_dim + self.num_channels = num_channels + + if patch_size == 4: + pass + else: + # TODO: Support arbitrary patch sizes. + raise ValueError("Dinat only supports patch size of 4 at the moment.") + + self.projection = nn.Sequential( + nn.Conv2d(self.num_channels, hidden_size // 2, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)), + nn.Conv2d(hidden_size // 2, hidden_size, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)), + ) + + def forward(self, pixel_values: Optional[torch.FloatTensor]) -> torch.Tensor: + _, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + embeddings = self.projection(pixel_values) + embeddings = embeddings.permute(0, 2, 3, 1) + + return embeddings + + +# Copied from transformers.models.nat.modeling_nat.NatDownsampler with Nat->Dinat +class DinatDownsampler(nn.Module): + """ + Convolutional Downsampling Layer. + + Args: + dim (`int`): + Number of input channels. + norm_layer (`nn.Module`, *optional*, defaults to `nn.LayerNorm`): + Normalization layer class. + """ + + def __init__(self, dim: int, norm_layer: nn.Module = nn.LayerNorm) -> None: + super().__init__() + self.dim = dim + self.reduction = nn.Conv2d(dim, 2 * dim, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False) + self.norm = norm_layer(2 * dim) + + def forward(self, input_feature: torch.Tensor) -> torch.Tensor: + input_feature = self.reduction(input_feature.permute(0, 3, 1, 2)).permute(0, 2, 3, 1) + input_feature = self.norm(input_feature) + return input_feature + + +# Copied from transformers.models.beit.modeling_beit.drop_path +def drop_path(input, drop_prob=0.0, training=False, scale_by_keep=True): + """ + Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, + however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the + layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the + argument. + """ + if drop_prob == 0.0 or not training: + return input + keep_prob = 1 - drop_prob + shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device) + random_tensor.floor_() # binarize + output = input.div(keep_prob) * random_tensor + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitDropPath with Beit->Dinat +class DinatDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob: Optional[float] = None) -> None: + super().__init__() + self.drop_prob = drop_prob + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + return drop_path(hidden_states, self.drop_prob, self.training) + + def extra_repr(self) -> str: + return "p={}".format(self.drop_prob) + + +class NeighborhoodAttention(nn.Module): + def __init__(self, config, dim, num_heads, kernel_size, dilation): + super().__init__() + if dim % num_heads != 0: + raise ValueError( + f"The hidden size ({dim}) is not a multiple of the number of attention heads ({num_heads})" + ) + + self.num_attention_heads = num_heads + self.attention_head_size = int(dim / num_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.kernel_size = kernel_size + self.dilation = dilation + + # rpb is learnable relative positional biases; same concept is used Swin. + self.rpb = nn.Parameter(torch.zeros(num_heads, (2 * self.kernel_size - 1), (2 * self.kernel_size - 1))) + + self.query = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + # Copied from transformers.models.nat.modeling_nat.NeighborhoodAttention.transpose_for_scores with Nat->Dinat + def transpose_for_scores(self, x): + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 3, 1, 2, 4) + + def forward( + self, + hidden_states: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + query_layer = self.transpose_for_scores(self.query(hidden_states)) + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + # Apply the scale factor before computing attention weights. It's usually more efficient because + # attention weights are typically a bigger tensor compared to query. + # It gives identical results because scalars are commutable in matrix multiplication. + query_layer = query_layer / math.sqrt(self.attention_head_size) + + # Compute NA between "query" and "key" to get the raw attention scores, and add relative positional biases. + attention_scores = natten2dqkrpb(query_layer, key_layer, self.rpb, self.kernel_size, self.dilation) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + context_layer = natten2dav(attention_probs, value_layer, self.kernel_size, self.dilation) + context_layer = context_layer.permute(0, 2, 3, 1, 4).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.nat.modeling_nat.NeighborhoodAttentionOutput +class NeighborhoodAttentionOutput(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(dim, dim) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +class NeighborhoodAttentionModule(nn.Module): + def __init__(self, config, dim, num_heads, kernel_size, dilation): + super().__init__() + self.self = NeighborhoodAttention(config, dim, num_heads, kernel_size, dilation) + self.output = NeighborhoodAttentionOutput(config, dim) + self.pruned_heads = set() + + # Copied from transformers.models.nat.modeling_nat.NeighborhoodAttentionModule.prune_heads + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + # Copied from transformers.models.nat.modeling_nat.NeighborhoodAttentionModule.forward + def forward( + self, + hidden_states: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self(hidden_states, output_attentions) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.nat.modeling_nat.NatIntermediate with Nat->Dinat +class DinatIntermediate(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(dim, int(config.mlp_ratio * dim)) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.nat.modeling_nat.NatOutput with Nat->Dinat +class DinatOutput(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(int(config.mlp_ratio * dim), dim) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states + + +class DinatLayer(nn.Module): + def __init__(self, config, dim, num_heads, dilation, drop_path_rate=0.0): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.kernel_size = config.kernel_size + self.dilation = dilation + self.window_size = self.kernel_size * self.dilation + self.layernorm_before = nn.LayerNorm(dim, eps=config.layer_norm_eps) + self.attention = NeighborhoodAttentionModule( + config, dim, num_heads, kernel_size=self.kernel_size, dilation=self.dilation + ) + self.drop_path = DinatDropPath(drop_path_rate) if drop_path_rate > 0.0 else nn.Identity() + self.layernorm_after = nn.LayerNorm(dim, eps=config.layer_norm_eps) + self.intermediate = DinatIntermediate(config, dim) + self.output = DinatOutput(config, dim) + self.layer_scale_parameters = ( + nn.Parameter(config.layer_scale_init_value * torch.ones((2, dim)), requires_grad=True) + if config.layer_scale_init_value > 0 + else None + ) + + def maybe_pad(self, hidden_states, height, width): + window_size = self.window_size + pad_values = (0, 0, 0, 0, 0, 0) + if height < window_size or width < window_size: + pad_l = pad_t = 0 + pad_r = max(0, window_size - width) + pad_b = max(0, window_size - height) + pad_values = (0, 0, pad_l, pad_r, pad_t, pad_b) + hidden_states = nn.functional.pad(hidden_states, pad_values) + return hidden_states, pad_values + + def forward( + self, + hidden_states: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor, torch.Tensor]: + batch_size, height, width, channels = hidden_states.size() + shortcut = hidden_states + + hidden_states = self.layernorm_before(hidden_states) + # pad hidden_states if they are smaller than kernel size x dilation + hidden_states, pad_values = self.maybe_pad(hidden_states, height, width) + + _, height_pad, width_pad, _ = hidden_states.shape + + attention_outputs = self.attention(hidden_states, output_attentions=output_attentions) + + attention_output = attention_outputs[0] + + was_padded = pad_values[3] > 0 or pad_values[5] > 0 + if was_padded: + attention_output = attention_output[:, :height, :width, :].contiguous() + + if self.layer_scale_parameters is not None: + attention_output = self.layer_scale_parameters[0] * attention_output + + hidden_states = shortcut + self.drop_path(attention_output) + + layer_output = self.layernorm_after(hidden_states) + layer_output = self.output(self.intermediate(layer_output)) + + if self.layer_scale_parameters is not None: + layer_output = self.layer_scale_parameters[1] * layer_output + + layer_output = hidden_states + self.drop_path(layer_output) + + layer_outputs = (layer_output, attention_outputs[1]) if output_attentions else (layer_output,) + return layer_outputs + + +class DinatStage(nn.Module): + def __init__(self, config, dim, depth, num_heads, dilations, drop_path_rate, downsample): + super().__init__() + self.config = config + self.dim = dim + self.layers = nn.ModuleList( + [ + DinatLayer( + config=config, + dim=dim, + num_heads=num_heads, + dilation=dilations[i], + drop_path_rate=drop_path_rate[i], + ) + for i in range(depth) + ] + ) + + # patch merging layer + if downsample is not None: + self.downsample = downsample(dim=dim, norm_layer=nn.LayerNorm) + else: + self.downsample = None + + self.pointing = False + + # Copied from transformers.models.nat.modeling_nat.NatStage.forward + def forward( + self, + hidden_states: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + _, height, width, _ = hidden_states.size() + for i, layer_module in enumerate(self.layers): + layer_outputs = layer_module(hidden_states, output_attentions) + hidden_states = layer_outputs[0] + + hidden_states_before_downsampling = hidden_states + if self.downsample is not None: + hidden_states = self.downsample(hidden_states_before_downsampling) + + stage_outputs = (hidden_states, hidden_states_before_downsampling) + + if output_attentions: + stage_outputs += layer_outputs[1:] + return stage_outputs + + +class DinatEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.num_levels = len(config.depths) + self.config = config + dpr = [x.item() for x in torch.linspace(0, config.drop_path_rate, sum(config.depths))] + self.levels = nn.ModuleList( + [ + DinatStage( + config=config, + dim=int(config.embed_dim * 2**i_layer), + depth=config.depths[i_layer], + num_heads=config.num_heads[i_layer], + dilations=config.dilations[i_layer], + drop_path_rate=dpr[sum(config.depths[:i_layer]) : sum(config.depths[: i_layer + 1])], + downsample=DinatDownsampler if (i_layer < self.num_levels - 1) else None, + ) + for i_layer in range(self.num_levels) + ] + ) + + # Copied from transformers.models.nat.modeling_nat.NatEncoder.forward with Nat->Dinat + def forward( + self, + hidden_states: torch.Tensor, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + output_hidden_states_before_downsampling: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple, DinatEncoderOutput]: + all_hidden_states = () if output_hidden_states else None + all_reshaped_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if output_hidden_states: + # rearrange b h w c -> b c h w + reshaped_hidden_state = hidden_states.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + + for i, layer_module in enumerate(self.levels): + layer_outputs = layer_module(hidden_states, output_attentions) + + hidden_states = layer_outputs[0] + hidden_states_before_downsampling = layer_outputs[1] + + if output_hidden_states and output_hidden_states_before_downsampling: + # rearrange b h w c -> b c h w + reshaped_hidden_state = hidden_states_before_downsampling.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states_before_downsampling,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + elif output_hidden_states and not output_hidden_states_before_downsampling: + # rearrange b h w c -> b c h w + reshaped_hidden_state = hidden_states.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + + if output_attentions: + all_self_attentions += layer_outputs[2:] + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + + return DinatEncoderOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + reshaped_hidden_states=all_reshaped_hidden_states, + ) + + +class DinatPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DinatConfig + base_model_prefix = "dinat" + main_input_name = "pixel_values" + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module: DinatEncoder, value: bool = False) -> None: + pass + + +DINAT_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`DinatConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DINAT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Dinat Model transformer outputting raw hidden-states without any specific head on top.", + DINAT_START_DOCSTRING, +) +# Copied from transformers.models.nat.modeling_nat.NatModel with Nat->Dinat, NAT->DINAT +class DinatModel(DinatPreTrainedModel): + def __init__(self, config, add_pooling_layer=True): + super().__init__(config) + + requires_backends(self, ["natten"]) + + self.config = config + self.num_levels = len(config.depths) + self.num_features = int(config.embed_dim * 2 ** (self.num_levels - 1)) + + self.embeddings = DinatEmbeddings(config) + self.encoder = DinatEncoder(config) + + self.layernorm = nn.LayerNorm(self.num_features, eps=config.layer_norm_eps) + self.pooler = nn.AdaptiveAvgPool1d(1) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(DINAT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=DinatModelOutput, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, DinatModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + embedding_output = self.embeddings(pixel_values) + + encoder_outputs = self.encoder( + embedding_output, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + + pooled_output = None + if self.pooler is not None: + pooled_output = self.pooler(sequence_output.flatten(1, 2).transpose(1, 2)) + pooled_output = torch.flatten(pooled_output, 1) + + if not return_dict: + output = (sequence_output, pooled_output) + encoder_outputs[1:] + + return output + + return DinatModelOutput( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + reshaped_hidden_states=encoder_outputs.reshaped_hidden_states, + ) + + +@add_start_docstrings( + """ + Dinat Model transformer with an image classification head on top (a linear layer on top of the final hidden state + of the [CLS] token) e.g. for ImageNet. + """, + DINAT_START_DOCSTRING, +) +class DinatForImageClassification(DinatPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + requires_backends(self, ["natten"]) + + self.num_labels = config.num_labels + self.dinat = DinatModel(config) + + # Classifier head + self.classifier = ( + nn.Linear(self.dinat.num_features, config.num_labels) if config.num_labels > 0 else nn.Identity() + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DINAT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=DinatImageClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, DinatImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.dinat( + pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return DinatImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + reshaped_hidden_states=outputs.reshaped_hidden_states, + ) + + +@add_start_docstrings( + "NAT backbone, to be used with frameworks like DETR and MaskFormer.", + DINAT_START_DOCSTRING, +) +class DinatBackbone(DinatPreTrainedModel, BackboneMixin): + def __init__(self, config): + super().__init__(config) + + requires_backends(self, ["natten"]) + + self.stage_names = config.stage_names + + self.embeddings = DinatEmbeddings(config) + self.encoder = DinatEncoder(config) + + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + config.out_features, config.out_indices, self.stage_names + ) + self.num_features = [config.embed_dim] + [int(config.embed_dim * 2**i) for i in range(len(config.depths))] + + # Add layer norms to hidden states of out_features + hidden_states_norms = {} + for stage, num_channels in zip(self._out_features, self.channels): + hidden_states_norms[stage] = nn.LayerNorm(num_channels) + self.hidden_states_norms = nn.ModuleDict(hidden_states_norms) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.patch_embeddings + + @add_start_docstrings_to_model_forward(DINAT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BackboneOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: torch.Tensor, + output_hidden_states: Optional[bool] = None, + output_attentions: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> BackboneOutput: + """ + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, AutoBackbone + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> processor = AutoImageProcessor.from_pretrained("shi-labs/nat-mini-in1k-224") + >>> model = AutoBackbone.from_pretrained( + ... "shi-labs/nat-mini-in1k-224", out_features=["stage1", "stage2", "stage3", "stage4"] + ... ) + + >>> inputs = processor(image, return_tensors="pt") + + >>> outputs = model(**inputs) + + >>> feature_maps = outputs.feature_maps + >>> list(feature_maps[-1].shape) + [1, 512, 7, 7] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + + embedding_output = self.embeddings(pixel_values) + + outputs = self.encoder( + embedding_output, + output_attentions=output_attentions, + output_hidden_states=True, + output_hidden_states_before_downsampling=True, + return_dict=True, + ) + + hidden_states = outputs.reshaped_hidden_states + + feature_maps = () + for stage, hidden_state in zip(self.stage_names, hidden_states): + if stage in self.out_features: + batch_size, num_channels, height, width = hidden_state.shape + hidden_state = hidden_state.permute(0, 2, 3, 1).contiguous() + hidden_state = hidden_state.view(batch_size, height * width, num_channels) + hidden_state = self.hidden_states_norms[stage](hidden_state) + hidden_state = hidden_state.view(batch_size, height, width, num_channels) + hidden_state = hidden_state.permute(0, 3, 1, 2).contiguous() + feature_maps += (hidden_state,) + + if not return_dict: + output = (feature_maps,) + if output_hidden_states: + output += (outputs.hidden_states,) + return output + + return BackboneOutput( + feature_maps=feature_maps, + hidden_states=outputs.hidden_states if output_hidden_states else None, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6a2756eb9d1c269e08446f9328120738196349d0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/__init__.py @@ -0,0 +1,166 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_distilbert": [ + "DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP", + "DistilBertConfig", + "DistilBertOnnxConfig", + ], + "tokenization_distilbert": ["DistilBertTokenizer"], +} + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_distilbert_fast"] = ["DistilBertTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_distilbert"] = [ + "DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST", + "DistilBertForMaskedLM", + "DistilBertForMultipleChoice", + "DistilBertForQuestionAnswering", + "DistilBertForSequenceClassification", + "DistilBertForTokenClassification", + "DistilBertModel", + "DistilBertPreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_distilbert"] = [ + "TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFDistilBertForMaskedLM", + "TFDistilBertForMultipleChoice", + "TFDistilBertForQuestionAnswering", + "TFDistilBertForSequenceClassification", + "TFDistilBertForTokenClassification", + "TFDistilBertMainLayer", + "TFDistilBertModel", + "TFDistilBertPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_distilbert"] = [ + "FlaxDistilBertForMaskedLM", + "FlaxDistilBertForMultipleChoice", + "FlaxDistilBertForQuestionAnswering", + "FlaxDistilBertForSequenceClassification", + "FlaxDistilBertForTokenClassification", + "FlaxDistilBertModel", + "FlaxDistilBertPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_distilbert import ( + DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, + DistilBertConfig, + DistilBertOnnxConfig, + ) + from .tokenization_distilbert import DistilBertTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_distilbert_fast import DistilBertTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_distilbert import ( + DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + DistilBertForMaskedLM, + DistilBertForMultipleChoice, + DistilBertForQuestionAnswering, + DistilBertForSequenceClassification, + DistilBertForTokenClassification, + DistilBertModel, + DistilBertPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_distilbert import ( + TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + TFDistilBertForMaskedLM, + TFDistilBertForMultipleChoice, + TFDistilBertForQuestionAnswering, + TFDistilBertForSequenceClassification, + TFDistilBertForTokenClassification, + TFDistilBertMainLayer, + TFDistilBertModel, + TFDistilBertPreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_distilbert import ( + FlaxDistilBertForMaskedLM, + FlaxDistilBertForMultipleChoice, + FlaxDistilBertForQuestionAnswering, + FlaxDistilBertForSequenceClassification, + FlaxDistilBertForTokenClassification, + FlaxDistilBertModel, + FlaxDistilBertPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/configuration_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/configuration_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..3dabb3d3e2340e49bb8df47580cf7cd9ae9631fb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/configuration_distilbert.py @@ -0,0 +1,154 @@ +# coding=utf-8 +# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DistilBERT model configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "distilbert-base-uncased": "https://huggingface.co/distilbert-base-uncased/resolve/main/config.json", + "distilbert-base-uncased-distilled-squad": ( + "https://huggingface.co/distilbert-base-uncased-distilled-squad/resolve/main/config.json" + ), + "distilbert-base-cased": "https://huggingface.co/distilbert-base-cased/resolve/main/config.json", + "distilbert-base-cased-distilled-squad": ( + "https://huggingface.co/distilbert-base-cased-distilled-squad/resolve/main/config.json" + ), + "distilbert-base-german-cased": "https://huggingface.co/distilbert-base-german-cased/resolve/main/config.json", + "distilbert-base-multilingual-cased": ( + "https://huggingface.co/distilbert-base-multilingual-cased/resolve/main/config.json" + ), + "distilbert-base-uncased-finetuned-sst-2-english": ( + "https://huggingface.co/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/config.json" + ), +} + + +class DistilBertConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DistilBertModel`] or a [`TFDistilBertModel`]. It + is used to instantiate a DistilBERT model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the DistilBERT + [distilbert-base-uncased](https://huggingface.co/distilbert-base-uncased) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the DistilBERT model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`DistilBertModel`] or [`TFDistilBertModel`]. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + sinusoidal_pos_embds (`boolean`, *optional*, defaults to `False`): + Whether to use sinusoidal positional embeddings. + n_layers (`int`, *optional*, defaults to 6): + Number of hidden layers in the Transformer encoder. + n_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + dim (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + hidden_dim (`int`, *optional*, defaults to 3072): + The size of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + activation (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + qa_dropout (`float`, *optional*, defaults to 0.1): + The dropout probabilities used in the question answering model [`DistilBertForQuestionAnswering`]. + seq_classif_dropout (`float`, *optional*, defaults to 0.2): + The dropout probabilities used in the sequence classification and the multiple choice model + [`DistilBertForSequenceClassification`]. + + Examples: + + ```python + >>> from transformers import DistilBertConfig, DistilBertModel + + >>> # Initializing a DistilBERT configuration + >>> configuration = DistilBertConfig() + + >>> # Initializing a model (with random weights) from the configuration + >>> model = DistilBertModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "distilbert" + attribute_map = { + "hidden_size": "dim", + "num_attention_heads": "n_heads", + "num_hidden_layers": "n_layers", + } + + def __init__( + self, + vocab_size=30522, + max_position_embeddings=512, + sinusoidal_pos_embds=False, + n_layers=6, + n_heads=12, + dim=768, + hidden_dim=4 * 768, + dropout=0.1, + attention_dropout=0.1, + activation="gelu", + initializer_range=0.02, + qa_dropout=0.1, + seq_classif_dropout=0.2, + pad_token_id=0, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.sinusoidal_pos_embds = sinusoidal_pos_embds + self.n_layers = n_layers + self.n_heads = n_heads + self.dim = dim + self.hidden_dim = hidden_dim + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation = activation + self.initializer_range = initializer_range + self.qa_dropout = qa_dropout + self.seq_classif_dropout = seq_classif_dropout + super().__init__(**kwargs, pad_token_id=pad_token_id) + + +class DistilBertOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..84db89e0f4b50284b5ba1b3947bd3330497e8659 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_distilbert.py @@ -0,0 +1,1153 @@ +# coding=utf-8 +# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" + PyTorch DistilBERT model adapted in part from Facebook, Inc XLM model (https://github.com/facebookresearch/XLM) and in + part from HuggingFace PyTorch version of Google AI Bert model (https://github.com/google-research/bert) +""" + + +import math +from typing import Dict, List, Optional, Set, Tuple, Union + +import numpy as np +import torch +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import get_activation +from ...configuration_utils import PretrainedConfig +from ...deepspeed import is_deepspeed_zero3_enabled +from ...modeling_outputs import ( + BaseModelOutput, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_distilbert import DistilBertConfig + + +logger = logging.get_logger(__name__) +_CHECKPOINT_FOR_DOC = "distilbert-base-uncased" +_CONFIG_FOR_DOC = "DistilBertConfig" + +DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "distilbert-base-uncased", + "distilbert-base-uncased-distilled-squad", + "distilbert-base-cased", + "distilbert-base-cased-distilled-squad", + "distilbert-base-german-cased", + "distilbert-base-multilingual-cased", + "distilbert-base-uncased-finetuned-sst-2-english", + # See all DistilBERT models at https://huggingface.co/models?filter=distilbert +] + + +# UTILS AND BUILDING BLOCKS OF THE ARCHITECTURE # + + +def create_sinusoidal_embeddings(n_pos: int, dim: int, out: torch.Tensor): + if is_deepspeed_zero3_enabled(): + import deepspeed + + with deepspeed.zero.GatheredParameters(out, modifier_rank=0): + if torch.distributed.get_rank() == 0: + _create_sinusoidal_embeddings(n_pos=n_pos, dim=dim, out=out) + else: + _create_sinusoidal_embeddings(n_pos=n_pos, dim=dim, out=out) + + +def _create_sinusoidal_embeddings(n_pos: int, dim: int, out: torch.Tensor): + position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) + out.requires_grad = False + out[:, 0::2] = torch.FloatTensor(np.sin(position_enc[:, 0::2])) + out[:, 1::2] = torch.FloatTensor(np.cos(position_enc[:, 1::2])) + out.detach_() + + +class Embeddings(nn.Module): + def __init__(self, config: PretrainedConfig): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.dim, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.dim) + if config.sinusoidal_pos_embds: + create_sinusoidal_embeddings( + n_pos=config.max_position_embeddings, dim=config.dim, out=self.position_embeddings.weight + ) + + self.LayerNorm = nn.LayerNorm(config.dim, eps=1e-12) + self.dropout = nn.Dropout(config.dropout) + self.register_buffer( + "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False + ) + + def forward(self, input_ids: torch.Tensor, input_embeds: Optional[torch.Tensor] = None) -> torch.Tensor: + """ + Parameters: + input_ids (torch.Tensor): + torch.tensor(bs, max_seq_length) The token ids to embed. + input_embeds (*optional*, torch.Tensor): + The pre-computed word embeddings. Can only be passed if the input ids are `None`. + + + Returns: torch.tensor(bs, max_seq_length, dim) The embedded tokens (plus position embeddings, no token_type + embeddings) + """ + if input_ids is not None: + input_embeds = self.word_embeddings(input_ids) # (bs, max_seq_length, dim) + + seq_length = input_embeds.size(1) + + # Setting the position-ids to the registered buffer in constructor, it helps + # when tracing the model without passing position-ids, solves + # isues similar to issue #5664 + if hasattr(self, "position_ids"): + position_ids = self.position_ids[:, :seq_length] + else: + position_ids = torch.arange(seq_length, dtype=torch.long, device=input_ids.device) # (max_seq_length) + position_ids = position_ids.unsqueeze(0).expand_as(input_ids) # (bs, max_seq_length) + + position_embeddings = self.position_embeddings(position_ids) # (bs, max_seq_length, dim) + + embeddings = input_embeds + position_embeddings # (bs, max_seq_length, dim) + embeddings = self.LayerNorm(embeddings) # (bs, max_seq_length, dim) + embeddings = self.dropout(embeddings) # (bs, max_seq_length, dim) + return embeddings + + +class MultiHeadSelfAttention(nn.Module): + def __init__(self, config: PretrainedConfig): + super().__init__() + + self.n_heads = config.n_heads + self.dim = config.dim + self.dropout = nn.Dropout(p=config.attention_dropout) + + # Have an even number of multi heads that divide the dimensions + if self.dim % self.n_heads != 0: + # Raise value errors for even multi-head attention nodes + raise ValueError(f"self.n_heads: {self.n_heads} must divide self.dim: {self.dim} evenly") + + self.q_lin = nn.Linear(in_features=config.dim, out_features=config.dim) + self.k_lin = nn.Linear(in_features=config.dim, out_features=config.dim) + self.v_lin = nn.Linear(in_features=config.dim, out_features=config.dim) + self.out_lin = nn.Linear(in_features=config.dim, out_features=config.dim) + + self.pruned_heads: Set[int] = set() + self.attention_head_size = self.dim // self.n_heads + + def prune_heads(self, heads: List[int]): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.n_heads, self.attention_head_size, self.pruned_heads + ) + # Prune linear layers + self.q_lin = prune_linear_layer(self.q_lin, index) + self.k_lin = prune_linear_layer(self.k_lin, index) + self.v_lin = prune_linear_layer(self.v_lin, index) + self.out_lin = prune_linear_layer(self.out_lin, index, dim=1) + # Update hyper params + self.n_heads = self.n_heads - len(heads) + self.dim = self.attention_head_size * self.n_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + mask: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, ...]: + """ + Parameters: + query: torch.tensor(bs, seq_length, dim) + key: torch.tensor(bs, seq_length, dim) + value: torch.tensor(bs, seq_length, dim) + mask: torch.tensor(bs, seq_length) + + Returns: + weights: torch.tensor(bs, n_heads, seq_length, seq_length) Attention weights context: torch.tensor(bs, + seq_length, dim) Contextualized layer. Optional: only if `output_attentions=True` + """ + bs, q_length, dim = query.size() + k_length = key.size(1) + # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' + # assert key.size() == value.size() + + dim_per_head = self.dim // self.n_heads + + mask_reshp = (bs, 1, 1, k_length) + + def shape(x: torch.Tensor) -> torch.Tensor: + """separate heads""" + return x.view(bs, -1, self.n_heads, dim_per_head).transpose(1, 2) + + def unshape(x: torch.Tensor) -> torch.Tensor: + """group heads""" + return x.transpose(1, 2).contiguous().view(bs, -1, self.n_heads * dim_per_head) + + q = shape(self.q_lin(query)) # (bs, n_heads, q_length, dim_per_head) + k = shape(self.k_lin(key)) # (bs, n_heads, k_length, dim_per_head) + v = shape(self.v_lin(value)) # (bs, n_heads, k_length, dim_per_head) + + q = q / math.sqrt(dim_per_head) # (bs, n_heads, q_length, dim_per_head) + scores = torch.matmul(q, k.transpose(2, 3)) # (bs, n_heads, q_length, k_length) + mask = (mask == 0).view(mask_reshp).expand_as(scores) # (bs, n_heads, q_length, k_length) + scores = scores.masked_fill( + mask, torch.tensor(torch.finfo(scores.dtype).min) + ) # (bs, n_heads, q_length, k_length) + + weights = nn.functional.softmax(scores, dim=-1) # (bs, n_heads, q_length, k_length) + weights = self.dropout(weights) # (bs, n_heads, q_length, k_length) + + # Mask heads if we want to + if head_mask is not None: + weights = weights * head_mask + + context = torch.matmul(weights, v) # (bs, n_heads, q_length, dim_per_head) + context = unshape(context) # (bs, q_length, dim) + context = self.out_lin(context) # (bs, q_length, dim) + + if output_attentions: + return (context, weights) + else: + return (context,) + + +class FFN(nn.Module): + def __init__(self, config: PretrainedConfig): + super().__init__() + self.dropout = nn.Dropout(p=config.dropout) + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.lin1 = nn.Linear(in_features=config.dim, out_features=config.hidden_dim) + self.lin2 = nn.Linear(in_features=config.hidden_dim, out_features=config.dim) + self.activation = get_activation(config.activation) + + def forward(self, input: torch.Tensor) -> torch.Tensor: + return apply_chunking_to_forward(self.ff_chunk, self.chunk_size_feed_forward, self.seq_len_dim, input) + + def ff_chunk(self, input: torch.Tensor) -> torch.Tensor: + x = self.lin1(input) + x = self.activation(x) + x = self.lin2(x) + x = self.dropout(x) + return x + + +class TransformerBlock(nn.Module): + def __init__(self, config: PretrainedConfig): + super().__init__() + + # Have an even number of Configure multi-heads + if config.dim % config.n_heads != 0: + raise ValueError(f"config.n_heads {config.n_heads} must divide config.dim {config.dim} evenly") + + self.attention = MultiHeadSelfAttention(config) + self.sa_layer_norm = nn.LayerNorm(normalized_shape=config.dim, eps=1e-12) + + self.ffn = FFN(config) + self.output_layer_norm = nn.LayerNorm(normalized_shape=config.dim, eps=1e-12) + + def forward( + self, + x: torch.Tensor, + attn_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, ...]: + """ + Parameters: + x: torch.tensor(bs, seq_length, dim) + attn_mask: torch.tensor(bs, seq_length) + + Returns: + sa_weights: torch.tensor(bs, n_heads, seq_length, seq_length) The attention weights ffn_output: + torch.tensor(bs, seq_length, dim) The output of the transformer block contextualization. + """ + # Self-Attention + sa_output = self.attention( + query=x, + key=x, + value=x, + mask=attn_mask, + head_mask=head_mask, + output_attentions=output_attentions, + ) + if output_attentions: + sa_output, sa_weights = sa_output # (bs, seq_length, dim), (bs, n_heads, seq_length, seq_length) + else: # To handle these `output_attentions` or `output_hidden_states` cases returning tuples + if type(sa_output) != tuple: + raise TypeError(f"sa_output must be a tuple but it is {type(sa_output)} type") + + sa_output = sa_output[0] + sa_output = self.sa_layer_norm(sa_output + x) # (bs, seq_length, dim) + + # Feed Forward Network + ffn_output = self.ffn(sa_output) # (bs, seq_length, dim) + ffn_output: torch.Tensor = self.output_layer_norm(ffn_output + sa_output) # (bs, seq_length, dim) + + output = (ffn_output,) + if output_attentions: + output = (sa_weights,) + output + return output + + +class Transformer(nn.Module): + def __init__(self, config: PretrainedConfig): + super().__init__() + self.n_layers = config.n_layers + self.layer = nn.ModuleList([TransformerBlock(config) for _ in range(config.n_layers)]) + + def forward( + self, + x: torch.Tensor, + attn_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: Optional[bool] = None, + ) -> Union[BaseModelOutput, Tuple[torch.Tensor, ...]]: # docstyle-ignore + """ + Parameters: + x: torch.tensor(bs, seq_length, dim) Input sequence embedded. + attn_mask: torch.tensor(bs, seq_length) Attention mask on the sequence. + + Returns: + hidden_state: torch.tensor(bs, seq_length, dim) Sequence of hidden states in the last (top) + layer all_hidden_states: Tuple[torch.tensor(bs, seq_length, dim)] + Tuple of length n_layers with the hidden states from each layer. + Optional: only if output_hidden_states=True + all_attentions: Tuple[torch.tensor(bs, n_heads, seq_length, seq_length)] + Tuple of length n_layers with the attention weights from each layer + Optional: only if output_attentions=True + """ + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + hidden_state = x + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_state,) + + layer_outputs = layer_module( + x=hidden_state, attn_mask=attn_mask, head_mask=head_mask[i], output_attentions=output_attentions + ) + hidden_state = layer_outputs[-1] + + if output_attentions: + if len(layer_outputs) != 2: + raise ValueError(f"The length of the layer_outputs should be 2, but it is {len(layer_outputs)}") + + attentions = layer_outputs[0] + all_attentions = all_attentions + (attentions,) + else: + if len(layer_outputs) != 1: + raise ValueError(f"The length of the layer_outputs should be 1, but it is {len(layer_outputs)}") + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_state,) + + if not return_dict: + return tuple(v for v in [hidden_state, all_hidden_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_state, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +# INTERFACE FOR ENCODER AND TASK SPECIFIC MODEL # +class DistilBertPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DistilBertConfig + load_tf_weights = None + base_model_prefix = "distilbert" + + def _init_weights(self, module: nn.Module): + """Initialize the weights.""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +DISTILBERT_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`DistilBertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DISTILBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DistilBERT encoder/transformer outputting raw hidden-states without any specific head on top.", + DISTILBERT_START_DOCSTRING, +) +class DistilBertModel(DistilBertPreTrainedModel): + def __init__(self, config: PretrainedConfig): + super().__init__(config) + + self.embeddings = Embeddings(config) # Embeddings + self.transformer = Transformer(config) # Encoder + + # Initialize weights and apply final processing + self.post_init() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.embeddings.position_embeddings + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`): + The number of new position embedding matrix. If position embeddings are learned, increasing the size + will add newly initialized vectors at the end, whereas reducing the size will remove vectors from the + end. If position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the + size will add correct vectors at the end following the position encoding algorithm, whereas reducing + the size will remove vectors from the end. + """ + num_position_embeds_diff = new_num_position_embeddings - self.config.max_position_embeddings + + # no resizing needs to be done if the length stays the same + if num_position_embeds_diff == 0: + return + + logger.info(f"Setting `config.max_position_embeddings={new_num_position_embeddings}`...") + self.config.max_position_embeddings = new_num_position_embeddings + + old_position_embeddings_weight = self.embeddings.position_embeddings.weight.clone() + + self.embeddings.position_embeddings = nn.Embedding(self.config.max_position_embeddings, self.config.dim) + + if self.config.sinusoidal_pos_embds: + create_sinusoidal_embeddings( + n_pos=self.config.max_position_embeddings, dim=self.config.dim, out=self.position_embeddings.weight + ) + else: + with torch.no_grad(): + if num_position_embeds_diff > 0: + self.embeddings.position_embeddings.weight[:-num_position_embeds_diff] = nn.Parameter( + old_position_embeddings_weight + ) + else: + self.embeddings.position_embeddings.weight = nn.Parameter( + old_position_embeddings_weight[:num_position_embeds_diff] + ) + # move position_embeddings to correct device + self.embeddings.position_embeddings.to(self.device) + + def get_input_embeddings(self) -> nn.Embedding: + return self.embeddings.word_embeddings + + def set_input_embeddings(self, new_embeddings: nn.Embedding): + self.embeddings.word_embeddings = new_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[List[int]]]): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.transformer.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[BaseModelOutput, Tuple[torch.Tensor, ...]]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) # (bs, seq_length) + + # Prepare head mask if needed + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embeddings = self.embeddings(input_ids, inputs_embeds) # (bs, seq_length, dim) + + return self.transformer( + x=embeddings, + attn_mask=attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +@add_start_docstrings( + """DistilBert Model with a `masked language modeling` head on top.""", + DISTILBERT_START_DOCSTRING, +) +class DistilBertForMaskedLM(DistilBertPreTrainedModel): + _keys_to_ignore_on_load_missing = ["vocab_projector.weight"] + + def __init__(self, config: PretrainedConfig): + super().__init__(config) + + self.activation = get_activation(config.activation) + + self.distilbert = DistilBertModel(config) + self.vocab_transform = nn.Linear(config.dim, config.dim) + self.vocab_layer_norm = nn.LayerNorm(config.dim, eps=1e-12) + self.vocab_projector = nn.Linear(config.dim, config.vocab_size) + + # Initialize weights and apply final processing + self.post_init() + + self.mlm_loss_fct = nn.CrossEntropyLoss() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.distilbert.get_position_embeddings() + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`): + The number of new position embedding matrix. If position embeddings are learned, increasing the size + will add newly initialized vectors at the end, whereas reducing the size will remove vectors from the + end. If position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the + size will add correct vectors at the end following the position encoding algorithm, whereas reducing + the size will remove vectors from the end. + """ + self.distilbert.resize_position_embeddings(new_num_position_embeddings) + + def get_output_embeddings(self) -> nn.Module: + return self.vocab_projector + + def set_output_embeddings(self, new_embeddings: nn.Module): + self.vocab_projector = new_embeddings + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[MaskedLMOutput, Tuple[torch.Tensor, ...]]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + dlbrt_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = dlbrt_output[0] # (bs, seq_length, dim) + prediction_logits = self.vocab_transform(hidden_states) # (bs, seq_length, dim) + prediction_logits = self.activation(prediction_logits) # (bs, seq_length, dim) + prediction_logits = self.vocab_layer_norm(prediction_logits) # (bs, seq_length, dim) + prediction_logits = self.vocab_projector(prediction_logits) # (bs, seq_length, vocab_size) + + mlm_loss = None + if labels is not None: + mlm_loss = self.mlm_loss_fct(prediction_logits.view(-1, prediction_logits.size(-1)), labels.view(-1)) + + if not return_dict: + output = (prediction_logits,) + dlbrt_output[1:] + return ((mlm_loss,) + output) if mlm_loss is not None else output + + return MaskedLMOutput( + loss=mlm_loss, + logits=prediction_logits, + hidden_states=dlbrt_output.hidden_states, + attentions=dlbrt_output.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class DistilBertForSequenceClassification(DistilBertPreTrainedModel): + def __init__(self, config: PretrainedConfig): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.distilbert = DistilBertModel(config) + self.pre_classifier = nn.Linear(config.dim, config.dim) + self.classifier = nn.Linear(config.dim, config.num_labels) + self.dropout = nn.Dropout(config.seq_classif_dropout) + + # Initialize weights and apply final processing + self.post_init() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.distilbert.get_position_embeddings() + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`): + The number of new position embedding matrix. If position embeddings are learned, increasing the size + will add newly initialized vectors at the end, whereas reducing the size will remove vectors from the + end. If position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the + size will add correct vectors at the end following the position encoding algorithm, whereas reducing + the size will remove vectors from the end. + """ + self.distilbert.resize_position_embeddings(new_num_position_embeddings) + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[SequenceClassifierOutput, Tuple[torch.Tensor, ...]]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + distilbert_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_state = distilbert_output[0] # (bs, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs, dim) + pooled_output = nn.ReLU()(pooled_output) # (bs, dim) + pooled_output = self.dropout(pooled_output) # (bs, dim) + logits = self.classifier(pooled_output) # (bs, num_labels) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + distilbert_output[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DISTILBERT_START_DOCSTRING, +) +class DistilBertForQuestionAnswering(DistilBertPreTrainedModel): + def __init__(self, config: PretrainedConfig): + super().__init__(config) + + self.distilbert = DistilBertModel(config) + self.qa_outputs = nn.Linear(config.dim, config.num_labels) + if config.num_labels != 2: + raise ValueError(f"config.num_labels should be 2, but it is {config.num_labels}") + + self.dropout = nn.Dropout(config.qa_dropout) + + # Initialize weights and apply final processing + self.post_init() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.distilbert.get_position_embeddings() + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`): + The number of new position embedding matrix. If position embeddings are learned, increasing the size + will add newly initialized vectors at the end, whereas reducing the size will remove vectors from the + end. If position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the + size will add correct vectors at the end following the position encoding algorithm, whereas reducing + the size will remove vectors from the end. + """ + self.distilbert.resize_position_embeddings(new_num_position_embeddings) + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[QuestionAnsweringModelOutput, Tuple[torch.Tensor, ...]]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + distilbert_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = distilbert_output[0] # (bs, max_query_len, dim) + + hidden_states = self.dropout(hidden_states) # (bs, max_query_len, dim) + logits = self.qa_outputs(hidden_states) # (bs, max_query_len, 2) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() # (bs, max_query_len) + end_logits = end_logits.squeeze(-1).contiguous() # (bs, max_query_len) + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = nn.CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + distilbert_output[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class DistilBertForTokenClassification(DistilBertPreTrainedModel): + def __init__(self, config: PretrainedConfig): + super().__init__(config) + self.num_labels = config.num_labels + + self.distilbert = DistilBertModel(config) + self.dropout = nn.Dropout(config.dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.distilbert.get_position_embeddings() + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`): + The number of new position embedding matrix. If position embeddings are learned, increasing the size + will add newly initialized vectors at the end, whereas reducing the size will remove vectors from the + end. If position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the + size will add correct vectors at the end following the position encoding algorithm, whereas reducing + the size will remove vectors from the end. + """ + self.distilbert.resize_position_embeddings(new_num_position_embeddings) + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[TokenClassifierOutput, Tuple[torch.Tensor, ...]]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.distilbert( + input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class DistilBertForMultipleChoice(DistilBertPreTrainedModel): + def __init__(self, config: PretrainedConfig): + super().__init__(config) + + self.distilbert = DistilBertModel(config) + self.pre_classifier = nn.Linear(config.dim, config.dim) + self.classifier = nn.Linear(config.dim, 1) + self.dropout = nn.Dropout(config.seq_classif_dropout) + + # Initialize weights and apply final processing + self.post_init() + + def get_position_embeddings(self) -> nn.Embedding: + """ + Returns the position embeddings + """ + return self.distilbert.get_position_embeddings() + + def resize_position_embeddings(self, new_num_position_embeddings: int): + """ + Resizes position embeddings of the model if `new_num_position_embeddings != config.max_position_embeddings`. + + Arguments: + new_num_position_embeddings (`int`) + The number of new position embeddings. If position embeddings are learned, increasing the size will add + newly initialized vectors at the end, whereas reducing the size will remove vectors from the end. If + position embeddings are not learned (*e.g.* sinusoidal position embeddings), increasing the size will + add correct vectors at the end following the position encoding algorithm, whereas reducing the size + will remove vectors from the end. + """ + self.distilbert.resize_position_embeddings(new_num_position_embeddings) + + @add_start_docstrings_to_model_forward( + DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") + ) + @replace_return_docstrings(output_type=MultipleChoiceModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[MultipleChoiceModelOutput, Tuple[torch.Tensor, ...]]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + + Returns: + + Examples: + + ```python + >>> from transformers import AutoTokenizer, DistilBertForMultipleChoice + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-cased") + >>> model = DistilBertForMultipleChoice.from_pretrained("distilbert-base-cased") + + >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." + >>> choice0 = "It is eaten with a fork and a knife." + >>> choice1 = "It is eaten while held in the hand." + >>> labels = torch.tensor(0).unsqueeze(0) # choice0 is correct (according to Wikipedia ;)), batch size 1 + + >>> encoding = tokenizer([[prompt, choice0], [prompt, choice1]], return_tensors="pt", padding=True) + >>> outputs = model(**{k: v.unsqueeze(0) for k, v in encoding.items()}, labels=labels) # batch size is 1 + + >>> # the linear classifier still needs to be trained + >>> loss = outputs.loss + >>> logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.distilbert( + input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_state = outputs[0] # (bs * num_choices, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs * num_choices, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs * num_choices, dim) + pooled_output = nn.ReLU()(pooled_output) # (bs * num_choices, dim) + pooled_output = self.dropout(pooled_output) # (bs * num_choices, dim) + logits = self.classifier(pooled_output) # (bs * num_choices, 1) + + reshaped_logits = logits.view(-1, num_choices) # (bs, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_flax_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_flax_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..24e2c7e3987e07b40a3fbfb8bea97886124f7587 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_flax_distilbert.py @@ -0,0 +1,894 @@ +# coding=utf-8 +# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import math +from typing import Callable, Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutput, + FlaxMaskedLMOutput, + FlaxMultipleChoiceModelOutput, + FlaxQuestionAnsweringModelOutput, + FlaxSequenceClassifierOutput, + FlaxTokenClassifierOutput, +) +from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_distilbert import DistilBertConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "distilbert-base-uncased" +_CONFIG_FOR_DOC = "DistilBertConfig" + + +FLAX_DISTILBERT_START_DOCSTRING = r""" + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading, saving and converting weights from PyTorch models) + + This model is also a Flax Linen [flax.linen.Module](https://flax.readthedocs.io/en/latest/flax.linen.html#module) + subclass. Use it as a regular Flax linen Module and refer to the Flax documentation for all matter related to + general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`DistilBertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DISTILBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`numpy.ndarray` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +def get_angles(pos, i, d_model): + angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model)) + return pos * angle_rates + + +def positional_encoding(position, d_model): + # create the sinusoidal pattern for the positional encoding + angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], d_model) + + # apply sin to even indices in the array; 2i + angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2]) + + # apply cos to odd indices in the array; 2i+1 + angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2]) + + pos_encoding = angle_rads[np.newaxis, ...] + + return jnp.array(pos_encoding) + + +class FlaxEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.word_embeddings = nn.Embed( + self.config.vocab_size, + self.config.dim, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + if not self.config.sinusoidal_pos_embds: + self.position_embeddings = nn.Embed( + self.config.max_position_embeddings, + self.config.dim, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + else: + self.pos_encoding = positional_encoding(self.config.max_position_embeddings, self.config.dim) + self.LayerNorm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.dropout) + + def __call__(self, input_ids, deterministic: bool = True): + # Embed + batch_size, seq_length = input_ids.shape + inputs_embeds = self.word_embeddings(input_ids.astype("i4")) + if not self.config.sinusoidal_pos_embds: + position_ids = jnp.arange(seq_length).astype("i4") + position_ids = jnp.broadcast_to(position_ids, shape=(batch_size, seq_length)) + position_embeds = self.position_embeddings(position_ids.astype("i4")) + else: + position_embeds = self.pos_encoding[:, :seq_length, :] + # explictly cast the positions here, since self.embed_positions are not registered as parameters + position_embeds = position_embeds.astype(inputs_embeds.dtype) + + # Sum all embeddings + hidden_states = inputs_embeds + position_embeds + + # Layer Norm + hidden_states = self.LayerNorm(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxMultiHeadSelfAttention(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.n_heads = self.config.n_heads + self.dim = self.config.dim + self.dropout = nn.Dropout(rate=self.config.attention_dropout) + + if not (self.dim % self.n_heads == 0): + raise ValueError(f"Hidden size {self.dim} not dividable by number of heads {self.n_heads}") + + self.q_lin = nn.Dense( + self.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.k_lin = nn.Dense( + self.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.v_lin = nn.Dense( + self.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.out_lin = nn.Dense( + self.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + + def __call__( + self, + query, + key, + value, + mask, + deterministic: bool = True, + output_attentions: bool = False, + ): + bs, q_len, dim = query.shape + k_len = key.shape[1] + # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' + # assert key.size() == value.size() + + dim_per_head = self.dim // self.n_heads + + mask_reshp = (bs, 1, 1, k_len) + + def shape(x): + """separate heads""" + return x.reshape(bs, -1, self.n_heads, dim_per_head).transpose(0, 2, 1, 3) + + def unshape(x): + """group heads""" + return x.transpose(0, 2, 1, 3).reshape(bs, -1, self.n_heads * dim_per_head) + + q = shape(self.q_lin(query)) # (bs, n_heads, q_len, dim_per_head) + k = shape(self.k_lin(key)) # (bs, n_heads, k_len, dim_per_head) + v = shape(self.v_lin(value)) # (bs, n_heads, k_len, dim_per_head) + + q = q / math.sqrt(dim_per_head) # (bs, n_heads, q_len, dim_per_head) + scores = jnp.matmul(q, k.transpose(0, 1, 3, 2)) # (bs, n_heads, q_len, k_len) + mask = jnp.reshape(mask, mask_reshp) + + mask = mask.astype(scores.dtype) + scores = scores - 1e30 * (1.0 - mask) + + weights = nn.softmax(scores, axis=-1) # (bs, n_heads, q_len, k_len) + weights = self.dropout(weights, deterministic=deterministic) + + context = jnp.matmul(weights, v) # (bs, n_heads, q_len, dim_per_head) + context = unshape(context) # (bs, q_len, dim) + context = self.out_lin(context) # (bs, q_len, dim) + + if output_attentions: + return (context, weights) + else: + return (context,) + + +class FlaxFFN(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dropout = nn.Dropout(rate=self.config.dropout) + self.chunk_size_feed_forward = self.config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.lin1 = nn.Dense( + self.config.hidden_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.lin2 = nn.Dense( + self.config.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + + self.activation = ACT2FN[self.config.activation] + + def __call__(self, hidden_states, deterministic: bool = True): + hidden_states = self.lin1(hidden_states) + hidden_states = self.activation(hidden_states) + hidden_states = self.lin2(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxTransformerBlock(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + assert ( + self.config.dim % self.config.n_heads == 0 + ), f"Hidden size {self.config.dim} not dividable by number of heads {self.config.n_heads}" + + self.attention = FlaxMultiHeadSelfAttention(self.config, dtype=self.dtype) + self.sa_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) + + self.ffn = FlaxFFN(self.config, dtype=self.dtype) + self.output_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attn_mask, + output_attentions: bool = False, + deterministic: bool = True, + ): + # Self-Attention + sa_output = self.attention( + query=hidden_states, + key=hidden_states, + value=hidden_states, + mask=attn_mask, + output_attentions=output_attentions, + deterministic=deterministic, + ) + if output_attentions: + sa_output, sa_weights = sa_output + else: + assert type(sa_output) == tuple + sa_output = sa_output[0] + sa_output = self.sa_layer_norm(sa_output + hidden_states) + + # Feed Forward Network + ffn_output = self.ffn(sa_output, deterministic=deterministic) + ffn_output = self.output_layer_norm(ffn_output + sa_output) + output = (ffn_output,) + if output_attentions: + output = (sa_weights,) + output + return output + + +class FlaxTransformer(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxTransformerBlock(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.n_layers) + ] + + def __call__( + self, + hidden_states, + attention_mask, + output_attentions: bool = False, + output_hidden_states: bool = False, + deterministic: bool = True, + return_dict: bool = False, + ): + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + for layer_module in self.layers: + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states=hidden_states, + attn_mask=attention_mask, + output_attentions=output_attentions, + deterministic=deterministic, + ) + hidden_states = layer_outputs[-1] + + if output_attentions: + assert len(layer_outputs) == 2 + attentions = layer_outputs[0] + all_attentions = all_attentions + (attentions,) + else: + assert len(layer_outputs) == 1 + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_attentions, all_hidden_states] if v is not None) + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxTransformerEncoder(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layer = FlaxTransformer(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask, + output_attentions: bool = False, + output_hidden_states: bool = False, + deterministic: bool = True, + return_dict: bool = False, + ): + return self.layer( + hidden_states=hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + deterministic=deterministic, + return_dict=return_dict, + ) + + +class FlaxDistilBertLMDecoder(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros + + def setup(self): + self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) + + def __call__(self, inputs, kernel): + inputs = jnp.asarray(inputs, self.dtype) + kernel = jnp.asarray(kernel, self.dtype) + y = lax.dot_general(inputs, kernel, (((inputs.ndim - 1,), (0,)), ((), ()))) + bias = jnp.asarray(self.bias, self.dtype) + y = y + bias + return y + + +class FlaxDistilBertPreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DistilBertConfig + base_model_prefix = "distilbert" + module_class: nn.Module = None + + def __init__( + self, + config: DistilBertConfig, + input_shape: Tuple = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + attention_mask = jnp.ones_like(input_ids) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init(rngs, input_ids, attention_mask, return_dict=False)["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def __call__( + self, + input_ids, + attention_mask=None, + head_mask=None, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + return self.module.apply( + {"params": params or self.params}, + jnp.array(input_ids, dtype="i4"), + jnp.array(attention_mask, dtype="i4"), + not train, + output_attentions, + output_hidden_states, + return_dict, + rngs=rngs, + ) + + +class FlaxDistilBertModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.embeddings = FlaxEmbeddings(self.config, dtype=self.dtype) + self.transformer = FlaxTransformerEncoder(self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + input_embeds = self.embeddings(input_ids, deterministic=deterministic) + return self.transformer( + hidden_states=input_embeds, + attention_mask=attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +@add_start_docstrings( + "The bare DistilBert Model transformer outputting raw hidden-states without any specific head on top.", + FLAX_DISTILBERT_START_DOCSTRING, +) +class FlaxDistilBertModel(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertModule + + +append_call_sample_docstring(FlaxDistilBertModel, _CHECKPOINT_FOR_DOC, None, _CONFIG_FOR_DOC) + + +class FlaxDistilBertForMaskedLMModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.distilbert = FlaxDistilBertModule(self.config, dtype=self.dtype) + self.vocab_transform = nn.Dense( + self.config.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.vocab_layer_norm = nn.LayerNorm(epsilon=1e-12, dtype=self.dtype) + if self.config.tie_word_embeddings: + self.vocab_projector = FlaxDistilBertLMDecoder( + self.config, + dtype=self.dtype, + ) + else: + self.vocab_projector = nn.Dense( + self.config.vocab_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + dlbrt_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + deterministic=deterministic, + return_dict=return_dict, + ) + hidden_states = dlbrt_output[0] + prediction_logits = self.vocab_transform(hidden_states) + prediction_logits = ACT2FN[self.config.activation](prediction_logits) + prediction_logits = self.vocab_layer_norm(prediction_logits) + + if self.config.tie_word_embeddings: + shared_embedding = self.distilbert.variables["params"]["embeddings"]["word_embeddings"]["embedding"] + prediction_logits = self.vocab_projector(prediction_logits, shared_embedding.T) + else: + prediction_logits = self.vocab_projector(prediction_logits) + + if not return_dict: + output = (prediction_logits,) + dlbrt_output[1:] + return output + + return FlaxMaskedLMOutput( + logits=prediction_logits, + hidden_states=dlbrt_output.hidden_states, + attentions=dlbrt_output.attentions, + ) + + +@add_start_docstrings("""DistilBert Model with a `language modeling` head on top.""", FLAX_DISTILBERT_START_DOCSTRING) +class FlaxDistilBertForMaskedLM(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertForMaskedLMModule + + +append_call_sample_docstring(FlaxDistilBertForMaskedLM, _CHECKPOINT_FOR_DOC, FlaxMaskedLMOutput, _CONFIG_FOR_DOC) + + +class FlaxDistilBertForSequenceClassificationModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) + self.pre_classifier = nn.Dense( + self.config.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.dropout = nn.Dropout(rate=self.config.seq_classif_dropout) + self.classifier = nn.Dense( + self.config.num_labels, + dtype=self.dtype, + ) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + # Model + distilbert_output = self.distilbert( + input_ids, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_state = distilbert_output[0] # (bs, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs, dim) + pooled_output = ACT2FN["relu"](pooled_output) + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) # (bs, dim) + + if not return_dict: + return (logits,) + distilbert_output[1:] + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + FLAX_DISTILBERT_START_DOCSTRING, +) +class FlaxDistilBertForSequenceClassification(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertForSequenceClassificationModule + + +append_call_sample_docstring( + FlaxDistilBertForSequenceClassification, + _CHECKPOINT_FOR_DOC, + FlaxSequenceClassifierOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxDistilBertForMultipleChoiceModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) + self.pre_classifier = nn.Dense( + self.config.dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + ) + self.dropout = nn.Dropout(rate=self.config.seq_classif_dropout) + self.classifier = nn.Dense( + 1, + dtype=self.dtype, + ) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] + input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None + attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None + + # Model + outputs = self.distilbert( + input_ids, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_state = outputs[0] + pooled_output = hidden_state[:, 0] + pooled_output = self.pre_classifier(pooled_output) + pooled_output = ACT2FN["relu"](pooled_output) + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) + + reshaped_logits = logits.reshape(-1, num_choices) + + if not return_dict: + return (reshaped_logits,) + outputs[2:] + + return FlaxMultipleChoiceModelOutput( + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + FLAX_DISTILBERT_START_DOCSTRING, +) +class FlaxDistilBertForMultipleChoice(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertForMultipleChoiceModule + + +overwrite_call_docstring( + FlaxDistilBertForMultipleChoice, DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") +) +append_call_sample_docstring( + FlaxDistilBertForMultipleChoice, + _CHECKPOINT_FOR_DOC, + FlaxMultipleChoiceModelOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxDistilBertForTokenClassificationModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.dropout) + self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + # Model + outputs = self.distilbert( + input_ids, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + logits = self.classifier(hidden_states) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxTokenClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + FLAX_DISTILBERT_START_DOCSTRING, +) +class FlaxDistilBertForTokenClassification(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertForTokenClassificationModule + + +append_call_sample_docstring( + FlaxDistilBertForTokenClassification, + _CHECKPOINT_FOR_DOC, + FlaxTokenClassifierOutput, + _CONFIG_FOR_DOC, +) + + +class FlaxDistilBertForQuestionAnsweringModule(nn.Module): + config: DistilBertConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.distilbert = FlaxDistilBertModule(config=self.config, dtype=self.dtype) + self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) + assert self.config.num_labels == 2 + self.dropout = nn.Dropout(rate=self.config.qa_dropout) + + def __call__( + self, + input_ids, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # Model + distilbert_output = self.distilbert( + input_ids, + attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = distilbert_output[0] + + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + logits = self.qa_outputs(hidden_states) + start_logits, end_logits = logits.split(self.config.num_labels, axis=-1) + start_logits = start_logits.squeeze(-1) + end_logits = end_logits.squeeze(-1) + + if not return_dict: + return (start_logits, end_logits) + distilbert_output[1:] + + return FlaxQuestionAnsweringModelOutput( + start_logits=start_logits, + end_logits=end_logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + +@add_start_docstrings( + """ + DistilBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + FLAX_DISTILBERT_START_DOCSTRING, +) +class FlaxDistilBertForQuestionAnswering(FlaxDistilBertPreTrainedModel): + module_class = FlaxDistilBertForQuestionAnsweringModule + + +append_call_sample_docstring( + FlaxDistilBertForQuestionAnswering, + _CHECKPOINT_FOR_DOC, + FlaxQuestionAnsweringModelOutput, + _CONFIG_FOR_DOC, +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_tf_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_tf_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..95c3aef42615724e9b620a2a91177499aabd844a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/modeling_tf_distilbert.py @@ -0,0 +1,1079 @@ +# coding=utf-8 +# Copyright 2019-present, the HuggingFace Inc. team, The Google AI Language Team and Facebook, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + TF 2.0 DistilBERT model +""" + +import warnings +from typing import Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFMaskedLMOutput, + TFMultipleChoiceModelOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFMaskedLanguageModelingLoss, + TFModelInputType, + TFMultipleChoiceLoss, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFTokenClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + MULTIPLE_CHOICE_DUMMY_INPUTS, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, +) +from .configuration_distilbert import DistilBertConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "distilbert-base-uncased" +_CONFIG_FOR_DOC = "DistilBertConfig" + +TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "distilbert-base-uncased", + "distilbert-base-uncased-distilled-squad", + "distilbert-base-cased", + "distilbert-base-cased-distilled-squad", + "distilbert-base-multilingual-cased", + "distilbert-base-uncased-finetuned-sst-2-english", + # See all DistilBERT models at https://huggingface.co/models?filter=distilbert +] + + +class TFEmbeddings(tf.keras.layers.Layer): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.config = config + self.dim = config.dim + self.initializer_range = config.initializer_range + self.max_position_embeddings = config.max_position_embeddings + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=1e-12, name="LayerNorm") + self.dropout = tf.keras.layers.Dropout(rate=config.dropout) + + def build(self, input_shape: tf.TensorShape): + with tf.name_scope("word_embeddings"): + self.weight = self.add_weight( + name="weight", + shape=[self.config.vocab_size, self.dim], + initializer=get_initializer(initializer_range=self.initializer_range), + ) + + with tf.name_scope("position_embeddings"): + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.dim], + initializer=get_initializer(initializer_range=self.initializer_range), + ) + + super().build(input_shape) + + def call(self, input_ids=None, position_ids=None, inputs_embeds=None, training=False): + """ + Applies embedding based on inputs tensor. + + Returns: + final_embeddings (`tf.Tensor`): output embedding tensor. + """ + assert not (input_ids is None and inputs_embeds is None) + + if input_ids is not None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.config.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.config.vocab_size})" + ), + ) + inputs_embeds = tf.gather(params=self.weight, indices=input_ids) + + input_shape = shape_list(inputs_embeds)[:-1] + + if position_ids is None: + position_ids = tf.expand_dims(tf.range(start=0, limit=input_shape[-1]), axis=0) + + position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) + final_embeddings = inputs_embeds + position_embeds + final_embeddings = self.LayerNorm(inputs=final_embeddings) + final_embeddings = self.dropout(inputs=final_embeddings, training=training) + + return final_embeddings + + +class TFMultiHeadSelfAttention(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.n_heads = config.n_heads + self.dim = config.dim + self.dropout = tf.keras.layers.Dropout(config.attention_dropout) + self.output_attentions = config.output_attentions + + assert self.dim % self.n_heads == 0, f"Hidden size {self.dim} not dividable by number of heads {self.n_heads}" + + self.q_lin = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="q_lin" + ) + self.k_lin = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="k_lin" + ) + self.v_lin = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="v_lin" + ) + self.out_lin = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="out_lin" + ) + + self.pruned_heads = set() + + def prune_heads(self, heads): + raise NotImplementedError + + def call(self, query, key, value, mask, head_mask, output_attentions, training=False): + """ + Parameters: + query: tf.Tensor(bs, seq_length, dim) + key: tf.Tensor(bs, seq_length, dim) + value: tf.Tensor(bs, seq_length, dim) + mask: tf.Tensor(bs, seq_length) + + Returns: + weights: tf.Tensor(bs, n_heads, seq_length, seq_length) Attention weights context: tf.Tensor(bs, + seq_length, dim) Contextualized layer. Optional: only if `output_attentions=True` + """ + bs, q_length, dim = shape_list(query) + k_length = shape_list(key)[1] + # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' + # assert key.size() == value.size() + dim_per_head = int(self.dim / self.n_heads) + dim_per_head = tf.cast(dim_per_head, dtype=tf.int32) + mask_reshape = [bs, 1, 1, k_length] + + def shape(x): + """separate heads""" + return tf.transpose(tf.reshape(x, (bs, -1, self.n_heads, dim_per_head)), perm=(0, 2, 1, 3)) + + def unshape(x): + """group heads""" + return tf.reshape(tf.transpose(x, perm=(0, 2, 1, 3)), (bs, -1, self.n_heads * dim_per_head)) + + q = shape(self.q_lin(query)) # (bs, n_heads, q_length, dim_per_head) + k = shape(self.k_lin(key)) # (bs, n_heads, k_length, dim_per_head) + v = shape(self.v_lin(value)) # (bs, n_heads, k_length, dim_per_head) + q = tf.cast(q, dtype=tf.float32) + q = tf.multiply(q, tf.math.rsqrt(tf.cast(dim_per_head, dtype=tf.float32))) + k = tf.cast(k, dtype=q.dtype) + scores = tf.matmul(q, k, transpose_b=True) # (bs, n_heads, q_length, k_length) + mask = tf.reshape(mask, mask_reshape) # (bs, n_heads, qlen, klen) + # scores.masked_fill_(mask, -float('inf')) # (bs, n_heads, q_length, k_length) + + mask = tf.cast(mask, dtype=scores.dtype) + scores = scores - 1e30 * (1.0 - mask) + weights = stable_softmax(scores, axis=-1) # (bs, n_heads, qlen, klen) + weights = self.dropout(weights, training=training) # (bs, n_heads, qlen, klen) + + # Mask heads if we want to + if head_mask is not None: + weights = weights * head_mask + + context = tf.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) + context = unshape(context) # (bs, q_length, dim) + context = self.out_lin(context) # (bs, q_length, dim) + + if output_attentions: + return (context, weights) + else: + return (context,) + + +class TFFFN(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.lin1 = tf.keras.layers.Dense( + config.hidden_dim, kernel_initializer=get_initializer(config.initializer_range), name="lin1" + ) + self.lin2 = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="lin2" + ) + self.activation = get_tf_activation(config.activation) + + def call(self, input, training=False): + x = self.lin1(input) + x = self.activation(x) + x = self.lin2(x) + x = self.dropout(x, training=training) + return x + + +class TFTransformerBlock(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.n_heads = config.n_heads + self.dim = config.dim + self.hidden_dim = config.hidden_dim + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation = config.activation + self.output_attentions = config.output_attentions + + assert ( + config.dim % config.n_heads == 0 + ), f"Hidden size {config.dim} not dividable by number of heads {config.n_heads}" + + self.attention = TFMultiHeadSelfAttention(config, name="attention") + self.sa_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-12, name="sa_layer_norm") + + self.ffn = TFFFN(config, name="ffn") + self.output_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-12, name="output_layer_norm") + + def call(self, x, attn_mask, head_mask, output_attentions, training=False): # removed: src_enc=None, src_len=None + """ + Parameters: + x: tf.Tensor(bs, seq_length, dim) + attn_mask: tf.Tensor(bs, seq_length) + + Outputs: sa_weights: tf.Tensor(bs, n_heads, seq_length, seq_length) The attention weights ffn_output: + tf.Tensor(bs, seq_length, dim) The output of the transformer block contextualization. + """ + # Self-Attention + sa_output = self.attention(x, x, x, attn_mask, head_mask, output_attentions, training=training) + if output_attentions: + sa_output, sa_weights = sa_output # (bs, seq_length, dim), (bs, n_heads, seq_length, seq_length) + else: # To handle these `output_attentions` or `output_hidden_states` cases returning tuples + # assert type(sa_output) == tuple + sa_output = sa_output[0] + sa_output = self.sa_layer_norm(sa_output + x) # (bs, seq_length, dim) + + # Feed Forward Network + ffn_output = self.ffn(sa_output, training=training) # (bs, seq_length, dim) + ffn_output = self.output_layer_norm(ffn_output + sa_output) # (bs, seq_length, dim) + + output = (ffn_output,) + if output_attentions: + output = (sa_weights,) + output + return output + + +class TFTransformer(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.n_layers = config.n_layers + self.output_hidden_states = config.output_hidden_states + self.output_attentions = config.output_attentions + + self.layer = [TFTransformerBlock(config, name=f"layer_._{i}") for i in range(config.n_layers)] + + def call(self, x, attn_mask, head_mask, output_attentions, output_hidden_states, return_dict, training=False): + # docstyle-ignore + """ + Parameters: + x: tf.Tensor(bs, seq_length, dim) Input sequence embedded. + attn_mask: tf.Tensor(bs, seq_length) Attention mask on the sequence. + + Returns: + hidden_state: tf.Tensor(bs, seq_length, dim) + Sequence of hidden states in the last (top) layer + all_hidden_states: Tuple[tf.Tensor(bs, seq_length, dim)] + Tuple of length n_layers with the hidden states from each layer. + Optional: only if output_hidden_states=True + all_attentions: Tuple[tf.Tensor(bs, n_heads, seq_length, seq_length)] + Tuple of length n_layers with the attention weights from each layer + Optional: only if output_attentions=True + """ + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + hidden_state = x + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_state,) + + layer_outputs = layer_module(hidden_state, attn_mask, head_mask[i], output_attentions, training=training) + hidden_state = layer_outputs[-1] + + if output_attentions: + assert len(layer_outputs) == 2 + attentions = layer_outputs[0] + all_attentions = all_attentions + (attentions,) + else: + assert len(layer_outputs) == 1, f"Incorrect number of outputs {len(layer_outputs)} instead of 1" + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_state,) + + if not return_dict: + return tuple(v for v in [hidden_state, all_hidden_states, all_attentions] if v is not None) + return TFBaseModelOutput( + last_hidden_state=hidden_state, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +@keras_serializable +class TFDistilBertMainLayer(tf.keras.layers.Layer): + config_class = DistilBertConfig + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.num_hidden_layers = config.num_hidden_layers + self.output_attentions = config.output_attentions + self.output_hidden_states = config.output_hidden_states + self.return_dict = config.use_return_dict + + self.embeddings = TFEmbeddings(config, name="embeddings") # Embeddings + self.transformer = TFTransformer(config, name="transformer") # Encoder + + def get_input_embeddings(self): + return self.embeddings + + def set_input_embeddings(self, value): + self.embeddings.weight = value + self.embeddings.vocab_size = value.shape[0] + + def _prune_heads(self, heads_to_prune): + raise NotImplementedError + + @unpack_inputs + def call( + self, + input_ids=None, + attention_mask=None, + head_mask=None, + inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ): + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = tf.ones(input_shape) # (bs, seq_length) + + attention_mask = tf.cast(attention_mask, dtype=tf.float32) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.num_hidden_layers + + embedding_output = self.embeddings(input_ids, inputs_embeds=inputs_embeds) # (bs, seq_length, dim) + tfmr_output = self.transformer( + embedding_output, + attention_mask, + head_mask, + output_attentions, + output_hidden_states, + return_dict, + training=training, + ) + + return tfmr_output # last-layer hidden-state, (all hidden_states), (all attentions) + + +# INTERFACE FOR ENCODER AND TASK SPECIFIC MODEL # +class TFDistilBertPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DistilBertConfig + base_model_prefix = "distilbert" + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + +DISTILBERT_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`DistilBertConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DISTILBERT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and + [`PreTrainedTokenizer.encode`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare DistilBERT encoder/transformer outputting raw hidden-states without any specific head on top.", + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertModel(TFDistilBertPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") # Embeddings + + @unpack_inputs + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + outputs = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + return outputs + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutput(last_hidden_state=output.last_hidden_state, hidden_states=hs, attentions=attns) + + +class TFDistilBertLMHead(tf.keras.layers.Layer): + def __init__(self, config, input_embeddings, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.dim = config.dim + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.input_embeddings = input_embeddings + + def build(self, input_shape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + + super().build(input_shape) + + def get_output_embeddings(self): + return self.input_embeddings + + def set_output_embeddings(self, value): + self.input_embeddings.weight = value + self.input_embeddings.vocab_size = shape_list(value)[0] + + def get_bias(self): + return {"bias": self.bias} + + def set_bias(self, value): + self.bias = value["bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states): + seq_length = shape_list(tensor=hidden_states)[1] + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.dim]) + hidden_states = tf.matmul(a=hidden_states, b=self.input_embeddings.weight, transpose_b=True) + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) + hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) + + return hidden_states + + +@add_start_docstrings( + """DistilBert Model with a `masked language modeling` head on top.""", + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertForMaskedLM(TFDistilBertPreTrainedModel, TFMaskedLanguageModelingLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.config = config + + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") + self.vocab_transform = tf.keras.layers.Dense( + config.dim, kernel_initializer=get_initializer(config.initializer_range), name="vocab_transform" + ) + self.act = get_tf_activation(config.activation) + self.vocab_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-12, name="vocab_layer_norm") + self.vocab_projector = TFDistilBertLMHead(config, self.distilbert.embeddings, name="vocab_projector") + + def get_lm_head(self): + return self.vocab_projector + + def get_prefix_bias_name(self): + warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) + return self.name + "/" + self.vocab_projector.name + + @unpack_inputs + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMaskedLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + distilbert_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_states = distilbert_output[0] # (bs, seq_length, dim) + prediction_logits = self.vocab_transform(hidden_states) # (bs, seq_length, dim) + prediction_logits = self.act(prediction_logits) # (bs, seq_length, dim) + prediction_logits = self.vocab_layer_norm(prediction_logits) # (bs, seq_length, dim) + prediction_logits = self.vocab_projector(prediction_logits) + + loss = None if labels is None else self.hf_compute_loss(labels, prediction_logits) + + if not return_dict: + output = (prediction_logits,) + distilbert_output[1:] + return ((loss,) + output) if loss is not None else output + + return TFMaskedLMOutput( + loss=loss, + logits=prediction_logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMaskedLM.serving_output + def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedLMOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DistilBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertForSequenceClassification(TFDistilBertPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") + self.pre_classifier = tf.keras.layers.Dense( + config.dim, + kernel_initializer=get_initializer(config.initializer_range), + activation="relu", + name="pre_classifier", + ) + self.classifier = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + self.dropout = tf.keras.layers.Dropout(config.seq_classif_dropout) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + distilbert_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_state = distilbert_output[0] # (bs, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs, dim) + pooled_output = self.dropout(pooled_output, training=training) # (bs, dim) + logits = self.classifier(pooled_output) # (bs, dim) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + distilbert_output[1:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForSequenceClassification.serving_output + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DistilBert Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertForTokenClassification(TFDistilBertPreTrainedModel, TFTokenClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.classifier = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + sequence_output = self.dropout(sequence_output, training=training) + logits = self.classifier(sequence_output) + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForTokenClassification.serving_output + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DistilBert Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertForMultipleChoice(TFDistilBertPreTrainedModel, TFMultipleChoiceLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") + self.dropout = tf.keras.layers.Dropout(config.seq_classif_dropout) + self.pre_classifier = tf.keras.layers.Dense( + config.dim, + kernel_initializer=get_initializer(config.initializer_range), + activation="relu", + name="pre_classifier", + ) + self.classifier = tf.keras.layers.Dense( + 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @property + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + tf.Tensor with dummy inputs + """ + return {"input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32)} + + @unpack_inputs + @add_start_docstrings_to_model_forward( + DISTILBERT_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") + ) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMultipleChoiceModelOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` + where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) + """ + if input_ids is not None: + num_choices = shape_list(input_ids)[1] + seq_length = shape_list(input_ids)[2] + else: + num_choices = shape_list(inputs_embeds)[1] + seq_length = shape_list(inputs_embeds)[2] + + flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None + flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None + flat_inputs_embeds = ( + tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) + if inputs_embeds is not None + else None + ) + distilbert_output = self.distilbert( + flat_input_ids, + flat_attention_mask, + head_mask, + flat_inputs_embeds, + output_attentions, + output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_state = distilbert_output[0] # (bs, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs, dim) + pooled_output = self.dropout(pooled_output, training=training) # (bs, dim) + logits = self.classifier(pooled_output) + reshaped_logits = tf.reshape(logits, (-1, num_choices)) + + loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) + + if not return_dict: + output = (reshaped_logits,) + distilbert_output[1:] + return ((loss,) + output) if loss is not None else output + + return TFMultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving_output + def serving_output(self, output: TFMultipleChoiceModelOutput) -> TFMultipleChoiceModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMultipleChoiceModelOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + DistilBert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layer on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + DISTILBERT_START_DOCSTRING, +) +class TFDistilBertForQuestionAnswering(TFDistilBertPreTrainedModel, TFQuestionAnsweringLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.distilbert = TFDistilBertMainLayer(config, name="distilbert") + self.qa_outputs = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + assert config.num_labels == 2, f"Incorrect number of labels {config.num_labels} instead of 2" + self.dropout = tf.keras.layers.Dropout(config.qa_dropout) + + @unpack_inputs + @add_start_docstrings_to_model_forward(DISTILBERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + distilbert_output = self.distilbert( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_states = distilbert_output[0] # (bs, max_query_len, dim) + hidden_states = self.dropout(hidden_states, training=training) # (bs, max_query_len, dim) + logits = self.qa_outputs(hidden_states) # (bs, max_query_len, 2) + start_logits, end_logits = tf.split(logits, 2, axis=-1) + start_logits = tf.squeeze(start_logits, axis=-1) + end_logits = tf.squeeze(end_logits, axis=-1) + + loss = None + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels, (start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + distilbert_output[1:] + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=distilbert_output.hidden_states, + attentions=distilbert_output.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForQuestionAnswering.serving_output + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..76582ae4eab1cda4e29709654d473b4abfd7023c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert.py @@ -0,0 +1,539 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for DistilBERT.""" + +import collections +import os +import unicodedata +from typing import List, Optional, Tuple + +from ...tokenization_utils import PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace +from ...utils import logging + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "distilbert-base-uncased": "https://huggingface.co/distilbert-base-uncased/resolve/main/vocab.txt", + "distilbert-base-uncased-distilled-squad": ( + "https://huggingface.co/distilbert-base-uncased-distilled-squad/resolve/main/vocab.txt" + ), + "distilbert-base-cased": "https://huggingface.co/distilbert-base-cased/resolve/main/vocab.txt", + "distilbert-base-cased-distilled-squad": ( + "https://huggingface.co/distilbert-base-cased-distilled-squad/resolve/main/vocab.txt" + ), + "distilbert-base-german-cased": "https://huggingface.co/distilbert-base-german-cased/resolve/main/vocab.txt", + "distilbert-base-multilingual-cased": ( + "https://huggingface.co/distilbert-base-multilingual-cased/resolve/main/vocab.txt" + ), + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "distilbert-base-uncased": 512, + "distilbert-base-uncased-distilled-squad": 512, + "distilbert-base-cased": 512, + "distilbert-base-cased-distilled-squad": 512, + "distilbert-base-german-cased": 512, + "distilbert-base-multilingual-cased": 512, +} + + +PRETRAINED_INIT_CONFIGURATION = { + "distilbert-base-uncased": {"do_lower_case": True}, + "distilbert-base-uncased-distilled-squad": {"do_lower_case": True}, + "distilbert-base-cased": {"do_lower_case": False}, + "distilbert-base-cased-distilled-squad": {"do_lower_case": False}, + "distilbert-base-german-cased": {"do_lower_case": False}, + "distilbert-base-multilingual-cased": {"do_lower_case": False}, +} + + +# Copied from transformers.models.bert.tokenization_bert.load_vocab +def load_vocab(vocab_file): + """Loads a vocabulary file into a dictionary.""" + vocab = collections.OrderedDict() + with open(vocab_file, "r", encoding="utf-8") as reader: + tokens = reader.readlines() + for index, token in enumerate(tokens): + token = token.rstrip("\n") + vocab[token] = index + return vocab + + +# Copied from transformers.models.bert.tokenization_bert.whitespace_tokenize +def whitespace_tokenize(text): + """Runs basic whitespace cleaning and splitting on a piece of text.""" + text = text.strip() + if not text: + return [] + tokens = text.split() + return tokens + + +class DistilBertTokenizer(PreTrainedTokenizer): + r""" + Construct a DistilBERT tokenizer. Based on WordPiece. + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + do_basic_tokenize (`bool`, *optional*, defaults to `True`): + Whether or not to do basic tokenization before WordPiece. + never_split (`Iterable`, *optional*): + Collection of tokens which will never be split during tokenization. Only has an effect when + `do_basic_tokenize=True` + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + tokenize_chinese_chars (`bool`, *optional*, defaults to `True`): + Whether or not to tokenize Chinese characters. + + This should likely be deactivated for Japanese (see this + [issue](https://github.com/huggingface/transformers/issues/328)). + strip_accents (`bool`, *optional*): + Whether or not to strip all accents. If this option is not specified, then it will be determined by the + value for `lowercase` (as in the original BERT). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + do_lower_case=True, + do_basic_tokenize=True, + never_split=None, + unk_token="[UNK]", + sep_token="[SEP]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + tokenize_chinese_chars=True, + strip_accents=None, + **kwargs, + ): + super().__init__( + do_lower_case=do_lower_case, + do_basic_tokenize=do_basic_tokenize, + never_split=never_split, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + tokenize_chinese_chars=tokenize_chinese_chars, + strip_accents=strip_accents, + **kwargs, + ) + + if not os.path.isfile(vocab_file): + raise ValueError( + f"Can't find a vocabulary file at path '{vocab_file}'. To load the vocabulary from a Google pretrained" + " model use `tokenizer = DistilBertTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`" + ) + self.vocab = load_vocab(vocab_file) + self.ids_to_tokens = collections.OrderedDict([(ids, tok) for tok, ids in self.vocab.items()]) + self.do_basic_tokenize = do_basic_tokenize + if do_basic_tokenize: + self.basic_tokenizer = BasicTokenizer( + do_lower_case=do_lower_case, + never_split=never_split, + tokenize_chinese_chars=tokenize_chinese_chars, + strip_accents=strip_accents, + ) + self.wordpiece_tokenizer = WordpieceTokenizer(vocab=self.vocab, unk_token=self.unk_token) + + @property + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.do_lower_case + def do_lower_case(self): + return self.basic_tokenizer.do_lower_case + + @property + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.vocab_size + def vocab_size(self): + return len(self.vocab) + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.get_vocab + def get_vocab(self): + return dict(self.vocab, **self.added_tokens_encoder) + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer._tokenize + def _tokenize(self, text): + split_tokens = [] + if self.do_basic_tokenize: + for token in self.basic_tokenizer.tokenize(text, never_split=self.all_special_tokens): + # If the token is part of the never_split set + if token in self.basic_tokenizer.never_split: + split_tokens.append(token) + else: + split_tokens += self.wordpiece_tokenizer.tokenize(token) + else: + split_tokens = self.wordpiece_tokenizer.tokenize(text) + return split_tokens + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer._convert_token_to_id + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.vocab.get(token, self.vocab.get(self.unk_token)) + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer._convert_id_to_token + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.ids_to_tokens.get(index, self.unk_token) + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.convert_tokens_to_string + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + out_string = " ".join(tokens).replace(" ##", "").strip() + return out_string + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.build_inputs_with_special_tokens + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A BERT sequence has the following format: + + - single sequence: `[CLS] X [SEP]` + - pair of sequences: `[CLS] A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + token_ids_1 + sep + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.get_special_tokens_mask + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.create_token_type_ids_from_sequences + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A BERT sequence + pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + # Copied from transformers.models.bert.tokenization_bert.BertTokenizer.save_vocabulary + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + index = 0 + if os.path.isdir(save_directory): + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + else: + vocab_file = (filename_prefix + "-" if filename_prefix else "") + save_directory + with open(vocab_file, "w", encoding="utf-8") as writer: + for token, token_index in sorted(self.vocab.items(), key=lambda kv: kv[1]): + if index != token_index: + logger.warning( + f"Saving vocabulary to {vocab_file}: vocabulary indices are not consecutive." + " Please check that the vocabulary is not corrupted!" + ) + index = token_index + writer.write(token + "\n") + index += 1 + return (vocab_file,) + + +# Copied from transformers.models.bert.tokenization_bert.BasicTokenizer +class BasicTokenizer(object): + """ + Constructs a BasicTokenizer that will run basic tokenization (punctuation splitting, lower casing, etc.). + + Args: + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + never_split (`Iterable`, *optional*): + Collection of tokens which will never be split during tokenization. Only has an effect when + `do_basic_tokenize=True` + tokenize_chinese_chars (`bool`, *optional*, defaults to `True`): + Whether or not to tokenize Chinese characters. + + This should likely be deactivated for Japanese (see this + [issue](https://github.com/huggingface/transformers/issues/328)). + strip_accents (`bool`, *optional*): + Whether or not to strip all accents. If this option is not specified, then it will be determined by the + value for `lowercase` (as in the original BERT). + """ + + def __init__(self, do_lower_case=True, never_split=None, tokenize_chinese_chars=True, strip_accents=None): + if never_split is None: + never_split = [] + self.do_lower_case = do_lower_case + self.never_split = set(never_split) + self.tokenize_chinese_chars = tokenize_chinese_chars + self.strip_accents = strip_accents + + def tokenize(self, text, never_split=None): + """ + Basic Tokenization of a piece of text. Split on "white spaces" only, for sub-word tokenization, see + WordPieceTokenizer. + + Args: + never_split (`List[str]`, *optional*) + Kept for backward compatibility purposes. Now implemented directly at the base class level (see + [`PreTrainedTokenizer.tokenize`]) List of token not to split. + """ + # union() returns a new set by concatenating the two sets. + never_split = self.never_split.union(set(never_split)) if never_split else self.never_split + text = self._clean_text(text) + + # This was added on November 1st, 2018 for the multilingual and Chinese + # models. This is also applied to the English models now, but it doesn't + # matter since the English models were not trained on any Chinese data + # and generally don't have any Chinese data in them (there are Chinese + # characters in the vocabulary because Wikipedia does have some Chinese + # words in the English Wikipedia.). + if self.tokenize_chinese_chars: + text = self._tokenize_chinese_chars(text) + orig_tokens = whitespace_tokenize(text) + split_tokens = [] + for token in orig_tokens: + if token not in never_split: + if self.do_lower_case: + token = token.lower() + if self.strip_accents is not False: + token = self._run_strip_accents(token) + elif self.strip_accents: + token = self._run_strip_accents(token) + split_tokens.extend(self._run_split_on_punc(token, never_split)) + + output_tokens = whitespace_tokenize(" ".join(split_tokens)) + return output_tokens + + def _run_strip_accents(self, text): + """Strips accents from a piece of text.""" + text = unicodedata.normalize("NFD", text) + output = [] + for char in text: + cat = unicodedata.category(char) + if cat == "Mn": + continue + output.append(char) + return "".join(output) + + def _run_split_on_punc(self, text, never_split=None): + """Splits punctuation on a piece of text.""" + if never_split is not None and text in never_split: + return [text] + chars = list(text) + i = 0 + start_new_word = True + output = [] + while i < len(chars): + char = chars[i] + if _is_punctuation(char): + output.append([char]) + start_new_word = True + else: + if start_new_word: + output.append([]) + start_new_word = False + output[-1].append(char) + i += 1 + + return ["".join(x) for x in output] + + def _tokenize_chinese_chars(self, text): + """Adds whitespace around any CJK character.""" + output = [] + for char in text: + cp = ord(char) + if self._is_chinese_char(cp): + output.append(" ") + output.append(char) + output.append(" ") + else: + output.append(char) + return "".join(output) + + def _is_chinese_char(self, cp): + """Checks whether CP is the codepoint of a CJK character.""" + # This defines a "chinese character" as anything in the CJK Unicode block: + # https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block) + # + # Note that the CJK Unicode block is NOT all Japanese and Korean characters, + # despite its name. The modern Korean Hangul alphabet is a different block, + # as is Japanese Hiragana and Katakana. Those alphabets are used to write + # space-separated words, so they are not treated specially and handled + # like the all of the other languages. + if ( + (cp >= 0x4E00 and cp <= 0x9FFF) + or (cp >= 0x3400 and cp <= 0x4DBF) # + or (cp >= 0x20000 and cp <= 0x2A6DF) # + or (cp >= 0x2A700 and cp <= 0x2B73F) # + or (cp >= 0x2B740 and cp <= 0x2B81F) # + or (cp >= 0x2B820 and cp <= 0x2CEAF) # + or (cp >= 0xF900 and cp <= 0xFAFF) + or (cp >= 0x2F800 and cp <= 0x2FA1F) # + ): # + return True + + return False + + def _clean_text(self, text): + """Performs invalid character removal and whitespace cleanup on text.""" + output = [] + for char in text: + cp = ord(char) + if cp == 0 or cp == 0xFFFD or _is_control(char): + continue + if _is_whitespace(char): + output.append(" ") + else: + output.append(char) + return "".join(output) + + +# Copied from transformers.models.bert.tokenization_bert.WordpieceTokenizer +class WordpieceTokenizer(object): + """Runs WordPiece tokenization.""" + + def __init__(self, vocab, unk_token, max_input_chars_per_word=100): + self.vocab = vocab + self.unk_token = unk_token + self.max_input_chars_per_word = max_input_chars_per_word + + def tokenize(self, text): + """ + Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform + tokenization using the given vocabulary. + + For example, `input = "unaffable"` wil return as output `["un", "##aff", "##able"]`. + + Args: + text: A single token or whitespace separated tokens. This should have + already been passed through *BasicTokenizer*. + + Returns: + A list of wordpiece tokens. + """ + + output_tokens = [] + for token in whitespace_tokenize(text): + chars = list(token) + if len(chars) > self.max_input_chars_per_word: + output_tokens.append(self.unk_token) + continue + + is_bad = False + start = 0 + sub_tokens = [] + while start < len(chars): + end = len(chars) + cur_substr = None + while start < end: + substr = "".join(chars[start:end]) + if start > 0: + substr = "##" + substr + if substr in self.vocab: + cur_substr = substr + break + end -= 1 + if cur_substr is None: + is_bad = True + break + sub_tokens.append(cur_substr) + start = end + + if is_bad: + output_tokens.append(self.unk_token) + else: + output_tokens.extend(sub_tokens) + return output_tokens diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..dd9dcd165d4109ff94d9ee786994bc897efcd814 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/distilbert/tokenization_distilbert_fast.py @@ -0,0 +1,231 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for DistilBERT.""" + +import json +from typing import List, Optional, Tuple + +from tokenizers import normalizers + +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging +from .tokenization_distilbert import DistilBertTokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "distilbert-base-uncased": "https://huggingface.co/distilbert-base-uncased/resolve/main/vocab.txt", + "distilbert-base-uncased-distilled-squad": ( + "https://huggingface.co/distilbert-base-uncased-distilled-squad/resolve/main/vocab.txt" + ), + "distilbert-base-cased": "https://huggingface.co/distilbert-base-cased/resolve/main/vocab.txt", + "distilbert-base-cased-distilled-squad": ( + "https://huggingface.co/distilbert-base-cased-distilled-squad/resolve/main/vocab.txt" + ), + "distilbert-base-german-cased": "https://huggingface.co/distilbert-base-german-cased/resolve/main/vocab.txt", + "distilbert-base-multilingual-cased": ( + "https://huggingface.co/distilbert-base-multilingual-cased/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "distilbert-base-uncased": "https://huggingface.co/distilbert-base-uncased/resolve/main/tokenizer.json", + "distilbert-base-uncased-distilled-squad": ( + "https://huggingface.co/distilbert-base-uncased-distilled-squad/resolve/main/tokenizer.json" + ), + "distilbert-base-cased": "https://huggingface.co/distilbert-base-cased/resolve/main/tokenizer.json", + "distilbert-base-cased-distilled-squad": ( + "https://huggingface.co/distilbert-base-cased-distilled-squad/resolve/main/tokenizer.json" + ), + "distilbert-base-german-cased": ( + "https://huggingface.co/distilbert-base-german-cased/resolve/main/tokenizer.json" + ), + "distilbert-base-multilingual-cased": ( + "https://huggingface.co/distilbert-base-multilingual-cased/resolve/main/tokenizer.json" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "distilbert-base-uncased": 512, + "distilbert-base-uncased-distilled-squad": 512, + "distilbert-base-cased": 512, + "distilbert-base-cased-distilled-squad": 512, + "distilbert-base-german-cased": 512, + "distilbert-base-multilingual-cased": 512, +} + + +PRETRAINED_INIT_CONFIGURATION = { + "distilbert-base-uncased": {"do_lower_case": True}, + "distilbert-base-uncased-distilled-squad": {"do_lower_case": True}, + "distilbert-base-cased": {"do_lower_case": False}, + "distilbert-base-cased-distilled-squad": {"do_lower_case": False}, + "distilbert-base-german-cased": {"do_lower_case": False}, + "distilbert-base-multilingual-cased": {"do_lower_case": False}, +} + + +class DistilBertTokenizerFast(PreTrainedTokenizerFast): + r""" + Construct a "fast" DistilBERT tokenizer (backed by HuggingFace's *tokenizers* library). Based on WordPiece. + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + clean_text (`bool`, *optional*, defaults to `True`): + Whether or not to clean the text before tokenization by removing any control characters and replacing all + whitespaces by the classic one. + tokenize_chinese_chars (`bool`, *optional*, defaults to `True`): + Whether or not to tokenize Chinese characters. This should likely be deactivated for Japanese (see [this + issue](https://github.com/huggingface/transformers/issues/328)). + strip_accents (`bool`, *optional*): + Whether or not to strip all accents. If this option is not specified, then it will be determined by the + value for `lowercase` (as in the original BERT). + wordpieces_prefix (`str`, *optional*, defaults to `"##"`): + The prefix for subwords. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = DistilBertTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + do_lower_case=True, + unk_token="[UNK]", + sep_token="[SEP]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + tokenize_chinese_chars=True, + strip_accents=None, + **kwargs, + ): + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + do_lower_case=do_lower_case, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + tokenize_chinese_chars=tokenize_chinese_chars, + strip_accents=strip_accents, + **kwargs, + ) + + normalizer_state = json.loads(self.backend_tokenizer.normalizer.__getstate__()) + if ( + normalizer_state.get("lowercase", do_lower_case) != do_lower_case + or normalizer_state.get("strip_accents", strip_accents) != strip_accents + or normalizer_state.get("handle_chinese_chars", tokenize_chinese_chars) != tokenize_chinese_chars + ): + normalizer_class = getattr(normalizers, normalizer_state.pop("type")) + normalizer_state["lowercase"] = do_lower_case + normalizer_state["strip_accents"] = strip_accents + normalizer_state["handle_chinese_chars"] = tokenize_chinese_chars + self.backend_tokenizer.normalizer = normalizer_class(**normalizer_state) + + self.do_lower_case = do_lower_case + + # Copied from transformers.models.bert.tokenization_bert_fast.BertTokenizerFast.build_inputs_with_special_tokens + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A BERT sequence has the following format: + + - single sequence: `[CLS] X [SEP]` + - pair of sequences: `[CLS] A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + output = [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + + if token_ids_1: + output += token_ids_1 + [self.sep_token_id] + + return output + + # Copied from transformers.models.bert.tokenization_bert_fast.BertTokenizerFast.create_token_type_ids_from_sequences + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A BERT sequence + pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + # Copied from transformers.models.bert.tokenization_bert_fast.BertTokenizerFast.save_vocabulary + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + files = self._tokenizer.model.save(save_directory, name=filename_prefix) + return tuple(files) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dit/convert_dit_unilm_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dit/convert_dit_unilm_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..d80e9d890ddc306628476d8d3d72e5de9cca8c98 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dit/convert_dit_unilm_to_pytorch.py @@ -0,0 +1,231 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DiT checkpoints from the unilm repository.""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import BeitConfig, BeitFeatureExtractor, BeitForImageClassification, BeitForMaskedImageModeling +from transformers.image_utils import PILImageResampling +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def create_rename_keys(config, has_lm_head=False, is_semantic=False): + prefix = "backbone." if is_semantic else "" + + rename_keys = [] + for i in range(config.num_hidden_layers): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append((f"{prefix}blocks.{i}.norm1.weight", f"beit.encoder.layer.{i}.layernorm_before.weight")) + rename_keys.append((f"{prefix}blocks.{i}.norm1.bias", f"beit.encoder.layer.{i}.layernorm_before.bias")) + rename_keys.append( + (f"{prefix}blocks.{i}.attn.proj.weight", f"beit.encoder.layer.{i}.attention.output.dense.weight") + ) + rename_keys.append( + (f"{prefix}blocks.{i}.attn.proj.bias", f"beit.encoder.layer.{i}.attention.output.dense.bias") + ) + rename_keys.append((f"{prefix}blocks.{i}.norm2.weight", f"beit.encoder.layer.{i}.layernorm_after.weight")) + rename_keys.append((f"{prefix}blocks.{i}.norm2.bias", f"beit.encoder.layer.{i}.layernorm_after.bias")) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc1.weight", f"beit.encoder.layer.{i}.intermediate.dense.weight")) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc1.bias", f"beit.encoder.layer.{i}.intermediate.dense.bias")) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.weight", f"beit.encoder.layer.{i}.output.dense.weight")) + rename_keys.append((f"{prefix}blocks.{i}.mlp.fc2.bias", f"beit.encoder.layer.{i}.output.dense.bias")) + + # projection layer + position embeddings + rename_keys.extend( + [ + (f"{prefix}cls_token", "beit.embeddings.cls_token"), + (f"{prefix}patch_embed.proj.weight", "beit.embeddings.patch_embeddings.projection.weight"), + (f"{prefix}patch_embed.proj.bias", "beit.embeddings.patch_embeddings.projection.bias"), + (f"{prefix}pos_embed", "beit.embeddings.position_embeddings"), + ] + ) + + if has_lm_head: + # mask token + layernorm + rename_keys.extend( + [ + ("mask_token", "beit.embeddings.mask_token"), + ("norm.weight", "layernorm.weight"), + ("norm.bias", "layernorm.bias"), + ] + ) + else: + # layernorm + classification head + rename_keys.extend( + [ + ("fc_norm.weight", "beit.pooler.layernorm.weight"), + ("fc_norm.bias", "beit.pooler.layernorm.bias"), + ("head.weight", "classifier.weight"), + ("head.bias", "classifier.bias"), + ] + ) + + return rename_keys + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_q_k_v(state_dict, config, has_lm_head=False, is_semantic=False): + for i in range(config.num_hidden_layers): + prefix = "backbone." if is_semantic else "" + # queries, keys and values + in_proj_weight = state_dict.pop(f"{prefix}blocks.{i}.attn.qkv.weight") + q_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.q_bias") + v_bias = state_dict.pop(f"{prefix}blocks.{i}.attn.v_bias") + + state_dict[f"beit.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[ + : config.hidden_size, : + ] + state_dict[f"beit.encoder.layer.{i}.attention.attention.query.bias"] = q_bias + state_dict[f"beit.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"beit.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[ + -config.hidden_size :, : + ] + state_dict[f"beit.encoder.layer.{i}.attention.attention.value.bias"] = v_bias + + # gamma_1 and gamma_2 + # we call them lambda because otherwise they are renamed when using .from_pretrained + gamma_1 = state_dict.pop(f"{prefix}blocks.{i}.gamma_1") + gamma_2 = state_dict.pop(f"{prefix}blocks.{i}.gamma_2") + + state_dict[f"beit.encoder.layer.{i}.lambda_1"] = gamma_1 + state_dict[f"beit.encoder.layer.{i}.lambda_2"] = gamma_2 + + +def rename_key(dct, old, new): + val = dct.pop(old) + dct[new] = val + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@torch.no_grad() +def convert_dit_checkpoint(checkpoint_url, pytorch_dump_folder_path, push_to_hub=False): + """ + Copy/paste/tweak model's weights to our BEiT structure. + """ + + # define default BEiT configuration + has_lm_head = False if "rvlcdip" in checkpoint_url else True + config = BeitConfig(use_absolute_position_embeddings=True, use_mask_token=has_lm_head) + + # size of the architecture + if "large" in checkpoint_url or "dit-l" in checkpoint_url: + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + + # labels + if "rvlcdip" in checkpoint_url: + config.num_labels = 16 + repo_id = "huggingface/label-files" + filename = "rvlcdip-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + # load state_dict of original model, remove and rename some keys + state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")["model"] + + rename_keys = create_rename_keys(config, has_lm_head=has_lm_head) + for src, dest in rename_keys: + rename_key(state_dict, src, dest) + read_in_q_k_v(state_dict, config, has_lm_head=has_lm_head) + + # load HuggingFace model + model = BeitForMaskedImageModeling(config) if has_lm_head else BeitForImageClassification(config) + model.eval() + model.load_state_dict(state_dict) + + # Check outputs on an image + feature_extractor = BeitFeatureExtractor( + size=config.image_size, resample=PILImageResampling.BILINEAR, do_center_crop=False + ) + image = prepare_img() + + encoding = feature_extractor(images=image, return_tensors="pt") + pixel_values = encoding["pixel_values"] + + outputs = model(pixel_values) + logits = outputs.logits + + # verify logits + expected_shape = [1, 16] if "rvlcdip" in checkpoint_url else [1, 196, 8192] + assert logits.shape == torch.Size(expected_shape), "Shape of logits not as expected" + + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + print(f"Saving model to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + if has_lm_head: + model_name = "dit-base" if "base" in checkpoint_url else "dit-large" + else: + model_name = "dit-base-finetuned-rvlcdip" if "dit-b" in checkpoint_url else "dit-large-finetuned-rvlcdip" + feature_extractor.push_to_hub( + repo_path_or_name=Path(pytorch_dump_folder_path, model_name), + organization="nielsr", + commit_message="Add feature extractor", + use_temp_dir=True, + ) + model.push_to_hub( + repo_path_or_name=Path(pytorch_dump_folder_path, model_name), + organization="nielsr", + commit_message="Add model", + use_temp_dir=True, + ) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--checkpoint_url", + default="https://layoutlm.blob.core.windows.net/dit/dit-pts/dit-base-224-p16-500k-62d53a.pth", + type=str, + help="URL to the original PyTorch checkpoint (.pth file).", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model." + ) + parser.add_argument( + "--push_to_hub", + action="store_true", + ) + args = parser.parse_args() + convert_dit_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c548a181a3bf3023fd64defca5a3748624db6b7c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/__init__.py @@ -0,0 +1,74 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available + + +_import_structure = { + "configuration_donut_swin": ["DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP", "DonutSwinConfig"], + "processing_donut": ["DonutProcessor"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_donut_swin"] = [ + "DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST", + "DonutSwinModel", + "DonutSwinPreTrainedModel", + ] + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_donut"] = ["DonutFeatureExtractor"] + _import_structure["image_processing_donut"] = ["DonutImageProcessor"] + + +if TYPE_CHECKING: + from .configuration_donut_swin import DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP, DonutSwinConfig + from .processing_donut import DonutProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_donut_swin import ( + DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST, + DonutSwinModel, + DonutSwinPreTrainedModel, + ) + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_donut import DonutFeatureExtractor + from .image_processing_donut import DonutImageProcessor + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/configuration_donut_swin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/configuration_donut_swin.py new file mode 100644 index 0000000000000000000000000000000000000000..059016dafef949391743f3af6f960fb0489ab39b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/configuration_donut_swin.py @@ -0,0 +1,136 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Donut Swin Transformer model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "naver-clova-ix/donut-base": "https://huggingface.co/naver-clova-ix/donut-base/resolve/main/config.json", + # See all Donut models at https://huggingface.co/models?filter=donut-swin +} + + +class DonutSwinConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DonutSwinModel`]. It is used to instantiate a + Donut model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of the Donut + [naver-clova-ix/donut-base](https://huggingface.co/naver-clova-ix/donut-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + image_size (`int`, *optional*, defaults to 224): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 4): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + embed_dim (`int`, *optional*, defaults to 96): + Dimensionality of patch embedding. + depths (`list(int)`, *optional*, defaults to [2, 2, 6, 2]): + Depth of each layer in the Transformer encoder. + num_heads (`list(int)`, *optional*, defaults to [3, 6, 12, 24]): + Number of attention heads in each layer of the Transformer encoder. + window_size (`int`, *optional*, defaults to 7): + Size of windows. + mlp_ratio (`float`, *optional*, defaults to 4.0): + Ratio of MLP hidden dimensionality to embedding dimensionality. + qkv_bias (`bool`, *optional*, defaults to True): + Whether or not a learnable bias should be added to the queries, keys and values. + hidden_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout probability for all fully connected layers in the embeddings and encoder. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + drop_path_rate (`float`, *optional*, defaults to 0.1): + Stochastic depth rate. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder. If string, `"gelu"`, `"relu"`, + `"selu"` and `"gelu_new"` are supported. + use_absolute_embeddings (`bool`, *optional*, defaults to False): + Whether or not to add absolute position embeddings to the patch embeddings. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + + Example: + + ```python + >>> from transformers import DonutSwinConfig, DonutSwinModel + + >>> # Initializing a Donut naver-clova-ix/donut-base style configuration + >>> configuration = DonutSwinConfig() + + >>> # Randomly initializing a model from the naver-clova-ix/donut-base style configuration + >>> model = DonutSwinModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "donut-swin" + + attribute_map = { + "num_attention_heads": "num_heads", + "num_hidden_layers": "num_layers", + } + + def __init__( + self, + image_size=224, + patch_size=4, + num_channels=3, + embed_dim=96, + depths=[2, 2, 6, 2], + num_heads=[3, 6, 12, 24], + window_size=7, + mlp_ratio=4.0, + qkv_bias=True, + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + drop_path_rate=0.1, + hidden_act="gelu", + use_absolute_embeddings=False, + initializer_range=0.02, + layer_norm_eps=1e-5, + **kwargs, + ): + super().__init__(**kwargs) + + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.embed_dim = embed_dim + self.depths = depths + self.num_layers = len(depths) + self.num_heads = num_heads + self.window_size = window_size + self.mlp_ratio = mlp_ratio + self.qkv_bias = qkv_bias + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.drop_path_rate = drop_path_rate + self.hidden_act = hidden_act + self.use_absolute_embeddings = use_absolute_embeddings + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + # we set the hidden_size attribute in order to make Swin work with VisionEncoderDecoderModel + # this indicates the channel dimension after the last stage of the model + self.hidden_size = int(embed_dim * 2 ** (len(depths) - 1)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/convert_donut_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/convert_donut_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..cd0f43773567f16bde00d768544a38cf5723aaba --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/convert_donut_to_pytorch.py @@ -0,0 +1,234 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Donut checkpoints using the original `donut-python` library. URL: https://github.com/clovaai/donut""" + +import argparse + +import torch +from datasets import load_dataset +from donut import DonutModel + +from transformers import ( + DonutFeatureExtractor, + DonutProcessor, + DonutSwinConfig, + DonutSwinModel, + MBartConfig, + MBartForCausalLM, + VisionEncoderDecoderModel, + XLMRobertaTokenizerFast, +) + + +def get_configs(model): + original_config = model.config + + encoder_config = DonutSwinConfig( + image_size=original_config.input_size, + patch_size=4, + depths=original_config.encoder_layer, + num_heads=[4, 8, 16, 32], + window_size=original_config.window_size, + embed_dim=128, + ) + decoder_config = MBartConfig( + is_decoder=True, + is_encoder_decoder=False, + add_cross_attention=True, + decoder_layers=original_config.decoder_layer, + max_position_embeddings=original_config.max_position_embeddings, + vocab_size=len( + model.decoder.tokenizer + ), # several special tokens are added to the vocab of XLMRobertaTokenizer, see repo on the hub (added_tokens.json) + scale_embedding=True, + add_final_layer_norm=True, + ) + + return encoder_config, decoder_config + + +def rename_key(name): + if "encoder.model" in name: + name = name.replace("encoder.model", "encoder") + if "decoder.model" in name: + name = name.replace("decoder.model", "decoder") + if "patch_embed.proj" in name: + name = name.replace("patch_embed.proj", "embeddings.patch_embeddings.projection") + if "patch_embed.norm" in name: + name = name.replace("patch_embed.norm", "embeddings.norm") + if name.startswith("encoder"): + if "layers" in name: + name = "encoder." + name + if "attn.proj" in name: + name = name.replace("attn.proj", "attention.output.dense") + if "attn" in name and "mask" not in name: + name = name.replace("attn", "attention.self") + if "norm1" in name: + name = name.replace("norm1", "layernorm_before") + if "norm2" in name: + name = name.replace("norm2", "layernorm_after") + if "mlp.fc1" in name: + name = name.replace("mlp.fc1", "intermediate.dense") + if "mlp.fc2" in name: + name = name.replace("mlp.fc2", "output.dense") + + if name == "encoder.norm.weight": + name = "encoder.layernorm.weight" + if name == "encoder.norm.bias": + name = "encoder.layernorm.bias" + + return name + + +def convert_state_dict(orig_state_dict, model): + for key in orig_state_dict.copy().keys(): + val = orig_state_dict.pop(key) + + if "qkv" in key: + key_split = key.split(".") + layer_num = int(key_split[3]) + block_num = int(key_split[5]) + dim = model.encoder.encoder.layers[layer_num].blocks[block_num].attention.self.all_head_size + + if "weight" in key: + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.query.weight" + ] = val[:dim, :] + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.key.weight" + ] = val[dim : dim * 2, :] + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.value.weight" + ] = val[-dim:, :] + else: + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.query.bias" + ] = val[:dim] + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.key.bias" + ] = val[dim : dim * 2] + orig_state_dict[ + f"encoder.encoder.layers.{layer_num}.blocks.{block_num}.attention.self.value.bias" + ] = val[-dim:] + elif "attn_mask" in key or key in ["encoder.model.norm.weight", "encoder.model.norm.bias"]: + # HuggingFace implementation doesn't use attn_mask buffer + # and model doesn't use final LayerNorms for the encoder + pass + else: + orig_state_dict[rename_key(key)] = val + + return orig_state_dict + + +def convert_donut_checkpoint(model_name, pytorch_dump_folder_path=None, push_to_hub=False): + # load original model + original_model = DonutModel.from_pretrained(model_name).eval() + + # load HuggingFace model + encoder_config, decoder_config = get_configs(original_model) + encoder = DonutSwinModel(encoder_config) + decoder = MBartForCausalLM(decoder_config) + model = VisionEncoderDecoderModel(encoder=encoder, decoder=decoder) + model.eval() + + state_dict = original_model.state_dict() + new_state_dict = convert_state_dict(state_dict, model) + model.load_state_dict(new_state_dict) + + # verify results on scanned document + dataset = load_dataset("hf-internal-testing/example-documents") + image = dataset["test"][0]["image"].convert("RGB") + + tokenizer = XLMRobertaTokenizerFast.from_pretrained(model_name, from_slow=True) + feature_extractor = DonutFeatureExtractor( + do_align_long_axis=original_model.config.align_long_axis, size=original_model.config.input_size[::-1] + ) + processor = DonutProcessor(feature_extractor, tokenizer) + pixel_values = processor(image, return_tensors="pt").pixel_values + + if model_name == "naver-clova-ix/donut-base-finetuned-docvqa": + task_prompt = "{user_input}" + question = "When is the coffee break?" + task_prompt = task_prompt.replace("{user_input}", question) + elif model_name == "naver-clova-ix/donut-base-finetuned-rvlcdip": + task_prompt = "" + elif model_name in [ + "naver-clova-ix/donut-base-finetuned-cord-v1", + "naver-clova-ix/donut-base-finetuned-cord-v1-2560", + ]: + task_prompt = "" + elif model_name == "naver-clova-ix/donut-base-finetuned-cord-v2": + task_prompt = "s_cord-v2>" + elif model_name == "naver-clova-ix/donut-base-finetuned-zhtrainticket": + task_prompt = "" + elif model_name in ["naver-clova-ix/donut-proto", "naver-clova-ix/donut-base"]: + # use a random prompt + task_prompt = "hello world" + else: + raise ValueError("Model name not supported") + prompt_tensors = original_model.decoder.tokenizer(task_prompt, add_special_tokens=False, return_tensors="pt")[ + "input_ids" + ] + + original_patch_embed = original_model.encoder.model.patch_embed(pixel_values) + patch_embeddings, _ = model.encoder.embeddings(pixel_values) + assert torch.allclose(original_patch_embed, patch_embeddings, atol=1e-3) + + # verify encoder hidden states + original_last_hidden_state = original_model.encoder(pixel_values) + last_hidden_state = model.encoder(pixel_values).last_hidden_state + assert torch.allclose(original_last_hidden_state, last_hidden_state, atol=1e-2) + + # verify decoder hidden states + original_logits = original_model(pixel_values, prompt_tensors, None).logits + logits = model(pixel_values, decoder_input_ids=prompt_tensors).logits + assert torch.allclose(original_logits, logits, atol=1e-3) + print("Looks ok!") + + if pytorch_dump_folder_path is not None: + print(f"Saving model and processor to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + processor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + model.push_to_hub("nielsr/" + model_name.split("/")[-1], commit_message="Update model") + processor.push_to_hub("nielsr/" + model_name.split("/")[-1], commit_message="Update model") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--model_name", + default="naver-clova-ix/donut-base-finetuned-docvqa", + required=False, + type=str, + help="Name of the original model you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + required=False, + type=str, + help="Path to the output PyTorch model directory.", + ) + parser.add_argument( + "--push_to_hub", + action="store_true", + help="Whether or not to push the converted model and processor to the 🤗 hub.", + ) + + args = parser.parse_args() + convert_donut_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/feature_extraction_donut.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/feature_extraction_donut.py new file mode 100644 index 0000000000000000000000000000000000000000..e6ca078c0e8ac4939514dcb297f5d2c63de032f7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/feature_extraction_donut.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for Donut.""" + +import warnings + +from ...utils import logging +from .image_processing_donut import DonutImageProcessor + + +logger = logging.get_logger(__name__) + + +class DonutFeatureExtractor(DonutImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class DonutFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please" + " use DonutImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/modeling_donut_swin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/modeling_donut_swin.py new file mode 100644 index 0000000000000000000000000000000000000000..65c48eb81f8368147798be3ec3166ec38fb4a929 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/modeling_donut_swin.py @@ -0,0 +1,963 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Donut Swin Transformer model. + +This implementation is identical to a regular Swin Transformer, without final layer norm on top of the final hidden +states.""" + +import collections.abc +import math +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn + +from ...activations import ACT2FN +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, meshgrid, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, +) +from .configuration_donut_swin import DonutSwinConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "DonutSwinConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "https://huggingface.co/naver-clova-ix/donut-base" +_EXPECTED_OUTPUT_SHAPE = [1, 49, 768] + +DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "naver-clova-ix/donut-base", + # See all Donut Swin models at https://huggingface.co/models?filter=donut +] + + +@dataclass +# Copied from transformers.models.swin.modeling_swin.SwinEncoderOutput with Swin->DonutSwin +class DonutSwinEncoderOutput(ModelOutput): + """ + DonutSwin encoder's outputs, with potential hidden states and attentions. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, hidden_size, height, width)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to + include the spatial dimensions. + """ + + last_hidden_state: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + reshaped_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +# Copied from transformers.models.swin.modeling_swin.SwinModelOutput with Swin->DonutSwin +class DonutSwinModelOutput(ModelOutput): + """ + DonutSwin model's outputs that also contains a pooling of the last hidden states. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`, *optional*, returned when `add_pooling_layer=True` is passed): + Average pooling of the last layer hidden-state. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each stage) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + reshaped_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each stage) of + shape `(batch_size, hidden_size, height, width)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs reshaped to + include the spatial dimensions. + """ + + last_hidden_state: torch.FloatTensor = None + pooler_output: Optional[torch.FloatTensor] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + reshaped_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + + +# Copied from transformers.models.swin.modeling_swin.window_partition +def window_partition(input_feature, window_size): + """ + Partitions the given input into windows. + """ + batch_size, height, width, num_channels = input_feature.shape + input_feature = input_feature.view( + batch_size, height // window_size, window_size, width // window_size, window_size, num_channels + ) + windows = input_feature.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, num_channels) + return windows + + +# Copied from transformers.models.swin.modeling_swin.window_reverse +def window_reverse(windows, window_size, height, width): + """ + Merges windows to produce higher resolution features. + """ + num_channels = windows.shape[-1] + windows = windows.view(-1, height // window_size, width // window_size, window_size, window_size, num_channels) + windows = windows.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, height, width, num_channels) + return windows + + +# Copied from transformers.models.swin.modeling_swin.SwinEmbeddings with Swin->DonutSwin +class DonutSwinEmbeddings(nn.Module): + """ + Construct the patch and position embeddings. Optionally, also the mask token. + """ + + def __init__(self, config, use_mask_token=False): + super().__init__() + + self.patch_embeddings = DonutSwinPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.patch_grid = self.patch_embeddings.grid_size + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.embed_dim)) if use_mask_token else None + + if config.use_absolute_embeddings: + self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 1, config.embed_dim)) + else: + self.position_embeddings = None + + self.norm = nn.LayerNorm(config.embed_dim) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward( + self, pixel_values: Optional[torch.FloatTensor], bool_masked_pos: Optional[torch.BoolTensor] = None + ) -> Tuple[torch.Tensor]: + embeddings, output_dimensions = self.patch_embeddings(pixel_values) + embeddings = self.norm(embeddings) + batch_size, seq_len, _ = embeddings.size() + + if bool_masked_pos is not None: + mask_tokens = self.mask_token.expand(batch_size, seq_len, -1) + # replace the masked visual tokens by mask_tokens + mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + if self.position_embeddings is not None: + embeddings = embeddings + self.position_embeddings + + embeddings = self.dropout(embeddings) + + return embeddings, output_dimensions + + +# Copied from transformers.models.swin.modeling_swin.SwinPatchEmbeddings +class DonutSwinPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.embed_dim + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + self.grid_size = (image_size[0] // patch_size[0], image_size[1] // patch_size[1]) + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def maybe_pad(self, pixel_values, height, width): + if width % self.patch_size[1] != 0: + pad_values = (0, self.patch_size[1] - width % self.patch_size[1]) + pixel_values = nn.functional.pad(pixel_values, pad_values) + if height % self.patch_size[0] != 0: + pad_values = (0, 0, 0, self.patch_size[0] - height % self.patch_size[0]) + pixel_values = nn.functional.pad(pixel_values, pad_values) + return pixel_values + + def forward(self, pixel_values: Optional[torch.FloatTensor]) -> Tuple[torch.Tensor, Tuple[int]]: + _, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + # pad the input to be divisible by self.patch_size, if needed + pixel_values = self.maybe_pad(pixel_values, height, width) + embeddings = self.projection(pixel_values) + _, _, height, width = embeddings.shape + output_dimensions = (height, width) + embeddings = embeddings.flatten(2).transpose(1, 2) + + return embeddings, output_dimensions + + +# Copied from transformers.models.swin.modeling_swin.SwinPatchMerging +class DonutSwinPatchMerging(nn.Module): + """ + Patch Merging Layer. + + Args: + input_resolution (`Tuple[int]`): + Resolution of input feature. + dim (`int`): + Number of input channels. + norm_layer (`nn.Module`, *optional*, defaults to `nn.LayerNorm`): + Normalization layer class. + """ + + def __init__(self, input_resolution: Tuple[int], dim: int, norm_layer: nn.Module = nn.LayerNorm) -> None: + super().__init__() + self.input_resolution = input_resolution + self.dim = dim + self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) + self.norm = norm_layer(4 * dim) + + def maybe_pad(self, input_feature, height, width): + should_pad = (height % 2 == 1) or (width % 2 == 1) + if should_pad: + pad_values = (0, 0, 0, width % 2, 0, height % 2) + input_feature = nn.functional.pad(input_feature, pad_values) + + return input_feature + + def forward(self, input_feature: torch.Tensor, input_dimensions: Tuple[int, int]) -> torch.Tensor: + height, width = input_dimensions + # `dim` is height * width + batch_size, dim, num_channels = input_feature.shape + + input_feature = input_feature.view(batch_size, height, width, num_channels) + # pad input to be disible by width and height, if needed + input_feature = self.maybe_pad(input_feature, height, width) + # [batch_size, height/2, width/2, num_channels] + input_feature_0 = input_feature[:, 0::2, 0::2, :] + # [batch_size, height/2, width/2, num_channels] + input_feature_1 = input_feature[:, 1::2, 0::2, :] + # [batch_size, height/2, width/2, num_channels] + input_feature_2 = input_feature[:, 0::2, 1::2, :] + # [batch_size, height/2, width/2, num_channels] + input_feature_3 = input_feature[:, 1::2, 1::2, :] + # batch_size height/2 width/2 4*num_channels + input_feature = torch.cat([input_feature_0, input_feature_1, input_feature_2, input_feature_3], -1) + input_feature = input_feature.view(batch_size, -1, 4 * num_channels) # batch_size height/2*width/2 4*C + + input_feature = self.norm(input_feature) + input_feature = self.reduction(input_feature) + + return input_feature + + +# Copied from transformers.models.swin.modeling_swin.drop_path +def drop_path(input, drop_prob=0.0, training=False, scale_by_keep=True): + """ + Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, + however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the + layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the + argument. + """ + if drop_prob == 0.0 or not training: + return input + keep_prob = 1 - drop_prob + shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device) + random_tensor.floor_() # binarize + output = input.div(keep_prob) * random_tensor + return output + + +# Copied from transformers.models.swin.modeling_swin.SwinDropPath +class DonutSwinDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob: Optional[float] = None) -> None: + super().__init__() + self.drop_prob = drop_prob + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + return drop_path(hidden_states, self.drop_prob, self.training) + + def extra_repr(self) -> str: + return "p={}".format(self.drop_prob) + + +# Copied from transformers.models.swin.modeling_swin.SwinSelfAttention with Swin->DonutSwin +class DonutSwinSelfAttention(nn.Module): + def __init__(self, config, dim, num_heads, window_size): + super().__init__() + if dim % num_heads != 0: + raise ValueError( + f"The hidden size ({dim}) is not a multiple of the number of attention heads ({num_heads})" + ) + + self.num_attention_heads = num_heads + self.attention_head_size = int(dim / num_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.window_size = ( + window_size if isinstance(window_size, collections.abc.Iterable) else (window_size, window_size) + ) + + self.relative_position_bias_table = nn.Parameter( + torch.zeros((2 * self.window_size[0] - 1) * (2 * self.window_size[1] - 1), num_heads) + ) + + # get pair-wise relative position index for each token inside the window + coords_h = torch.arange(self.window_size[0]) + coords_w = torch.arange(self.window_size[1]) + coords = torch.stack(meshgrid([coords_h, coords_w], indexing="ij")) + coords_flatten = torch.flatten(coords, 1) + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] + relative_coords = relative_coords.permute(1, 2, 0).contiguous() + relative_coords[:, :, 0] += self.window_size[0] - 1 + relative_coords[:, :, 1] += self.window_size[1] - 1 + relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 + relative_position_index = relative_coords.sum(-1) + self.register_buffer("relative_position_index", relative_position_index) + + self.query = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(self.all_head_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x): + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + batch_size, dim, num_channels = hidden_states.shape + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)] + relative_position_bias = relative_position_bias.view( + self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1 + ) + + relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() + attention_scores = attention_scores + relative_position_bias.unsqueeze(0) + + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in DonutSwinModel forward() function) + mask_shape = attention_mask.shape[0] + attention_scores = attention_scores.view( + batch_size // mask_shape, mask_shape, self.num_attention_heads, dim, dim + ) + attention_scores = attention_scores + attention_mask.unsqueeze(1).unsqueeze(0) + attention_scores = attention_scores.view(-1, self.num_attention_heads, dim, dim) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.swin.modeling_swin.SwinSelfOutput +class DonutSwinSelfOutput(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(dim, dim) + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.swin.modeling_swin.SwinAttention with Swin->DonutSwin +class DonutSwinAttention(nn.Module): + def __init__(self, config, dim, num_heads, window_size): + super().__init__() + self.self = DonutSwinSelfAttention(config, dim, num_heads, window_size) + self.output = DonutSwinSelfOutput(config, dim) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self(hidden_states, attention_mask, head_mask, output_attentions) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.swin.modeling_swin.SwinIntermediate +class DonutSwinIntermediate(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(dim, int(config.mlp_ratio * dim)) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.swin.modeling_swin.SwinOutput +class DonutSwinOutput(nn.Module): + def __init__(self, config, dim): + super().__init__() + self.dense = nn.Linear(int(config.mlp_ratio * dim), dim) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states + + +# Copied from transformers.models.swin.modeling_swin.SwinLayer with Swin->DonutSwin +class DonutSwinLayer(nn.Module): + def __init__(self, config, dim, input_resolution, num_heads, shift_size=0): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.shift_size = shift_size + self.window_size = config.window_size + self.input_resolution = input_resolution + self.layernorm_before = nn.LayerNorm(dim, eps=config.layer_norm_eps) + self.attention = DonutSwinAttention(config, dim, num_heads, window_size=self.window_size) + self.drop_path = DonutSwinDropPath(config.drop_path_rate) if config.drop_path_rate > 0.0 else nn.Identity() + self.layernorm_after = nn.LayerNorm(dim, eps=config.layer_norm_eps) + self.intermediate = DonutSwinIntermediate(config, dim) + self.output = DonutSwinOutput(config, dim) + + def set_shift_and_window_size(self, input_resolution): + if min(input_resolution) <= self.window_size: + # if window size is larger than input resolution, we don't partition windows + self.shift_size = 0 + self.window_size = min(input_resolution) + + def get_attn_mask(self, height, width, dtype): + if self.shift_size > 0: + # calculate attention mask for SW-MSA + img_mask = torch.zeros((1, height, width, 1), dtype=dtype) + height_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + width_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + count = 0 + for height_slice in height_slices: + for width_slice in width_slices: + img_mask[:, height_slice, width_slice, :] = count + count += 1 + + mask_windows = window_partition(img_mask, self.window_size) + mask_windows = mask_windows.view(-1, self.window_size * self.window_size) + attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2) + attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0)) + else: + attn_mask = None + return attn_mask + + def maybe_pad(self, hidden_states, height, width): + pad_right = (self.window_size - width % self.window_size) % self.window_size + pad_bottom = (self.window_size - height % self.window_size) % self.window_size + pad_values = (0, 0, 0, pad_right, 0, pad_bottom) + hidden_states = nn.functional.pad(hidden_states, pad_values) + return hidden_states, pad_values + + def forward( + self, + hidden_states: torch.Tensor, + input_dimensions: Tuple[int, int], + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = False, + always_partition: Optional[bool] = False, + ) -> Tuple[torch.Tensor, torch.Tensor]: + if not always_partition: + self.set_shift_and_window_size(input_dimensions) + else: + pass + height, width = input_dimensions + batch_size, _, channels = hidden_states.size() + shortcut = hidden_states + + hidden_states = self.layernorm_before(hidden_states) + + hidden_states = hidden_states.view(batch_size, height, width, channels) + + # pad hidden_states to multiples of window size + hidden_states, pad_values = self.maybe_pad(hidden_states, height, width) + + _, height_pad, width_pad, _ = hidden_states.shape + # cyclic shift + if self.shift_size > 0: + shifted_hidden_states = torch.roll(hidden_states, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) + else: + shifted_hidden_states = hidden_states + + # partition windows + hidden_states_windows = window_partition(shifted_hidden_states, self.window_size) + hidden_states_windows = hidden_states_windows.view(-1, self.window_size * self.window_size, channels) + attn_mask = self.get_attn_mask(height_pad, width_pad, dtype=hidden_states.dtype) + if attn_mask is not None: + attn_mask = attn_mask.to(hidden_states_windows.device) + + attention_outputs = self.attention( + hidden_states_windows, attn_mask, head_mask, output_attentions=output_attentions + ) + + attention_output = attention_outputs[0] + + attention_windows = attention_output.view(-1, self.window_size, self.window_size, channels) + shifted_windows = window_reverse(attention_windows, self.window_size, height_pad, width_pad) + + # reverse cyclic shift + if self.shift_size > 0: + attention_windows = torch.roll(shifted_windows, shifts=(self.shift_size, self.shift_size), dims=(1, 2)) + else: + attention_windows = shifted_windows + + was_padded = pad_values[3] > 0 or pad_values[5] > 0 + if was_padded: + attention_windows = attention_windows[:, :height, :width, :].contiguous() + + attention_windows = attention_windows.view(batch_size, height * width, channels) + + hidden_states = shortcut + self.drop_path(attention_windows) + + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + layer_output = hidden_states + self.output(layer_output) + + layer_outputs = (layer_output, attention_outputs[1]) if output_attentions else (layer_output,) + return layer_outputs + + +# Copied from transformers.models.swin.modeling_swin.SwinStage with Swin->DonutSwin +class DonutSwinStage(nn.Module): + def __init__(self, config, dim, input_resolution, depth, num_heads, drop_path, downsample): + super().__init__() + self.config = config + self.dim = dim + self.blocks = nn.ModuleList( + [ + DonutSwinLayer( + config=config, + dim=dim, + input_resolution=input_resolution, + num_heads=num_heads, + shift_size=0 if (i % 2 == 0) else config.window_size // 2, + ) + for i in range(depth) + ] + ) + + # patch merging layer + if downsample is not None: + self.downsample = downsample(input_resolution, dim=dim, norm_layer=nn.LayerNorm) + else: + self.downsample = None + + self.pointing = False + + def forward( + self, + hidden_states: torch.Tensor, + input_dimensions: Tuple[int, int], + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = False, + always_partition: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + height, width = input_dimensions + for i, layer_module in enumerate(self.blocks): + layer_head_mask = head_mask[i] if head_mask is not None else None + + layer_outputs = layer_module( + hidden_states, input_dimensions, layer_head_mask, output_attentions, always_partition + ) + + hidden_states = layer_outputs[0] + + hidden_states_before_downsampling = hidden_states + if self.downsample is not None: + height_downsampled, width_downsampled = (height + 1) // 2, (width + 1) // 2 + output_dimensions = (height, width, height_downsampled, width_downsampled) + hidden_states = self.downsample(hidden_states_before_downsampling, input_dimensions) + else: + output_dimensions = (height, width, height, width) + + stage_outputs = (hidden_states, hidden_states_before_downsampling, output_dimensions) + + if output_attentions: + stage_outputs += layer_outputs[1:] + return stage_outputs + + +# Copied from transformers.models.swin.modeling_swin.SwinEncoder with Swin->DonutSwin +class DonutSwinEncoder(nn.Module): + def __init__(self, config, grid_size): + super().__init__() + self.num_layers = len(config.depths) + self.config = config + dpr = [x.item() for x in torch.linspace(0, config.drop_path_rate, sum(config.depths))] + self.layers = nn.ModuleList( + [ + DonutSwinStage( + config=config, + dim=int(config.embed_dim * 2**i_layer), + input_resolution=(grid_size[0] // (2**i_layer), grid_size[1] // (2**i_layer)), + depth=config.depths[i_layer], + num_heads=config.num_heads[i_layer], + drop_path=dpr[sum(config.depths[:i_layer]) : sum(config.depths[: i_layer + 1])], + downsample=DonutSwinPatchMerging if (i_layer < self.num_layers - 1) else None, + ) + for i_layer in range(self.num_layers) + ] + ) + + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + input_dimensions: Tuple[int, int], + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + output_hidden_states_before_downsampling: Optional[bool] = False, + always_partition: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple, DonutSwinEncoderOutput]: + all_hidden_states = () if output_hidden_states else None + all_reshaped_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if output_hidden_states: + batch_size, _, hidden_size = hidden_states.shape + # rearrange b (h w) c -> b c h w + reshaped_hidden_state = hidden_states.view(batch_size, *input_dimensions, hidden_size) + reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + + for i, layer_module in enumerate(self.layers): + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), hidden_states, input_dimensions, layer_head_mask + ) + else: + layer_outputs = layer_module( + hidden_states, input_dimensions, layer_head_mask, output_attentions, always_partition + ) + + hidden_states = layer_outputs[0] + hidden_states_before_downsampling = layer_outputs[1] + output_dimensions = layer_outputs[2] + + input_dimensions = (output_dimensions[-2], output_dimensions[-1]) + + if output_hidden_states and output_hidden_states_before_downsampling: + batch_size, _, hidden_size = hidden_states_before_downsampling.shape + # rearrange b (h w) c -> b c h w + # here we use the original (not downsampled) height and width + reshaped_hidden_state = hidden_states_before_downsampling.view( + batch_size, *(output_dimensions[0], output_dimensions[1]), hidden_size + ) + reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states_before_downsampling,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + elif output_hidden_states and not output_hidden_states_before_downsampling: + batch_size, _, hidden_size = hidden_states.shape + # rearrange b (h w) c -> b c h w + reshaped_hidden_state = hidden_states.view(batch_size, *input_dimensions, hidden_size) + reshaped_hidden_state = reshaped_hidden_state.permute(0, 3, 1, 2) + all_hidden_states += (hidden_states,) + all_reshaped_hidden_states += (reshaped_hidden_state,) + + if output_attentions: + all_self_attentions += layer_outputs[3:] + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + + return DonutSwinEncoderOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + reshaped_hidden_states=all_reshaped_hidden_states, + ) + + +# Copied from transformers.models.swin.modeling_swin.SwinPreTrainedModel with Swin->DonutSwin +class DonutSwinPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DonutSwinConfig + base_model_prefix = "swin" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, DonutSwinEncoder): + module.gradient_checkpointing = value + + +SWIN_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`DonutSwinConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +SWIN_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`DonutImageProcessor.__call__`] for details. + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Donut Swin Model transformer outputting raw hidden-states without any specific head on top.", + SWIN_START_DOCSTRING, +) +class DonutSwinModel(DonutSwinPreTrainedModel): + def __init__(self, config, add_pooling_layer=True, use_mask_token=False): + super().__init__(config) + self.config = config + self.num_layers = len(config.depths) + self.num_features = int(config.embed_dim * 2 ** (self.num_layers - 1)) + + self.embeddings = DonutSwinEmbeddings(config, use_mask_token=use_mask_token) + self.encoder = DonutSwinEncoder(config, self.embeddings.patch_grid) + + self.pooler = nn.AdaptiveAvgPool1d(1) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(SWIN_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=DonutSwinModelOutput, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, DonutSwinModelOutput]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, len(self.config.depths)) + + embedding_output, input_dimensions = self.embeddings(pixel_values, bool_masked_pos=bool_masked_pos) + + encoder_outputs = self.encoder( + embedding_output, + input_dimensions, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = encoder_outputs[0] + + pooled_output = None + if self.pooler is not None: + pooled_output = self.pooler(sequence_output.transpose(1, 2)) + pooled_output = torch.flatten(pooled_output, 1) + + if not return_dict: + output = (sequence_output, pooled_output) + encoder_outputs[1:] + + return output + + return DonutSwinModelOutput( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + reshaped_hidden_states=encoder_outputs.reshaped_hidden_states, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/processing_donut.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/processing_donut.py new file mode 100644 index 0000000000000000000000000000000000000000..5693fe110d95b75f63af3a94d857d395aa626799 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/donut/processing_donut.py @@ -0,0 +1,190 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Processor class for Donut. +""" +import re +import warnings +from contextlib import contextmanager + +from ...processing_utils import ProcessorMixin + + +class DonutProcessor(ProcessorMixin): + r""" + Constructs a Donut processor which wraps a Donut image processor and an XLMRoBERTa tokenizer into a single + processor. + + [`DonutProcessor`] offers all the functionalities of [`DonutImageProcessor`] and + [`XLMRobertaTokenizer`/`XLMRobertaTokenizerFast`]. See the [`~DonutProcessor.__call__`] and + [`~DonutProcessor.decode`] for more information. + + Args: + image_processor ([`DonutImageProcessor`]): + An instance of [`DonutImageProcessor`]. The image processor is a required input. + tokenizer ([`XLMRobertaTokenizer`/`XLMRobertaTokenizerFast`]): + An instance of [`XLMRobertaTokenizer`/`XLMRobertaTokenizerFast`]. The tokenizer is a required input. + """ + attributes = ["image_processor", "tokenizer"] + image_processor_class = "AutoImageProcessor" + tokenizer_class = "AutoTokenizer" + + def __init__(self, image_processor=None, tokenizer=None, **kwargs): + if "feature_extractor" in kwargs: + warnings.warn( + "The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`" + " instead.", + FutureWarning, + ) + feature_extractor = kwargs.pop("feature_extractor") + + image_processor = image_processor if image_processor is not None else feature_extractor + if image_processor is None: + raise ValueError("You need to specify an `image_processor`.") + if tokenizer is None: + raise ValueError("You need to specify a `tokenizer`.") + + super().__init__(image_processor, tokenizer) + self.current_processor = self.image_processor + self._in_target_context_manager = False + + def __call__(self, *args, **kwargs): + """ + When used in normal mode, this method forwards all its arguments to AutoImageProcessor's + [`~AutoImageProcessor.__call__`] and returns its output. If used in the context + [`~DonutProcessor.as_target_processor`] this method forwards all its arguments to DonutTokenizer's + [`~DonutTokenizer.__call__`]. Please refer to the doctsring of the above two methods for more information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor(*args, **kwargs) + + images = kwargs.pop("images", None) + text = kwargs.pop("text", None) + if len(args) > 0: + images = args[0] + args = args[1:] + + if images is None and text is None: + raise ValueError("You need to specify either an `images` or `text` input to process.") + + if images is not None: + inputs = self.image_processor(images, *args, **kwargs) + if text is not None: + encodings = self.tokenizer(text, **kwargs) + + if text is None: + return inputs + elif images is None: + return encodings + else: + inputs["labels"] = encodings["input_ids"] + return inputs + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to DonutTokenizer's [`~PreTrainedTokenizer.batch_decode`]. Please refer + to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to DonutTokenizer's [`~PreTrainedTokenizer.decode`]. Please refer to the + docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + @contextmanager + def as_target_processor(self): + """ + Temporarily sets the tokenizer for processing the input. Useful for encoding the labels when fine-tuning TrOCR. + """ + warnings.warn( + "`as_target_processor` is deprecated and will be removed in v5 of Transformers. You can process your " + "labels by using the argument `text` of the regular `__call__` method (either in the same call as " + "your images inputs, or in a separate call." + ) + self._in_target_context_manager = True + self.current_processor = self.tokenizer + yield + self.current_processor = self.image_processor + self._in_target_context_manager = False + + def token2json(self, tokens, is_inner_value=False, added_vocab=None): + """ + Convert a (generated) token sequence into an ordered JSON format. + """ + if added_vocab is None: + added_vocab = self.tokenizer.get_added_vocab() + + output = {} + + while tokens: + start_token = re.search(r"", tokens, re.IGNORECASE) + if start_token is None: + break + key = start_token.group(1) + end_token = re.search(rf"", tokens, re.IGNORECASE) + start_token = start_token.group() + if end_token is None: + tokens = tokens.replace(start_token, "") + else: + end_token = end_token.group() + start_token_escaped = re.escape(start_token) + end_token_escaped = re.escape(end_token) + content = re.search(f"{start_token_escaped}(.*?){end_token_escaped}", tokens, re.IGNORECASE) + if content is not None: + content = content.group(1).strip() + if r""): + leaf = leaf.strip() + if leaf in added_vocab and leaf[0] == "<" and leaf[-2:] == "/>": + leaf = leaf[1:-2] # for categorical special tokens + output[key].append(leaf) + if len(output[key]) == 1: + output[key] = output[key][0] + + tokens = tokens[tokens.find(end_token) + len(end_token) :].strip() + if tokens[:6] == r"": # non-leaf nodes + return [output] + self.token2json(tokens[6:], is_inner_value=True, added_vocab=added_vocab) + + if len(output): + return [output] if is_inner_value else output + else: + return [] if is_inner_value else {"text_sequence": tokens} + + @property + def feature_extractor_class(self): + warnings.warn( + "`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead.", + FutureWarning, + ) + return self.image_processor_class + + @property + def feature_extractor(self): + warnings.warn( + "`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead.", + FutureWarning, + ) + return self.image_processor diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6ea8b78e503739e91991ff14b23d8abb0cbdb975 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/__init__.py @@ -0,0 +1,148 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_dpr": ["DPR_PRETRAINED_CONFIG_ARCHIVE_MAP", "DPRConfig"], + "tokenization_dpr": [ + "DPRContextEncoderTokenizer", + "DPRQuestionEncoderTokenizer", + "DPRReaderOutput", + "DPRReaderTokenizer", + ], +} + + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_dpr_fast"] = [ + "DPRContextEncoderTokenizerFast", + "DPRQuestionEncoderTokenizerFast", + "DPRReaderTokenizerFast", + ] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_dpr"] = [ + "DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST", + "DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST", + "DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST", + "DPRContextEncoder", + "DPRPretrainedContextEncoder", + "DPRPreTrainedModel", + "DPRPretrainedQuestionEncoder", + "DPRPretrainedReader", + "DPRQuestionEncoder", + "DPRReader", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_dpr"] = [ + "TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST", + "TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST", + "TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFDPRContextEncoder", + "TFDPRPretrainedContextEncoder", + "TFDPRPretrainedQuestionEncoder", + "TFDPRPretrainedReader", + "TFDPRQuestionEncoder", + "TFDPRReader", + ] + + +if TYPE_CHECKING: + from .configuration_dpr import DPR_PRETRAINED_CONFIG_ARCHIVE_MAP, DPRConfig + from .tokenization_dpr import ( + DPRContextEncoderTokenizer, + DPRQuestionEncoderTokenizer, + DPRReaderOutput, + DPRReaderTokenizer, + ) + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_dpr_fast import ( + DPRContextEncoderTokenizerFast, + DPRQuestionEncoderTokenizerFast, + DPRReaderTokenizerFast, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_dpr import ( + DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST, + DPRContextEncoder, + DPRPretrainedContextEncoder, + DPRPreTrainedModel, + DPRPretrainedQuestionEncoder, + DPRPretrainedReader, + DPRQuestionEncoder, + DPRReader, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_dpr import ( + TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST, + TFDPRContextEncoder, + TFDPRPretrainedContextEncoder, + TFDPRPretrainedQuestionEncoder, + TFDPRPretrainedReader, + TFDPRQuestionEncoder, + TFDPRReader, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/configuration_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/configuration_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..5551883e09645e440f4b728719ee343402de56b6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/configuration_dpr.py @@ -0,0 +1,146 @@ +# coding=utf-8 +# Copyright 2010, DPR authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DPR model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +DPR_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/dpr-ctx_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/config.json" + ), + "facebook/dpr-question_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/config.json" + ), + "facebook/dpr-reader-single-nq-base": ( + "https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/config.json" + ), + "facebook/dpr-ctx_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/config.json" + ), + "facebook/dpr-question_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/config.json" + ), + "facebook/dpr-reader-multiset-base": ( + "https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/config.json" + ), +} + + +class DPRConfig(PretrainedConfig): + r""" + [`DPRConfig`] is the configuration class to store the configuration of a *DPRModel*. + + This is the configuration class to store the configuration of a [`DPRContextEncoder`], [`DPRQuestionEncoder`], or a + [`DPRReader`]. It is used to instantiate the components of the DPR model according to the specified arguments, + defining the model component architectures. Instantiating a configuration with the defaults will yield a similar + configuration to that of the DPRContextEncoder + [facebook/dpr-ctx_encoder-single-nq-base](https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base) + architecture. + + This class is a subclass of [`BertConfig`]. Please check the superclass for the documentation of all kwargs. + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the DPR model. Defines the different tokens that can be represented by the *inputs_ids* + passed to the forward method of [`BertModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the *token_type_ids* passed into [`BertModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + projection_dim (`int`, *optional*, defaults to 0): + Dimension of the projection for the context and question encoders. If it is set to zero (default), then no + projection is done. + + Example: + + ```python + >>> from transformers import DPRConfig, DPRContextEncoder + + >>> # Initializing a DPR facebook/dpr-ctx_encoder-single-nq-base style configuration + >>> configuration = DPRConfig() + + >>> # Initializing a model (with random weights) from the facebook/dpr-ctx_encoder-single-nq-base style configuration + >>> model = DPRContextEncoder(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "dpr" + + def __init__( + self, + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=0, + position_embedding_type="absolute", + projection_dim: int = 0, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.projection_dim = projection_dim + self.position_embedding_type = position_embedding_type diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..b4965857b557574c6d1f4593caa3ad2077ba2ca8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/convert_dpr_original_checkpoint_to_pytorch.py @@ -0,0 +1,143 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import collections +from pathlib import Path + +import torch +from torch.serialization import default_restore_location + +from transformers import BertConfig, DPRConfig, DPRContextEncoder, DPRQuestionEncoder, DPRReader + + +CheckpointState = collections.namedtuple( + "CheckpointState", ["model_dict", "optimizer_dict", "scheduler_dict", "offset", "epoch", "encoder_params"] +) + + +def load_states_from_checkpoint(model_file: str) -> CheckpointState: + print(f"Reading saved model from {model_file}") + state_dict = torch.load(model_file, map_location=lambda s, l: default_restore_location(s, "cpu")) + return CheckpointState(**state_dict) + + +class DPRState: + def __init__(self, src_file: Path): + self.src_file = src_file + + def load_dpr_model(self): + raise NotImplementedError + + @staticmethod + def from_type(comp_type: str, *args, **kwargs) -> "DPRState": + if comp_type.startswith("c"): + return DPRContextEncoderState(*args, **kwargs) + if comp_type.startswith("q"): + return DPRQuestionEncoderState(*args, **kwargs) + if comp_type.startswith("r"): + return DPRReaderState(*args, **kwargs) + else: + raise ValueError("Component type must be either 'ctx_encoder', 'question_encoder' or 'reader'.") + + +class DPRContextEncoderState(DPRState): + def load_dpr_model(self): + model = DPRContextEncoder(DPRConfig(**BertConfig.get_config_dict("bert-base-uncased")[0])) + print(f"Loading DPR biencoder from {self.src_file}") + saved_state = load_states_from_checkpoint(self.src_file) + encoder, prefix = model.ctx_encoder, "ctx_model." + # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3 + state_dict = {"bert_model.embeddings.position_ids": model.ctx_encoder.bert_model.embeddings.position_ids} + for key, value in saved_state.model_dict.items(): + if key.startswith(prefix): + key = key[len(prefix) :] + if not key.startswith("encode_proj."): + key = "bert_model." + key + state_dict[key] = value + encoder.load_state_dict(state_dict) + return model + + +class DPRQuestionEncoderState(DPRState): + def load_dpr_model(self): + model = DPRQuestionEncoder(DPRConfig(**BertConfig.get_config_dict("bert-base-uncased")[0])) + print(f"Loading DPR biencoder from {self.src_file}") + saved_state = load_states_from_checkpoint(self.src_file) + encoder, prefix = model.question_encoder, "question_model." + # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3 + state_dict = {"bert_model.embeddings.position_ids": model.question_encoder.bert_model.embeddings.position_ids} + for key, value in saved_state.model_dict.items(): + if key.startswith(prefix): + key = key[len(prefix) :] + if not key.startswith("encode_proj."): + key = "bert_model." + key + state_dict[key] = value + encoder.load_state_dict(state_dict) + return model + + +class DPRReaderState(DPRState): + def load_dpr_model(self): + model = DPRReader(DPRConfig(**BertConfig.get_config_dict("bert-base-uncased")[0])) + print(f"Loading DPR reader from {self.src_file}") + saved_state = load_states_from_checkpoint(self.src_file) + # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3 + state_dict = { + "encoder.bert_model.embeddings.position_ids": model.span_predictor.encoder.bert_model.embeddings.position_ids + } + for key, value in saved_state.model_dict.items(): + if key.startswith("encoder.") and not key.startswith("encoder.encode_proj"): + key = "encoder.bert_model." + key[len("encoder.") :] + state_dict[key] = value + model.span_predictor.load_state_dict(state_dict) + return model + + +def convert(comp_type: str, src_file: Path, dest_dir: Path): + dest_dir = Path(dest_dir) + dest_dir.mkdir(exist_ok=True) + + dpr_state = DPRState.from_type(comp_type, src_file=src_file) + model = dpr_state.load_dpr_model() + model.save_pretrained(dest_dir) + model.from_pretrained(dest_dir) # sanity check + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--type", type=str, help="Type of the component to convert: 'ctx_encoder', 'question_encoder' or 'reader'." + ) + parser.add_argument( + "--src", + type=str, + help=( + "Path to the dpr checkpoint file. They can be downloaded from the official DPR repo" + " https://github.com/facebookresearch/DPR. Note that in the official repo, both encoders are stored in the" + " 'retriever' checkpoints." + ), + ) + parser.add_argument("--dest", type=str, default=None, help="Path to the output PyTorch model directory.") + args = parser.parse_args() + + src_file = Path(args.src) + dest_dir = f"converted-{src_file.name}" if args.dest is None else args.dest + dest_dir = Path(dest_dir) + assert src_file.exists() + assert ( + args.type is not None + ), "Please specify the component type of the DPR model to convert: 'ctx_encoder', 'question_encoder' or 'reader'." + convert(args.type, src_file, dest_dir) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..a551e507300b0d2f11b000531413698dfd736bb8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_dpr.py @@ -0,0 +1,676 @@ +# coding=utf-8 +# Copyright 2018 DPR Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch DPR model for Open Domain Question Answering.""" + + +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +from torch import Tensor, nn + +from ...modeling_outputs import BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from ..bert.modeling_bert import BertEncoder, BertModel +from .configuration_dpr import DPRConfig + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DPRConfig" +_CHECKPOINT_FOR_DOC = "facebook/dpr-ctx_encoder-single-nq-base" + +DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-ctx_encoder-single-nq-base", + "facebook/dpr-ctx_encoder-multiset-base", +] +DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-question_encoder-single-nq-base", + "facebook/dpr-question_encoder-multiset-base", +] +DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-reader-single-nq-base", + "facebook/dpr-reader-multiset-base", +] + + +########## +# Outputs +########## + + +@dataclass +class DPRContextEncoderOutput(ModelOutput): + """ + Class for outputs of [`DPRQuestionEncoder`]. + + Args: + pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`): + The DPR encoder outputs the *pooler_output* that corresponds to the context representation. Last layer + hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. + This output is to be used to embed contexts for nearest neighbors queries with questions embeddings. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + pooler_output: torch.FloatTensor + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class DPRQuestionEncoderOutput(ModelOutput): + """ + Class for outputs of [`DPRQuestionEncoder`]. + + Args: + pooler_output (`torch.FloatTensor` of shape `(batch_size, embeddings_size)`): + The DPR encoder outputs the *pooler_output* that corresponds to the question representation. Last layer + hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. + This output is to be used to embed questions for nearest neighbors queries with context embeddings. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + pooler_output: torch.FloatTensor + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class DPRReaderOutput(ModelOutput): + """ + Class for outputs of [`DPRQuestionEncoder`]. + + Args: + start_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`): + Logits of the start index of the span for each passage. + end_logits (`torch.FloatTensor` of shape `(n_passages, sequence_length)`): + Logits of the end index of the span for each passage. + relevance_logits (`torch.FloatTensor` of shape `(n_passages, )`): + Outputs of the QA classifier of the DPRReader that corresponds to the scores of each passage to answer the + question, compared to all the other passages. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + start_logits: torch.FloatTensor + end_logits: torch.FloatTensor = None + relevance_logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +class DPRPreTrainedModel(PreTrainedModel): + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, BertEncoder): + module.gradient_checkpointing = value + + +class DPREncoder(DPRPreTrainedModel): + base_model_prefix = "bert_model" + + def __init__(self, config: DPRConfig): + super().__init__(config) + self.bert_model = BertModel(config, add_pooling_layer=False) + if self.bert_model.config.hidden_size <= 0: + raise ValueError("Encoder hidden_size can't be zero") + self.projection_dim = config.projection_dim + if self.projection_dim > 0: + self.encode_proj = nn.Linear(self.bert_model.config.hidden_size, config.projection_dim) + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + input_ids: Tensor, + attention_mask: Optional[Tensor] = None, + token_type_ids: Optional[Tensor] = None, + inputs_embeds: Optional[Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = False, + ) -> Union[BaseModelOutputWithPooling, Tuple[Tensor, ...]]: + outputs = self.bert_model( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + pooled_output = sequence_output[:, 0, :] + + if self.projection_dim > 0: + pooled_output = self.encode_proj(pooled_output) + + if not return_dict: + return (sequence_output, pooled_output) + outputs[2:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + @property + def embeddings_size(self) -> int: + if self.projection_dim > 0: + return self.encode_proj.out_features + return self.bert_model.config.hidden_size + + +class DPRSpanPredictor(DPRPreTrainedModel): + base_model_prefix = "encoder" + + def __init__(self, config: DPRConfig): + super().__init__(config) + self.encoder = DPREncoder(config) + self.qa_outputs = nn.Linear(self.encoder.embeddings_size, 2) + self.qa_classifier = nn.Linear(self.encoder.embeddings_size, 1) + # Initialize weights and apply final processing + self.post_init() + + def forward( + self, + input_ids: Tensor, + attention_mask: Tensor, + inputs_embeds: Optional[Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = False, + ) -> Union[DPRReaderOutput, Tuple[Tensor, ...]]: + # notations: N - number of questions in a batch, M - number of passages per questions, L - sequence length + n_passages, sequence_length = input_ids.size() if input_ids is not None else inputs_embeds.size()[:2] + # feed encoder + outputs = self.encoder( + input_ids, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + + # compute logits + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + relevance_logits = self.qa_classifier(sequence_output[:, 0, :]) + + # resize + start_logits = start_logits.view(n_passages, sequence_length) + end_logits = end_logits.view(n_passages, sequence_length) + relevance_logits = relevance_logits.view(n_passages) + + if not return_dict: + return (start_logits, end_logits, relevance_logits) + outputs[2:] + + return DPRReaderOutput( + start_logits=start_logits, + end_logits=end_logits, + relevance_logits=relevance_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +################## +# PreTrainedModel +################## + + +class DPRPretrainedContextEncoder(DPRPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + load_tf_weights = None + base_model_prefix = "ctx_encoder" + _keys_to_ignore_on_load_missing = [r"position_ids"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + +class DPRPretrainedQuestionEncoder(DPRPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + load_tf_weights = None + base_model_prefix = "question_encoder" + _keys_to_ignore_on_load_missing = [r"position_ids"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + +class DPRPretrainedReader(DPRPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + load_tf_weights = None + base_model_prefix = "span_predictor" + _keys_to_ignore_on_load_missing = [r"position_ids"] + + +############### +# Actual Models +############### + + +DPR_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`DPRConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +DPR_ENCODERS_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be + formatted with [CLS] and [SEP] tokens as follows: + + (a) For sequence pairs (for a pair title+text for example): + + ``` + tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] + token_type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 + ``` + + (b) For single sequences (for a question for example): + + ``` + tokens: [CLS] the dog is hairy . [SEP] + token_type_ids: 0 0 0 0 0 0 0 + ``` + + DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right + rather than the left. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +DPR_READER_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Tuple[torch.LongTensor]` of shapes `(n_passages, sequence_length)`): + Indices of input sequence tokens in the vocabulary. It has to be a sequence triplet with 1) the question + and 2) the passages titles and 3) the passages texts To match pretraining, DPR `input_ids` sequence should + be formatted with [CLS] and [SEP] with the format: + + `[CLS] [SEP] [SEP] ` + + DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right + rather than the left. + + Indices can be obtained using [`DPRReaderTokenizer`]. See this class documentation for more details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `(n_passages, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + inputs_embeds (`torch.FloatTensor` of shape `(n_passages, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare DPRContextEncoder transformer outputting pooler outputs as context representations.", + DPR_START_DOCSTRING, +) +class DPRContextEncoder(DPRPretrainedContextEncoder): + def __init__(self, config: DPRConfig): + super().__init__(config) + self.config = config + self.ctx_encoder = DPREncoder(config) + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DPR_ENCODERS_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DPRContextEncoderOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + token_type_ids: Optional[Tensor] = None, + inputs_embeds: Optional[Tensor] = None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ) -> Union[DPRContextEncoderOutput, Tuple[Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import DPRContextEncoder, DPRContextEncoderTokenizer + + >>> tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base") + >>> model = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base") + >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"] + >>> embeddings = model(input_ids).pooler_output + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = ( + torch.ones(input_shape, device=device) + if input_ids is None + else (input_ids != self.config.pad_token_id) + ) + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + outputs = self.ctx_encoder( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return outputs[1:] + return DPRContextEncoderOutput( + pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + "The bare DPRQuestionEncoder transformer outputting pooler outputs as question representations.", + DPR_START_DOCSTRING, +) +class DPRQuestionEncoder(DPRPretrainedQuestionEncoder): + def __init__(self, config: DPRConfig): + super().__init__(config) + self.config = config + self.question_encoder = DPREncoder(config) + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DPR_ENCODERS_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DPRQuestionEncoderOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + token_type_ids: Optional[Tensor] = None, + inputs_embeds: Optional[Tensor] = None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ) -> Union[DPRQuestionEncoderOutput, Tuple[Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import DPRQuestionEncoder, DPRQuestionEncoderTokenizer + + >>> tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base") + >>> model = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base") + >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="pt")["input_ids"] + >>> embeddings = model(input_ids).pooler_output + ``` + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = ( + torch.ones(input_shape, device=device) + if input_ids is None + else (input_ids != self.config.pad_token_id) + ) + if token_type_ids is None: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + outputs = self.question_encoder( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return outputs[1:] + return DPRQuestionEncoderOutput( + pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + "The bare DPRReader transformer outputting span predictions.", + DPR_START_DOCSTRING, +) +class DPRReader(DPRPretrainedReader): + def __init__(self, config: DPRConfig): + super().__init__(config) + self.config = config + self.span_predictor = DPRSpanPredictor(config) + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(DPR_READER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=DPRReaderOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + inputs_embeds: Optional[Tensor] = None, + output_attentions: bool = None, + output_hidden_states: bool = None, + return_dict=None, + ) -> Union[DPRReaderOutput, Tuple[Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import DPRReader, DPRReaderTokenizer + + >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> encoded_inputs = tokenizer( + ... questions=["What is love ?"], + ... titles=["Haddaway"], + ... texts=["'What Is Love' is a song recorded by the artist Haddaway"], + ... return_tensors="pt", + ... ) + >>> outputs = model(**encoded_inputs) + >>> start_logits = outputs.start_logits + >>> end_logits = outputs.end_logits + >>> relevance_logits = outputs.relevance_logits + ``` + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) + + return self.span_predictor( + input_ids, + attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_tf_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_tf_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..565ad37b2117e802ddeac8ac8d79b7df53ae34ae --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/modeling_tf_dpr.py @@ -0,0 +1,789 @@ +# coding=utf-8 +# Copyright 2018 DPR Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" TensorFlow DPR model for Open Domain Question Answering.""" + +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import tensorflow as tf + +from ...modeling_tf_outputs import TFBaseModelOutputWithPooling +from ...modeling_tf_utils import TFPreTrainedModel, get_initializer, shape_list, unpack_inputs +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from ..bert.modeling_tf_bert import TFBertMainLayer +from .configuration_dpr import DPRConfig + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "DPRConfig" + +TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-ctx_encoder-single-nq-base", + "facebook/dpr-ctx_encoder-multiset-base", +] +TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-question_encoder-single-nq-base", + "facebook/dpr-question_encoder-multiset-base", +] +TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/dpr-reader-single-nq-base", + "facebook/dpr-reader-multiset-base", +] + + +########## +# Outputs +########## + + +@dataclass +class TFDPRContextEncoderOutput(ModelOutput): + r""" + Class for outputs of [`TFDPRContextEncoder`]. + + Args: + pooler_output (`tf.Tensor` of shape `(batch_size, embeddings_size)`): + The DPR encoder outputs the *pooler_output* that corresponds to the context representation. Last layer + hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. + This output is to be used to embed contexts for nearest neighbors queries with questions embeddings. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + pooler_output: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFDPRQuestionEncoderOutput(ModelOutput): + """ + Class for outputs of [`TFDPRQuestionEncoder`]. + + Args: + pooler_output (`tf.Tensor` of shape `(batch_size, embeddings_size)`): + The DPR encoder outputs the *pooler_output* that corresponds to the question representation. Last layer + hidden-state of the first token of the sequence (classification token) further processed by a Linear layer. + This output is to be used to embed questions for nearest neighbors queries with context embeddings. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + pooler_output: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFDPRReaderOutput(ModelOutput): + """ + Class for outputs of [`TFDPRReaderEncoder`]. + + Args: + start_logits (`tf.Tensor` of shape `(n_passages, sequence_length)`): + Logits of the start index of the span for each passage. + end_logits (`tf.Tensor` of shape `(n_passages, sequence_length)`): + Logits of the end index of the span for each passage. + relevance_logits (`tf.Tensor` of shape `(n_passages, )`): + Outputs of the QA classifier of the DPRReader that corresponds to the scores of each passage to answer the + question, compared to all the other passages. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + start_logits: tf.Tensor = None + end_logits: tf.Tensor = None + relevance_logits: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +class TFDPREncoderLayer(tf.keras.layers.Layer): + base_model_prefix = "bert_model" + + def __init__(self, config: DPRConfig, **kwargs): + super().__init__(**kwargs) + + # resolve name conflict with TFBertMainLayer instead of TFBertModel + self.bert_model = TFBertMainLayer(config, add_pooling_layer=False, name="bert_model") + self.config = config + + if self.config.hidden_size <= 0: + raise ValueError("Encoder hidden_size can't be zero") + self.projection_dim = config.projection_dim + if self.projection_dim > 0: + self.encode_proj = tf.keras.layers.Dense( + config.projection_dim, kernel_initializer=get_initializer(config.initializer_range), name="encode_proj" + ) + + @unpack_inputs + def call( + self, + input_ids: tf.Tensor = None, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: bool = None, + output_hidden_states: bool = None, + return_dict: bool = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor, ...]]: + outputs = self.bert_model( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + pooled_output = sequence_output[:, 0, :] + if self.projection_dim > 0: + pooled_output = self.encode_proj(pooled_output) + + if not return_dict: + return (sequence_output, pooled_output) + outputs[1:] + + return TFBaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + @property + def embeddings_size(self) -> int: + if self.projection_dim > 0: + return self.projection_dim + return self.bert_model.config.hidden_size + + +class TFDPRSpanPredictorLayer(tf.keras.layers.Layer): + base_model_prefix = "encoder" + + def __init__(self, config: DPRConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + self.encoder = TFDPREncoderLayer(config, name="encoder") + + self.qa_outputs = tf.keras.layers.Dense( + 2, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + self.qa_classifier = tf.keras.layers.Dense( + 1, kernel_initializer=get_initializer(config.initializer_range), name="qa_classifier" + ) + + @unpack_inputs + def call( + self, + input_ids: tf.Tensor = None, + attention_mask: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = False, + training: bool = False, + ) -> Union[TFDPRReaderOutput, Tuple[tf.Tensor, ...]]: + # notations: N - number of questions in a batch, M - number of passages per questions, L - sequence length + n_passages, sequence_length = shape_list(input_ids) if input_ids is not None else shape_list(inputs_embeds)[:2] + # feed encoder + outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + + # compute logits + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = tf.split(logits, 2, axis=-1) + start_logits = tf.squeeze(start_logits, axis=-1) + end_logits = tf.squeeze(end_logits, axis=-1) + relevance_logits = self.qa_classifier(sequence_output[:, 0, :]) + + # resize + start_logits = tf.reshape(start_logits, [n_passages, sequence_length]) + end_logits = tf.reshape(end_logits, [n_passages, sequence_length]) + relevance_logits = tf.reshape(relevance_logits, [n_passages]) + + if not return_dict: + return (start_logits, end_logits, relevance_logits) + outputs[2:] + + return TFDPRReaderOutput( + start_logits=start_logits, + end_logits=end_logits, + relevance_logits=relevance_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class TFDPRSpanPredictor(TFPreTrainedModel): + base_model_prefix = "encoder" + + def __init__(self, config: DPRConfig, **kwargs): + super().__init__(config, **kwargs) + self.encoder = TFDPRSpanPredictorLayer(config) + + @unpack_inputs + def call( + self, + input_ids: tf.Tensor = None, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = False, + training: bool = False, + ) -> Union[TFDPRReaderOutput, Tuple[tf.Tensor, ...]]: + outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + +class TFDPREncoder(TFPreTrainedModel): + base_model_prefix = "encoder" + + def __init__(self, config: DPRConfig, **kwargs): + super().__init__(config, **kwargs) + + self.encoder = TFDPREncoderLayer(config) + + @unpack_inputs + def call( + self, + input_ids: tf.Tensor = None, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = False, + training: bool = False, + ) -> Union[TFDPRReaderOutput, Tuple[tf.Tensor, ...]]: + outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + return outputs + + +################## +# PreTrainedModel +################## + + +class TFDPRPretrainedContextEncoder(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + base_model_prefix = "ctx_encoder" + + +class TFDPRPretrainedQuestionEncoder(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + base_model_prefix = "question_encoder" + + +class TFDPRPretrainedReader(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = DPRConfig + base_model_prefix = "reader" + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + +############### +# Actual Models +############### + + +TF_DPR_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a Tensorflow [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) + subclass. Use it as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to + general usage and behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`DPRConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +TF_DPR_ENCODERS_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. To match pretraining, DPR input sequence should be + formatted with [CLS] and [SEP] tokens as follows: + + (a) For sequence pairs (for a pair title+text for example): + + ``` + tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] + token_type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 + ``` + + (b) For single sequences (for a question for example): + + ``` + tokens: [CLS] the dog is hairy . [SEP] + token_type_ids: 0 0 0 0 0 0 0 + ``` + + DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right + rather than the left. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + inputs_embeds (`Numpy array` or `tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + +TF_DPR_READER_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shapes `(n_passages, sequence_length)`): + Indices of input sequence tokens in the vocabulary. It has to be a sequence triplet with 1) the question + and 2) the passages titles and 3) the passages texts To match pretraining, DPR `input_ids` sequence should + be formatted with [CLS] and [SEP] with the format: + + `[CLS] [SEP] [SEP] ` + + DPR is a model with absolute position embeddings so it's usually advised to pad the inputs on the right + rather than the left. + + Indices can be obtained using [`DPRReaderTokenizer`]. See this class documentation for more details. + attention_mask (`Numpy array` or `tf.Tensor` of shape `(n_passages, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + inputs_embeds (`Numpy array` or `tf.Tensor` of shape `(n_passages, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare DPRContextEncoder transformer outputting pooler outputs as context representations.", + TF_DPR_START_DOCSTRING, +) +class TFDPRContextEncoder(TFDPRPretrainedContextEncoder): + def __init__(self, config: DPRConfig, *args, **kwargs): + super().__init__(config, *args, **kwargs) + self.ctx_encoder = TFDPREncoderLayer(config, name="ctx_encoder") + + def get_input_embeddings(self): + try: + return self.ctx_encoder.bert_model.get_input_embeddings() + except AttributeError: + self(self.dummy_inputs) + return self.ctx_encoder.bert_model.get_input_embeddings() + + @unpack_inputs + @add_start_docstrings_to_model_forward(TF_DPR_ENCODERS_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFDPRContextEncoderOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids=None, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training: bool = False, + ) -> Union[TFDPRContextEncoderOutput, Tuple[tf.Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import TFDPRContextEncoder, DPRContextEncoderTokenizer + + >>> tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base") + >>> model = TFDPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base", from_pt=True) + >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="tf")["input_ids"] + >>> embeddings = model(input_ids).pooler_output + ``` + """ + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = ( + tf.ones(input_shape, dtype=tf.dtypes.int32) + if input_ids is None + else (input_ids != self.config.pad_token_id) + ) + if token_type_ids is None: + token_type_ids = tf.zeros(input_shape, dtype=tf.dtypes.int32) + + outputs = self.ctx_encoder( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + if not return_dict: + return outputs[1:] + + return TFDPRContextEncoderOutput( + pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFDPRContextEncoderOutput(pooler_output=output.pooler_output, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + "The bare DPRQuestionEncoder transformer outputting pooler outputs as question representations.", + TF_DPR_START_DOCSTRING, +) +class TFDPRQuestionEncoder(TFDPRPretrainedQuestionEncoder): + def __init__(self, config: DPRConfig, *args, **kwargs): + super().__init__(config, *args, **kwargs) + self.question_encoder = TFDPREncoderLayer(config, name="question_encoder") + + def get_input_embeddings(self): + try: + return self.question_encoder.bert_model.get_input_embeddings() + except AttributeError: + self(self.dummy_inputs) + return self.question_encoder.bert_model.get_input_embeddings() + + @unpack_inputs + @add_start_docstrings_to_model_forward(TF_DPR_ENCODERS_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFDPRQuestionEncoderOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids=None, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training: bool = False, + ) -> Union[TFDPRQuestionEncoderOutput, Tuple[tf.Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import TFDPRQuestionEncoder, DPRQuestionEncoderTokenizer + + >>> tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base") + >>> model = TFDPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base", from_pt=True) + >>> input_ids = tokenizer("Hello, is my dog cute ?", return_tensors="tf")["input_ids"] + >>> embeddings = model(input_ids).pooler_output + ``` + """ + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = ( + tf.ones(input_shape, dtype=tf.dtypes.int32) + if input_ids is None + else (input_ids != self.config.pad_token_id) + ) + if token_type_ids is None: + token_type_ids = tf.zeros(input_shape, dtype=tf.dtypes.int32) + + outputs = self.question_encoder( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + if not return_dict: + return outputs[1:] + return TFDPRQuestionEncoderOutput( + pooler_output=outputs.pooler_output, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFDPRQuestionEncoderOutput(pooler_output=output.pooler_output, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + "The bare DPRReader transformer outputting span predictions.", + TF_DPR_START_DOCSTRING, +) +class TFDPRReader(TFDPRPretrainedReader): + def __init__(self, config: DPRConfig, *args, **kwargs): + super().__init__(config, *args, **kwargs) + self.span_predictor = TFDPRSpanPredictorLayer(config, name="span_predictor") + + def get_input_embeddings(self): + try: + return self.span_predictor.encoder.bert_model.get_input_embeddings() + except AttributeError: + self(self.dummy_inputs) + return self.span_predictor.encoder.bert_model.get_input_embeddings() + + @unpack_inputs + @add_start_docstrings_to_model_forward(TF_DPR_READER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFDPRReaderOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids=None, + attention_mask: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: bool = None, + output_hidden_states: bool = None, + return_dict=None, + training: bool = False, + ) -> Union[TFDPRReaderOutput, Tuple[tf.Tensor, ...]]: + r""" + Return: + + Examples: + + ```python + >>> from transformers import TFDPRReader, DPRReaderTokenizer + + >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> model = TFDPRReader.from_pretrained("facebook/dpr-reader-single-nq-base", from_pt=True) + >>> encoded_inputs = tokenizer( + ... questions=["What is love ?"], + ... titles=["Haddaway"], + ... texts=["'What Is Love' is a song recorded by the artist Haddaway"], + ... return_tensors="tf", + ... ) + >>> outputs = model(encoded_inputs) + >>> start_logits = outputs.start_logits + >>> end_logits = outputs.end_logits + >>> relevance_logits = outputs.relevance_logits + ``` + """ + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if attention_mask is None: + attention_mask = tf.ones(input_shape, dtype=tf.dtypes.int32) + + return self.span_predictor( + input_ids=input_ids, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFDPRReaderOutput( + start_logits=output.start_logits, + end_logits=output.end_logits, + relevance_logits=output.relevance_logits, + hidden_states=hs, + attentions=attns, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..a2024dda5d69e3c96becc895be53c82c76f8bb0e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr.py @@ -0,0 +1,412 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for DPR.""" + + +import collections +from typing import List, Optional, Union + +from ...tokenization_utils_base import BatchEncoding +from ...utils import TensorType, add_end_docstrings, add_start_docstrings, logging +from ..bert.tokenization_bert import BertTokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"} + +CONTEXT_ENCODER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-ctx_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-ctx_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-ctx_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-ctx_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/tokenizer.json" + ), + }, +} +QUESTION_ENCODER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-question_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-question_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-question_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-question_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/tokenizer.json" + ), + }, +} +READER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-reader-single-nq-base": ( + "https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-reader-multiset-base": ( + "https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-reader-single-nq-base": ( + "https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-reader-multiset-base": ( + "https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/tokenizer.json" + ), + }, +} + +CONTEXT_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-ctx_encoder-single-nq-base": 512, + "facebook/dpr-ctx_encoder-multiset-base": 512, +} +QUESTION_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-question_encoder-single-nq-base": 512, + "facebook/dpr-question_encoder-multiset-base": 512, +} +READER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-reader-single-nq-base": 512, + "facebook/dpr-reader-multiset-base": 512, +} + + +CONTEXT_ENCODER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-ctx_encoder-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-ctx_encoder-multiset-base": {"do_lower_case": True}, +} +QUESTION_ENCODER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-question_encoder-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-question_encoder-multiset-base": {"do_lower_case": True}, +} +READER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-reader-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-reader-multiset-base": {"do_lower_case": True}, +} + + +class DPRContextEncoderTokenizer(BertTokenizer): + r""" + Construct a DPRContextEncoder tokenizer. + + [`DPRContextEncoderTokenizer`] is identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation + splitting and wordpiece. + + Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = CONTEXT_ENCODER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = CONTEXT_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = CONTEXT_ENCODER_PRETRAINED_INIT_CONFIGURATION + + +class DPRQuestionEncoderTokenizer(BertTokenizer): + r""" + Constructs a DPRQuestionEncoder tokenizer. + + [`DPRQuestionEncoderTokenizer`] is identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation + splitting and wordpiece. + + Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = QUESTION_ENCODER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = QUESTION_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = QUESTION_ENCODER_PRETRAINED_INIT_CONFIGURATION + + +DPRSpanPrediction = collections.namedtuple( + "DPRSpanPrediction", ["span_score", "relevance_score", "doc_id", "start_index", "end_index", "text"] +) + +DPRReaderOutput = collections.namedtuple("DPRReaderOutput", ["start_logits", "end_logits", "relevance_logits"]) + + +CUSTOM_DPR_READER_DOCSTRING = r""" + Return a dictionary with the token ids of the input strings and other information to give to `.decode_best_spans`. + It converts the strings of a question and different passages (title and text) in a sequence of IDs (integers), + using the tokenizer and vocabulary. The resulting `input_ids` is a matrix of size `(n_passages, sequence_length)` + with the format: + + ``` + [CLS] [SEP] [SEP] + ``` + + Args: + questions (`str` or `List[str]`): + The questions to be encoded. You can specify one question for many passages. In this case, the question + will be duplicated like `[questions] * n_passages`. Otherwise you have to specify as many questions as in + `titles` or `texts`. + titles (`str` or `List[str]`): + The passages titles to be encoded. This can be a string or a list of strings if there are several passages. + texts (`str` or `List[str]`): + The passages texts to be encoded. This can be a string or a list of strings if there are several passages. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single sequence + if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`): + Activates and controls truncation. Accepts the following values: + + - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to + the maximum acceptable input length for the model if that argument is not provided. This will truncate + token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a batch + of pairs) is provided. + - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. This will only truncate the first + sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. This will only truncate the + second sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths + greater than the model maximum admissible input size). + max_length (`int`, *optional*): + Controls the maximum length to use by one of the truncation/padding parameters. + + If left unset or set to `None`, this will use the predefined model maximum length if a maximum length + is required by one of the truncation/padding parameters. If the model has no specific maximum input + length (like XLNet) truncation/padding to a maximum length will be deactivated. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + return_attention_mask (`bool`, *optional*): + Whether or not to return the attention mask. If not set, will return the attention mask according to the + specific tokenizer's default, defined by the `return_outputs` attribute. + + [What are attention masks?](../glossary#attention-mask) + + Returns: + `Dict[str, List[List[int]]]`: A dictionary with the following keys: + + - `input_ids`: List of token ids to be fed to a model. + - `attention_mask`: List of indices specifying which tokens should be attended to by the model. + """ + + +@add_start_docstrings(CUSTOM_DPR_READER_DOCSTRING) +class CustomDPRReaderTokenizerMixin: + def __call__( + self, + questions, + titles: Optional[str] = None, + texts: Optional[str] = None, + padding: Union[bool, str] = False, + truncation: Union[bool, str] = False, + max_length: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_attention_mask: Optional[bool] = None, + **kwargs, + ) -> BatchEncoding: + if titles is None and texts is None: + return super().__call__( + questions, + padding=padding, + truncation=truncation, + max_length=max_length, + return_tensors=return_tensors, + return_attention_mask=return_attention_mask, + **kwargs, + ) + elif titles is None or texts is None: + text_pair = titles if texts is None else texts + return super().__call__( + questions, + text_pair, + padding=padding, + truncation=truncation, + max_length=max_length, + return_tensors=return_tensors, + return_attention_mask=return_attention_mask, + **kwargs, + ) + titles = titles if not isinstance(titles, str) else [titles] + texts = texts if not isinstance(texts, str) else [texts] + n_passages = len(titles) + questions = questions if not isinstance(questions, str) else [questions] * n_passages + if len(titles) != len(texts): + raise ValueError( + f"There should be as many titles than texts but got {len(titles)} titles and {len(texts)} texts." + ) + encoded_question_and_titles = super().__call__(questions, titles, padding=False, truncation=False)["input_ids"] + encoded_texts = super().__call__(texts, add_special_tokens=False, padding=False, truncation=False)["input_ids"] + encoded_inputs = { + "input_ids": [ + (encoded_question_and_title + encoded_text)[:max_length] + if max_length is not None and truncation + else encoded_question_and_title + encoded_text + for encoded_question_and_title, encoded_text in zip(encoded_question_and_titles, encoded_texts) + ] + } + if return_attention_mask is not False: + attention_mask = [] + for input_ids in encoded_inputs["input_ids"]: + attention_mask.append([int(input_id != self.pad_token_id) for input_id in input_ids]) + encoded_inputs["attention_mask"] = attention_mask + return self.pad(encoded_inputs, padding=padding, max_length=max_length, return_tensors=return_tensors) + + def decode_best_spans( + self, + reader_input: BatchEncoding, + reader_output: DPRReaderOutput, + num_spans: int = 16, + max_answer_length: int = 64, + num_spans_per_passage: int = 4, + ) -> List[DPRSpanPrediction]: + """ + Get the span predictions for the extractive Q&A model. + + Returns: *List* of *DPRReaderOutput* sorted by descending *(relevance_score, span_score)*. Each + *DPRReaderOutput* is a *Tuple* with: + + - **span_score**: `float` that corresponds to the score given by the reader for this span compared to other + spans in the same passage. It corresponds to the sum of the start and end logits of the span. + - **relevance_score**: `float` that corresponds to the score of the each passage to answer the question, + compared to all the other passages. It corresponds to the output of the QA classifier of the DPRReader. + - **doc_id**: `int` the id of the passage. - **start_index**: `int` the start index of the span + (inclusive). - **end_index**: `int` the end index of the span (inclusive). + + Examples: + + ```python + >>> from transformers import DPRReader, DPRReaderTokenizer + + >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> encoded_inputs = tokenizer( + ... questions=["What is love ?"], + ... titles=["Haddaway"], + ... texts=["'What Is Love' is a song recorded by the artist Haddaway"], + ... return_tensors="pt", + ... ) + >>> outputs = model(**encoded_inputs) + >>> predicted_spans = tokenizer.decode_best_spans(encoded_inputs, outputs) + >>> print(predicted_spans[0].text) # best span + a song + ```""" + input_ids = reader_input["input_ids"] + start_logits, end_logits, relevance_logits = reader_output[:3] + n_passages = len(relevance_logits) + sorted_docs = sorted(range(n_passages), reverse=True, key=relevance_logits.__getitem__) + nbest_spans_predictions: List[DPRReaderOutput] = [] + for doc_id in sorted_docs: + sequence_ids = list(input_ids[doc_id]) + # assuming question & title information is at the beginning of the sequence + passage_offset = sequence_ids.index(self.sep_token_id, 2) + 1 # second sep id + if sequence_ids[-1] == self.pad_token_id: + sequence_len = sequence_ids.index(self.pad_token_id) + else: + sequence_len = len(sequence_ids) + + best_spans = self._get_best_spans( + start_logits=start_logits[doc_id][passage_offset:sequence_len], + end_logits=end_logits[doc_id][passage_offset:sequence_len], + max_answer_length=max_answer_length, + top_spans=num_spans_per_passage, + ) + for start_index, end_index in best_spans: + start_index += passage_offset + end_index += passage_offset + nbest_spans_predictions.append( + DPRSpanPrediction( + span_score=start_logits[doc_id][start_index] + end_logits[doc_id][end_index], + relevance_score=relevance_logits[doc_id], + doc_id=doc_id, + start_index=start_index, + end_index=end_index, + text=self.decode(sequence_ids[start_index : end_index + 1]), + ) + ) + if len(nbest_spans_predictions) >= num_spans: + break + return nbest_spans_predictions[:num_spans] + + def _get_best_spans( + self, + start_logits: List[int], + end_logits: List[int], + max_answer_length: int, + top_spans: int, + ) -> List[DPRSpanPrediction]: + """ + Finds the best answer span for the extractive Q&A model for one passage. It returns the best span by descending + `span_score` order and keeping max `top_spans` spans. Spans longer that `max_answer_length` are ignored. + """ + scores = [] + for start_index, start_score in enumerate(start_logits): + for answer_length, end_score in enumerate(end_logits[start_index : start_index + max_answer_length]): + scores.append(((start_index, start_index + answer_length), start_score + end_score)) + scores = sorted(scores, key=lambda x: x[1], reverse=True) + chosen_span_intervals = [] + for (start_index, end_index), score in scores: + if start_index > end_index: + raise ValueError(f"Wrong span indices: [{start_index}:{end_index}]") + length = end_index - start_index + 1 + if length > max_answer_length: + raise ValueError(f"Span is too long: {length} > {max_answer_length}") + if any( + [ + start_index <= prev_start_index <= prev_end_index <= end_index + or prev_start_index <= start_index <= end_index <= prev_end_index + for (prev_start_index, prev_end_index) in chosen_span_intervals + ] + ): + continue + chosen_span_intervals.append((start_index, end_index)) + + if len(chosen_span_intervals) == top_spans: + break + return chosen_span_intervals + + +@add_end_docstrings(CUSTOM_DPR_READER_DOCSTRING) +class DPRReaderTokenizer(CustomDPRReaderTokenizerMixin, BertTokenizer): + r""" + Construct a DPRReader tokenizer. + + [`DPRReaderTokenizer`] is almost identical to [`BertTokenizer`] and runs end-to-end tokenization: punctuation + splitting and wordpiece. The difference is that is has three inputs strings: question, titles and texts that are + combined to be fed to the [`DPRReader`] model. + + Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = READER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = READER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = READER_PRETRAINED_INIT_CONFIGURATION + model_input_names = ["input_ids", "attention_mask"] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..de32332bf27176f15be3af1be1c8830cc8d44ec5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpr/tokenization_dpr_fast.py @@ -0,0 +1,412 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for DPR.""" + + +import collections +from typing import List, Optional, Union + +from ...tokenization_utils_base import BatchEncoding +from ...utils import TensorType, add_end_docstrings, add_start_docstrings, logging +from ..bert.tokenization_bert_fast import BertTokenizerFast +from .tokenization_dpr import DPRContextEncoderTokenizer, DPRQuestionEncoderTokenizer, DPRReaderTokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"} + +CONTEXT_ENCODER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-ctx_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-ctx_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-ctx_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-ctx_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-ctx_encoder-multiset-base/resolve/main/tokenizer.json" + ), + }, +} +QUESTION_ENCODER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-question_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-question_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-question_encoder-single-nq-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-question_encoder-multiset-base": ( + "https://huggingface.co/facebook/dpr-question_encoder-multiset-base/resolve/main/tokenizer.json" + ), + }, +} +READER_PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/dpr-reader-single-nq-base": ( + "https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/vocab.txt" + ), + "facebook/dpr-reader-multiset-base": ( + "https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "facebook/dpr-reader-single-nq-base": ( + "https://huggingface.co/facebook/dpr-reader-single-nq-base/resolve/main/tokenizer.json" + ), + "facebook/dpr-reader-multiset-base": ( + "https://huggingface.co/facebook/dpr-reader-multiset-base/resolve/main/tokenizer.json" + ), + }, +} + +CONTEXT_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-ctx_encoder-single-nq-base": 512, + "facebook/dpr-ctx_encoder-multiset-base": 512, +} +QUESTION_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-question_encoder-single-nq-base": 512, + "facebook/dpr-question_encoder-multiset-base": 512, +} +READER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/dpr-reader-single-nq-base": 512, + "facebook/dpr-reader-multiset-base": 512, +} + + +CONTEXT_ENCODER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-ctx_encoder-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-ctx_encoder-multiset-base": {"do_lower_case": True}, +} +QUESTION_ENCODER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-question_encoder-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-question_encoder-multiset-base": {"do_lower_case": True}, +} +READER_PRETRAINED_INIT_CONFIGURATION = { + "facebook/dpr-reader-single-nq-base": {"do_lower_case": True}, + "facebook/dpr-reader-multiset-base": {"do_lower_case": True}, +} + + +class DPRContextEncoderTokenizerFast(BertTokenizerFast): + r""" + Construct a "fast" DPRContextEncoder tokenizer (backed by HuggingFace's *tokenizers* library). + + [`DPRContextEncoderTokenizerFast`] is identical to [`BertTokenizerFast`] and runs end-to-end tokenization: + punctuation splitting and wordpiece. + + Refer to superclass [`BertTokenizerFast`] for usage examples and documentation concerning parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = CONTEXT_ENCODER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = CONTEXT_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = CONTEXT_ENCODER_PRETRAINED_INIT_CONFIGURATION + slow_tokenizer_class = DPRContextEncoderTokenizer + + +class DPRQuestionEncoderTokenizerFast(BertTokenizerFast): + r""" + Constructs a "fast" DPRQuestionEncoder tokenizer (backed by HuggingFace's *tokenizers* library). + + [`DPRQuestionEncoderTokenizerFast`] is identical to [`BertTokenizerFast`] and runs end-to-end tokenization: + punctuation splitting and wordpiece. + + Refer to superclass [`BertTokenizerFast`] for usage examples and documentation concerning parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = QUESTION_ENCODER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = QUESTION_ENCODER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = QUESTION_ENCODER_PRETRAINED_INIT_CONFIGURATION + slow_tokenizer_class = DPRQuestionEncoderTokenizer + + +DPRSpanPrediction = collections.namedtuple( + "DPRSpanPrediction", ["span_score", "relevance_score", "doc_id", "start_index", "end_index", "text"] +) + +DPRReaderOutput = collections.namedtuple("DPRReaderOutput", ["start_logits", "end_logits", "relevance_logits"]) + + +CUSTOM_DPR_READER_DOCSTRING = r""" + Return a dictionary with the token ids of the input strings and other information to give to `.decode_best_spans`. + It converts the strings of a question and different passages (title and text) in a sequence of IDs (integers), + using the tokenizer and vocabulary. The resulting `input_ids` is a matrix of size `(n_passages, sequence_length)` + with the format: + + [CLS] [SEP] [SEP] + + Args: + questions (`str` or `List[str]`): + The questions to be encoded. You can specify one question for many passages. In this case, the question + will be duplicated like `[questions] * n_passages`. Otherwise you have to specify as many questions as in + `titles` or `texts`. + titles (`str` or `List[str]`): + The passages titles to be encoded. This can be a string or a list of strings if there are several passages. + texts (`str` or `List[str]`): + The passages texts to be encoded. This can be a string or a list of strings if there are several passages. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single sequence + if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`): + Activates and controls truncation. Accepts the following values: + + - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to + the maximum acceptable input length for the model if that argument is not provided. This will truncate + token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a batch + of pairs) is provided. + - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. This will only truncate the first + sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. This will only truncate the + second sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths + greater than the model maximum admissible input size). + max_length (`int`, *optional*): + Controls the maximum length to use by one of the truncation/padding parameters. + + If left unset or set to `None`, this will use the predefined model maximum length if a maximum length + is required by one of the truncation/padding parameters. If the model has no specific maximum input + length (like XLNet) truncation/padding to a maximum length will be deactivated. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + return_attention_mask (`bool`, *optional*): + Whether or not to return the attention mask. If not set, will return the attention mask according to the + specific tokenizer's default, defined by the `return_outputs` attribute. + + [What are attention masks?](../glossary#attention-mask) + + Return: + `Dict[str, List[List[int]]]`: A dictionary with the following keys: + + - `input_ids`: List of token ids to be fed to a model. + - `attention_mask`: List of indices specifying which tokens should be attended to by the model. + """ + + +@add_start_docstrings(CUSTOM_DPR_READER_DOCSTRING) +class CustomDPRReaderTokenizerMixin: + def __call__( + self, + questions, + titles: Optional[str] = None, + texts: Optional[str] = None, + padding: Union[bool, str] = False, + truncation: Union[bool, str] = False, + max_length: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_attention_mask: Optional[bool] = None, + **kwargs, + ) -> BatchEncoding: + if titles is None and texts is None: + return super().__call__( + questions, + padding=padding, + truncation=truncation, + max_length=max_length, + return_tensors=return_tensors, + return_attention_mask=return_attention_mask, + **kwargs, + ) + elif titles is None or texts is None: + text_pair = titles if texts is None else texts + return super().__call__( + questions, + text_pair, + padding=padding, + truncation=truncation, + max_length=max_length, + return_tensors=return_tensors, + return_attention_mask=return_attention_mask, + **kwargs, + ) + titles = titles if not isinstance(titles, str) else [titles] + texts = texts if not isinstance(texts, str) else [texts] + n_passages = len(titles) + questions = questions if not isinstance(questions, str) else [questions] * n_passages + assert len(titles) == len( + texts + ), f"There should be as many titles than texts but got {len(titles)} titles and {len(texts)} texts." + encoded_question_and_titles = super().__call__(questions, titles, padding=False, truncation=False)["input_ids"] + encoded_texts = super().__call__(texts, add_special_tokens=False, padding=False, truncation=False)["input_ids"] + encoded_inputs = { + "input_ids": [ + (encoded_question_and_title + encoded_text)[:max_length] + if max_length is not None and truncation + else encoded_question_and_title + encoded_text + for encoded_question_and_title, encoded_text in zip(encoded_question_and_titles, encoded_texts) + ] + } + if return_attention_mask is not False: + attention_mask = [] + for input_ids in encoded_inputs["input_ids"]: + attention_mask.append([int(input_id != self.pad_token_id) for input_id in input_ids]) + encoded_inputs["attention_mask"] = attention_mask + return self.pad(encoded_inputs, padding=padding, max_length=max_length, return_tensors=return_tensors) + + def decode_best_spans( + self, + reader_input: BatchEncoding, + reader_output: DPRReaderOutput, + num_spans: int = 16, + max_answer_length: int = 64, + num_spans_per_passage: int = 4, + ) -> List[DPRSpanPrediction]: + """ + Get the span predictions for the extractive Q&A model. + + Returns: *List* of *DPRReaderOutput* sorted by descending *(relevance_score, span_score)*. Each + *DPRReaderOutput* is a *Tuple* with: + + - **span_score**: `float` that corresponds to the score given by the reader for this span compared to other + spans in the same passage. It corresponds to the sum of the start and end logits of the span. + - **relevance_score**: `float` that corresponds to the score of the each passage to answer the question, + compared to all the other passages. It corresponds to the output of the QA classifier of the DPRReader. + - **doc_id**: `int` the id of the passage. - ***start_index**: `int` the start index of the span + (inclusive). - **end_index**: `int` the end index of the span (inclusive). + + Examples: + + ```python + >>> from transformers import DPRReader, DPRReaderTokenizer + + >>> tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base") + >>> encoded_inputs = tokenizer( + ... questions=["What is love ?"], + ... titles=["Haddaway"], + ... texts=["'What Is Love' is a song recorded by the artist Haddaway"], + ... return_tensors="pt", + ... ) + >>> outputs = model(**encoded_inputs) + >>> predicted_spans = tokenizer.decode_best_spans(encoded_inputs, outputs) + >>> print(predicted_spans[0].text) # best span + a song + ```""" + input_ids = reader_input["input_ids"] + start_logits, end_logits, relevance_logits = reader_output[:3] + n_passages = len(relevance_logits) + sorted_docs = sorted(range(n_passages), reverse=True, key=relevance_logits.__getitem__) + nbest_spans_predictions: List[DPRReaderOutput] = [] + for doc_id in sorted_docs: + sequence_ids = list(input_ids[doc_id]) + # assuming question & title information is at the beginning of the sequence + passage_offset = sequence_ids.index(self.sep_token_id, 2) + 1 # second sep id + if sequence_ids[-1] == self.pad_token_id: + sequence_len = sequence_ids.index(self.pad_token_id) + else: + sequence_len = len(sequence_ids) + + best_spans = self._get_best_spans( + start_logits=start_logits[doc_id][passage_offset:sequence_len], + end_logits=end_logits[doc_id][passage_offset:sequence_len], + max_answer_length=max_answer_length, + top_spans=num_spans_per_passage, + ) + for start_index, end_index in best_spans: + start_index += passage_offset + end_index += passage_offset + nbest_spans_predictions.append( + DPRSpanPrediction( + span_score=start_logits[doc_id][start_index] + end_logits[doc_id][end_index], + relevance_score=relevance_logits[doc_id], + doc_id=doc_id, + start_index=start_index, + end_index=end_index, + text=self.decode(sequence_ids[start_index : end_index + 1]), + ) + ) + if len(nbest_spans_predictions) >= num_spans: + break + return nbest_spans_predictions[:num_spans] + + def _get_best_spans( + self, + start_logits: List[int], + end_logits: List[int], + max_answer_length: int, + top_spans: int, + ) -> List[DPRSpanPrediction]: + """ + Finds the best answer span for the extractive Q&A model for one passage. It returns the best span by descending + `span_score` order and keeping max `top_spans` spans. Spans longer that `max_answer_length` are ignored. + """ + scores = [] + for start_index, start_score in enumerate(start_logits): + for answer_length, end_score in enumerate(end_logits[start_index : start_index + max_answer_length]): + scores.append(((start_index, start_index + answer_length), start_score + end_score)) + scores = sorted(scores, key=lambda x: x[1], reverse=True) + chosen_span_intervals = [] + for (start_index, end_index), score in scores: + assert start_index <= end_index, f"Wrong span indices: [{start_index}:{end_index}]" + length = end_index - start_index + 1 + assert length <= max_answer_length, f"Span is too long: {length} > {max_answer_length}" + if any( + [ + start_index <= prev_start_index <= prev_end_index <= end_index + or prev_start_index <= start_index <= end_index <= prev_end_index + for (prev_start_index, prev_end_index) in chosen_span_intervals + ] + ): + continue + chosen_span_intervals.append((start_index, end_index)) + + if len(chosen_span_intervals) == top_spans: + break + return chosen_span_intervals + + +@add_end_docstrings(CUSTOM_DPR_READER_DOCSTRING) +class DPRReaderTokenizerFast(CustomDPRReaderTokenizerMixin, BertTokenizerFast): + r""" + Constructs a "fast" DPRReader tokenizer (backed by HuggingFace's *tokenizers* library). + + [`DPRReaderTokenizerFast`] is almost identical to [`BertTokenizerFast`] and runs end-to-end tokenization: + punctuation splitting and wordpiece. The difference is that is has three inputs strings: question, titles and texts + that are combined to be fed to the [`DPRReader`] model. + + Refer to superclass [`BertTokenizerFast`] for usage examples and documentation concerning parameters. + + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = READER_PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = READER_PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = READER_PRETRAINED_INIT_CONFIGURATION + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = DPRReaderTokenizer diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..da53011b87b318bbef0d48557284d290f92a9fe4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/__init__.py @@ -0,0 +1,76 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...file_utils import _LazyModule, is_tokenizers_available, is_torch_available, is_vision_available +from ...utils import OptionalDependencyNotAvailable + + +_import_structure = {"configuration_dpt": ["DPT_PRETRAINED_CONFIG_ARCHIVE_MAP", "DPTConfig"]} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_dpt"] = ["DPTFeatureExtractor"] + _import_structure["image_processing_dpt"] = ["DPTImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_dpt"] = [ + "DPT_PRETRAINED_MODEL_ARCHIVE_LIST", + "DPTForDepthEstimation", + "DPTForSemanticSegmentation", + "DPTModel", + "DPTPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_dpt import DPT_PRETRAINED_CONFIG_ARCHIVE_MAP, DPTConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_dpt import DPTFeatureExtractor + from .image_processing_dpt import DPTImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_dpt import ( + DPT_PRETRAINED_MODEL_ARCHIVE_LIST, + DPTForDepthEstimation, + DPTForSemanticSegmentation, + DPTModel, + DPTPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/configuration_dpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/configuration_dpt.py new file mode 100644 index 0000000000000000000000000000000000000000..7f2dd2e807b70241fbf341dba12c6dde15413dbe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/configuration_dpt.py @@ -0,0 +1,231 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" DPT model configuration""" + +import copy + +from ...configuration_utils import PretrainedConfig +from ...utils import logging +from ..bit import BitConfig + + +logger = logging.get_logger(__name__) + +DPT_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "Intel/dpt-large": "https://huggingface.co/Intel/dpt-large/resolve/main/config.json", + # See all DPT models at https://huggingface.co/models?filter=dpt +} + + +class DPTConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`DPTModel`]. It is used to instantiate an DPT + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the DPT + [Intel/dpt-large](https://huggingface.co/Intel/dpt-large) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + image_size (`int`, *optional*, defaults to 384): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 16): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + backbone_out_indices (`List[int]`, *optional*, defaults to `[2, 5, 8, 11]`): + Indices of the intermediate hidden states to use from backbone. + readout_type (`str`, *optional*, defaults to `"project"`): + The readout type to use when processing the readout token (CLS token) of the intermediate hidden states of + the ViT backbone. Can be one of [`"ignore"`, `"add"`, `"project"`]. + + - "ignore" simply ignores the CLS token. + - "add" passes the information from the CLS token to all other tokens by adding the representations. + - "project" passes information to the other tokens by concatenating the readout to all other tokens before + projecting the + representation to the original feature dimension D using a linear layer followed by a GELU non-linearity. + is_hybrid (`bool`, *optional*, defaults to `False`): + Whether to use a hybrid backbone. Useful in the context of loading DPT-Hybrid models. + reassemble_factors (`List[int]`, *optional*, defaults to `[4, 2, 1, 0.5]`): + The up/downsampling factors of the reassemble layers. + neck_hidden_sizes (`List[str]`, *optional*, defaults to [96, 192, 384, 768]): + The hidden sizes to project to for the feature maps of the backbone. + fusion_hidden_size (`int`, *optional*, defaults to 256): + The number of channels before fusion. + head_in_index (`int`, *optional*, defaults to -1): + The index of the features to use in the heads. + use_batch_norm_in_fusion_residual (`bool`, *optional*, defaults to `False`): + Whether to use batch normalization in the pre-activate residual units of the fusion blocks. + use_auxiliary_head (`bool`, *optional*, defaults to `True`): + Whether to use an auxiliary head during training. + auxiliary_loss_weight (`float`, *optional*, defaults to 0.4): + Weight of the cross-entropy loss of the auxiliary head. + semantic_loss_ignore_index (`int`, *optional*, defaults to 255): + The index that is ignored by the loss function of the semantic segmentation model. + semantic_classifier_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the semantic classification head. + backbone_featmap_shape (`List[int]`, *optional*, defaults to `[1, 1024, 24, 24]`): + Used only for the `hybrid` embedding type. The shape of the feature maps of the backbone. + neck_ignore_stages (`List[int]`, *optional*, defaults to `[0, 1]`): + Used only for the `hybrid` embedding type. The stages of the readout layers to ignore. + backbone_config (`Union[Dict[str, Any], PretrainedConfig]`, *optional*): + Used only for the `hybrid` embedding type. The configuration of the backbone in a dictionary. + + Example: + + ```python + >>> from transformers import DPTModel, DPTConfig + + >>> # Initializing a DPT dpt-large style configuration + >>> configuration = DPTConfig() + + >>> # Initializing a model from the dpt-large style configuration + >>> model = DPTModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "dpt" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + image_size=384, + patch_size=16, + num_channels=3, + is_hybrid=False, + qkv_bias=True, + backbone_out_indices=[2, 5, 8, 11], + readout_type="project", + reassemble_factors=[4, 2, 1, 0.5], + neck_hidden_sizes=[96, 192, 384, 768], + fusion_hidden_size=256, + head_in_index=-1, + use_batch_norm_in_fusion_residual=False, + use_auxiliary_head=True, + auxiliary_loss_weight=0.4, + semantic_loss_ignore_index=255, + semantic_classifier_dropout=0.1, + backbone_featmap_shape=[1, 1024, 24, 24], + neck_ignore_stages=[0, 1], + backbone_config=None, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.is_hybrid = is_hybrid + + if self.is_hybrid: + if backbone_config is None: + logger.info("Initializing the config with a `BiT` backbone.") + backbone_config = { + "global_padding": "same", + "layer_type": "bottleneck", + "depths": [3, 4, 9], + "out_features": ["stage1", "stage2", "stage3"], + "embedding_dynamic_padding": True, + } + self.backbone_config = BitConfig(**backbone_config) + elif isinstance(backbone_config, dict): + logger.info("Initializing the config with a `BiT` backbone.") + self.backbone_config = BitConfig(**backbone_config) + elif isinstance(backbone_config, PretrainedConfig): + self.backbone_config = backbone_config + else: + raise ValueError( + f"backbone_config must be a dictionary or a `PretrainedConfig`, got {backbone_config.__class__}." + ) + + self.backbone_featmap_shape = backbone_featmap_shape + self.neck_ignore_stages = neck_ignore_stages + + if readout_type != "project": + raise ValueError("Readout type must be 'project' when using `DPT-hybrid` mode.") + else: + self.backbone_config = None + self.backbone_featmap_shape = None + self.neck_ignore_stages = [] + + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias + self.backbone_out_indices = backbone_out_indices + if readout_type not in ["ignore", "add", "project"]: + raise ValueError("Readout_type must be one of ['ignore', 'add', 'project']") + self.readout_type = readout_type + self.reassemble_factors = reassemble_factors + self.neck_hidden_sizes = neck_hidden_sizes + self.fusion_hidden_size = fusion_hidden_size + self.head_in_index = head_in_index + self.use_batch_norm_in_fusion_residual = use_batch_norm_in_fusion_residual + # auxiliary head attributes (semantic segmentation) + self.use_auxiliary_head = use_auxiliary_head + self.auxiliary_loss_weight = auxiliary_loss_weight + self.semantic_loss_ignore_index = semantic_loss_ignore_index + self.semantic_classifier_dropout = semantic_classifier_dropout + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + + if output["backbone_config"] is not None: + output["backbone_config"] = self.backbone_config.to_dict() + + output["model_type"] = self.__class__.model_type + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/convert_dpt_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/convert_dpt_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..7ef5f7cf119a1b2a70d3afad7be73d329cc04933 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/convert_dpt_to_pytorch.py @@ -0,0 +1,283 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert DPT checkpoints from the original repository. URL: https://github.com/isl-org/DPT""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import cached_download, hf_hub_url +from PIL import Image + +from transformers import DPTConfig, DPTFeatureExtractor, DPTForDepthEstimation, DPTForSemanticSegmentation +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_dpt_config(checkpoint_url): + config = DPTConfig() + + if "large" in checkpoint_url: + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + config.backbone_out_indices = [5, 11, 17, 23] + config.neck_hidden_sizes = [256, 512, 1024, 1024] + expected_shape = (1, 384, 384) + + if "ade" in checkpoint_url: + config.use_batch_norm_in_fusion_residual = True + + config.num_labels = 150 + repo_id = "huggingface/label-files" + filename = "ade20k-id2label.json" + id2label = json.load(open(cached_download(hf_hub_url(repo_id, filename, repo_type="dataset")), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + expected_shape = [1, 150, 480, 480] + + return config, expected_shape + + +def remove_ignore_keys_(state_dict): + ignore_keys = ["pretrained.model.head.weight", "pretrained.model.head.bias"] + for k in ignore_keys: + state_dict.pop(k, None) + + +def rename_key(name): + if ( + "pretrained.model" in name + and "cls_token" not in name + and "pos_embed" not in name + and "patch_embed" not in name + ): + name = name.replace("pretrained.model", "dpt.encoder") + if "pretrained.model" in name: + name = name.replace("pretrained.model", "dpt.embeddings") + if "patch_embed" in name: + name = name.replace("patch_embed", "patch_embeddings") + if "pos_embed" in name: + name = name.replace("pos_embed", "position_embeddings") + if "attn.proj" in name: + name = name.replace("attn.proj", "attention.output.dense") + if "proj" in name and "project" not in name: + name = name.replace("proj", "projection") + if "blocks" in name: + name = name.replace("blocks", "layer") + if "mlp.fc1" in name: + name = name.replace("mlp.fc1", "intermediate.dense") + if "mlp.fc2" in name: + name = name.replace("mlp.fc2", "output.dense") + if "norm1" in name: + name = name.replace("norm1", "layernorm_before") + if "norm2" in name: + name = name.replace("norm2", "layernorm_after") + if "scratch.output_conv" in name: + name = name.replace("scratch.output_conv", "head") + if "scratch" in name: + name = name.replace("scratch", "neck") + if "layer1_rn" in name: + name = name.replace("layer1_rn", "convs.0") + if "layer2_rn" in name: + name = name.replace("layer2_rn", "convs.1") + if "layer3_rn" in name: + name = name.replace("layer3_rn", "convs.2") + if "layer4_rn" in name: + name = name.replace("layer4_rn", "convs.3") + if "refinenet" in name: + layer_idx = int(name[len("neck.refinenet") : len("neck.refinenet") + 1]) + # tricky here: we need to map 4 to 0, 3 to 1, 2 to 2 and 1 to 3 + name = name.replace(f"refinenet{layer_idx}", f"fusion_stage.layers.{abs(layer_idx-4)}") + if "out_conv" in name: + name = name.replace("out_conv", "projection") + if "resConfUnit1" in name: + name = name.replace("resConfUnit1", "residual_layer1") + if "resConfUnit2" in name: + name = name.replace("resConfUnit2", "residual_layer2") + if "conv1" in name: + name = name.replace("conv1", "convolution1") + if "conv2" in name: + name = name.replace("conv2", "convolution2") + # readout blocks + if "pretrained.act_postprocess1.0.project.0" in name: + name = name.replace("pretrained.act_postprocess1.0.project.0", "neck.reassemble_stage.readout_projects.0.0") + if "pretrained.act_postprocess2.0.project.0" in name: + name = name.replace("pretrained.act_postprocess2.0.project.0", "neck.reassemble_stage.readout_projects.1.0") + if "pretrained.act_postprocess3.0.project.0" in name: + name = name.replace("pretrained.act_postprocess3.0.project.0", "neck.reassemble_stage.readout_projects.2.0") + if "pretrained.act_postprocess4.0.project.0" in name: + name = name.replace("pretrained.act_postprocess4.0.project.0", "neck.reassemble_stage.readout_projects.3.0") + # resize blocks + if "pretrained.act_postprocess1.3" in name: + name = name.replace("pretrained.act_postprocess1.3", "neck.reassemble_stage.layers.0.projection") + if "pretrained.act_postprocess1.4" in name: + name = name.replace("pretrained.act_postprocess1.4", "neck.reassemble_stage.layers.0.resize") + if "pretrained.act_postprocess2.3" in name: + name = name.replace("pretrained.act_postprocess2.3", "neck.reassemble_stage.layers.1.projection") + if "pretrained.act_postprocess2.4" in name: + name = name.replace("pretrained.act_postprocess2.4", "neck.reassemble_stage.layers.1.resize") + if "pretrained.act_postprocess3.3" in name: + name = name.replace("pretrained.act_postprocess3.3", "neck.reassemble_stage.layers.2.projection") + if "pretrained.act_postprocess4.3" in name: + name = name.replace("pretrained.act_postprocess4.3", "neck.reassemble_stage.layers.3.projection") + if "pretrained.act_postprocess4.4" in name: + name = name.replace("pretrained.act_postprocess4.4", "neck.reassemble_stage.layers.3.resize") + if "pretrained" in name: + name = name.replace("pretrained", "dpt") + if "bn" in name: + name = name.replace("bn", "batch_norm") + if "head" in name: + name = name.replace("head", "head.head") + if "encoder.norm" in name: + name = name.replace("encoder.norm", "layernorm") + if "auxlayer" in name: + name = name.replace("auxlayer", "auxiliary_head.head") + + return name + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_q_k_v(state_dict, config): + for i in range(config.num_hidden_layers): + # read in weights + bias of input projection layer (in timm, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"dpt.encoder.layer.{i}.attn.qkv.weight") + in_proj_bias = state_dict.pop(f"dpt.encoder.layer.{i}.attn.qkv.bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"dpt.encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[: config.hidden_size, :] + state_dict[f"dpt.encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[: config.hidden_size] + state_dict[f"dpt.encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"dpt.encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[ + config.hidden_size : config.hidden_size * 2 + ] + state_dict[f"dpt.encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[ + -config.hidden_size :, : + ] + state_dict[f"dpt.encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-config.hidden_size :] + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@torch.no_grad() +def convert_dpt_checkpoint(checkpoint_url, pytorch_dump_folder_path, push_to_hub, model_name): + """ + Copy/paste/tweak model's weights to our DPT structure. + """ + + # define DPT configuration based on URL + config, expected_shape = get_dpt_config(checkpoint_url) + # load original state_dict from URL + state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu") + # remove certain keys + remove_ignore_keys_(state_dict) + # rename keys + for key in state_dict.copy().keys(): + val = state_dict.pop(key) + state_dict[rename_key(key)] = val + # read in qkv matrices + read_in_q_k_v(state_dict, config) + + # load HuggingFace model + model = DPTForSemanticSegmentation(config) if "ade" in checkpoint_url else DPTForDepthEstimation(config) + model.load_state_dict(state_dict) + model.eval() + + # Check outputs on an image + size = 480 if "ade" in checkpoint_url else 384 + feature_extractor = DPTFeatureExtractor(size=size) + + image = prepare_img() + encoding = feature_extractor(image, return_tensors="pt") + + # forward pass + outputs = model(**encoding).logits if "ade" in checkpoint_url else model(**encoding).predicted_depth + + # Assert logits + expected_slice = torch.tensor([[6.3199, 6.3629, 6.4148], [6.3850, 6.3615, 6.4166], [6.3519, 6.3176, 6.3575]]) + if "ade" in checkpoint_url: + expected_slice = torch.tensor([[4.0480, 4.2420, 4.4360], [4.3124, 4.5693, 4.8261], [4.5768, 4.8965, 5.2163]]) + assert outputs.shape == torch.Size(expected_shape) + assert ( + torch.allclose(outputs[0, 0, :3, :3], expected_slice, atol=1e-4) + if "ade" in checkpoint_url + else torch.allclose(outputs[0, :3, :3], expected_slice) + ) + + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + print(f"Saving model to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + print("Pushing model to hub...") + model.push_to_hub( + repo_path_or_name=Path(pytorch_dump_folder_path, model_name), + organization="nielsr", + commit_message="Add model", + use_temp_dir=True, + ) + feature_extractor.push_to_hub( + repo_path_or_name=Path(pytorch_dump_folder_path, model_name), + organization="nielsr", + commit_message="Add feature extractor", + use_temp_dir=True, + ) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--checkpoint_url", + default="https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt", + type=str, + help="URL of the original DPT checkpoint you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + type=str, + required=True, + help="Path to the output PyTorch model directory.", + ) + parser.add_argument( + "--push_to_hub", + action="store_true", + ) + parser.add_argument( + "--model_name", + default="dpt-large", + type=str, + help="Name of the model, in case you're pushing to the hub.", + ) + + args = parser.parse_args() + convert_dpt_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub, args.model_name) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/feature_extraction_dpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/feature_extraction_dpt.py new file mode 100644 index 0000000000000000000000000000000000000000..d375d8229f5ee9b3278af363c40043815ff0cf29 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/feature_extraction_dpt.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for DPT.""" + +import warnings + +from ...utils import logging +from .image_processing_dpt import DPTImageProcessor + + +logger = logging.get_logger(__name__) + + +class DPTFeatureExtractor(DPTImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class DPTFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please" + " use DPTImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/image_processing_dpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/image_processing_dpt.py new file mode 100644 index 0000000000000000000000000000000000000000..4f5dbc44507e83f2f2751b9c4d27debe4051f3fa --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/dpt/image_processing_dpt.py @@ -0,0 +1,383 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for DPT.""" + +import math +from typing import Dict, Iterable, List, Optional, Tuple, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import normalize, rescale, resize, to_channel_dimension_format +from ...image_utils import ( + IMAGENET_STANDARD_MEAN, + IMAGENET_STANDARD_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + get_image_size, + is_torch_available, + is_torch_tensor, + make_list_of_images, + to_numpy_array, + valid_images, +) +from ...utils import TensorType, is_vision_available, logging + + +if is_torch_available(): + import torch + +if is_vision_available(): + import PIL + + +logger = logging.get_logger(__name__) + + +def get_resize_output_image_size( + input_image: np.ndarray, output_size: Union[int, Iterable[int]], keep_aspect_ratio: bool, multiple: int +) -> Tuple[int, int]: + def constraint_to_multiple_of(val, multiple, min_val=0, max_val=None): + x = round(val / multiple) * multiple + + if max_val is not None and x > max_val: + x = math.floor(val / multiple) * multiple + + if x < min_val: + x = math.ceil(val / multiple) * multiple + + return x + + output_size = (output_size, output_size) if isinstance(output_size, int) else output_size + + input_height, input_width = get_image_size(input_image) + output_height, output_width = output_size + + # determine new height and width + scale_height = output_height / input_height + scale_width = output_width / input_width + + if keep_aspect_ratio: + # scale as little as possible + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + + new_height = constraint_to_multiple_of(scale_height * input_height, multiple=multiple) + new_width = constraint_to_multiple_of(scale_width * input_width, multiple=multiple) + + return (new_height, new_width) + + +class DPTImageProcessor(BaseImageProcessor): + r""" + Constructs a DPT image processor. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Whether to resize the image's (height, width) dimensions. Can be overidden by `do_resize` in `preprocess`. + size (`Dict[str, int]` *optional*, defaults to `{"height": 384, "width": 384}`): + Size of the image after resizing. Can be overidden by `size` in `preprocess`. + keep_aspect_ratio (`bool`, *optional*, defaults to `False`): + If `True`, the image is resized to the largest possible size such that the aspect ratio is preserved. Can + be overidden by `keep_aspect_ratio` in `preprocess`. + ensure_multiple_of (`int`, *optional*, defaults to `1`): + If `do_resize` is `True`, the image is resized to a size that is a multiple of this value. Can be overidden + by `ensure_multiple_of` in `preprocess`. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Defines the resampling filter to use if resizing the image. Can be overidden by `resample` in `preprocess`. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. Can be overidden by `do_rescale` in + `preprocess`. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overidden by `rescale_factor` in `preprocess`. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess` + method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`): + Mean to use if normalizing the image. This is a float or list of floats the length of the number of + channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`): + Standard deviation to use if normalizing the image. This is a float or list of floats the length of the + number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values"] + + def __init__( + self, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + keep_aspect_ratio: bool = False, + ensure_multiple_of: int = 1, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + **kwargs, + ) -> None: + super().__init__(**kwargs) + size = size if size is not None else {"height": 384, "width": 384} + size = get_size_dict(size) + self.do_resize = do_resize + self.size = size + self.keep_aspect_ratio = keep_aspect_ratio + self.ensure_multiple_of = ensure_multiple_of + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_STANDARD_STD + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + keep_aspect_ratio: bool = False, + ensure_multiple_of: int = 1, + resample: PILImageResampling = PILImageResampling.BICUBIC, + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize an image to target size `(size["height"], size["width"])`. If `keep_aspect_ratio` is `True`, the image + is resized to the largest possible size such that the aspect ratio is preserved. If `ensure_multiple_of` is + set, the image is resized to a size that is a multiple of this value. + + Args: + image (`np.ndarray`): + Image to resize. + size (`Dict[str, int]`): + Target size of the output image. + keep_aspect_ratio (`bool`, *optional*, defaults to `False`): + If `True`, the image is resized to the largest possible size such that the aspect ratio is preserved. + ensure_multiple_of (`int`, *optional*, defaults to `1`): + The image is resized to a size that is a multiple of this value. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): + Defines the resampling filter to use if resizing the image. Otherwise, the image is resized to size + specified in `size`. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use when resiizing the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size) + if "height" not in size or "width" not in size: + raise ValueError(f"The size dictionary must contain the keys 'height' and 'width'. Got {size.keys()}") + output_size = get_resize_output_image_size( + image, + output_size=(size["height"], size["width"]), + keep_aspect_ratio=keep_aspect_ratio, + multiple=ensure_multiple_of, + ) + return resize(image, size=output_size, resample=resample, data_format=data_format, **kwargs) + + def rescale( + self, + image: np.ndarray, + scale: Union[int, float], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ): + """ + Rescale an image by a scale factor. image = image * scale. + + Args: + image (`np.ndarray`): + Image to rescale. + scale (`int` or `float`): + Scale to apply to the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return rescale(image, scale=scale, data_format=data_format, **kwargs) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, List[float]], + std: Union[float, List[float]], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Normalize an image. image = (image - image_mean) / image_std. + + Args: + image (`np.ndarray`): + Image to normalize. + image_mean (`float` or `List[float]`): + Image mean. + image_std (`float` or `List[float]`): + Image standard deviation. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return normalize(image, mean=mean, std=std, data_format=data_format, **kwargs) + + def preprocess( + self, + images: ImageInput, + do_resize: bool = None, + size: int = None, + keep_aspect_ratio: bool = None, + ensure_multiple_of: int = None, + resample: PILImageResampling = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: ChannelDimension = ChannelDimension.FIRST, + **kwargs, + ) -> PIL.Image.Image: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Size of the image after reszing. If `keep_aspect_ratio` is `True`, the image is resized to the largest + possible size such that the aspect ratio is preserved. If `ensure_multiple_of` is set, the image is + resized to a size that is a multiple of this value. + keep_aspect_ratio (`bool`, *optional*, defaults to `self.keep_aspect_ratio`): + Whether to keep the aspect ratio of the image. If False, the image will be resized to (size, size). If + True, the image will be resized to keep the aspect ratio and the size will be the maximum possible. + ensure_multiple_of (`int`, *optional*, defaults to `self.ensure_multiple_of`): + Ensure that the image size is a multiple of this value. + resample (`int`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`, Only + has an effect if `do_resize` is set to `True`. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image values between [0 - 1]. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `ChannelDimension.LAST`: image in (height, width, num_channels) format. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + size = size if size is not None else self.size + size = get_size_dict(size) + keep_aspect_ratio = keep_aspect_ratio if keep_aspect_ratio is not None else self.keep_aspect_ratio + ensure_multiple_of = ensure_multiple_of if ensure_multiple_of is not None else self.ensure_multiple_of + resample = resample if resample is not None else self.resample + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + + images = make_list_of_images(images) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + if do_resize and size is None or resample is None: + raise ValueError("Size and resample must be specified if do_resize is True.") + + if do_rescale and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_resize: + images = [self.resize(image=image, size=size, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image=image, scale=rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image=image, mean=image_mean, std=image_std) for image in images] + + images = [to_channel_dimension_format(image, data_format) for image in images] + + data = {"pixel_values": images} + return BatchFeature(data=data, tensor_type=return_tensors) + + def post_process_semantic_segmentation(self, outputs, target_sizes: List[Tuple] = None): + """ + Converts the output of [`DPTForSemanticSegmentation`] into semantic segmentation maps. Only supports PyTorch. + + Args: + outputs ([`DPTForSemanticSegmentation`]): + Raw outputs of the model. + target_sizes (`List[Tuple]` of length `batch_size`, *optional*): + List of tuples corresponding to the requested final size (height, width) of each prediction. If unset, + predictions will not be resized. + + Returns: + semantic_segmentation: `List[torch.Tensor]` of length `batch_size`, where each item is a semantic + segmentation map of shape (height, width) corresponding to the target_sizes entry (if `target_sizes` is + specified). Each entry of each `torch.Tensor` correspond to a semantic class id. + """ + # TODO: add support for other frameworks + logits = outputs.logits + + # Resize logits and compute semantic segmentation maps + if target_sizes is not None: + if len(logits) != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + if is_torch_tensor(target_sizes): + target_sizes = target_sizes.numpy() + + semantic_segmentation = [] + + for idx in range(len(logits)): + resized_logits = torch.nn.functional.interpolate( + logits[idx].unsqueeze(dim=0), size=target_sizes[idx], mode="bilinear", align_corners=False + ) + semantic_map = resized_logits[0].argmax(dim=0) + semantic_segmentation.append(semantic_map) + else: + semantic_segmentation = logits.argmax(dim=1) + semantic_segmentation = [semantic_segmentation[i] for i in range(semantic_segmentation.shape[0])] + + return semantic_segmentation diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/configuration_efficientformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/configuration_efficientformer.py new file mode 100644 index 0000000000000000000000000000000000000000..5f30664ff325a05f18e9e1aea7e1cfd5e8a9e6ba --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/configuration_efficientformer.py @@ -0,0 +1,167 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" EfficientFormer model configuration""" + +from typing import List + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +EFFICIENTFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "snap-research/efficientformer-l1-300": ( + "https://huggingface.co/snap-research/efficientformer-l1-300/resolve/main/config.json" + ), +} + + +class EfficientFormerConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of an [`EfficientFormerModel`]. It is used to + instantiate an EfficientFormer model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the EfficientFormer + [snap-research/efficientformer-l1](https://huggingface.co/snap-research/efficientformer-l1) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + depths (`List(int)`, *optional*, defaults to `[3, 2, 6, 4]`) + Depth of each stage. + hidden_sizes (`List(int)`, *optional*, defaults to `[48, 96, 224, 448]`) + Dimensionality of each stage. + downsamples (`List(bool)`, *optional*, defaults to `[True, True, True, True]`) + Whether or not to downsample inputs between two stages. + dim (`int`, *optional*, defaults to 448): + Number of channels in Meta3D layers + key_dim (`int`, *optional*, defaults to 32): + The size of the key in meta3D block. + attention_ratio (`int`, *optional*, defaults to 4): + Ratio of the dimension of the query and value to the dimension of the key in MSHA block + resolution (`int`, *optional*, defaults to 5) + Size of each patch + num_hidden_layers (`int`, *optional*, defaults to 5): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the 3D MetaBlock. + mlp_expansion_ratio (`int`, *optional*, defaults to 4): + Ratio of size of the hidden dimensionality of an MLP to the dimensionality of its input. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings and encoder. + patch_size (`int`, *optional*, defaults to 16): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + pool_size (`int`, *optional*, defaults to 3): + Kernel size of pooling layers. + downsample_patch_size (`int`, *optional*, defaults to 3): + The size of patches in downsampling layers. + downsample_stride (`int`, *optional*, defaults to 2): + The stride of convolution kernels in downsampling layers. + downsample_pad (`int`, *optional*, defaults to 1): + Padding in downsampling layers. + drop_path_rate (`int`, *optional*, defaults to 0): + Rate at which to increase dropout probability in DropPath. + num_meta3d_blocks (`int`, *optional*, defaults to 1): + The number of 3D MetaBlocks in the last stage. + distillation (`bool`, *optional*, defaults to `True`): + Whether to add a distillation head. + use_layer_scale (`bool`, *optional*, defaults to `True`): + Whether to scale outputs from token mixers. + layer_scale_init_value (`float`, *optional*, defaults to 1e-5): + Factor by which outputs from token mixers are scaled. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + + Example: + + ```python + >>> from transformers import EfficientFormerConfig, EfficientFormerModel + + >>> # Initializing a EfficientFormer efficientformer-l1 style configuration + >>> configuration = EfficientFormerConfig() + + >>> # Initializing a EfficientFormerModel (with random weights) from the efficientformer-l3 style configuration + >>> model = EfficientFormerModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "efficientformer" + + def __init__( + self, + depths: List[int] = [3, 2, 6, 4], + hidden_sizes: List[int] = [48, 96, 224, 448], + downsamples: List[bool] = [True, True, True, True], + dim: int = 448, + key_dim: int = 32, + attention_ratio: int = 4, + resolution: int = 7, + num_hidden_layers: int = 5, + num_attention_heads: int = 8, + mlp_expansion_ratio: int = 4, + hidden_dropout_prob: float = 0.0, + patch_size: int = 16, + num_channels: int = 3, + pool_size: int = 3, + downsample_patch_size: int = 3, + downsample_stride: int = 2, + downsample_pad: int = 1, + drop_path_rate: float = 0.0, + num_meta3d_blocks: int = 1, + distillation: bool = True, + use_layer_scale: bool = True, + layer_scale_init_value: float = 1e-5, + hidden_act: str = "gelu", + initializer_range: float = 0.02, + layer_norm_eps: float = 1e-12, + **kwargs, + ) -> None: + super().__init__(**kwargs) + + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.hidden_sizes = hidden_sizes + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.patch_size = patch_size + self.num_channels = num_channels + self.depths = depths + self.mlp_expansion_ratio = mlp_expansion_ratio + self.downsamples = downsamples + self.dim = dim + self.key_dim = key_dim + self.attention_ratio = attention_ratio + self.resolution = resolution + self.pool_size = pool_size + self.downsample_patch_size = downsample_patch_size + self.downsample_stride = downsample_stride + self.downsample_pad = downsample_pad + self.drop_path_rate = drop_path_rate + self.num_meta3d_blocks = num_meta3d_blocks + self.distillation = distillation + self.use_layer_scale = use_layer_scale + self.layer_scale_init_value = layer_scale_init_value diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/image_processing_efficientformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/image_processing_efficientformer.py new file mode 100644 index 0000000000000000000000000000000000000000..81e3d798d11990bb8b186472de6a7acb857277ce --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/image_processing_efficientformer.py @@ -0,0 +1,337 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for EfficientFormer.""" + +from typing import Dict, List, Optional, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import ( + center_crop, + get_resize_output_image_size, + normalize, + rescale, + resize, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_DEFAULT_MEAN, + IMAGENET_DEFAULT_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + is_batched, + to_numpy_array, + valid_images, +) +from ...utils import TensorType, logging + + +logger = logging.get_logger(__name__) + + +class EfficientFormerImageProcessor(BaseImageProcessor): + r""" + Constructs a EfficientFormer image processor. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Whether to resize the image's (height, width) dimensions to the specified `(size["height"], + size["width"])`. Can be overridden by the `do_resize` parameter in the `preprocess` method. + size (`dict`, *optional*, defaults to `{"height": 224, "width": 224}`): + Size of the output image after resizing. Can be overridden by the `size` parameter in the `preprocess` + method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. Can be overridden by the `resample` parameter in the + `preprocess` method. + do_center_crop (`bool`, *optional*, defaults to `True`): + Whether to center crop the image to the specified `crop_size`. Can be overridden by `do_center_crop` in the + `preprocess` method. + crop_size (`Dict[str, int]` *optional*, defaults to 224): + Size of the output image after applying `center_crop`. Can be overridden by `crop_size` in the `preprocess` + method. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the `do_rescale` + parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize: + Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess` + method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`): + Mean to use if normalizing the image. This is a float or list of floats the length of the number of + channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`): + Standard deviation to use if normalizing the image. This is a float or list of floats the length of the + number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values"] + + def __init__( + self, + do_resize: bool = True, + size: Optional[Dict[str, int]] = None, + resample: PILImageResampling = PILImageResampling.BICUBIC, + do_center_crop: bool = True, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + crop_size: Dict[str, int] = None, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + **kwargs, + ) -> None: + super().__init__(**kwargs) + size = size if size is not None else {"height": 224, "width": 224} + size = get_size_dict(size) + crop_size = crop_size if crop_size is not None else {"height": 224, "width": 224} + crop_size = get_size_dict(crop_size, default_to_square=True, param_name="crop_size") + + self.do_resize = do_resize + self.do_rescale = do_rescale + self.do_normalize = do_normalize + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.size = size + self.resample = resample + self.rescale_factor = rescale_factor + self.image_mean = image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_DEFAULT_STD + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BILINEAR, + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize an image to `(size["height"], size["width"])`. + + Args: + image (`np.ndarray`): + Image to resize. + size (`Dict[str, int]`): + Dictionary in the format `{"height": int, "width": int}` specifying the size of the output image. + resample: + `PILImageResampling` filter to use when resizing the image e.g. `PILImageResampling.BILINEAR`. + data_format (`ChannelDimension` or `str`, *optional*): + The channel dimension format for the output image. If unset, the channel dimension format of the input + image is used. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + + Returns: + `np.ndarray`: The resized image. + """ + size = get_size_dict(size) + + if "shortest_edge" in size: + size = get_resize_output_image_size(image, size=size["shortest_edge"], default_to_square=False) + # size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"]) + elif "height" in size and "width" in size: + size = (size["height"], size["width"]) + else: + raise ValueError(f"Size must contain 'height' and 'width' keys or 'shortest_edge' key. Got {size.keys()}") + return resize(image, size=size, resample=resample, data_format=data_format, **kwargs) + + def center_crop( + self, + image: np.ndarray, + size: Dict[str, int], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Center crop an image. If the image is too small to be cropped to the size given, it will be padded (so the + returned result will always be of size `size`). + + Args: + image (`np.ndarray`): + Image to center crop. + size (`Dict[str, int]`): + Size of the output image in the form of a dictionary with keys `height` and `width`. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size) + if "height" not in size or "width" not in size: + raise ValueError(f"The `size` parameter must contain the keys (height, width). Got {size.keys()}") + return center_crop(image, size=(size["height"], size["width"]), data_format=data_format, **kwargs) + + def rescale( + self, image: np.ndarray, scale: float, data_format: Optional[Union[str, ChannelDimension]] = None, **kwargs + ) -> np.ndarray: + """ + Rescale an image by a scale factor. image = image * scale. + + Args: + image (`np.ndarray`): + Image to rescale. + scale (`float`): + The scaling factor to rescale pixel values by. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format for the output image. If unset, the channel dimension format of the input + image is used. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + + Returns: + `np.ndarray`: The rescaled image. + """ + return rescale(image, scale=scale, data_format=data_format, **kwargs) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, List[float]], + std: Union[float, List[float]], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Normalize an image. image = (image - image_mean) / image_std. + + Args: + image (`np.ndarray`): + Image to normalize. + mean (`float` or `List[float]`): + Image mean to use for normalization. + std (`float` or `List[float]`): + Image standard deviation to use for normalization. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format for the output image. If unset, the channel dimension format of the input + image is used. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + + Returns: + `np.ndarray`: The normalized image. + """ + return normalize(image, mean=mean, std=std, data_format=data_format, **kwargs) + + def preprocess( + self, + images: ImageInput, + do_resize: Optional[bool] = None, + size: Dict[str, int] = None, + resample: PILImageResampling = None, + do_center_crop: bool = None, + crop_size: int = None, + do_rescale: Optional[bool] = None, + rescale_factor: Optional[float] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> BatchFeature: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Dictionary in the format `{"height": h, "width": w}` specifying the size of the output image after + resizing. + resample (`PILImageResampling` filter, *optional*, defaults to `self.resample`): + `PILImageResampling` filter to use if resizing the image e.g. `PILImageResampling.BILINEAR`. Only has + an effect if `do_resize` is set to `True`. + do_center_crop (`bool`, *optional*, defaults to `self.do_center_crop`): + Whether to center crop the image. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image values between [0 - 1]. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + crop_size (`Dict[str, int]`, *optional*, defaults to `self.crop_size`): + Size of the center crop. Only has an effect if `do_center_crop` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean to use if `do_normalize` is set to `True`. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation to use if `do_normalize` is set to `True`. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - Unset: Use the channel dimension format of the input image. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + do_center_crop = do_center_crop if do_center_crop is not None else self.do_center_crop + crop_size = crop_size if crop_size is not None else self.crop_size + crop_size = get_size_dict(crop_size, param_name="crop_size", default_to_square=True) + resample = resample if resample is not None else self.resample + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + + size = size if size is not None else self.size + size_dict = get_size_dict(size) + + if not is_batched(images): + images = [images] + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + if do_resize and size is None: + raise ValueError("Size must be specified if do_resize is True.") + + if do_center_crop and crop_size is None: + raise ValueError("Crop size must be specified if do_center_crop is True.") + + if do_rescale and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_resize: + images = [self.resize(image=image, size=size_dict, resample=resample) for image in images] + + if do_center_crop: + images = [self.center_crop(image=image, size=crop_size) for image in images] + + if do_rescale: + images = [self.rescale(image=image, scale=rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image=image, mean=image_mean, std=image_std) for image in images] + + images = [to_channel_dimension_format(image, data_format) for image in images] + + data = {"pixel_values": images} + return BatchFeature(data=data, tensor_type=return_tensors) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/modeling_efficientformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/modeling_efficientformer.py new file mode 100644 index 0000000000000000000000000000000000000000..b6264e60c8b8990e6a8f8dd5faabaec6eb6354f3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientformer/modeling_efficientformer.py @@ -0,0 +1,795 @@ +# coding=utf-8 +# Copyright 2022 Snapchat Research and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch EfficientFormer model.""" + +import itertools +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, +) +from .configuration_efficientformer import EfficientFormerConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "EfficientFormerConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "snap-research/efficientformer-l1-300" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "snap-research/efficientformer-l1-300" +_IMAGE_CLASS_EXPECTED_OUTPUT = "Egyptian cat" + + +EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "snap-research/efficientformer-l1-300", + # See all EfficientFormer models at https://huggingface.co/models?filter=efficientformer +] + + +class EfficientFormerPatchEmbeddings(nn.Module): + """ + This class performs downsampling between two stages. For the input tensor with the shape [batch_size, num_channels, + height, width] it produces output tensor with the shape [batch_size, num_channels, height/stride, width/stride] + """ + + def __init__(self, config: EfficientFormerConfig, num_channels: int, embed_dim: int, apply_norm: bool = True): + super().__init__() + self.num_channels = num_channels + + self.projection = nn.Conv2d( + num_channels, + embed_dim, + kernel_size=config.downsample_patch_size, + stride=config.downsample_stride, + padding=config.downsample_pad, + ) + self.norm = nn.BatchNorm2d(embed_dim) if apply_norm else nn.Identity() + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + + embeddings = self.projection(pixel_values) + embeddings = self.norm(embeddings) + + return embeddings + + +class EfficientFormerSelfAttention(nn.Module): + def __init__(self, dim: int, key_dim: int, num_heads: int, attention_ratio: int, resolution: int): + super().__init__() + + self.num_heads = num_heads + self.key_dim = key_dim + self.attention_ratio = attention_ratio + self.scale = key_dim**-0.5 + self.total_key_dim = key_dim * num_heads + self.expanded_key_dim = int(attention_ratio * key_dim) + self.total_expanded_key_dim = int(self.expanded_key_dim * num_heads) + hidden_size = self.total_expanded_key_dim + self.total_key_dim * 2 + self.qkv = nn.Linear(dim, hidden_size) + self.projection = nn.Linear(self.total_expanded_key_dim, dim) + points = list(itertools.product(range(resolution), range(resolution))) + num_points = len(points) + attention_offsets = {} + idxs = [] + for point_1 in points: + for point_2 in points: + offset = (abs(point_1[0] - point_2[0]), abs(point_1[1] - point_2[1])) + if offset not in attention_offsets: + attention_offsets[offset] = len(attention_offsets) + idxs.append(attention_offsets[offset]) + self.attention_biases = torch.nn.Parameter(torch.zeros(num_heads, len(attention_offsets))) + self.register_buffer("attention_bias_idxs", torch.LongTensor(idxs).view(num_points, num_points)) + + @torch.no_grad() + def train(self, mode=True): + super().train(mode) + if mode and hasattr(self, "ab"): + del self.ab + else: + self.ab = self.attention_biases[:, self.attention_bias_idxs] + + def forward(self, hidden_states: torch.Tensor, output_attentions: bool = False) -> Tuple[torch.Tensor]: + batch_size, sequence_length, num_channels = hidden_states.shape + qkv = self.qkv(hidden_states) + query_layer, key_layer, value_layer = qkv.reshape(batch_size, sequence_length, self.num_heads, -1).split( + [self.key_dim, self.key_dim, self.expanded_key_dim], dim=3 + ) + query_layer = query_layer.permute(0, 2, 1, 3) + key_layer = key_layer.permute(0, 2, 1, 3) + value_layer = value_layer.permute(0, 2, 1, 3) + + # set `model.to(torch_device)` won't change `self.ab.device`, if there is no follow-up `train` or `eval` call. + # Let's do it manually here, so users won't have to do this everytime. + if not self.training: + self.ab = self.ab.to(self.attention_biases.device) + attention_probs = (torch.matmul(query_layer, key_layer.transpose(-2, -1))) * self.scale + ( + self.attention_biases[:, self.attention_bias_idxs] if self.training else self.ab + ) + + attention_probs = attention_probs.softmax(dim=-1) + + context_layer = torch.matmul(attention_probs, value_layer).transpose(1, 2) + context_layer = context_layer.reshape(batch_size, sequence_length, self.total_expanded_key_dim) + context_layer = self.projection(context_layer) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +class EfficientFormerConvStem(nn.Module): + def __init__(self, config: EfficientFormerConfig, out_channels: int): + super().__init__() + + self.convolution1 = nn.Conv2d(config.num_channels, out_channels // 2, kernel_size=3, stride=2, padding=1) + self.batchnorm_before = nn.BatchNorm2d(out_channels // 2) + + self.convolution2 = nn.Conv2d(out_channels // 2, out_channels, kernel_size=3, stride=2, padding=1) + self.batchnorm_after = nn.BatchNorm2d(out_channels) + + self.activation = nn.ReLU() + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + features = self.batchnorm_before(self.convolution1(pixel_values)) + features = self.activation(features) + features = self.batchnorm_after(self.convolution2(features)) + features = self.activation(features) + + return features + + +class EfficientFormerPooling(nn.Module): + def __init__(self, pool_size: int): + super().__init__() + self.pool = nn.AvgPool2d(pool_size, stride=1, padding=pool_size // 2, count_include_pad=False) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + output = self.pool(hidden_states) - hidden_states + return output + + +class EfficientFormerDenseMlp(nn.Module): + def __init__( + self, + config: EfficientFormerConfig, + in_features: int, + hidden_features: Optional[int] = None, + out_features: Optional[int] = None, + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + + self.linear_in = nn.Linear(in_features, hidden_features) + self.activation = ACT2FN[config.hidden_act] + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.linear_out = nn.Linear(hidden_features, out_features) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.linear_in(hidden_states) + hidden_states = self.activation(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.linear_out(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +class EfficientFormerConvMlp(nn.Module): + def __init__( + self, + config: EfficientFormerConfig, + in_features: int, + hidden_features: Optional[int] = None, + out_features: Optional[int] = None, + drop: float = 0.0, + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + + self.convolution1 = nn.Conv2d(in_features, hidden_features, 1) + self.actvation = ACT2FN[config.hidden_act] + self.convolution2 = nn.Conv2d(hidden_features, out_features, 1) + self.dropout = nn.Dropout(drop) + + self.batchnorm_before = nn.BatchNorm2d(hidden_features) + self.batchnorm_after = nn.BatchNorm2d(out_features) + + def forward(self, hidden_state: torch.Tensor) -> torch.Tensor: + hidden_state = self.convolution1(hidden_state) + hidden_state = self.batchnorm_before(hidden_state) + + hidden_state = self.actvation(hidden_state) + hidden_state = self.dropout(hidden_state) + hidden_state = self.convolution2(hidden_state) + + hidden_state = self.batchnorm_after(hidden_state) + + hidden_state = self.dropout(hidden_state) + return hidden_state + + +# Copied from transformers.models.convnext.modeling_convnext.drop_path +def drop_path(input, drop_prob: float = 0.0, training: bool = False): + """ + Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, + however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the + layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the + argument. + """ + if drop_prob == 0.0 or not training: + return input + keep_prob = 1 - drop_prob + shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device) + random_tensor.floor_() # binarize + output = input.div(keep_prob) * random_tensor + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitDropPath with Beit->Bit +class EfficientFormerDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob: Optional[float] = None) -> None: + super().__init__() + self.drop_prob = drop_prob + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + return drop_path(hidden_states, self.drop_prob, self.training) + + def extra_repr(self) -> str: + return "p={}".format(self.drop_prob) + + +class EfficientFormerFlat(nn.Module): + def __init__(self): + super().__init__() + + def forward(self, hidden_states: torch.Tensor) -> Tuple[torch.Tensor]: + hidden_states = hidden_states.flatten(2).transpose(1, 2) + return hidden_states + + +class EfficientFormerMeta3D(nn.Module): + def __init__(self, config: EfficientFormerConfig, dim: int, drop_path: float = 0.0): + super().__init__() + + self.token_mixer = EfficientFormerSelfAttention( + dim=config.dim, + key_dim=config.key_dim, + num_heads=config.num_attention_heads, + attention_ratio=config.attention_ratio, + resolution=config.resolution, + ) + self.layernorm1 = nn.LayerNorm(dim) + self.layernorm2 = nn.LayerNorm(dim) + mlp_hidden_dim = int(dim * config.mlp_expansion_ratio) + self.mlp = EfficientFormerDenseMlp(config, in_features=dim, hidden_features=mlp_hidden_dim) + + self.drop_path = EfficientFormerDropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.use_layer_scale = config.use_layer_scale + if config.use_layer_scale: + self.layer_scale_1 = nn.Parameter(config.layer_scale_init_value * torch.ones((dim)), requires_grad=True) + self.layer_scale_2 = nn.Parameter(config.layer_scale_init_value * torch.ones((dim)), requires_grad=True) + + def forward(self, hidden_states: torch.Tensor, output_attentions: bool = False) -> Tuple[torch.Tensor]: + self_attention_outputs = self.token_mixer(self.layernorm1(hidden_states), output_attentions) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + if self.use_layer_scale: + layer_output = hidden_states + self.drop_path( + self.layer_scale_1.unsqueeze(0).unsqueeze(0) * attention_output + ) + layer_output = layer_output + self.drop_path( + self.layer_scale_2.unsqueeze(0).unsqueeze(0) * self.mlp(self.layernorm2(layer_output)) + ) + else: + layer_output = hidden_states + self.drop_path(attention_output) + layer_output = layer_output + self.drop_path(self.mlp(self.layernorm2(layer_output))) + + outputs = (layer_output,) + outputs + + return outputs + + +class EfficientFormerMeta3DLayers(nn.Module): + def __init__(self, config: EfficientFormerConfig): + super().__init__() + drop_paths = [ + config.drop_path_rate * (block_idx + sum(config.depths[:-1])) + for block_idx in range(config.num_meta3d_blocks) + ] + self.blocks = nn.ModuleList( + [EfficientFormerMeta3D(config, config.hidden_sizes[-1], drop_path=drop_path) for drop_path in drop_paths] + ) + + def forward(self, hidden_states: torch.Tensor, output_attentions: bool = False) -> Tuple[torch.Tensor]: + all_attention_outputs = () if output_attentions else None + for layer_module in self.blocks: + if isinstance(hidden_states, tuple): + hidden_states = hidden_states[0] + hidden_states = layer_module(hidden_states, output_attentions) + if output_attentions: + all_attention_outputs = all_attention_outputs + (hidden_states[1],) + if output_attentions: + outputs = (hidden_states[0],) + all_attention_outputs + return outputs + return hidden_states + + +class EfficientFormerMeta4D(nn.Module): + def __init__(self, config: EfficientFormerConfig, dim: int, drop_path: float = 0.0): + super().__init__() + pool_size = config.pool_size if config.pool_size is not None else 3 + self.token_mixer = EfficientFormerPooling(pool_size=pool_size) + mlp_hidden_dim = int(dim * config.mlp_expansion_ratio) + self.mlp = EfficientFormerConvMlp( + config, in_features=dim, hidden_features=mlp_hidden_dim, drop=config.hidden_dropout_prob + ) + + self.drop_path = EfficientFormerDropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.use_layer_scale = config.use_layer_scale + if config.use_layer_scale: + self.layer_scale_1 = nn.Parameter(config.layer_scale_init_value * torch.ones((dim)), requires_grad=True) + self.layer_scale_2 = nn.Parameter(config.layer_scale_init_value * torch.ones((dim)), requires_grad=True) + + def forward(self, hidden_states: torch.Tensor) -> Tuple[torch.Tensor]: + outputs = self.token_mixer(hidden_states) + + if self.use_layer_scale: + layer_output = hidden_states + self.drop_path(self.layer_scale_1.unsqueeze(-1).unsqueeze(-1) * outputs) + layer_output = layer_output + self.drop_path( + self.layer_scale_2.unsqueeze(-1).unsqueeze(-1) * self.mlp(layer_output) + ) + else: + layer_output = hidden_states + self.drop_path(outputs) + layer_output = layer_output + self.drop_path(self.mlp(layer_output)) + + return layer_output + + +class EfficientFormerMeta4DLayers(nn.Module): + def __init__(self, config: EfficientFormerConfig, stage_idx: int): + super().__init__() + num_layers = ( + config.depths[stage_idx] if stage_idx != -1 else config.depths[stage_idx] - config.num_meta3d_blocks + ) + drop_paths = [ + config.drop_path_rate * (block_idx + sum(config.depths[:stage_idx])) for block_idx in range(num_layers) + ] + self.blocks = nn.ModuleList( + [ + EfficientFormerMeta4D(config, config.hidden_sizes[stage_idx], drop_path=drop_path) + for drop_path in drop_paths + ] + ) + + def forward(self, hidden_states: torch.Tensor) -> Tuple[torch.Tensor]: + for layer_module in self.blocks: + hidden_states = layer_module(hidden_states) + return hidden_states + + +class EfficientFormerIntermediateStage(nn.Module): + def __init__(self, config: EfficientFormerConfig, index: int): + super().__init__() + self.meta4D_layers = EfficientFormerMeta4DLayers(config, index) + + def forward(self, hidden_states: torch.Tensor) -> Tuple[torch.Tensor]: + hidden_states = self.meta4D_layers(hidden_states) + return hidden_states + + +class EfficientFormerLastStage(nn.Module): + def __init__(self, config: EfficientFormerConfig): + super().__init__() + self.meta4D_layers = EfficientFormerMeta4DLayers(config, -1) + self.flat = EfficientFormerFlat() + self.meta3D_layers = EfficientFormerMeta3DLayers(config) + + def forward(self, hidden_states: torch.Tensor, output_attentions: bool = False) -> Tuple[torch.Tensor]: + hidden_states = self.meta4D_layers(hidden_states) + hidden_states = self.flat(hidden_states) + hidden_states = self.meta3D_layers(hidden_states, output_attentions) + + return hidden_states + + +class EfficientFormerEncoder(nn.Module): + def __init__(self, config: EfficientFormerConfig): + super().__init__() + self.config = config + num_intermediate_stages = len(config.depths) - 1 + downsamples = [ + config.downsamples[i] or config.hidden_sizes[i] != config.hidden_sizes[i + 1] + for i in range(num_intermediate_stages) + ] + intermediate_stages = [] + for i in range(num_intermediate_stages): + intermediate_stages.append(EfficientFormerIntermediateStage(config, i)) + if downsamples[i]: + intermediate_stages.append( + EfficientFormerPatchEmbeddings(config, config.hidden_sizes[i], config.hidden_sizes[i + 1]) + ) + + self.intermediate_stages = nn.ModuleList(intermediate_stages) + self.last_stage = EfficientFormerLastStage(config) + + def forward( + self, + hidden_states: torch.Tensor, + output_hidden_states: bool = False, + output_attentions: bool = False, + return_dict: bool = True, + ) -> BaseModelOutput: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + for layer_module in self.intermediate_stages: + hidden_states = layer_module(hidden_states) + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_output = self.last_stage(hidden_states, output_attentions=output_attentions) + if output_attentions: + all_self_attentions = all_self_attentions + layer_output[1:] + + if output_hidden_states: + all_hidden_states = all_hidden_states + (layer_output[0],) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + + return BaseModelOutput( + last_hidden_state=layer_output[0], + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class EfficientFormerPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = EfficientFormerConfig + base_model_prefix = "efficientformer" + main_input_name = "pixel_values" + supports_gradient_checkpointing = False + + def _init_weights(self, module: nn.Module): + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +EFFICIENTFORMER_START_DOCSTRING = r""" + This model is a PyTorch [nn.Module](https://pytorch.org/docs/stable/nn.html#nn.Module) subclass. Use it as a + regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and behavior. + + Parameters: + config ([`EfficientFormerConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +EFFICIENTFORMER_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`ViTFeatureExtractor`]. See + [`ViTFeatureExtractor.__call__`] for details. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare EfficientFormer Model transformer outputting raw hidden-states without any specific head on top.", + EFFICIENTFORMER_START_DOCSTRING, +) +class EfficientFormerModel(EfficientFormerPreTrainedModel): + def __init__(self, config: EfficientFormerConfig): + super().__init__(config) + self.config = config + + self.patch_embed = EfficientFormerConvStem(config, config.hidden_sizes[0]) + self.encoder = EfficientFormerEncoder(config) + self.layernorm = nn.LayerNorm(config.hidden_sizes[-1], eps=config.layer_norm_eps) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + embedding_output = self.patch_embed(pixel_values) + encoder_outputs = self.encoder( + embedding_output, output_attentions=output_attentions, output_hidden_states=output_hidden_states + ) + + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + + if not return_dict: + head_outputs = (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + """ + EfficientFormer Model transformer with an image classification head on top (a linear layer on top of the final + hidden state of the [CLS] token) e.g. for ImageNet. + """, + EFFICIENTFORMER_START_DOCSTRING, +) +class EfficientFormerForImageClassification(EfficientFormerPreTrainedModel): + def __init__(self, config: EfficientFormerConfig): + super().__init__(config) + + self.num_labels = config.num_labels + self.efficientformer = EfficientFormerModel(config) + + # Classifier head + self.classifier = ( + nn.Linear(config.hidden_sizes[-1], config.num_labels) if config.num_labels > 0 else nn.Identity() + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=ImageClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.efficientformer( + pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output.mean(-2)) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@dataclass +class EfficientFormerForImageClassificationWithTeacherOutput(ModelOutput): + """ + Output type of [`EfficientFormerForImageClassificationWithTeacher`]. + + Args: + logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores as the average of the cls_logits and distillation logits. + cls_logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the classification head (i.e. the linear layer on top of the final hidden state of the + class token). + distillation_logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Prediction scores of the distillation head (i.e. the linear layer on top of the final hidden state of the + distillation token). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer + plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + logits: torch.FloatTensor = None + cls_logits: torch.FloatTensor = None + distillation_logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@add_start_docstrings( + """ + EfficientFormer Model transformer with image classification heads on top (a linear layer on top of the final hidden + state of the [CLS] token and a linear layer on top of the final hidden state of the distillation token) e.g. for + ImageNet. + + + + This model supports inference-only. Fine-tuning with distillation (i.e. with a teacher) is not yet + supported. + + + """, + EFFICIENTFORMER_START_DOCSTRING, +) +class EfficientFormerForImageClassificationWithTeacher(EfficientFormerPreTrainedModel): + def __init__(self, config: EfficientFormerConfig): + super().__init__(config) + + self.num_labels = config.num_labels + self.efficientformer = EfficientFormerModel(config) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + # Distillation head + self.distillation_classifier = ( + nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(EFFICIENTFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=EfficientFormerForImageClassificationWithTeacherOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, EfficientFormerForImageClassificationWithTeacherOutput]: + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + outputs = self.efficientformer( + pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + cls_logits = self.classifier(sequence_output.mean(-2)) + distillation_logits = self.distillation_classifier(sequence_output.mean(-2)) + + # during inference, return the average of both classifier predictions + logits = (cls_logits + distillation_logits) / 2 + + if not return_dict: + output = (logits, cls_logits, distillation_logits) + outputs[1:] + return output + + return EfficientFormerForImageClassificationWithTeacherOutput( + logits=logits, + cls_logits=cls_logits, + distillation_logits=distillation_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/configuration_efficientnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/configuration_efficientnet.py new file mode 100644 index 0000000000000000000000000000000000000000..a6e4d172f442898c16e47b0da808260c87e23fe4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/configuration_efficientnet.py @@ -0,0 +1,169 @@ +# coding=utf-8 +# Copyright 2023 Google Research, Inc. and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" EfficientNet model configuration""" + +from collections import OrderedDict +from typing import List, Mapping + +from packaging import version + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +EFFICIENTNET_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "google/efficientnet-b7": "https://huggingface.co/google/efficientnet-b7/resolve/main/config.json", +} + + +class EfficientNetConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`EfficientNetModel`]. It is used to instantiate an + EfficientNet model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the EfficientNet + [google/efficientnet-b7](https://huggingface.co/google/efficientnet-b7) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + image_size (`int`, *optional*, defaults to 600): + The input image size. + width_coefficient (`float`, *optional*, defaults to 2.0): + Scaling coefficient for network width at each stage. + depth_coefficient (`float`, *optional*, defaults to 3.1): + Scaling coefficient for network depth at each stage. + depth_divisor `int`, *optional*, defaults to 8): + A unit of network width. + kernel_sizes (`List[int]`, *optional*, defaults to `[3, 3, 5, 3, 5, 5, 3]`): + List of kernel sizes to be used in each block. + in_channels (`List[int]`, *optional*, defaults to `[32, 16, 24, 40, 80, 112, 192]`): + List of input channel sizes to be used in each block for convolutional layers. + out_channels (`List[int]`, *optional*, defaults to `[16, 24, 40, 80, 112, 192, 320]`): + List of output channel sizes to be used in each block for convolutional layers. + depthwise_padding (`List[int]`, *optional*, defaults to `[]`): + List of block indices with square padding. + strides: (`List[int]`, *optional*, defaults to `[1, 2, 2, 2, 1, 2, 1]`): + List of stride sizes to be used in each block for convolutional layers. + num_block_repeats (`List[int]`, *optional*, defaults to `[1, 2, 2, 3, 3, 4, 1]`): + List of the number of times each block is to repeated. + expand_ratios (`List[int]`, *optional*, defaults to `[1, 6, 6, 6, 6, 6, 6]`): + List of scaling coefficient of each block. + squeeze_expansion_ratio (`float`, *optional*, defaults to 0.25): + Squeeze expansion ratio. + hidden_act (`str` or `function`, *optional*, defaults to `"silu"`): + The non-linear activation function (function or string) in each block. If string, `"gelu"`, `"relu"`, + `"selu", `"gelu_new"`, `"silu"` and `"mish"` are supported. + hiddem_dim (`int`, *optional*, defaults to 1280): + The hidden dimension of the layer before the classification head. + pooling_type (`str` or `function`, *optional*, defaults to `"mean"`): + Type of final pooling to be applied before the dense classification head. Available options are [`"mean"`, + `"max"`] + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + batch_norm_eps (`float`, *optional*, defaults to 1e-3): + The epsilon used by the batch normalization layers. + batch_norm_momentum (`float`, *optional*, defaults to 0.99): + The momentum used by the batch normalization layers. + dropout_rate (`float`, *optional*, defaults to 0.5): + The dropout rate to be applied before final classifier layer. + drop_connect_rate (`float`, *optional*, defaults to 0.2): + The drop rate for skip connections. + + Example: + ```python + >>> from transformers import EfficientNetConfig, EfficientNetModel + + >>> # Initializing a EfficientNet efficientnet-b7 style configuration + >>> configuration = EfficientNetConfig() + + >>> # Initializing a model (with random weights) from the efficientnet-b7 style configuration + >>> model = EfficientNetModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "efficientnet" + + def __init__( + self, + num_channels: int = 3, + image_size: int = 600, + width_coefficient: float = 2.0, + depth_coefficient: float = 3.1, + depth_divisor: int = 8, + kernel_sizes: List[int] = [3, 3, 5, 3, 5, 5, 3], + in_channels: List[int] = [32, 16, 24, 40, 80, 112, 192], + out_channels: List[int] = [16, 24, 40, 80, 112, 192, 320], + depthwise_padding: List[int] = [], + strides: List[int] = [1, 2, 2, 2, 1, 2, 1], + num_block_repeats: List[int] = [1, 2, 2, 3, 3, 4, 1], + expand_ratios: List[int] = [1, 6, 6, 6, 6, 6, 6], + squeeze_expansion_ratio: float = 0.25, + hidden_act: str = "swish", + hidden_dim: int = 2560, + pooling_type: str = "mean", + initializer_range: float = 0.02, + batch_norm_eps: float = 0.001, + batch_norm_momentum: float = 0.99, + dropout_rate: float = 0.5, + drop_connect_rate: float = 0.2, + **kwargs, + ): + super().__init__(**kwargs) + + self.num_channels = num_channels + self.image_size = image_size + self.width_coefficient = width_coefficient + self.depth_coefficient = depth_coefficient + self.depth_divisor = depth_divisor + self.kernel_sizes = kernel_sizes + self.in_channels = in_channels + self.out_channels = out_channels + self.depthwise_padding = depthwise_padding + self.strides = strides + self.num_block_repeats = num_block_repeats + self.expand_ratios = expand_ratios + self.squeeze_expansion_ratio = squeeze_expansion_ratio + self.hidden_act = hidden_act + self.hidden_dim = hidden_dim + self.pooling_type = pooling_type + self.initializer_range = initializer_range + self.batch_norm_eps = batch_norm_eps + self.batch_norm_momentum = batch_norm_momentum + self.dropout_rate = dropout_rate + self.drop_connect_rate = drop_connect_rate + self.num_hidden_layers = sum(num_block_repeats) * 4 + + +class EfficientNetOnnxConfig(OnnxConfig): + torch_onnx_minimum_version = version.parse("1.11") + + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + return OrderedDict( + [ + ("pixel_values", {0: "batch", 1: "num_channels", 2: "height", 3: "width"}), + ] + ) + + @property + def atol_for_validation(self) -> float: + return 1e-5 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/convert_efficientnet_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/convert_efficientnet_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..9813ccb9b80ff2016da63a9059f0abdb02e36249 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/efficientnet/convert_efficientnet_to_pytorch.py @@ -0,0 +1,339 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert EfficientNet checkpoints from the original repository. + +URL: https://github.com/keras-team/keras/blob/v2.11.0/keras/applications/efficientnet.py""" + +import argparse +import json +import os + +import numpy as np +import PIL +import requests +import tensorflow.keras.applications.efficientnet as efficientnet +import torch +from huggingface_hub import hf_hub_download +from PIL import Image +from tensorflow.keras.preprocessing import image + +from transformers import ( + EfficientNetConfig, + EfficientNetForImageClassification, + EfficientNetImageProcessor, +) +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +model_classes = { + "b0": efficientnet.EfficientNetB0, + "b1": efficientnet.EfficientNetB1, + "b2": efficientnet.EfficientNetB2, + "b3": efficientnet.EfficientNetB3, + "b4": efficientnet.EfficientNetB4, + "b5": efficientnet.EfficientNetB5, + "b6": efficientnet.EfficientNetB6, + "b7": efficientnet.EfficientNetB7, +} + +CONFIG_MAP = { + "b0": { + "hidden_dim": 1280, + "width_coef": 1.0, + "depth_coef": 1.0, + "image_size": 224, + "dropout_rate": 0.2, + "dw_padding": [], + }, + "b1": { + "hidden_dim": 1280, + "width_coef": 1.0, + "depth_coef": 1.1, + "image_size": 240, + "dropout_rate": 0.2, + "dw_padding": [16], + }, + "b2": { + "hidden_dim": 1408, + "width_coef": 1.1, + "depth_coef": 1.2, + "image_size": 260, + "dropout_rate": 0.3, + "dw_padding": [5, 8, 16], + }, + "b3": { + "hidden_dim": 1536, + "width_coef": 1.2, + "depth_coef": 1.4, + "image_size": 300, + "dropout_rate": 0.3, + "dw_padding": [5, 18], + }, + "b4": { + "hidden_dim": 1792, + "width_coef": 1.4, + "depth_coef": 1.8, + "image_size": 380, + "dropout_rate": 0.4, + "dw_padding": [6], + }, + "b5": { + "hidden_dim": 2048, + "width_coef": 1.6, + "depth_coef": 2.2, + "image_size": 456, + "dropout_rate": 0.4, + "dw_padding": [13, 27], + }, + "b6": { + "hidden_dim": 2304, + "width_coef": 1.8, + "depth_coef": 2.6, + "image_size": 528, + "dropout_rate": 0.5, + "dw_padding": [31], + }, + "b7": { + "hidden_dim": 2560, + "width_coef": 2.0, + "depth_coef": 3.1, + "image_size": 600, + "dropout_rate": 0.5, + "dw_padding": [18], + }, +} + + +def get_efficientnet_config(model_name): + config = EfficientNetConfig() + config.hidden_dim = CONFIG_MAP[model_name]["hidden_dim"] + config.width_coefficient = CONFIG_MAP[model_name]["width_coef"] + config.depth_coefficient = CONFIG_MAP[model_name]["depth_coef"] + config.image_size = CONFIG_MAP[model_name]["image_size"] + config.dropout_rate = CONFIG_MAP[model_name]["dropout_rate"] + config.depthwise_padding = CONFIG_MAP[model_name]["dw_padding"] + + repo_id = "huggingface/label-files" + filename = "imagenet-1k-id2label.json" + config.num_labels = 1000 + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + return config + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +def convert_image_processor(model_name): + size = CONFIG_MAP[model_name]["image_size"] + preprocessor = EfficientNetImageProcessor( + size={"height": size, "width": size}, + image_mean=[0.485, 0.456, 0.406], + image_std=[0.47853944, 0.4732864, 0.47434163], + do_center_crop=False, + ) + return preprocessor + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def rename_keys(original_param_names): + block_names = [v.split("_")[0].split("block")[1] for v in original_param_names if v.startswith("block")] + block_names = sorted(set(block_names)) + num_blocks = len(block_names) + block_name_mapping = {b: str(i) for b, i in zip(block_names, range(num_blocks))} + + rename_keys = [] + rename_keys.append(("stem_conv/kernel:0", "embeddings.convolution.weight")) + rename_keys.append(("stem_bn/gamma:0", "embeddings.batchnorm.weight")) + rename_keys.append(("stem_bn/beta:0", "embeddings.batchnorm.bias")) + rename_keys.append(("stem_bn/moving_mean:0", "embeddings.batchnorm.running_mean")) + rename_keys.append(("stem_bn/moving_variance:0", "embeddings.batchnorm.running_var")) + + for b in block_names: + hf_b = block_name_mapping[b] + rename_keys.append((f"block{b}_expand_conv/kernel:0", f"encoder.blocks.{hf_b}.expansion.expand_conv.weight")) + rename_keys.append((f"block{b}_expand_bn/gamma:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.weight")) + rename_keys.append((f"block{b}_expand_bn/beta:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.bias")) + rename_keys.append( + (f"block{b}_expand_bn/moving_mean:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.running_mean") + ) + rename_keys.append( + (f"block{b}_expand_bn/moving_variance:0", f"encoder.blocks.{hf_b}.expansion.expand_bn.running_var") + ) + rename_keys.append( + (f"block{b}_dwconv/depthwise_kernel:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight") + ) + rename_keys.append((f"block{b}_bn/gamma:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight")) + rename_keys.append((f"block{b}_bn/beta:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias")) + rename_keys.append( + (f"block{b}_bn/moving_mean:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean") + ) + rename_keys.append( + (f"block{b}_bn/moving_variance:0", f"encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var") + ) + + rename_keys.append((f"block{b}_se_reduce/kernel:0", f"encoder.blocks.{hf_b}.squeeze_excite.reduce.weight")) + rename_keys.append((f"block{b}_se_reduce/bias:0", f"encoder.blocks.{hf_b}.squeeze_excite.reduce.bias")) + rename_keys.append((f"block{b}_se_expand/kernel:0", f"encoder.blocks.{hf_b}.squeeze_excite.expand.weight")) + rename_keys.append((f"block{b}_se_expand/bias:0", f"encoder.blocks.{hf_b}.squeeze_excite.expand.bias")) + rename_keys.append( + (f"block{b}_project_conv/kernel:0", f"encoder.blocks.{hf_b}.projection.project_conv.weight") + ) + rename_keys.append((f"block{b}_project_bn/gamma:0", f"encoder.blocks.{hf_b}.projection.project_bn.weight")) + rename_keys.append((f"block{b}_project_bn/beta:0", f"encoder.blocks.{hf_b}.projection.project_bn.bias")) + rename_keys.append( + (f"block{b}_project_bn/moving_mean:0", f"encoder.blocks.{hf_b}.projection.project_bn.running_mean") + ) + rename_keys.append( + (f"block{b}_project_bn/moving_variance:0", f"encoder.blocks.{hf_b}.projection.project_bn.running_var") + ) + + rename_keys.append(("top_conv/kernel:0", "encoder.top_conv.weight")) + rename_keys.append(("top_bn/gamma:0", "encoder.top_bn.weight")) + rename_keys.append(("top_bn/beta:0", "encoder.top_bn.bias")) + rename_keys.append(("top_bn/moving_mean:0", "encoder.top_bn.running_mean")) + rename_keys.append(("top_bn/moving_variance:0", "encoder.top_bn.running_var")) + + key_mapping = {} + for item in rename_keys: + if item[0] in original_param_names: + key_mapping[item[0]] = "efficientnet." + item[1] + + key_mapping["predictions/kernel:0"] = "classifier.weight" + key_mapping["predictions/bias:0"] = "classifier.bias" + return key_mapping + + +def replace_params(hf_params, tf_params, key_mapping): + for key, value in tf_params.items(): + if "normalization" in key: + continue + + hf_key = key_mapping[key] + if "_conv" in key and "kernel" in key: + new_hf_value = torch.from_numpy(value).permute(3, 2, 0, 1) + elif "depthwise_kernel" in key: + new_hf_value = torch.from_numpy(value).permute(2, 3, 0, 1) + elif "kernel" in key: + new_hf_value = torch.from_numpy(np.transpose(value)) + else: + new_hf_value = torch.from_numpy(value) + + # Replace HF parameters with original TF model parameters + assert hf_params[hf_key].shape == new_hf_value.shape + hf_params[hf_key].copy_(new_hf_value) + + +@torch.no_grad() +def convert_efficientnet_checkpoint(model_name, pytorch_dump_folder_path, save_model, push_to_hub): + """ + Copy/paste/tweak model's weights to our EfficientNet structure. + """ + # Load original model + original_model = model_classes[model_name]( + include_top=True, + weights="imagenet", + input_tensor=None, + input_shape=None, + pooling=None, + classes=1000, + classifier_activation="softmax", + ) + + tf_params = original_model.trainable_variables + tf_non_train_params = original_model.non_trainable_variables + tf_params = {param.name: param.numpy() for param in tf_params} + for param in tf_non_train_params: + tf_params[param.name] = param.numpy() + tf_param_names = list(tf_params.keys()) + + # Load HuggingFace model + config = get_efficientnet_config(model_name) + hf_model = EfficientNetForImageClassification(config).eval() + hf_params = hf_model.state_dict() + + # Create src-to-dst parameter name mapping dictionary + print("Converting parameters...") + key_mapping = rename_keys(tf_param_names) + replace_params(hf_params, tf_params, key_mapping) + + # Initialize preprocessor and preprocess input image + preprocessor = convert_image_processor(model_name) + inputs = preprocessor(images=prepare_img(), return_tensors="pt") + + # HF model inference + hf_model.eval() + with torch.no_grad(): + outputs = hf_model(**inputs) + hf_logits = outputs.logits.detach().numpy() + + # Original model inference + original_model.trainable = False + image_size = CONFIG_MAP[model_name]["image_size"] + img = prepare_img().resize((image_size, image_size), resample=PIL.Image.NEAREST) + x = image.img_to_array(img) + x = np.expand_dims(x, axis=0) + original_logits = original_model.predict(x) + + # Check whether original and HF model outputs match -> np.allclose + assert np.allclose(original_logits, hf_logits, atol=1e-3), "The predicted logits are not the same." + print("Model outputs match!") + + if save_model: + # Create folder to save model + if not os.path.isdir(pytorch_dump_folder_path): + os.mkdir(pytorch_dump_folder_path) + # Save converted model and feature extractor + hf_model.save_pretrained(pytorch_dump_folder_path) + preprocessor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + # Push model and feature extractor to hub + print(f"Pushing converted {model_name} to the hub...") + model_name = f"efficientnet-{model_name}" + preprocessor.push_to_hub(model_name) + hf_model.push_to_hub(model_name) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--model_name", + default="b0", + type=str, + help="Version name of the EfficientNet model you want to convert, select from [b0, b1, b2, b3, b4, b5, b6, b7].", + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default="hf_model", + type=str, + help="Path to the output PyTorch model directory.", + ) + parser.add_argument("--save_model", action="store_true", help="Save model to local") + parser.add_argument("--push_to_hub", action="store_true", help="Push model and feature extractor to the hub") + + args = parser.parse_args() + convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..09ce039d25fd057608693a8d6c9d79358d970225 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/__init__.py @@ -0,0 +1,168 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_electra": ["ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP", "ElectraConfig", "ElectraOnnxConfig"], + "tokenization_electra": ["ElectraTokenizer"], +} + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_electra_fast"] = ["ElectraTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_electra"] = [ + "ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST", + "ElectraForCausalLM", + "ElectraForMaskedLM", + "ElectraForMultipleChoice", + "ElectraForPreTraining", + "ElectraForQuestionAnswering", + "ElectraForSequenceClassification", + "ElectraForTokenClassification", + "ElectraModel", + "ElectraPreTrainedModel", + "load_tf_weights_in_electra", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_electra"] = [ + "TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFElectraForMaskedLM", + "TFElectraForMultipleChoice", + "TFElectraForPreTraining", + "TFElectraForQuestionAnswering", + "TFElectraForSequenceClassification", + "TFElectraForTokenClassification", + "TFElectraModel", + "TFElectraPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_electra"] = [ + "FlaxElectraForCausalLM", + "FlaxElectraForMaskedLM", + "FlaxElectraForMultipleChoice", + "FlaxElectraForPreTraining", + "FlaxElectraForQuestionAnswering", + "FlaxElectraForSequenceClassification", + "FlaxElectraForTokenClassification", + "FlaxElectraModel", + "FlaxElectraPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_electra import ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP, ElectraConfig, ElectraOnnxConfig + from .tokenization_electra import ElectraTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_electra_fast import ElectraTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_electra import ( + ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST, + ElectraForCausalLM, + ElectraForMaskedLM, + ElectraForMultipleChoice, + ElectraForPreTraining, + ElectraForQuestionAnswering, + ElectraForSequenceClassification, + ElectraForTokenClassification, + ElectraModel, + ElectraPreTrainedModel, + load_tf_weights_in_electra, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_electra import ( + TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST, + TFElectraForMaskedLM, + TFElectraForMultipleChoice, + TFElectraForPreTraining, + TFElectraForQuestionAnswering, + TFElectraForSequenceClassification, + TFElectraForTokenClassification, + TFElectraModel, + TFElectraPreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_electra import ( + FlaxElectraForCausalLM, + FlaxElectraForMaskedLM, + FlaxElectraForMultipleChoice, + FlaxElectraForPreTraining, + FlaxElectraForQuestionAnswering, + FlaxElectraForSequenceClassification, + FlaxElectraForTokenClassification, + FlaxElectraModel, + FlaxElectraPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/configuration_electra.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/configuration_electra.py new file mode 100644 index 0000000000000000000000000000000000000000..d8e1de0fc97fa449c4941bc407fd689a7f50be7c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/configuration_electra.py @@ -0,0 +1,198 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" ELECTRA model configuration""" + +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "google/electra-small-generator": "https://huggingface.co/google/electra-small-generator/resolve/main/config.json", + "google/electra-base-generator": "https://huggingface.co/google/electra-base-generator/resolve/main/config.json", + "google/electra-large-generator": "https://huggingface.co/google/electra-large-generator/resolve/main/config.json", + "google/electra-small-discriminator": ( + "https://huggingface.co/google/electra-small-discriminator/resolve/main/config.json" + ), + "google/electra-base-discriminator": ( + "https://huggingface.co/google/electra-base-discriminator/resolve/main/config.json" + ), + "google/electra-large-discriminator": ( + "https://huggingface.co/google/electra-large-discriminator/resolve/main/config.json" + ), +} + + +class ElectraConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`ElectraModel`] or a [`TFElectraModel`]. It is + used to instantiate a ELECTRA model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the ELECTRA + [google/electra-small-discriminator](https://huggingface.co/google/electra-small-discriminator) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the ELECTRA model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`ElectraModel`] or [`TFElectraModel`]. + embedding_size (`int`, *optional*, defaults to 128): + Dimensionality of the encoder layers and the pooler layer. + hidden_size (`int`, *optional*, defaults to 256): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 4): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 1024): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`ElectraModel`] or [`TFElectraModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + summary_type (`str`, *optional*, defaults to `"first"`): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Has to be one of the following options: + + - `"last"`: Take the last token hidden state (like XLNet). + - `"first"`: Take the first token hidden state (like BERT). + - `"mean"`: Take the mean of all tokens hidden states. + - `"cls_index"`: Supply a Tensor of classification token position (like GPT/GPT-2). + - `"attn"`: Not implemented now, use multi-head attention. + summary_use_proj (`bool`, *optional*, defaults to `True`): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Whether or not to add a projection after the vector extraction. + summary_activation (`str`, *optional*): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Pass `"gelu"` for a gelu activation to the output, any other value will result in no activation. + summary_last_dropout (`float`, *optional*, defaults to 0.0): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + The dropout ratio to be used after the projection and activation. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + classifier_dropout (`float`, *optional*): + The dropout ratio for the classification head. + + Examples: + + ```python + >>> from transformers import ElectraConfig, ElectraModel + + >>> # Initializing a ELECTRA electra-base-uncased style configuration + >>> configuration = ElectraConfig() + + >>> # Initializing a model (with random weights) from the electra-base-uncased style configuration + >>> model = ElectraModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "electra" + + def __init__( + self, + vocab_size=30522, + embedding_size=128, + hidden_size=256, + num_hidden_layers=12, + num_attention_heads=4, + intermediate_size=1024, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + summary_type="first", + summary_use_proj=True, + summary_activation="gelu", + summary_last_dropout=0.1, + pad_token_id=0, + position_embedding_type="absolute", + use_cache=True, + classifier_dropout=None, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, **kwargs) + + self.vocab_size = vocab_size + self.embedding_size = embedding_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + + self.summary_type = summary_type + self.summary_use_proj = summary_use_proj + self.summary_activation = summary_activation + self.summary_last_dropout = summary_last_dropout + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.classifier_dropout = classifier_dropout + + +class ElectraOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ("token_type_ids", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/modeling_electra.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/modeling_electra.py new file mode 100644 index 0000000000000000000000000000000000000000..9c6b68f26ac799dd28bbea9858e632d8e14a81a6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/modeling_electra.py @@ -0,0 +1,1680 @@ +# coding=utf-8 +# Copyright 2019 The Google AI Language Team Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTorch ELECTRA model.""" + +import math +import os +from dataclasses import dataclass +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN, get_activation +from ...modeling_outputs import ( + BaseModelOutputWithCrossAttentions, + BaseModelOutputWithPastAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel, SequenceSummary +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_electra import ElectraConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "google/electra-small-discriminator" +_CONFIG_FOR_DOC = "ElectraConfig" + +ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "google/electra-small-generator", + "google/electra-base-generator", + "google/electra-large-generator", + "google/electra-small-discriminator", + "google/electra-base-discriminator", + "google/electra-large-discriminator", + # See all ELECTRA models at https://huggingface.co/models?filter=electra +] + + +def load_tf_weights_in_electra(model, config, tf_checkpoint_path, discriminator_or_generator="discriminator"): + """Load tf checkpoints in a pytorch model.""" + try: + import re + + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + tf_path = os.path.abspath(tf_checkpoint_path) + logger.info(f"Converting TensorFlow checkpoint from {tf_path}") + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + names = [] + arrays = [] + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + names.append(name) + arrays.append(array) + for name, array in zip(names, arrays): + original_name: str = name + + try: + if isinstance(model, ElectraForMaskedLM): + name = name.replace("electra/embeddings/", "generator/embeddings/") + + if discriminator_or_generator == "generator": + name = name.replace("electra/", "discriminator/") + name = name.replace("generator/", "electra/") + + name = name.replace("dense_1", "dense_prediction") + name = name.replace("generator_predictions/output_bias", "generator_lm_head/bias") + + name = name.split("/") + # print(original_name, name) + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if any(n in ["global_step", "temperature"] for n in name): + logger.info(f"Skipping {original_name}") + continue + pointer = model + for m_name in name: + if re.fullmatch(r"[A-Za-z]+_\d+", m_name): + scope_names = re.split(r"_(\d+)", m_name) + else: + scope_names = [m_name] + if scope_names[0] == "kernel" or scope_names[0] == "gamma": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "output_bias" or scope_names[0] == "beta": + pointer = getattr(pointer, "bias") + elif scope_names[0] == "output_weights": + pointer = getattr(pointer, "weight") + elif scope_names[0] == "squad": + pointer = getattr(pointer, "classifier") + else: + pointer = getattr(pointer, scope_names[0]) + if len(scope_names) >= 2: + num = int(scope_names[1]) + pointer = pointer[num] + if m_name.endswith("_embeddings"): + pointer = getattr(pointer, "weight") + elif m_name == "kernel": + array = np.transpose(array) + try: + if pointer.shape != array.shape: + raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched") + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + print(f"Initialize PyTorch weight {name}", original_name) + pointer.data = torch.from_numpy(array) + except AttributeError as e: + print(f"Skipping {original_name}", name, e) + continue + return model + + +class ElectraEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.embedding_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.forward + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + past_key_values_length: int = 0, + ) -> torch.Tensor: + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + +# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->Electra +class ElectraSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in ElectraModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertSelfOutput +class ElectraSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Electra +class ElectraAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = ElectraSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = ElectraSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self( + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate +class ElectraIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertOutput +class ElectraOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertLayer with Bert->Electra +class ElectraLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = ElectraAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = ElectraAttention(config, position_embedding_type="absolute") + self.intermediate = ElectraIntermediate(config) + self.output = ElectraOutput(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +# Copied from transformers.models.bert.modeling_bert.BertEncoder with Bert->Electra +class ElectraEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([ElectraLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +class ElectraDiscriminatorPredictions(nn.Module): + """Prediction module for the discriminator, made up of two dense layers.""" + + def __init__(self, config): + super().__init__() + + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dense_prediction = nn.Linear(config.hidden_size, 1) + self.config = config + + def forward(self, discriminator_hidden_states): + hidden_states = self.dense(discriminator_hidden_states) + hidden_states = get_activation(self.config.hidden_act)(hidden_states) + logits = self.dense_prediction(hidden_states).squeeze(-1) + + return logits + + +class ElectraGeneratorPredictions(nn.Module): + """Prediction module for the generator, made up of two dense layers.""" + + def __init__(self, config): + super().__init__() + + self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps) + self.dense = nn.Linear(config.hidden_size, config.embedding_size) + + def forward(self, generator_hidden_states): + hidden_states = self.dense(generator_hidden_states) + hidden_states = get_activation("gelu")(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + + return hidden_states + + +class ElectraPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ElectraConfig + load_tf_weights = load_tf_weights_in_electra + base_model_prefix = "electra" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + _keys_to_ignore_on_load_unexpected = [r"electra.embeddings_project.weight", r"electra.embeddings_project.bias"] + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, ElectraEncoder): + module.gradient_checkpointing = value + + +@dataclass +class ElectraForPreTrainingOutput(ModelOutput): + """ + Output type of [`ElectraForPreTraining`]. + + Args: + loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`): + Total loss of the ELECTRA objective. + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Prediction scores of the head (scores for each token before SoftMax). + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +ELECTRA_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`ElectraConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +ELECTRA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + encoder_hidden_states (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Electra Model transformer outputting raw hidden-states without any specific head on top. Identical to " + "the BERT model except that it uses an additional linear layer between the embedding layer and the encoder if the " + "hidden size and embedding size are different. " + "" + "Both the generator and discriminator checkpoints may be loaded into this model.", + ELECTRA_START_DOCSTRING, +) +class ElectraModel(ElectraPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.embeddings = ElectraEmbeddings(config) + + if config.embedding_size != config.hidden_size: + self.embeddings_project = nn.Linear(config.embedding_size, config.hidden_size) + + self.encoder = ElectraEncoder(config) + self.config = config + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithCrossAttentions]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if attention_mask is None: + attention_mask = torch.ones(input_shape, device=device) + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape) + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.is_decoder and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_extended_attention_mask = None + + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + hidden_states = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + + if hasattr(self, "embeddings_project"): + hidden_states = self.embeddings_project(hidden_states) + + hidden_states = self.encoder( + hidden_states, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + return hidden_states + + +class ElectraClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = get_activation("gelu")(x) # although BERT uses tanh here, it seems Electra authors used gelu here + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """ + ELECTRA Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForSequenceClassification(ElectraPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + self.electra = ElectraModel(config) + self.classifier = ElectraClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="bhadresh-savani/electra-base-emotion", + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="'joy'", + expected_loss=0.06, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + discriminator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = discriminator_hidden_states[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + discriminator_hidden_states[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=discriminator_hidden_states.hidden_states, + attentions=discriminator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ + Electra model with a binary classification head on top as used during pretraining for identifying generated tokens. + + It is recommended to load the discriminator checkpoint into that model. + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForPreTraining(ElectraPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.electra = ElectraModel(config) + self.discriminator_predictions = ElectraDiscriminatorPredictions(config) + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=ElectraForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], ElectraForPreTrainingOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the ELECTRA loss. Input should be a sequence of tokens (see `input_ids` docstring) + Indices should be in `[0, 1]`: + + - 0 indicates the token is an original token, + - 1 indicates the token was replaced. + + Returns: + + Examples: + + ```python + >>> from transformers import ElectraForPreTraining, AutoTokenizer + >>> import torch + + >>> discriminator = ElectraForPreTraining.from_pretrained("google/electra-base-discriminator") + >>> tokenizer = AutoTokenizer.from_pretrained("google/electra-base-discriminator") + + >>> sentence = "The quick brown fox jumps over the lazy dog" + >>> fake_sentence = "The quick brown fox fake over the lazy dog" + + >>> fake_tokens = tokenizer.tokenize(fake_sentence, add_special_tokens=True) + >>> fake_inputs = tokenizer.encode(fake_sentence, return_tensors="pt") + >>> discriminator_outputs = discriminator(fake_inputs) + >>> predictions = torch.round((torch.sign(discriminator_outputs[0]) + 1) / 2) + + >>> fake_tokens + ['[CLS]', 'the', 'quick', 'brown', 'fox', 'fake', 'over', 'the', 'lazy', 'dog', '[SEP]'] + + >>> predictions.squeeze().tolist() + [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + discriminator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + discriminator_sequence_output = discriminator_hidden_states[0] + + logits = self.discriminator_predictions(discriminator_sequence_output) + + loss = None + if labels is not None: + loss_fct = nn.BCEWithLogitsLoss() + if attention_mask is not None: + active_loss = attention_mask.view(-1, discriminator_sequence_output.shape[1]) == 1 + active_logits = logits.view(-1, discriminator_sequence_output.shape[1])[active_loss] + active_labels = labels[active_loss] + loss = loss_fct(active_logits, active_labels.float()) + else: + loss = loss_fct(logits.view(-1, discriminator_sequence_output.shape[1]), labels.float()) + + if not return_dict: + output = (logits,) + discriminator_hidden_states[1:] + return ((loss,) + output) if loss is not None else output + + return ElectraForPreTrainingOutput( + loss=loss, + logits=logits, + hidden_states=discriminator_hidden_states.hidden_states, + attentions=discriminator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ + Electra model with a language modeling head on top. + + Even though both the discriminator and generator may be loaded into this model, the generator is the only model of + the two to have been trained for the masked language modeling task. + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForMaskedLM(ElectraPreTrainedModel): + _keys_to_ignore_on_load_missing = ["generator_lm_head.weight"] + + def __init__(self, config): + super().__init__(config) + + self.electra = ElectraModel(config) + self.generator_predictions = ElectraGeneratorPredictions(config) + + self.generator_lm_head = nn.Linear(config.embedding_size, config.vocab_size) + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.generator_lm_head + + def set_output_embeddings(self, word_embeddings): + self.generator_lm_head = word_embeddings + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="google/electra-small-generator", + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="[MASK]", + expected_output="'paris'", + expected_loss=1.22, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + generator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + generator_sequence_output = generator_hidden_states[0] + + prediction_scores = self.generator_predictions(generator_sequence_output) + prediction_scores = self.generator_lm_head(prediction_scores) + + loss = None + # Masked language modeling softmax layer + if labels is not None: + loss_fct = nn.CrossEntropyLoss() # -100 index = padding token + loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + generator_hidden_states[1:] + return ((loss,) + output) if loss is not None else output + + return MaskedLMOutput( + loss=loss, + logits=prediction_scores, + hidden_states=generator_hidden_states.hidden_states, + attentions=generator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ + Electra model with a token classification head on top. + + Both the discriminator and generator may be loaded into this model. + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForTokenClassification(ElectraPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.electra = ElectraModel(config) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="bhadresh-savani/electra-base-discriminator-finetuned-conll03-english", + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="['B-LOC', 'B-ORG', 'O', 'O', 'O', 'O', 'O', 'B-LOC', 'O', 'B-LOC', 'I-LOC']", + expected_loss=0.11, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + discriminator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + discriminator_sequence_output = discriminator_hidden_states[0] + + discriminator_sequence_output = self.dropout(discriminator_sequence_output) + logits = self.classifier(discriminator_sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + discriminator_hidden_states[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=discriminator_hidden_states.hidden_states, + attentions=discriminator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ + ELECTRA Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForQuestionAnswering(ElectraPreTrainedModel): + config_class = ElectraConfig + base_model_prefix = "electra" + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.electra = ElectraModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="bhadresh-savani/electra-base-squad2", + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + qa_target_start_index=11, + qa_target_end_index=12, + expected_output="'a nice puppet'", + expected_loss=2.64, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + discriminator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + ) + + sequence_output = discriminator_hidden_states[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = ( + start_logits, + end_logits, + ) + discriminator_hidden_states[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=discriminator_hidden_states.hidden_states, + attentions=discriminator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ + ELECTRA Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + ELECTRA_START_DOCSTRING, +) +class ElectraForMultipleChoice(ElectraPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.electra = ElectraModel(config) + self.sequence_summary = SequenceSummary(config) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + discriminator_hidden_states = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = discriminator_hidden_states[0] + + pooled_output = self.sequence_summary(sequence_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + discriminator_hidden_states[1:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=discriminator_hidden_states.hidden_states, + attentions=discriminator_hidden_states.attentions, + ) + + +@add_start_docstrings( + """ELECTRA Model with a `language modeling` head on top for CLM fine-tuning.""", ELECTRA_START_DOCSTRING +) +class ElectraForCausalLM(ElectraPreTrainedModel): + _keys_to_ignore_on_load_missing = ["generator_lm_head.weight"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `ElectraForCausalLM` as a standalone, add `is_decoder=True.`") + + self.electra = ElectraModel(config) + self.generator_predictions = ElectraGeneratorPredictions(config) + self.generator_lm_head = nn.Linear(config.embedding_size, config.vocab_size) + + self.init_weights() + + def get_output_embeddings(self): + return self.generator_lm_head + + def set_output_embeddings(self, new_embeddings): + self.generator_lm_head = new_embeddings + + @add_start_docstrings_to_model_forward(ELECTRA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=CausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, ElectraForCausalLM, ElectraConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("google/electra-base-generator") + >>> config = ElectraConfig.from_pretrained("google/electra-base-generator") + >>> config.is_decoder = True + >>> model = ElectraForCausalLM.from_pretrained("google/electra-base-generator", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + outputs = self.electra( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.generator_lm_head(self.generator_predictions(sequence_output)) + + lm_loss = None + if labels is not None: + # we are doing next-token prediction; shift prediction scores and input ids by one + shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous() + labels = labels[:, 1:].contiguous() + loss_fct = CrossEntropyLoss() + lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[1:] + return ((lm_loss,) + output) if lm_loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM.prepare_inputs_for_generation + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): + input_shape = input_ids.shape + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_shape) + + # cut decoder_input_ids if past is used + if past_key_values is not None: + input_ids = input_ids[:, -1:] + + return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM._reorder_cache + def _reorder_cache(self, past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/tokenization_electra_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/tokenization_electra_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..cf92dd01714f9d3bd8f52c8570bba6be2f6b1feb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/electra/tokenization_electra_fast.py @@ -0,0 +1,231 @@ +# coding=utf-8 +# Copyright 2020 The Google AI Team, Stanford University and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from typing import List, Optional, Tuple + +from tokenizers import normalizers + +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from .tokenization_electra import ElectraTokenizer + + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "google/electra-small-generator": ( + "https://huggingface.co/google/electra-small-generator/resolve/main/vocab.txt" + ), + "google/electra-base-generator": "https://huggingface.co/google/electra-base-generator/resolve/main/vocab.txt", + "google/electra-large-generator": ( + "https://huggingface.co/google/electra-large-generator/resolve/main/vocab.txt" + ), + "google/electra-small-discriminator": ( + "https://huggingface.co/google/electra-small-discriminator/resolve/main/vocab.txt" + ), + "google/electra-base-discriminator": ( + "https://huggingface.co/google/electra-base-discriminator/resolve/main/vocab.txt" + ), + "google/electra-large-discriminator": ( + "https://huggingface.co/google/electra-large-discriminator/resolve/main/vocab.txt" + ), + }, + "tokenizer_file": { + "google/electra-small-generator": ( + "https://huggingface.co/google/electra-small-generator/resolve/main/tokenizer.json" + ), + "google/electra-base-generator": ( + "https://huggingface.co/google/electra-base-generator/resolve/main/tokenizer.json" + ), + "google/electra-large-generator": ( + "https://huggingface.co/google/electra-large-generator/resolve/main/tokenizer.json" + ), + "google/electra-small-discriminator": ( + "https://huggingface.co/google/electra-small-discriminator/resolve/main/tokenizer.json" + ), + "google/electra-base-discriminator": ( + "https://huggingface.co/google/electra-base-discriminator/resolve/main/tokenizer.json" + ), + "google/electra-large-discriminator": ( + "https://huggingface.co/google/electra-large-discriminator/resolve/main/tokenizer.json" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "google/electra-small-generator": 512, + "google/electra-base-generator": 512, + "google/electra-large-generator": 512, + "google/electra-small-discriminator": 512, + "google/electra-base-discriminator": 512, + "google/electra-large-discriminator": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "google/electra-small-generator": {"do_lower_case": True}, + "google/electra-base-generator": {"do_lower_case": True}, + "google/electra-large-generator": {"do_lower_case": True}, + "google/electra-small-discriminator": {"do_lower_case": True}, + "google/electra-base-discriminator": {"do_lower_case": True}, + "google/electra-large-discriminator": {"do_lower_case": True}, +} + + +# Copied from transformers.models.bert.tokenization_bert_fast.BertTokenizerFast with Bert->Electra , BERT->ELECTRA +class ElectraTokenizerFast(PreTrainedTokenizerFast): + r""" + Construct a "fast" ELECTRA tokenizer (backed by HuggingFace's *tokenizers* library). Based on WordPiece. + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether or not to lowercase the input when tokenizing. + unk_token (`str`, *optional*, defaults to `"[UNK]"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `"[SEP]"`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `"[PAD]"`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `"[CLS]"`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `"[MASK]"`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + clean_text (`bool`, *optional*, defaults to `True`): + Whether or not to clean the text before tokenization by removing any control characters and replacing all + whitespaces by the classic one. + tokenize_chinese_chars (`bool`, *optional*, defaults to `True`): + Whether or not to tokenize Chinese characters. This should likely be deactivated for Japanese (see [this + issue](https://github.com/huggingface/transformers/issues/328)). + strip_accents (`bool`, *optional*): + Whether or not to strip all accents. If this option is not specified, then it will be determined by the + value for `lowercase` (as in the original ELECTRA). + wordpieces_prefix (`str`, *optional*, defaults to `"##"`): + The prefix for subwords. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + slow_tokenizer_class = ElectraTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + do_lower_case=True, + unk_token="[UNK]", + sep_token="[SEP]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + tokenize_chinese_chars=True, + strip_accents=None, + **kwargs, + ): + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + do_lower_case=do_lower_case, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + tokenize_chinese_chars=tokenize_chinese_chars, + strip_accents=strip_accents, + **kwargs, + ) + + normalizer_state = json.loads(self.backend_tokenizer.normalizer.__getstate__()) + if ( + normalizer_state.get("lowercase", do_lower_case) != do_lower_case + or normalizer_state.get("strip_accents", strip_accents) != strip_accents + or normalizer_state.get("handle_chinese_chars", tokenize_chinese_chars) != tokenize_chinese_chars + ): + normalizer_class = getattr(normalizers, normalizer_state.pop("type")) + normalizer_state["lowercase"] = do_lower_case + normalizer_state["strip_accents"] = strip_accents + normalizer_state["handle_chinese_chars"] = tokenize_chinese_chars + self.backend_tokenizer.normalizer = normalizer_class(**normalizer_state) + + self.do_lower_case = do_lower_case + + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A ELECTRA sequence has the following format: + + - single sequence: `[CLS] X [SEP]` + - pair of sequences: `[CLS] A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + output = [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + + if token_ids_1: + output += token_ids_1 + [self.sep_token_id] + + return output + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. A ELECTRA + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + files = self._tokenizer.model.save(save_directory, name=filename_prefix) + return tuple(files) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/ernie/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/ernie/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ea7f077f928d39527ab5cf9ba4f195a62445bb84 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/ernie/__init__.py @@ -0,0 +1,70 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tensorflow_text_available, is_torch_available + + +_import_structure = { + "configuration_ernie": ["ERNIE_PRETRAINED_CONFIG_ARCHIVE_MAP", "ErnieConfig", "ErnieOnnxConfig"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_ernie"] = [ + "ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST", + "ErnieForCausalLM", + "ErnieForMaskedLM", + "ErnieForMultipleChoice", + "ErnieForNextSentencePrediction", + "ErnieForPreTraining", + "ErnieForQuestionAnswering", + "ErnieForSequenceClassification", + "ErnieForTokenClassification", + "ErnieModel", + "ErniePreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_ernie import ERNIE_PRETRAINED_CONFIG_ARCHIVE_MAP, ErnieConfig, ErnieOnnxConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_ernie import ( + ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST, + ErnieForCausalLM, + ErnieForMaskedLM, + ErnieForMultipleChoice, + ErnieForNextSentencePrediction, + ErnieForPreTraining, + ErnieForQuestionAnswering, + ErnieForSequenceClassification, + ErnieForTokenClassification, + ErnieModel, + ErniePreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d426ec93bf5859bc3ba040421c54ae4eefbbb32e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_torch_available, + is_vision_available, +) + + +_import_structure = {"configuration_vit": ["VIT_PRETRAINED_CONFIG_ARCHIVE_MAP", "ViTConfig", "ViTOnnxConfig"]} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_vit"] = ["ViTFeatureExtractor"] + _import_structure["image_processing_vit"] = ["ViTImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_vit"] = [ + "VIT_PRETRAINED_MODEL_ARCHIVE_LIST", + "ViTForImageClassification", + "ViTForMaskedImageModeling", + "ViTModel", + "ViTPreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_vit"] = [ + "TFViTForImageClassification", + "TFViTModel", + "TFViTPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_vit"] = [ + "FlaxViTForImageClassification", + "FlaxViTModel", + "FlaxViTPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_vit import VIT_PRETRAINED_CONFIG_ARCHIVE_MAP, ViTConfig, ViTOnnxConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_vit import ViTFeatureExtractor + from .image_processing_vit import ViTImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_vit import ( + VIT_PRETRAINED_MODEL_ARCHIVE_LIST, + ViTForImageClassification, + ViTForMaskedImageModeling, + ViTModel, + ViTPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_vit import TFViTForImageClassification, TFViTModel, TFViTPreTrainedModel + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_vit import FlaxViTForImageClassification, FlaxViTModel, FlaxViTPreTrainedModel + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_flax_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_flax_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..1ab2671efd75bfa30c9dea084dbbb732a85c1e8c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_flax_vit.py @@ -0,0 +1,672 @@ +# coding=utf-8 +# Copyright 2021 The Google Flax Team Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict + +from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxBaseModelOutputWithPooling, FlaxSequenceClassifierOutput +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward +from .configuration_vit import ViTConfig + + +VIT_START_DOCSTRING = r""" + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading, saving and converting weights from PyTorch models) + + This model is also a Flax Linen [flax.linen.Module](https://flax.readthedocs.io/en/latest/flax.linen.html#module) + subclass. Use it as a regular Flax linen Module and refer to the Flax documentation for all matter related to + general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`ViTConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + +VIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`numpy.ndarray` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class FlaxViTPatchEmbeddings(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + image_size = self.config.image_size + patch_size = self.config.patch_size + num_patches = (image_size // patch_size) * (image_size // patch_size) + self.num_patches = num_patches + self.num_channels = self.config.num_channels + self.projection = nn.Conv( + self.config.hidden_size, + kernel_size=(patch_size, patch_size), + strides=(patch_size, patch_size), + padding="VALID", + dtype=self.dtype, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + ) + + def __call__(self, pixel_values): + num_channels = pixel_values.shape[-1] + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + embeddings = self.projection(pixel_values) + batch_size, _, _, channels = embeddings.shape + return jnp.reshape(embeddings, (batch_size, -1, channels)) + + +class FlaxViTEmbeddings(nn.Module): + """Construct the CLS token, position and patch embeddings.""" + + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.cls_token = self.param( + "cls_token", + jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), + (1, 1, self.config.hidden_size), + ) + self.patch_embeddings = FlaxViTPatchEmbeddings(self.config, dtype=self.dtype) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = self.param( + "position_embeddings", + jax.nn.initializers.variance_scaling(self.config.initializer_range**2, "fan_in", "truncated_normal"), + (1, num_patches + 1, self.config.hidden_size), + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, pixel_values, deterministic=True): + batch_size = pixel_values.shape[0] + + embeddings = self.patch_embeddings(pixel_values) + + cls_tokens = jnp.broadcast_to(self.cls_token, (batch_size, 1, self.config.hidden_size)) + embeddings = jnp.concatenate((cls_tokens, embeddings), axis=1) + embeddings = embeddings + self.position_embeddings + embeddings = self.dropout(embeddings, deterministic=deterministic) + return embeddings + + +class FlaxViTSelfAttention(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + if self.config.hidden_size % self.config.num_attention_heads != 0: + raise ValueError( + "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads`:" + " {self.config.num_attention_heads}" + ) + + self.query = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" + ), + use_bias=self.config.qkv_bias, + ) + self.key = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" + ), + use_bias=self.config.qkv_bias, + ) + self.value = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, mode="fan_in", distribution="truncated_normal" + ), + use_bias=self.config.qkv_bias, + ) + + def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): + head_dim = self.config.hidden_size // self.config.num_attention_heads + + query_states = self.query(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + value_states = self.value(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + key_states = self.key(hidden_states).reshape( + hidden_states.shape[:2] + (self.config.num_attention_heads, head_dim) + ) + + dropout_rng = None + if not deterministic and self.config.attention_probs_dropout_prob > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + dropout_rng=dropout_rng, + dropout_rate=self.config.attention_probs_dropout_prob, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) + + outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) + return outputs + + +class FlaxViTSelfOutput(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, input_tensor, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxViTAttention(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.attention = FlaxViTSelfAttention(self.config, dtype=self.dtype) + self.output = FlaxViTSelfOutput(self.config, dtype=self.dtype) + + def __call__(self, hidden_states, deterministic=True, output_attentions: bool = False): + attn_outputs = self.attention(hidden_states, deterministic=deterministic, output_attentions=output_attentions) + attn_output = attn_outputs[0] + hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_outputs[1],) + + return outputs + + +class FlaxViTIntermediate(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.intermediate_size, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + dtype=self.dtype, + ) + self.activation = ACT2FN[self.config.hidden_act] + + def __call__(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class FlaxViTOutput(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, attention_output, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = hidden_states + attention_output + return hidden_states + + +class FlaxViTLayer(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.attention = FlaxViTAttention(self.config, dtype=self.dtype) + self.intermediate = FlaxViTIntermediate(self.config, dtype=self.dtype) + self.output = FlaxViTOutput(self.config, dtype=self.dtype) + self.layernorm_before = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.layernorm_after = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + + def __call__(self, hidden_states, deterministic: bool = True, output_attentions: bool = False): + attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in ViT, layernorm is applied before self-attention + deterministic=deterministic, + output_attentions=output_attentions, + ) + + attention_output = attention_outputs[0] + + # first residual connection + attention_output = attention_output + hidden_states + + # in ViT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(attention_output) + + hidden_states = self.intermediate(layer_output) + hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attention_outputs[1],) + return outputs + + +class FlaxViTLayerCollection(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxViTLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_hidden_layers) + ] + + def __call__( + self, + hidden_states, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states += (hidden_states,) + + layer_outputs = layer(hidden_states, deterministic=deterministic, output_attentions=output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions += (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states,) + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxViTEncoder(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layer = FlaxViTLayerCollection(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return self.layer( + hidden_states, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +class FlaxViTPooler(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + dtype=self.dtype, + ) + + def __call__(self, hidden_states): + cls_hidden_state = hidden_states[:, 0] + cls_hidden_state = self.dense(cls_hidden_state) + return nn.tanh(cls_hidden_state) + + +class FlaxViTPreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + module_class: nn.Module = None + + def __init__( + self, + config: ViTConfig, + input_shape=None, + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + if input_shape is None: + input_shape = (1, config.image_size, config.image_size, config.num_channels) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + pixel_values = jnp.zeros(input_shape, dtype=self.dtype) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init(rngs, pixel_values, return_dict=False)["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def __call__( + self, + pixel_values, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + pixel_values = jnp.transpose(pixel_values, (0, 2, 3, 1)) + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + return self.module.apply( + {"params": params or self.params}, + jnp.array(pixel_values, dtype=jnp.float32), + not train, + output_attentions, + output_hidden_states, + return_dict, + rngs=rngs, + ) + + +class FlaxViTModule(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + add_pooling_layer: bool = True + + def setup(self): + self.embeddings = FlaxViTEmbeddings(self.config, dtype=self.dtype) + self.encoder = FlaxViTEncoder(self.config, dtype=self.dtype) + self.layernorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.pooler = FlaxViTPooler(self.config, dtype=self.dtype) if self.add_pooling_layer else None + + def __call__( + self, + pixel_values, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + hidden_states = self.embeddings(pixel_values, deterministic=deterministic) + + outputs = self.encoder( + hidden_states, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = outputs[0] + hidden_states = self.layernorm(hidden_states) + pooled = self.pooler(hidden_states) if self.add_pooling_layer else None + + if not return_dict: + # if pooled is None, don't return it + if pooled is None: + return (hidden_states,) + outputs[1:] + return (hidden_states, pooled) + outputs[1:] + + return FlaxBaseModelOutputWithPooling( + last_hidden_state=hidden_states, + pooler_output=pooled, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + "The bare ViT Model transformer outputting raw hidden-states without any specific head on top.", + VIT_START_DOCSTRING, +) +class FlaxViTModel(FlaxViTPreTrainedModel): + module_class = FlaxViTModule + + +FLAX_VISION_MODEL_DOCSTRING = """ + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, FlaxViTModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") + >>> model = FlaxViTModel.from_pretrained("google/vit-base-patch16-224-in21k") + + >>> inputs = image_processor(images=image, return_tensors="np") + >>> outputs = model(**inputs) + >>> last_hidden_states = outputs.last_hidden_state + ``` +""" + +overwrite_call_docstring(FlaxViTModel, FLAX_VISION_MODEL_DOCSTRING) +append_replace_return_docstrings(FlaxViTModel, output_type=FlaxBaseModelOutputWithPooling, config_class=ViTConfig) + + +class FlaxViTForImageClassificationModule(nn.Module): + config: ViTConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.vit = FlaxViTModule(config=self.config, dtype=self.dtype, add_pooling_layer=False) + self.classifier = nn.Dense( + self.config.num_labels, + dtype=self.dtype, + kernel_init=jax.nn.initializers.variance_scaling( + self.config.initializer_range**2, "fan_in", "truncated_normal" + ), + ) + + def __call__( + self, + pixel_values=None, + deterministic: bool = True, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + logits = self.classifier(hidden_states[:, 0, :]) + + if not return_dict: + output = (logits,) + outputs[2:] + return output + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + ViT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of + the [CLS] token) e.g. for ImageNet. + """, + VIT_START_DOCSTRING, +) +class FlaxViTForImageClassification(FlaxViTPreTrainedModel): + module_class = FlaxViTForImageClassificationModule + + +FLAX_VISION_CLASSIF_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> from transformers import AutoImageProcessor, FlaxViTForImageClassification + >>> from PIL import Image + >>> import jax + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") + >>> model = FlaxViTForImageClassification.from_pretrained("google/vit-base-patch16-224") + + >>> inputs = image_processor(images=image, return_tensors="np") + >>> outputs = model(**inputs) + >>> logits = outputs.logits + + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_class_idx = jax.numpy.argmax(logits, axis=-1) + >>> print("Predicted class:", model.config.id2label[predicted_class_idx.item()]) + ``` +""" + +overwrite_call_docstring(FlaxViTForImageClassification, FLAX_VISION_CLASSIF_DOCSTRING) +append_replace_return_docstrings( + FlaxViTForImageClassification, output_type=FlaxSequenceClassifierOutput, config_class=ViTConfig +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_tf_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_tf_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..6d0c579a43db0a5d2ae18c3b592e9ff83427e1a7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_tf_vit.py @@ -0,0 +1,813 @@ +# coding=utf-8 +# Copyright 2021 Google AI, Ross Wightman, The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 ViT model.""" + + +import collections.abc +import math +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import TFBaseModelOutput, TFBaseModelOutputWithPooling, TFSequenceClassifierOutput +from ...modeling_tf_utils import ( + TFModelInputType, + TFPreTrainedModel, + TFSequenceClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_vit import ViTConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "ViTConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "google/vit-base-patch16-224-in21k" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "google/vit-base-patch16-224" +_IMAGE_CLASS_EXPECTED_OUTPUT = "Egyptian cat" + + +class TFViTEmbeddings(tf.keras.layers.Layer): + """ + Construct the CLS token, position and patch embeddings. + + """ + + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.patch_embeddings = TFViTPatchEmbeddings(config, name="patch_embeddings") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + self.config = config + + def build(self, input_shape: tf.TensorShape): + num_patches = self.patch_embeddings.num_patches + self.cls_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=get_initializer(self.config.initializer_range), + trainable=True, + name="cls_token", + ) + self.position_embeddings = self.add_weight( + shape=(1, num_patches + 1, self.config.hidden_size), + initializer=get_initializer(self.config.initializer_range), + trainable=True, + name="position_embeddings", + ) + + super().build(input_shape) + + def interpolate_pos_encoding(self, embeddings, height, width) -> tf.Tensor: + """ + This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher + resolution images. + + Source: + https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 + """ + + batch_size, seq_len, dim = shape_list(embeddings) + num_patches = seq_len - 1 + + _, num_positions, _ = shape_list(self.position_embeddings) + num_positions -= 1 + + if num_patches == num_positions and height == width: + return self.position_embeddings + class_pos_embed = self.position_embeddings[:, :1] + patch_pos_embed = self.position_embeddings[:, 1:] + h0 = height // self.config.patch_size + w0 = width // self.config.patch_size + patch_pos_embed = tf.image.resize( + images=tf.reshape( + patch_pos_embed, shape=(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) + ), + size=(h0, w0), + method="bicubic", + ) + + shape = shape_list(patch_pos_embed) + assert h0 == shape[-3] and w0 == shape[-2] + patch_pos_embed = tf.reshape(tensor=patch_pos_embed, shape=(1, -1, dim)) + return tf.concat(values=(class_pos_embed, patch_pos_embed), axis=1) + + def call( + self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False + ) -> tf.Tensor: + batch_size, num_channels, height, width = shape_list(pixel_values) + embeddings = self.patch_embeddings( + pixel_values, interpolate_pos_encoding=interpolate_pos_encoding, training=training + ) + + # add the [CLS] token to the embedded patch tokens + cls_tokens = tf.repeat(self.cls_token, repeats=batch_size, axis=0) + embeddings = tf.concat((cls_tokens, embeddings), axis=1) + + # add positional encoding to each token + if interpolate_pos_encoding: + embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) + else: + embeddings = embeddings + self.position_embeddings + + embeddings = self.dropout(embeddings, training=training) + + return embeddings + + +# Based on timm implementation, which can be found here: +# https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py +class TFViTPatchEmbeddings(tf.keras.layers.Layer): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_patches = num_patches + self.num_channels = num_channels + self.config = config + + self.projection = tf.keras.layers.Conv2D( + filters=hidden_size, + kernel_size=patch_size, + strides=patch_size, + padding="valid", + data_format="channels_last", + use_bias=True, + kernel_initializer=get_initializer(self.config.initializer_range), + bias_initializer="zeros", + name="projection", + ) + + def call( + self, pixel_values: tf.Tensor, interpolate_pos_encoding: bool = False, training: bool = False + ) -> tf.Tensor: + batch_size, num_channels, height, width = shape_list(pixel_values) + if tf.executing_eagerly() and num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + if not interpolate_pos_encoding: + if tf.executing_eagerly(): + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + + # When running on CPU, `tf.keras.layers.Conv2D` doesn't support `NCHW` format. + # So change the input format from `NCHW` to `NHWC`. + # shape = (batch_size, in_height, in_width, in_channels=num_channels) + pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) + + projection = self.projection(pixel_values) + + # Change the 2D spatial dimensions to a single temporal dimension. + # shape = (batch_size, num_patches, out_channels=embed_dim) + num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) + embeddings = tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) + + return embeddings + + +class TFViTSelfAttention(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(hidden_states)[0] + mixed_query_layer = self.query(inputs=hidden_states) + mixed_key_layer = self.key(inputs=hidden_states) + mixed_value_layer = self.value(inputs=hidden_states) + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) + value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) + attention_scores = tf.divide(attention_scores, dk) + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + attention_output = tf.matmul(attention_probs, value_layer) + attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) + outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) + + return outputs + + +class TFViTSelfOutput(tf.keras.layers.Layer): + """ + The residual connection is defined in TFViTLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + + return hidden_states + + +class TFViTAttention(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.self_attention = TFViTSelfAttention(config, name="attention") + self.dense_output = TFViTSelfOutput(config, name="output") + + def prune_heads(self, heads): + raise NotImplementedError + + def call( + self, + input_tensor: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self_attention( + hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training + ) + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=input_tensor, training=training + ) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + + return outputs + + +class TFViTIntermediate(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +class TFViTOutput(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + hidden_states = hidden_states + input_tensor + + return hidden_states + + +class TFViTLayer(tf.keras.layers.Layer): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFViTAttention(config, name="attention") + self.intermediate = TFViTIntermediate(config, name="intermediate") + self.vit_output = TFViTOutput(config, name="output") + + self.layernorm_before = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_before" + ) + self.layernorm_after = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_after" + ) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + # in ViT, layernorm is applied before self-attention + input_tensor=self.layernorm_before(inputs=hidden_states), + head_mask=head_mask, + output_attentions=output_attentions, + training=training, + ) + attention_output = attention_outputs[0] + + # first residual connection + hidden_states = attention_output + hidden_states + + # in ViT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(inputs=hidden_states) + + intermediate_output = self.intermediate(hidden_states=layer_output) + + # second residual connection is done here + layer_output = self.vit_output( + hidden_states=intermediate_output, input_tensor=hidden_states, training=training + ) + outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them + + return outputs + + +class TFViTEncoder(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.layer = [TFViTLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + output_hidden_states: bool, + return_dict: bool, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states=hidden_states, + head_mask=head_mask[i], + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +@keras_serializable +class TFViTMainLayer(tf.keras.layers.Layer): + config_class = ViTConfig + + def __init__(self, config: ViTConfig, add_pooling_layer: bool = True, **kwargs): + super().__init__(**kwargs) + + self.config = config + + self.embeddings = TFViTEmbeddings(config, name="embeddings") + self.encoder = TFViTEncoder(config, name="encoder") + self.layernorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") + self.pooler = TFViTPooler(config, name="pooler") if add_pooling_layer else None + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor]]: + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + embedding_output = self.embeddings( + pixel_values=pixel_values, + interpolate_pos_encoding=interpolate_pos_encoding, + training=training, + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + encoder_outputs = self.encoder( + hidden_states=embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(inputs=sequence_output) + pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return TFBaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class TFViTPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + """ + Dummy inputs to build the network. + + Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + VISION_DUMMY_INPUTS = tf.random.uniform( + shape=(3, self.config.num_channels, self.config.image_size, self.config.image_size), dtype=tf.float32 + ) + return {"pixel_values": tf.constant(VISION_DUMMY_INPUTS)} + + @tf.function( + input_signature=[ + { + "pixel_values": tf.TensorSpec((None, None, None, None), tf.float32, name="pixel_values"), + } + ] + ) + def serving(self, inputs): + """ + Method used for serving the model. + + Args: + inputs (`Dict[str, tf.Tensor]`): + The input of the saved model as a dictionary of tensors. + """ + output = self.call(inputs) + + return self.serving_output(output) + + +VIT_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`ViTConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +VIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` ``Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + interpolate_pos_encoding (`bool`, *optional*): + Whether to interpolate the pre-trained position encodings. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False``): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare ViT Model transformer outputting raw hidden-states without any specific head on top.", + VIT_START_DOCSTRING, +) +class TFViTModel(TFViTPreTrainedModel): + def __init__(self, config: ViTConfig, *inputs, add_pooling_layer=True, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.vit = TFViTMainLayer(config, add_pooling_layer=add_pooling_layer, name="vit") + + @unpack_inputs + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPooling, Tuple[tf.Tensor]]: + outputs = self.vit( + pixel_values=pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFBaseModelOutputWithPooling) -> TFBaseModelOutputWithPooling: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutputWithPooling( + last_hidden_state=output.last_hidden_state, + pooler_output=output.pooler_output, + hidden_states=hs, + attentions=attns, + ) + + +class TFViTPooler(tf.keras.layers.Layer): + def __init__(self, config: ViTConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + activation="tanh", + name="dense", + ) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(inputs=first_token_tensor) + + return pooled_output + + +@add_start_docstrings( + """ + ViT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of + the [CLS] token) e.g. for ImageNet. + + + + Note that it's possible to fine-tune ViT on higher resolution images than the ones it has been trained on, by + setting `interpolate_pos_encoding` to `True` in the forward of the model. This will interpolate the pre-trained + position embeddings to the higher resolution. + + + """, + VIT_START_DOCSTRING, +) +class TFViTForImageClassification(TFViTPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config: ViTConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.num_labels = config.num_labels + self.vit = TFViTMainLayer(config, add_pooling_layer=False, name="vit") + + # Classifier head + self.classifier = tf.keras.layers.Dense( + units=config.num_labels, + kernel_initializer=get_initializer(config.initializer_range), + name="classifier", + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + outputs = self.vit( + pixel_values=pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + logits = self.classifier(inputs=sequence_output[:, 0, :]) + loss = None if labels is None else self.hf_compute_loss(labels=labels, logits=logits) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..474b92f72dd6b79e199df0cb2f559c3b09b958b5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit/modeling_vit.py @@ -0,0 +1,844 @@ +# coding=utf-8 +# Copyright 2021 Google AI, Ross Wightman, The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch ViT model.""" + + +import collections.abc +import math +from typing import Dict, List, Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPooling, + ImageClassifierOutput, + MaskedImageModelingOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_vit import ViTConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "ViTConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "google/vit-base-patch16-224-in21k" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "google/vit-base-patch16-224" +_IMAGE_CLASS_EXPECTED_OUTPUT = "Egyptian cat" + + +VIT_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "google/vit-base-patch16-224", + # See all ViT models at https://huggingface.co/models?filter=vit +] + + +class ViTEmbeddings(nn.Module): + """ + Construct the CLS token, position and patch embeddings. Optionally, also the mask token. + """ + + def __init__(self, config: ViTConfig, use_mask_token: bool = False) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.randn(1, 1, config.hidden_size)) + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) if use_mask_token else None + self.patch_embeddings = ViTPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = nn.Parameter(torch.randn(1, num_patches + 1, config.hidden_size)) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.config = config + + def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor: + """ + This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher + resolution images. + + Source: + https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 + """ + + num_patches = embeddings.shape[1] - 1 + num_positions = self.position_embeddings.shape[1] - 1 + if num_patches == num_positions and height == width: + return self.position_embeddings + class_pos_embed = self.position_embeddings[:, 0] + patch_pos_embed = self.position_embeddings[:, 1:] + dim = embeddings.shape[-1] + h0 = height // self.config.patch_size + w0 = width // self.config.patch_size + # we add a small number to avoid floating point error in the interpolation + # see discussion at https://github.com/facebookresearch/dino/issues/8 + h0, w0 = h0 + 0.1, w0 + 0.1 + patch_pos_embed = patch_pos_embed.reshape(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) + patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2) + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, + scale_factor=(h0 / math.sqrt(num_positions), w0 / math.sqrt(num_positions)), + mode="bicubic", + align_corners=False, + ) + assert int(h0) == patch_pos_embed.shape[-2] and int(w0) == patch_pos_embed.shape[-1] + patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) + return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) + + def forward( + self, + pixel_values: torch.Tensor, + bool_masked_pos: Optional[torch.BoolTensor] = None, + interpolate_pos_encoding: bool = False, + ) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + embeddings = self.patch_embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) + + if bool_masked_pos is not None: + seq_length = embeddings.shape[1] + mask_tokens = self.mask_token.expand(batch_size, seq_length, -1) + # replace the masked visual tokens by mask_tokens + mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + # add the [CLS] token to the embedded patch tokens + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, embeddings), dim=1) + + # add positional encoding to each token + if interpolate_pos_encoding: + embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) + else: + embeddings = embeddings + self.position_embeddings + + embeddings = self.dropout(embeddings) + + return embeddings + + +class ViTPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor, interpolate_pos_encoding: bool = False) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + f" Expected {self.num_channels} but got {num_channels}." + ) + if not interpolate_pos_encoding: + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + embeddings = self.projection(pixel_values).flatten(2).transpose(1, 2) + return embeddings + + +class ViTSelfAttention(nn.Module): + def __init__(self, config: ViTConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +class ViTSelfOutput(nn.Module): + """ + The residual connection is defined in ViTLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +class ViTAttention(nn.Module): + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.attention = ViTSelfAttention(config) + self.output = ViTSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +class ViTIntermediate(nn.Module): + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +class ViTOutput(nn.Module): + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +class ViTLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = ViTAttention(config) + self.intermediate = ViTIntermediate(config) + self.output = ViTOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in ViT, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + hidden_states = attention_output + hidden_states + + # in ViT, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +class ViTEncoder(nn.Module): + def __init__(self, config: ViTConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([ViTLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class ViTPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + _no_split_modules = [] + + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Upcast the input in `fp32` and cast it back to desired `dtype` to avoid + # `trunc_normal_cpu` not implemented in `half` issues + module.weight.data = nn.init.trunc_normal_( + module.weight.data.to(torch.float32), mean=0.0, std=self.config.initializer_range + ).to(module.weight.dtype) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, ViTEmbeddings): + module.position_embeddings.data = nn.init.trunc_normal_( + module.position_embeddings.data.to(torch.float32), + mean=0.0, + std=self.config.initializer_range, + ).to(module.position_embeddings.dtype) + + module.cls_token.data = nn.init.trunc_normal_( + module.cls_token.data.to(torch.float32), + mean=0.0, + std=self.config.initializer_range, + ).to(module.cls_token.dtype) + + def _set_gradient_checkpointing(self, module: ViTEncoder, value: bool = False) -> None: + if isinstance(module, ViTEncoder): + module.gradient_checkpointing = value + + +VIT_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`ViTConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +VIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + interpolate_pos_encoding (`bool`, *optional*): + Whether to interpolate the pre-trained position encodings. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare ViT Model transformer outputting raw hidden-states without any specific head on top.", + VIT_START_DOCSTRING, +) +class ViTModel(ViTPreTrainedModel): + def __init__(self, config: ViTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False): + super().__init__(config) + self.config = config + + self.embeddings = ViTEmbeddings(config, use_mask_token=use_mask_token) + self.encoder = ViTEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.pooler = ViTPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> ViTPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + # TODO: maybe have a cleaner way to cast the input (from `ImageProcessor` side?) + expected_dtype = self.embeddings.patch_embeddings.projection.weight.dtype + if pixel_values.dtype != expected_dtype: + pixel_values = pixel_values.to(expected_dtype) + + embedding_output = self.embeddings( + pixel_values, bool_masked_pos=bool_masked_pos, interpolate_pos_encoding=interpolate_pos_encoding + ) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class ViTPooler(nn.Module): + def __init__(self, config: ViTConfig): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +@add_start_docstrings( + """ViT Model with a decoder on top for masked image modeling, as proposed in [SimMIM](https://arxiv.org/abs/2111.09886). + + + + Note that we provide a script to pre-train this model on custom data in our [examples + directory](https://github.com/huggingface/transformers/tree/main/examples/pytorch/image-pretraining). + + + """, + VIT_START_DOCSTRING, +) +class ViTForMaskedImageModeling(ViTPreTrainedModel): + def __init__(self, config: ViTConfig) -> None: + super().__init__(config) + + self.vit = ViTModel(config, add_pooling_layer=False, use_mask_token=True) + + self.decoder = nn.Sequential( + nn.Conv2d( + in_channels=config.hidden_size, + out_channels=config.encoder_stride**2 * config.num_channels, + kernel_size=1, + ), + nn.PixelShuffle(config.encoder_stride), + ) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=MaskedImageModelingOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, MaskedImageModelingOutput]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + + Returns: + + Examples: + ```python + >>> from transformers import AutoImageProcessor, ViTForMaskedImageModeling + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") + >>> model = ViTForMaskedImageModeling.from_pretrained("google/vit-base-patch16-224-in21k") + + >>> num_patches = (model.config.image_size // model.config.patch_size) ** 2 + >>> pixel_values = image_processor(images=image, return_tensors="pt").pixel_values + >>> # create random boolean mask of shape (batch_size, num_patches) + >>> bool_masked_pos = torch.randint(low=0, high=2, size=(1, num_patches)).bool() + + >>> outputs = model(pixel_values, bool_masked_pos=bool_masked_pos) + >>> loss, reconstructed_pixel_values = outputs.loss, outputs.reconstruction + >>> list(reconstructed_pixel_values.shape) + [1, 3, 224, 224] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values, + bool_masked_pos=bool_masked_pos, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + # Reshape to (batch_size, num_channels, height, width) + sequence_output = sequence_output[:, 1:] + batch_size, sequence_length, num_channels = sequence_output.shape + height = width = math.floor(sequence_length**0.5) + sequence_output = sequence_output.permute(0, 2, 1).reshape(batch_size, num_channels, height, width) + + # Reconstruct pixel values + reconstructed_pixel_values = self.decoder(sequence_output) + + masked_im_loss = None + if bool_masked_pos is not None: + size = self.config.image_size // self.config.patch_size + bool_masked_pos = bool_masked_pos.reshape(-1, size, size) + mask = ( + bool_masked_pos.repeat_interleave(self.config.patch_size, 1) + .repeat_interleave(self.config.patch_size, 2) + .unsqueeze(1) + .contiguous() + ) + reconstruction_loss = nn.functional.l1_loss(pixel_values, reconstructed_pixel_values, reduction="none") + masked_im_loss = (reconstruction_loss * mask).sum() / (mask.sum() + 1e-5) / self.config.num_channels + + if not return_dict: + output = (reconstructed_pixel_values,) + outputs[1:] + return ((masked_im_loss,) + output) if masked_im_loss is not None else output + + return MaskedImageModelingOutput( + loss=masked_im_loss, + reconstruction=reconstructed_pixel_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + ViT Model transformer with an image classification head on top (a linear layer on top of the final hidden state of + the [CLS] token) e.g. for ImageNet. + + + + Note that it's possible to fine-tune ViT on higher resolution images than the ones it has been trained on, by + setting `interpolate_pos_encoding` to `True` in the forward of the model. This will interpolate the pre-trained + position embeddings to the higher resolution. + + + """, + VIT_START_DOCSTRING, +) +class ViTForImageClassification(ViTPreTrainedModel): + def __init__(self, config: ViTConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.vit = ViTModel(config, add_pooling_layer=False) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=ImageClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output[:, 0, :]) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/image_processing_vit_hybrid.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/image_processing_vit_hybrid.py new file mode 100644 index 0000000000000000000000000000000000000000..a45ece6e5a387cc4b5ca5fe361df1814492f0af0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/image_processing_vit_hybrid.py @@ -0,0 +1,337 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for ViT hybrid.""" + +from typing import Dict, List, Optional, Union + +import numpy as np + +from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict +from ...image_transforms import ( + center_crop, + convert_to_rgb, + get_resize_output_image_size, + normalize, + rescale, + resize, + to_channel_dimension_format, +) +from ...image_utils import ( + OPENAI_CLIP_MEAN, + OPENAI_CLIP_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + make_list_of_images, + to_numpy_array, + valid_images, +) +from ...utils import TensorType, is_vision_available, logging + + +logger = logging.get_logger(__name__) + + +if is_vision_available(): + import PIL + + +class ViTHybridImageProcessor(BaseImageProcessor): + r""" + Constructs a ViT Hybrid image processor. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Whether to resize the image's (height, width) dimensions to the specified `size`. Can be overridden by + `do_resize` in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 224}`): + Size of the image after resizing. The shortest edge of the image is resized to size["shortest_edge"], with + the longest edge resized to keep the input aspect ratio. Can be overridden by `size` in the `preprocess` + method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use if resizing the image. Can be overridden by `resample` in the `preprocess` method. + do_center_crop (`bool`, *optional*, defaults to `True`): + Whether to center crop the image to the specified `crop_size`. Can be overridden by `do_center_crop` in the + `preprocess` method. + crop_size (`Dict[str, int]` *optional*, defaults to 224): + Size of the output image after applying `center_crop`. Can be overridden by `crop_size` in the `preprocess` + method. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by `do_rescale` in + the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by `rescale_factor` in the `preprocess` + method. + do_normalize: + Whether to normalize the image. Can be overridden by `do_normalize` in the `preprocess` method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_MEAN`): + Mean to use if normalizing the image. This is a float or list of floats the length of the number of + channels in the image. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_STANDARD_STD`): + Image standard deviation. + do_convert_rgb (`bool`, *optional*, defaults to `True`): + Standard deviation to use if normalizing the image. This is a float or list of floats the length of the + number of channels in the image. Can be overridden by the `image_std` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values"] + + def __init__( + self, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BICUBIC, + do_center_crop: bool = True, + crop_size: Dict[str, int] = None, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_convert_rgb: bool = True, + **kwargs, + ) -> None: + super().__init__(**kwargs) + size = size if size is not None else {"shortest_edge": 224} + size = get_size_dict(size, default_to_square=False) + crop_size = crop_size if crop_size is not None else {"height": 224, "width": 224} + crop_size = get_size_dict(crop_size, default_to_square=True, param_name="crop_size") + + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else OPENAI_CLIP_MEAN + self.image_std = image_std if image_std is not None else OPENAI_CLIP_STD + self.do_convert_rgb = do_convert_rgb + + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BICUBIC, + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize an image. The shortest edge of the image is resized to size["shortest_edge"], with the longest edge + resized to keep the input aspect ratio. + + Args: + image (`np.ndarray`): + Image to resize. + size (`Dict[str, int]`): + Size of the output image. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BICUBIC`): + Resampling filter to use when resiizing the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size, default_to_square=False) + if "shortest_edge" not in size: + raise ValueError(f"The `size` parameter must contain the key `shortest_edge`. Got {size.keys()}") + output_size = get_resize_output_image_size(image, size=size["shortest_edge"], default_to_square=False) + return resize(image, size=output_size, resample=resample, data_format=data_format, **kwargs) + + def center_crop( + self, + image: np.ndarray, + size: Dict[str, int], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Center crop an image. If the image is too small to be cropped to the size given, it will be padded (so the + returned result will always be of size `size`). + + Args: + image (`np.ndarray`): + Image to center crop. + size (`Dict[str, int]`): + Size of the output image in the form of a dictionary with keys `height` and `width`. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + size = get_size_dict(size) + if "height" not in size or "width" not in size: + raise ValueError(f"The `size` parameter must contain the keys (height, width). Got {size.keys()}") + return center_crop(image, size=(size["height"], size["width"]), data_format=data_format, **kwargs) + + def rescale( + self, + image: np.ndarray, + scale: Union[int, float], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ): + """ + Rescale an image by a scale factor. image = image * scale. + + Args: + image (`np.ndarray`): + Image to rescale. + scale (`int` or `float`): + Scale to apply to the image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return rescale(image, scale=scale, data_format=data_format, **kwargs) + + def normalize( + self, + image: np.ndarray, + mean: Union[float, List[float]], + std: Union[float, List[float]], + data_format: Optional[Union[str, ChannelDimension]] = None, + **kwargs, + ) -> np.ndarray: + """ + Normalize an image. image = (image - image_mean) / image_std. + + Args: + image (`np.ndarray`): + Image to normalize. + image_mean (`float` or `List[float]`): + Image mean. + image_std (`float` or `List[float]`): + Image standard deviation. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + return normalize(image, mean=mean, std=std, data_format=data_format, **kwargs) + + def preprocess( + self, + images: ImageInput, + do_resize: bool = None, + size: Dict[str, int] = None, + resample: PILImageResampling = None, + do_center_crop: bool = None, + crop_size: int = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_convert_rgb: bool = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> PIL.Image.Image: + """ + Preprocess an image or batch of images. + + Args: + images (`ImageInput`): + Image to preprocess. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Size of the image after resizing. Shortest edge of the image is resized to size["shortest_edge"], with + the longest edge resized to keep the input aspect ratio. + resample (`int`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only + has an effect if `do_resize` is set to `True`. + do_center_crop (`bool`, *optional*, defaults to `self.do_center_crop`): + Whether to center crop the image. + crop_size (`Dict[str, int]`, *optional*, defaults to `self.crop_size`): + Size of the center crop. Only has an effect if `do_center_crop` is set to `True`. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to + `True`. + do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): + Whether to convert the image to RGB. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - Unset: defaults to the channel dimension format of the input image. + """ + do_resize = do_resize if do_resize is not None else self.do_resize + size = size if size is not None else self.size + size = get_size_dict(size, param_name="size", default_to_square=False) + resample = resample if resample is not None else self.resample + do_center_crop = do_center_crop if do_center_crop is not None else self.do_center_crop + crop_size = crop_size if crop_size is not None else self.crop_size + crop_size = get_size_dict(crop_size, param_name="crop_size", default_to_square=True) + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = rescale_factor if rescale_factor is not None else self.rescale_factor + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + + images = make_list_of_images(images) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + if do_resize and size is None: + raise ValueError("Size must be specified if do_resize is True.") + + if do_center_crop and crop_size is None: + raise ValueError("Crop size must be specified if do_center_crop is True.") + + if do_rescale and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + # PIL RGBA images are converted to RGB + if do_convert_rgb: + images = [convert_to_rgb(image) for image in images] + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if do_resize: + images = [self.resize(image=image, size=size, resample=resample) for image in images] + + if do_center_crop: + images = [self.center_crop(image=image, size=crop_size) for image in images] + + if do_rescale: + images = [self.rescale(image=image, scale=rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image=image, mean=image_mean, std=image_std) for image in images] + + images = [to_channel_dimension_format(image, data_format) for image in images] + + data = {"pixel_values": images} + return BatchFeature(data=data, tensor_type=return_tensors) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/modeling_vit_hybrid.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/modeling_vit_hybrid.py new file mode 100644 index 0000000000000000000000000000000000000000..051d431946a852790f46efe105257b2a7bc580f7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_hybrid/modeling_vit_hybrid.py @@ -0,0 +1,737 @@ +# coding=utf-8 +# Copyright 2022 Google AI, Ross Wightman, The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch ViT Hybrid model.""" + + +import collections.abc +import math +from typing import Dict, List, Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from ..auto import AutoBackbone +from .configuration_vit_hybrid import ViTHybridConfig + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "ViTHybridConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "google/vit-hybrid-base-bit-384" +_EXPECTED_OUTPUT_SHAPE = [1, 197, 768] + +# Image classification docstring +_IMAGE_CLASS_CHECKPOINT = "google/vit-hybrid-base-bit-384" +_IMAGE_CLASS_EXPECTED_OUTPUT = "tabby, tabby cat" + + +VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "google/vit-hybrid-base-bit-384", + # See all ViT hybrid models at https://huggingface.co/models?filter=vit-hybrid +] + + +class ViTHybridEmbeddings(nn.Module): + """ + Construct the CLS token, position and patch embeddings. Optionally, also the mask token. + """ + + # Copied from transformers.models.vit.modeling_vit.ViTEmbeddings.__init__ with ViT->ViTHybrid + def __init__(self, config: ViTHybridConfig, use_mask_token: bool = False) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.randn(1, 1, config.hidden_size)) + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) if use_mask_token else None + self.patch_embeddings = ViTHybridPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = nn.Parameter(torch.randn(1, num_patches + 1, config.hidden_size)) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.config = config + + def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor: + """ + This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher + resolution images. + + Source: + https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 + """ + + num_patches = embeddings.shape[1] - 1 + num_positions = self.position_embeddings.shape[1] - 1 + if num_patches == num_positions and height == width: + return self.position_embeddings + class_pos_embed = self.position_embeddings[:, 0] + patch_pos_embed = self.position_embeddings[:, 1:] + dim = embeddings.shape[-1] + height = height // self.config.patch_size + width = width // self.config.patch_size + # we add a small number to avoid floating point error in the interpolation + # see discussion at https://github.com/facebookresearch/dino/issues/8 + height, width = height + 0.1, width + 0.1 + patch_pos_embed = patch_pos_embed.reshape(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) + patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2) + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, + scale_factor=(height / math.sqrt(num_positions), width / math.sqrt(num_positions)), + mode="bicubic", + align_corners=False, + ) + if int(height) != patch_pos_embed.shape[-2] or int(width) != patch_pos_embed.shape[-1]: + raise ValueError(f"Invalid height or width: {height}, {width}") + patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) + return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) + + def forward( + self, + pixel_values: torch.Tensor, + bool_masked_pos: Optional[torch.BoolTensor] = None, + interpolate_pos_encoding: bool = False, + ) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + embeddings = self.patch_embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) + + if bool_masked_pos is not None: + seq_length = embeddings.shape[1] + mask_tokens = self.mask_token.expand(batch_size, seq_length, -1) + # replace the masked visual tokens by mask_tokens + mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + # add the [CLS] token to the embedded patch tokens + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, embeddings), dim=1) + + # add positional encoding to each token + if interpolate_pos_encoding: + embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) + else: + embeddings = embeddings + self.position_embeddings + + embeddings = self.dropout(embeddings) + + return embeddings + + +class ViTHybridPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config, feature_size=None): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + + self.backbone = AutoBackbone.from_config(config.backbone_config) + if self.backbone.config.model_type != "bit": + raise ValueError(f"Backbone model type {self.backbone.model_type} is not supported.") + feature_dim = self.backbone.channels[-1] + + if feature_size is None: + feature_map = config.backbone_featmap_shape + + feature_size = feature_map[-2:] + feature_dim = feature_map[1] + else: + feature_size = ( + feature_size if isinstance(feature_size, collections.abc.Iterable) else (feature_size, feature_size) + ) + feature_dim = self.backbone.channels[-1] + + self.grid_size = (feature_size[0] // patch_size[0], feature_size[1] // patch_size[1]) + self.num_patches = self.grid_size[0] * self.grid_size[1] + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + + self.projection = nn.Conv2d(feature_dim, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor, interpolate_pos_encoding: bool = False) -> torch.Tensor: + _, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + if not interpolate_pos_encoding: + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + + features = self.backbone(pixel_values).feature_maps[-1] + embeddings = self.projection(features).flatten(2).transpose(1, 2) + + return embeddings + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfAttention with ViT->ViTHybrid +class ViTHybridSelfAttention(nn.Module): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfOutput with ViT->ViTHybrid +class ViTHybridSelfOutput(nn.Module): + """ + The residual connection is defined in ViTHybridLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTAttention with ViT->ViTHybrid +class ViTHybridAttention(nn.Module): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.attention = ViTHybridSelfAttention(config) + self.output = ViTHybridSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTIntermediate with ViT->ViTHybrid +class ViTHybridIntermediate(nn.Module): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTOutput with ViT->ViTHybrid +class ViTHybridOutput(nn.Module): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +class ViTHybridLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = ViTHybridAttention(config) + self.intermediate = ViTHybridIntermediate(config) + self.output = ViTHybridOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in ViTHybrid, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + # We assign to correct device for `accelerate`, check: https://github.com/huggingface/transformers/pull/20705/ + hidden_states = attention_output + hidden_states.to(attention_output.device) + + # in ViTHybrid, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTEncoder with ViT->ViTHybrid +class ViTHybridEncoder(nn.Module): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([ViTHybridLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +# Copied from transformers.models.vit.modeling_vit.ViTPreTrainedModel with ViT->ViTHybrid +class ViTHybridPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTHybridConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + _no_split_modules = [] + + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Upcast the input in `fp32` and cast it back to desired `dtype` to avoid + # `trunc_normal_cpu` not implemented in `half` issues + module.weight.data = nn.init.trunc_normal_( + module.weight.data.to(torch.float32), mean=0.0, std=self.config.initializer_range + ).to(module.weight.dtype) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, ViTHybridEmbeddings): + module.position_embeddings.data = nn.init.trunc_normal_( + module.position_embeddings.data.to(torch.float32), + mean=0.0, + std=self.config.initializer_range, + ).to(module.position_embeddings.dtype) + + module.cls_token.data = nn.init.trunc_normal_( + module.cls_token.data.to(torch.float32), + mean=0.0, + std=self.config.initializer_range, + ).to(module.cls_token.dtype) + + def _set_gradient_checkpointing(self, module: ViTHybridEncoder, value: bool = False) -> None: + if isinstance(module, ViTHybridEncoder): + module.gradient_checkpointing = value + + +VIT_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`ViTHybridConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +VIT_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`ViTHybridImageProcessor.__call__`] for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare ViT Hybrid Model transformer outputting raw hidden-states without any specific head on top.", + VIT_START_DOCSTRING, +) +# Copied from transformers.models.vit.modeling_vit.ViTModel with ViT->ViTHybrid +class ViTHybridModel(ViTHybridPreTrainedModel): + def __init__(self, config: ViTHybridConfig, add_pooling_layer: bool = True, use_mask_token: bool = False): + super().__init__(config) + self.config = config + + self.embeddings = ViTHybridEmbeddings(config, use_mask_token=use_mask_token) + self.encoder = ViTHybridEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.pooler = ViTHybridPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> ViTHybridPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + # TODO: maybe have a cleaner way to cast the input (from `ImageProcessor` side?) + expected_dtype = self.embeddings.patch_embeddings.projection.weight.dtype + if pixel_values.dtype != expected_dtype: + pixel_values = pixel_values.to(expected_dtype) + + embedding_output = self.embeddings( + pixel_values, bool_masked_pos=bool_masked_pos, interpolate_pos_encoding=interpolate_pos_encoding + ) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Copied from transformers.models.vit.modeling_vit.ViTPooler with ViT->ViTHybrid +class ViTHybridPooler(nn.Module): + def __init__(self, config: ViTHybridConfig): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +@add_start_docstrings( + """ + ViT Hybrid Model transformer with an image classification head on top (a linear layer on top of the final hidden + state of the [CLS] token) e.g. for ImageNet. + """, + VIT_START_DOCSTRING, +) +# Copied from transformers.models.vit.modeling_vit.ViTForImageClassification with ViT->ViTHybrid +class ViTHybridForImageClassification(ViTHybridPreTrainedModel): + def __init__(self, config: ViTHybridConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.vit = ViTHybridModel(config, add_pooling_layer=False) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(VIT_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_IMAGE_CLASS_CHECKPOINT, + output_type=ImageClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the image classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output[:, 0, :]) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/configuration_vit_mae.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/configuration_vit_mae.py new file mode 100644 index 0000000000000000000000000000000000000000..4c065421a9f19d53ed1e851fc144f168b2d7aef4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/configuration_vit_mae.py @@ -0,0 +1,141 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" ViT MAE model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +VIT_MAE_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/vit-mae-base": "https://huggingface.co/facebook/vit-mae-base/resolve/main/config.json", + # See all ViT MAE models at https://huggingface.co/models?filter=vit-mae +} + + +class ViTMAEConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`ViTMAEModel`]. It is used to instantiate an ViT + MAE model according to the specified arguments, defining the model architecture. Instantiating a configuration with + the defaults will yield a similar configuration to that of the ViT + [facebook/vit-mae-base](https://huggingface.co/facebook/vit-mae-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + image_size (`int`, *optional*, defaults to 224): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 16): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + decoder_num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the decoder. + decoder_hidden_size (`int`, *optional*, defaults to 512): + Dimensionality of the decoder. + decoder_num_hidden_layers (`int`, *optional*, defaults to 8): + Number of hidden layers in the decoder. + decoder_intermediate_size (`int`, *optional*, defaults to 2048): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the decoder. + mask_ratio (`float`, *optional*, defaults to 0.75): + The ratio of the number of masked tokens in the input sequence. + norm_pix_loss (`bool`, *optional*, defaults to `False`): + Whether or not to train with normalized pixels (see Table 3 in the paper). Using normalized pixels improved + representation quality in the experiments of the authors. + + Example: + + ```python + >>> from transformers import ViTMAEConfig, ViTMAEModel + + >>> # Initializing a ViT MAE vit-mae-base style configuration + >>> configuration = ViTMAEConfig() + + >>> # Initializing a model (with random weights) from the vit-mae-base style configuration + >>> model = ViTMAEModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "vit_mae" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + image_size=224, + patch_size=16, + num_channels=3, + qkv_bias=True, + decoder_num_attention_heads=16, + decoder_hidden_size=512, + decoder_num_hidden_layers=8, + decoder_intermediate_size=2048, + mask_ratio=0.75, + norm_pix_loss=False, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias + self.decoder_num_attention_heads = decoder_num_attention_heads + self.decoder_hidden_size = decoder_hidden_size + self.decoder_num_hidden_layers = decoder_num_hidden_layers + self.decoder_intermediate_size = decoder_intermediate_size + self.mask_ratio = mask_ratio + self.norm_pix_loss = norm_pix_loss diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/modeling_tf_vit_mae.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/modeling_tf_vit_mae.py new file mode 100644 index 0000000000000000000000000000000000000000..afb40478ccdae1342e92992efd5ad11a515349c1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_mae/modeling_tf_vit_mae.py @@ -0,0 +1,1184 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 ViT MAE (masked autoencoder) model.""" + +import collections.abc +import math +from copy import deepcopy +from dataclasses import dataclass +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...file_utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + replace_return_docstrings, +) +from ...modeling_tf_outputs import TFBaseModelOutput +from ...modeling_tf_utils import ( + TFModelInputType, + TFPreTrainedModel, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import logging +from .configuration_vit_mae import ViTMAEConfig + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "ViTMAEConfig" +_CHECKPOINT_FOR_DOC = "facebook/vit-mae-base" + + +@dataclass +class TFViTMAEModelOutput(ModelOutput): + """ + Class for TFViTMAEModel's outputs, with potential hidden states and attentions. + + Args: + last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Tensor indicating which patches are masked (1) and which are not (0). + ids_restore (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Tensor containing the original index of the (shuffled) masked patches. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus + the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + last_hidden_state: tf.Tensor = None + mask: tf.Tensor = None + ids_restore: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFViTMAEDecoderOutput(ModelOutput): + """ + Class for TFViTMAEDecoder's outputs, with potential hidden states and attentions. + + Args: + logits (`tf.Tensor` of shape `(batch_size, sequence_length, patch_size ** 2 * num_channels)`): + Pixel reconstruction logits. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus + the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + logits: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFViTMAEForPreTrainingOutput(ModelOutput): + """ + Class for TFViTMAEForPreTraining's outputs, with potential hidden states and attentions. + + Args: + loss (`tf.Tensor` of shape `(1,)`): + Pixel reconstruction loss. + logits (`tf.Tensor` of shape `(batch_size, sequence_length, patch_size ** 2 * num_channels)`): + Pixel reconstruction logits. + mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Tensor indicating which patches are masked (1) and which are not (0). + ids_restore (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Tensor containing the original index of the (shuffled) masked patches. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. Hidden-states of the model at the output of each layer plus + the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + loss: Optional[tf.Tensor] = None + logits: tf.Tensor = None + mask: tf.Tensor = None + ids_restore: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +def get_2d_sincos_pos_embed(embed_dim, grid_size, add_cls_token=False): + """ + Create 2D sin/cos positional embeddings. + + Args: + embed_dim (`int`): + Embedding dimension. + grid_size (`int`): + The grid height and width. + add_cls_token (`bool`, *optional*, defaults to `False`): + Whether or not to add a classification (CLS) token. + + Returns: + (`tf.Tensor` of shape (grid_size*grid_size, embed_dim) or (1+grid_size*grid_size, embed_dim): the position + embeddings (with or without classification token) + """ + grid_h = tf.range(grid_size, dtype=tf.float32) + grid_w = tf.range(grid_size, dtype=tf.float32) + grid = tf.meshgrid(grid_w, grid_h) # here w goes first + grid = tf.stack(grid, axis=0) + + grid = tf.reshape(grid, [2, 1, grid_size, grid_size]) + pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid) + if add_cls_token: + pos_embed = tf.concat([tf.zeros((1, embed_dim)), pos_embed], axis=0) + return pos_embed + + +def get_2d_sincos_pos_embed_from_grid(embed_dim, grid): + if embed_dim % 2 != 0: + raise ValueError("embed_dim must be even") + + # use half of dimensions to encode grid_h + emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2) + emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2) + + emb = tf.concat([emb_h, emb_w], axis=1) # (H*W, D) + return emb + + +def get_1d_sincos_pos_embed_from_grid(embed_dim, pos): + """ + embed_dim: output dimension for each position pos: a list of positions to be encoded: size (M,) out: (M, D) + """ + if embed_dim % 2 != 0: + raise ValueError("embed_dim must be even") + + omega = tf.range(embed_dim // 2, dtype="float32") + omega /= embed_dim / 2.0 + omega = 1.0 / 10000**omega # (D/2,) + + pos = tf.reshape(pos, [-1]) # (M,) + out = tf.einsum("m,d->md", pos, omega) # (M, D/2), outer product + + # half of the positions get sinusoidal pattern and the rest gets + # cosine pattern and then they are concatenated + emb_sin = tf.sin(out) # (M, D/2) + emb_cos = tf.cos(out) # (M, D/2) + + emb = tf.concat([emb_sin, emb_cos], axis=1) # (M, D) + return emb + + +class TFViTMAEEmbeddings(tf.keras.layers.Layer): + """ + Construct the CLS token, position and patch embeddings. + + """ + + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.patch_embeddings = TFViTMAEPatchEmbeddings(config, name="patch_embeddings") + self.num_patches = self.patch_embeddings.num_patches + + self.config = config + + def build(self, input_shape: tf.TensorShape): + self.cls_token = self.add_weight( + shape=(1, 1, self.config.hidden_size), + initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), + trainable=True, + name="cls_token", + ) + self.position_embeddings = self.add_weight( + shape=(1, self.num_patches + 1, self.config.hidden_size), + initializer="zeros", + trainable=False, # fixed sin-cos embedding + name="position_embeddings", + ) + pos_embed = get_2d_sincos_pos_embed( + self.position_embeddings.shape[-1], + int(self.patch_embeddings.num_patches**0.5), + add_cls_token=True, + )[None, ...] + self.position_embeddings.assign(pos_embed) + + super().build(input_shape) + + def random_masking(self, sequence: tf.Tensor, noise: Optional[tf.Tensor] = None): + """ + Perform per-sample random masking by per-sample shuffling. Per-sample shuffling is done by argsort random + noise. + + Args: + sequence (`tf.Tensor` of shape `(batch_size, sequence_length, dim)`) + noise (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*) which is + mainly used for testing purposes to control randomness and maintain the reproducibility + """ + batch_size, seq_length, dim = shape_list(sequence) + len_keep = int(seq_length * (1 - self.config.mask_ratio)) + + if noise is None: + noise = tf.random.uniform(shape=(batch_size, seq_length), minval=0.0, maxval=1.0) # noise in [0, 1) + + # sort noise for each sample + ids_shuffle = tf.argsort(noise, axis=1) # ascend: small is keep, large is remove + ids_restore = tf.argsort(ids_shuffle, axis=1) + + # keep the first subset + ids_keep = ids_shuffle[:, :len_keep] + sequence_unmasked = tf.gather( + sequence, + axis=1, + batch_dims=1, + indices=ids_keep, + ) + + # generate the binary mask: 0 is keep, 1 is remove + # this hack is needed because TF's EagerTensors don't support + # assignment + mask_keep = tf.zeros((batch_size, len_keep)) + mask_remove = tf.ones((batch_size, seq_length - len_keep)) + mask = tf.concat([mask_keep, mask_remove], axis=-1) + + # unshuffle to get the binary mask + mask = tf.gather(mask, axis=1, batch_dims=1, indices=ids_restore) + + return sequence_unmasked, mask, ids_restore + + def call(self, pixel_values: tf.Tensor, noise: tf.Tensor = None) -> tf.Tensor: + embeddings = self.patch_embeddings(pixel_values) + + # add position embeddings w/o cls token + embeddings = embeddings + self.position_embeddings[:, 1:, :] + + # masking: length -> length * config.mask_ratio + embeddings, mask, ids_restore = self.random_masking(embeddings, noise) + + # append cls token + cls_token = self.cls_token + self.position_embeddings[:, :1, :] + cls_tokens = tf.tile(cls_token, (shape_list(embeddings)[0], 1, 1)) + embeddings = tf.concat([cls_tokens, embeddings], axis=1) + + return embeddings, mask, ids_restore + + +class TFViTMAEPatchEmbeddings(tf.keras.layers.Layer): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_patches = num_patches + self.num_channels = num_channels + self.config = config + + self.projection = tf.keras.layers.Conv2D( + filters=hidden_size, + kernel_size=patch_size, + strides=patch_size, + padding="valid", + data_format="channels_last", + kernel_initializer="glorot_uniform", # following torch.nn.Linear + bias_initializer="zeros", + name="projection", + ) + + def call(self, pixel_values: tf.Tensor, training: bool = False) -> tf.Tensor: + batch_size, num_channels, height, width = shape_list(pixel_values) + if tf.executing_eagerly(): + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the" + " configuration." + ) + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + + # When running on CPU, `tf.keras.layers.Conv2D` doesn't support `NCHW` format. + # So change the input format from `NCHW` to `NHWC`. + # shape = (batch_size, in_height, in_width, in_channels=num_channels) + pixel_values = tf.transpose(pixel_values, perm=(0, 2, 3, 1)) + + projection = self.projection(pixel_values) + + # Change the 2D spatial dimensions to a single temporal dimension. + # shape = (batch_size, num_patches, out_channels=embed_dim) + num_patches = (width // self.patch_size[1]) * (height // self.patch_size[0]) + x = tf.reshape(tensor=projection, shape=(batch_size, num_patches, -1)) + + return x + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfAttention with ViT->ViTMAE +class TFViTMAESelfAttention(tf.keras.layers.Layer): + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(hidden_states)[0] + mixed_query_layer = self.query(inputs=hidden_states) + mixed_key_layer = self.key(inputs=hidden_states) + mixed_value_layer = self.value(inputs=hidden_states) + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) + value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) + attention_scores = tf.divide(attention_scores, dk) + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + attention_output = tf.matmul(attention_probs, value_layer) + attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) + outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTSelfOutput with ViT->ViTMAE +class TFViTMAESelfOutput(tf.keras.layers.Layer): + """ + The residual connection is defined in TFViTMAELayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTAttention with ViT->ViTMAE +class TFViTMAEAttention(tf.keras.layers.Layer): + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.self_attention = TFViTMAESelfAttention(config, name="attention") + self.dense_output = TFViTMAESelfOutput(config, name="output") + + def prune_heads(self, heads): + raise NotImplementedError + + def call( + self, + input_tensor: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self_attention( + hidden_states=input_tensor, head_mask=head_mask, output_attentions=output_attentions, training=training + ) + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=input_tensor, training=training + ) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTIntermediate with ViT->ViTMAE +class TFViTMAEIntermediate(tf.keras.layers.Layer): + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTOutput with ViT->ViTMAE +class TFViTMAEOutput(tf.keras.layers.Layer): + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + hidden_states = hidden_states + input_tensor + + return hidden_states + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTLayer with ViT->ViTMAE +class TFViTMAELayer(tf.keras.layers.Layer): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFViTMAEAttention(config, name="attention") + self.intermediate = TFViTMAEIntermediate(config, name="intermediate") + self.vit_output = TFViTMAEOutput(config, name="output") + + self.layernorm_before = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_before" + ) + self.layernorm_after = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="layernorm_after" + ) + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attention_outputs = self.attention( + # in ViTMAE, layernorm is applied before self-attention + input_tensor=self.layernorm_before(inputs=hidden_states), + head_mask=head_mask, + output_attentions=output_attentions, + training=training, + ) + attention_output = attention_outputs[0] + + # first residual connection + hidden_states = attention_output + hidden_states + + # in ViTMAE, layernorm is also applied after self-attention + layer_output = self.layernorm_after(inputs=hidden_states) + + intermediate_output = self.intermediate(hidden_states=layer_output) + + # second residual connection is done here + layer_output = self.vit_output( + hidden_states=intermediate_output, input_tensor=hidden_states, training=training + ) + outputs = (layer_output,) + attention_outputs[1:] # add attentions if we output them + + return outputs + + +# Copied from transformers.models.vit.modeling_tf_vit.TFViTEncoder with ViT->ViTMAE +class TFViTMAEEncoder(tf.keras.layers.Layer): + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.layer = [TFViTMAELayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + + def call( + self, + hidden_states: tf.Tensor, + head_mask: tf.Tensor, + output_attentions: bool, + output_hidden_states: bool, + return_dict: bool, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states=hidden_states, + head_mask=head_mask[i], + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_attentions] if v is not None) + + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +@keras_serializable +class TFViTMAEMainLayer(tf.keras.layers.Layer): + config_class = ViTMAEConfig + + def __init__(self, config: ViTMAEConfig, **kwargs): + super().__init__(**kwargs) + + self.config = config + + self.embeddings = TFViTMAEEmbeddings(config, name="embeddings") + self.encoder = TFViTMAEEncoder(config, name="encoder") + self.layernorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layernorm") + + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + noise: tf.Tensor = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFViTMAEModelOutput, Tuple[tf.Tensor]]: + embedding_output, mask, ids_restore = self.embeddings( + pixel_values=pixel_values, training=training, noise=noise + ) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(inputs=sequence_output) + + if not return_dict: + return (sequence_output, mask, ids_restore) + encoder_outputs[1:] + + return TFViTMAEModelOutput( + last_hidden_state=sequence_output, + mask=mask, + ids_restore=ids_restore, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class TFViTMAEPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTMAEConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + """ + Dummy inputs to build the network. Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + VISION_DUMMY_INPUTS = tf.random.uniform( + shape=(3, self.config.num_channels, self.config.image_size, self.config.image_size), + dtype=tf.float32, + ) + return {"pixel_values": tf.constant(VISION_DUMMY_INPUTS)} + + @tf.function( + input_signature=[ + { + "pixel_values": tf.TensorSpec((None, None, None, None), tf.float32, name="pixel_values"), + } + ] + ) + def serving(self, inputs): + """ + Method used for serving the model. + + Args: + inputs (`Dict[str, tf.Tensor]`): + The input of the saved model as a dictionary of tensors. + """ + output = self.call(inputs) + return self.serving_output(output) + + +VIT_MAE_START_DOCSTRING = r""" + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `pixel_values` only and nothing else: `model(pixel_values)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([pixel_values, attention_mask])` or `model([pixel_values, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"pixel_values": pixel_values, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`ViTMAEConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +VIT_MAE_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` ``Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + + return_dict (`bool`, *optional*): + Whether or not to return a [`~file_utils.ModelOutput`] instead of a plain tuple. This argument can be used + in eager mode, in graph mode the value will always be set to True. + + training (`bool`, *optional*, defaults to `False``): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare ViTMAE Model transformer outputting raw hidden-states without any specific head on top.", + VIT_MAE_START_DOCSTRING, +) +class TFViTMAEModel(TFViTMAEPreTrainedModel): + def __init__(self, config: ViTMAEConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.vit = TFViTMAEMainLayer(config, name="vit") + + def get_input_embeddings(self): + return self.vit.get_input_embeddings() + + @unpack_inputs + @add_start_docstrings_to_model_forward(VIT_MAE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFViTMAEModelOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + noise: tf.Tensor = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFViTMAEModelOutput, Tuple[tf.Tensor]]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, TFViTMAEModel + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-mae-base") + >>> model = TFViTMAEModel.from_pretrained("facebook/vit-mae-base") + + >>> inputs = image_processor(images=image, return_tensors="tf") + >>> outputs = model(**inputs) + >>> last_hidden_states = outputs.last_hidden_state + ```""" + outputs = self.vit( + pixel_values=pixel_values, + noise=noise, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output: TFViTMAEModelOutput) -> TFViTMAEModelOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFViTMAEModelOutput( + last_hidden_state=output.last_hidden_state, + mask=output.mask, + ids_restore=output.ids_restore, + hidden_states=hidden_states, + attentions=attentions, + ) + + +class TFViTMAEDecoder(tf.keras.layers.Layer): + def __init__(self, config, num_patches, **kwargs): + super().__init__(**kwargs) + self.decoder_embed = tf.keras.layers.Dense(config.decoder_hidden_size, name="decoder_embed") + + decoder_config = deepcopy(config) + decoder_config.hidden_size = config.decoder_hidden_size + decoder_config.num_hidden_layers = config.decoder_num_hidden_layers + decoder_config.num_attention_heads = config.decoder_num_attention_heads + decoder_config.intermediate_size = config.decoder_intermediate_size + self.decoder_layers = [ + TFViTMAELayer(decoder_config, name=f"decoder_layers.{j}") for j in range(config.decoder_num_hidden_layers) + ] + + self.decoder_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="decoder_norm") + self.decoder_pred = tf.keras.layers.Dense( + config.patch_size**2 * config.num_channels, + kernel_initializer=get_initializer(config.initializer_range), + name="decoder_pred", + ) # encoder to decoder + self.config = config + self.num_patches = num_patches + + def build(self, input_shape: tf.TensorShape): + self.mask_token = self.add_weight( + shape=(1, 1, self.config.decoder_hidden_size), + initializer=tf.random_normal_initializer(stddev=self.config.initializer_range), + trainable=True, + name="mask_token", + ) + self.decoder_pos_embed = self.add_weight( + shape=(1, self.num_patches + 1, self.config.decoder_hidden_size), + initializer="zeros", + trainable=False, + name="decoder_pos_embed", + ) + decoder_pos_embed = get_2d_sincos_pos_embed( + self.decoder_pos_embed.shape[-1], + int(self.num_patches**0.5), + add_cls_token=True, + )[None, ...] + self.decoder_pos_embed.assign(decoder_pos_embed) + + super().build(input_shape) + + def call( + self, + hidden_states, + ids_restore, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + # embed tokens + x = self.decoder_embed(hidden_states) + + # append mask tokens to sequence + mask_tokens = tf.tile( + self.mask_token, + (shape_list(x)[0], shape_list(ids_restore)[1] + 1 - shape_list(x)[1], 1), + ) + x_ = tf.concat([x[:, 1:, :], mask_tokens], axis=1) # no cls token + x_ = tf.gather(x_, axis=1, batch_dims=1, indices=ids_restore) # unshuffle + x = tf.concat([x[:, :1, :], x_], axis=1) # append cls token + + # add pos embed + hidden_states = x + self.decoder_pos_embed + + # apply Transformer layers (blocks) + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + for i, layer_module in enumerate(self.decoder_layers): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_outputs = layer_module( + hidden_states, + head_mask=None, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + hidden_states = self.decoder_norm(hidden_states) + + # predictor projection + logits = self.decoder_pred(hidden_states) + + # remove cls token + logits = logits[:, 1:, :] + + if not return_dict: + return tuple(v for v in [logits, all_hidden_states, all_self_attentions] if v is not None) + return TFViTMAEDecoderOutput(logits=logits, hidden_states=all_hidden_states, attentions=all_self_attentions) + + +@add_start_docstrings( + "The ViTMAE Model transformer with the decoder on top for self-supervised pre-training.", + VIT_MAE_START_DOCSTRING, +) +class TFViTMAEForPreTraining(TFViTMAEPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.config = config + + self.vit = TFViTMAEMainLayer(config, name="vit") + self.decoder = TFViTMAEDecoder( + config, + num_patches=self.vit.embeddings.num_patches, + name="decoder", + ) + + def get_input_embeddings(self): + return self.vit.get_input_embeddings() + + def _prune_heads(self, heads_to_prune): + raise NotImplementedError + + def patchify(self, pixel_values): + """ + Args: + pixel_values (`tf.Tensor` of shape `(batch_size, height, width, num_channels)` or `(batch_size, num_channels, height, width)`): + Pixel values. + + Returns: + `tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: + Patchified pixel values. + """ + patch_size, num_channels = self.config.patch_size, self.config.num_channels + # make sure channels are last + pixel_values = tf.cond( + tf.math.equal(shape_list(pixel_values)[1], num_channels), + lambda: tf.transpose(pixel_values, perm=(0, 2, 3, 1)), + lambda: pixel_values, + ) + + # sanity checks + tf.debugging.assert_equal( + shape_list(pixel_values)[1], + shape_list(pixel_values)[2], + message="Make sure the pixel values have a squared size", + ) + tf.debugging.assert_equal( + shape_list(pixel_values)[1] % patch_size, + 0, + message="Make sure the pixel values have a size that is divisible by the patch size", + ) + tf.debugging.assert_equal( + shape_list(pixel_values)[3], + num_channels, + message=( + "Make sure the number of channels of the pixel values is equal to the one set in the configuration" + ), + ) + + # patchify + batch_size = shape_list(pixel_values)[0] + num_patches_one_direction = shape_list(pixel_values)[2] // patch_size + patchified_pixel_values = tf.reshape( + pixel_values, + (batch_size, num_patches_one_direction, patch_size, num_patches_one_direction, patch_size, num_channels), + ) + patchified_pixel_values = tf.einsum("nhpwqc->nhwpqc", patchified_pixel_values) + patchified_pixel_values = tf.reshape( + patchified_pixel_values, + (batch_size, num_patches_one_direction * num_patches_one_direction, patch_size**2 * num_channels), + ) + return patchified_pixel_values + + def unpatchify(self, patchified_pixel_values): + """ + Args: + patchified_pixel_values (`tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: + Patchified pixel values. + + Returns: + `tf.Tensor` of shape `(batch_size, height, width, num_channels)`: + Pixel values. + """ + patch_size, num_channels = self.config.patch_size, self.config.num_channels + num_patches_one_direction = int(shape_list(patchified_pixel_values)[1] ** 0.5) + # sanity check + tf.debugging.assert_equal( + num_patches_one_direction * num_patches_one_direction, + shape_list(patchified_pixel_values)[1], + message="Make sure that the number of patches can be squared", + ) + + # unpatchify + batch_size = shape_list(patchified_pixel_values)[0] + patchified_pixel_values = tf.reshape( + patchified_pixel_values, + (batch_size, num_patches_one_direction, num_patches_one_direction, patch_size, patch_size, num_channels), + ) + patchified_pixel_values = tf.einsum("nhwpqc->nhpwqc", patchified_pixel_values) + pixel_values = tf.reshape( + patchified_pixel_values, + (batch_size, num_patches_one_direction * patch_size, num_patches_one_direction * patch_size, num_channels), + ) + return pixel_values + + def forward_loss(self, pixel_values, pred, mask): + """ + Args: + pixel_values (`tf.Tensor` of shape `(batch_size, height, width, num_channels)`): + Pixel values. + pred (`tf.Tensor` of shape `(batch_size, num_patches, patch_size**2 * num_channels)`: + Predicted pixel values. + mask (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Tensor indicating which patches are masked (1) and which are not (0). + + Returns: + `tf.Tensor`: Pixel reconstruction loss. + """ + target = self.patchify(pixel_values) + if self.config.norm_pix_loss: + mean = tf.reduce_mean(target, axis=-1, keepdims=True) + var = tf.math.reduce_variance(target, axis=-1, keepdims=True) + target = (target - mean) / (var + 1.0e-6) ** 0.5 + + loss = (pred - target) ** 2 + loss = tf.reduce_mean(loss, axis=-1) # [batch_size, num_patches], mean loss per patch + + loss = tf.reduce_sum(loss * mask) / tf.reduce_sum(mask) # mean loss on removed patches + loss = tf.reshape(loss, (1,)) + return loss + + @unpack_inputs + @add_start_docstrings_to_model_forward(VIT_MAE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFViTMAEForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + pixel_values: Optional[TFModelInputType] = None, + noise: tf.Tensor = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFViTMAEForPreTrainingOutput, Tuple[tf.Tensor]]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, TFViTMAEForPreTraining + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-mae-base") + >>> model = TFViTMAEForPreTraining.from_pretrained("facebook/vit-mae-base") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + >>> loss = outputs.loss + >>> mask = outputs.mask + >>> ids_restore = outputs.ids_restore + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values=pixel_values, + noise=noise, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + latent = outputs.last_hidden_state + ids_restore = outputs.ids_restore + mask = outputs.mask + + decoder_outputs = self.decoder(latent, ids_restore) # [batch_size, num_patches, patch_size**2*3] + logits = decoder_outputs.logits + + loss = self.forward_loss(pixel_values, logits, mask) + + if not return_dict: + output = (logits, mask, ids_restore) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFViTMAEForPreTrainingOutput( + loss=loss, + logits=logits, + mask=mask, + ids_restore=ids_restore, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFViTMAEForPreTrainingOutput) -> TFViTMAEForPreTrainingOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFViTMAEForPreTrainingOutput( + logits=output.logits, + mask=output.mask, + ids_restore=output.ids_restore, + hidden_states=hidden_states, + attentions=attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c36cb750cfa4e6273de0a8a2646236ee14b516d1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/__init__.py @@ -0,0 +1,53 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = {"configuration_vit_msn": ["VIT_MSN_PRETRAINED_CONFIG_ARCHIVE_MAP", "ViTMSNConfig"]} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_vit_msn"] = [ + "VIT_MSN_PRETRAINED_MODEL_ARCHIVE_LIST", + "ViTMSNModel", + "ViTMSNForImageClassification", + "ViTMSNPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_vit_msn import VIT_MSN_PRETRAINED_CONFIG_ARCHIVE_MAP, ViTMSNConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_vit_msn import ( + VIT_MSN_PRETRAINED_MODEL_ARCHIVE_LIST, + ViTMSNForImageClassification, + ViTMSNModel, + ViTMSNPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/configuration_vit_msn.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/configuration_vit_msn.py new file mode 100644 index 0000000000000000000000000000000000000000..87d9a37a68e067a0d125e9e14337ab0657171787 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/configuration_vit_msn.py @@ -0,0 +1,117 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" ViT MSN model configuration""" + + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +VIT_MSN_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "sayakpaul/vit-msn-base": "https://huggingface.co/sayakpaul/vit-msn-base/resolve/main/config.json", + # See all ViT MSN models at https://huggingface.co/models?filter=vit_msn +} + + +class ViTMSNConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`ViTMSNModel`]. It is used to instantiate an ViT + MSN model according to the specified arguments, defining the model architecture. Instantiating a configuration with + the defaults will yield a similar configuration to that of the ViT + [facebook/vit_msn_base](https://huggingface.co/facebook/vit_msn_base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-06): + The epsilon used by the layer normalization layers. + image_size (`int`, *optional*, defaults to 224): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 16): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to 3): + The number of input channels. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + + Example: + + ```python + >>> from transformers import ViTMSNModel, ViTMSNConfig + + >>> # Initializing a ViT MSN vit-msn-base style configuration + >>> configuration = ViTConfig() + + >>> # Initializing a model from the vit-msn-base style configuration + >>> model = ViTMSNModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "vit_msn" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-06, + image_size=224, + patch_size=16, + num_channels=3, + qkv_bias=True, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/convert_msn_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/convert_msn_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..482073a4faa0053ad5349e8624ed810d7e817c98 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/convert_msn_to_pytorch.py @@ -0,0 +1,245 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert ViT MSN checkpoints from the original repository: https://github.com/facebookresearch/msn""" + +import argparse +import json + +import requests +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import ViTFeatureExtractor, ViTMSNConfig, ViTMSNModel +from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD + + +torch.set_grad_enabled(False) + + +# here we list all keys to be renamed (original name on the left, our name on the right) +def create_rename_keys(config, base_model=False): + rename_keys = [] + for i in range(config.num_hidden_layers): + # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms + rename_keys.append((f"module.blocks.{i}.norm1.weight", f"vit.encoder.layer.{i}.layernorm_before.weight")) + rename_keys.append((f"module.blocks.{i}.norm1.bias", f"vit.encoder.layer.{i}.layernorm_before.bias")) + rename_keys.append( + (f"module.blocks.{i}.attn.proj.weight", f"vit.encoder.layer.{i}.attention.output.dense.weight") + ) + rename_keys.append((f"module.blocks.{i}.attn.proj.bias", f"vit.encoder.layer.{i}.attention.output.dense.bias")) + rename_keys.append((f"module.blocks.{i}.norm2.weight", f"vit.encoder.layer.{i}.layernorm_after.weight")) + rename_keys.append((f"module.blocks.{i}.norm2.bias", f"vit.encoder.layer.{i}.layernorm_after.bias")) + rename_keys.append((f"module.blocks.{i}.mlp.fc1.weight", f"vit.encoder.layer.{i}.intermediate.dense.weight")) + rename_keys.append((f"module.blocks.{i}.mlp.fc1.bias", f"vit.encoder.layer.{i}.intermediate.dense.bias")) + rename_keys.append((f"module.blocks.{i}.mlp.fc2.weight", f"vit.encoder.layer.{i}.output.dense.weight")) + rename_keys.append((f"module.blocks.{i}.mlp.fc2.bias", f"vit.encoder.layer.{i}.output.dense.bias")) + + # projection layer + position embeddings + rename_keys.extend( + [ + ("module.cls_token", "vit.embeddings.cls_token"), + ("module.patch_embed.proj.weight", "vit.embeddings.patch_embeddings.projection.weight"), + ("module.patch_embed.proj.bias", "vit.embeddings.patch_embeddings.projection.bias"), + ("module.pos_embed", "vit.embeddings.position_embeddings"), + ] + ) + + if base_model: + # layernorm + pooler + rename_keys.extend( + [ + ("module.norm.weight", "layernorm.weight"), + ("module.norm.bias", "layernorm.bias"), + ] + ) + + # if just the base model, we should remove "vit" from all keys that start with "vit" + rename_keys = [(pair[0], pair[1][4:]) if pair[1].startswith("vit") else pair for pair in rename_keys] + else: + # layernorm + classification head + rename_keys.extend( + [ + ("norm.weight", "vit.layernorm.weight"), + ("norm.bias", "vit.layernorm.bias"), + ("head.weight", "classifier.weight"), + ("head.bias", "classifier.bias"), + ] + ) + + return rename_keys + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_q_k_v(state_dict, config, base_model=False): + for i in range(config.num_hidden_layers): + if base_model: + prefix = "" + else: + prefix = "vit." + # read in weights + bias of input projection layer (in timm, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"module.blocks.{i}.attn.qkv.weight") + in_proj_bias = state_dict.pop(f"module.blocks.{i}.attn.qkv.bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[ + : config.hidden_size, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[: config.hidden_size] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[ + config.hidden_size : config.hidden_size * 2 + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[ + -config.hidden_size :, : + ] + state_dict[f"{prefix}encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-config.hidden_size :] + + +def remove_classification_head_(state_dict): + ignore_keys = ["head.weight", "head.bias"] + for k in ignore_keys: + state_dict.pop(k, None) + + +def remove_projection_head(state_dict): + # projection head is used in the self-supervised pre-training in MSN, + # for downstream task it's not needed. + ignore_keys = [ + "module.fc.fc1.weight", + "module.fc.fc1.bias", + "module.fc.bn1.weight", + "module.fc.bn1.bias", + "module.fc.bn1.running_mean", + "module.fc.bn1.running_var", + "module.fc.bn1.num_batches_tracked", + "module.fc.fc2.weight", + "module.fc.fc2.bias", + "module.fc.bn2.weight", + "module.fc.bn2.bias", + "module.fc.bn2.running_mean", + "module.fc.bn2.running_var", + "module.fc.bn2.num_batches_tracked", + "module.fc.fc3.weight", + "module.fc.fc3.bias", + ] + for k in ignore_keys: + state_dict.pop(k, None) + + +def rename_key(dct, old, new): + val = dct.pop(old) + dct[new] = val + + +def convert_vit_msn_checkpoint(checkpoint_url, pytorch_dump_folder_path): + config = ViTMSNConfig() + config.num_labels = 1000 + + repo_id = "datasets/huggingface/label-files" + filename = "imagenet-1k-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + if "s16" in checkpoint_url: + config.hidden_size = 384 + config.intermediate_size = 1536 + config.num_attention_heads = 6 + elif "l16" in checkpoint_url: + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + config.hidden_dropout_prob = 0.1 + elif "b4" in checkpoint_url: + config.patch_size = 4 + elif "l7" in checkpoint_url: + config.patch_size = 7 + config.hidden_size = 1024 + config.intermediate_size = 4096 + config.num_hidden_layers = 24 + config.num_attention_heads = 16 + config.hidden_dropout_prob = 0.1 + + model = ViTMSNModel(config) + + state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")["target_encoder"] + + feature_extractor = ViTFeatureExtractor(size=config.image_size) + + remove_projection_head(state_dict) + rename_keys = create_rename_keys(config, base_model=True) + + for src, dest in rename_keys: + rename_key(state_dict, src, dest) + read_in_q_k_v(state_dict, config, base_model=True) + + model.load_state_dict(state_dict) + model.eval() + + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + + image = Image.open(requests.get(url, stream=True).raw) + feature_extractor = ViTFeatureExtractor( + size=config.image_size, image_mean=IMAGENET_DEFAULT_MEAN, image_std=IMAGENET_DEFAULT_STD + ) + inputs = feature_extractor(images=image, return_tensors="pt") + + # forward pass + torch.manual_seed(2) + outputs = model(**inputs) + last_hidden_state = outputs.last_hidden_state + + # The following Colab Notebook was used to generate these outputs: + # https://colab.research.google.com/gist/sayakpaul/3672419a04f5997827503fd84079bdd1/scratchpad.ipynb + if "s16" in checkpoint_url: + expected_slice = torch.tensor([[-1.0915, -1.4876, -1.1809]]) + elif "b16" in checkpoint_url: + expected_slice = torch.tensor([[14.2889, -18.9045, 11.7281]]) + elif "l16" in checkpoint_url: + expected_slice = torch.tensor([[41.5028, -22.8681, 45.6475]]) + elif "b4" in checkpoint_url: + expected_slice = torch.tensor([[-4.3868, 5.2932, -0.4137]]) + else: + expected_slice = torch.tensor([[-0.1792, -0.6465, 2.4263]]) + + # verify logits + assert torch.allclose(last_hidden_state[:, 0, :3], expected_slice, atol=1e-4) + + print(f"Saving model to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--checkpoint_url", + default="https://dl.fbaipublicfiles.com/msn/vits16_800ep.pth.tar", + type=str, + help="URL of the checkpoint you'd like to convert.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + + args = parser.parse_args() + convert_vit_msn_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/modeling_vit_msn.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/modeling_vit_msn.py new file mode 100644 index 0000000000000000000000000000000000000000..46639e7d622cb739fae20848bc3dca8bc0596c60 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/vit_msn/modeling_vit_msn.py @@ -0,0 +1,700 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch ViT MSN (masked siamese network) model.""" + + +import collections.abc +import math +from typing import Dict, List, Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, ImageClassifierOutput +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_vit_msn import ViTMSNConfig + + +logger = logging.get_logger(__name__) + + +_CONFIG_FOR_DOC = "ViTMSNConfig" +_CHECKPOINT_FOR_DOC = "facebook/vit-msn-small" +VIT_MSN_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/vit-msn-small", + # See all ViTMSN models at https://huggingface.co/models?filter=vit_msn +] + + +class ViTMSNEmbeddings(nn.Module): + """ + Construct the CLS token, position and patch embeddings. Optionally, also the mask token. + """ + + def __init__(self, config: ViTMSNConfig, use_mask_token: bool = False) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.mask_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) if use_mask_token else None + self.patch_embeddings = ViTMSNPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches + 1, config.hidden_size)) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.config = config + + def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor: + """ + This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher + resolution images. + + Source: + https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174 + """ + + num_patches = embeddings.shape[1] - 1 + num_positions = self.position_embeddings.shape[1] - 1 + if num_patches == num_positions and height == width: + return self.position_embeddings + class_pos_embed = self.position_embeddings[:, 0] + patch_pos_embed = self.position_embeddings[:, 1:] + dim = embeddings.shape[-1] + patch_window_height = height // self.config.patch_size + patch_window_width = width // self.config.patch_size + # we add a small number to avoid floating point error in the interpolation + # see discussion at https://github.com/facebookresearch/dino/issues/8 + patch_window_height, patch_window_width = patch_window_height + 0.1, patch_window_width + 0.1 + patch_pos_embed = patch_pos_embed.reshape(1, int(math.sqrt(num_positions)), int(math.sqrt(num_positions)), dim) + patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2) + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, + scale_factor=( + patch_window_height / math.sqrt(num_positions), + patch_window_width / math.sqrt(num_positions), + ), + mode="bicubic", + align_corners=False, + ) + patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) + return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) + + def forward( + self, + pixel_values: torch.Tensor, + bool_masked_pos: Optional[torch.BoolTensor] = None, + interpolate_pos_encoding: bool = False, + ) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + embeddings = self.patch_embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding) + + if bool_masked_pos is not None: + seq_length = embeddings.shape[1] + mask_tokens = self.mask_token.expand(batch_size, seq_length, -1) + # replace the masked visual tokens by mask_tokens + mask = bool_masked_pos.unsqueeze(-1).type_as(mask_tokens) + embeddings = embeddings * (1.0 - mask) + mask_tokens * mask + + # add the [CLS] token to the embedded patch tokens + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, embeddings), dim=1) + + # add positional encoding to each token + if interpolate_pos_encoding: + embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width) + else: + embeddings = embeddings + self.position_embeddings + + embeddings = self.dropout(embeddings) + + return embeddings + + +# Copied from transformers.models.vit.modeling_vit.ViTPatchEmbeddings with ViT->ViTMSN +class ViTMSNPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor, interpolate_pos_encoding: bool = False) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + f" Expected {self.num_channels} but got {num_channels}." + ) + if not interpolate_pos_encoding: + if height != self.image_size[0] or width != self.image_size[1]: + raise ValueError( + f"Input image size ({height}*{width}) doesn't match model" + f" ({self.image_size[0]}*{self.image_size[1]})." + ) + embeddings = self.projection(pixel_values).flatten(2).transpose(1, 2) + return embeddings + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfAttention with ViT->ViTMSN +class ViTMSNSelfAttention(nn.Module): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfOutput with ViT->ViTMSN +class ViTMSNSelfOutput(nn.Module): + """ + The residual connection is defined in ViTMSNLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTAttention with ViT->ViTMSN +class ViTMSNAttention(nn.Module): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.attention = ViTMSNSelfAttention(config) + self.output = ViTMSNSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTIntermediate with ViT->ViTMSN +class ViTMSNIntermediate(nn.Module): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTOutput with ViT->ViTMSN +class ViTMSNOutput(nn.Module): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTLayer with ViT->ViTMSN +class ViTMSNLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = ViTMSNAttention(config) + self.intermediate = ViTMSNIntermediate(config) + self.output = ViTMSNOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in ViTMSN, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + hidden_states = attention_output + hidden_states + + # in ViTMSN, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTEncoder with ViT->ViTMSN +class ViTMSNEncoder(nn.Module): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([ViTMSNLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class ViTMSNPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = ViTMSNConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + + # todo: Resort to https://github.com/facebookresearch/msn/blob/main/src/deit.py#L200-#L211 + # when creating pre-training scripts. + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module: ViTMSNEncoder, value: bool = False) -> None: + if isinstance(module, ViTMSNEncoder): + module.gradient_checkpointing = value + + +VIT_MSN_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`ViTMSNConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +VIT_MSN_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See [`ViTImageProcessor.__call__`] + for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + interpolate_pos_encoding (`bool`, *optional*): + Whether to interpolate the pre-trained position encodings. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare ViTMSN Model outputting raw hidden-states without any specific head on top.", + VIT_MSN_START_DOCSTRING, +) +class ViTMSNModel(ViTMSNPreTrainedModel): + def __init__(self, config: ViTMSNConfig, use_mask_token: bool = False): + super().__init__(config) + self.config = config + + self.embeddings = ViTMSNEmbeddings(config, use_mask_token=use_mask_token) + self.encoder = ViTMSNEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> ViTMSNPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(VIT_MSN_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + bool_masked_pos: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, BaseModelOutput]: + r""" + bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, num_patches)`, *optional*): + Boolean masked positions. Indicates which patches are masked (1) and which aren't (0). + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, ViTMSNModel + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-msn-small") + >>> model = ViTMSNModel.from_pretrained("facebook/vit-msn-small") + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> with torch.no_grad(): + ... outputs = model(**inputs) + >>> last_hidden_states = outputs.last_hidden_state + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + pixel_values, bool_masked_pos=bool_masked_pos, interpolate_pos_encoding=interpolate_pos_encoding + ) + + encoder_outputs = self.encoder( + embedding_output, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + + if not return_dict: + head_outputs = (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutput( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +# Caution: We don't have the weights for the classification head yet. This class +# is here for the users that are interested to fine-tune the base model (ViTMSNModel). +@add_start_docstrings( + """ + ViTMSN Model with an image classification head on top e.g. for ImageNet. + """, + VIT_MSN_START_DOCSTRING, +) +class ViTMSNForImageClassification(ViTMSNPreTrainedModel): + def __init__(self, config: ViTMSNConfig) -> None: + super().__init__(config) + + self.num_labels = config.num_labels + self.vit = ViTMSNModel(config) + + # Classifier head + self.classifier = nn.Linear(config.hidden_size, config.num_labels) if config.num_labels > 0 else nn.Identity() + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(VIT_MSN_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=ImageClassifierOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[tuple, ImageClassifierOutput]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, ViTMSNForImageClassification + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> torch.manual_seed(2) # doctest: +IGNORE_RESULT + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-msn-small") + >>> model = ViTMSNForImageClassification.from_pretrained("facebook/vit-msn-small") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_label = logits.argmax(-1).item() + >>> print(model.config.id2label[predicted_label]) + Kerry blue terrier + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.vit( + pixel_values, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output[:, 0, :]) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return ImageClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b3abdb99ec722d6f5e13b136d89b664a79527840 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/__init__.py @@ -0,0 +1,134 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_torch_available, +) + + +_import_structure = { + "configuration_wav2vec2": ["WAV_2_VEC_2_PRETRAINED_CONFIG_ARCHIVE_MAP", "Wav2Vec2Config"], + "feature_extraction_wav2vec2": ["Wav2Vec2FeatureExtractor"], + "processing_wav2vec2": ["Wav2Vec2Processor"], + "tokenization_wav2vec2": ["Wav2Vec2CTCTokenizer", "Wav2Vec2Tokenizer"], +} + + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_wav2vec2"] = [ + "WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST", + "Wav2Vec2ForAudioFrameClassification", + "Wav2Vec2ForCTC", + "Wav2Vec2ForMaskedLM", + "Wav2Vec2ForPreTraining", + "Wav2Vec2ForSequenceClassification", + "Wav2Vec2ForXVector", + "Wav2Vec2Model", + "Wav2Vec2PreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_wav2vec2"] = [ + "TF_WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFWav2Vec2ForCTC", + "TFWav2Vec2Model", + "TFWav2Vec2PreTrainedModel", + "TFWav2Vec2ForSequenceClassification", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_wav2vec2"] = [ + "FlaxWav2Vec2ForCTC", + "FlaxWav2Vec2ForPreTraining", + "FlaxWav2Vec2Model", + "FlaxWav2Vec2PreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_wav2vec2 import WAV_2_VEC_2_PRETRAINED_CONFIG_ARCHIVE_MAP, Wav2Vec2Config + from .feature_extraction_wav2vec2 import Wav2Vec2FeatureExtractor + from .processing_wav2vec2 import Wav2Vec2Processor + from .tokenization_wav2vec2 import Wav2Vec2CTCTokenizer, Wav2Vec2Tokenizer + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_wav2vec2 import ( + WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST, + Wav2Vec2ForAudioFrameClassification, + Wav2Vec2ForCTC, + Wav2Vec2ForMaskedLM, + Wav2Vec2ForPreTraining, + Wav2Vec2ForSequenceClassification, + Wav2Vec2ForXVector, + Wav2Vec2Model, + Wav2Vec2PreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_wav2vec2 import ( + TF_WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST, + TFWav2Vec2ForCTC, + TFWav2Vec2ForSequenceClassification, + TFWav2Vec2Model, + TFWav2Vec2PreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_wav2vec2 import ( + FlaxWav2Vec2ForCTC, + FlaxWav2Vec2ForPreTraining, + FlaxWav2Vec2Model, + FlaxWav2Vec2PreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/configuration_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/configuration_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..7afcd3f0ee28e258892dc3ea0f6bc3e618aadfc9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/configuration_wav2vec2.py @@ -0,0 +1,338 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Wav2Vec2 model configuration""" + +import functools +import operator + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +WAV_2_VEC_2_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/wav2vec2-base-960h": "https://huggingface.co/facebook/wav2vec2-base-960h/resolve/main/config.json", + # See all Wav2Vec2 models at https://huggingface.co/models?filter=wav2vec2 +} + + +class Wav2Vec2Config(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Wav2Vec2Model`]. It is used to instantiate an + Wav2Vec2 model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of the Wav2Vec2 + [facebook/wav2vec2-base-960h](https://huggingface.co/facebook/wav2vec2-base-960h) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 32): + Vocabulary size of the Wav2Vec2 model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`Wav2Vec2Model`] or [`TFWav2Vec2Model`]. Vocabulary size of the + model. Defines the different tokens that can be represented by the *inputs_ids* passed to the forward + method of [`Wav2Vec2Model`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + final_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for the final projection layer of [`Wav2Vec2ForCTC`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + feat_extract_norm (`str`, *optional*, defaults to `"group"`): + The norm to be applied to 1D convolutional layers in feature encoder. One of `"group"` for group + normalization of only the first 1D convolutional layer or `"layer"` for layer normalization of all 1D + convolutional layers. + feat_proj_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for output of the feature encoder. + feat_extract_activation (`str, `optional`, defaults to `"gelu"`): + The non-linear activation function (function or string) in the 1D convolutional layers of the feature + extractor. If string, `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` are supported. + feat_quantizer_dropout (`float`, *optional*, defaults to 0.0): + The dropout probabilitiy for quantized feature encoder states. + conv_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 512, 512, 512)`): + A tuple of integers defining the number of input and output channels of each 1D convolutional layer in the + feature encoder. The length of *conv_dim* defines the number of 1D convolutional layers. + conv_stride (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 2, 2, 2, 2, 2, 2)`): + A tuple of integers defining the stride of each 1D convolutional layer in the feature encoder. The length + of *conv_stride* defines the number of convolutional layers and has to match the length of *conv_dim*. + conv_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(10, 3, 3, 3, 3, 3, 3)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the feature encoder. The + length of *conv_kernel* defines the number of convolutional layers and has to match the length of + *conv_dim*. + conv_bias (`bool`, *optional*, defaults to `False`): + Whether the 1D convolutional layers have a bias. + num_conv_pos_embeddings (`int`, *optional*, defaults to 128): + Number of convolutional positional embeddings. Defines the kernel size of 1D convolutional positional + embeddings layer. + num_conv_pos_embedding_groups (`int`, *optional*, defaults to 16): + Number of groups of 1D convolutional positional embeddings layer. + do_stable_layer_norm (`bool`, *optional*, defaults to `False`): + Whether to apply *stable* layer norm architecture of the Transformer encoder. `do_stable_layer_norm is + True` corresponds to applying layer norm before the attention layer, whereas `do_stable_layer_norm is + False` corresponds to applying layer norm after the attention layer. + apply_spec_augment (`bool`, *optional*, defaults to `True`): + Whether to apply *SpecAugment* data augmentation to the outputs of the feature encoder. For reference see + [SpecAugment: A Simple Data Augmentation Method for Automatic Speech + Recognition](https://arxiv.org/abs/1904.08779). + mask_time_prob (`float`, *optional*, defaults to 0.05): + Percentage (between 0 and 1) of all feature vectors along the time axis which will be masked. The masking + procecure generates ''mask_time_prob*len(time_axis)/mask_time_length'' independent masks over the axis. If + reasoning from the propability of each feature vector to be chosen as the start of the vector span to be + masked, *mask_time_prob* should be `prob_vector_start*mask_time_length`. Note that overlap may decrease the + actual percentage of masked vectors. This is only relevant if `apply_spec_augment is True`. + mask_time_length (`int`, *optional*, defaults to 10): + Length of vector span along the time axis. + mask_time_min_masks (`int`, *optional*, defaults to 2),: + The minimum number of masks of length `mask_feature_length` generated along the time axis, each time step, + irrespectively of `mask_feature_prob`. Only relevant if ''mask_time_prob*len(time_axis)/mask_time_length < + mask_time_min_masks'' + mask_feature_prob (`float`, *optional*, defaults to 0.0): + Percentage (between 0 and 1) of all feature vectors along the feature axis which will be masked. The + masking procecure generates ''mask_feature_prob*len(feature_axis)/mask_time_length'' independent masks over + the axis. If reasoning from the propability of each feature vector to be chosen as the start of the vector + span to be masked, *mask_feature_prob* should be `prob_vector_start*mask_feature_length`. Note that overlap + may decrease the actual percentage of masked vectors. This is only relevant if `apply_spec_augment is + True`. + mask_feature_length (`int`, *optional*, defaults to 10): + Length of vector span along the feature axis. + mask_feature_min_masks (`int`, *optional*, defaults to 0),: + The minimum number of masks of length `mask_feature_length` generated along the feature axis, each time + step, irrespectively of `mask_feature_prob`. Only relevant if + ''mask_feature_prob*len(feature_axis)/mask_feature_length < mask_feature_min_masks'' + num_codevectors_per_group (`int`, *optional*, defaults to 320): + Number of entries in each quantization codebook (group). + num_codevector_groups (`int`, *optional*, defaults to 2): + Number of codevector groups for product codevector quantization. + contrastive_logits_temperature (`float`, *optional*, defaults to 0.1): + The temperature *kappa* in the contrastive loss. + feat_quantizer_dropout (`float`, *optional*, defaults to 0.0): + The dropout probabilitiy for the output of the feature encoder that's used by the quantizer. + num_negatives (`int`, *optional*, defaults to 100): + Number of negative samples for the contrastive loss. + codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the quantized feature vectors. + proj_codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the final projection of both the quantized and the transformer features. + diversity_loss_weight (`int`, *optional*, defaults to 0.1): + The weight of the codebook diversity loss component. + ctc_loss_reduction (`str`, *optional*, defaults to `"sum"`): + Specifies the reduction to apply to the output of `torch.nn.CTCLoss`. Only relevant when training an + instance of [`Wav2Vec2ForCTC`]. + ctc_zero_infinity (`bool`, *optional*, defaults to `False`): + Whether to zero infinite losses and the associated gradients of `torch.nn.CTCLoss`. Infinite losses mainly + occur when the inputs are too short to be aligned to the targets. Only relevant when training an instance + of [`Wav2Vec2ForCTC`]. + use_weighted_layer_sum (`bool`, *optional*, defaults to `False`): + Whether to use a weighted average of layer outputs with learned weights. Only relevant when using an + instance of [`Wav2Vec2ForSequenceClassification`]. + classifier_proj_size (`int`, *optional*, defaults to 256): + Dimensionality of the projection before token mean-pooling for classification. + tdnn_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 1500)`): + A tuple of integers defining the number of output channels of each 1D convolutional layer in the *TDNN* + module of the *XVector* model. The length of *tdnn_dim* defines the number of *TDNN* layers. + tdnn_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 3, 3, 1, 1)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the *TDNN* module of the + *XVector* model. The length of *tdnn_kernel* has to match the length of *tdnn_dim*. + tdnn_dilation (`Tuple[int]` or `List[int]`, *optional*, defaults to `(1, 2, 3, 1, 1)`): + A tuple of integers defining the dilation factor of each 1D convolutional layer in *TDNN* module of the + *XVector* model. The length of *tdnn_dilation* has to match the length of *tdnn_dim*. + xvector_output_dim (`int`, *optional*, defaults to 512): + Dimensionality of the *XVector* embedding vectors. + add_adapter (`bool`, *optional*, defaults to `False`): + Whether a convolutional network should be stacked on top of the Wav2Vec2 Encoder. Can be very useful for + warm-starting Wav2Vec2 for SpeechEncoderDecoder models. + adapter_kernel_size (`int`, *optional*, defaults to 3): + Kernel size of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + adapter_stride (`int`, *optional*, defaults to 2): + Stride of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + num_adapter_layers (`int`, *optional*, defaults to 3): + Number of convolutional layers that should be used in the adapter network. Only relevant if `add_adapter is + True`. + output_hidden_size (`int`, *optional*): + Dimensionality of the encoder output layer. If not defined, this defaults to *hidden-size*. Only relevant + if `add_adapter is True`. + + Example: + + ```python + >>> from transformers import Wav2Vec2Config, Wav2Vec2Model + + >>> # Initializing a Wav2Vec2 facebook/wav2vec2-base-960h style configuration + >>> configuration = Wav2Vec2Config() + + >>> # Initializing a model (with random weights) from the facebook/wav2vec2-base-960h style configuration + >>> model = Wav2Vec2Model(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "wav2vec2" + + def __init__( + self, + vocab_size=32, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout=0.1, + activation_dropout=0.1, + attention_dropout=0.1, + feat_proj_dropout=0.0, + feat_quantizer_dropout=0.0, + final_dropout=0.1, + layerdrop=0.1, + initializer_range=0.02, + layer_norm_eps=1e-5, + feat_extract_norm="group", + feat_extract_activation="gelu", + conv_dim=(512, 512, 512, 512, 512, 512, 512), + conv_stride=(5, 2, 2, 2, 2, 2, 2), + conv_kernel=(10, 3, 3, 3, 3, 2, 2), + conv_bias=False, + num_conv_pos_embeddings=128, + num_conv_pos_embedding_groups=16, + do_stable_layer_norm=False, + apply_spec_augment=True, + mask_time_prob=0.05, + mask_time_length=10, + mask_time_min_masks=2, + mask_feature_prob=0.0, + mask_feature_length=10, + mask_feature_min_masks=0, + num_codevectors_per_group=320, + num_codevector_groups=2, + contrastive_logits_temperature=0.1, + num_negatives=100, + codevector_dim=256, + proj_codevector_dim=256, + diversity_loss_weight=0.1, + ctc_loss_reduction="sum", + ctc_zero_infinity=False, + use_weighted_layer_sum=False, + classifier_proj_size=256, + tdnn_dim=(512, 512, 512, 512, 1500), + tdnn_kernel=(5, 3, 3, 1, 1), + tdnn_dilation=(1, 2, 3, 1, 1), + xvector_output_dim=512, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + add_adapter=False, + adapter_kernel_size=3, + adapter_stride=2, + num_adapter_layers=3, + output_hidden_size=None, + **kwargs, + ): + super().__init__(**kwargs, pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id) + self.hidden_size = hidden_size + self.feat_extract_norm = feat_extract_norm + self.feat_extract_activation = feat_extract_activation + self.conv_dim = list(conv_dim) + self.conv_stride = list(conv_stride) + self.conv_kernel = list(conv_kernel) + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_feat_extract_layers = len(self.conv_dim) + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_attention_heads = num_attention_heads + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.feat_proj_dropout = feat_proj_dropout + self.final_dropout = final_dropout + self.layerdrop = layerdrop + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.do_stable_layer_norm = do_stable_layer_norm + self.use_weighted_layer_sum = use_weighted_layer_sum + + if ( + (len(self.conv_stride) != self.num_feat_extract_layers) + or (len(self.conv_kernel) != self.num_feat_extract_layers) + or (len(self.conv_dim) != self.num_feat_extract_layers) + ): + raise ValueError( + "Configuration for convolutional layers is incorrect. It is required that `len(config.conv_dim)` ==" + " `len(config.conv_stride)` == `len(config.conv_kernel)`, but is `len(config.conv_dim) =" + f" {len(self.conv_dim)}`, `len(config.conv_stride) = {len(self.conv_stride)}`," + f" `len(config.conv_kernel) = {len(self.conv_kernel)}`." + ) + + # fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779 + self.apply_spec_augment = apply_spec_augment + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.mask_time_min_masks = mask_time_min_masks + self.mask_feature_prob = mask_feature_prob + self.mask_feature_length = mask_feature_length + self.mask_feature_min_masks = mask_feature_min_masks + + # parameters for pretraining with codevector quantized representations + self.num_codevectors_per_group = num_codevectors_per_group + self.num_codevector_groups = num_codevector_groups + self.contrastive_logits_temperature = contrastive_logits_temperature + self.feat_quantizer_dropout = feat_quantizer_dropout + self.num_negatives = num_negatives + self.codevector_dim = codevector_dim + self.proj_codevector_dim = proj_codevector_dim + self.diversity_loss_weight = diversity_loss_weight + + # ctc loss + self.ctc_loss_reduction = ctc_loss_reduction + self.ctc_zero_infinity = ctc_zero_infinity + + # adapter + self.add_adapter = add_adapter + self.adapter_kernel_size = adapter_kernel_size + self.adapter_stride = adapter_stride + self.num_adapter_layers = num_adapter_layers + self.output_hidden_size = output_hidden_size or hidden_size + + # SequenceClassification-specific parameter. Feel free to ignore for other classes. + self.classifier_proj_size = classifier_proj_size + + # XVector-specific parameters. Feel free to ignore for other classes. + self.tdnn_dim = list(tdnn_dim) + self.tdnn_kernel = list(tdnn_kernel) + self.tdnn_dilation = list(tdnn_dilation) + self.xvector_output_dim = xvector_output_dim + + @property + def inputs_to_logits_ratio(self): + return functools.reduce(operator.mul, self.conv_stride, 1) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..4656f5b811e13a1e9ddbca987a3c7c20da16f36a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,273 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Wav2Vec2 checkpoint.""" + + +import argparse +import json +import os + +import fairseq +import torch +from fairseq.data import Dictionary + +from transformers import ( + Wav2Vec2Config, + Wav2Vec2CTCTokenizer, + Wav2Vec2FeatureExtractor, + Wav2Vec2ForCTC, + Wav2Vec2ForPreTraining, + Wav2Vec2Processor, + logging, +) + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +MAPPING = { + "post_extract_proj": "feature_projection.projection", + "encoder.pos_conv.0": "encoder.pos_conv_embed.conv", + "self_attn.k_proj": "encoder.layers.*.attention.k_proj", + "self_attn.v_proj": "encoder.layers.*.attention.v_proj", + "self_attn.q_proj": "encoder.layers.*.attention.q_proj", + "self_attn.out_proj": "encoder.layers.*.attention.out_proj", + "self_attn_layer_norm": "encoder.layers.*.layer_norm", + "fc1": "encoder.layers.*.feed_forward.intermediate_dense", + "fc2": "encoder.layers.*.feed_forward.output_dense", + "final_layer_norm": "encoder.layers.*.final_layer_norm", + "encoder.layer_norm": "encoder.layer_norm", + "w2v_model.layer_norm": "feature_projection.layer_norm", + "quantizer.weight_proj": "quantizer.weight_proj", + "quantizer.vars": "quantizer.codevectors", + "project_q": "project_q", + "final_proj": "project_hid", + "w2v_encoder.proj": "lm_head", + "mask_emb": "masked_spec_embed", +} +TOP_LEVEL_KEYS = [ + "lm_head", + "quantizer.weight_proj", + "quantizer.codevectors", + "project_q", + "project_hid", +] + + +def set_recursively(hf_pointer, key, value, full_name, weight_type): + for attribute in key.split("."): + hf_pointer = getattr(hf_pointer, attribute) + + if weight_type is not None: + hf_shape = getattr(hf_pointer, weight_type).shape + else: + hf_shape = hf_pointer.shape + + if hf_shape != value.shape: + raise ValueError( + f"Shape of hf {key + '.' + weight_type if weight_type is not None else ''} is {hf_shape}, but should be" + f" {value.shape} for {full_name}" + ) + + if weight_type == "weight": + hf_pointer.weight.data = value + elif weight_type == "weight_g": + hf_pointer.weight_g.data = value + elif weight_type == "weight_v": + hf_pointer.weight_v.data = value + elif weight_type == "bias": + hf_pointer.bias.data = value + else: + hf_pointer.data = value + + logger.info(f"{key + '.' + weight_type if weight_type is not None else ''} was initialized from {full_name}.") + + +def recursively_load_weights(fairseq_model, hf_model, is_headless): + unused_weights = [] + fairseq_dict = fairseq_model.state_dict() + + feature_extractor = hf_model.wav2vec2.feature_extractor + + for name, value in fairseq_dict.items(): + is_used = False + if "conv_layers" in name: + load_conv_layer( + name, + value, + feature_extractor, + unused_weights, + hf_model.config.feat_extract_norm == "group", + ) + is_used = True + else: + for key, mapped_key in MAPPING.items(): + mapped_key = "wav2vec2." + mapped_key if mapped_key not in TOP_LEVEL_KEYS else mapped_key + if key in name or key.split("w2v_model.")[-1] == name.split(".")[0]: + is_used = True + if "*" in mapped_key: + layer_index = name.split(key)[0].split(".")[-2] + mapped_key = mapped_key.replace("*", layer_index) + if "weight_g" in name: + weight_type = "weight_g" + elif "weight_v" in name: + weight_type = "weight_v" + elif "bias" in name: + weight_type = "bias" + elif "weight" in name: + # TODO: don't match quantizer.weight_proj + weight_type = "weight" + else: + weight_type = None + set_recursively(hf_model, mapped_key, value, name, weight_type) + continue + if not is_used: + unused_weights.append(name) + + logger.warning(f"Unused weights: {unused_weights}") + + +def load_conv_layer(full_name, value, feature_extractor, unused_weights, use_group_norm): + name = full_name.split("conv_layers.")[-1] + items = name.split(".") + layer_id = int(items[0]) + type_id = int(items[1]) + + if type_id == 0: + if "bias" in name: + if value.shape != feature_extractor.conv_layers[layer_id].conv.bias.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.bias.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + if value.shape != feature_extractor.conv_layers[layer_id].conv.weight.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.weight.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif (type_id == 2 and not use_group_norm) or (type_id == 2 and layer_id == 0 and use_group_norm): + if "bias" in name: + if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.bias.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.weight.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + else: + unused_weights.append(full_name) + + +@torch.no_grad() +def convert_wav2vec2_checkpoint( + checkpoint_path, pytorch_dump_folder_path, config_path=None, dict_path=None, is_finetuned=True +): + """ + Copy/paste/tweak model's weights to transformers design. + """ + if config_path is not None: + config = Wav2Vec2Config.from_pretrained(config_path) + else: + config = Wav2Vec2Config() + + if is_finetuned: + if dict_path: + target_dict = Dictionary.load(dict_path) + + # important change bos & pad token id since CTC symbol is and + # not as in fairseq + config.bos_token_id = target_dict.pad_index + config.pad_token_id = target_dict.bos_index + config.eos_token_id = target_dict.eos_index + config.vocab_size = len(target_dict.symbols) + vocab_path = os.path.join(pytorch_dump_folder_path, "vocab.json") + if not os.path.isdir(pytorch_dump_folder_path): + logger.error("--pytorch_dump_folder_path ({}) should be a directory".format(pytorch_dump_folder_path)) + return + os.makedirs(pytorch_dump_folder_path, exist_ok=True) + vocab_dict = target_dict.indices + + # fairseq has the and switched + vocab_dict[""] = 0 + vocab_dict[""] = 1 + with open(vocab_path, "w", encoding="utf-8") as vocab_handle: + json.dump(vocab_dict, vocab_handle) + tokenizer = Wav2Vec2CTCTokenizer( + vocab_path, + unk_token=target_dict.unk_word, + pad_token=target_dict.pad_word, + bos_token=target_dict.bos_word, + eos_token=target_dict.eos_word, + word_delimiter_token="|", + do_lower_case=False, + ) + return_attention_mask = True if config.feat_extract_norm == "layer" else False + feature_extractor = Wav2Vec2FeatureExtractor( + feature_size=1, + sampling_rate=16000, + padding_value=0, + do_normalize=True, + return_attention_mask=return_attention_mask, + ) + processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer) + processor.save_pretrained(pytorch_dump_folder_path) + + hf_wav2vec = Wav2Vec2ForCTC(config) + else: + hf_wav2vec = Wav2Vec2ForPreTraining(config) + + if is_finetuned: + model, _, _ = fairseq.checkpoint_utils.load_model_ensemble_and_task( + [checkpoint_path], arg_overrides={"data": "/".join(dict_path.split("/")[:-1])} + ) + else: + task_arg = argparse.Namespace(task="audio_pretraining") + task = fairseq.tasks.setup_task(task_arg) + + model, _, _ = fairseq.checkpoint_utils.load_model_ensemble_and_task([checkpoint_path], task=task) + + model = model[0].eval() + + recursively_load_weights(model, hf_wav2vec, not is_finetuned) + + hf_wav2vec.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.") + parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to fairseq checkpoint") + parser.add_argument("--dict_path", default=None, type=str, help="Path to dict of fine-tuned model") + parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert") + parser.add_argument( + "--not_finetuned", action="store_true", help="Whether the model to convert is a fine-tuned model or not" + ) + args = parser.parse_args() + convert_wav2vec2_checkpoint( + args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_s3prl_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_s3prl_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..bcc9fd95a4d2448656c0d1d1b521a79cbd7bc8f7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/convert_wav2vec2_original_s3prl_checkpoint_to_pytorch.py @@ -0,0 +1,110 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Hubert checkpoint.""" + + +import argparse + +import torch + +from transformers import ( + Wav2Vec2Config, + Wav2Vec2FeatureExtractor, + Wav2Vec2ForAudioFrameClassification, + Wav2Vec2ForSequenceClassification, + Wav2Vec2ForXVector, + logging, +) + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def convert_classification(base_model_name, hf_config, downstream_dict): + model = Wav2Vec2ForSequenceClassification.from_pretrained(base_model_name, config=hf_config) + model.projector.weight.data = downstream_dict["projector.weight"] + model.projector.bias.data = downstream_dict["projector.bias"] + model.classifier.weight.data = downstream_dict["model.post_net.linear.weight"] + model.classifier.bias.data = downstream_dict["model.post_net.linear.bias"] + return model + + +def convert_diarization(base_model_name, hf_config, downstream_dict): + model = Wav2Vec2ForAudioFrameClassification.from_pretrained(base_model_name, config=hf_config) + model.classifier.weight.data = downstream_dict["model.linear.weight"] + model.classifier.bias.data = downstream_dict["model.linear.bias"] + return model + + +def convert_xvector(base_model_name, hf_config, downstream_dict): + model = Wav2Vec2ForXVector.from_pretrained(base_model_name, config=hf_config) + model.projector.weight.data = downstream_dict["connector.weight"] + model.projector.bias.data = downstream_dict["connector.bias"] + for i, kernel_size in enumerate(hf_config.tdnn_kernel): + model.tdnn[i].kernel.weight.data = downstream_dict[ + f"model.framelevel_feature_extractor.module.{i}.kernel.weight" + ] + model.tdnn[i].kernel.bias.data = downstream_dict[f"model.framelevel_feature_extractor.module.{i}.kernel.bias"] + + model.feature_extractor.weight.data = downstream_dict["model.utterancelevel_feature_extractor.linear1.weight"] + model.feature_extractor.bias.data = downstream_dict["model.utterancelevel_feature_extractor.linear1.bias"] + model.classifier.weight.data = downstream_dict["model.utterancelevel_feature_extractor.linear2.weight"] + model.classifier.bias.data = downstream_dict["model.utterancelevel_feature_extractor.linear2.bias"] + model.objective.weight.data = downstream_dict["objective.W"] + return model + + +@torch.no_grad() +def convert_s3prl_checkpoint(base_model_name, config_path, checkpoint_path, model_dump_path): + """ + Copy/paste/tweak model's weights to transformers design. + """ + checkpoint = torch.load(checkpoint_path, map_location="cpu") + + downstream_dict = checkpoint["Downstream"] + + hf_config = Wav2Vec2Config.from_pretrained(config_path) + hf_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained( + base_model_name, return_attention_mask=True, do_normalize=False + ) + + arch = hf_config.architectures[0] + if arch.endswith("ForSequenceClassification"): + hf_model = convert_classification(base_model_name, hf_config, downstream_dict) + elif arch.endswith("ForAudioFrameClassification"): + hf_model = convert_diarization(base_model_name, hf_config, downstream_dict) + elif arch.endswith("ForXVector"): + hf_model = convert_xvector(base_model_name, hf_config, downstream_dict) + else: + raise NotImplementedError(f"S3PRL weights conversion is not supported for {arch}") + + if hf_config.use_weighted_layer_sum: + hf_model.layer_weights.data = checkpoint["Featurizer"]["weights"] + + hf_feature_extractor.save_pretrained(model_dump_path) + hf_model.save_pretrained(model_dump_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--base_model_name", default=None, type=str, help="Name of the huggingface pretrained base model." + ) + parser.add_argument("--config_path", default=None, type=str, help="Path to the huggingface classifier config.") + parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to the s3prl checkpoint.") + parser.add_argument("--model_dump_path", default=None, type=str, help="Path to the final converted model.") + args = parser.parse_args() + convert_s3prl_checkpoint(args.base_model_name, args.config_path, args.checkpoint_path, args.model_dump_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..9550b7c2a9ef9037888c49f2537e67472dafa502 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/feature_extraction_wav2vec2.py @@ -0,0 +1,237 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Feature extractor class for Wav2Vec2 +""" + +from typing import List, Optional, Union + +import numpy as np + +from ...feature_extraction_sequence_utils import SequenceFeatureExtractor +from ...feature_extraction_utils import BatchFeature +from ...utils import PaddingStrategy, TensorType, logging + + +logger = logging.get_logger(__name__) + + +class Wav2Vec2FeatureExtractor(SequenceFeatureExtractor): + r""" + Constructs a Wav2Vec2 feature extractor. + + This feature extractor inherits from [`~feature_extraction_sequence_utils.SequenceFeatureExtractor`] which contains + most of the main methods. Users should refer to this superclass for more information regarding those methods. + + Args: + feature_size (`int`, defaults to 1): + The feature dimension of the extracted features. + sampling_rate (`int`, defaults to 16000): + The sampling rate at which the audio files should be digitalized expressed in hertz (Hz). + padding_value (`float`, defaults to 0.0): + The value that is used to fill the padding values. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether or not to zero-mean unit-variance normalize the input. Normalizing can help to significantly + improve the performance for some models, *e.g.*, + [wav2vec2-lv60](https://huggingface.co/models?search=lv60). + return_attention_mask (`bool`, *optional*, defaults to `False`): + Whether or not [`~Wav2Vec2FeatureExtractor.__call__`] should return `attention_mask`. + + + + Wav2Vec2 models that have set `config.feat_extract_norm == "group"`, such as + [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), have **not** been trained using + `attention_mask`. For such models, `input_values` should simply be padded with 0 and no `attention_mask` + should be passed. + + For Wav2Vec2 models that have set `config.feat_extract_norm == "layer"`, such as + [wav2vec2-lv60](https://huggingface.co/facebook/wav2vec2-large-960h-lv60-self), `attention_mask` should be + passed for batched inference. + + """ + + model_input_names = ["input_values", "attention_mask"] + + def __init__( + self, + feature_size=1, + sampling_rate=16000, + padding_value=0.0, + return_attention_mask=False, + do_normalize=True, + **kwargs, + ): + super().__init__(feature_size=feature_size, sampling_rate=sampling_rate, padding_value=padding_value, **kwargs) + self.return_attention_mask = return_attention_mask + self.do_normalize = do_normalize + + @staticmethod + def zero_mean_unit_var_norm( + input_values: List[np.ndarray], attention_mask: List[np.ndarray], padding_value: float = 0.0 + ) -> List[np.ndarray]: + """ + Every array in the list is normalized to have zero mean and unit variance + """ + if attention_mask is not None: + attention_mask = np.array(attention_mask, np.int32) + normed_input_values = [] + + for vector, length in zip(input_values, attention_mask.sum(-1)): + normed_slice = (vector - vector[:length].mean()) / np.sqrt(vector[:length].var() + 1e-7) + if length < normed_slice.shape[0]: + normed_slice[length:] = padding_value + + normed_input_values.append(normed_slice) + else: + normed_input_values = [(x - x.mean()) / np.sqrt(x.var() + 1e-7) for x in input_values] + + return normed_input_values + + def __call__( + self, + raw_speech: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]], + padding: Union[bool, str, PaddingStrategy] = False, + max_length: Optional[int] = None, + truncation: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_attention_mask: Optional[bool] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + sampling_rate: Optional[int] = None, + **kwargs, + ) -> BatchFeature: + """ + Main method to featurize and prepare for the model one or several sequence(s). + + Args: + raw_speech (`np.ndarray`, `List[float]`, `List[np.ndarray]`, `List[List[float]]`): + The sequence or batch of sequences to be padded. Each sequence can be a numpy array, a list of float + values, a list of numpy arrays or a list of list of float values. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Select a strategy to pad the returned sequences (according to the model's padding side and padding + index) among: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + max_length (`int`, *optional*): + Maximum length of the returned list and optionally padding length (see above). + truncation (`bool`): + Activates truncation to cut input sequences longer than *max_length* to *max_length*. + pad_to_multiple_of (`int`, *optional*): + If set will pad the sequence to a multiple of the provided value. + + This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability + `>= 7.5` (Volta), or on TPUs which benefit from having sequence lengths be a multiple of 128. + return_attention_mask (`bool`, *optional*): + Whether to return the attention mask. If left to the default, will return the attention mask according + to the specific feature_extractor's default. + + [What are attention masks?](../glossary#attention-mask) + + + + Wav2Vec2 models that have set `config.feat_extract_norm == "group"`, such as + [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), have **not** been trained using + `attention_mask`. For such models, `input_values` should simply be padded with 0 and no + `attention_mask` should be passed. + + For Wav2Vec2 models that have set `config.feat_extract_norm == "layer"`, such as + [wav2vec2-lv60](https://huggingface.co/facebook/wav2vec2-large-960h-lv60-self), `attention_mask` should + be passed for batched inference. + + + + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + sampling_rate (`int`, *optional*): + The sampling rate at which the `raw_speech` input was sampled. It is strongly recommended to pass + `sampling_rate` at the forward call to prevent silent errors. + padding_value (`float`, defaults to 0.0): + """ + + if sampling_rate is not None: + if sampling_rate != self.sampling_rate: + raise ValueError( + f"The model corresponding to this feature extractor: {self} was trained using a sampling rate of" + f" {self.sampling_rate}. Please make sure that the provided `raw_speech` input was sampled with" + f" {self.sampling_rate} and not {sampling_rate}." + ) + else: + logger.warning( + "It is strongly recommended to pass the ``sampling_rate`` argument to this function. " + "Failing to do so can result in silent errors that might be hard to debug." + ) + + is_batched = bool( + isinstance(raw_speech, (list, tuple)) + and (isinstance(raw_speech[0], np.ndarray) or isinstance(raw_speech[0], (tuple, list))) + ) + + # always return batch + if not is_batched: + raw_speech = [raw_speech] + + # convert into correct format for padding + encoded_inputs = BatchFeature({"input_values": raw_speech}) + + padded_inputs = self.pad( + encoded_inputs, + padding=padding, + max_length=max_length, + truncation=truncation, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=return_attention_mask, + ) + + # convert input values to correct format + input_values = padded_inputs["input_values"] + if not isinstance(input_values[0], np.ndarray): + padded_inputs["input_values"] = [np.asarray(array, dtype=np.float32) for array in input_values] + elif ( + not isinstance(input_values, np.ndarray) + and isinstance(input_values[0], np.ndarray) + and input_values[0].dtype is np.dtype(np.float64) + ): + padded_inputs["input_values"] = [array.astype(np.float32) for array in input_values] + elif isinstance(input_values, np.ndarray) and input_values.dtype is np.dtype(np.float64): + padded_inputs["input_values"] = input_values.astype(np.float32) + + # convert attention_mask to correct format + attention_mask = padded_inputs.get("attention_mask") + if attention_mask is not None: + padded_inputs["attention_mask"] = [np.asarray(array, dtype=np.int32) for array in attention_mask] + + # zero-mean and unit-variance normalization + if self.do_normalize: + attention_mask = ( + attention_mask + if self._get_padding_strategies(padding, max_length=max_length) is not PaddingStrategy.DO_NOT_PAD + else None + ) + padded_inputs["input_values"] = self.zero_mean_unit_var_norm( + padded_inputs["input_values"], attention_mask=attention_mask, padding_value=self.padding_value + ) + + if return_tensors is not None: + padded_inputs = padded_inputs.convert_to_tensors(return_tensors) + + return padded_inputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..86cfb5e089ea006116541a5af3eacd17f0554a89 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_flax_wav2vec2.py @@ -0,0 +1,1425 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Flax Wav2Vec2 model.""" + +from functools import partial +from typing import Optional, Tuple, Union + +import flax +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax + +from ...modeling_flax_outputs import FlaxBaseModelOutput, FlaxCausalLMOutput +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import ModelOutput, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_wav2vec2 import Wav2Vec2Config + + +logger = logging.get_logger(__name__) + + +@flax.struct.dataclass +class FlaxWav2Vec2BaseModelOutput(ModelOutput): + """ + Output type of [`FlaxWav2Vec2BaseModelOutput`], with potential hidden states and attentions. + + Args: + last_hidden_state (`jnp.ndarray` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + extract_features (`jnp.ndarray` of shape `(batch_size, sequence_length, last_conv_dim)`): + Sequence of extracted feature vectors of the last convolutional layer of the model with `last_conv_dim` + being the dimension of the last convolutional layer. + hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + last_hidden_state: jnp.ndarray = None + extract_features: jnp.ndarray = None + hidden_states: Optional[Tuple[jnp.ndarray]] = None + attentions: Optional[Tuple[jnp.ndarray]] = None + + +@flax.struct.dataclass +class FlaxWav2Vec2ForPreTrainingOutput(ModelOutput): + """ + Output type of [`FlaxWav2Vec2ForPreTrainingOutput`], with potential hidden states and attentions. + + Args: + loss (*optional*, returned when model is in train mode, `jnp.ndarray` of shape `(1,)`): + Total loss as the sum of the contrastive loss (L_m) and the diversity loss (L_d) as stated in the [official + paper](https://arxiv.org/pdf/2006.11477.pdf) . (classification) loss. + projected_states (`jnp.ndarray` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Hidden-states of the model projected to *config.proj_codevector_dim* that can be used to predict the masked + projected quantized states. + projected_quantized_states (`jnp.ndarray` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Quantized extracted feature vectors projected to *config.proj_codevector_dim* representing the positive + target vectors for contrastive loss. + hidden_states (`tuple(jnp.ndarray)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `jnp.ndarray` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(jnp.ndarray)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `jnp.ndarray` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + projected_states: jnp.ndarray = None + projected_quantized_states: jnp.ndarray = None + codevector_perplexity: jnp.ndarray = None + hidden_states: Optional[Tuple[jnp.ndarray]] = None + attentions: Optional[Tuple[jnp.ndarray]] = None + + +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + attention_mask: Optional[np.ndarray] = None, + min_masks: int = 0, +) -> np.ndarray: + """ + Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for + ASR](https://arxiv.org/abs/1904.08779). Note that this method is not optimized to run on TPU and should be run on + CPU as part of the preprocessing during training. + + Args: + shape: the shape for which to compute masks. + should be of size 2 where first element is batch size and 2nd is timesteps + mask_prob: + probability for each token to be chosen as start of the span to be masked. this will be multiplied by + number of timesteps divided by length of mask span to mask approximately this percentage of all elements. + however due to overlaps, the actual number will be smaller (unless no_overlap is True) + mask_length: size of the mask + min_masks: minimum number of masked spans + + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + if mask_length > sequence_length: + raise ValueError( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and" + f" `sequence_length`: {sequence_length}`" + ) + + # compute number of masked spans in batch + num_masked_spans = int(mask_prob * sequence_length / mask_length + np.random.rand(1).item()) + num_masked_spans = max(num_masked_spans, min_masks) + + # make sure num masked indices <= sequence_length + if num_masked_spans * mask_length > sequence_length: + num_masked_spans = sequence_length // mask_length + + # SpecAugment mask to fill + spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) + + # get random indices to mask + spec_aug_mask_idxs = np.array( + [ + np.random.choice(np.arange(sequence_length - (mask_length - 1)), num_masked_spans, replace=False) + for _ in range(batch_size) + ] + ) + + # expand masked indices to masked spans + spec_aug_mask_idxs = np.broadcast_to(spec_aug_mask_idxs[:, :, None], (batch_size, num_masked_spans, mask_length)) + spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, num_masked_spans * mask_length) + + offsets = np.arange(mask_length)[None, None, :] + offsets = np.broadcast_to(offsets, (batch_size, num_masked_spans, mask_length)).reshape( + batch_size, num_masked_spans * mask_length + ) + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # scatter indices to mask + np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) + + if attention_mask is not None: + # make sure padded input ids cannot be masked + spec_aug_mask = np.where(attention_mask, spec_aug_mask, False) + + return spec_aug_mask + + +def _sample_negative_indices(features_shape: Tuple, num_negatives: int, attention_mask: Optional[np.ndarray] = None): + """ + Sample `num_negatives` vectors from feature vectors. + """ + batch_size, sequence_length, hidden_size = features_shape + if sequence_length <= 1: + raise ValueError( + "`features should have `sequence_length` > 1, but are of shape " + f"(batch_size, sequence_length, hidden_size) = ({batch_size, sequence_length, hidden_size})." + ) + + # get `num_negatives` random vector indices from the same utterance + sampled_negative_indices = [] + for batch_idx in range(batch_size): + high = attention_mask[batch_idx].sum() - 1 if attention_mask is not None else sequence_length - 1 + sampled_indices_slice = np.random.randint(0, high, size=(num_negatives * sequence_length,)) + sampled_negative_indices.append(sampled_indices_slice) + + sampled_negative_indices = np.asarray(sampled_negative_indices, dtype=np.int32) + + # generate indices of the positive vectors themselves, repeat them `num_negatives` times + feature_indices = np.broadcast_to(np.arange(sequence_length)[:, None], (sequence_length, num_negatives)).flatten() + + # avoid sampling the same positive vector, but keep the distribution uniform + sampled_negative_indices[sampled_negative_indices >= feature_indices] += 1 + + # correct for batch size + for batch_idx in range(1, batch_size): + sampled_negative_indices[batch_idx] += batch_idx * sequence_length + + return sampled_negative_indices + + +WAV_2_VEC_2_START_DOCSTRING = r""" + Wav2Vec2 was proposed in [wav2vec 2.0: A Framework for Self-Supervised Learning of Speech + Representations](https://arxiv.org/abs/2006.11477) by Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael + Auli. + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a Flax Linen + [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a + regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`Wav2Vec2Config`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + + +WAV_2_VEC_2_INPUTS_DOCSTRING = r""" + Args: + input_values (`jnp.ndarray` of shape `(batch_size, sequence_length)`): + Float values of input raw speech waveform. Values can be obtained by loading a `.flac` or `.wav` audio file + into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via the soundfile library (`pip install + soundfile`). To prepare the array into `input_values`, the [`AutoProcessor`] should be used for padding and + conversion into a tensor of type `jnp.ndarray`. See [`Wav2Vec2Processor.__call__`] for details. + attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing convolution and attention on padding token indices. Mask values selected in `[0, + 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) .. warning:: `attention_mask` should only be passed + if the corresponding processor has `config.return_attention_mask == True`. For all models whose processor + has `config.return_attention_mask == False`, such as + [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), `attention_mask` should **not** be + passed to avoid degraded performance when doing batched inference. For such models `input_values` should + simply be padded with 0 and passed without `attention_mask`. Be aware that these models also yield slightly + different results depending on whether `input_values` is padded or not. + mask_time_indices (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices to mask extracted features for contrastive loss. When in training mode, model learns to predict + masked extracted features in *config.proj_codevector_dim* space. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class FlaxWav2Vec2LayerNormConvLayer(nn.Module): + config: Wav2Vec2Config + layer_id: int = 0 + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.in_conv_dim = self.config.conv_dim[self.layer_id] if self.layer_id > 0 else 1 + self.out_conv_dim = self.config.conv_dim[self.layer_id] + + self.conv = nn.Conv( + features=self.config.conv_dim[self.layer_id], + kernel_size=(self.config.conv_kernel[self.layer_id],), + strides=(self.config.conv_stride[self.layer_id],), + use_bias=self.config.conv_bias, + kernel_init=jax.nn.initializers.he_normal(), + padding="VALID", + dtype=self.dtype, + ) + self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.activation = ACT2FN[self.config.feat_extract_activation] + + def __call__(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class FlaxConvWithWeightNorm(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.conv = nn.Conv( + features=self.config.hidden_size, + kernel_size=(self.config.num_conv_pos_embeddings,), + kernel_init=jax.nn.initializers.he_normal(), + padding="VALID", + feature_group_count=self.config.num_conv_pos_embedding_groups, + dtype=self.dtype, + ) + weight_shape = ( + self.conv.features, + self.conv.features // self.conv.feature_group_count, + self.conv.kernel_size[0], + ) + self.weight_v = self.param("weight_v", jax.nn.initializers.he_normal(), weight_shape) + self.weight_g = self.param("weight_g", lambda _: jnp.linalg.norm(self.weight_v, axis=(0, 1))[None, None, :]) + self.bias = self.param("bias", jax.nn.initializers.zeros, (self.conv.features,)) + self.prev_padding = self.conv.kernel_size[0] // 2 + + def _get_normed_weights(self): + weight_v_norm = jnp.linalg.norm(self.weight_v, axis=(0, 1))[None, None, :] + normed_weight_v = jnp.divide(self.weight_v, weight_v_norm) + normed_kernel = jnp.multiply(normed_weight_v, self.weight_g) + return normed_kernel + + def __call__(self, hidden_states): + kernel = self._get_normed_weights() + hidden_states = jnp.pad(hidden_states, ((0, 0), (self.prev_padding, self.prev_padding), (0, 0))) + hidden_states = self.conv.apply({"params": {"kernel": kernel.T, "bias": self.bias}}, hidden_states) + return hidden_states + + +class FlaxWav2Vec2PositionalConvEmbedding(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.conv = FlaxConvWithWeightNorm(self.config, dtype=self.dtype) + self.activation = ACT2FN[self.config.feat_extract_activation] + self.num_pad_remove = 1 if self.config.num_conv_pos_embeddings % 2 == 0 else 0 + + def __call__(self, hidden_states): + hidden_states = hidden_states.transpose((0, 1, 2)) + + hidden_states = self.conv(hidden_states) + + if self.num_pad_remove > 0: + hidden_states = hidden_states[:, : -self.num_pad_remove, :] + hidden_states = self.activation(hidden_states) + + hidden_states = hidden_states.transpose((0, 1, 2)) + return hidden_states + + +class FlaxConvLayersCollection(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + if self.config.feat_extract_norm == "layer": + self.layers = [ + FlaxWav2Vec2LayerNormConvLayer(self.config, layer_id=i, name=str(i), dtype=self.dtype) + for i in range(self.config.num_feat_extract_layers) + ] + elif self.config.feat_extract_norm == "group": + raise NotImplementedError("At the moment only ``config.feat_extact_norm == 'layer'`` is supported") + else: + raise ValueError( + f"`config.feat_extract_norm` is {self.config.feat_extract_norm}, but has to be one of ['group'," + " 'layer']" + ) + + def __call__(self, hidden_states): + for i, conv_layer in enumerate(self.layers): + hidden_states = conv_layer(hidden_states) + return hidden_states + + +class FlaxWav2Vec2FeatureEncoder(nn.Module): + """Construct the features from raw audio waveform""" + + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.conv_layers = FlaxConvLayersCollection(self.config, dtype=self.dtype) + + def __call__(self, input_values, freeze_feature_encoder=False): + hidden_states = input_values[:, :, None] + hidden_states = self.conv_layers(hidden_states) + if freeze_feature_encoder: + hidden_states = jax.lax.stop_gradient(hidden_states) + return hidden_states + + +class FlaxWav2Vec2FeatureProjection(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.projection = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.feat_proj_dropout) + + def __call__(self, hidden_states, deterministic=True): + norm_hidden_states = self.layer_norm(hidden_states) + hidden_states = self.projection(norm_hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states, norm_hidden_states + + +class FlaxWav2Vec2Attention(nn.Module): + config: Wav2Vec2Config + embed_dim: int + num_heads: int + dropout: float = 0.0 + bias: bool = True + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self) -> None: + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {self.num_heads})." + ) + + dense = partial( + nn.Dense, + self.embed_dim, + use_bias=self.bias, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + + self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() + self.out_proj = dense() + + self.dropout_layer = nn.Dropout(rate=self.dropout) + + def _split_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) + + def _merge_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) + + def __call__( + self, + hidden_states: jnp.ndarray, + key_value_states: Optional[jnp.ndarray] = None, + attention_mask: Optional[jnp.ndarray] = None, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + """Input shape: Batch x Time x Channel""" + + # get query proj + query_states = self.q_proj(hidden_states) + + key_states = self.k_proj(hidden_states) + value_states = self.v_proj(hidden_states) + + query_states = self._split_heads(query_states) + key_states = self._split_heads(key_states) + value_states = self._split_heads(value_states) + + if attention_mask is not None: + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.dropout > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.dropout, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = self._merge_heads(attn_output) + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights + + +class FlaxWav2Vec2FeedForward(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.intermediate_dropout = nn.Dropout(rate=self.config.activation_dropout) + + self.intermediate_dense = nn.Dense( + self.config.intermediate_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + if isinstance(self.config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[self.config.hidden_act] + else: + self.intermediate_act_fn = self.config.hidden_act + + self.output_dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.output_dropout = nn.Dropout(rate=self.config.hidden_dropout) + + def __call__(self, hidden_states, deterministic=True): + hidden_states = self.intermediate_dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + hidden_states = self.intermediate_dropout(hidden_states, deterministic=deterministic) + + hidden_states = self.output_dense(hidden_states) + hidden_states = self.output_dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +class FlaxWav2Vec2EncoderLayerStableLayerNorm(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.attention = FlaxWav2Vec2Attention( + config=self.config, + embed_dim=self.config.hidden_size, + num_heads=self.config.num_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout) + self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.feed_forward = FlaxWav2Vec2FeedForward(self.config, dtype=self.dtype) + self.final_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + + def __call__(self, hidden_states, attention_mask=None, deterministic=True, output_attentions=False): + attn_residual = hidden_states + hidden_states = self.layer_norm(hidden_states) + hidden_states, attn_weights = self.attention( + hidden_states, attention_mask=attention_mask, deterministic=deterministic + ) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = attn_residual + hidden_states + hidden_states = hidden_states + self.feed_forward( + self.final_layer_norm(hidden_states), deterministic=deterministic + ) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class FlaxWav2Vec2EncoderLayerStableLayerNormCollection(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.layers = [ + FlaxWav2Vec2EncoderLayerStableLayerNorm(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.num_hidden_layers) + ] + + def __call__( + self, + hidden_states, + attention_mask=None, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states += (hidden_states,) + + layer_outputs = layer( + hidden_states, attention_mask, deterministic=deterministic, output_attentions=output_attentions + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions += (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states, all_hidden_states, all_attentions) + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +class FlaxWav2Vec2StableLayerNormEncoder(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.pos_conv_embed = FlaxWav2Vec2PositionalConvEmbedding(self.config, dtype=self.dtype) + self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout) + self.layers = FlaxWav2Vec2EncoderLayerStableLayerNormCollection(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask=None, + deterministic=True, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + if attention_mask is not None: + # make sure padded tokens are not attended to + hidden_states = jnp.where( + jnp.broadcast_to(attention_mask[:, :, None], hidden_states.shape), hidden_states, 0 + ) + + position_embeddings = self.pos_conv_embed(hidden_states) + + hidden_states = hidden_states + position_embeddings + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_state = self.layer_norm(outputs[0]) + + # update the last element in `hidden_states` after applying `layernorm` above + hidden_states = None + if output_hidden_states: + hidden_states = outputs[1] + hidden_states = hidden_states[:-1] + (last_hidden_state,) + + if not return_dict: + outputs = (last_hidden_state, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=last_hidden_state, hidden_states=hidden_states, attentions=outputs.attentions + ) + + +class FlaxWav2Vec2GumbelVectorQuantizer(nn.Module): + """ + Vector quantization using gumbel softmax. See [CATEGORICAL REPARAMETERIZATION WITH + GUMBEL-SOFTMAX](https://arxiv.org/pdf/1611.01144.pdf) for more information. + """ + + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.num_groups = self.config.num_codevector_groups + self.num_vars = self.config.num_codevectors_per_group + + if self.config.codevector_dim % self.num_groups != 0: + raise ValueError( + f"`config.codevector_dim {self.config.codevector_dim} must be divisible by" + f" `config.num_codevector_groups` {self.num_groups} for concatenation" + ) + + # storage for codebook variables (codewords) + self.codevectors = self.param( + "codevectors", + jax.nn.initializers.uniform(), + (1, self.num_groups * self.num_vars, self.config.codevector_dim // self.num_groups), + ) + self.weight_proj = nn.Dense( + self.num_groups * self.num_vars, + kernel_init=jax.nn.initializers.normal(1.0), + dtype=self.dtype, + ) + + @staticmethod + def _compute_perplexity(probs, mask=None): + if mask is not None: + mask_extended = jnp.broadcast_to(mask.flatten()[:, None, None], probs.shape) + probs = jnp.where(mask_extended, probs, jnp.zeros_like(probs)) + marginal_probs = probs.sum(axis=0) / mask.sum() + else: + marginal_probs = probs.mean(axis=0) + + perplexity = jnp.exp(-jnp.sum(marginal_probs * jnp.log(marginal_probs + 1e-7), axis=-1)).sum() + return perplexity + + def __call__(self, hidden_states, mask_time_indices=None, deterministic=True, temperature=1): + batch_size, sequence_length, hidden_size = hidden_states.shape + + # project to codevector dim + hidden_states = self.weight_proj(hidden_states) + hidden_states = hidden_states.reshape(batch_size * sequence_length * self.num_groups, -1) + + if not deterministic: + # sample code vector probs via gumbel in differentiateable way + gumbel_rng = self.make_rng("gumbel") + gumbels = jax.random.gumbel(gumbel_rng, hidden_states.shape) + codevector_probs = nn.softmax((hidden_states + gumbels) / temperature) + + # compute perplexity + codevector_soft_dist = nn.softmax( + hidden_states.reshape(batch_size * sequence_length, self.num_groups, -1), axis=-1 + ) + perplexity = self._compute_perplexity(codevector_soft_dist, mask_time_indices) + else: + # take argmax in non-differentiable way + # comptute hard codevector distribution (one hot) + codevector_idx = hidden_states.argmax(axis=-1) + codevector_probs = jax.nn.one_hot(codevector_idx, hidden_states.shape[-1]) * 1.0 + codevector_probs = codevector_probs.reshape(batch_size * sequence_length, self.num_groups, -1) + perplexity = self._compute_perplexity(codevector_probs, mask_time_indices) + + codevector_probs = codevector_probs.reshape(batch_size * sequence_length, -1) + # use probs to retrieve codevectors + codevectors_per_group = jnp.expand_dims(codevector_probs, axis=-1) * self.codevectors + codevectors = codevectors_per_group.reshape(batch_size * sequence_length, self.num_groups, self.num_vars, -1) + codevectors = codevectors.sum(-2).reshape(batch_size, sequence_length, -1) + + return codevectors, perplexity + + +class FlaxWav2Vec2Adapter(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + # hidden_states require down-projection if feature dims don't match + if self.config.output_hidden_size != self.config.hidden_size: + self.proj = nn.Dense( + self.config.output_hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.proj_layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + else: + self.proj = self.proj_layer_norm = None + + self.layers = FlaxWav2Vec2AdapterLayersCollection(self.config, dtype=self.dtype) + + def __call__(self, hidden_states, deterministic=True): + # down-project hidden_states if required + if self.proj is not None and self.proj_layer_norm is not None: + hidden_states = self.proj(hidden_states) + hidden_states = self.proj_layer_norm(hidden_states) + + hidden_states = self.layers(hidden_states) + + return hidden_states + + +class FlaxWav2Vec2AdapterLayer(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.conv = nn.Conv( + features=2 * self.config.output_hidden_size, + kernel_size=(self.config.adapter_kernel_size,), + strides=(self.config.adapter_stride,), + padding=((1, 1),), + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = nn.glu(hidden_states, axis=2) + + return hidden_states + + +class FlaxWav2Vec2AdapterLayersCollection(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.layers = [ + FlaxWav2Vec2AdapterLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.num_adapter_layers) + ] + + def __call__(self, hidden_states): + for conv_layer in self.layers: + hidden_states = conv_layer(hidden_states) + + return hidden_states + + +class FlaxWav2Vec2PreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Wav2Vec2Config + base_model_prefix: str = "wav2vec2" + main_input_name = "input_values" + module_class: nn.Module = None + + def __init__( + self, + config: Wav2Vec2Config, + input_shape: Tuple = (1, 1024), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_values = jnp.zeros(input_shape, dtype="i4") + attention_mask = jnp.ones_like(input_values) + params_rng, dropout_rng = jax.random.split(rng, 2) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init(rngs, input_values, attention_mask, return_dict=False)["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + def __call__( + self, + input_values, + attention_mask=None, + mask_time_indices=None, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + freeze_feature_encoder: bool = False, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + batch_size, sequence_length = input_values.shape + + if attention_mask is None: + attention_mask = jnp.ones((batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + return self.module.apply( + inputs, + jnp.array(input_values, dtype="f4"), + jnp.array(attention_mask, dtype="i4"), + mask_time_indices, + not train, + output_attentions, + output_hidden_states, + freeze_feature_encoder, + return_dict, + rngs=rngs, + ) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None + ): + return self.module._get_feat_extract_output_lengths(input_lengths, add_adapter=add_adapter) + + +class FlaxWav2Vec2Module(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.feature_extractor = FlaxWav2Vec2FeatureEncoder(self.config, dtype=self.dtype) + self.feature_projection = FlaxWav2Vec2FeatureProjection(self.config, dtype=self.dtype) + self.masked_spec_embed = self.param( + "masked_spec_embed", jax.nn.initializers.uniform(), (self.config.hidden_size,) + ) + + if self.config.do_stable_layer_norm: + self.encoder = FlaxWav2Vec2StableLayerNormEncoder(self.config, dtype=self.dtype) + else: + raise NotImplementedError("``config.do_stable_layer_norm is False`` is currently not supported.") + + self.adapter = FlaxWav2Vec2Adapter(self.config, dtype=self.dtype) if self.config.add_adapter else None + + def __call__( + self, + input_values, + attention_mask=None, + mask_time_indices=None, + deterministic=True, + output_attentions=None, + output_hidden_states=None, + freeze_feature_encoder=False, + return_dict=None, + ): + extract_features = self.feature_extractor(input_values, freeze_feature_encoder=freeze_feature_encoder) + + # make sure that no loss is computed on padded inputs + if attention_mask is not None: + # compute reduced attention_mask corresponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + hidden_states, extract_features = self.feature_projection(extract_features, deterministic=deterministic) + if mask_time_indices is not None: # apply SpecAugment along time axis with given indices + hidden_states = jnp.where( + jnp.broadcast_to(mask_time_indices[:, :, None], hidden_states.shape), + jnp.broadcast_to(self.masked_spec_embed[None, None, :], hidden_states.shape), + hidden_states, + ) + + encoder_outputs = self.encoder( + hidden_states, + attention_mask=attention_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = encoder_outputs[0] + + if self.adapter is not None: + hidden_states = self.adapter(hidden_states) + + if not return_dict: + return (hidden_states, extract_features) + encoder_outputs[1:] + + return FlaxWav2Vec2BaseModelOutput( + last_hidden_state=hidden_states, + extract_features=extract_features, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + def _get_feature_vector_attention_mask( + self, feature_vector_length: int, attention_mask: jnp.ndarray, add_adapter=None + ): + # Effectively attention_mask.sum(-1), but not inplace to be able to run + # on inference mode. + non_padded_lengths = attention_mask.cumsum(axis=-1)[:, -1] + + output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) + + batch_size = attention_mask.shape[0] + + attention_mask = jnp.zeros((batch_size, feature_vector_length), dtype=attention_mask.dtype) + # these two operations makes sure that all values + # before the output lengths indices are attended to + attention_mask = attention_mask.at[jnp.arange(attention_mask.shape[0]), output_lengths - 1].set(1) + attention_mask = jnp.flip(jnp.flip(attention_mask, -1).cumsum(-1), -1).astype("bool") + return attention_mask + + +@add_start_docstrings( + "The bare Wav2Vec2 Model transformer outputting raw hidden-states without any specific head on top.", + WAV_2_VEC_2_START_DOCSTRING, +) +class FlaxWav2Vec2Model(FlaxWav2Vec2PreTrainedModel): + module_class = FlaxWav2Vec2Module + + +FLAX_WAV2VEC2_MODEL_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> from transformers import AutoProcessor, FlaxWav2Vec2Model + >>> from datasets import load_dataset + >>> import soundfile as sf + + >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-large-lv60") + >>> model = FlaxWav2Vec2Model.from_pretrained("facebook/wav2vec2-large-lv60") + + + >>> def map_to_array(batch): + ... speech, _ = sf.read(batch["file"]) + ... batch["speech"] = speech + ... return batch + + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> ds = ds.map(map_to_array) + + >>> input_values = processor( + ... ds["speech"][0], sampling_rate=16_000, return_tensors="np" + ... ).input_values # Batch size 1 + >>> hidden_states = model(input_values).last_hidden_state + ``` +""" + +overwrite_call_docstring( + FlaxWav2Vec2Model, + WAV_2_VEC_2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_MODEL_DOCSTRING, +) +append_replace_return_docstrings( + FlaxWav2Vec2Model, output_type=FlaxWav2Vec2BaseModelOutput, config_class=Wav2Vec2Config +) + + +class FlaxWav2Vec2ForCTCModule(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.wav2vec2 = FlaxWav2Vec2Module(self.config, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.final_dropout) + self.lm_head = nn.Dense( + self.config.vocab_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__( + self, + input_values, + attention_mask=None, + mask_time_indices=None, + deterministic=True, + output_attentions=None, + output_hidden_states=None, + freeze_feature_encoder=False, + return_dict=None, + ): + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + mask_time_indices=mask_time_indices, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + freeze_feature_encoder=freeze_feature_encoder, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + + logits = self.lm_head(hidden_states) + + if not return_dict: + return (logits,) + outputs[2:] + + return FlaxCausalLMOutput(logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) + + def _get_feat_extract_output_lengths( + self, + input_lengths: Union[jnp.ndarray, int], + add_adapter: Optional[bool] = None, + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + +@add_start_docstrings( + "Wav2Vec2 Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).", + WAV_2_VEC_2_START_DOCSTRING, +) +class FlaxWav2Vec2ForCTC(FlaxWav2Vec2PreTrainedModel): + module_class = FlaxWav2Vec2ForCTCModule + + +FLAX_WAV2VEC2_FOR_CTC_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> import jax.numpy as jnp + >>> from transformers import AutoProcessor, FlaxWav2Vec2ForCTC + >>> from datasets import load_dataset + >>> import soundfile as sf + + >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-large-960h-lv60") + >>> model = FlaxWav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-large-960h-lv60") + + + >>> def map_to_array(batch): + ... speech, _ = sf.read(batch["file"]) + ... batch["speech"] = speech + ... return batch + + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> ds = ds.map(map_to_array) + + >>> input_values = processor( + ... ds["speech"][0], sampling_rate=16_000, return_tensors="np" + ... ).input_values # Batch size 1 + >>> logits = model(input_values).logits + >>> predicted_ids = jnp.argmax(logits, axis=-1) + + >>> transcription = processor.decode(predicted_ids[0]) + >>> # should give: "A MAN SAID TO THE UNIVERSE SIR I EXIST" + ``` +""" + +overwrite_call_docstring( + FlaxWav2Vec2ForCTC, + WAV_2_VEC_2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_FOR_CTC_DOCSTRING, +) +append_replace_return_docstrings(FlaxWav2Vec2ForCTC, output_type=FlaxCausalLMOutput, config_class=Wav2Vec2Config) + + +class FlaxWav2Vec2ForPreTrainingModule(nn.Module): + config: Wav2Vec2Config + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.wav2vec2 = FlaxWav2Vec2Module(self.config, dtype=self.dtype) + self.dropout_features = nn.Dropout(self.config.feat_quantizer_dropout) + + self.quantizer = FlaxWav2Vec2GumbelVectorQuantizer(self.config, dtype=self.dtype) + self.project_q = nn.Dense( + self.config.proj_codevector_dim, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.project_hid = nn.Dense( + self.config.proj_codevector_dim, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__( + self, + input_values, + attention_mask=None, + mask_time_indices=None, + gumbel_temperature: int = 1, + deterministic: bool = True, + output_attentions=None, + output_hidden_states=None, + freeze_feature_encoder=False, + return_dict=None, + ): + r""" + Returns: + + Example: + + ```python + + ```""" + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + mask_time_indices=mask_time_indices, + deterministic=deterministic, + freeze_feature_encoder=freeze_feature_encoder, + return_dict=return_dict, + ) + + # project all transformed features (including masked) to final vq dim + transformer_features = self.project_hid(outputs[0]) + + # quantize all (unmasked) extracted features and project to final vq dim + extract_features = self.dropout_features(outputs[1], deterministic=deterministic) + quantized_features, codevector_perplexity = self.quantizer( + extract_features, mask_time_indices, deterministic=deterministic, temperature=gumbel_temperature + ) + quantized_features = self.project_q(quantized_features) + + if not return_dict: + return (transformer_features, quantized_features, codevector_perplexity) + outputs[2:] + + return FlaxWav2Vec2ForPreTrainingOutput( + projected_states=transformer_features, + projected_quantized_states=quantized_features, + codevector_perplexity=codevector_perplexity, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[jnp.ndarray, int], add_adapter: Optional[bool] = None + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + +@add_start_docstrings("""Wav2Vec2 Model with a quantizer and `VQ` head on top.""", WAV_2_VEC_2_START_DOCSTRING) +class FlaxWav2Vec2ForPreTraining(FlaxWav2Vec2PreTrainedModel): + module_class = FlaxWav2Vec2ForPreTrainingModule + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + # overwrite since has `gumbel_temperature` input + def __call__( + self, + input_values, + attention_mask=None, + mask_time_indices=None, + gumbel_temperature: int = 1, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + gumbel_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + freeze_feature_encoder: bool = False, + return_dict: Optional[bool] = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + batch_size, sequence_length = input_values.shape + + if attention_mask is None: + attention_mask = jnp.ones((batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + if gumbel_rng is not None: + rngs["gumbel"] = gumbel_rng + + inputs = {"params": params or self.params} + + return self.module.apply( + inputs, + jnp.array(input_values, dtype="f4"), + jnp.array(attention_mask, dtype="i4"), + mask_time_indices, + gumbel_temperature, + not train, + output_attentions, + output_hidden_states, + freeze_feature_encoder, + return_dict, + rngs=rngs, + ) + + +FLAX_WAV2VEC2_FOR_PRETRAINING_DOCSTRING = """ + Returns: + + Example: + + ```python + >>> import optax + >>> import numpy as np + >>> import jax.numpy as jnp + >>> from transformers import AutoFeatureExtractor, FlaxWav2Vec2ForPreTraining + >>> from transformers.models.wav2vec2.modeling_flax_wav2vec2 import _compute_mask_indices + >>> from datasets import load_dataset + >>> import soundfile as sf + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-large-lv60") + >>> model = FlaxWav2Vec2ForPreTraining.from_pretrained("facebook/wav2vec2-large-lv60") + + + >>> def map_to_array(batch): + ... speech, _ = sf.read(batch["file"]) + ... batch["speech"] = speech + ... return batch + + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> ds = ds.map(map_to_array) + + >>> input_values = feature_extractor(ds["speech"][0], return_tensors="np").input_values # Batch size 1 + + >>> # compute masked indices + >>> batch_size, raw_sequence_length = input_values.shape + >>> sequence_length = model._get_feat_extract_output_lengths(raw_sequence_length) + >>> mask_time_indices = _compute_mask_indices((batch_size, sequence_length), mask_prob=0.2, mask_length=2) + + >>> outputs = model(input_values, mask_time_indices=mask_time_indices) + + >>> # compute cosine similarity between predicted (=projected_states) and target (=projected_quantized_states) + >>> cosine_sim = optax.cosine_similarity(outputs.projected_states, outputs.projected_quantized_states) + + >>> # show that cosine similarity is much higher than random + >>> assert np.asarray(cosine_sim)[mask_time_indices].mean() > 0.5 + ``` +""" + +overwrite_call_docstring( + FlaxWav2Vec2ForPreTraining, + WAV_2_VEC_2_INPUTS_DOCSTRING + FLAX_WAV2VEC2_FOR_PRETRAINING_DOCSTRING, +) +append_replace_return_docstrings( + FlaxWav2Vec2ForPreTraining, output_type=FlaxWav2Vec2ForPreTrainingOutput, config_class=Wav2Vec2Config +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..dcc59d7f7322aa67bb90c6b62a8fab2d11ef33e8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_tf_wav2vec2.py @@ -0,0 +1,1716 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TensorFlow Wav2Vec2 model.""" + +import warnings +from dataclasses import dataclass +from typing import Any, Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import TFBaseModelOutput, TFCausalLMOutput, TFSequenceClassifierOutput +from ...modeling_tf_utils import ( + TFPreTrainedModel, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_wav2vec2 import Wav2Vec2Config + + +logger = logging.get_logger(__name__) + + +_HIDDEN_STATES_START_POSITION = 2 + +_CHECKPOINT_FOR_DOC = "facebook/wav2vec2-base-960h" +_CONFIG_FOR_DOC = "Wav2Vec2Config" + +TF_WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/wav2vec2-base-960h", + "facebook/wav2vec2-large-960h", + "facebook/wav2vec2-large-960h-lv60", + "facebook/wav2vec2-large-960h-lv60-self", + # See all Wav2Vec2 models at https://huggingface.co/models?filter=wav2vec2 +] + +LARGE_NEGATIVE = -1e8 + + +@dataclass +class TFWav2Vec2BaseModelOutput(ModelOutput): + """ + Output type of [`TFWav2Vec2BaseModelOutput`], with potential hidden states and attentions. + + Args: + last_hidden_state (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`): + Sequence of hidden-states at the output of the last layer of the model. + extract_features (`tf.Tensor` of shape `(batch_size, sequence_length, conv_dim[-1])`): + Sequence of extracted feature vectors of the last convolutional layer of the model. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + last_hidden_state: tf.Tensor = None + extract_features: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +def _sample_without_replacement(distribution, num_samples): + """ + Categorical sampling without replacement is currently not implemented. The gumbel-max trick will do for now - see + https://github.com/tensorflow/tensorflow/issues/9260 for more info + """ + z = -tf.math.log(tf.random.uniform(shape_list(distribution), 0, 1)) + _, indices = tf.nn.top_k(distribution + z, num_samples) + return indices + + +def _scatter_values_on_batch_indices(values, batch_indices, output_shape): + """ + Scatter function as in PyTorch with indices in format (batch_dim, indixes) + """ + indices_shape = shape_list(batch_indices) + # broadcast batch dim to indices_shape + broad_casted_batch_dims = tf.reshape( + tf.broadcast_to(tf.expand_dims(tf.range(indices_shape[0]), axis=-1), indices_shape), [1, -1] + ) + # transform batch_indices to pair_indices + pair_indices = tf.transpose(tf.concat([broad_casted_batch_dims, tf.reshape(batch_indices, [1, -1])], 0)) + # scatter values to pair indices + return tf.scatter_nd(pair_indices, tf.reshape(values, [-1]), output_shape) + + +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + min_masks: int = 0, +) -> tf.Tensor: + """ + Computes random mask spans for a given shape + + Args: + shape: the shape for which to compute masks. + should be of size 2 where first element is batch size and 2nd is timesteps + attention_mask: optional padding mask of the same size as shape, which will prevent masking padded elements + mask_prob: + probability for each token to be chosen as start of the span to be masked. this will be multiplied by + number of timesteps divided by length of mask span to mask approximately this percentage of all elements. + however due to overlaps, the actual number will be smaller (unless no_overlap is True) + mask_length: size of the mask + min_masks: minimum number of masked spans + + Adapted from [fairseq's + data_utils.py](https://github.com/pytorch/fairseq/blob/e0788f7007a8473a76db573985031f3c94201e79/fairseq/data/data_utils.py#L376). + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + tf.debugging.assert_less( + mask_length, + sequence_length, + message=( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length} and" + f" `sequence_length`: {sequence_length}`" + ), + ) + + # compute number of masked spans in batch + num_masked_spans = mask_prob * tf.cast(sequence_length, tf.float32) / mask_length + tf.random.uniform((1,)) + num_masked_spans = tf.maximum(num_masked_spans, min_masks) + num_masked_spans = tf.cast(num_masked_spans, tf.int32) + + # make sure num masked indices <= sequence_length + num_masked_spans = tf.math.minimum(sequence_length // mask_length, num_masked_spans) + num_masked_spans = tf.squeeze(num_masked_spans) + + # SpecAugment mask to fill + spec_aug_mask = tf.zeros((batch_size, sequence_length), dtype=tf.int32) + + # uniform distribution to sample from, make sure that offset samples are < sequence_length + uniform_dist = tf.ones((batch_size, sequence_length - (mask_length - 1))) + + # get random indices to mask + spec_aug_mask_idxs = _sample_without_replacement(uniform_dist, num_masked_spans) + + # expand masked indices to masked spans + spec_aug_mask_idxs = tf.expand_dims(spec_aug_mask_idxs, -1) + spec_aug_mask_idxs = tf.tile(spec_aug_mask_idxs, (1, 1, mask_length)) + spec_aug_mask_idxs = tf.reshape(spec_aug_mask_idxs, (batch_size, num_masked_spans * mask_length)) + + offsets = tf.range(mask_length)[tf.newaxis, tf.newaxis, :] + offsets = tf.tile(offsets, (batch_size, num_masked_spans, 1)) + offsets = tf.reshape(offsets, (batch_size, num_masked_spans * mask_length)) + + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # scatter indices to mask + spec_aug_mask = _scatter_values_on_batch_indices( + tf.ones_like(spec_aug_mask_idxs), spec_aug_mask_idxs, tf.shape(spec_aug_mask) + ) + + return spec_aug_mask + + +# Copied from transformers.models.bart.modeling_tf_bart._expand_mask +def _expand_mask(mask: tf.Tensor, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + src_len = shape_list(mask)[1] + tgt_len = tgt_len if tgt_len is not None else src_len + one_cst = tf.constant(1.0) + mask = tf.cast(mask, dtype=one_cst.dtype) + expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) + + return (one_cst - expanded_mask) * LARGE_NEGATIVE + + +class TFWav2Vec2GroupNorm(tf.keras.layers.Layer): + """ + From tensorflow-addons https://www.tensorflow.org/addons/api_docs/python/tfa/layers/GroupNormalization + """ + + def __init__( + self, + groups: int = 32, + axis: int = -1, + epsilon: float = 1e-3, + center: bool = True, + scale: bool = True, + beta_initializer: tf.keras.initializers.Initializer = "zeros", + gamma_initializer: tf.keras.initializers.Initializer = "ones", + beta_regularizer: tf.keras.regularizers.Regularizer = None, + gamma_regularizer: tf.keras.regularizers.Regularizer = None, + beta_constraint: tf.keras.constraints.Constraint = None, + gamma_constraint: tf.keras.constraints.Constraint = None, + **kwargs, + ): + super().__init__(**kwargs) + self.supports_masking = True + self.groups = groups + self.axis = axis + self.epsilon = epsilon + self.center = center + self.scale = scale + self.beta_initializer = tf.keras.initializers.get(beta_initializer) + self.gamma_initializer = tf.keras.initializers.get(gamma_initializer) + self.beta_regularizer = tf.keras.regularizers.get(beta_regularizer) + self.gamma_regularizer = tf.keras.regularizers.get(gamma_regularizer) + self.beta_constraint = tf.keras.constraints.get(beta_constraint) + self.gamma_constraint = tf.keras.constraints.get(gamma_constraint) + self._check_axis() + + def build(self, input_shape): + self._check_if_input_shape_is_none(input_shape) + self._set_number_of_groups_for_instance_norm(input_shape) + self._check_size_of_dimensions(input_shape) + self._create_input_spec(input_shape) + + self._add_gamma_weight(input_shape) + self._add_beta_weight(input_shape) + self.built = True + super().build(input_shape) + + def call(self, inputs): + input_shape = tf.keras.backend.int_shape(inputs) + tensor_input_shape = tf.shape(inputs) + + reshaped_inputs, group_shape = self._reshape_into_groups(inputs, input_shape, tensor_input_shape) + + normalized_inputs = self._apply_normalization(reshaped_inputs, input_shape) + + is_instance_norm = (input_shape[self.axis] // self.groups) == 1 + if not is_instance_norm: + outputs = tf.reshape(normalized_inputs, tensor_input_shape) + else: + outputs = normalized_inputs + + return outputs + + def get_config(self): + config = { + "groups": self.groups, + "axis": self.axis, + "epsilon": self.epsilon, + "center": self.center, + "scale": self.scale, + "beta_initializer": tf.keras.initializers.serialize(self.beta_initializer), + "gamma_initializer": tf.keras.initializers.serialize(self.gamma_initializer), + "beta_regularizer": tf.keras.regularizers.serialize(self.beta_regularizer), + "gamma_regularizer": tf.keras.regularizers.serialize(self.gamma_regularizer), + "beta_constraint": tf.keras.constraints.serialize(self.beta_constraint), + "gamma_constraint": tf.keras.constraints.serialize(self.gamma_constraint), + } + base_config = super().get_config() + return {**base_config, **config} + + def compute_output_shape(self, input_shape): + return input_shape + + def _reshape_into_groups(self, inputs, input_shape, tensor_input_shape): + group_shape = [tensor_input_shape[i] for i in range(len(input_shape))] + is_instance_norm = (input_shape[self.axis] // self.groups) == 1 + if not is_instance_norm: + group_shape[self.axis] = input_shape[self.axis] // self.groups + group_shape.insert(self.axis, self.groups) + group_shape = tf.stack(group_shape) + reshaped_inputs = tf.reshape(inputs, group_shape) + return reshaped_inputs, group_shape + else: + return inputs, group_shape + + def _apply_normalization(self, reshaped_inputs, input_shape): + group_shape = tf.keras.backend.int_shape(reshaped_inputs) + group_reduction_axes = list(range(1, len(group_shape))) + is_instance_norm = (input_shape[self.axis] // self.groups) == 1 + if not is_instance_norm: + axis = -2 if self.axis == -1 else self.axis - 1 + else: + axis = -1 if self.axis == -1 else self.axis - 1 + group_reduction_axes.pop(axis) + + mean, variance = tf.nn.moments(reshaped_inputs, group_reduction_axes, keepdims=True) + + gamma, beta = self._get_reshaped_weights(input_shape) + normalized_inputs = tf.nn.batch_normalization( + reshaped_inputs, + mean=mean, + variance=variance, + scale=gamma, + offset=beta, + variance_epsilon=self.epsilon, + ) + return normalized_inputs + + def _get_reshaped_weights(self, input_shape): + broadcast_shape = self._create_broadcast_shape(input_shape) + gamma = None + beta = None + if self.scale: + gamma = tf.reshape(self.gamma, broadcast_shape) + + if self.center: + beta = tf.reshape(self.beta, broadcast_shape) + return gamma, beta + + def _check_if_input_shape_is_none(self, input_shape): + dim = input_shape[self.axis] + if dim is None: + raise ValueError( + "Axis " + + str(self.axis) + + " of input tensor should have a defined dimension but the layer received an input with shape " + + str(input_shape) + + "." + ) + + def _set_number_of_groups_for_instance_norm(self, input_shape): + dim = input_shape[self.axis] + + if self.groups == -1: + self.groups = dim + + def _check_size_of_dimensions(self, input_shape): + dim = input_shape[self.axis] + if dim < self.groups: + raise ValueError( + "Number of groups (" + + str(self.groups) + + ") cannot be more than the number of channels (" + + str(dim) + + ")." + ) + + if dim % self.groups != 0: + raise ValueError( + "Number of groups (" + + str(self.groups) + + ") must be a multiple of the number of channels (" + + str(dim) + + ")." + ) + + def _check_axis(self): + if self.axis == 0: + raise ValueError( + "You are trying to normalize your batch axis. Do you want to use tf.layer.batch_normalization instead" + ) + + def _create_input_spec(self, input_shape): + dim = input_shape[self.axis] + self.input_spec = tf.keras.layers.InputSpec(ndim=len(input_shape), axes={self.axis: dim}) + + def _add_gamma_weight(self, input_shape): + dim = input_shape[self.axis] + shape = (dim,) + + if self.scale: + self.gamma = self.add_weight( + shape=shape, + name="gamma", + initializer=self.gamma_initializer, + regularizer=self.gamma_regularizer, + constraint=self.gamma_constraint, + ) + else: + self.gamma = None + + def _add_beta_weight(self, input_shape): + dim = input_shape[self.axis] + shape = (dim,) + + if self.center: + self.beta = self.add_weight( + shape=shape, + name="beta", + initializer=self.beta_initializer, + regularizer=self.beta_regularizer, + constraint=self.beta_constraint, + ) + else: + self.beta = None + + def _create_broadcast_shape(self, input_shape): + broadcast_shape = [1] * len(input_shape) + is_instance_norm = (input_shape[self.axis] // self.groups) == 1 + if not is_instance_norm: + broadcast_shape[self.axis] = input_shape[self.axis] // self.groups + broadcast_shape.insert(self.axis, self.groups) + else: + broadcast_shape[self.axis] = self.groups + return broadcast_shape + + +class TFWav2Vec2WeightNormConv1D(tf.keras.layers.Conv1D): + """Adapted from https://www.tensorflow.org/probability/api_docs/python/tfp/layers/weight_norm/WeightNorm""" + + def __init__(self, filters, kernel_size, groups, explicit_padding, **kwargs): + super().__init__( + filters=filters, + kernel_size=kernel_size, + groups=groups, + padding="valid", + use_bias=True, + bias_initializer="he_normal", + **kwargs, + ) + self.explicit_padding = explicit_padding + self.filter_axis = 2 + self.initialized = False + self.kernel_norm_axes = tf.constant([0, 1]) + + def _init_norm(self): + """Set the norm of the weight vector.""" + kernel_norm = tf.sqrt(tf.reduce_sum(tf.square(self.weight_v), axis=self.kernel_norm_axes)) + self.weight_g.assign(kernel_norm[:, tf.newaxis, tf.newaxis]) + + def _normalize_kernel(self): + """Generate normalized weights.""" + kernel = tf.nn.l2_normalize(self.weight_v, axis=self.kernel_norm_axes) * tf.transpose(self.weight_g) + self.kernel = tf.transpose(kernel) + + def build(self, input_shape): + if not self.built: + input_shape = input_shape.as_list() + # Conv1D output shapes are checked at build time since TF 2.7, so we need to account for padding + input_shape[-2] += self.explicit_padding * 2 + super().build(input_shape) + + self.kernel = tf.Variable(tf.transpose(self.kernel), name="weight_v", trainable=True) + self.weight_v = self.kernel + + self.weight_g = self.add_weight( + name="weight_g", + shape=(int(self.weight_v.shape[self.filter_axis]), 1, 1), + initializer="ones", + dtype=self.weight_v.dtype, + trainable=True, + ) + self.bias = self.add_weight(name="bias", shape=(self.filters,), initializer="zeros", trainable=True) + + def call(self, inputs): + if not self.initialized: + self._init_norm() + self.initialized = True + + self._normalize_kernel() + + padded_inputs = tf.pad(inputs, ((0, 0), (self.explicit_padding, self.explicit_padding), (0, 0))) + output = super().call(padded_inputs) + + return output + + +class TFWav2Vec2NoLayerNormConvLayer(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: + super().__init__(**kwargs) + self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = tf.keras.layers.Conv1D( + filters=self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + strides=config.conv_stride[layer_id], + use_bias=config.conv_bias, + name="conv", + ) + self.activation = get_tf_activation(config.feat_extract_activation) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.conv(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class TFWav2Vec2LayerNormConvLayer(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: + super().__init__(**kwargs) + self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = tf.keras.layers.Conv1D( + filters=self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + strides=config.conv_stride[layer_id], + use_bias=config.conv_bias, + name="conv", + ) + self.layer_norm = tf.keras.layers.LayerNormalization(name="layer_norm", epsilon=config.layer_norm_eps) + self.activation = get_tf_activation(config.feat_extract_activation) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class TFWav2Vec2GroupNormConvLayer(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, layer_id: int = 0, **kwargs: Any) -> None: + super().__init__(**kwargs) + self.in_conv_dim = config.conv_dim[layer_id] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = tf.keras.layers.Conv1D( + filters=self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + strides=config.conv_stride[layer_id], + use_bias=config.conv_bias, + name="conv", + ) + self.activation = get_tf_activation(config.feat_extract_activation) + self.layer_norm = TFWav2Vec2GroupNorm( + groups=self.out_conv_dim, epsilon=config.layer_norm_eps, name="layer_norm" + ) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class TFWav2Vec2PositionalConvEmbedding(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs: Any) -> None: + super().__init__(**kwargs) + self.conv = TFWav2Vec2WeightNormConv1D( + filters=config.hidden_size, + kernel_size=config.num_conv_pos_embeddings, + groups=config.num_conv_pos_embedding_groups, + explicit_padding=config.num_conv_pos_embeddings // 2, + name="conv", + ) + self.padding = TFWav2Vec2SamePadLayer(config.num_conv_pos_embeddings) + self.activation = get_tf_activation(config.feat_extract_activation) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.conv(hidden_states) + hidden_states = self.padding(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class TFWav2Vec2SamePadLayer(tf.keras.layers.Layer): + def __init__(self, num_conv_pos_embeddings, **kwargs): + super().__init__(**kwargs) + self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 + + def call(self, hidden_states): + if self.num_pad_remove > 0: + hidden_states = hidden_states[:, : -self.num_pad_remove, :] + return hidden_states + + +class TFWav2Vec2FeatureEncoder(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs: Any) -> None: + super().__init__(**kwargs) + + if config.feat_extract_norm == "group": + conv_layers = [TFWav2Vec2GroupNormConvLayer(config, layer_id=0, name=f"conv_layers.{0}")] + [ + TFWav2Vec2NoLayerNormConvLayer(config, layer_id=i + 1, name=f"conv_layers.{i+1}") + for i in range(config.num_feat_extract_layers - 1) + ] + elif config.feat_extract_norm == "layer": + conv_layers = [ + TFWav2Vec2LayerNormConvLayer(config, layer_id=i, name=f"conv_layers.{i}") + for i in range(config.num_feat_extract_layers) + ] + else: + raise ValueError( + f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" + ) + self.conv_layers = conv_layers + + def call(self, input_values): + hidden_states = tf.expand_dims(input_values, -1) + for conv_layer in self.conv_layers: + hidden_states = conv_layer(hidden_states) + return hidden_states + + +class TFWav2Vec2FeatureExtractor(TFWav2Vec2FeatureEncoder): + def __init__(self, config, **kwargs): + super().__init__(config, **kwargs) + warnings.warn( + f"The class `{self.__class__.__name__}` has been depreciated " + "and will be removed in Transformers v5. " + f"Use `{self.__class__.__bases__[0].__name__}` instead.", + FutureWarning, + ) + + +class TFWav2Vec2FeatureProjection(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.projection = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + bias_initializer="zeros", + name="projection", + ) + self.dropout = tf.keras.layers.Dropout(rate=config.feat_proj_dropout) + + def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: + norm_hidden_states = self.layer_norm(hidden_states) + hidden_states = self.projection(norm_hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + return hidden_states, norm_hidden_states + + +# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with TFBart->TFWav2Vec2 +class TFWav2Vec2Attention(tf.keras.layers.Layer): + """Multi-headed attention from "Attention Is All You Need""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + **kwargs, + ): + super().__init__(**kwargs) + self.embed_dim = embed_dim + + self.num_heads = num_heads + self.dropout = tf.keras.layers.Dropout(dropout) + self.head_dim = embed_dim // num_heads + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") + self.q_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") + self.v_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") + self.out_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") + + def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): + return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) + + def call( + self, + hidden_states: tf.Tensor, + key_value_states: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[Tuple[tf.Tensor]]] = None, + attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, Optional[tf.Tensor]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + bsz, tgt_len, embed_dim = shape_list(hidden_states) + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = tf.concat([past_key_value[0], key_states], axis=2) + value_states = tf.concat([past_key_value[1], value_states], axis=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) + key_states = tf.reshape(key_states, proj_shape) + value_states = tf.reshape(value_states, proj_shape) + + src_len = shape_list(key_states)[1] + attn_weights = tf.matmul(query_states, key_states, transpose_b=True) + + tf.debugging.assert_equal( + shape_list(attn_weights), + [bsz * self.num_heads, tgt_len, src_len], + message=( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {shape_list(attn_weights)}" + ), + ) + + if attention_mask is not None: + tf.debugging.assert_equal( + shape_list(attention_mask), + [bsz, 1, tgt_len, src_len], + message=( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {shape_list(attention_mask)}" + ), + ) + + attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) + attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_weights = stable_softmax(attn_weights, axis=-1) + + if layer_head_mask is not None: + tf.debugging.assert_equal( + shape_list(layer_head_mask), + [self.num_heads], + message=( + f"Head mask for a single layer should be of size {(self.num_heads)}, but is" + f" {shape_list(layer_head_mask)}" + ), + ) + + attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( + attn_weights, (bsz, self.num_heads, tgt_len, src_len) + ) + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_probs = self.dropout(attn_weights, training=training) + attn_output = tf.matmul(attn_probs, value_states) + + tf.debugging.assert_equal( + shape_list(attn_output), + [bsz * self.num_heads, tgt_len, self.head_dim], + message=( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {shape_list(attn_output)}" + ), + ) + + attn_output = tf.transpose( + tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) + ) + attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) + + attn_output = self.out_proj(attn_output) + attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + + return attn_output, attn_weights, past_key_value + + +class TFWav2Vec2FeedForward(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + + self.intermediate_dropout = tf.keras.layers.Dropout(config.activation_dropout) + + self.intermediate_dense = tf.keras.layers.Dense( + units=config.intermediate_size, + kernel_initializer=get_initializer(config.initializer_range), + bias_initializer="zeros", + name="intermediate_dense", + ) + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + + self.output_dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + bias_initializer="zeros", + name="output_dense", + ) + self.output_dropout = tf.keras.layers.Dropout(config.hidden_dropout) + + def call(self, hidden_states: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.intermediate_dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + hidden_states = self.intermediate_dropout(hidden_states, training=training) + + hidden_states = self.output_dense(hidden_states) + hidden_states = self.output_dropout(hidden_states, training=training) + return hidden_states + + +class TFWav2Vec2EncoderLayer(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + self.attention = TFWav2Vec2Attention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + is_decoder=False, + name="attention", + ) + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout) + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.feed_forward = TFWav2Vec2FeedForward(config, name="feed_forward") + self.final_layer_norm = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="final_layer_norm" + ) + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attn_residual = hidden_states + hidden_states, attn_weights, _ = self.attention( + hidden_states, attention_mask=attention_mask, training=training + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = attn_residual + hidden_states + + hidden_states = self.layer_norm(hidden_states) + hidden_states = hidden_states + self.feed_forward(hidden_states) + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class TFWav2Vec2EncoderLayerStableLayerNorm(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + self.attention = TFWav2Vec2Attention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + is_decoder=False, + name="attention", + ) + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout) + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.feed_forward = TFWav2Vec2FeedForward(config, name="feed_forward") + self.final_layer_norm = tf.keras.layers.LayerNormalization( + epsilon=config.layer_norm_eps, name="final_layer_norm" + ) + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = False, + training: bool = False, + ) -> Tuple[tf.Tensor]: + attn_residual = hidden_states + hidden_states = self.layer_norm(hidden_states) + hidden_states, attn_weights, _ = self.attention( + hidden_states, attention_mask=attention_mask, training=training + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = attn_residual + hidden_states + hidden_states = hidden_states + self.feed_forward(self.final_layer_norm(hidden_states)) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class TFWav2Vec2Encoder(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + self.config = config + self.pos_conv_embed = TFWav2Vec2PositionalConvEmbedding(config, name="pos_conv_embed") + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout) + self.layer = [TFWav2Vec2EncoderLayer(config, name=f"layers.{i}") for i in range(config.num_hidden_layers)] + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) + attention_mask = _expand_mask(attention_mask) + else: + attention_mask = None + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + if training and (dropout_probability < self.config.layerdrop): # skip the layer + continue + + layer_outputs = layer_module( + hidden_states=hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return TFBaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class TFWav2Vec2EncoderStableLayerNorm(tf.keras.layers.Layer): + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + self.config = config + self.pos_conv_embed = TFWav2Vec2PositionalConvEmbedding(config, name="pos_conv_embed") + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout) + self.layer = [ + TFWav2Vec2EncoderLayerStableLayerNorm(config, name=f"layers.{i}") for i in range(config.num_hidden_layers) + ] + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + training: Optional[bool] = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + hidden_states = hidden_states * tf.expand_dims(attention_mask, -1) + attention_mask = _expand_mask(attention_mask) + else: + attention_mask = None + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.dropout(hidden_states, training=training) + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + if training and (dropout_probability < self.config.layerdrop): # skip the layer + continue + + layer_outputs = layer_module( + hidden_states=hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + hidden_states = self.layer_norm(hidden_states) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return TFBaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +@keras_serializable +class TFWav2Vec2MainLayer(tf.keras.layers.Layer): + config_class = Wav2Vec2Config + + def __init__(self, config: Wav2Vec2Config, **kwargs): + super().__init__(**kwargs) + self.config = config + self.feature_extractor = TFWav2Vec2FeatureEncoder(config, name="feature_extractor") + self.feature_projection = TFWav2Vec2FeatureProjection(config, name="feature_projection") + + if config.do_stable_layer_norm: + self.encoder = TFWav2Vec2EncoderStableLayerNorm(config, name="encoder") + else: + self.encoder = TFWav2Vec2Encoder(config, name="encoder") + + def build(self, input_shape: tf.TensorShape): + self.masked_spec_embed = self.add_weight( + shape=(self.config.hidden_size,), initializer="uniform", trainable=True, name="masked_spec_embed" + ) + + super().build(input_shape) + + def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor): + """ + Computes the output length of the convolutional layers + """ + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + return input_lengths + + def _mask_hidden_states(self, hidden_states: tf.Tensor, mask_time_indices: Optional[tf.Tensor] = None): + """ + Masks extracted features along time axis and/or along feature axis according to + [SpecAugment](https://arxiv.org/abs/1904.08779). + """ + batch_size, sequence_length, hidden_size = shape_list(hidden_states) + + # `config.apply_spec_augment` can set masking to False + if not getattr(self.config, "apply_spec_augment", True): + return hidden_states + + if mask_time_indices is not None: + # apply SpecAugment along time axis with given mask_time_indices + hidden_states = tf.where( + tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), + self.masked_spec_embed[tf.newaxis, tf.newaxis, :], + hidden_states, + ) + + elif self.config.mask_time_prob > 0: + # generate indices & apply SpecAugment along time axis + mask_time_indices = _compute_mask_indices( + (batch_size, sequence_length), + mask_prob=self.config.mask_time_prob, + mask_length=self.config.mask_time_length, + min_masks=2, + ) + hidden_states = tf.where( + tf.cast(mask_time_indices[:, :, tf.newaxis], tf.bool), + self.masked_spec_embed[tf.newaxis, tf.newaxis, :], + hidden_states, + ) + + # apply SpecAugment along feature axis + if self.config.mask_feature_prob > 0: + mask_feature_indices = _compute_mask_indices( + (batch_size, hidden_size), + mask_prob=self.config.mask_feature_prob, + mask_length=self.config.mask_feature_length, + ) + hidden_states = tf.where(mask_feature_indices[:, tf.newaxis, :], hidden_states, 0) + + return hidden_states + + @unpack_inputs + def call( + self, + input_values: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + position_ids: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + **kwargs: Any, + ): + extract_features = self.feature_extractor(tf.cast(input_values, tf.float32), training=training) + # extract_features = tf.transpose(extract_features, perm=(0, 2, 1)) + + if attention_mask is not None: + # compute real output lengths according to convolution formula + output_lengths = self._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, -1)) + + attention_mask = tf.sequence_mask( + output_lengths, maxlen=shape_list(extract_features)[1], dtype=extract_features.dtype + ) + + hidden_states, extract_features = self.feature_projection(extract_features, training=training) + + mask_time_indices = kwargs.get("mask_time_indices", None) + if training: + hidden_states = self._mask_hidden_states(hidden_states, mask_time_indices=mask_time_indices) + + encoder_outputs = self.encoder( + hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_states = encoder_outputs[0] + + if not return_dict: + return (hidden_states, extract_features) + encoder_outputs[1:] + + return TFWav2Vec2BaseModelOutput( + last_hidden_state=hidden_states, + extract_features=extract_features, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class TFWav2Vec2PreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Wav2Vec2Config + base_model_prefix = "wav2vec2" + main_input_name = "input_values" + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + pad_token = 0.0 + input_values = tf.convert_to_tensor(np.random.rand(1, 16000), tf.float32) + dummy_inputs = { + "input_values": input_values, + "attention_mask": tf.cast(tf.not_equal(input_values, pad_token), tf.float32), + } + return dummy_inputs + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + logger.warning( + f"\n{self.__class__.__name__} has backpropagation operations that are NOT supported on CPU. If you wish " + "to train/fine-tine this model, you need a GPU or a TPU" + ) + + @tf.function( + input_signature=[ + { + "input_values": tf.TensorSpec((None, None), tf.float32, name="input_values"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + "token_type_ids": tf.TensorSpec((None, None), tf.int32, name="token_type_ids"), + } + ] + ) + def serving(self, inputs): + output = self.call(input_values=inputs, training=False) + + return self.serving_output(output) + + def _get_feat_extract_output_lengths(self, input_lengths, add_adapter=None): + """ + Computes the output length of the convolutional layers + """ + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + return tf.math.floordiv(input_length - kernel_size, stride) + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + return input_lengths + + def _get_feature_vector_attention_mask( + self, feature_vector_length: int, attention_mask: tf.Tensor, add_adapter=None + ): + non_padded_lengths = tf.math.cumsum(attention_mask, axis=-1)[:, -1] + output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) + output_lengths = tf.cast(output_lengths, tf.int32) + batch_size = tf.shape(attention_mask)[0] + # check device here + attention_mask = tf.zeros( + (batch_size, feature_vector_length), dtype=attention_mask.dtype, name="attention_mask" + ) # these two operations makes sure that all values before the output lengths idxs are attended to + ## check device + attention_mask = tf.tensor_scatter_nd_update( + attention_mask, + indices=tf.stack([tf.range(batch_size), output_lengths - 1], axis=1), + updates=tf.ones([batch_size], dtype=attention_mask.dtype), + ) + attention_mask = tf.reverse(attention_mask, axis=[-1]) + attention_mask = tf.cumsum(attention_mask, axis=-1) + attention_mask = tf.reverse(attention_mask, axis=[-1]) + attention_mask = tf.cast(attention_mask, tf.bool) + return attention_mask + + +WAV_2_VEC_2_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_values` only and nothing else: `model(input_values)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_values, attention_mask])` or `model([input_values, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_values": input_values, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`Wav2Vec2Config`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +WAV_2_VEC_2_INPUTS_DOCSTRING = r""" + Args: + input_values (`np.ndarray`, `tf.Tensor`, `List[tf.Tensor]` `Dict[str, tf.Tensor]` or `Dict[str, np.ndarray]` and each example must have the shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and + [`PreTrainedTokenizer.encode`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`np.ndarray` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`np.ndarray` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`np.ndarray` or `tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_values` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_values` indices into associated vectors + than the model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False``): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare TFWav2Vec2 Model transformer outputing raw hidden-states without any specific head on top.", + WAV_2_VEC_2_START_DOCSTRING, +) +class TFWav2Vec2Model(TFWav2Vec2PreTrainedModel): + def __init__(self, config: Wav2Vec2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.config = config + self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFBaseModelOutput, config_class=_CONFIG_FOR_DOC) + @unpack_inputs + def call( + self, + input_values: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + position_ids: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + """ + + Returns: + + Example: + + ```python + >>> from transformers import AutoProcessor, TFWav2Vec2Model + >>> from datasets import load_dataset + >>> import soundfile as sf + + >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h") + >>> model = TFWav2Vec2Model.from_pretrained("facebook/wav2vec2-base-960h") + + + >>> def map_to_array(batch): + ... speech, _ = sf.read(batch["file"]) + ... batch["speech"] = speech + ... return batch + + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> ds = ds.map(map_to_array) + + >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 + >>> hidden_states = model(input_values).last_hidden_state + ```""" + + output_hidden_states = output_hidden_states if output_hidden_states else self.config.output_hidden_states + output_attentions = output_attentions if output_attentions else self.config.output_attentions + return_dict = return_dict if return_dict else self.config.return_dict + + outputs = self.wav2vec2( + input_values=input_values, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output): + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFWav2Vec2BaseModelOutput( + last_hidden_state=output.last_hidden_state, + extract_features=output.extract_features, + hidden_states=hidden_states, + attentions=attentions, + ) + + +@add_start_docstrings( + """TFWav2Vec2 Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", + WAV_2_VEC_2_START_DOCSTRING, +) +class TFWav2Vec2ForCTC(TFWav2Vec2PreTrainedModel): + def __init__(self, config: Wav2Vec2Config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") + self.dropout = tf.keras.layers.Dropout(config.final_dropout) + self.lm_head = tf.keras.layers.Dense(config.vocab_size, name="lm_head") + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor.trainable = False + + @unpack_inputs + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFCausalLMOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_values: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + token_type_ids: Optional[tf.Tensor] = None, + position_ids: Optional[tf.Tensor] = None, + head_mask: Optional[tf.Tensor] = None, + inputs_embeds: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + labels: Optional[tf.Tensor] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[TFCausalLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_values` docstring) Tokens with indices set to `-100` are ignored (masked), + the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + + Returns: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import AutoProcessor, TFWav2Vec2ForCTC + >>> from datasets import load_dataset + >>> import soundfile as sf + + >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h") + >>> model = TFWav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h") + + + >>> def map_to_array(batch): + ... speech, _ = sf.read(batch["file"]) + ... batch["speech"] = speech + ... return batch + + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> ds = ds.map(map_to_array) + + >>> input_values = processor(ds["speech"][0], return_tensors="tf").input_values # Batch size 1 + >>> logits = model(input_values).logits + >>> predicted_ids = tf.argmax(logits, axis=-1) + + >>> transcription = processor.decode(predicted_ids[0]) + + >>> # compute loss + >>> target_transcription = "A MAN SAID TO THE UNIVERSE SIR I EXIST" + + >>> # Pass transcription as `text` to encode labels + >>> labels = processor(text=transcription, return_tensors="tf").input_ids + + >>> loss = model(input_values, labels=labels).loss + ```""" + + outputs = self.wav2vec2( + input_values=input_values, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states, training=training) + + logits = self.lm_head(hidden_states) + + if labels is not None: + if tf.reduce_max(labels) >= self.config.vocab_size: + raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") + + attention_mask = ( + attention_mask if attention_mask is not None else tf.ones_like(input_values, dtype=tf.float32) + ) + input_lengths = self.wav2vec2._get_feat_extract_output_lengths(tf.reduce_sum(attention_mask, axis=-1)) + + # assuming that padded tokens are filled with -100 + # when not being attended to + labels_mask = tf.cast(labels >= 0, tf.int32) + target_lengths = tf.reduce_sum(labels_mask, axis=-1) + + loss = tf.nn.ctc_loss( + logits=logits, + labels=labels, + logit_length=input_lengths, + label_length=target_lengths, + blank_index=self.config.pad_token_id, + logits_time_major=False, + ) + + if self.config.ctc_loss_reduction == "sum": + loss = tf.reduce_sum(loss) + if self.config.ctc_loss_reduction == "mean": + loss = tf.reduce_mean(loss) + + loss = tf.reshape(loss, (1,)) + else: + loss = None + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return TFCausalLMOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output: TFCausalLMOutput) -> TFCausalLMOutput: + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + return TFCausalLMOutput(logits=output.logits, hidden_states=hidden_states, attentions=attentions) + + +class TFWav2Vec2ForSequenceClassification(TFWav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.wav2vec2 = TFWav2Vec2MainLayer(config, name="wav2vec2") + self.num_layers = config.num_hidden_layers + 1 + with tf.name_scope(self._name_scope()): + if config.use_weighted_layer_sum: + self.layer_weights = self.add_weight( + shape=(self.num_layers,), initializer="ones", trainable=True, name="layer_weights" + ) + self.config = config + self.projector = tf.keras.layers.Dense(units=config.classifier_proj_size, name="projector") + self.classifier = tf.keras.layers.Dense(units=config.num_labels, activation=None, name="classifier") + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor.trainable = False + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for layer in self.wav2vec2.layers: + layer.trainable = False + + @unpack_inputs + def call( + self, + input_values: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[tf.Tensor] = None, + training: bool = False, + ): + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = tf.stack(hidden_states, axis=1) + norm_weights = tf.nn.softmax(self.layer_weights, axis=-1) + hidden_states = tf.reduce_sum(hidden_states * tf.reshape(norm_weights, [-1, 1, 1]), axis=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + if attention_mask is None: + pooled_output = tf.reduce_mean(hidden_states, axis=1) + else: + padding_mask = self._get_feature_vector_attention_mask(hidden_states.shape[1], attention_mask) + padding_mask_float = tf.cast(padding_mask, hidden_states.dtype) + hidden_states = tf.multiply(hidden_states, tf.expand_dims(padding_mask_float, axis=-1)) + pooled_output = tf.divide( + tf.reduce_sum(hidden_states, axis=1), tf.expand_dims(tf.reduce_sum(padding_mask_float, axis=1), axis=1) + ) + logits = self.classifier(pooled_output) + loss = None + if labels is not None: + loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) + loss = loss_fn(tf.reshape(labels, [-1]), tf.reshape(logits, [-1, self.config.num_labels])) + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + def serving_output(self, output): + hidden_states = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attentions = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput( + logits=output.logits, + hidden_states=hidden_states, + attentions=attentions, + ) + + @tf.function( + input_signature=[ + { + "input_values": tf.TensorSpec((None, None), tf.float32, name="input_values"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + "token_type_ids": tf.TensorSpec((None, None), tf.int32, name="token_type_ids"), + } + ] + ) + def serving(self, inputs): + output = self.call(input_values=inputs) + + return self.serving_output(output) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..bcf7b7a3ad8df7b4f171d7c08d6bcaa68a8bef5c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/modeling_wav2vec2.py @@ -0,0 +1,2170 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Wav2Vec2 model.""" + +import math +import warnings +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import numpy as np +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...deepspeed import is_deepspeed_zero3_enabled +from ...modeling_outputs import ( + BaseModelOutput, + CausalLMOutput, + MaskedLMOutput, + SequenceClassifierOutput, + TokenClassifierOutput, + Wav2Vec2BaseModelOutput, + XVectorOutput, +) +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_wav2vec2 import Wav2Vec2Config + + +logger = logging.get_logger(__name__) + + +_HIDDEN_STATES_START_POSITION = 2 + +# General docstring +_CONFIG_FOR_DOC = "Wav2Vec2Config" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/wav2vec2-base-960h" +_EXPECTED_OUTPUT_SHAPE = [1, 292, 768] + +# CTC docstring +_CTC_EXPECTED_OUTPUT = "'MISTER QUILTER IS THE APOSTLE OF THE MIDDLE CLASSES AND WE ARE GLAD TO WELCOME HIS GOSPEL'" +_CTC_EXPECTED_LOSS = 53.48 + +# Audio class docstring +_SEQ_CLASS_CHECKPOINT = "superb/wav2vec2-base-superb-ks" +_SEQ_CLASS_EXPECTED_OUTPUT = "'_unknown_'" +_SEQ_CLASS_EXPECTED_LOSS = 6.54 + +# Frame class docstring +_FRAME_CLASS_CHECKPOINT = "anton-l/wav2vec2-base-superb-sd" +_FRAME_EXPECTED_OUTPUT = [0, 0] + +# Speaker Verification docstring +_XVECTOR_CHECKPOINT = "anton-l/wav2vec2-base-superb-sv" +_XVECTOR_EXPECTED_OUTPUT = 0.98 + + +WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/wav2vec2-base-960h", + "facebook/wav2vec2-large-960h", + "facebook/wav2vec2-large-960h-lv60", + "facebook/wav2vec2-large-960h-lv60-self", + # See all Wav2Vec2 models at https://huggingface.co/models?filter=wav2vec2 +] + + +@dataclass +class Wav2Vec2ForPreTrainingOutput(ModelOutput): + """ + Output type of [`Wav2Vec2ForPreTraining`], with potential hidden states and attentions. + + Args: + loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + Total loss as the sum of the contrastive loss (L_m) and the diversity loss (L_d) as stated in the [official + paper](https://arxiv.org/pdf/2006.11477.pdf) . (classification) loss. + projected_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Hidden-states of the model projected to *config.proj_codevector_dim* that can be used to predict the masked + projected quantized states. + projected_quantized_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Quantized extracted feature vectors projected to *config.proj_codevector_dim* representing the positive + target vectors for contrastive loss. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + contrastive_loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + The contrastive loss (L_m) as stated in the [official paper](https://arxiv.org/pdf/2006.11477.pdf) . + diversity_loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + The diversity loss (L_d) as stated in the [official paper](https://arxiv.org/pdf/2006.11477.pdf) . + """ + + loss: Optional[torch.FloatTensor] = None + projected_states: torch.FloatTensor = None + projected_quantized_states: torch.FloatTensor = None + codevector_perplexity: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + contrastive_loss: Optional[torch.FloatTensor] = None + diversity_loss: Optional[torch.FloatTensor] = None + + +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + attention_mask: Optional[torch.LongTensor] = None, + min_masks: int = 0, +) -> np.ndarray: + """ + Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for + ASR](https://arxiv.org/abs/1904.08779). Note that this method is not optimized to run on TPU and should be run on + CPU as part of the preprocessing during training. + + Args: + shape: The shape for which to compute masks. This should be of a tuple of size 2 where + the first element is the batch size and the second element is the length of the axis to span. + mask_prob: The percentage of the whole axis (between 0 and 1) which will be masked. The number of + independently generated mask spans of length `mask_length` is computed by + `mask_prob*shape[1]/mask_length`. Note that due to overlaps, `mask_prob` is an upper bound and the + actual percentage will be smaller. + mask_length: size of the mask + min_masks: minimum number of masked spans + attention_mask: A (right-padded) attention mask which independently shortens the feature axis of + each batch dimension. + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + if mask_length > sequence_length: + raise ValueError( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length}" + f" and `sequence_length`: {sequence_length}`" + ) + + # epsilon is used for probabilistic rounding + epsilon = np.random.rand(1).item() + + def compute_num_masked_span(input_length): + """Given input length, compute how many spans should be masked""" + num_masked_span = int(mask_prob * input_length / mask_length + epsilon) + num_masked_span = max(num_masked_span, min_masks) + + # make sure num masked span <= sequence_length + if num_masked_span * mask_length > sequence_length: + num_masked_span = sequence_length // mask_length + + # make sure num_masked span is also <= input_length - (mask_length - 1) + if input_length - (mask_length - 1) < num_masked_span: + num_masked_span = max(input_length - (mask_length - 1), 0) + + return num_masked_span + + # compute number of masked spans in batch + input_lengths = ( + attention_mask.sum(-1).detach().tolist() + if attention_mask is not None + else [sequence_length for _ in range(batch_size)] + ) + + # SpecAugment mask to fill + spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) + spec_aug_mask_idxs = [] + + max_num_masked_span = compute_num_masked_span(sequence_length) + + if max_num_masked_span == 0: + return spec_aug_mask + + for input_length in input_lengths: + # compute num of masked spans for this input + num_masked_span = compute_num_masked_span(input_length) + + # get random indices to mask + spec_aug_mask_idx = np.random.choice( + np.arange(input_length - (mask_length - 1)), num_masked_span, replace=False + ) + + # pick first sampled index that will serve as a dummy index to pad vector + # to ensure same dimension for all batches due to probabilistic rounding + # Picking first sample just pads those vectors twice. + if len(spec_aug_mask_idx) == 0: + # this case can only happen if `input_length` is strictly smaller then + # `sequence_length` in which case the last token has to be a padding + # token which we can use as a dummy mask id + dummy_mask_idx = sequence_length - 1 + else: + dummy_mask_idx = spec_aug_mask_idx[0] + + spec_aug_mask_idx = np.concatenate( + [spec_aug_mask_idx, np.ones(max_num_masked_span - num_masked_span, dtype=np.int32) * dummy_mask_idx] + ) + spec_aug_mask_idxs.append(spec_aug_mask_idx) + + spec_aug_mask_idxs = np.array(spec_aug_mask_idxs) + + # expand masked indices to masked spans + spec_aug_mask_idxs = np.broadcast_to( + spec_aug_mask_idxs[:, :, None], (batch_size, max_num_masked_span, mask_length) + ) + spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, max_num_masked_span * mask_length) + + # add offset to the starting indexes so that indexes now create a span + offsets = np.arange(mask_length)[None, None, :] + offsets = np.broadcast_to(offsets, (batch_size, max_num_masked_span, mask_length)).reshape( + batch_size, max_num_masked_span * mask_length + ) + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # ensure that we cannot have indices larger than sequence_length + if spec_aug_mask_idxs.max() > sequence_length - 1: + spec_aug_mask_idxs[spec_aug_mask_idxs > sequence_length - 1] = sequence_length - 1 + + # scatter indices to mask + np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) + + return spec_aug_mask + + +def _sample_negative_indices( + features_shape: Tuple, num_negatives: int, mask_time_indices: Optional[np.ndarray] = None +): + """ + Sample `num_negatives` vectors from feature vectors. + """ + batch_size, sequence_length = features_shape + + # generate indices of the positive vectors themselves, repeat them `num_negatives` times + sequence_length_range = np.arange(sequence_length) + + # get `num_negatives` random vector indices from the same utterance + sampled_negative_indices = np.zeros(shape=(batch_size, sequence_length, num_negatives), dtype=np.int32) + + mask_time_indices = ( + mask_time_indices.astype(bool) if mask_time_indices is not None else np.ones(features_shape, dtype=bool) + ) + + for batch_idx in range(batch_size): + high = mask_time_indices[batch_idx].sum() - 1 + mapped_masked_indices = sequence_length_range[mask_time_indices[batch_idx]] + + feature_indices = np.broadcast_to(np.arange(high + 1)[:, None], (high + 1, num_negatives)) + sampled_indices = np.random.randint(0, high, size=(high + 1, num_negatives)) + # avoid sampling the same positive vector, but keep the distribution uniform + sampled_indices[sampled_indices >= feature_indices] += 1 + + # remap to actual indices + sampled_negative_indices[batch_idx][mask_time_indices[batch_idx]] = mapped_masked_indices[sampled_indices] + + # correct for batch size + sampled_negative_indices[batch_idx] += batch_idx * sequence_length + + return sampled_negative_indices + + +class Wav2Vec2NoLayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class Wav2Vec2LayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.layer_norm = nn.LayerNorm(self.out_conv_dim, elementwise_affine=True) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + + hidden_states = hidden_states.transpose(-2, -1) + hidden_states = self.layer_norm(hidden_states) + hidden_states = hidden_states.transpose(-2, -1) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +class Wav2Vec2GroupNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + self.layer_norm = nn.GroupNorm(num_groups=self.out_conv_dim, num_channels=self.out_conv_dim, affine=True) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +class Wav2Vec2PositionalConvEmbedding(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.hidden_size, + config.hidden_size, + kernel_size=config.num_conv_pos_embeddings, + padding=config.num_conv_pos_embeddings // 2, + groups=config.num_conv_pos_embedding_groups, + ) + + if is_deepspeed_zero3_enabled(): + import deepspeed + + with deepspeed.zero.GatheredParameters(self.conv.weight, modifier_rank=0): + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + deepspeed.zero.register_external_parameter(self, self.conv.weight_v) + deepspeed.zero.register_external_parameter(self, self.conv.weight_g) + else: + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + + self.padding = Wav2Vec2SamePadLayer(config.num_conv_pos_embeddings) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = hidden_states.transpose(1, 2) + + hidden_states = self.conv(hidden_states) + hidden_states = self.padding(hidden_states) + hidden_states = self.activation(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +class Wav2Vec2SamePadLayer(nn.Module): + def __init__(self, num_conv_pos_embeddings): + super().__init__() + self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 + + def forward(self, hidden_states): + if self.num_pad_remove > 0: + hidden_states = hidden_states[:, :, : -self.num_pad_remove] + return hidden_states + + +class Wav2Vec2FeatureEncoder(nn.Module): + """Construct the features from raw audio waveform""" + + def __init__(self, config): + super().__init__() + + if config.feat_extract_norm == "group": + conv_layers = [Wav2Vec2GroupNormConvLayer(config, layer_id=0)] + [ + Wav2Vec2NoLayerNormConvLayer(config, layer_id=i + 1) for i in range(config.num_feat_extract_layers - 1) + ] + elif config.feat_extract_norm == "layer": + conv_layers = [ + Wav2Vec2LayerNormConvLayer(config, layer_id=i) for i in range(config.num_feat_extract_layers) + ] + else: + raise ValueError( + f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" + ) + self.conv_layers = nn.ModuleList(conv_layers) + self.gradient_checkpointing = False + self._requires_grad = True + + def _freeze_parameters(self): + for param in self.parameters(): + param.requires_grad = False + self._requires_grad = False + + def forward(self, input_values): + hidden_states = input_values[:, None] + + # make sure hidden_states require grad for gradient_checkpointing + if self._requires_grad and self.training: + hidden_states.requires_grad = True + + for conv_layer in self.conv_layers: + if self._requires_grad and self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(conv_layer), + hidden_states, + ) + else: + hidden_states = conv_layer(hidden_states) + + return hidden_states + + +class Wav2Vec2FeatureExtractor(Wav2Vec2FeatureEncoder): + def __init__(self, config): + super().__init__(config) + warnings.warn( + f"The class `{self.__class__.__name__}` has been depreciated " + "and will be removed in Transformers v5. " + f"Use `{self.__class__.__bases__[0].__name__}` instead.", + FutureWarning, + ) + + +class Wav2Vec2FeatureProjection(nn.Module): + def __init__(self, config): + super().__init__() + self.layer_norm = nn.LayerNorm(config.conv_dim[-1], eps=config.layer_norm_eps) + self.projection = nn.Linear(config.conv_dim[-1], config.hidden_size) + self.dropout = nn.Dropout(config.feat_proj_dropout) + + def forward(self, hidden_states): + # non-projected hidden states are needed for quantization + norm_hidden_states = self.layer_norm(hidden_states) + hidden_states = self.projection(norm_hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states, norm_hidden_states + + +# Copied from transformers.models.bart.modeling_bart.BartAttention with Bart->Wav2Vec2 +class Wav2Vec2Attention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states: torch.Tensor, + key_value_states: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + + bsz, tgt_len, _ = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + # `past_key_value[0].shape[2] == key_value_states.shape[1]` + # is checking that the `sequence_length` of the `past_key_value` is the same as + # the provided `key_value_states` to support prefix tuning + if ( + is_cross_attention + and past_key_value is not None + and past_key_value[0].shape[2] == key_value_states.shape[1] + ): + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = torch.cat([past_key_value[0], key_states], dim=2) + value_states = torch.cat([past_key_value[1], value_states], dim=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.reshape(*proj_shape) + value_states = value_states.reshape(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if layer_head_mask is not None: + if layer_head_mask.size() != (self.num_heads,): + raise ValueError( + f"Head mask for a single layer should be of size {(self.num_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to be reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz * self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + + # Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be + # partitioned across GPUs when using tensor-parallelism. + attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped, past_key_value + + +class Wav2Vec2FeedForward(nn.Module): + def __init__(self, config): + super().__init__() + self.intermediate_dropout = nn.Dropout(config.activation_dropout) + + self.intermediate_dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + self.output_dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.output_dropout = nn.Dropout(config.hidden_dropout) + + def forward(self, hidden_states): + hidden_states = self.intermediate_dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + hidden_states = self.intermediate_dropout(hidden_states) + + hidden_states = self.output_dense(hidden_states) + hidden_states = self.output_dropout(hidden_states) + return hidden_states + + +class Wav2Vec2EncoderLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.attention = Wav2Vec2Attention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + is_decoder=False, + ) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.feed_forward = Wav2Vec2FeedForward(config) + self.final_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states, attention_mask=None, output_attentions=False): + attn_residual = hidden_states + hidden_states, attn_weights, _ = self.attention( + hidden_states, attention_mask=attention_mask, output_attentions=output_attentions + ) + hidden_states = self.dropout(hidden_states) + hidden_states = attn_residual + hidden_states + + hidden_states = self.layer_norm(hidden_states) + hidden_states = hidden_states + self.feed_forward(hidden_states) + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class Wav2Vec2EncoderLayerStableLayerNorm(nn.Module): + def __init__(self, config): + super().__init__() + self.attention = Wav2Vec2Attention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + is_decoder=False, + ) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.feed_forward = Wav2Vec2FeedForward(config) + self.final_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ): + attn_residual = hidden_states + hidden_states = self.layer_norm(hidden_states) + hidden_states, attn_weights, _ = self.attention( + hidden_states, attention_mask=attention_mask, output_attentions=output_attentions + ) + hidden_states = self.dropout(hidden_states) + hidden_states = attn_residual + hidden_states + hidden_states = hidden_states + self.feed_forward(self.final_layer_norm(hidden_states)) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class Wav2Vec2Encoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.pos_conv_embed = Wav2Vec2PositionalConvEmbedding(config) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layers = nn.ModuleList([Wav2Vec2EncoderLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.tensor, + attention_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + # make sure padded tokens output 0 + expand_attention_mask = attention_mask.unsqueeze(-1).repeat(1, 1, hidden_states.shape[2]) + hidden_states[~expand_attention_mask] = 0 + + # extend attention_mask + attention_mask = 1.0 - attention_mask[:, None, None, :].to(dtype=hidden_states.dtype) + attention_mask = attention_mask * torch.finfo(hidden_states.dtype).min + attention_mask = attention_mask.expand( + attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1] + ) + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.dropout(hidden_states) + + deepspeed_zero3_is_enabled = is_deepspeed_zero3_enabled() + + for layer in self.layers: + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + + skip_the_layer = True if self.training and (dropout_probability < self.config.layerdrop) else False + if not skip_the_layer or deepspeed_zero3_is_enabled: + # under deepspeed zero3 all gpus must run in sync + if self.gradient_checkpointing and self.training: + # create gradient checkpointing function + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer), + hidden_states, + attention_mask, + ) + else: + layer_outputs = layer( + hidden_states, attention_mask=attention_mask, output_attentions=output_attentions + ) + hidden_states = layer_outputs[0] + + if skip_the_layer: + layer_outputs = (None, None) + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class Wav2Vec2EncoderStableLayerNorm(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.pos_conv_embed = Wav2Vec2PositionalConvEmbedding(config) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layers = nn.ModuleList( + [Wav2Vec2EncoderLayerStableLayerNorm(config) for _ in range(config.num_hidden_layers)] + ) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + # make sure padded tokens are not attended to + expand_attention_mask = attention_mask.unsqueeze(-1).repeat(1, 1, hidden_states.shape[2]) + hidden_states[~expand_attention_mask] = 0 + + # extend attention_mask + attention_mask = 1.0 - attention_mask[:, None, None, :].to(dtype=hidden_states.dtype) + attention_mask = attention_mask * torch.finfo(hidden_states.dtype).min + attention_mask = attention_mask.expand( + attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1] + ) + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.dropout(hidden_states) + + deepspeed_zero3_is_enabled = is_deepspeed_zero3_enabled() + + for layer in self.layers: + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + + skip_the_layer = True if self.training and (dropout_probability < self.config.layerdrop) else False + if not skip_the_layer or deepspeed_zero3_is_enabled: + # under deepspeed zero3 all gpus must run in sync + # XXX: could optimize this like synced_gpus in generate_utils but not sure if it's worth the code complication + if self.gradient_checkpointing and self.training: + # create gradient checkpointing function + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer), + hidden_states, + attention_mask, + ) + else: + layer_outputs = layer( + hidden_states, attention_mask=attention_mask, output_attentions=output_attentions + ) + hidden_states = layer_outputs[0] + + if skip_the_layer: + layer_outputs = (None, None) + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + hidden_states = self.layer_norm(hidden_states) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class Wav2Vec2GumbelVectorQuantizer(nn.Module): + """ + Vector quantization using gumbel softmax. See `[CATEGORICAL REPARAMETERIZATION WITH + GUMBEL-SOFTMAX](https://arxiv.org/pdf/1611.01144.pdf) for more information. + """ + + def __init__(self, config): + super().__init__() + self.num_groups = config.num_codevector_groups + self.num_vars = config.num_codevectors_per_group + + if config.codevector_dim % self.num_groups != 0: + raise ValueError( + f"`config.codevector_dim {config.codevector_dim} must be divisible " + f"by `config.num_codevector_groups` {self.num_groups} for concatenation" + ) + + # storage for codebook variables (codewords) + self.codevectors = nn.Parameter( + torch.FloatTensor(1, self.num_groups * self.num_vars, config.codevector_dim // self.num_groups) + ) + self.weight_proj = nn.Linear(config.conv_dim[-1], self.num_groups * self.num_vars) + + # can be decayed for training + self.temperature = 2 + + @staticmethod + def _compute_perplexity(probs, mask=None): + if mask is not None: + mask_extended = mask.flatten()[:, None, None].expand(probs.shape) + probs = torch.where(mask_extended, probs, torch.zeros_like(probs)) + marginal_probs = probs.sum(dim=0) / mask.sum() + else: + marginal_probs = probs.mean(dim=0) + + perplexity = torch.exp(-torch.sum(marginal_probs * torch.log(marginal_probs + 1e-7), dim=-1)).sum() + return perplexity + + def forward(self, hidden_states, mask_time_indices=None): + batch_size, sequence_length, hidden_size = hidden_states.shape + + # project to codevector dim + hidden_states = self.weight_proj(hidden_states) + hidden_states = hidden_states.view(batch_size * sequence_length * self.num_groups, -1) + + if self.training: + # sample code vector probs via gumbel in differentiateable way + codevector_probs = nn.functional.gumbel_softmax( + hidden_states.float(), tau=self.temperature, hard=True + ).type_as(hidden_states) + + # compute perplexity + codevector_soft_dist = torch.softmax( + hidden_states.view(batch_size * sequence_length, self.num_groups, -1).float(), dim=-1 + ) + perplexity = self._compute_perplexity(codevector_soft_dist, mask_time_indices) + else: + # take argmax in non-differentiable way + # comptute hard codevector distribution (one hot) + codevector_idx = hidden_states.argmax(dim=-1) + codevector_probs = hidden_states.new_zeros(hidden_states.shape).scatter_( + -1, codevector_idx.view(-1, 1), 1.0 + ) + codevector_probs = codevector_probs.view(batch_size * sequence_length, self.num_groups, -1) + + perplexity = self._compute_perplexity(codevector_probs, mask_time_indices) + + codevector_probs = codevector_probs.view(batch_size * sequence_length, -1) + # use probs to retrieve codevectors + codevectors_per_group = codevector_probs.unsqueeze(-1) * self.codevectors + codevectors = codevectors_per_group.view(batch_size * sequence_length, self.num_groups, self.num_vars, -1) + codevectors = codevectors.sum(-2).view(batch_size, sequence_length, -1) + + return codevectors, perplexity + + +class Wav2Vec2Adapter(nn.Module): + def __init__(self, config): + super().__init__() + + # feature dim might need to be down-projected + if config.output_hidden_size != config.hidden_size: + self.proj = nn.Linear(config.hidden_size, config.output_hidden_size) + self.proj_layer_norm = nn.LayerNorm(config.output_hidden_size) + else: + self.proj = self.proj_layer_norm = None + + self.layers = nn.ModuleList(Wav2Vec2AdapterLayer(config) for _ in range(config.num_adapter_layers)) + self.layerdrop = config.layerdrop + + def forward(self, hidden_states): + # down project hidden_states if necessary + if self.proj is not None and self.proj_layer_norm is not None: + hidden_states = self.proj(hidden_states) + hidden_states = self.proj_layer_norm(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + + for layer in self.layers: + layerdrop_prob = np.random.random() + if not self.training or (layerdrop_prob > self.layerdrop): + hidden_states = layer(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +class Wav2Vec2AdapterLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.output_hidden_size, + 2 * config.output_hidden_size, + config.adapter_kernel_size, + stride=config.adapter_stride, + padding=1, + ) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = nn.functional.glu(hidden_states, dim=1) + + return hidden_states + + +class Wav2Vec2PreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Wav2Vec2Config + base_model_prefix = "wav2vec2" + main_input_name = "input_values" + _keys_to_ignore_on_load_missing = [r"position_ids"] + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights""" + # Wav2Vec2ForPreTraining last 2 linear layers need standard Linear init. + if isinstance(module, Wav2Vec2ForPreTraining): + module.project_hid.reset_parameters() + module.project_q.reset_parameters() + module.project_hid._is_hf_initialized = True + module.project_q._is_hf_initialized = True + # gumbel softmax requires special init + elif isinstance(module, Wav2Vec2GumbelVectorQuantizer): + module.weight_proj.weight.data.normal_(mean=0.0, std=1) + module.weight_proj.bias.data.zero_() + nn.init.uniform_(module.codevectors) + elif isinstance(module, Wav2Vec2PositionalConvEmbedding): + nn.init.normal_( + module.conv.weight, + mean=0, + std=2 * math.sqrt(1 / (module.conv.kernel_size[0] * module.conv.in_channels)), + ) + nn.init.constant_(module.conv.bias, 0) + elif isinstance(module, Wav2Vec2FeatureProjection): + k = math.sqrt(1 / module.projection.in_features) + nn.init.uniform_(module.projection.weight, a=-k, b=k) + nn.init.uniform_(module.projection.bias, a=-k, b=k) + elif isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, nn.Conv1d): + nn.init.kaiming_normal_(module.weight) + + if module.bias is not None: + k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0])) + nn.init.uniform_(module.bias, a=-k, b=k) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[torch.LongTensor, int], add_adapter: Optional[bool] = None + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return torch.div(input_length - kernel_size, stride, rounding_mode="floor") + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + def _get_feature_vector_attention_mask( + self, feature_vector_length: int, attention_mask: torch.LongTensor, add_adapter=None + ): + # Effectively attention_mask.sum(-1), but not inplace to be able to run + # on inference mode. + non_padded_lengths = attention_mask.cumsum(dim=-1)[:, -1] + + output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) + output_lengths = output_lengths.to(torch.long) + + batch_size = attention_mask.shape[0] + + attention_mask = torch.zeros( + (batch_size, feature_vector_length), dtype=attention_mask.dtype, device=attention_mask.device + ) + # these two operations makes sure that all values before the output lengths idxs are attended to + attention_mask[(torch.arange(attention_mask.shape[0], device=attention_mask.device), output_lengths - 1)] = 1 + attention_mask = attention_mask.flip([-1]).cumsum(-1).flip([-1]).bool() + return attention_mask + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (Wav2Vec2Encoder, Wav2Vec2EncoderStableLayerNorm, Wav2Vec2FeatureEncoder)): + module.gradient_checkpointing = value + + +WAV_2_VEC_2_START_DOCSTRING = r""" + Wav2Vec2 was proposed in [wav2vec 2.0: A Framework for Self-Supervised Learning of Speech + Representations](https://arxiv.org/abs/2006.11477) by Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael + Auli. + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving etc.). + + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`Wav2Vec2Config`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + + +WAV_2_VEC_2_INPUTS_DOCSTRING = r""" + Args: + input_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Float values of input raw speech waveform. Values can be obtained by loading a `.flac` or `.wav` audio file + into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via the soundfile library (`pip install + soundfile`). To prepare the array into `input_values`, the [`AutoProcessor`] should be used for padding and + conversion into a tensor of type `torch.FloatTensor`. See [`Wav2Vec2Processor.__call__`] for details. + attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing convolution and attention on padding token indices. Mask values selected in `[0, + 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + + + + `attention_mask` should only be passed if the corresponding processor has `config.return_attention_mask == + True`. For all models whose processor has `config.return_attention_mask == False`, such as + [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), `attention_mask` should **not** be + passed to avoid degraded performance when doing batched inference. For such models `input_values` should + simply be padded with 0 and passed without `attention_mask`. Be aware that these models also yield slightly + different results depending on whether `input_values` is padded or not. + + + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Wav2Vec2 Model transformer outputting raw hidden-states without any specific head on top.", + WAV_2_VEC_2_START_DOCSTRING, +) +class Wav2Vec2Model(Wav2Vec2PreTrainedModel): + def __init__(self, config: Wav2Vec2Config): + super().__init__(config) + self.config = config + self.feature_extractor = Wav2Vec2FeatureEncoder(config) + self.feature_projection = Wav2Vec2FeatureProjection(config) + + # model only needs masking vector if mask prob is > 0.0 + if config.mask_time_prob > 0.0 or config.mask_feature_prob > 0.0: + self.masked_spec_embed = nn.Parameter(torch.FloatTensor(config.hidden_size).uniform_()) + + if config.do_stable_layer_norm: + self.encoder = Wav2Vec2EncoderStableLayerNorm(config) + else: + self.encoder = Wav2Vec2Encoder(config) + + self.adapter = Wav2Vec2Adapter(config) if config.add_adapter else None + + # Initialize weights and apply final processing + self.post_init() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.feature_extractor._freeze_parameters() + + def _mask_hidden_states( + self, + hidden_states: torch.FloatTensor, + mask_time_indices: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.LongTensor] = None, + ): + """ + Masks extracted features along time axis and/or along feature axis according to + [SpecAugment](https://arxiv.org/abs/1904.08779). + """ + + # `config.apply_spec_augment` can set masking to False + if not getattr(self.config, "apply_spec_augment", True): + return hidden_states + + # generate indices & apply SpecAugment along time axis + batch_size, sequence_length, hidden_size = hidden_states.size() + + if mask_time_indices is not None: + # apply SpecAugment along time axis with given mask_time_indices + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + elif self.config.mask_time_prob > 0 and self.training: + mask_time_indices = _compute_mask_indices( + (batch_size, sequence_length), + mask_prob=self.config.mask_time_prob, + mask_length=self.config.mask_time_length, + attention_mask=attention_mask, + min_masks=self.config.mask_time_min_masks, + ) + mask_time_indices = torch.tensor(mask_time_indices, device=hidden_states.device, dtype=torch.bool) + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + + if self.config.mask_feature_prob > 0 and self.training: + # generate indices & apply SpecAugment along feature axis + mask_feature_indices = _compute_mask_indices( + (batch_size, hidden_size), + mask_prob=self.config.mask_feature_prob, + mask_length=self.config.mask_feature_length, + min_masks=self.config.mask_feature_min_masks, + ) + mask_feature_indices = torch.tensor(mask_feature_indices, device=hidden_states.device, dtype=torch.bool) + mask_feature_indices = mask_feature_indices[:, None].expand(-1, sequence_length, -1) + hidden_states[mask_feature_indices] = 0 + + return hidden_states + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=Wav2Vec2BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + mask_time_indices: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Wav2Vec2BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + extract_features = self.feature_extractor(input_values) + extract_features = extract_features.transpose(1, 2) + + if attention_mask is not None: + # compute reduced attention_mask corresponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + hidden_states, extract_features = self.feature_projection(extract_features) + hidden_states = self._mask_hidden_states( + hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask + ) + + encoder_outputs = self.encoder( + hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = encoder_outputs[0] + + if self.adapter is not None: + hidden_states = self.adapter(hidden_states) + + if not return_dict: + return (hidden_states, extract_features) + encoder_outputs[1:] + + return Wav2Vec2BaseModelOutput( + last_hidden_state=hidden_states, + extract_features=extract_features, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings("""Wav2Vec2 Model with a quantizer and `VQ` head on top.""", WAV_2_VEC_2_START_DOCSTRING) +class Wav2Vec2ForPreTraining(Wav2Vec2PreTrainedModel): + def __init__(self, config: Wav2Vec2Config): + super().__init__(config) + self.wav2vec2 = Wav2Vec2Model(config) + self.dropout_features = nn.Dropout(config.feat_quantizer_dropout) + + self.quantizer = Wav2Vec2GumbelVectorQuantizer(config) + + self.project_hid = nn.Linear(config.hidden_size, config.proj_codevector_dim) + self.project_q = nn.Linear(config.codevector_dim, config.proj_codevector_dim) + + # Initialize weights and apply final processing + self.post_init() + + def set_gumbel_temperature(self, temperature: int): + """ + Set the Gumbel softmax temperature to a given value. Only necessary for training + """ + self.quantizer.temperature = temperature + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor._freeze_parameters() + + @staticmethod + def compute_contrastive_logits( + target_features: torch.FloatTensor, + negative_features: torch.FloatTensor, + predicted_features: torch.FloatTensor, + temperature: int = 0.1, + ): + """ + Compute logits for contrastive loss based using cosine similarity as the distance measure between + `[positive_feature, negative_features]` and `[predicted_features]`. Additionally, temperature can be applied. + """ + target_features = torch.cat([target_features, negative_features], dim=0) + + logits = torch.cosine_similarity(predicted_features.float(), target_features.float(), dim=-1).type_as( + target_features + ) + + # apply temperature + logits = logits / temperature + return logits + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=Wav2Vec2ForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + mask_time_indices: Optional[torch.BoolTensor] = None, + sampled_negative_indices: Optional[torch.BoolTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Wav2Vec2ForPreTrainingOutput]: + r""" + mask_time_indices (`torch.BoolTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices to mask extracted features for contrastive loss. When in training mode, model learns to predict + masked extracted features in *config.proj_codevector_dim* space. + sampled_negative_indices (`torch.BoolTensor` of shape `(batch_size, sequence_length, num_negatives)`, *optional*): + Indices indicating which quantized target vectors are used as negative sampled vectors in contrastive loss. + Required input for pre-training. + + Returns: + + Example: + + ```python + >>> import torch + >>> from transformers import AutoFeatureExtractor, Wav2Vec2ForPreTraining + >>> from transformers.models.wav2vec2.modeling_wav2vec2 import _compute_mask_indices, _sample_negative_indices + >>> from datasets import load_dataset + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base") + >>> model = Wav2Vec2ForPreTraining.from_pretrained("facebook/wav2vec2-base") + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> input_values = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt").input_values # Batch size 1 + + >>> # compute masked indices + >>> batch_size, raw_sequence_length = input_values.shape + >>> sequence_length = model._get_feat_extract_output_lengths(raw_sequence_length).item() + >>> mask_time_indices = _compute_mask_indices( + ... shape=(batch_size, sequence_length), mask_prob=0.2, mask_length=2 + ... ) + >>> sampled_negative_indices = _sample_negative_indices( + ... features_shape=(batch_size, sequence_length), + ... num_negatives=model.config.num_negatives, + ... mask_time_indices=mask_time_indices, + ... ) + >>> mask_time_indices = torch.tensor(data=mask_time_indices, device=input_values.device, dtype=torch.long) + >>> sampled_negative_indices = torch.tensor( + ... data=sampled_negative_indices, device=input_values.device, dtype=torch.long + ... ) + + >>> with torch.no_grad(): + ... outputs = model(input_values, mask_time_indices=mask_time_indices) + + >>> # compute cosine similarity between predicted (=projected_states) and target (=projected_quantized_states) + >>> cosine_sim = torch.cosine_similarity(outputs.projected_states, outputs.projected_quantized_states, dim=-1) + + >>> # show that cosine similarity is much higher than random + >>> cosine_sim[mask_time_indices.to(torch.bool)].mean() > 0.5 + tensor(True) + + >>> # for contrastive loss training model should be put into train mode + >>> model = model.train() + >>> loss = model( + ... input_values, mask_time_indices=mask_time_indices, sampled_negative_indices=sampled_negative_indices + ... ).loss + ```""" + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if mask_time_indices is not None: + mask_time_indices = mask_time_indices.to(torch.bool) + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + mask_time_indices=mask_time_indices, + return_dict=return_dict, + ) + + # 1. project all transformed features (including masked) to final vq dim + transformer_features = self.project_hid(outputs[0]) + + # 2. quantize all (unmasked) extracted features and project to final vq dim + extract_features = self.dropout_features(outputs[1]) + + if attention_mask is not None: + # compute reduced attention_mask correponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + quantized_features, codevector_perplexity = self.quantizer( + extract_features, mask_time_indices=mask_time_indices + ) + quantized_features = self.project_q(quantized_features) + + loss = contrastive_loss = diversity_loss = None + if sampled_negative_indices is not None: + batch_size, sequence_length, hidden_size = quantized_features.shape + + # for training, we sample negatives + # 3. sample K negatives (distractors) quantized states for contrastive loss + # if attention_mask is passed, make sure that padded feature vectors cannot be sampled + # sample negative quantized vectors BTC => (BxT)C + negative_quantized_features = quantized_features.view(-1, hidden_size)[ + sampled_negative_indices.long().view(-1) + ] + negative_quantized_features = negative_quantized_features.view( + batch_size, sequence_length, -1, hidden_size + ).permute(2, 0, 1, 3) + + # 4. compute logits, corresponding to `logs = sim(c_t, [q_t, \sim{q}_t]) / \kappa` + # of equation (3) in https://arxiv.org/pdf/2006.11477.pdf + logits = self.compute_contrastive_logits( + quantized_features[None, :], + negative_quantized_features, + transformer_features, + self.config.contrastive_logits_temperature, + ) + + # 5. if a negative vector is identical to the positive (i.e. when codebook utilization is low), + # its cosine similarity will be masked + neg_is_pos = (quantized_features == negative_quantized_features).all(-1) + + if neg_is_pos.any(): + logits[1:][neg_is_pos] = float("-inf") + + # 6. compute contrastive loss \mathbf{L}_m = cross_entropy(logs) = + # -log(exp(sim(c_t, q_t)/\kappa) / \sum_{\sim{q}} exp(sim(c_t, \sim{q})/\kappa)) + logits = logits.transpose(0, 2).reshape(-1, logits.size(0)) + target = ((1 - mask_time_indices.long()) * -100).transpose(0, 1).flatten() + + contrastive_loss = nn.functional.cross_entropy(logits.float(), target, reduction="sum") + # 7. compute diversity loss: \mathbf{L}_d + num_codevectors = self.config.num_codevectors_per_group * self.config.num_codevector_groups + diversity_loss = ((num_codevectors - codevector_perplexity) / num_codevectors) * mask_time_indices.sum() + + # 8. \mathbf{L} = \mathbf{L}_m + \alpha * \mathbf{L}_d + loss = contrastive_loss + self.config.diversity_loss_weight * diversity_loss + + if not return_dict: + if loss is not None: + return (loss, transformer_features, quantized_features, codevector_perplexity) + outputs[2:] + return (transformer_features, quantized_features, codevector_perplexity) + outputs[2:] + + return Wav2Vec2ForPreTrainingOutput( + loss=loss, + projected_states=transformer_features, + projected_quantized_states=quantized_features, + codevector_perplexity=codevector_perplexity, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + contrastive_loss=contrastive_loss, + diversity_loss=diversity_loss, + ) + + +@add_start_docstrings("""Wav2Vec2 Model with a `language modeling` head on top.""", WAV_2_VEC_2_START_DOCSTRING) +class Wav2Vec2ForMaskedLM(Wav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + warnings.warn( + "The class `Wav2Vec2ForMaskedLM` is deprecated. Please use `Wav2Vec2ForCTC` instead.", FutureWarning + ) + + self.wav2vec2 = Wav2Vec2Model(config) + self.dropout = nn.Dropout(config.final_dropout) + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + def forward( + self, + input_values: torch.FloatTensor, + attention_mask: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, MaskedLMOutput]: + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.wav2vec2( + input_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states) + logits = self.lm_head(hidden_states) + + if not return_dict: + output = (logits,) + outputs[2:] + return output + + return MaskedLMOutput(logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions) + + +@add_start_docstrings( + """Wav2Vec2 Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", + WAV_2_VEC_2_START_DOCSTRING, +) +class Wav2Vec2ForCTC(Wav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.wav2vec2 = Wav2Vec2Model(config) + self.dropout = nn.Dropout(config.final_dropout) + + if config.vocab_size is None: + raise ValueError( + f"You are trying to instantiate {self.__class__} with a configuration that " + "does not define the vocabulary size of the language model head. Please " + "instantiate the model as follows: `Wav2Vec2ForCTC.from_pretrained(..., vocab_size=vocab_size)`. " + "or define `vocab_size` of your model's configuration." + ) + output_hidden_size = ( + config.output_hidden_size if hasattr(config, "add_adapter") and config.add_adapter else config.hidden_size + ) + self.lm_head = nn.Linear(output_hidden_size, config.vocab_size) + + # Initialize weights and apply final processing + self.post_init() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor._freeze_parameters() + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=CausalLMOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_CTC_EXPECTED_OUTPUT, + expected_loss=_CTC_EXPECTED_LOSS, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, CausalLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, target_length)`, *optional*): + Labels for connectionist temporal classification. Note that `target_length` has to be smaller or equal to + the sequence length of the output logits. Indices are selected in `[-100, 0, ..., config.vocab_size - 1]`. + All labels set to `-100` are ignored (masked), the loss is only computed for labels in `[0, ..., + config.vocab_size - 1]`. + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states) + + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + if labels.max() >= self.config.vocab_size: + raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") + + # retrieve loss input_lengths from attention_mask + attention_mask = ( + attention_mask if attention_mask is not None else torch.ones_like(input_values, dtype=torch.long) + ) + input_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(-1)).to(torch.long) + + # assuming that padded tokens are filled with -100 + # when not being attended to + labels_mask = labels >= 0 + target_lengths = labels_mask.sum(-1) + flattened_targets = labels.masked_select(labels_mask) + + # ctc_loss doesn't support fp16 + log_probs = nn.functional.log_softmax(logits, dim=-1, dtype=torch.float32).transpose(0, 1) + + with torch.backends.cudnn.flags(enabled=False): + loss = nn.functional.ctc_loss( + log_probs, + flattened_targets, + input_lengths, + target_lengths, + blank=self.config.pad_token_id, + reduction=self.config.ctc_loss_reduction, + zero_infinity=self.config.ctc_zero_infinity, + ) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return CausalLMOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + Wav2Vec2 Model with a sequence classification head on top (a linear layer over the pooled output) for tasks like + SUPERB Keyword Spotting. + """, + WAV_2_VEC_2_START_DOCSTRING, +) +class Wav2Vec2ForSequenceClassification(Wav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Sequence classification does not support the use of Wav2Vec2 adapters (config.add_adapter=True)" + ) + self.wav2vec2 = Wav2Vec2Model(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.classifier_proj_size) + self.classifier = nn.Linear(config.classifier_proj_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_SEQ_CLASS_CHECKPOINT, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_SEQ_CLASS_EXPECTED_OUTPUT, + expected_loss=_SEQ_CLASS_EXPECTED_LOSS, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + if attention_mask is None: + pooled_output = hidden_states.mean(dim=1) + else: + padding_mask = self._get_feature_vector_attention_mask(hidden_states.shape[1], attention_mask) + hidden_states[~padding_mask] = 0.0 + pooled_output = hidden_states.sum(dim=1) / padding_mask.sum(dim=1).view(-1, 1) + + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Wav2Vec2 Model with a frame classification head on top for tasks like Speaker Diarization. + """, + WAV_2_VEC_2_START_DOCSTRING, +) +class Wav2Vec2ForAudioFrameClassification(Wav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Audio frame classification does not support the use of Wav2Vec2 adapters (config.add_adapter=True)" + ) + self.wav2vec2 = Wav2Vec2Model(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + self.num_labels = config.num_labels + + self.init_weights() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_FRAME_CLASS_CHECKPOINT, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_FRAME_EXPECTED_OUTPUT, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + logits = self.classifier(hidden_states) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), torch.argmax(labels.view(-1, self.num_labels), axis=1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class AMSoftmaxLoss(nn.Module): + def __init__(self, input_dim, num_labels, scale=30.0, margin=0.4): + super(AMSoftmaxLoss, self).__init__() + self.scale = scale + self.margin = margin + self.num_labels = num_labels + self.weight = nn.Parameter(torch.randn(input_dim, num_labels), requires_grad=True) + self.loss = nn.CrossEntropyLoss() + + def forward(self, hidden_states, labels): + labels = labels.flatten() + weight = nn.functional.normalize(self.weight, dim=0) + hidden_states = nn.functional.normalize(hidden_states, dim=1) + cos_theta = torch.mm(hidden_states, weight) + psi = cos_theta - self.margin + + onehot = nn.functional.one_hot(labels, self.num_labels) + logits = self.scale * torch.where(onehot.bool(), psi, cos_theta) + loss = self.loss(logits, labels) + + return loss + + +class TDNNLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.tdnn_dim[layer_id - 1] if layer_id > 0 else config.tdnn_dim[layer_id] + self.out_conv_dim = config.tdnn_dim[layer_id] + self.kernel_size = config.tdnn_kernel[layer_id] + self.dilation = config.tdnn_dilation[layer_id] + + self.kernel = nn.Linear(self.in_conv_dim * self.kernel_size, self.out_conv_dim) + self.activation = nn.ReLU() + + def forward(self, hidden_states): + hidden_states = hidden_states.unsqueeze(1) + hidden_states = nn.functional.unfold( + hidden_states, + (self.kernel_size, self.in_conv_dim), + stride=(1, self.in_conv_dim), + dilation=(self.dilation, 1), + ) + hidden_states = hidden_states.transpose(1, 2) + hidden_states = self.kernel(hidden_states) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +@add_start_docstrings( + """ + Wav2Vec2 Model with an XVector feature extraction head on top for tasks like Speaker Verification. + """, + WAV_2_VEC_2_START_DOCSTRING, +) +class Wav2Vec2ForXVector(Wav2Vec2PreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.wav2vec2 = Wav2Vec2Model(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.tdnn_dim[0]) + + tdnn_layers = [TDNNLayer(config, i) for i in range(len(config.tdnn_dim))] + self.tdnn = nn.ModuleList(tdnn_layers) + + self.feature_extractor = nn.Linear(config.tdnn_dim[-1] * 2, config.xvector_output_dim) + self.classifier = nn.Linear(config.xvector_output_dim, config.xvector_output_dim) + + self.objective = AMSoftmaxLoss(config.xvector_output_dim, config.num_labels) + + self.init_weights() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2.parameters(): + param.requires_grad = False + + def _get_tdnn_output_lengths(self, input_lengths: Union[torch.LongTensor, int]): + """ + Computes the output length of the TDNN layers + """ + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size in self.config.tdnn_kernel: + input_lengths = _conv_out_length(input_lengths, kernel_size, 1) + + return input_lengths + + @add_start_docstrings_to_model_forward(WAV_2_VEC_2_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_XVECTOR_CHECKPOINT, + output_type=XVectorOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_XVECTOR_EXPECTED_OUTPUT, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, XVectorOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + + for tdnn_layer in self.tdnn: + hidden_states = tdnn_layer(hidden_states) + + # Statistic Pooling + if attention_mask is None: + mean_features = hidden_states.mean(dim=1) + std_features = hidden_states.std(dim=1) + else: + feat_extract_output_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(dim=1)) + tdnn_output_lengths = self._get_tdnn_output_lengths(feat_extract_output_lengths) + mean_features = [] + std_features = [] + for i, length in enumerate(tdnn_output_lengths): + mean_features.append(hidden_states[i, :length].mean(dim=0)) + std_features.append(hidden_states[i, :length].std(dim=0)) + mean_features = torch.stack(mean_features) + std_features = torch.stack(std_features) + statistic_pooling = torch.cat([mean_features, std_features], dim=-1) + + output_embeddings = self.feature_extractor(statistic_pooling) + logits = self.classifier(output_embeddings) + + loss = None + if labels is not None: + loss = self.objective(logits, labels) + + if not return_dict: + output = (logits, output_embeddings) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return XVectorOutput( + loss=loss, + logits=logits, + embeddings=output_embeddings, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/processing_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/processing_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..d6585a4f4dd67ba3685a529954a943ccf933b8a0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/processing_wav2vec2.py @@ -0,0 +1,164 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Speech processor class for Wav2Vec2 +""" +import warnings +from contextlib import contextmanager + +from ...processing_utils import ProcessorMixin +from .feature_extraction_wav2vec2 import Wav2Vec2FeatureExtractor +from .tokenization_wav2vec2 import Wav2Vec2CTCTokenizer + + +class Wav2Vec2Processor(ProcessorMixin): + r""" + Constructs a Wav2Vec2 processor which wraps a Wav2Vec2 feature extractor and a Wav2Vec2 CTC tokenizer into a single + processor. + + [`Wav2Vec2Processor`] offers all the functionalities of [`Wav2Vec2FeatureExtractor`] and [`PreTrainedTokenizer`]. + See the docstring of [`~Wav2Vec2Processor.__call__`] and [`~Wav2Vec2Processor.decode`] for more information. + + Args: + feature_extractor (`Wav2Vec2FeatureExtractor`): + An instance of [`Wav2Vec2FeatureExtractor`]. The feature extractor is a required input. + tokenizer ([`PreTrainedTokenizer`]): + An instance of [`PreTrainedTokenizer`]. The tokenizer is a required input. + """ + feature_extractor_class = "Wav2Vec2FeatureExtractor" + tokenizer_class = "AutoTokenizer" + + def __init__(self, feature_extractor, tokenizer): + super().__init__(feature_extractor, tokenizer) + self.current_processor = self.feature_extractor + self._in_target_context_manager = False + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + try: + return super().from_pretrained(pretrained_model_name_or_path, **kwargs) + except OSError: + warnings.warn( + f"Loading a tokenizer inside {cls.__name__} from a config that does not" + " include a `tokenizer_class` attribute is deprecated and will be " + "removed in v5. Please add `'tokenizer_class': 'Wav2Vec2CTCTokenizer'`" + " attribute to either your `config.json` or `tokenizer_config.json` " + "file to suppress this warning: ", + FutureWarning, + ) + + feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(pretrained_model_name_or_path, **kwargs) + tokenizer = Wav2Vec2CTCTokenizer.from_pretrained(pretrained_model_name_or_path, **kwargs) + + return cls(feature_extractor=feature_extractor, tokenizer=tokenizer) + + def __call__(self, *args, **kwargs): + """ + When used in normal mode, this method forwards all its arguments to Wav2Vec2FeatureExtractor's + [`~Wav2Vec2FeatureExtractor.__call__`] and returns its output. If used in the context + [`~Wav2Vec2Processor.as_target_processor`] this method forwards all its arguments to PreTrainedTokenizer's + [`~PreTrainedTokenizer.__call__`]. Please refer to the docstring of the above two methods for more information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor(*args, **kwargs) + + if "raw_speech" in kwargs: + warnings.warn("Using `raw_speech` as a keyword argument is deprecated. Use `audio` instead.") + audio = kwargs.pop("raw_speech") + else: + audio = kwargs.pop("audio", None) + sampling_rate = kwargs.pop("sampling_rate", None) + text = kwargs.pop("text", None) + if len(args) > 0: + audio = args[0] + args = 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 audio is not None: + inputs = self.feature_extractor(audio, *args, sampling_rate=sampling_rate, **kwargs) + if text is not None: + encodings = self.tokenizer(text, **kwargs) + + if text is None: + return inputs + elif audio is None: + return encodings + else: + inputs["labels"] = encodings["input_ids"] + return inputs + + def pad(self, *args, **kwargs): + """ + When used in normal mode, this method forwards all its arguments to Wav2Vec2FeatureExtractor's + [`~Wav2Vec2FeatureExtractor.pad`] and returns its output. If used in the context + [`~Wav2Vec2Processor.as_target_processor`] this method forwards all its arguments to PreTrainedTokenizer's + [`~PreTrainedTokenizer.pad`]. Please refer to the docstring of the above two methods for more information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor.pad(*args, **kwargs) + + input_features = kwargs.pop("input_features", None) + labels = kwargs.pop("labels", None) + if len(args) > 0: + input_features = args[0] + args = args[1:] + + if input_features is not None: + input_features = self.feature_extractor.pad(input_features, *args, **kwargs) + if labels is not None: + labels = self.tokenizer.pad(labels, **kwargs) + + if labels is None: + return input_features + elif input_features is None: + return labels + else: + input_features["labels"] = labels["input_ids"] + return input_features + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to PreTrainedTokenizer's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to PreTrainedTokenizer's [`~PreTrainedTokenizer.decode`]. Please refer + to the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + @contextmanager + def as_target_processor(self): + """ + Temporarily sets the tokenizer for processing the input. Useful for encoding the labels when fine-tuning + Wav2Vec2. + """ + warnings.warn( + "`as_target_processor` is deprecated and will be removed in v5 of Transformers. You can process your " + "labels by using the argument `text` of the regular `__call__` method (either in the same call as " + "your audio inputs, or in a separate call." + ) + self._in_target_context_manager = True + self.current_processor = self.tokenizer + yield + self.current_processor = self.feature_extractor + self._in_target_context_manager = False diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/tokenization_wav2vec2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/tokenization_wav2vec2.py new file mode 100644 index 0000000000000000000000000000000000000000..1708dbf12512a460e7a0b469c8ac0f80595c1988 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2/tokenization_wav2vec2.py @@ -0,0 +1,935 @@ +# coding=utf-8 +# Copyright 2021 The Facebook Inc. and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization class for Wav2Vec2.""" + +import json +import os +import sys +import warnings +from dataclasses import dataclass +from itertools import groupby +from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union + +import numpy as np + +from ...tokenization_utils import PreTrainedTokenizer, _insert_one_token_to_ordered_list +from ...tokenization_utils_base import AddedToken, BatchEncoding +from ...utils import ( + ModelOutput, + PaddingStrategy, + TensorType, + add_end_docstrings, + is_flax_available, + is_tf_available, + is_torch_available, + logging, + to_py_obj, +) + + +logger = logging.get_logger(__name__) + + +if TYPE_CHECKING: + if is_torch_available(): + import torch + if is_tf_available(): + import tensorflow as tf + if is_flax_available(): + import jax.numpy as jnp # noqa: F401 + + +VOCAB_FILES_NAMES = { + "vocab_file": "vocab.json", + "tokenizer_config_file": "tokenizer_config.json", +} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/wav2vec2-base-960h": "https://huggingface.co/facebook/wav2vec2-base-960h/resolve/main/vocab.json", + }, + "tokenizer_config_file": { + "facebook/wav2vec2-base-960h": ( + "https://huggingface.co/facebook/wav2vec2-base-960h/resolve/main/tokenizer_config.json" + ), + }, +} + +# Wav2Vec2 has no max input length +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {"facebook/wav2vec2-base-960h": sys.maxsize} + +WAV2VEC2_KWARGS_DOCSTRING = r""" + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + max_length (`int`, *optional*): + Controls the maximum length to use by one of the truncation/padding parameters. + + If left unset or set to `None`, this will use the predefined model maximum length if a maximum length + is required by one of the truncation/padding parameters. If the model has no specific maximum input + length (like XLNet) truncation/padding to a maximum length will be deactivated. + pad_to_multiple_of (`int`, *optional*): + If set will pad the sequence to a multiple of the provided value. This is especially useful to enable + the use of Tensor Cores on NVIDIA hardware with compute capability `>= 7.5` (Volta). + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + verbose (`bool`, *optional*, defaults to `True`): + Whether or not to print more information and warnings. +""" + +ListOfDict = List[Dict[str, Union[int, str]]] + + +@dataclass +class Wav2Vec2CTCTokenizerOutput(ModelOutput): + """ + Output type of [` Wav2Vec2CTCTokenizer`], with transcription. + + Args: + text (list of `str` or `str`): + Decoded logits in text from. Usually the speech transcription. + char_offsets (list of `List[Dict[str, Union[int, str]]]` or `List[Dict[str, Union[int, str]]]`): + Offsets of the decoded characters. In combination with sampling rate and model downsampling rate char + offsets can be used to compute time stamps for each charater. Total logit score of the beam associated with + produced text. + word_offsets (list of `List[Dict[str, Union[int, str]]]` or `List[Dict[str, Union[int, str]]]`): + Offsets of the decoded words. In combination with sampling rate and model downsampling rate word offsets + can be used to compute time stamps for each word. + """ + + text: Union[List[str], str] + char_offsets: Union[List[ListOfDict], ListOfDict] = None + word_offsets: Union[List[ListOfDict], ListOfDict] = None + + +class Wav2Vec2CTCTokenizer(PreTrainedTokenizer): + + """ + Constructs a Wav2Vec2CTC tokenizer. + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains some of the main methods. Users should refer to + the superclass for more information regarding such methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sentence token. + eos_token (`str`, *optional*, defaults to `""`): + The end of sentence token. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + word_delimiter_token (`str`, *optional*, defaults to `"|"`): + The token used for defining the end of a word. + do_lower_case (`bool`, *optional*, defaults to `False`): + Whether or not to accept lowercase input and lowercase the output when decoding. + + **kwargs + Additional keyword arguments passed along to [`PreTrainedTokenizer`] + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="", + eos_token="", + unk_token="", + pad_token="", + word_delimiter_token="|", + replace_word_delimiter_char=" ", + do_lower_case=False, + **kwargs, + ): + super().__init__( + unk_token=unk_token, + bos_token=bos_token, + eos_token=eos_token, + pad_token=pad_token, + do_lower_case=do_lower_case, + word_delimiter_token=word_delimiter_token, + replace_word_delimiter_char=replace_word_delimiter_char, + **kwargs, + ) + + self._word_delimiter_token = word_delimiter_token + + self.do_lower_case = do_lower_case + self.replace_word_delimiter_char = replace_word_delimiter_char + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + self.decoder = {v: k for k, v in self.encoder.items()} + + # make sure that tokens made of several + # characters are not split at tokenization + for token in self.encoder.keys(): + if len(token) > 1: + self.unique_no_split_tokens.append(token) + + self._create_trie(self.unique_no_split_tokens) + + @property + def word_delimiter_token(self) -> str: + """ + `str`: Word delimiter token. Log an error if used while not having been set. + """ + if self._word_delimiter_token is None and self.verbose: + logger.error("Using word_delimiter_token, but it is not set yet.") + return None + return str(self._word_delimiter_token) + + @property + def word_delimiter_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the word_delimiter_token in the vocabulary. Returns `None` if the token has not been + set. + """ + if self._word_delimiter_token is None: + return None + return self.convert_tokens_to_ids(self.word_delimiter_token) + + @word_delimiter_token.setter + def word_delimiter_token(self, value): + self._word_delimiter_token = value + + @word_delimiter_token_id.setter + def word_delimiter_token_id(self, value): + self._word_delimiter_token = self.convert_tokens_to_ids(value) + + @property + def vocab_size(self) -> int: + return len(self.decoder) + + def get_vocab(self) -> Dict: + return dict(self.encoder, **self.added_tokens_encoder) + + def _tokenize(self, text, **kwargs): + """ + Converts a string in a sequence of tokens (string), using the tokenizer. + """ + if self.do_lower_case: + text = text.upper() + + return list(text.replace(" ", self.word_delimiter_token)) + + def _convert_token_to_id(self, token: str) -> int: + """Converts a token (str) in an index (integer) using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + def _convert_id_to_token(self, index: int) -> str: + """Converts an index (integer) in a token (str) using the vocab.""" + result = self.decoder.get(index, self.unk_token) + return result + + def convert_tokens_to_string( + self, + tokens: List[str], + group_tokens: bool = True, + spaces_between_special_tokens: bool = False, + output_char_offsets: bool = False, + output_word_offsets: bool = False, + ) -> Dict[str, Union[str, float]]: + """ + Converts a connectionist-temporal-classification (CTC) output tokens into a single string. + """ + if len(tokens) == 0: + return {"text": "", "char_offsets": [], "word_offsets": []} + # group same tokens into non-repeating tokens in CTC style decoding + if group_tokens: + chars, char_repetitions = zip(*((token, len(list(group_iter))) for token, group_iter in groupby(tokens))) + else: + chars = tokens + char_repetitions = len(tokens) * [1] + + # filter self.pad_token which is used as CTC-blank token + processed_chars = list(filter(lambda char: char != self.pad_token, chars)) + + # replace delimiter token + processed_chars = [ + self.replace_word_delimiter_char if char == self.word_delimiter_token else char for char in processed_chars + ] + + # retrieve offsets + char_offsets = word_offsets = None + if output_char_offsets or output_word_offsets: + char_offsets = self._compute_offsets(char_repetitions, chars, self.pad_token) + + if len(char_offsets) != len(processed_chars): + raise ValueError( + f"`char_offsets`: {char_offsets} and `processed_tokens`: {processed_chars}" + " have to be of the same length, but are: " + f"`len(offsets)`: {len(char_offsets)} and `len(processed_tokens)`:" + f" {len(processed_chars)}" + ) + + # set tokens to correct processed token + for i, char in enumerate(processed_chars): + char_offsets[i]["char"] = char + + # retrieve word offsets from character offsets + word_offsets = None + if output_word_offsets: + word_offsets = self._get_word_offsets(char_offsets, self.replace_word_delimiter_char) + + # don't output chars if not set to True + if not output_char_offsets: + char_offsets = None + + # join to string + join_char = " " if spaces_between_special_tokens else "" + string = join_char.join(processed_chars).strip() + + if self.do_lower_case: + string = string.lower() + + return {"text": string, "char_offsets": char_offsets, "word_offsets": word_offsets} + + @staticmethod + def _compute_offsets( + char_repetitions: List[int], chars: List[str], ctc_token: int + ) -> List[Dict[str, Union[str, int]]]: + end_indices = np.asarray(char_repetitions).cumsum() + start_indices = np.concatenate(([0], end_indices[:-1])) + + offsets = [ + {"char": t, "start_offset": s, "end_offset": e} for t, s, e in zip(chars, start_indices, end_indices) + ] + + # filter out CTC token + offsets = list(filter(lambda offsets: offsets["char"] != ctc_token, offsets)) + return offsets + + @staticmethod + def _get_word_offsets( + offsets: Dict[str, Union[str, float]], word_delimiter_char: str = " " + ) -> Dict[str, Union[str, float]]: + word_offsets = [] + + last_state = "SPACE" + word = "" + start_offset = 0 + end_offset = 0 + for i, offset in enumerate(offsets): + char = offset["char"] + state = "SPACE" if char == word_delimiter_char else "WORD" + + if state == last_state: + # If we are in the same state as before, we simply repeat what we've done before + end_offset = offset["end_offset"] + word += char + else: + # Switching state + if state == "SPACE": + # Finishing a word + word_offsets.append({"word": word, "start_offset": start_offset, "end_offset": end_offset}) + else: + # Starting a new word + start_offset = offset["start_offset"] + end_offset = offset["end_offset"] + word = char + + last_state = state + if last_state == "WORD": + word_offsets.append({"word": word, "start_offset": start_offset, "end_offset": end_offset}) + + return word_offsets + + def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): + if is_split_into_words: + text = " " + text + return (text, kwargs) + + def _decode( + self, + token_ids: List[int], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + group_tokens: bool = True, + spaces_between_special_tokens: bool = False, + output_word_offsets: Optional[bool] = False, + output_char_offsets: Optional[bool] = False, + ) -> str: + """ + special _decode function is needed for Wav2Vec2Tokenizer because added tokens should be treated exactly the + same as tokens of the base vocabulary and therefore the function `convert_tokens_to_string` has to be called on + the whole token list and not individually on added tokens + """ + filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens) + + result = [] + for token in filtered_tokens: + if skip_special_tokens and token in self.all_special_ids: + continue + result.append(token) + + string_output = self.convert_tokens_to_string( + result, + group_tokens=group_tokens, + spaces_between_special_tokens=spaces_between_special_tokens, + output_word_offsets=output_word_offsets, + output_char_offsets=output_char_offsets, + ) + + text = string_output["text"] + + clean_up_tokenization_spaces = ( + clean_up_tokenization_spaces + if clean_up_tokenization_spaces is not None + else self.clean_up_tokenization_spaces + ) + if clean_up_tokenization_spaces: + text = self.clean_up_tokenization(text) + + if output_word_offsets or output_char_offsets: + return Wav2Vec2CTCTokenizerOutput( + text=text, + char_offsets=string_output["char_offsets"], + word_offsets=string_output["word_offsets"], + ) + else: + return text + + # overwritten from `tokenization_utils_base.py` because tokenizer can output + # `ModelOutput` which should not be a list for batched output and + # because we need docs for `output_char_offsets` here + def batch_decode( + self, + sequences: Union[List[int], List[List[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_char_offsets: bool = False, + output_word_offsets: bool = False, + **kwargs, + ) -> List[str]: + """ + Convert a list of lists of token ids into a list of strings by calling decode. + + Args: + sequences (`Union[List[int], List[List[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. + output_char_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output character offsets. Character offsets can be used in combination with the + sampling rate and model downsampling rate to compute the time-stamps of transcribed characters. + + + + Please take a look at the Example of [`~Wav2Vec2CTCTokenizer.decode`] to better understand how to make + use of `output_char_offsets`. [`~Wav2Vec2CTCTokenizer.batch_decode`] works the same way with batched + output. + + + + output_word_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate + and model downsampling rate to compute the time-stamps of transcribed words. + + + + Please take a look at the Example of [`~Wav2Vec2CTCTokenizer.decode`] to better understand how to make + use of `output_word_offsets`. [`~Wav2Vec2CTCTokenizer.batch_decode`] works the same way with batched + output. + + + + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `List[str]` or [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`]: The list of decoded + sentences. Will be a [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`] when + `output_char_offsets == True` or `output_word_offsets == True`. + """ + batch_decoded = [ + self.decode( + seq, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + output_char_offsets=output_char_offsets, + output_word_offsets=output_word_offsets, + **kwargs, + ) + for seq in sequences + ] + if output_char_offsets or output_word_offsets: + # transform list of dicts to dict of lists + return Wav2Vec2CTCTokenizerOutput({k: [d[k] for d in batch_decoded] for k in batch_decoded[0]}) + + return batch_decoded + + # overwritten from `tokenization_utils_base.py` because we need docs for `output_char_offsets` + # and `output_word_offsets` here + def decode( + self, + token_ids: Union[int, List[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_char_offsets: bool = False, + output_word_offsets: bool = False, + **kwargs, + ) -> str: + """ + Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special + tokens and clean up tokenization spaces. + + Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. + output_char_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output character offsets. Character offsets can be used in combination with the + sampling rate and model downsampling rate to compute the time-stamps of transcribed characters. + + + + Please take a look at the example below to better understand how to make use of `output_char_offsets`. + + + + output_word_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate + and model downsampling rate to compute the time-stamps of transcribed words. + + + + Please take a look at the example below to better understand how to make use of `output_word_offsets`. + + + + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `str` or [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`]: The list of decoded + sentences. Will be a [`~models.wav2vec2.tokenization_wav2vec2.Wav2Vec2CTCTokenizerOutput`] when + `output_char_offsets == True` or `output_word_offsets == True`. + + Example: + + ```python + >>> # Let's see how to retrieve time steps for a model + >>> from transformers import AutoTokenizer, AutoFeatureExtractor, AutoModelForCTC + >>> from datasets import load_dataset + >>> import datasets + >>> import torch + + >>> # import model, feature extractor, tokenizer + >>> model = AutoModelForCTC.from_pretrained("facebook/wav2vec2-base-960h") + >>> tokenizer = AutoTokenizer.from_pretrained("facebook/wav2vec2-base-960h") + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base-960h") + + >>> # load first sample of English common_voice + >>> dataset = load_dataset("common_voice", "en", split="train", streaming=True) + >>> dataset = dataset.cast_column("audio", datasets.Audio(sampling_rate=16_000)) + >>> dataset_iter = iter(dataset) + >>> sample = next(dataset_iter) + + >>> # forward sample through model to get greedily predicted transcription ids + >>> input_values = feature_extractor(sample["audio"]["array"], return_tensors="pt").input_values + >>> logits = model(input_values).logits[0] + >>> pred_ids = torch.argmax(logits, axis=-1) + + >>> # retrieve word stamps (analogous commands for `output_char_offsets`) + >>> outputs = tokenizer.decode(pred_ids, output_word_offsets=True) + >>> # compute `time_offset` in seconds as product of downsampling ratio and sampling_rate + >>> time_offset = model.config.inputs_to_logits_ratio / feature_extractor.sampling_rate + + >>> word_offsets = [ + ... { + ... "word": d["word"], + ... "start_time": round(d["start_offset"] * time_offset, 2), + ... "end_time": round(d["end_offset"] * time_offset, 2), + ... } + ... for d in outputs.word_offsets + ... ] + >>> # compare word offsets with audio `common_voice_en_100038.mp3` online on the dataset viewer: + >>> # https://huggingface.co/datasets/common_voice/viewer/en/train + >>> word_offsets[:3] + [{'word': 'WHY', 'start_time': 1.42, 'end_time': 1.54}, {'word': 'DOES', 'start_time': 1.64, 'end_time': 1.9}, {'word': 'MILISANDRA', 'start_time': 2.26, 'end_time': 2.9}] + ```""" + # Convert inputs to python lists + token_ids = to_py_obj(token_ids) + + return self._decode( + token_ids=token_ids, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + output_char_offsets=output_char_offsets, + output_word_offsets=output_word_offsets, + **kwargs, + ) + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + return (vocab_file,) + + def _add_tokens(self, new_tokens: Union[List[str], List[AddedToken]], special_tokens: bool = False) -> int: + """ + Add a list of new tokens to the tokenizer class. If the new tokens are not in the vocabulary, they are added to + it with indices starting from length of the current vocabulary. + + Args: + new_tokens (`List[str]`or `List[tokenizers.AddedToken]`): + Token(s) to add in vocabulary. A token is only added if it's not already in the vocabulary (tested by + checking if the tokenizer assign the index of the `unk_token` to them). + special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the tokens should be added as special tokens. + + Returns: + `int`: The number of tokens actually added to the vocabulary. + + Example: + + ```python + # Let's see how to increase the vocabulary of Bert model and tokenizer + tokenizer = Wav2Vec2CTCTokenizer.from_pretrained("facebook/wav2vec2-base-960h") + model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h") + + num_added_toks = tokenizer.add_tokens(["new_tok1", "my_new-tok2"]) + print("We have added", num_added_toks, "tokens") + # Note: resize_token_embeddings expects to receive the full size of the new vocabulary, i.e. the length of the tokenizer. + model.resize_token_embeddings(len(tokenizer)) + ```""" + new_tokens = [str(tok) for tok in new_tokens] + + tokens_to_add = [] + for token in new_tokens: + assert isinstance(token, str) + if not special_tokens and hasattr(self, "do_lower_case") and self.do_lower_case: + token = token.lower() + if ( + token != self.unk_token + and self.convert_tokens_to_ids(token) == self.convert_tokens_to_ids(self.unk_token) + and token not in tokens_to_add + ): + tokens_to_add.append(token) + if self.verbose: + logger.info(f"Adding {token} to the vocabulary") + + added_tok_encoder = {tok: len(self) + i for i, tok in enumerate(tokens_to_add)} + added_tok_decoder = {v: k for k, v in added_tok_encoder.items()} + self.added_tokens_encoder.update(added_tok_encoder) + self.added_tokens_decoder.update(added_tok_decoder) + + # Make sure we don't split on any special tokens (even they were already in the vocab before) + for token in tokens_to_add: + if len(token) > 1: + self._additional_special_tokens.append(AddedToken(token)) + _insert_one_token_to_ordered_list(self.unique_no_split_tokens, token) + + self._create_trie(self.unique_no_split_tokens) + + return len(tokens_to_add) + + +class Wav2Vec2Tokenizer(PreTrainedTokenizer): + """ + Constructs a Wav2Vec2 tokenizer. + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains some of the main methods. Users should refer to + the superclass for more information regarding such methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sentence token. + eos_token (`str`, *optional*, defaults to `""`): + The end of sentence token. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + word_delimiter_token (`str`, *optional*, defaults to `"|"`): + The token used for defining the end of a word. + do_lower_case (`bool`, *optional*, defaults to `False`): + Whether or not to lowercase the output when decoding. + do_normalize (`bool`, *optional*, defaults to `False`): + Whether or not to zero-mean unit-variance normalize the input. Normalizing can help to significantly + improve the performance for some models, *e.g.*, + [wav2vec2-lv60](https://huggingface.co/models?search=lv60). + return_attention_mask (`bool`, *optional*, defaults to `False`): + Whether or not [`~Wav2Vec2Tokenizer.__call__`] should return `attention_mask`. + + + + Wav2Vec2 models that have set `config.feat_extract_norm == "group"`, such as + [wav2vec2-base](https://huggingface.co/facebook/wav2vec2-base-960h), have **not** been trained using + `attention_mask`. For such models, `input_values` should simply be padded with 0 and no `attention_mask` + should be passed. + + For Wav2Vec2 models that have set `config.feat_extract_norm == "layer"`, such as + [wav2vec2-lv60](https://huggingface.co/facebook/wav2vec2-large-960h-lv60-self), `attention_mask` should be + passed for batched inference. + + + + **kwargs + Additional keyword arguments passed along to [`PreTrainedTokenizer`] + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = { + "vocab_file": { + "facebook/wav2vec2-base-960h": "https://huggingface.co/facebook/wav2vec2-base-960h/resolve/main/vocab.json" + }, + "tokenizer_config_file": { + "facebook/wav2vec2-base-960h": ( + "https://huggingface.co/facebook/wav2vec2-base-960h/resolve/main/tokenizer.json" + ), + }, + } + model_input_names = ["input_values", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="", + eos_token="", + unk_token="", + pad_token="", + word_delimiter_token="|", + do_lower_case=False, + do_normalize=False, + return_attention_mask=False, + **kwargs, + ): + super().__init__( + unk_token=unk_token, + bos_token=bos_token, + eos_token=eos_token, + pad_token=pad_token, + do_lower_case=do_lower_case, + do_normalize=do_normalize, + return_attention_mask=return_attention_mask, + word_delimiter_token=word_delimiter_token, + **kwargs, + ) + + warnings.warn( + "The class `Wav2Vec2Tokenizer` is deprecated and will be removed in version 5 of Transformers. Please use" + " `Wav2Vec2Processor` or `Wav2Vec2CTCTokenizer` instead.", + FutureWarning, + ) + + self._word_delimiter_token = word_delimiter_token + + self.do_lower_case = do_lower_case + self.return_attention_mask = return_attention_mask + self.do_normalize = do_normalize + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + + self.decoder = {v: k for k, v in self.encoder.items()} + + @property + def word_delimiter_token(self) -> str: + """ + `str`: Padding token. Log an error if used while not having been set. + """ + if self._word_delimiter_token is None and self.verbose: + logger.error("Using word_delimiter_token, but it is not set yet.") + return None + return str(self._word_delimiter_token) + + @property + def word_delimiter_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the word_delimiter_token in the vocabulary. Returns `None` if the token has not been + set. + """ + if self._word_delimiter_token is None: + return None + return self.convert_tokens_to_ids(self.word_delimiter_token) + + @word_delimiter_token.setter + def word_delimiter_token(self, value): + self._word_delimiter_token = value + + @word_delimiter_token_id.setter + def word_delimiter_token_id(self, value): + self._word_delimiter_token = self.convert_tokens_to_ids(value) + + @add_end_docstrings(WAV2VEC2_KWARGS_DOCSTRING) + def __call__( + self, + raw_speech: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]], + padding: Union[bool, str, PaddingStrategy] = False, + max_length: Optional[int] = None, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + """ + Main method to tokenize and prepare for the model one or several sequence(s) or one or several pair(s) of + sequences. + + Args: + raw_speech (`np.ndarray`, `List[float]`, `List[np.ndarray]`, `List[List[float]]`): + The sequence or batch of sequences to be padded. Each sequence can be a numpy array, a list of float + values, a list of numpy arrayr or a list of list of float values. + """ + + is_batched = bool( + isinstance(raw_speech, (list, tuple)) + and (isinstance(raw_speech[0], np.ndarray) or isinstance(raw_speech[0], (tuple, list))) + ) + + # make sure input is in list format + if is_batched and not isinstance(raw_speech[0], np.ndarray): + raw_speech = [np.asarray(speech) for speech in raw_speech] + elif not is_batched and not isinstance(raw_speech, np.ndarray): + raw_speech = np.asarray(raw_speech) + + # always return batch + if not is_batched: + raw_speech = [raw_speech] + + # zero-mean and unit-variance normalization + if self.do_normalize: + raw_speech = [(x - np.mean(x)) / np.sqrt(np.var(x) + 1e-5) for x in raw_speech] + + # convert into correct format for padding + encoded_inputs = BatchEncoding({"input_values": raw_speech}) + + padded_inputs = self.pad( + encoded_inputs, + padding=padding, + max_length=max_length, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=self.return_attention_mask, + return_tensors=return_tensors, + verbose=verbose, + ) + + return padded_inputs + + @property + def vocab_size(self) -> int: + return len(self.decoder) + + def get_vocab(self) -> Dict: + return dict(self.encoder, **self.added_tokens_encoder) + + def _convert_token_to_id(self, token: str) -> int: + """Converts a token (str) in an index (integer) using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + def _convert_id_to_token(self, index: int) -> str: + """Converts an index (integer) in a token (str) using the vocab.""" + result = self.decoder.get(index, self.unk_token) + return result + + def convert_tokens_to_string(self, tokens: List[str]) -> str: + """ + Converts a connectionist-temporal-classification (CTC) output tokens into a single string. + """ + # group same tokens into non-repeating tokens in CTC style decoding + grouped_tokens = [token_group[0] for token_group in groupby(tokens)] + + # filter self.pad_token which is used as CTC-blank token + filtered_tokens = list(filter(lambda token: token != self.pad_token, grouped_tokens)) + + # replace delimiter token + string = "".join([" " if token == self.word_delimiter_token else token for token in filtered_tokens]).strip() + + if self.do_lower_case: + string = string.lower() + + return string + + def _decode( + self, + token_ids: List[int], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + **kwargs, + ) -> str: + """ + special _decode function is needed for Wav2Vec2Tokenizer because added tokens should be treated exactly the + same as tokens of the base vocabulary and therefore the function `convert_tokens_to_string` has to be called on + the whole token list and not individually on added tokens + """ + filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens) + + result = [] + for token in filtered_tokens: + if skip_special_tokens and token in self.all_special_ids: + continue + result.append(token) + + text = self.convert_tokens_to_string(result) + + clean_up_tokenization_spaces = ( + clean_up_tokenization_spaces + if clean_up_tokenization_spaces is not None + else self.clean_up_tokenization_spaces + ) + if clean_up_tokenization_spaces: + clean_text = self.clean_up_tokenization(text) + return clean_text + else: + return text + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + return (vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..35081cfcdef97b99e1a3cc29461fa07c80f31ab8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/__init__.py @@ -0,0 +1,70 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = { + "configuration_wav2vec2_conformer": [ + "WAV2VEC2_CONFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP", + "Wav2Vec2ConformerConfig", + ], +} + + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_wav2vec2_conformer"] = [ + "WAV2VEC2_CONFORMER_PRETRAINED_MODEL_ARCHIVE_LIST", + "Wav2Vec2ConformerForAudioFrameClassification", + "Wav2Vec2ConformerForCTC", + "Wav2Vec2ConformerForPreTraining", + "Wav2Vec2ConformerForSequenceClassification", + "Wav2Vec2ConformerForXVector", + "Wav2Vec2ConformerModel", + "Wav2Vec2ConformerPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_wav2vec2_conformer import ( + WAV2VEC2_CONFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, + Wav2Vec2ConformerConfig, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_wav2vec2_conformer import ( + WAV2VEC2_CONFORMER_PRETRAINED_MODEL_ARCHIVE_LIST, + Wav2Vec2ConformerForAudioFrameClassification, + Wav2Vec2ConformerForCTC, + Wav2Vec2ConformerForPreTraining, + Wav2Vec2ConformerForSequenceClassification, + Wav2Vec2ConformerForXVector, + Wav2Vec2ConformerModel, + Wav2Vec2ConformerPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/configuration_wav2vec2_conformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/configuration_wav2vec2_conformer.py new file mode 100644 index 0000000000000000000000000000000000000000..b9f24c7e708057d92ca8741963c79ed2765020e9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/configuration_wav2vec2_conformer.py @@ -0,0 +1,357 @@ +# coding=utf-8 +# Copyright 2022 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Wav2Vec2Conformer model configuration""" + +import functools +import operator + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +WAV2VEC2_CONFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/wav2vec2-conformer-rel-pos-large": ( + "https://huggingface.co/facebook/wav2vec2-conformer-rel-pos-large/resolve/main/config.json" + ), +} + + +class Wav2Vec2ConformerConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`Wav2Vec2ConformerModel`]. It is used to + instantiate an Wav2Vec2Conformer model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the Wav2Vec2Conformer + [facebook/wav2vec2-conformer-rel-pos-large](https://huggingface.co/facebook/wav2vec2-conformer-rel-pos-large) + architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*): + Vocabulary size of the Wav2Vec2Conformer model. Defines the number of different tokens that can be + represented by the `inputs_ids` passed when calling [`Wav2Vec2ConformerModel`]. Vocabulary size of the + model. Defines the different tokens that can be represented by the *inputs_ids* passed to the forward + method of [`Wav2Vec2ConformerModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + final_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for the final projection layer of [`Wav2Vec2ConformerForCTC`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + feat_extract_norm (`str`, *optional*, defaults to `"group"`): + The norm to be applied to 1D convolutional layers in feature encoder. One of `"group"` for group + normalization of only the first 1D convolutional layer or `"layer"` for layer normalization of all 1D + convolutional layers. + feat_proj_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for output of the feature encoder. + feat_extract_activation (`str, `optional`, defaults to `"gelu"`): + The non-linear activation function (function or string) in the 1D convolutional layers of the feature + extractor. If string, `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` are supported. + feat_quantizer_dropout (`float`, *optional*, defaults to 0.0): + The dropout probabilitiy for quantized feature encoder states. + conv_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 512, 512, 512)`): + A tuple of integers defining the number of input and output channels of each 1D convolutional layer in the + feature encoder. The length of *conv_dim* defines the number of 1D convolutional layers. + conv_stride (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 2, 2, 2, 2, 2, 2)`): + A tuple of integers defining the stride of each 1D convolutional layer in the feature encoder. The length + of *conv_stride* defines the number of convolutional layers and has to match the length of *conv_dim*. + conv_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(10, 3, 3, 3, 3, 3, 3)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the feature encoder. The + length of *conv_kernel* defines the number of convolutional layers and has to match the length of + *conv_dim*. + conv_bias (`bool`, *optional*, defaults to `False`): + Whether the 1D convolutional layers have a bias. + num_conv_pos_embeddings (`int`, *optional*, defaults to 128): + Number of convolutional positional embeddings. Defines the kernel size of 1D convolutional positional + embeddings layer. + num_conv_pos_embedding_groups (`int`, *optional*, defaults to 16): + Number of groups of 1D convolutional positional embeddings layer. + apply_spec_augment (`bool`, *optional*, defaults to `True`): + Whether to apply *SpecAugment* data augmentation to the outputs of the feature encoder. For reference see + [SpecAugment: A Simple Data Augmentation Method for Automatic Speech + Recognition](https://arxiv.org/abs/1904.08779). + mask_time_prob (`float`, *optional*, defaults to 0.05): + Percentage (between 0 and 1) of all feature vectors along the time axis which will be masked. The masking + procecure generates ''mask_time_prob*len(time_axis)/mask_time_length'' independent masks over the axis. If + reasoning from the propability of each feature vector to be chosen as the start of the vector span to be + masked, *mask_time_prob* should be `prob_vector_start*mask_time_length`. Note that overlap may decrease the + actual percentage of masked vectors. This is only relevant if `apply_spec_augment is True`. + mask_time_length (`int`, *optional*, defaults to 10): + Length of vector span along the time axis. + mask_time_min_masks (`int`, *optional*, defaults to 2),: + The minimum number of masks of length `mask_feature_length` generated along the time axis, each time step, + irrespectively of `mask_feature_prob`. Only relevant if ''mask_time_prob*len(time_axis)/mask_time_length < + mask_time_min_masks'' + mask_feature_prob (`float`, *optional*, defaults to 0.0): + Percentage (between 0 and 1) of all feature vectors along the feature axis which will be masked. The + masking procecure generates ''mask_feature_prob*len(feature_axis)/mask_time_length'' independent masks over + the axis. If reasoning from the propability of each feature vector to be chosen as the start of the vector + span to be masked, *mask_feature_prob* should be `prob_vector_start*mask_feature_length`. Note that overlap + may decrease the actual percentage of masked vectors. This is only relevant if `apply_spec_augment is + True`. + mask_feature_length (`int`, *optional*, defaults to 10): + Length of vector span along the feature axis. + mask_feature_min_masks (`int`, *optional*, defaults to 0),: + The minimum number of masks of length `mask_feature_length` generated along the feature axis, each time + step, irrespectively of `mask_feature_prob`. Only relevant if + ''mask_feature_prob*len(feature_axis)/mask_feature_length < mask_feature_min_masks'' + num_codevectors_per_group (`int`, *optional*, defaults to 320): + Number of entries in each quantization codebook (group). + num_codevector_groups (`int`, *optional*, defaults to 2): + Number of codevector groups for product codevector quantization. + contrastive_logits_temperature (`float`, *optional*, defaults to 0.1): + The temperature *kappa* in the contrastive loss. + feat_quantizer_dropout (`float`, *optional*, defaults to 0.0): + The dropout probabilitiy for the output of the feature encoder that's used by the quantizer. + num_negatives (`int`, *optional*, defaults to 100): + Number of negative samples for the contrastive loss. + codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the quantized feature vectors. + proj_codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the final projection of both the quantized and the transformer features. + diversity_loss_weight (`int`, *optional*, defaults to 0.1): + The weight of the codebook diversity loss component. + ctc_loss_reduction (`str`, *optional*, defaults to `"sum"`): + Specifies the reduction to apply to the output of `torch.nn.CTCLoss`. Only relevant when training an + instance of [`Wav2Vec2ConformerForCTC`]. + ctc_zero_infinity (`bool`, *optional*, defaults to `False`): + Whether to zero infinite losses and the associated gradients of `torch.nn.CTCLoss`. Infinite losses mainly + occur when the inputs are too short to be aligned to the targets. Only relevant when training an instance + of [`Wav2Vec2ConformerForCTC`]. + use_weighted_layer_sum (`bool`, *optional*, defaults to `False`): + Whether to use a weighted average of layer outputs with learned weights. Only relevant when using an + instance of [`Wav2Vec2ConformerForSequenceClassification`]. + classifier_proj_size (`int`, *optional*, defaults to 256): + Dimensionality of the projection before token mean-pooling for classification. + tdnn_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 1500)`): + A tuple of integers defining the number of output channels of each 1D convolutional layer in the *TDNN* + module of the *XVector* model. The length of *tdnn_dim* defines the number of *TDNN* layers. + tdnn_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 3, 3, 1, 1)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the *TDNN* module of the + *XVector* model. The length of *tdnn_kernel* has to match the length of *tdnn_dim*. + tdnn_dilation (`Tuple[int]` or `List[int]`, *optional*, defaults to `(1, 2, 3, 1, 1)`): + A tuple of integers defining the dilation factor of each 1D convolutional layer in *TDNN* module of the + *XVector* model. The length of *tdnn_dilation* has to match the length of *tdnn_dim*. + xvector_output_dim (`int`, *optional*, defaults to 512): + Dimensionality of the *XVector* embedding vectors. + add_adapter (`bool`, *optional*, defaults to `False`): + Whether a convolutional network should be stacked on top of the Wav2Vec2Conformer Encoder. Can be very + useful for warm-starting Wav2Vec2Conformer for SpeechEncoderDecoder models. + adapter_kernel_size (`int`, *optional*, defaults to 3): + Kernel size of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + adapter_stride (`int`, *optional*, defaults to 2): + Stride of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + num_adapter_layers (`int`, *optional*, defaults to 3): + Number of convolutional layers that should be used in the adapter network. Only relevant if `add_adapter is + True`. + output_hidden_size (`int`, *optional*): + Dimensionality of the encoder output layer. If not defined, this defaults to *hidden-size*. Only relevant + if `add_adapter is True`. + position_embeddings_type (`str`, *optional*, defaults to `"relative"`): + Can be specified to `relative` or `rotary` for relative or rotary position embeddings respectively. If left + `None` no relative position embedding is applied. + rotary_embedding_base (`int`, *optional*, defaults to 10000): + If `"rotary"` position embeddings are used, defines the size of the embedding base. + max_source_positions (`int`, *optional*, defaults to 5000): + if `"relative"` position embeddings are used, defines the maximum source input positions. + conv_depthwise_kernel_size (`int`, defaults to 31): + Kernel size of convolutional depthwise 1D layer in Conformer blocks. + conformer_conv_dropout (`float`, defaults to 0.1): + The dropout probability for all convolutional layers in Conformer blocks. + + Example: + + ```python + >>> from transformers import Wav2Vec2ConformerConfig, Wav2Vec2ConformerModel + + >>> # Initializing a Wav2Vec2Conformer facebook/wav2vec2-conformer-rel-pos-large style configuration + >>> configuration = Wav2Vec2ConformerConfig() + + >>> # Initializing a model (with random weights) from the facebook/wav2vec2-conformer-rel-pos-large style configuration + >>> model = Wav2Vec2ConformerModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "wav2vec2-conformer" + + def __init__( + self, + vocab_size=None, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout=0.1, + activation_dropout=0.1, + attention_dropout=0.1, + feat_proj_dropout=0.0, + feat_quantizer_dropout=0.0, + final_dropout=0.1, + layerdrop=0.1, + initializer_range=0.02, + layer_norm_eps=1e-5, + feat_extract_norm="group", + feat_extract_activation="gelu", + conv_dim=(512, 512, 512, 512, 512, 512, 512), + conv_stride=(5, 2, 2, 2, 2, 2, 2), + conv_kernel=(10, 3, 3, 3, 3, 2, 2), + conv_bias=False, + num_conv_pos_embeddings=128, + num_conv_pos_embedding_groups=16, + apply_spec_augment=True, + mask_time_prob=0.05, + mask_time_length=10, + mask_time_min_masks=2, + mask_feature_prob=0.0, + mask_feature_length=10, + mask_feature_min_masks=0, + num_codevectors_per_group=320, + num_codevector_groups=2, + contrastive_logits_temperature=0.1, + num_negatives=100, + codevector_dim=256, + proj_codevector_dim=256, + diversity_loss_weight=0.1, + ctc_loss_reduction="sum", + ctc_zero_infinity=False, + use_weighted_layer_sum=False, + classifier_proj_size=256, + tdnn_dim=(512, 512, 512, 512, 1500), + tdnn_kernel=(5, 3, 3, 1, 1), + tdnn_dilation=(1, 2, 3, 1, 1), + xvector_output_dim=512, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + add_adapter=False, + adapter_kernel_size=3, + adapter_stride=2, + num_adapter_layers=3, + output_hidden_size=None, + position_embeddings_type="relative", + rotary_embedding_base=10000, + max_source_positions=5000, + conv_depthwise_kernel_size=31, + conformer_conv_dropout=0.1, + **kwargs, + ): + super().__init__(**kwargs, pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id) + self.hidden_size = hidden_size + self.feat_extract_norm = feat_extract_norm + self.feat_extract_activation = feat_extract_activation + self.conv_dim = list(conv_dim) + self.conv_stride = list(conv_stride) + self.conv_kernel = list(conv_kernel) + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_feat_extract_layers = len(self.conv_dim) + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_attention_heads = num_attention_heads + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.feat_proj_dropout = feat_proj_dropout + self.final_dropout = final_dropout + self.layerdrop = layerdrop + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.use_weighted_layer_sum = use_weighted_layer_sum + self.max_source_positions = max_source_positions + self.position_embeddings_type = position_embeddings_type + self.rotary_embedding_base = rotary_embedding_base + + if ( + (len(self.conv_stride) != self.num_feat_extract_layers) + or (len(self.conv_kernel) != self.num_feat_extract_layers) + or (len(self.conv_dim) != self.num_feat_extract_layers) + ): + raise ValueError( + "Configuration for convolutional layers is incorrect. It is required that `len(config.conv_dim)` ==" + " `len(config.conv_stride)` == `len(config.conv_kernel)`, but is `len(config.conv_dim) =" + f" {len(self.conv_dim)}`, `len(config.conv_stride) = {len(self.conv_stride)}`," + f" `len(config.conv_kernel) = {len(self.conv_kernel)}`." + ) + + # Conformer-block related + self.conv_depthwise_kernel_size = conv_depthwise_kernel_size + self.conformer_conv_dropout = conformer_conv_dropout + + # fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779 + self.apply_spec_augment = apply_spec_augment + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.mask_time_min_masks = mask_time_min_masks + self.mask_feature_prob = mask_feature_prob + self.mask_feature_length = mask_feature_length + self.mask_feature_min_masks = mask_feature_min_masks + + # parameters for pretraining with codevector quantized representations + self.num_codevectors_per_group = num_codevectors_per_group + self.num_codevector_groups = num_codevector_groups + self.contrastive_logits_temperature = contrastive_logits_temperature + self.feat_quantizer_dropout = feat_quantizer_dropout + self.num_negatives = num_negatives + self.codevector_dim = codevector_dim + self.proj_codevector_dim = proj_codevector_dim + self.diversity_loss_weight = diversity_loss_weight + + # ctc loss + self.ctc_loss_reduction = ctc_loss_reduction + self.ctc_zero_infinity = ctc_zero_infinity + + # adapter + self.add_adapter = add_adapter + self.adapter_kernel_size = adapter_kernel_size + self.adapter_stride = adapter_stride + self.num_adapter_layers = num_adapter_layers + self.output_hidden_size = output_hidden_size or hidden_size + + # SequenceClassification-specific parameter. Feel free to ignore for other classes. + self.classifier_proj_size = classifier_proj_size + + # XVector-specific parameters. Feel free to ignore for other classes. + self.tdnn_dim = list(tdnn_dim) + self.tdnn_kernel = list(tdnn_kernel) + self.tdnn_dilation = list(tdnn_dilation) + self.xvector_output_dim = xvector_output_dim + + @property + def inputs_to_logits_ratio(self): + return functools.reduce(operator.mul, self.conv_stride, 1) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/convert_wav2vec2_conformer_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/convert_wav2vec2_conformer_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..1a882e95aba533ae1d37497ca74acd232ac39bc5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/convert_wav2vec2_conformer_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,310 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Wav2Vec2Conformer checkpoint.""" + + +import argparse +import json +import os + +import fairseq +import torch +from fairseq.data import Dictionary + +from transformers import ( + Wav2Vec2ConformerConfig, + Wav2Vec2ConformerForCTC, + Wav2Vec2ConformerForPreTraining, + Wav2Vec2CTCTokenizer, + Wav2Vec2FeatureExtractor, + Wav2Vec2Processor, + logging, +) + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +MAPPING = { + "post_extract_proj": "feature_projection.projection", + "encoder.pos_conv.0": "encoder.pos_conv_embed.conv", + "self_attn.linear_k": "encoder.layers.*.self_attn.linear_k", + "self_attn.linear_v": "encoder.layers.*.self_attn.linear_v", + "self_attn.linear_q": "encoder.layers.*.self_attn.linear_q", + "self_attn.pos_bias_u": "encoder.layers.*.self_attn.pos_bias_u", + "self_attn.pos_bias_v": "encoder.layers.*.self_attn.pos_bias_v", + "self_attn.linear_out": "encoder.layers.*.self_attn.linear_out", + "self_attn.linear_pos": "encoder.layers.*.self_attn.linear_pos", + "self_attn.rotary_emb": "encoder.embed_positions", + "self_attn_layer_norm": "encoder.layers.*.self_attn_layer_norm", + "conv_module.pointwise_conv1": "encoder.layers.*.conv_module.pointwise_conv1", + "conv_module.pointwise_conv2": "encoder.layers.*.conv_module.pointwise_conv2", + "conv_module.depthwise_conv": "encoder.layers.*.conv_module.depthwise_conv", + "conv_module.batch_norm": "encoder.layers.*.conv_module.batch_norm", + "conv_module.layer_norm": "encoder.layers.*.conv_module.layer_norm", + "ffn1.w_1": "encoder.layers.*.ffn1.intermediate_dense", + "ffn1.w_2": "encoder.layers.*.ffn1.output_dense", + "ffn1.layer_norm": "encoder.layers.*.ffn1_layer_norm", + "ffn2.w_1": "encoder.layers.*.ffn2.intermediate_dense", + "ffn2.w_2": "encoder.layers.*.ffn2.output_dense", + "ffn2.layer_norm": "encoder.layers.*.ffn2_layer_norm", + "final_layer_norm": "encoder.layers.*.final_layer_norm", + "encoder.layer_norm": "encoder.layer_norm", + "w2v_model.layer_norm": "feature_projection.layer_norm", + "quantizer.weight_proj": "quantizer.weight_proj", + "quantizer.vars": "quantizer.codevectors", + "project_q": "project_q", + "final_proj": "project_hid", + "w2v_encoder.proj": "lm_head", + "mask_emb": "masked_spec_embed", +} +TOP_LEVEL_KEYS = [ + "lm_head", + "quantizer.weight_proj", + "quantizer.codevectors", + "project_q", + "project_hid", +] + + +def set_recursively(hf_pointer, key, value, full_name, weight_type): + for attribute in key.split("."): + hf_pointer = getattr(hf_pointer, attribute) + + if weight_type is not None: + hf_shape = getattr(hf_pointer, weight_type).shape + else: + hf_shape = hf_pointer.shape + + if hf_shape != value.shape: + raise ValueError( + f"Shape of hf {key + '.' + weight_type if weight_type is not None else ''} is {hf_shape}, but should be" + f" {value.shape} for {full_name}" + ) + + if weight_type == "weight": + hf_pointer.weight.data = value + elif weight_type == "weight_g": + hf_pointer.weight_g.data = value + elif weight_type == "weight_v": + hf_pointer.weight_v.data = value + elif weight_type == "bias": + hf_pointer.bias.data = value + elif weight_type == "running_mean": + hf_pointer.running_mean.data = value + elif weight_type == "running_var": + hf_pointer.running_var.data = value + elif weight_type == "num_batches_tracked": + hf_pointer.num_batches_tracked.data = value + elif weight_type == "inv_freq": + hf_pointer.inv_freq.data = value + else: + hf_pointer.data = value + + logger.info(f"{key + '.' + weight_type if weight_type is not None else ''} was initialized from {full_name}.") + + +def recursively_load_weights(fairseq_model, hf_model, is_headless): + unused_weights = [] + fairseq_dict = fairseq_model.state_dict() + + feature_extractor = hf_model.wav2vec2_conformer.feature_extractor + + for name, value in fairseq_dict.items(): + is_used = False + if "conv_layers" in name: + load_conv_layer( + name, + value, + feature_extractor, + unused_weights, + hf_model.config.feat_extract_norm == "group", + ) + is_used = True + else: + for key, mapped_key in MAPPING.items(): + mapped_key = "wav2vec2_conformer." + mapped_key if mapped_key not in TOP_LEVEL_KEYS else mapped_key + if key in name or key.split("w2v_model.")[-1] == name.split(".")[0]: + is_used = True + if "*" in mapped_key: + layer_index = name.split(key)[0].split(".")[-2] + mapped_key = mapped_key.replace("*", layer_index) + if "pos_bias_u" in name: + weight_type = None + elif "pos_bias_v" in name: + weight_type = None + elif "weight_g" in name: + weight_type = "weight_g" + elif "weight_v" in name: + weight_type = "weight_v" + elif "bias" in name: + weight_type = "bias" + elif "weight" in name: + # TODO: don't match quantizer.weight_proj + weight_type = "weight" + elif "running_mean" in name: + weight_type = "running_mean" + elif "inv_freq" in name: + weight_type = "inv_freq" + elif "running_var" in name: + weight_type = "running_var" + elif "num_batches_tracked" in name: + weight_type = "num_batches_tracked" + else: + weight_type = None + set_recursively(hf_model, mapped_key, value, name, weight_type) + continue + if not is_used: + unused_weights.append(name) + + logger.warning(f"Unused weights: {unused_weights}") + + +# Copied from transformers.models.wav2vec2.convert_wav2vec2_original_pytorch_checkpoint_to_pytorch.load_conv_layer +def load_conv_layer(full_name, value, feature_extractor, unused_weights, use_group_norm): + name = full_name.split("conv_layers.")[-1] + items = name.split(".") + layer_id = int(items[0]) + type_id = int(items[1]) + + if type_id == 0: + if "bias" in name: + if value.shape != feature_extractor.conv_layers[layer_id].conv.bias.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.bias.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + if value.shape != feature_extractor.conv_layers[layer_id].conv.weight.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.weight.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif (type_id == 2 and not use_group_norm) or (type_id == 2 and layer_id == 0 and use_group_norm): + if "bias" in name: + if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.bias.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape: + raise ValueError( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.weight.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + else: + unused_weights.append(full_name) + + +@torch.no_grad() +def convert_wav2vec2_conformer_checkpoint( + checkpoint_path, pytorch_dump_folder_path, config_path=None, dict_path=None, is_finetuned=True +): + """ + Copy/paste/tweak model's weights to transformers design. + """ + if config_path is not None: + config = Wav2Vec2ConformerConfig.from_pretrained(config_path, hidden_act="swish") + else: + config = Wav2Vec2ConformerConfig() + + if "rope" in checkpoint_path: + config.position_embeddings_type = "rotary" + + if is_finetuned: + if dict_path: + target_dict = Dictionary.load(dict_path) + + # important change bos & pad token id since CTC symbol is and + # not as in fairseq + config.bos_token_id = target_dict.pad_index + config.pad_token_id = target_dict.bos_index + config.eos_token_id = target_dict.eos_index + config.vocab_size = len(target_dict.symbols) + vocab_path = os.path.join(pytorch_dump_folder_path, "vocab.json") + if not os.path.isdir(pytorch_dump_folder_path): + logger.error("--pytorch_dump_folder_path ({}) should be a directory".format(pytorch_dump_folder_path)) + return + os.makedirs(pytorch_dump_folder_path, exist_ok=True) + vocab_dict = target_dict.indices + + # fairseq has the and switched + vocab_dict[""] = 0 + vocab_dict[""] = 1 + with open(vocab_path, "w", encoding="utf-8") as vocab_handle: + json.dump(vocab_dict, vocab_handle) + tokenizer = Wav2Vec2CTCTokenizer( + vocab_path, + unk_token=target_dict.unk_word, + pad_token=target_dict.pad_word, + bos_token=target_dict.bos_word, + eos_token=target_dict.eos_word, + word_delimiter_token="|", + do_lower_case=False, + ) + return_attention_mask = True if config.feat_extract_norm == "layer" else False + feature_extractor = Wav2Vec2FeatureExtractor( + feature_size=1, + sampling_rate=16000, + padding_value=0, + do_normalize=True, + return_attention_mask=return_attention_mask, + ) + processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer) + processor.save_pretrained(pytorch_dump_folder_path) + + hf_wav2vec = Wav2Vec2ConformerForCTC(config) + else: + hf_wav2vec = Wav2Vec2ConformerForPreTraining(config) + + if is_finetuned: + model, _, _ = fairseq.checkpoint_utils.load_model_ensemble_and_task( + [checkpoint_path], arg_overrides={"data": "/".join(dict_path.split("/")[:-1])} + ) + else: + task_arg = argparse.Namespace(task="audio_pretraining") + task = fairseq.tasks.setup_task(task_arg) + + model, _, _ = fairseq.checkpoint_utils.load_model_ensemble_and_task([checkpoint_path], task=task) + + model = model[0].eval() + + recursively_load_weights(model, hf_wav2vec, not is_finetuned) + + hf_wav2vec.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.") + parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to fairseq checkpoint") + parser.add_argument("--dict_path", default=None, type=str, help="Path to dict of fine-tuned model") + parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert") + parser.add_argument( + "--not_finetuned", action="store_true", help="Whether the model to convert is a fine-tuned model or not" + ) + args = parser.parse_args() + convert_wav2vec2_conformer_checkpoint( + args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py new file mode 100644 index 0000000000000000000000000000000000000000..94ce66e4f3d755d86cbbb605c366b7893272e2c9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_conformer/modeling_wav2vec2_conformer.py @@ -0,0 +1,2119 @@ +# coding=utf-8 +# Copyright 2022 The Fairseq Authors and the HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Wav2Vec2-Conformer model.""" + +import math +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import numpy as np +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...deepspeed import is_deepspeed_zero3_enabled +from ...modeling_outputs import ( + BaseModelOutput, + CausalLMOutput, + SequenceClassifierOutput, + TokenClassifierOutput, + Wav2Vec2BaseModelOutput, + XVectorOutput, +) +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_wav2vec2_conformer import Wav2Vec2ConformerConfig + + +logger = logging.get_logger(__name__) + + +_HIDDEN_STATES_START_POSITION = 2 + +# General docstring +_CONFIG_FOR_DOC = "Wav2Vec2ConformerConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "facebook/wav2vec2-conformer-rope-large-960h-ft" +_EXPECTED_OUTPUT_SHAPE = [1, 292, 1024] + +# CTC docstring +_CTC_EXPECTED_OUTPUT = "'MISTER QUILTER IS THE APOSTLE OF THE MIDDLE CLASSES AND WE ARE GLAD TO WELCOME HIS GOSPEL'" +_CTC_EXPECTED_LOSS = 64.21 + + +WAV2VEC2_CONFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/wav2vec2-conformer-rel-pos-large", + # See all Wav2Vec2Conformer models at https://huggingface.co/models?filter=wav2vec2-conformer +] + + +@dataclass +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTrainingOutput with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerForPreTrainingOutput(ModelOutput): + """ + Output type of [`Wav2Vec2ConformerForPreTraining`], with potential hidden states and attentions. + + Args: + loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + Total loss as the sum of the contrastive loss (L_m) and the diversity loss (L_d) as stated in the [official + paper](https://arxiv.org/pdf/2006.11477.pdf) . (classification) loss. + projected_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Hidden-states of the model projected to *config.proj_codevector_dim* that can be used to predict the masked + projected quantized states. + projected_quantized_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.proj_codevector_dim)`): + Quantized extracted feature vectors projected to *config.proj_codevector_dim* representing the positive + target vectors for contrastive loss. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + contrastive_loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + The contrastive loss (L_m) as stated in the [official paper](https://arxiv.org/pdf/2006.11477.pdf) . + diversity_loss (*optional*, returned when `sample_negative_indices` are passed, `torch.FloatTensor` of shape `(1,)`): + The diversity loss (L_d) as stated in the [official paper](https://arxiv.org/pdf/2006.11477.pdf) . + """ + + loss: Optional[torch.FloatTensor] = None + projected_states: torch.FloatTensor = None + projected_quantized_states: torch.FloatTensor = None + codevector_perplexity: torch.FloatTensor = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + contrastive_loss: Optional[torch.FloatTensor] = None + diversity_loss: Optional[torch.FloatTensor] = None + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2._compute_mask_indices +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + attention_mask: Optional[torch.LongTensor] = None, + min_masks: int = 0, +) -> np.ndarray: + """ + Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for + ASR](https://arxiv.org/abs/1904.08779). Note that this method is not optimized to run on TPU and should be run on + CPU as part of the preprocessing during training. + + Args: + shape: The shape for which to compute masks. This should be of a tuple of size 2 where + the first element is the batch size and the second element is the length of the axis to span. + mask_prob: The percentage of the whole axis (between 0 and 1) which will be masked. The number of + independently generated mask spans of length `mask_length` is computed by + `mask_prob*shape[1]/mask_length`. Note that due to overlaps, `mask_prob` is an upper bound and the + actual percentage will be smaller. + mask_length: size of the mask + min_masks: minimum number of masked spans + attention_mask: A (right-padded) attention mask which independently shortens the feature axis of + each batch dimension. + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + if mask_length > sequence_length: + raise ValueError( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length}" + f" and `sequence_length`: {sequence_length}`" + ) + + # epsilon is used for probabilistic rounding + epsilon = np.random.rand(1).item() + + def compute_num_masked_span(input_length): + """Given input length, compute how many spans should be masked""" + num_masked_span = int(mask_prob * input_length / mask_length + epsilon) + num_masked_span = max(num_masked_span, min_masks) + + # make sure num masked span <= sequence_length + if num_masked_span * mask_length > sequence_length: + num_masked_span = sequence_length // mask_length + + # make sure num_masked span is also <= input_length - (mask_length - 1) + if input_length - (mask_length - 1) < num_masked_span: + num_masked_span = max(input_length - (mask_length - 1), 0) + + return num_masked_span + + # compute number of masked spans in batch + input_lengths = ( + attention_mask.sum(-1).detach().tolist() + if attention_mask is not None + else [sequence_length for _ in range(batch_size)] + ) + + # SpecAugment mask to fill + spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) + spec_aug_mask_idxs = [] + + max_num_masked_span = compute_num_masked_span(sequence_length) + + if max_num_masked_span == 0: + return spec_aug_mask + + for input_length in input_lengths: + # compute num of masked spans for this input + num_masked_span = compute_num_masked_span(input_length) + + # get random indices to mask + spec_aug_mask_idx = np.random.choice( + np.arange(input_length - (mask_length - 1)), num_masked_span, replace=False + ) + + # pick first sampled index that will serve as a dummy index to pad vector + # to ensure same dimension for all batches due to probabilistic rounding + # Picking first sample just pads those vectors twice. + if len(spec_aug_mask_idx) == 0: + # this case can only happen if `input_length` is strictly smaller then + # `sequence_length` in which case the last token has to be a padding + # token which we can use as a dummy mask id + dummy_mask_idx = sequence_length - 1 + else: + dummy_mask_idx = spec_aug_mask_idx[0] + + spec_aug_mask_idx = np.concatenate( + [spec_aug_mask_idx, np.ones(max_num_masked_span - num_masked_span, dtype=np.int32) * dummy_mask_idx] + ) + spec_aug_mask_idxs.append(spec_aug_mask_idx) + + spec_aug_mask_idxs = np.array(spec_aug_mask_idxs) + + # expand masked indices to masked spans + spec_aug_mask_idxs = np.broadcast_to( + spec_aug_mask_idxs[:, :, None], (batch_size, max_num_masked_span, mask_length) + ) + spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, max_num_masked_span * mask_length) + + # add offset to the starting indexes so that indexes now create a span + offsets = np.arange(mask_length)[None, None, :] + offsets = np.broadcast_to(offsets, (batch_size, max_num_masked_span, mask_length)).reshape( + batch_size, max_num_masked_span * mask_length + ) + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # ensure that we cannot have indices larger than sequence_length + if spec_aug_mask_idxs.max() > sequence_length - 1: + spec_aug_mask_idxs[spec_aug_mask_idxs > sequence_length - 1] = sequence_length - 1 + + # scatter indices to mask + np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) + + return spec_aug_mask + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2._sample_negative_indices +def _sample_negative_indices( + features_shape: Tuple, num_negatives: int, mask_time_indices: Optional[np.ndarray] = None +): + """ + Sample `num_negatives` vectors from feature vectors. + """ + batch_size, sequence_length = features_shape + + # generate indices of the positive vectors themselves, repeat them `num_negatives` times + sequence_length_range = np.arange(sequence_length) + + # get `num_negatives` random vector indices from the same utterance + sampled_negative_indices = np.zeros(shape=(batch_size, sequence_length, num_negatives), dtype=np.int32) + + mask_time_indices = ( + mask_time_indices.astype(bool) if mask_time_indices is not None else np.ones(features_shape, dtype=bool) + ) + + for batch_idx in range(batch_size): + high = mask_time_indices[batch_idx].sum() - 1 + mapped_masked_indices = sequence_length_range[mask_time_indices[batch_idx]] + + feature_indices = np.broadcast_to(np.arange(high + 1)[:, None], (high + 1, num_negatives)) + sampled_indices = np.random.randint(0, high, size=(high + 1, num_negatives)) + # avoid sampling the same positive vector, but keep the distribution uniform + sampled_indices[sampled_indices >= feature_indices] += 1 + + # remap to actual indices + sampled_negative_indices[batch_idx][mask_time_indices[batch_idx]] = mapped_masked_indices[sampled_indices] + + # correct for batch size + sampled_negative_indices[batch_idx] += batch_idx * sequence_length + + return sampled_negative_indices + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2NoLayerNormConvLayer with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerNoLayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2LayerNormConvLayer with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerLayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.layer_norm = nn.LayerNorm(self.out_conv_dim, elementwise_affine=True) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + + hidden_states = hidden_states.transpose(-2, -1) + hidden_states = self.layer_norm(hidden_states) + hidden_states = hidden_states.transpose(-2, -1) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2GroupNormConvLayer with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerGroupNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + self.layer_norm = nn.GroupNorm(num_groups=self.out_conv_dim, num_channels=self.out_conv_dim, affine=True) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2PositionalConvEmbedding with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerPositionalConvEmbedding(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.hidden_size, + config.hidden_size, + kernel_size=config.num_conv_pos_embeddings, + padding=config.num_conv_pos_embeddings // 2, + groups=config.num_conv_pos_embedding_groups, + ) + + if is_deepspeed_zero3_enabled(): + import deepspeed + + with deepspeed.zero.GatheredParameters(self.conv.weight, modifier_rank=0): + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + deepspeed.zero.register_external_parameter(self, self.conv.weight_v) + deepspeed.zero.register_external_parameter(self, self.conv.weight_g) + else: + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + + self.padding = Wav2Vec2ConformerSamePadLayer(config.num_conv_pos_embeddings) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = hidden_states.transpose(1, 2) + + hidden_states = self.conv(hidden_states) + hidden_states = self.padding(hidden_states) + hidden_states = self.activation(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +class Wav2Vec2ConformerRotaryPositionalEmbedding(nn.Module): + """Rotary positional embedding + Reference : https://blog.eleuther.ai/rotary-embeddings/ Paper: https://arxiv.org/pdf/2104.09864.pdf + """ + + def __init__(self, config): + super().__init__() + dim = config.hidden_size // config.num_attention_heads + base = config.rotary_embedding_base + + inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim)) + self.register_buffer("inv_freq", inv_freq) + self.cached_sequence_length = None + self.cached_rotary_positional_embedding = None + + def forward(self, hidden_states): + sequence_length = hidden_states.shape[1] + + if sequence_length == self.cached_sequence_length and self.cached_rotary_positional_embedding is not None: + return self.cached_rotary_positional_embedding + + self.cached_sequence_length = sequence_length + time_stamps = torch.arange(sequence_length).type_as(self.inv_freq) + freqs = torch.einsum("i,j->ij", time_stamps, self.inv_freq) + embeddings = torch.cat((freqs, freqs), dim=-1) + + cos_embeddings = embeddings.cos()[:, None, None, :] + sin_embeddings = embeddings.sin()[:, None, None, :] + self.cached_rotary_positional_embedding = torch.stack([cos_embeddings, sin_embeddings]) + return self.cached_rotary_positional_embedding + + +class Wav2Vec2ConformerRelPositionalEmbedding(nn.Module): + """Relative positional encoding module.""" + + def __init__(self, config): + super().__init__() + self.max_len = config.max_source_positions + self.d_model = config.hidden_size + self.pe = None + self.extend_pe(torch.tensor(0.0).expand(1, self.max_len)) + + def extend_pe(self, x): + # Reset the positional encodings + if self.pe is not None: + # self.pe contains both positive and negative parts + # the length of self.pe is 2 * input_len - 1 + if self.pe.size(1) >= x.size(1) * 2 - 1: + if self.pe.dtype != x.dtype or self.pe.device != x.device: + self.pe = self.pe.to(dtype=x.dtype, device=x.device) + return + # Suppose `i` is the position of query vector and `j` is the + # position of key vector. We use positive relative positions when keys + # are to the left (i>j) and negative relative positions otherwise (iWav2Vec2Conformer +class Wav2Vec2ConformerSamePadLayer(nn.Module): + def __init__(self, num_conv_pos_embeddings): + super().__init__() + self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 + + def forward(self, hidden_states): + if self.num_pad_remove > 0: + hidden_states = hidden_states[:, :, : -self.num_pad_remove] + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeatureEncoder with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerFeatureEncoder(nn.Module): + """Construct the features from raw audio waveform""" + + def __init__(self, config): + super().__init__() + + if config.feat_extract_norm == "group": + conv_layers = [Wav2Vec2ConformerGroupNormConvLayer(config, layer_id=0)] + [ + Wav2Vec2ConformerNoLayerNormConvLayer(config, layer_id=i + 1) + for i in range(config.num_feat_extract_layers - 1) + ] + elif config.feat_extract_norm == "layer": + conv_layers = [ + Wav2Vec2ConformerLayerNormConvLayer(config, layer_id=i) for i in range(config.num_feat_extract_layers) + ] + else: + raise ValueError( + f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" + ) + self.conv_layers = nn.ModuleList(conv_layers) + self.gradient_checkpointing = False + self._requires_grad = True + + def _freeze_parameters(self): + for param in self.parameters(): + param.requires_grad = False + self._requires_grad = False + + def forward(self, input_values): + hidden_states = input_values[:, None] + + # make sure hidden_states require grad for gradient_checkpointing + if self._requires_grad and self.training: + hidden_states.requires_grad = True + + for conv_layer in self.conv_layers: + if self._requires_grad and self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(conv_layer), + hidden_states, + ) + else: + hidden_states = conv_layer(hidden_states) + + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeatureProjection with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerFeatureProjection(nn.Module): + def __init__(self, config): + super().__init__() + self.layer_norm = nn.LayerNorm(config.conv_dim[-1], eps=config.layer_norm_eps) + self.projection = nn.Linear(config.conv_dim[-1], config.hidden_size) + self.dropout = nn.Dropout(config.feat_proj_dropout) + + def forward(self, hidden_states): + # non-projected hidden states are needed for quantization + norm_hidden_states = self.layer_norm(hidden_states) + hidden_states = self.projection(norm_hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states, norm_hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeedForward with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerFeedForward(nn.Module): + def __init__(self, config): + super().__init__() + self.intermediate_dropout = nn.Dropout(config.activation_dropout) + + self.intermediate_dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + self.output_dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.output_dropout = nn.Dropout(config.hidden_dropout) + + def forward(self, hidden_states): + hidden_states = self.intermediate_dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + hidden_states = self.intermediate_dropout(hidden_states) + + hidden_states = self.output_dense(hidden_states) + hidden_states = self.output_dropout(hidden_states) + return hidden_states + + +class Wav2Vec2ConformerConvolutionModule(nn.Module): + """Convolution block used in the conformer block""" + + def __init__(self, config): + super().__init__() + if (config.conv_depthwise_kernel_size - 1) % 2 == 1: + raise ValueError("`config.conv_depthwise_kernel_size` should be a odd number for 'SAME' padding") + self.layer_norm = nn.LayerNorm(config.hidden_size) + self.pointwise_conv1 = torch.nn.Conv1d( + config.hidden_size, + 2 * config.hidden_size, + kernel_size=1, + stride=1, + padding=0, + bias=False, + ) + self.glu = torch.nn.GLU(dim=1) + self.depthwise_conv = torch.nn.Conv1d( + config.hidden_size, + config.hidden_size, + config.conv_depthwise_kernel_size, + stride=1, + padding=(config.conv_depthwise_kernel_size - 1) // 2, + groups=config.hidden_size, + bias=False, + ) + self.batch_norm = torch.nn.BatchNorm1d(config.hidden_size) + self.activation = ACT2FN[config.hidden_act] + self.pointwise_conv2 = torch.nn.Conv1d( + config.hidden_size, + config.hidden_size, + kernel_size=1, + stride=1, + padding=0, + bias=False, + ) + self.dropout = torch.nn.Dropout(config.conformer_conv_dropout) + + def forward(self, hidden_states): + hidden_states = self.layer_norm(hidden_states) + # exchange the temporal dimension and the feature dimension + hidden_states = hidden_states.transpose(1, 2) + + # GLU mechanism + # => (batch, 2*channel, dim) + hidden_states = self.pointwise_conv1(hidden_states) + # => (batch, channel, dim) + hidden_states = self.glu(hidden_states) + + # 1D Depthwise Conv + hidden_states = self.depthwise_conv(hidden_states) + hidden_states = self.batch_norm(hidden_states) + hidden_states = self.activation(hidden_states) + + hidden_states = self.pointwise_conv2(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +class Wav2Vec2ConformerSelfAttention(nn.Module): + """Construct an Wav2Vec2ConformerSelfAttention object. + Can be enhanced with rotary or relative position embeddings. + """ + + def __init__(self, config): + super().__init__() + + self.head_size = config.hidden_size // config.num_attention_heads + self.num_heads = config.num_attention_heads + self.position_embeddings_type = config.position_embeddings_type + + self.linear_q = nn.Linear(config.hidden_size, config.hidden_size) + self.linear_k = nn.Linear(config.hidden_size, config.hidden_size) + self.linear_v = nn.Linear(config.hidden_size, config.hidden_size) + self.linear_out = nn.Linear(config.hidden_size, config.hidden_size) + + self.dropout = nn.Dropout(p=config.attention_dropout) + + if self.position_embeddings_type == "relative": + # linear transformation for positional encoding + self.linear_pos = nn.Linear(config.hidden_size, config.hidden_size, bias=False) + # these two learnable bias are used in matrix c and matrix d + # as described in https://arxiv.org/abs/1901.02860 Section 3.3 + self.pos_bias_u = nn.Parameter(torch.zeros(self.num_heads, self.head_size)) + self.pos_bias_v = nn.Parameter(torch.zeros(self.num_heads, self.head_size)) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + relative_position_embeddings: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + # self-attention mechanism + batch_size, sequence_length, hidden_size = hidden_states.size() + + # make sure query/key states can be != value states + query_key_states = hidden_states + value_states = hidden_states + + if self.position_embeddings_type == "rotary": + if relative_position_embeddings is None: + raise ValueError( + "`relative_position_embeddings` has to be defined when `self.position_embeddings_type == 'rotary'" + ) + query_key_states = self._apply_rotary_embedding(query_key_states, relative_position_embeddings) + + # project query_key_states and value_states + query = self.linear_q(query_key_states).view(batch_size, -1, self.num_heads, self.head_size) + key = self.linear_k(query_key_states).view(batch_size, -1, self.num_heads, self.head_size) + value = self.linear_v(value_states).view(batch_size, -1, self.num_heads, self.head_size) + + # => (batch, head, time1, d_k) + query = query.transpose(1, 2) + key = key.transpose(1, 2) + value = value.transpose(1, 2) + + if self.position_embeddings_type == "relative": + if relative_position_embeddings is None: + raise ValueError( + "`relative_position_embeddings` has to be defined when `self.position_embeddings_type ==" + " 'relative'" + ) + # apply relative_position_embeddings to qk scores + # as proposed in Transformer_XL: https://arxiv.org/abs/1901.02860 + scores = self._apply_relative_embeddings( + query=query, key=key, relative_position_embeddings=relative_position_embeddings + ) + else: + scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(self.head_size) + + # apply attention_mask if necessary + if attention_mask is not None: + scores = scores + attention_mask + + # => (batch, head, time1, time2) + probs = torch.softmax(scores, dim=-1) + probs = self.dropout(probs) + + # => (batch, head, time1, d_k) + hidden_states = torch.matmul(probs, value) + + # => (batch, time1, hidden_size) + hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, self.num_heads * self.head_size) + hidden_states = self.linear_out(hidden_states) + + return hidden_states, probs + + def _apply_rotary_embedding(self, hidden_states, relative_position_embeddings): + batch_size, sequence_length, hidden_size = hidden_states.size() + hidden_states = hidden_states.view(batch_size, sequence_length, self.num_heads, self.head_size) + + cos = relative_position_embeddings[0, :sequence_length, ...] + sin = relative_position_embeddings[1, :sequence_length, ...] + + # rotate hidden_states with rotary embeddings + hidden_states = hidden_states.transpose(0, 1) + rotated_states_begin = hidden_states[..., : self.head_size // 2] + rotated_states_end = hidden_states[..., self.head_size // 2 :] + rotated_states = torch.cat((-rotated_states_end, rotated_states_begin), dim=rotated_states_begin.ndim - 1) + hidden_states = (hidden_states * cos) + (rotated_states * sin) + hidden_states = hidden_states.transpose(0, 1) + + hidden_states = hidden_states.view(batch_size, sequence_length, self.num_heads * self.head_size) + + return hidden_states + + def _apply_relative_embeddings(self, query, key, relative_position_embeddings): + # 1. project positional embeddings + # => (batch, head, 2*time1-1, d_k) + proj_relative_position_embeddings = self.linear_pos(relative_position_embeddings) + proj_relative_position_embeddings = proj_relative_position_embeddings.view( + relative_position_embeddings.size(0), -1, self.num_heads, self.head_size + ) + proj_relative_position_embeddings = proj_relative_position_embeddings.transpose(1, 2) + proj_relative_position_embeddings = proj_relative_position_embeddings.transpose(2, 3) + + # 2. Add bias to query + # => (batch, head, time1, d_k) + query = query.transpose(1, 2) + q_with_bias_u = (query + self.pos_bias_u).transpose(1, 2) + q_with_bias_v = (query + self.pos_bias_v).transpose(1, 2) + + # 3. attention score: first compute matrix a and matrix c + # as described in https://arxiv.org/abs/1901.02860 Section 3.3 + # => (batch, head, time1, time2) + scores_ac = torch.matmul(q_with_bias_u, key.transpose(-2, -1)) + + # 4. then compute matrix b and matrix d + # => (batch, head, time1, 2*time1-1) + scores_bd = torch.matmul(q_with_bias_v, proj_relative_position_embeddings) + + # 5. shift matrix b and matrix d + zero_pad = torch.zeros((*scores_bd.size()[:3], 1), device=scores_bd.device, dtype=scores_bd.dtype) + scores_bd_padded = torch.cat([zero_pad, scores_bd], dim=-1) + scores_bd_padded_shape = scores_bd.size()[:2] + (scores_bd.shape[3] + 1, scores_bd.shape[2]) + scores_bd_padded = scores_bd_padded.view(*scores_bd_padded_shape) + scores_bd = scores_bd_padded[:, :, 1:].view_as(scores_bd) + scores_bd = scores_bd[:, :, :, : scores_bd.size(-1) // 2 + 1] + + # 6. sum matrices + # => (batch, head, time1, time2) + scores = (scores_ac + scores_bd) / math.sqrt(self.head_size) + + return scores + + +class Wav2Vec2ConformerEncoderLayer(nn.Module): + """Conformer block based on https://arxiv.org/abs/2005.08100.""" + + def __init__(self, config): + super().__init__() + embed_dim = config.hidden_size + dropout = config.attention_dropout + + # Feed-forward 1 + self.ffn1_layer_norm = nn.LayerNorm(embed_dim) + self.ffn1 = Wav2Vec2ConformerFeedForward(config) + + # Self-Attention + self.self_attn_layer_norm = nn.LayerNorm(embed_dim) + self.self_attn_dropout = torch.nn.Dropout(dropout) + self.self_attn = Wav2Vec2ConformerSelfAttention(config) + + # Conformer Convolution + self.conv_module = Wav2Vec2ConformerConvolutionModule(config) + + # Feed-forward 2 + self.ffn2_layer_norm = nn.LayerNorm(embed_dim) + self.ffn2 = Wav2Vec2ConformerFeedForward(config) + self.final_layer_norm = nn.LayerNorm(embed_dim) + + def forward( + self, + hidden_states, + attention_mask: Optional[torch.Tensor] = None, + relative_position_embeddings: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ): + hidden_states = hidden_states + + # 1. Feed-Forward 1 layer + residual = hidden_states + hidden_states = self.ffn1_layer_norm(hidden_states) + hidden_states = self.ffn1(hidden_states) + hidden_states = hidden_states * 0.5 + residual + residual = hidden_states + + # 2. Self-Attention layer + hidden_states = self.self_attn_layer_norm(hidden_states) + hidden_states, attn_weigts = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + relative_position_embeddings=relative_position_embeddings, + output_attentions=output_attentions, + ) + hidden_states = self.self_attn_dropout(hidden_states) + hidden_states = hidden_states + residual + + # 3. Convolutional Layer + residual = hidden_states + hidden_states = self.conv_module(hidden_states) + hidden_states = residual + hidden_states + + # 4. Feed-Forward 2 Layer + residual = hidden_states + hidden_states = self.ffn2_layer_norm(hidden_states) + hidden_states = self.ffn2(hidden_states) + hidden_states = hidden_states * 0.5 + residual + hidden_states = self.final_layer_norm(hidden_states) + + return hidden_states, attn_weigts + + +class Wav2Vec2ConformerEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + + if config.position_embeddings_type == "relative": + self.embed_positions = Wav2Vec2ConformerRelPositionalEmbedding(config) + elif config.position_embeddings_type == "rotary": + self.embed_positions = Wav2Vec2ConformerRotaryPositionalEmbedding(config) + else: + self.embed_positions = None + + self.pos_conv_embed = Wav2Vec2ConformerPositionalConvEmbedding(config) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layers = nn.ModuleList([Wav2Vec2ConformerEncoderLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + # make sure padded tokens output 0 + hidden_states[~attention_mask] = 0.0 + + # extend attention_mask + attention_mask = 1.0 - attention_mask[:, None, None, :].to(dtype=hidden_states.dtype) + attention_mask = attention_mask * torch.finfo(hidden_states.dtype).min + attention_mask = attention_mask.expand( + attention_mask.shape[0], 1, attention_mask.shape[-1], attention_mask.shape[-1] + ) + + hidden_states = self.dropout(hidden_states) + + if self.embed_positions is not None: + relative_position_embeddings = self.embed_positions(hidden_states) + else: + relative_position_embeddings = None + + deepspeed_zero3_is_enabled = is_deepspeed_zero3_enabled() + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + + skip_the_layer = True if self.training and (dropout_probability < self.config.layerdrop) else False + if not skip_the_layer or deepspeed_zero3_is_enabled: + # under deepspeed zero3 all gpus must run in sync + if self.gradient_checkpointing and self.training: + # create gradient checkpointing function + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer), + hidden_states, + attention_mask, + relative_position_embeddings, + ) + else: + layer_outputs = layer( + hidden_states, + attention_mask=attention_mask, + relative_position_embeddings=relative_position_embeddings, + output_attentions=output_attentions, + ) + hidden_states = layer_outputs[0] + + if skip_the_layer: + layer_outputs = (None, None) + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + hidden_states = self.layer_norm(hidden_states) + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2GumbelVectorQuantizer with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerGumbelVectorQuantizer(nn.Module): + """ + Vector quantization using gumbel softmax. See `[CATEGORICAL REPARAMETERIZATION WITH + GUMBEL-SOFTMAX](https://arxiv.org/pdf/1611.01144.pdf) for more information. + """ + + def __init__(self, config): + super().__init__() + self.num_groups = config.num_codevector_groups + self.num_vars = config.num_codevectors_per_group + + if config.codevector_dim % self.num_groups != 0: + raise ValueError( + f"`config.codevector_dim {config.codevector_dim} must be divisible " + f"by `config.num_codevector_groups` {self.num_groups} for concatenation" + ) + + # storage for codebook variables (codewords) + self.codevectors = nn.Parameter( + torch.FloatTensor(1, self.num_groups * self.num_vars, config.codevector_dim // self.num_groups) + ) + self.weight_proj = nn.Linear(config.conv_dim[-1], self.num_groups * self.num_vars) + + # can be decayed for training + self.temperature = 2 + + @staticmethod + def _compute_perplexity(probs, mask=None): + if mask is not None: + mask_extended = mask.flatten()[:, None, None].expand(probs.shape) + probs = torch.where(mask_extended, probs, torch.zeros_like(probs)) + marginal_probs = probs.sum(dim=0) / mask.sum() + else: + marginal_probs = probs.mean(dim=0) + + perplexity = torch.exp(-torch.sum(marginal_probs * torch.log(marginal_probs + 1e-7), dim=-1)).sum() + return perplexity + + def forward(self, hidden_states, mask_time_indices=None): + batch_size, sequence_length, hidden_size = hidden_states.shape + + # project to codevector dim + hidden_states = self.weight_proj(hidden_states) + hidden_states = hidden_states.view(batch_size * sequence_length * self.num_groups, -1) + + if self.training: + # sample code vector probs via gumbel in differentiateable way + codevector_probs = nn.functional.gumbel_softmax( + hidden_states.float(), tau=self.temperature, hard=True + ).type_as(hidden_states) + + # compute perplexity + codevector_soft_dist = torch.softmax( + hidden_states.view(batch_size * sequence_length, self.num_groups, -1).float(), dim=-1 + ) + perplexity = self._compute_perplexity(codevector_soft_dist, mask_time_indices) + else: + # take argmax in non-differentiable way + # comptute hard codevector distribution (one hot) + codevector_idx = hidden_states.argmax(dim=-1) + codevector_probs = hidden_states.new_zeros(hidden_states.shape).scatter_( + -1, codevector_idx.view(-1, 1), 1.0 + ) + codevector_probs = codevector_probs.view(batch_size * sequence_length, self.num_groups, -1) + + perplexity = self._compute_perplexity(codevector_probs, mask_time_indices) + + codevector_probs = codevector_probs.view(batch_size * sequence_length, -1) + # use probs to retrieve codevectors + codevectors_per_group = codevector_probs.unsqueeze(-1) * self.codevectors + codevectors = codevectors_per_group.view(batch_size * sequence_length, self.num_groups, self.num_vars, -1) + codevectors = codevectors.sum(-2).view(batch_size, sequence_length, -1) + + return codevectors, perplexity + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Adapter with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerAdapter(nn.Module): + def __init__(self, config): + super().__init__() + + # feature dim might need to be down-projected + if config.output_hidden_size != config.hidden_size: + self.proj = nn.Linear(config.hidden_size, config.output_hidden_size) + self.proj_layer_norm = nn.LayerNorm(config.output_hidden_size) + else: + self.proj = self.proj_layer_norm = None + + self.layers = nn.ModuleList(Wav2Vec2ConformerAdapterLayer(config) for _ in range(config.num_adapter_layers)) + self.layerdrop = config.layerdrop + + def forward(self, hidden_states): + # down project hidden_states if necessary + if self.proj is not None and self.proj_layer_norm is not None: + hidden_states = self.proj(hidden_states) + hidden_states = self.proj_layer_norm(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + + for layer in self.layers: + layerdrop_prob = np.random.random() + if not self.training or (layerdrop_prob > self.layerdrop): + hidden_states = layer(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2AdapterLayer with Wav2Vec2->Wav2Vec2Conformer +class Wav2Vec2ConformerAdapterLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.output_hidden_size, + 2 * config.output_hidden_size, + config.adapter_kernel_size, + stride=config.adapter_stride, + padding=1, + ) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = nn.functional.glu(hidden_states, dim=1) + + return hidden_states + + +class Wav2Vec2ConformerPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = Wav2Vec2ConformerConfig + base_model_prefix = "wav2vec2_conformer" + main_input_name = "input_values" + _keys_to_ignore_on_load_missing = [r"position_ids"] + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights""" + # Wav2Vec2ForPreTraining last 2 linear layers need standard Linear init. + if isinstance(module, Wav2Vec2ConformerForPreTraining): + module.project_hid.reset_parameters() + module.project_q.reset_parameters() + module.project_hid._is_hf_initialized = True + module.project_q._is_hf_initialized = True + # gumbel softmax requires special init + elif isinstance(module, Wav2Vec2ConformerGumbelVectorQuantizer): + module.weight_proj.weight.data.normal_(mean=0.0, std=1) + module.weight_proj.bias.data.zero_() + nn.init.uniform_(module.codevectors) + elif isinstance(module, Wav2Vec2ConformerSelfAttention): + if hasattr(module, "pos_bias_u"): + nn.init.xavier_uniform_(module.pos_bias_u) + if hasattr(module, "pos_bias_v"): + nn.init.xavier_uniform_(module.pos_bias_v) + elif isinstance(module, Wav2Vec2ConformerPositionalConvEmbedding): + nn.init.normal_( + module.conv.weight, + mean=0, + std=2 * math.sqrt(1 / (module.conv.kernel_size[0] * module.conv.in_channels)), + ) + nn.init.constant_(module.conv.bias, 0) + elif isinstance(module, Wav2Vec2ConformerFeatureProjection): + k = math.sqrt(1 / module.projection.in_features) + nn.init.uniform_(module.projection.weight, a=-k, b=k) + nn.init.uniform_(module.projection.bias, a=-k, b=k) + elif isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, nn.Conv1d): + nn.init.kaiming_normal_(module.weight) + + if module.bias is not None: + k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0])) + nn.init.uniform_(module.bias, a=-k, b=k) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[torch.LongTensor, int], add_adapter: Optional[bool] = None + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return torch.div(input_length - kernel_size, stride, rounding_mode="floor") + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + def _get_feature_vector_attention_mask( + self, feature_vector_length: int, attention_mask: torch.LongTensor, add_adapter=None + ): + # Effectively attention_mask.sum(-1), but not inplace to be able to run + # on inference mode. + non_padded_lengths = attention_mask.cumsum(dim=-1)[:, -1] + + output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) + output_lengths = output_lengths.to(torch.long) + + batch_size = attention_mask.shape[0] + + attention_mask = torch.zeros( + (batch_size, feature_vector_length), dtype=attention_mask.dtype, device=attention_mask.device + ) + # these two operations makes sure that all values before the output lengths idxs are attended to + attention_mask[(torch.arange(attention_mask.shape[0], device=attention_mask.device), output_lengths - 1)] = 1 + attention_mask = attention_mask.flip([-1]).cumsum(-1).flip([-1]).bool() + return attention_mask + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (Wav2Vec2ConformerEncoder, Wav2Vec2ConformerFeatureEncoder)): + module.gradient_checkpointing = value + + +WAV2VEC2_CONFORMER_START_DOCSTRING = r""" + Wav2Vec2Conformer was proposed in [wav2vec 2.0: A Framework for Self-Supervised Learning of Speech + Representations](https://arxiv.org/abs/2006.11477) by Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael + Auli. + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving etc.). + + This model is a PyTorch [nn.Module](https://pytorch.org/docs/stable/nn.html#nn.Module) sub-class. Use it as a + regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and behavior. + + Parameters: + config ([`Wav2Vec2ConformerConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + + +WAV2VEC2_CONFORMER_INPUTS_DOCSTRING = r""" + Args: + input_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Float values of input raw speech waveform. Values can be obtained by loading a `.flac` or `.wav` audio file + into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via the soundfile library (`pip install + soundfile`). To prepare the array into `input_values`, the [`AutoProcessor`] should be used for padding and + conversion into a tensor of type `torch.FloatTensor`. See [`Wav2Vec2Processor.__call__`] for details. + attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing convolution and attention on padding token indices. Mask values selected in `[0, + 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + + + + `attention_mask` should only be passed if the corresponding processor has `config.return_attention_mask == + True`. For all models whose processor has `config.return_attention_mask == False`, such as + [wav2vec2-conformer-rel-pos-large](https://huggingface.co/facebook/wav2vec2-conformer-rel-pos-large), + `attention_mask` should **not** be passed to avoid degraded performance when doing batched inference. For + such models `input_values` should simply be padded with 0 and passed without `attention_mask`. Be aware + that these models also yield slightly different results depending on whether `input_values` is padded or + not. + + + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare Wav2Vec2Conformer Model transformer outputting raw hidden-states without any specific head on top.", + WAV2VEC2_CONFORMER_START_DOCSTRING, +) +class Wav2Vec2ConformerModel(Wav2Vec2ConformerPreTrainedModel): + def __init__(self, config: Wav2Vec2ConformerConfig): + super().__init__(config) + self.config = config + self.feature_extractor = Wav2Vec2ConformerFeatureEncoder(config) + self.feature_projection = Wav2Vec2ConformerFeatureProjection(config) + + # model only needs masking vector if mask prob is > 0.0 + if config.mask_time_prob > 0.0 or config.mask_feature_prob > 0.0: + self.masked_spec_embed = nn.Parameter(torch.FloatTensor(config.hidden_size).uniform_()) + + self.encoder = Wav2Vec2ConformerEncoder(config) + + self.adapter = Wav2Vec2ConformerAdapter(config) if config.add_adapter else None + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Model.freeze_feature_encoder + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.feature_extractor._freeze_parameters() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Model._mask_hidden_states + def _mask_hidden_states( + self, + hidden_states: torch.FloatTensor, + mask_time_indices: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.LongTensor] = None, + ): + """ + Masks extracted features along time axis and/or along feature axis according to + [SpecAugment](https://arxiv.org/abs/1904.08779). + """ + + # `config.apply_spec_augment` can set masking to False + if not getattr(self.config, "apply_spec_augment", True): + return hidden_states + + # generate indices & apply SpecAugment along time axis + batch_size, sequence_length, hidden_size = hidden_states.size() + + if mask_time_indices is not None: + # apply SpecAugment along time axis with given mask_time_indices + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + elif self.config.mask_time_prob > 0 and self.training: + mask_time_indices = _compute_mask_indices( + (batch_size, sequence_length), + mask_prob=self.config.mask_time_prob, + mask_length=self.config.mask_time_length, + attention_mask=attention_mask, + min_masks=self.config.mask_time_min_masks, + ) + mask_time_indices = torch.tensor(mask_time_indices, device=hidden_states.device, dtype=torch.bool) + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + + if self.config.mask_feature_prob > 0 and self.training: + # generate indices & apply SpecAugment along feature axis + mask_feature_indices = _compute_mask_indices( + (batch_size, hidden_size), + mask_prob=self.config.mask_feature_prob, + mask_length=self.config.mask_feature_length, + min_masks=self.config.mask_feature_min_masks, + ) + mask_feature_indices = torch.tensor(mask_feature_indices, device=hidden_states.device, dtype=torch.bool) + mask_feature_indices = mask_feature_indices[:, None].expand(-1, sequence_length, -1) + hidden_states[mask_feature_indices] = 0 + + return hidden_states + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=Wav2Vec2BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Model.forward with wav2vec2->wav2vec2_conformer + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + mask_time_indices: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Wav2Vec2BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + extract_features = self.feature_extractor(input_values) + extract_features = extract_features.transpose(1, 2) + + if attention_mask is not None: + # compute reduced attention_mask corresponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + hidden_states, extract_features = self.feature_projection(extract_features) + hidden_states = self._mask_hidden_states( + hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask + ) + + encoder_outputs = self.encoder( + hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = encoder_outputs[0] + + if self.adapter is not None: + hidden_states = self.adapter(hidden_states) + + if not return_dict: + return (hidden_states, extract_features) + encoder_outputs[1:] + + return Wav2Vec2BaseModelOutput( + last_hidden_state=hidden_states, + extract_features=extract_features, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + """Wav2Vec2Conformer Model with a quantizer and `VQ` head on top.""", WAV2VEC2_CONFORMER_START_DOCSTRING +) +class Wav2Vec2ConformerForPreTraining(Wav2Vec2ConformerPreTrainedModel): + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTraining.__init__ with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer + def __init__(self, config: Wav2Vec2ConformerConfig): + super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + self.dropout_features = nn.Dropout(config.feat_quantizer_dropout) + + self.quantizer = Wav2Vec2ConformerGumbelVectorQuantizer(config) + + self.project_hid = nn.Linear(config.hidden_size, config.proj_codevector_dim) + self.project_q = nn.Linear(config.codevector_dim, config.proj_codevector_dim) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTraining.set_gumbel_temperature + def set_gumbel_temperature(self, temperature: int): + """ + Set the Gumbel softmax temperature to a given value. Only necessary for training + """ + self.quantizer.temperature = temperature + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTraining.freeze_feature_encoder with wav2vec2->wav2vec2_conformer + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2_conformer.feature_extractor._freeze_parameters() + + @staticmethod + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTraining.compute_contrastive_logits + def compute_contrastive_logits( + target_features: torch.FloatTensor, + negative_features: torch.FloatTensor, + predicted_features: torch.FloatTensor, + temperature: int = 0.1, + ): + """ + Compute logits for contrastive loss based using cosine similarity as the distance measure between + `[positive_feature, negative_features]` and `[predicted_features]`. Additionally, temperature can be applied. + """ + target_features = torch.cat([target_features, negative_features], dim=0) + + logits = torch.cosine_similarity(predicted_features.float(), target_features.float(), dim=-1).type_as( + target_features + ) + + # apply temperature + logits = logits / temperature + return logits + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=Wav2Vec2ConformerForPreTrainingOutput, config_class=_CONFIG_FOR_DOC) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForPreTraining.forward with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer,wav2vec2_conformer-base->wav2vec2-conformer-rel-pos-large + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + mask_time_indices: Optional[torch.BoolTensor] = None, + sampled_negative_indices: Optional[torch.BoolTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Wav2Vec2ConformerForPreTrainingOutput]: + r""" + mask_time_indices (`torch.BoolTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices to mask extracted features for contrastive loss. When in training mode, model learns to predict + masked extracted features in *config.proj_codevector_dim* space. + sampled_negative_indices (`torch.BoolTensor` of shape `(batch_size, sequence_length, num_negatives)`, *optional*): + Indices indicating which quantized target vectors are used as negative sampled vectors in contrastive loss. + Required input for pre-training. + + Returns: + + Example: + + ```python + >>> import torch + >>> from transformers import AutoFeatureExtractor, Wav2Vec2ConformerForPreTraining + >>> from transformers.models.wav2vec2_conformer.modeling_wav2vec2_conformer import ( + ... _compute_mask_indices, + ... _sample_negative_indices, + ... ) + >>> from datasets import load_dataset + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-conformer-rel-pos-large") + >>> model = Wav2Vec2ConformerForPreTraining.from_pretrained("facebook/wav2vec2-conformer-rel-pos-large") + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> input_values = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt").input_values # Batch size 1 + + >>> # compute masked indices + >>> batch_size, raw_sequence_length = input_values.shape + >>> sequence_length = model._get_feat_extract_output_lengths(raw_sequence_length).item() + >>> mask_time_indices = _compute_mask_indices( + ... shape=(batch_size, sequence_length), mask_prob=0.2, mask_length=2 + ... ) + >>> sampled_negative_indices = _sample_negative_indices( + ... features_shape=(batch_size, sequence_length), + ... num_negatives=model.config.num_negatives, + ... mask_time_indices=mask_time_indices, + ... ) + >>> mask_time_indices = torch.tensor(data=mask_time_indices, device=input_values.device, dtype=torch.long) + >>> sampled_negative_indices = torch.tensor( + ... data=sampled_negative_indices, device=input_values.device, dtype=torch.long + ... ) + + >>> with torch.no_grad(): + ... outputs = model(input_values, mask_time_indices=mask_time_indices) + + >>> # compute cosine similarity between predicted (=projected_states) and target (=projected_quantized_states) + >>> cosine_sim = torch.cosine_similarity(outputs.projected_states, outputs.projected_quantized_states, dim=-1) + + >>> # show that cosine similarity is much higher than random + >>> cosine_sim[mask_time_indices.to(torch.bool)].mean() > 0.5 + tensor(True) + + >>> # for contrastive loss training model should be put into train mode + >>> model = model.train() + >>> loss = model( + ... input_values, mask_time_indices=mask_time_indices, sampled_negative_indices=sampled_negative_indices + ... ).loss + ```""" + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if mask_time_indices is not None: + mask_time_indices = mask_time_indices.to(torch.bool) + + outputs = self.wav2vec2_conformer( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + mask_time_indices=mask_time_indices, + return_dict=return_dict, + ) + + # 1. project all transformed features (including masked) to final vq dim + transformer_features = self.project_hid(outputs[0]) + + # 2. quantize all (unmasked) extracted features and project to final vq dim + extract_features = self.dropout_features(outputs[1]) + + if attention_mask is not None: + # compute reduced attention_mask correponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + quantized_features, codevector_perplexity = self.quantizer( + extract_features, mask_time_indices=mask_time_indices + ) + quantized_features = self.project_q(quantized_features) + + loss = contrastive_loss = diversity_loss = None + if sampled_negative_indices is not None: + batch_size, sequence_length, hidden_size = quantized_features.shape + + # for training, we sample negatives + # 3. sample K negatives (distractors) quantized states for contrastive loss + # if attention_mask is passed, make sure that padded feature vectors cannot be sampled + # sample negative quantized vectors BTC => (BxT)C + negative_quantized_features = quantized_features.view(-1, hidden_size)[ + sampled_negative_indices.long().view(-1) + ] + negative_quantized_features = negative_quantized_features.view( + batch_size, sequence_length, -1, hidden_size + ).permute(2, 0, 1, 3) + + # 4. compute logits, corresponding to `logs = sim(c_t, [q_t, \sim{q}_t]) / \kappa` + # of equation (3) in https://arxiv.org/pdf/2006.11477.pdf + logits = self.compute_contrastive_logits( + quantized_features[None, :], + negative_quantized_features, + transformer_features, + self.config.contrastive_logits_temperature, + ) + + # 5. if a negative vector is identical to the positive (i.e. when codebook utilization is low), + # its cosine similarity will be masked + neg_is_pos = (quantized_features == negative_quantized_features).all(-1) + + if neg_is_pos.any(): + logits[1:][neg_is_pos] = float("-inf") + + # 6. compute contrastive loss \mathbf{L}_m = cross_entropy(logs) = + # -log(exp(sim(c_t, q_t)/\kappa) / \sum_{\sim{q}} exp(sim(c_t, \sim{q})/\kappa)) + logits = logits.transpose(0, 2).reshape(-1, logits.size(0)) + target = ((1 - mask_time_indices.long()) * -100).transpose(0, 1).flatten() + + contrastive_loss = nn.functional.cross_entropy(logits.float(), target, reduction="sum") + # 7. compute diversity loss: \mathbf{L}_d + num_codevectors = self.config.num_codevectors_per_group * self.config.num_codevector_groups + diversity_loss = ((num_codevectors - codevector_perplexity) / num_codevectors) * mask_time_indices.sum() + + # 8. \mathbf{L} = \mathbf{L}_m + \alpha * \mathbf{L}_d + loss = contrastive_loss + self.config.diversity_loss_weight * diversity_loss + + if not return_dict: + if loss is not None: + return (loss, transformer_features, quantized_features, codevector_perplexity) + outputs[2:] + return (transformer_features, quantized_features, codevector_perplexity) + outputs[2:] + + return Wav2Vec2ConformerForPreTrainingOutput( + loss=loss, + projected_states=transformer_features, + projected_quantized_states=quantized_features, + codevector_perplexity=codevector_perplexity, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + contrastive_loss=contrastive_loss, + diversity_loss=diversity_loss, + ) + + +@add_start_docstrings( + """Wav2Vec2Conformer Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", + WAV2VEC2_CONFORMER_START_DOCSTRING, +) +class Wav2Vec2ConformerForCTC(Wav2Vec2ConformerPreTrainedModel): + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForCTC.__init__ with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer + def __init__(self, config): + super().__init__(config) + + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + self.dropout = nn.Dropout(config.final_dropout) + + if config.vocab_size is None: + raise ValueError( + f"You are trying to instantiate {self.__class__} with a configuration that " + "does not define the vocabulary size of the language model head. Please " + "instantiate the model as follows: `Wav2Vec2ConformerForCTC.from_pretrained(..., vocab_size=vocab_size)`. " + "or define `vocab_size` of your model's configuration." + ) + output_hidden_size = ( + config.output_hidden_size if hasattr(config, "add_adapter") and config.add_adapter else config.hidden_size + ) + self.lm_head = nn.Linear(output_hidden_size, config.vocab_size) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForCTC.freeze_feature_encoder with wav2vec2->wav2vec2_conformer + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2_conformer.feature_extractor._freeze_parameters() + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=CausalLMOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_CTC_EXPECTED_OUTPUT, + expected_loss=_CTC_EXPECTED_LOSS, + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForCTC.forward with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, CausalLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, target_length)`, *optional*): + Labels for connectionist temporal classification. Note that `target_length` has to be smaller or equal to + the sequence length of the output logits. Indices are selected in `[-100, 0, ..., config.vocab_size - 1]`. + All labels set to `-100` are ignored (masked), the loss is only computed for labels in `[0, ..., + config.vocab_size - 1]`. + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.wav2vec2_conformer( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states) + + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + if labels.max() >= self.config.vocab_size: + raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") + + # retrieve loss input_lengths from attention_mask + attention_mask = ( + attention_mask if attention_mask is not None else torch.ones_like(input_values, dtype=torch.long) + ) + input_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(-1)).to(torch.long) + + # assuming that padded tokens are filled with -100 + # when not being attended to + labels_mask = labels >= 0 + target_lengths = labels_mask.sum(-1) + flattened_targets = labels.masked_select(labels_mask) + + # ctc_loss doesn't support fp16 + log_probs = nn.functional.log_softmax(logits, dim=-1, dtype=torch.float32).transpose(0, 1) + + with torch.backends.cudnn.flags(enabled=False): + loss = nn.functional.ctc_loss( + log_probs, + flattened_targets, + input_lengths, + target_lengths, + blank=self.config.pad_token_id, + reduction=self.config.ctc_loss_reduction, + zero_infinity=self.config.ctc_zero_infinity, + ) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return CausalLMOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + Wav2Vec2Conformer Model with a sequence classification head on top (a linear layer over the pooled output) for + tasks like SUPERB Keyword Spotting. + """, + WAV2VEC2_CONFORMER_START_DOCSTRING, +) +class Wav2Vec2ConformerForSequenceClassification(Wav2Vec2ConformerPreTrainedModel): + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.__init__ with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Sequence classification does not support the use of Wav2Vec2Conformer adapters (config.add_adapter=True)" + ) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.classifier_proj_size) + self.classifier = nn.Linear(config.classifier_proj_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.freeze_feature_encoder with wav2vec2->wav2vec2_conformer + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2_conformer.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2_conformer.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.forward with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer,WAV_2_VEC_2->WAV2VEC2_CONFORMER + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2_conformer( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + if attention_mask is None: + pooled_output = hidden_states.mean(dim=1) + else: + padding_mask = self._get_feature_vector_attention_mask(hidden_states.shape[1], attention_mask) + hidden_states[~padding_mask] = 0.0 + pooled_output = hidden_states.sum(dim=1) / padding_mask.sum(dim=1).view(-1, 1) + + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + Wav2Vec2Conformer Model with a frame classification head on top for tasks like Speaker Diarization. + """, + WAV2VEC2_CONFORMER_START_DOCSTRING, +) +class Wav2Vec2ConformerForAudioFrameClassification(Wav2Vec2ConformerPreTrainedModel): + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForAudioFrameClassification.__init__ with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer,WAV_2_VEC_2->WAV2VEC2_CONFORMER + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Audio frame classification does not support the use of Wav2Vec2Conformer adapters (config.add_adapter=True)" + ) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + self.num_labels = config.num_labels + + self.init_weights() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForAudioFrameClassification.freeze_feature_encoder with wav2vec2->wav2vec2_conformer + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2_conformer.feature_extractor._freeze_parameters() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForAudioFrameClassification.freeze_base_model with wav2vec2->wav2vec2_conformer + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2_conformer.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForAudioFrameClassification.forward with wav2vec2->wav2vec2_conformer + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2_conformer( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + logits = self.classifier(hidden_states) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), torch.argmax(labels.view(-1, self.num_labels), axis=1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.AMSoftmaxLoss +class AMSoftmaxLoss(nn.Module): + def __init__(self, input_dim, num_labels, scale=30.0, margin=0.4): + super(AMSoftmaxLoss, self).__init__() + self.scale = scale + self.margin = margin + self.num_labels = num_labels + self.weight = nn.Parameter(torch.randn(input_dim, num_labels), requires_grad=True) + self.loss = nn.CrossEntropyLoss() + + def forward(self, hidden_states, labels): + labels = labels.flatten() + weight = nn.functional.normalize(self.weight, dim=0) + hidden_states = nn.functional.normalize(hidden_states, dim=1) + cos_theta = torch.mm(hidden_states, weight) + psi = cos_theta - self.margin + + onehot = nn.functional.one_hot(labels, self.num_labels) + logits = self.scale * torch.where(onehot.bool(), psi, cos_theta) + loss = self.loss(logits, labels) + + return loss + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.TDNNLayer +class TDNNLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.tdnn_dim[layer_id - 1] if layer_id > 0 else config.tdnn_dim[layer_id] + self.out_conv_dim = config.tdnn_dim[layer_id] + self.kernel_size = config.tdnn_kernel[layer_id] + self.dilation = config.tdnn_dilation[layer_id] + + self.kernel = nn.Linear(self.in_conv_dim * self.kernel_size, self.out_conv_dim) + self.activation = nn.ReLU() + + def forward(self, hidden_states): + hidden_states = hidden_states.unsqueeze(1) + hidden_states = nn.functional.unfold( + hidden_states, + (self.kernel_size, self.in_conv_dim), + stride=(1, self.in_conv_dim), + dilation=(self.dilation, 1), + ) + hidden_states = hidden_states.transpose(1, 2) + hidden_states = self.kernel(hidden_states) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +@add_start_docstrings( + """ + Wav2Vec2Conformer Model with an XVector feature extraction head on top for tasks like Speaker Verification. + """, + WAV2VEC2_CONFORMER_START_DOCSTRING, +) +class Wav2Vec2ConformerForXVector(Wav2Vec2ConformerPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.tdnn_dim[0]) + + tdnn_layers = [TDNNLayer(config, i) for i in range(len(config.tdnn_dim))] + self.tdnn = nn.ModuleList(tdnn_layers) + + self.feature_extractor = nn.Linear(config.tdnn_dim[-1] * 2, config.xvector_output_dim) + self.classifier = nn.Linear(config.xvector_output_dim, config.xvector_output_dim) + + self.objective = AMSoftmaxLoss(config.xvector_output_dim, config.num_labels) + + self.init_weights() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForXVector.freeze_feature_encoder with wav2vec2->wav2vec2_conformer + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wav2vec2_conformer.feature_extractor._freeze_parameters() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForXVector.freeze_base_model with wav2vec2->wav2vec2_conformer + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wav2vec2_conformer.parameters(): + param.requires_grad = False + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForXVector._get_tdnn_output_lengths with wav2vec2->wav2vec2_conformer + def _get_tdnn_output_lengths(self, input_lengths: Union[torch.LongTensor, int]): + """ + Computes the output length of the TDNN layers + """ + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size in self.config.tdnn_kernel: + input_lengths = _conv_out_length(input_lengths, kernel_size, 1) + + return input_lengths + + @add_start_docstrings_to_model_forward(WAV2VEC2_CONFORMER_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XVectorOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForXVector.forward with Wav2Vec2->Wav2Vec2Conformer,wav2vec2->wav2vec2_conformer,WAV_2_VEC_2->WAV2VEC2_CONFORMER + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, XVectorOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wav2vec2_conformer( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + + for tdnn_layer in self.tdnn: + hidden_states = tdnn_layer(hidden_states) + + # Statistic Pooling + if attention_mask is None: + mean_features = hidden_states.mean(dim=1) + std_features = hidden_states.std(dim=1) + else: + feat_extract_output_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(dim=1)) + tdnn_output_lengths = self._get_tdnn_output_lengths(feat_extract_output_lengths) + mean_features = [] + std_features = [] + for i, length in enumerate(tdnn_output_lengths): + mean_features.append(hidden_states[i, :length].mean(dim=0)) + std_features.append(hidden_states[i, :length].std(dim=0)) + mean_features = torch.stack(mean_features) + std_features = torch.stack(std_features) + statistic_pooling = torch.cat([mean_features, std_features], dim=-1) + + output_embeddings = self.feature_extractor(statistic_pooling) + logits = self.classifier(output_embeddings) + + loss = None + if labels is not None: + loss = self.objective(logits, labels) + + if not return_dict: + output = (logits, output_embeddings) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return XVectorOutput( + loss=loss, + logits=logits, + embeddings=output_embeddings, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7859f381dd51906785b356064dad9fa508e672d8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule + + +_import_structure = {"tokenization_wav2vec2_phoneme": ["Wav2Vec2PhonemeCTCTokenizer"]} + + +if TYPE_CHECKING: + from .tokenization_wav2vec2_phoneme import Wav2Vec2PhonemeCTCTokenizer +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py new file mode 100644 index 0000000000000000000000000000000000000000..f9a1cf631cb52533432bccfb0068d09080293230 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_phoneme/tokenization_wav2vec2_phoneme.py @@ -0,0 +1,636 @@ +# coding=utf-8 +# Copyright 2021 The Facebook Inc. and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization class for Wav2Vec2Phoneme.""" + +import json +import os +import sys +from dataclasses import dataclass +from itertools import groupby +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union + +import numpy as np + +from ...tokenization_utils import PreTrainedTokenizer, _insert_one_token_to_ordered_list +from ...tokenization_utils_base import AddedToken +from ...utils import ( + ModelOutput, + is_flax_available, + is_tf_available, + is_torch_available, + logging, + requires_backends, + to_py_obj, +) + + +logger = logging.get_logger(__name__) + + +if TYPE_CHECKING: + if is_torch_available(): + import torch + if is_tf_available(): + import tensorflow as tf + if is_flax_available(): + import jax.numpy as jnp # noqa: F401 + + +VOCAB_FILES_NAMES = { + "vocab_file": "vocab.json", + "tokenizer_config_file": "tokenizer_config.json", +} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/wav2vec2-lv-60-espeak-cv-ft": ( + "https://huggingface.co/facebook/wav2vec2-lv-60-espeak-cv-ft/resolve/main/vocab.json" + ), + }, + "tokenizer_config_file": { + "facebook/wav2vec2-lv-60-espeak-cv-ft": ( + "https://huggingface.co/facebook/wav2vec2-lv-60-espeak-cv-ft/resolve/main/tokenizer_config.json" + ), + }, +} + +# Wav2Vec2Phoneme has no max input length +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {"facebook/wav2vec2-lv-60-espeak-cv-ft": sys.maxsize} + + +ListOfDict = List[Dict[str, Union[int, str]]] + + +@dataclass +class Wav2Vec2PhonemeCTCTokenizerOutput(ModelOutput): + """ + Output type of [` Wav2Vec2PhonemeCTCTokenizer`], with transcription. + + Args: + text (list of `str` or `str`): + Decoded logits in text from. Usually the speech transcription. + char_offsets (list of `List[Dict[str, Union[int, str]]]` or `List[Dict[str, Union[int, str]]]`): + Offsets of the decoded characters. In combination with sampling rate and model downsampling rate char + offsets can be used to compute time stamps for each charater. Total logit score of the beam associated with + produced text. + """ + + text: Union[List[str], str] + char_offsets: Union[List[ListOfDict], ListOfDict] = None + + +class Wav2Vec2PhonemeCTCTokenizer(PreTrainedTokenizer): + + """ + Constructs a Wav2Vec2PhonemeCTC tokenizer. + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains some of the main methods. Users should refer to + the superclass for more information regarding such methods. + + Args: + vocab_file (`str`): + File containing the vocabulary. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sentence token. + eos_token (`str`, *optional*, defaults to `""`): + The end of sentence token. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + do_phonemize (`bool`, *optional*, defaults to `True`): + Whether the tokenizer should phonetize the input or not. Only if a sequence of phonemes is passed to the + tokenizer, `do_phonemize` should be set to `False`. + phonemizer_lang (`str`, *optional*, defaults to `"en-us"`): + The language of the phoneme set to which the tokenizer should phonetize the input text to. + phonemizer_backend (`str`, *optional*. defaults to `"espeak"`): + The backend phonetization library that shall be used by the phonemizer library. Defaults to `espeak-ng`. + See the [phonemizer package](https://github.com/bootphon/phonemizer#readme). for more information. + + **kwargs + Additional keyword arguments passed along to [`PreTrainedTokenizer`] + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="", + eos_token="", + unk_token="", + pad_token="", + phone_delimiter_token=" ", + word_delimiter_token=None, + do_phonemize=True, + phonemizer_lang="en-us", + phonemizer_backend="espeak", + **kwargs, + ): + super().__init__( + unk_token=unk_token, + bos_token=bos_token, + eos_token=eos_token, + pad_token=pad_token, + word_delimiter_token=word_delimiter_token, + phone_delimiter_token=phone_delimiter_token, + do_phonemize=do_phonemize, + phonemizer_lang=phonemizer_lang, + phonemizer_backend=phonemizer_backend, + **kwargs, + ) + + self._word_delimiter_token = word_delimiter_token + self._phone_delimiter_token = phone_delimiter_token + self.do_phonemize = do_phonemize + self.phonemizer_lang = phonemizer_lang + self.phonemizer_backend = phonemizer_backend + + if do_phonemize: + self.init_backend(self.phonemizer_lang) + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + self.decoder = {v: k for k, v in self.encoder.items()} + + @property + def vocab_size(self) -> int: + return len(self.decoder) + + def get_vocab(self) -> Dict: + return dict(self.encoder, **self.added_tokens_encoder) + + def init_backend(self, phonemizer_lang: str): + """ + Initializes the backend. + + Args: + phonemizer_lang (`str`): The language to be used. + """ + requires_backends(self, "phonemizer") + from phonemizer.backend import BACKENDS + + self.backend = BACKENDS[self.phonemizer_backend](phonemizer_lang, language_switch="remove-flags") + + def prepare_for_tokenization( + self, + text: str, + is_split_into_words: bool = False, + phonemizer_lang: Optional[str] = None, + do_phonemize: Optional[bool] = None, + ) -> Tuple[str, Dict[str, Any]]: + """ + Performs any necessary transformations before tokenization. + + This method should pop the arguments from kwargs and return the remaining `kwargs` as well. We test the + `kwargs` at the end of the encoding process to be sure all the arguments have been used. + + Args: + text (`str`): + The text to prepare. + is_split_into_words (`bool`, *optional*, defaults to `False`): + Whether or not the input is already pre-tokenized (e.g., split into words). If set to `True`, the + tokenizer assumes the input is already split into words (for instance, by splitting it on whitespace) + which it will tokenize. This is useful for NER or token classification. + phonemizer_lang (`str`, *optional*): + The language of the phoneme set to which the tokenizer should phonetize the input text to. + do_phonemize (`bool`, *optional*): + Whether the tokenizer should phonetize the input text or not. Only if a sequence of phonemes is passed + to the tokenizer, `do_phonemize` should be set to `False`. + + + Returns: + `Tuple[str, Dict[str, Any]]`: The prepared text and the unused kwargs. + """ + if is_split_into_words: + text = " " + text + + # set whether tokenizer should phonemize or not + if do_phonemize is not None: + self.do_phonemize = do_phonemize + + # set the correct phonemizer language + if phonemizer_lang is not None: + self.phonemizer_lang = phonemizer_lang + self.init_backend(phonemizer_lang) + + return (text, {}) + + def _tokenize(self, text, **kwargs): + """ + Converts a string in a sequence of tokens (string), using the tokenizer. + """ + + # make sure whitespace is stripped to prevent + text = text.strip() + + # phonemize + if self.do_phonemize: + text = text.lower() + + # create list of phonemes + text = self.phonemize(text, self.phonemizer_lang) + + # make sure ' ' is between phonemes + tokens = text.split(" ") + + tokens = list(filter(lambda p: p.strip() != "", tokens)) + return tokens + + def phonemize(self, text: str, phonemizer_lang: Optional[str] = None) -> str: + from phonemizer.separator import Separator + + word_delimiter = self.word_delimiter_token + " " if self.word_delimiter_token is not None else "" + if phonemizer_lang is not None and phonemizer_lang != self.phonemizer_lang: + self.init_backend(phonemizer_lang) + else: + phonemizer_lang = self.phonemizer_lang + + separator = Separator(phone=self.phone_delimiter_token, word=word_delimiter, syllable="") + phonemes = self.backend.phonemize( + [text], + separator=separator, + ) + phonemes = phonemes[0].strip() + + return phonemes + + @property + def word_delimiter_token(self) -> str: + """ + `str`: Word delimiter token. Log an error if used while not having been set. + """ + if self._word_delimiter_token is None and self.verbose: + return None + return str(self._word_delimiter_token) + + @property + def word_delimiter_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the word_delimiter_token in the vocabulary. Returns `None` if the token has not been + set. + """ + if self._word_delimiter_token is None: + return None + return self.convert_tokens_to_ids(self.word_delimiter_token) + + @word_delimiter_token.setter + def word_delimiter_token(self, value): + self._word_delimiter_token = value + + @word_delimiter_token_id.setter + def word_delimiter_token_id(self, value): + self._word_delimiter_token = self.convert_tokens_to_ids(value) + + @property + def phone_delimiter_token(self) -> str: + """ + `str`: Word delimiter token. Log an error if used while not having been set. + """ + if self._phone_delimiter_token is None and self.verbose: + logger.error("Using phone_delimiter_token, but it is not set yet.") + return None + return str(self._phone_delimiter_token) + + @property + def phone_delimiter_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the phone_delimiter_token in the vocabulary. Returns `None` if the token has not been + set. + """ + if self._phone_delimiter_token is None: + return None + return self.convert_tokens_to_ids(self.phone_delimiter_token) + + @phone_delimiter_token.setter + def phone_delimiter_token(self, value): + self._phone_delimiter_token = value + + @phone_delimiter_token_id.setter + def phone_delimiter_token_id(self, value): + self._phone_delimiter_token = self.convert_tokens_to_ids(value) + + def _convert_token_to_id(self, token: str) -> int: + """Converts a token (str) in an index (integer) using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + def _convert_id_to_token(self, index: int) -> str: + """Converts an index (integer) in a token (str) using the vocab.""" + result = self.decoder.get(index, self.unk_token) + return result + + def convert_tokens_to_string( + self, + tokens: List[str], + group_tokens: bool = True, + spaces_between_special_tokens: bool = False, + filter_word_delimiter_token: bool = True, + output_char_offsets: bool = False, + ) -> str: + """ + Converts a connectionist-temporal-classification (CTC) output tokens into a single string. + """ + # group same tokens into non-repeating tokens in CTC style decoding + if group_tokens: + chars, char_repetitions = zip(*((token, len(list(group_iter))) for token, group_iter in groupby(tokens))) + else: + chars = tokens + char_repetitions = len(tokens) * [1] + + # filter self.pad_token which is used as CTC-blank token + processed_chars = list(filter(lambda char: char != self.pad_token, chars)) + + # also filter self.word_delimiter_token if not not + if filter_word_delimiter_token and self.word_delimiter_token is not None: + processed_chars = list(filter(lambda token: token != self.word_delimiter_token, processed_chars)) + + # retrieve offsets + char_offsets = None + if output_char_offsets: + word_delimiter_token_for_offsets = ( + self.word_delimiter_token if filter_word_delimiter_token is True else None + ) + char_offsets = self._compute_offsets( + char_repetitions, chars, self.pad_token, word_delimiter_token=word_delimiter_token_for_offsets + ) + + if len(char_offsets) != len(processed_chars): + raise ValueError( + f"`char_offsets`: {char_offsets} and `processed_tokens`: {processed_chars}" + " have to be of the same length, but are: `len(offsets)`: " + f"{len(char_offsets)} and `len(processed_tokens)`: {len(processed_chars)}" + ) + + # set tokens to correct processed token + for i, char in enumerate(processed_chars): + char_offsets[i]["char"] = char + + string = " ".join(processed_chars).strip() + + return {"text": string, "char_offsets": char_offsets} + + @staticmethod + def _compute_offsets( + char_repetitions: List[int], chars: List[str], ctc_token: int, word_delimiter_token: Optional[int] = None + ) -> List[Dict[str, Union[str, int]]]: + end_indices = np.asarray(char_repetitions).cumsum() + start_indices = np.concatenate(([0], end_indices[:-1])) + + offsets = [ + {"char": t, "start_offset": s, "end_offset": e} for t, s, e in zip(chars, start_indices, end_indices) + ] + + # filter out CTC token + offsets = list(filter(lambda offsets: offsets["char"] != ctc_token, offsets)) + + # filter out word delimiter token if necessary + if word_delimiter_token is not None: + offsets = list(filter(lambda offsets: offsets["char"] != word_delimiter_token, offsets)) + + return offsets + + def _decode( + self, + token_ids: List[int], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + group_tokens: bool = True, + filter_word_delimiter_token: bool = True, + spaces_between_special_tokens: bool = False, + output_char_offsets: bool = False, + ) -> str: + """ + special _decode function is needed for Wav2Vec2PhonemeTokenizer because added tokens should be treated exactly + the same as tokens of the base vocabulary and therefore the function `convert_tokens_to_string` has to be + called on the whole token list and not individually on added tokens + """ + filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens) + + result = [] + for token in filtered_tokens: + if skip_special_tokens and token in self.all_special_ids: + continue + result.append(token) + + string_output = self.convert_tokens_to_string( + result, + group_tokens=group_tokens, + spaces_between_special_tokens=spaces_between_special_tokens, + filter_word_delimiter_token=filter_word_delimiter_token, + output_char_offsets=output_char_offsets, + ) + + text = string_output["text"] + + clean_up_tokenization_spaces = ( + clean_up_tokenization_spaces + if clean_up_tokenization_spaces is not None + else self.clean_up_tokenization_spaces + ) + if clean_up_tokenization_spaces: + text = self.clean_up_tokenization(text) + + if output_char_offsets: + return Wav2Vec2PhonemeCTCTokenizerOutput(text=text, char_offsets=string_output["char_offsets"]) + else: + return text + + # overwritten from `tokenization_utils_base.py` because we need docs for `output_char_offsets` here + def decode( + self, + token_ids: Union[int, List[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_char_offsets: bool = False, + **kwargs, + ) -> str: + """ + Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special + tokens and clean up tokenization spaces. + + Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. + output_char_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output character offsets. Character offsets can be used in combination with the + sampling rate and model downsampling rate to compute the time-stamps of transcribed characters. + + + + Please take a look at the Example of [`~models.wav2vec2.tokenization_wav2vec2.decode`] to better + understand how to make use of `output_word_offsets`. + [`~model.wav2vec2_phoneme.tokenization_wav2vec2_phoneme.batch_decode`] works the same way with + phonemes. + + + + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `str` or [`~models.wav2vec2.tokenization_wav2vec2_phoneme.Wav2Vec2PhonemeCTCTokenizerOutput`]: The decoded + sentence. Will be a [`~models.wav2vec2.tokenization_wav2vec2_phoneme.Wav2Vec2PhonemeCTCTokenizerOutput`] + when `output_char_offsets == True`. + """ + # Convert inputs to python lists + token_ids = to_py_obj(token_ids) + + return self._decode( + token_ids=token_ids, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + output_char_offsets=output_char_offsets, + **kwargs, + ) + + # overwritten from `tokenization_utils_base.py` because tokenizer can output + # `ModelOutput` which should not be a list for batched output and because + # we need docs for `output_char_offsets` here + def batch_decode( + self, + sequences: Union[List[int], List[List[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_char_offsets: bool = False, + **kwargs, + ) -> List[str]: + """ + Convert a list of lists of token ids into a list of strings by calling decode. + + Args: + sequences (`Union[List[int], List[List[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. + output_char_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output character offsets. Character offsets can be used in combination with the + sampling rate and model downsampling rate to compute the time-stamps of transcribed characters. + + + + Please take a look at the Example of [`~models.wav2vec2.tokenization_wav2vec2.decode`] to better + understand how to make use of `output_word_offsets`. + [`~model.wav2vec2_phoneme.tokenization_wav2vec2_phoneme.batch_decode`] works analogous with phonemes + and batched output. + + + + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `List[str]` or [`~models.wav2vec2.tokenization_wav2vec2_phoneme.Wav2Vec2PhonemeCTCTokenizerOutput`]: The + decoded sentence. Will be a + [`~models.wav2vec2.tokenization_wav2vec2_phoneme.Wav2Vec2PhonemeCTCTokenizerOutput`] when + `output_char_offsets == True`. + """ + batch_decoded = [ + self.decode( + seq, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + output_char_offsets=output_char_offsets, + **kwargs, + ) + for seq in sequences + ] + if output_char_offsets: + # transform list of dicts to dict of lists + return Wav2Vec2PhonemeCTCTokenizerOutput({k: [d[k] for d in batch_decoded] for k in batch_decoded[0]}) + + return batch_decoded + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + return (vocab_file,) + + def _add_tokens(self, new_tokens: Union[List[str], List[AddedToken]], special_tokens: bool = False) -> int: + """ + Add a list of new tokens to the tokenizer class. If the new tokens are not in the vocabulary, they are added to + it with indices starting from length of the current vocabulary. + + Args: + new_tokens (`List[str]`or `List[tokenizers.AddedToken]`): + Token(s) to add in vocabulary. A token is only added if it's not already in the vocabulary (tested by + checking if the tokenizer assign the index of the `unk_token` to them). + special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the tokens should be added as special tokens. + + Returns: + `int`: The number of tokens actually added to the vocabulary. + + Examples: + + ```python + # Let's see how to increase the vocabulary of Bert model and tokenizer + tokenizer = Wav2Vec2PhonemeCTCTokenizer.from_pretrained("facebook/wav2vec2-lv-60-espeak-cv-ft") + model = Wav2Vec2PhonemeForCTC.from_pretrained("facebook/wav2vec2-lv-60-espeak-cv-ft") + + num_added_toks = tokenizer.add_tokens(["new_tok1", "my_new-tok2"]) + print("We have added", num_added_toks, "tokens") + # Note: resize_token_embeddings expects to receive the full size of the new vocabulary, i.e. the length of the tokenizer. + model.resize_token_embeddings(len(tokenizer)) + ```""" + new_tokens = [str(tok) for tok in new_tokens] + + tokens_to_add = [] + for token in new_tokens: + if not isinstance(token, str): + raise ValueError(f"Token {token} has to be of type string, but is of type {type(token)}.") + assert isinstance(token, str) + if ( + token != self.unk_token + and self.convert_tokens_to_ids(token) == self.convert_tokens_to_ids(self.unk_token) + and token not in tokens_to_add + ): + tokens_to_add.append(token) + if self.verbose: + logger.info(f"Adding {token} to the vocabulary") + + added_tok_encoder = {tok: len(self) + i for i, tok in enumerate(tokens_to_add)} + added_tok_decoder = {v: k for k, v in added_tok_encoder.items()} + self.added_tokens_encoder.update(added_tok_encoder) + self.added_tokens_decoder.update(added_tok_decoder) + + # Make sure we don't split on any special tokens (even they were already in the vocab before) + for token in tokens_to_add: + if len(token) > 1: + self._additional_special_tokens.append(AddedToken(token)) + _insert_one_token_to_ordered_list(self.unique_no_split_tokens, token) + + self._create_trie(self.unique_no_split_tokens) + + return len(tokens_to_add) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..611688f6a683e73fa1287c88bfbf7b0736657647 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule + + +_import_structure = {"processing_wav2vec2_with_lm": ["Wav2Vec2ProcessorWithLM"]} + + +if TYPE_CHECKING: + from .processing_wav2vec2_with_lm import Wav2Vec2ProcessorWithLM +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/processing_wav2vec2_with_lm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/processing_wav2vec2_with_lm.py new file mode 100644 index 0000000000000000000000000000000000000000..e331da14e810e88437a5d7a2788fd4e28e584f90 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wav2vec2_with_lm/processing_wav2vec2_with_lm.py @@ -0,0 +1,648 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Speech processor class for Wav2Vec2 +""" +import os +import warnings +from contextlib import contextmanager, nullcontext +from dataclasses import dataclass +from multiprocessing import Pool, get_context, get_start_method +from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Union + +import numpy as np + +from ...processing_utils import ProcessorMixin +from ...utils import ModelOutput, logging, requires_backends + + +logger = logging.get_logger(__name__) + + +if TYPE_CHECKING: + from pyctcdecode import BeamSearchDecoderCTC + + from ...feature_extraction_utils import FeatureExtractionMixin + from ...tokenization_utils import PreTrainedTokenizerBase + + +ListOfDict = List[Dict[str, Union[int, str]]] + + +@dataclass +class Wav2Vec2DecoderWithLMOutput(ModelOutput): + """ + Output type of [`Wav2Vec2DecoderWithLM`], with transcription. + + Args: + text (list of `str` or `str`): + Decoded logits in text from. Usually the speech transcription. + logit_score (list of `float` or `float`): + Total logit score of the beams associated with produced text. + lm_score (list of `float`): + Fused lm_score of the beams associated with produced text. + word_offsets (list of `List[Dict[str, Union[int, str]]]` or `List[Dict[str, Union[int, str]]]`): + Offsets of the decoded words. In combination with sampling rate and model downsampling rate word offsets + can be used to compute time stamps for each word. + """ + + text: Union[List[List[str]], List[str], str] + logit_score: Union[List[List[float]], List[float], float] = None + lm_score: Union[List[List[float]], List[float], float] = None + word_offsets: Union[List[List[ListOfDict]], List[ListOfDict], ListOfDict] = None + + +class Wav2Vec2ProcessorWithLM(ProcessorMixin): + r""" + Constructs a Wav2Vec2 processor which wraps a Wav2Vec2 feature extractor, a Wav2Vec2 CTC tokenizer and a decoder + with language model support into a single processor for language model boosted speech recognition decoding. + + Args: + feature_extractor ([`Wav2Vec2FeatureExtractor`]): + An instance of [`Wav2Vec2FeatureExtractor`]. The feature extractor is a required input. + tokenizer ([`Wav2Vec2CTCTokenizer`]): + An instance of [`Wav2Vec2CTCTokenizer`]. The tokenizer is a required input. + decoder (`pyctcdecode.BeamSearchDecoderCTC`): + An instance of [`pyctcdecode.BeamSearchDecoderCTC`]. The decoder is a required input. + """ + feature_extractor_class = "Wav2Vec2FeatureExtractor" + tokenizer_class = "Wav2Vec2CTCTokenizer" + + def __init__( + self, + feature_extractor: "FeatureExtractionMixin", + tokenizer: "PreTrainedTokenizerBase", + decoder: "BeamSearchDecoderCTC", + ): + from pyctcdecode import BeamSearchDecoderCTC + + super().__init__(feature_extractor, tokenizer) + if not isinstance(decoder, BeamSearchDecoderCTC): + raise ValueError(f"`decoder` has to be of type {BeamSearchDecoderCTC.__class__}, but is {type(decoder)}") + + # make sure that decoder's alphabet and tokenizer's vocab match in content + missing_decoder_tokens = self.get_missing_alphabet_tokens(decoder, tokenizer) + if len(missing_decoder_tokens) > 0: + raise ValueError( + f"The tokens {missing_decoder_tokens} are defined in the tokenizer's " + "vocabulary, but not in the decoder's alphabet. " + f"Make sure to include {missing_decoder_tokens} in the decoder's alphabet." + ) + + self.decoder = decoder + self.current_processor = self.feature_extractor + self._in_target_context_manager = False + + def save_pretrained(self, save_directory): + super().save_pretrained(save_directory) + self.decoder.save_to_dir(save_directory) + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path, **kwargs): + r""" + Instantiate a [`Wav2Vec2ProcessorWithLM`] from a pretrained Wav2Vec2 processor. + + + + This class method is simply calling Wav2Vec2FeatureExtractor's + [`~feature_extraction_utils.FeatureExtractionMixin.from_pretrained`], Wav2Vec2CTCTokenizer's + [`~tokenization_utils_base.PreTrainedTokenizerBase.from_pretrained`], and + [`pyctcdecode.BeamSearchDecoderCTC.load_from_hf_hub`]. + + Please refer to the docstrings of the methods above for more information. + + + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or + namespaced under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a feature extractor file saved using the + [`~SequenceFeatureExtractor.save_pretrained`] method, e.g., `./my_model_directory/`. + - a path or url to a saved feature extractor JSON *file*, e.g., + `./my_model_directory/preprocessor_config.json`. + **kwargs + Additional keyword arguments passed along to both [`SequenceFeatureExtractor`] and + [`PreTrainedTokenizer`] + """ + requires_backends(cls, "pyctcdecode") + from pyctcdecode import BeamSearchDecoderCTC + + feature_extractor, tokenizer = super()._get_arguments_from_pretrained(pretrained_model_name_or_path, **kwargs) + + if os.path.isdir(pretrained_model_name_or_path) or os.path.isfile(pretrained_model_name_or_path): + decoder = BeamSearchDecoderCTC.load_from_dir(pretrained_model_name_or_path) + else: + # BeamSearchDecoderCTC has no auto class + kwargs.pop("_from_auto", None) + # snapshot_download has no `trust_remote_code` flag + kwargs.pop("trust_remote_code", None) + + # make sure that only relevant filenames are downloaded + language_model_filenames = os.path.join(BeamSearchDecoderCTC._LANGUAGE_MODEL_SERIALIZED_DIRECTORY, "*") + alphabet_filename = BeamSearchDecoderCTC._ALPHABET_SERIALIZED_FILENAME + allow_patterns = [language_model_filenames, alphabet_filename] + + decoder = BeamSearchDecoderCTC.load_from_hf_hub( + pretrained_model_name_or_path, allow_patterns=allow_patterns, **kwargs + ) + + # set language model attributes + for attribute in ["alpha", "beta", "unk_score_offset", "score_boundary"]: + value = kwargs.pop(attribute, None) + + if value is not None: + cls._set_language_model_attribute(decoder, attribute, value) + + # make sure that decoder's alphabet and tokenizer's vocab match in content + missing_decoder_tokens = cls.get_missing_alphabet_tokens(decoder, tokenizer) + if len(missing_decoder_tokens) > 0: + raise ValueError( + f"The tokens {missing_decoder_tokens} are defined in the tokenizer's " + "vocabulary, but not in the decoder's alphabet. " + f"Make sure to include {missing_decoder_tokens} in the decoder's alphabet." + ) + + return cls(feature_extractor=feature_extractor, tokenizer=tokenizer, decoder=decoder) + + @staticmethod + def _set_language_model_attribute(decoder: "BeamSearchDecoderCTC", attribute: str, value: float): + setattr(decoder.model_container[decoder._model_key], attribute, value) + + @property + def language_model(self): + return self.decoder.model_container[self.decoder._model_key] + + @staticmethod + def get_missing_alphabet_tokens(decoder, tokenizer): + from pyctcdecode.alphabet import BLANK_TOKEN_PTN, UNK_TOKEN, UNK_TOKEN_PTN + + # we need to make sure that all of the tokenizer's except the special tokens + # are present in the decoder's alphabet. Retrieve missing alphabet token + # from decoder + tokenizer_vocab_list = list(tokenizer.get_vocab().keys()) + + # replace special tokens + for i, token in enumerate(tokenizer_vocab_list): + if BLANK_TOKEN_PTN.match(token): + tokenizer_vocab_list[i] = "" + if token == tokenizer.word_delimiter_token: + tokenizer_vocab_list[i] = " " + if UNK_TOKEN_PTN.match(token): + tokenizer_vocab_list[i] = UNK_TOKEN + + # are any of the extra tokens no special tokenizer tokens? + missing_tokens = set(tokenizer_vocab_list) - set(decoder._alphabet.labels) + + return missing_tokens + + def __call__(self, *args, **kwargs): + """ + When used in normal mode, this method forwards all its arguments to Wav2Vec2FeatureExtractor's + [`~Wav2Vec2FeatureExtractor.__call__`] and returns its output. If used in the context + [`~Wav2Vec2ProcessorWithLM.as_target_processor`] this method forwards all its arguments to + Wav2Vec2CTCTokenizer's [`~Wav2Vec2CTCTokenizer.__call__`]. Please refer to the docstring of the above two + methods for more information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor(*args, **kwargs) + + if "raw_speech" in kwargs: + warnings.warn("Using `raw_speech` as a keyword argument is deprecated. Use `audio` instead.") + audio = kwargs.pop("raw_speech") + else: + audio = kwargs.pop("audio", None) + sampling_rate = kwargs.pop("sampling_rate", None) + text = kwargs.pop("text", None) + if len(args) > 0: + audio = args[0] + args = 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 audio is not None: + inputs = self.feature_extractor(audio, *args, sampling_rate=sampling_rate, **kwargs) + if text is not None: + encodings = self.tokenizer(text, **kwargs) + + if text is None: + return inputs + elif audio is None: + return encodings + else: + inputs["labels"] = encodings["input_ids"] + return inputs + + def pad(self, *args, **kwargs): + """ + When used in normal mode, this method forwards all its arguments to Wav2Vec2FeatureExtractor's + [`~Wav2Vec2FeatureExtractor.pad`] and returns its output. If used in the context + [`~Wav2Vec2ProcessorWithLM.as_target_processor`] this method forwards all its arguments to + Wav2Vec2CTCTokenizer's [`~Wav2Vec2CTCTokenizer.pad`]. Please refer to the docstring of the above two methods + for more information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor.pad(*args, **kwargs) + + input_features = kwargs.pop("input_features", None) + labels = kwargs.pop("labels", None) + if len(args) > 0: + input_features = args[0] + args = args[1:] + + if input_features is not None: + input_features = self.feature_extractor.pad(input_features, *args, **kwargs) + if labels is not None: + labels = self.tokenizer.pad(labels, **kwargs) + + if labels is None: + return input_features + elif input_features is None: + return labels + else: + input_features["labels"] = labels["input_ids"] + return input_features + + def batch_decode( + self, + logits: np.ndarray, + pool: Optional[Pool] = None, + num_processes: Optional[int] = None, + beam_width: Optional[int] = None, + beam_prune_logp: Optional[float] = None, + token_min_logp: Optional[float] = None, + hotwords: Optional[Iterable[str]] = None, + hotword_weight: Optional[float] = None, + alpha: Optional[float] = None, + beta: Optional[float] = None, + unk_score_offset: Optional[float] = None, + lm_score_boundary: Optional[bool] = None, + output_word_offsets: bool = False, + n_best: int = 1, + ): + """ + Batch decode output logits to audio transcription with language model support. + + + + This function makes use of Python's multiprocessing. Currently, multiprocessing is available only on Unix + systems (see this [issue](https://github.com/kensho-technologies/pyctcdecode/issues/65)). + + If you are decoding multiple batches, consider creating a `Pool` and passing it to `batch_decode`. Otherwise, + `batch_decode` will be very slow since it will create a fresh `Pool` for each call. See usage example below. + + + + Args: + logits (`np.ndarray`): + The logits output vector of the model representing the log probabilities for each token. + pool (`multiprocessing.Pool`, *optional*): + An optional user-managed pool. If not set, one will be automatically created and closed. The pool + should be instantiated *after* `Wav2Vec2ProcessorWithLM`. Otherwise, the LM won't be available to the + pool's sub-processes. + + + + Currently, only pools created with a 'fork' context can be used. If a 'spawn' pool is passed, it will + be ignored and sequential decoding will be used instead. + + + + num_processes (`int`, *optional*): + If `pool` is not set, number of processes on which the function should be parallelized over. Defaults + to the number of available CPUs. + beam_width (`int`, *optional*): + Maximum number of beams at each step in decoding. Defaults to pyctcdecode's DEFAULT_BEAM_WIDTH. + beam_prune_logp (`int`, *optional*): + Beams that are much worse than best beam will be pruned Defaults to pyctcdecode's DEFAULT_PRUNE_LOGP. + token_min_logp (`int`, *optional*): + Tokens below this logp are skipped unless they are argmax of frame Defaults to pyctcdecode's + DEFAULT_MIN_TOKEN_LOGP. + hotwords (`List[str]`, *optional*): + List of words with extra importance, can be OOV for LM + hotword_weight (`int`, *optional*): + Weight factor for hotword importance Defaults to pyctcdecode's DEFAULT_HOTWORD_WEIGHT. + alpha (`float`, *optional*): + Weight for language model during shallow fusion + beta (`float`, *optional*): + Weight for length score adjustment of during scoring + unk_score_offset (`float`, *optional*): + Amount of log score offset for unknown tokens + lm_score_boundary (`bool`, *optional*): + Whether to have kenlm respect boundaries when scoring + output_word_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate + and model downsampling rate to compute the time-stamps of transcribed words. + n_best (`int`, *optional*, defaults to `1`): + Number of best hypotheses to return. If `n_best` is greater than 1, the returned `text` will be a list + of lists of strings, `logit_score` will be a list of lists of floats, and `lm_score` will be a list of + lists of floats, where the length of the outer list will correspond to the batch size and the length of + the inner list will correspond to the number of returned hypotheses . The value should be >= 1. + + + + Please take a look at the Example of [`~Wav2Vec2ProcessorWithLM.decode`] to better understand how to + make use of `output_word_offsets`. [`~Wav2Vec2ProcessorWithLM.batch_decode`] works the same way with + batched output. + + + + Returns: + [`~models.wav2vec2.Wav2Vec2DecoderWithLMOutput`]. + + Example: + See [Decoding multiple audios](#decoding-multiple-audios). + """ + + from pyctcdecode.constants import ( + DEFAULT_BEAM_WIDTH, + DEFAULT_HOTWORD_WEIGHT, + DEFAULT_MIN_TOKEN_LOGP, + DEFAULT_PRUNE_LOGP, + ) + + # set defaults + beam_width = beam_width if beam_width is not None else DEFAULT_BEAM_WIDTH + beam_prune_logp = beam_prune_logp if beam_prune_logp is not None else DEFAULT_PRUNE_LOGP + token_min_logp = token_min_logp if token_min_logp is not None else DEFAULT_MIN_TOKEN_LOGP + hotword_weight = hotword_weight if hotword_weight is not None else DEFAULT_HOTWORD_WEIGHT + + # reset params at every forward call. It's just a `set` method in pyctcdecode + self.decoder.reset_params( + alpha=alpha, beta=beta, unk_score_offset=unk_score_offset, lm_score_boundary=lm_score_boundary + ) + + # create multiprocessing pool and list numpy arrays + # filter out logits padding + logits_list = [array[(array != -100.0).all(axis=-1)] for array in logits] + + # create a pool if necessary while also using it as a context manager to close itself + if pool is None: + # fork is safe to use only on Unix, see "Contexts and start methods" section on + # multiprocessing's docs (https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods) + default_context = get_start_method() + + if default_context == "fork": + cm = pool = get_context().Pool(num_processes) + else: + logger.warning( + "Parallel batch decoding is not currently supported in this platform. " + "Falling back to sequential decoding." + ) + cm = nullcontext() + else: + # pool is managed by the user, so we don't need to close it + cm = nullcontext() + + if num_processes is not None: + logger.warning( + "Parameter `num_process` was passed, but it will be ignored since `pool` was also specified." + ) + + # pyctcdecode + with cm: + decoded_beams = self.decoder.decode_beams_batch( + pool=pool, + logits_list=logits_list, + beam_width=beam_width, + beam_prune_logp=beam_prune_logp, + token_min_logp=token_min_logp, + hotwords=hotwords, + hotword_weight=hotword_weight, + ) + + # extract text and scores + batch_texts, logit_scores, lm_scores, word_offsets = [], [], [], [] + + for d in decoded_beams: + batch_texts.append([beam[0] for beam in d]) + logit_scores.append([beam[-2] for beam in d]) + lm_scores.append([beam[-1] for beam in d]) + + # word_offsets.append([{"word": t[0], "start_offset": t[1][0], "end_offset": t[1][1]} for t in d[0][1]]) + + word_offsets.append( + [ + [ + {"word": word, "start_offset": start_offset, "end_offset": end_offset} + for word, (start_offset, end_offset) in beam[1] + ] + for beam in d + ] + ) + + word_offsets = word_offsets if output_word_offsets else None + + if n_best == 1: + return Wav2Vec2DecoderWithLMOutput( + text=[hyps[0] for hyps in batch_texts], + logit_score=[hyps[0] for hyps in logit_scores], + lm_score=[hyps[0] for hyps in lm_scores], + word_offsets=[hyps[0] for hyps in word_offsets] if word_offsets is not None else None, + ) + else: + return Wav2Vec2DecoderWithLMOutput( + text=[hyps[:n_best] for hyps in batch_texts], + logit_score=[hyps[:n_best] for hyps in logit_scores], + lm_score=[hyps[:n_best] for hyps in lm_scores], + word_offsets=[hyps[:n_best] for hyps in word_offsets] if word_offsets is not None else None, + ) + + def decode( + self, + logits: np.ndarray, + beam_width: Optional[int] = None, + beam_prune_logp: Optional[float] = None, + token_min_logp: Optional[float] = None, + hotwords: Optional[Iterable[str]] = None, + hotword_weight: Optional[float] = None, + alpha: Optional[float] = None, + beta: Optional[float] = None, + unk_score_offset: Optional[float] = None, + lm_score_boundary: Optional[bool] = None, + output_word_offsets: bool = False, + n_best: int = 1, + ): + """ + Decode output logits to audio transcription with language model support. + + Args: + logits (`np.ndarray`): + The logits output vector of the model representing the log probabilities for each token. + beam_width (`int`, *optional*): + Maximum number of beams at each step in decoding. Defaults to pyctcdecode's DEFAULT_BEAM_WIDTH. + beam_prune_logp (`int`, *optional*): + A threshold to prune beams with log-probs less than best_beam_logp + beam_prune_logp. The value should + be <= 0. Defaults to pyctcdecode's DEFAULT_PRUNE_LOGP. + token_min_logp (`int`, *optional*): + Tokens with log-probs below token_min_logp are skipped unless they are have the maximum log-prob for an + utterance. Defaults to pyctcdecode's DEFAULT_MIN_TOKEN_LOGP. + hotwords (`List[str]`, *optional*): + List of words with extra importance which can be missing from the LM's vocabulary, e.g. ["huggingface"] + hotword_weight (`int`, *optional*): + Weight multiplier that boosts hotword scores. Defaults to pyctcdecode's DEFAULT_HOTWORD_WEIGHT. + alpha (`float`, *optional*): + Weight for language model during shallow fusion + beta (`float`, *optional*): + Weight for length score adjustment of during scoring + unk_score_offset (`float`, *optional*): + Amount of log score offset for unknown tokens + lm_score_boundary (`bool`, *optional*): + Whether to have kenlm respect boundaries when scoring + output_word_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output word offsets. Word offsets can be used in combination with the sampling rate + and model downsampling rate to compute the time-stamps of transcribed words. + n_best (`int`, *optional*, defaults to `1`): + Number of best hypotheses to return. If `n_best` is greater than 1, the returned `text` will be a list + of strings, `logit_score` will be a list of floats, and `lm_score` will be a list of floats, where the + length of these lists will correspond to the number of returned hypotheses. The value should be >= 1. + + + + Please take a look at the example below to better understand how to make use of `output_word_offsets`. + + + + Returns: + [`~models.wav2vec2.Wav2Vec2DecoderWithLMOutput`]. + + Example: + + ```python + >>> # Let's see how to retrieve time steps for a model + >>> from transformers import AutoTokenizer, AutoProcessor, AutoModelForCTC + >>> from datasets import load_dataset + >>> import datasets + >>> import torch + + >>> # import model, feature extractor, tokenizer + >>> model = AutoModelForCTC.from_pretrained("patrickvonplaten/wav2vec2-base-100h-with-lm") + >>> processor = AutoProcessor.from_pretrained("patrickvonplaten/wav2vec2-base-100h-with-lm") + + >>> # load first sample of English common_voice + >>> dataset = load_dataset("common_voice", "en", split="train", streaming=True) + >>> dataset = dataset.cast_column("audio", datasets.Audio(sampling_rate=16_000)) + >>> dataset_iter = iter(dataset) + >>> sample = next(dataset_iter) + + >>> # forward sample through model to get greedily predicted transcription ids + >>> input_values = processor(sample["audio"]["array"], return_tensors="pt").input_values + >>> with torch.no_grad(): + ... logits = model(input_values).logits[0].cpu().numpy() + + >>> # retrieve word stamps (analogous commands for `output_char_offsets`) + >>> outputs = processor.decode(logits, output_word_offsets=True) + >>> # compute `time_offset` in seconds as product of downsampling ratio and sampling_rate + >>> time_offset = model.config.inputs_to_logits_ratio / processor.feature_extractor.sampling_rate + + >>> word_offsets = [ + ... { + ... "word": d["word"], + ... "start_time": round(d["start_offset"] * time_offset, 2), + ... "end_time": round(d["end_offset"] * time_offset, 2), + ... } + ... for d in outputs.word_offsets + ... ] + >>> # compare word offsets with audio `common_voice_en_100038.mp3` online on the dataset viewer: + >>> # https://huggingface.co/datasets/common_voice/viewer/en/train + >>> word_offsets[:4] + [{'word': 'WHY', 'start_time': 1.42, 'end_time': 1.54}, {'word': 'DOES', 'start_time': 1.66, 'end_time': 1.9}, {'word': 'MILISANDRA', 'start_time': 2.26, 'end_time': 2.9}, {'word': 'LOOK', 'start_time': 3.0, 'end_time': 3.16}] + ```""" + + from pyctcdecode.constants import ( + DEFAULT_BEAM_WIDTH, + DEFAULT_HOTWORD_WEIGHT, + DEFAULT_MIN_TOKEN_LOGP, + DEFAULT_PRUNE_LOGP, + ) + + # set defaults + beam_width = beam_width if beam_width is not None else DEFAULT_BEAM_WIDTH + beam_prune_logp = beam_prune_logp if beam_prune_logp is not None else DEFAULT_PRUNE_LOGP + token_min_logp = token_min_logp if token_min_logp is not None else DEFAULT_MIN_TOKEN_LOGP + hotword_weight = hotword_weight if hotword_weight is not None else DEFAULT_HOTWORD_WEIGHT + + # reset params at every forward call. It's just a `set` method in pyctcdecode + self.decoder.reset_params( + alpha=alpha, beta=beta, unk_score_offset=unk_score_offset, lm_score_boundary=lm_score_boundary + ) + + # pyctcdecode + decoded_beams = self.decoder.decode_beams( + logits, + beam_width=beam_width, + beam_prune_logp=beam_prune_logp, + token_min_logp=token_min_logp, + hotwords=hotwords, + hotword_weight=hotword_weight, + ) + + word_offsets = None + if output_word_offsets: + word_offsets = [ + [ + {"word": word, "start_offset": start_offset, "end_offset": end_offset} + for word, (start_offset, end_offset) in beam[2] + ] + for beam in decoded_beams + ] + logit_scores = [beam[-2] for beam in decoded_beams] + + lm_scores = [beam[-1] for beam in decoded_beams] + + hypotheses = [beam[0] for beam in decoded_beams] + + if n_best > len(decoded_beams): + logger.info( + "N-best size is larger than the number of generated hypotheses, all hypotheses will be returned." + ) + + if n_best == 1: + return Wav2Vec2DecoderWithLMOutput( + text=hypotheses[0], + logit_score=logit_scores[0], + lm_score=lm_scores[0], + word_offsets=word_offsets[0] if word_offsets is not None else None, + ) + else: + return Wav2Vec2DecoderWithLMOutput( + text=hypotheses[:n_best], + logit_score=logit_scores[:n_best], + lm_score=lm_scores[:n_best], + word_offsets=word_offsets[:n_best] if word_offsets is not None else None, + ) + + @contextmanager + def as_target_processor(self): + """ + Temporarily sets the processor for processing the target. Useful for encoding the labels when fine-tuning + Wav2Vec2. + """ + warnings.warn( + "`as_target_processor` is deprecated and will be removed in v5 of Transformers. You can process your " + "labels by using the argument `text` of the regular `__call__` method (either in the same call as " + "your audio inputs, or in a separate call." + ) + self._in_target_context_manager = True + self.current_processor = self.tokenizer + yield + self.current_processor = self.feature_extractor + self._in_target_context_manager = False diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d48a3615bb4a30f9d9bd43445ef420518346c58 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/__init__.py @@ -0,0 +1,59 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = {"configuration_wavlm": ["WAVLM_PRETRAINED_CONFIG_ARCHIVE_MAP", "WavLMConfig"]} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_wavlm"] = [ + "WAVLM_PRETRAINED_MODEL_ARCHIVE_LIST", + "WavLMForAudioFrameClassification", + "WavLMForCTC", + "WavLMForSequenceClassification", + "WavLMForXVector", + "WavLMModel", + "WavLMPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_wavlm import WAVLM_PRETRAINED_CONFIG_ARCHIVE_MAP, WavLMConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_wavlm import ( + WAVLM_PRETRAINED_MODEL_ARCHIVE_LIST, + WavLMForAudioFrameClassification, + WavLMForCTC, + WavLMForSequenceClassification, + WavLMForXVector, + WavLMModel, + WavLMPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/configuration_wavlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/configuration_wavlm.py new file mode 100644 index 0000000000000000000000000000000000000000..becbe100240d88db81b6de79a18c50a02bdebf99 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/configuration_wavlm.py @@ -0,0 +1,333 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors, Microsoft Research, and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" WavLM model configuration""" + +import functools +import operator + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +WAVLM_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "microsoft/wavlm-base": "https://huggingface.co/microsoft/wavlm-base/resolve/main/config.json", + # See all WavLM models at https://huggingface.co/models?filter=wavlm +} + + +class WavLMConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`WavLMModel`]. It is used to instantiate an WavLM + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the WavLM + [microsoft/wavlm-base](https://huggingface.co/microsoft/wavlm-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 32): + Vocabulary size of the WavLM model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`WavLMModel`]. Vocabulary size of the model. Defines the different tokens + that can be represented by the *inputs_ids* passed to the forward method of [`WavLMModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + final_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for the final projection layer of [`WavLMForCTC`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + feat_extract_norm (`str`, *optional*, defaults to `"group"`): + The norm to be applied to 1D convolutional layers in feature encoder. One of `"group"` for group + normalization of only the first 1D convolutional layer or `"layer"` for layer normalization of all 1D + convolutional layers. + feat_proj_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for output of the feature encoder. + feat_extract_activation (`str, `optional`, defaults to `"gelu"`): + The non-linear activation function (function or string) in the 1D convolutional layers of the feature + extractor. If string, `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` are supported. + conv_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 512, 512, 512)`): + A tuple of integers defining the number of input and output channels of each 1D convolutional layer in the + feature encoder. The length of *conv_dim* defines the number of 1D convolutional layers. + conv_stride (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 2, 2, 2, 2, 2, 2)`): + A tuple of integers defining the stride of each 1D convolutional layer in the feature encoder. The length + of *conv_stride* defines the number of convolutional layers and has to match the length of *conv_dim*. + conv_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(10, 3, 3, 3, 3, 3, 3)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the feature encoder. The + length of *conv_kernel* defines the number of convolutional layers and has to match the length of + *conv_dim*. + conv_bias (`bool`, *optional*, defaults to `False`): + Whether the 1D convolutional layers have a bias. + num_conv_pos_embeddings (`int`, *optional*, defaults to 128): + Number of convolutional positional embeddings. Defines the kernel size of 1D convolutional positional + embeddings layer. + num_conv_pos_embedding_groups (`int`, *optional*, defaults to 16): + Number of groups of 1D convolutional positional embeddings layer. + do_stable_layer_norm (`bool`, *optional*, defaults to `False`): + Whether to apply *stable* layer norm architecture of the Transformer encoder. `do_stable_layer_norm is + True` corresponds to applying layer norm before the attention layer, whereas `do_stable_layer_norm is + False` corresponds to applying layer norm after the attention layer. + apply_spec_augment (`bool`, *optional*, defaults to `True`): + Whether to apply *SpecAugment* data augmentation to the outputs of the feature encoder. For reference see + [SpecAugment: A Simple Data Augmentation Method for Automatic Speech + Recognition](https://arxiv.org/abs/1904.08779). + mask_time_prob (`float`, *optional*, defaults to 0.05): + Propability of each feature vector along the time axis to be chosen as the start of the vector span to be + masked. Approximately `mask_time_prob * sequence_length // mask_time_length` feature vectors will be masked + along the time axis. This is only relevant if `apply_spec_augment is True`. + mask_time_length (`int`, *optional*, defaults to 10): + Length of vector span along the time axis. + mask_time_min_masks (`int`, *optional*, defaults to 2),: + The minimum number of masks of length `mask_feature_length` generated along the time axis, each time step, + irrespectively of `mask_feature_prob`. Only relevant if ''mask_time_prob*len(time_axis)/mask_time_length < + mask_time_min_masks'' + mask_feature_prob (`float`, *optional*, defaults to 0.0): + Propability of each feature vector along the feature axis to be chosen as the start of the vector span to + be masked. Approximately `mask_time_prob * hidden_size // mask_time_length` feature vectors will be masked + along the time axis. This is only relevant if `apply_spec_augment is True`. + mask_feature_length (`int`, *optional*, defaults to 10): + Length of vector span along the feature axis. + num_codevectors_per_group (`int`, *optional*, defaults to 320): + Number of entries in each quantization codebook (group). + num_codevector_groups (`int`, *optional*, defaults to 2): + Number of codevector groups for product codevector quantization. + contrastive_logits_temperature (`float`, *optional*, defaults to 0.1): + The temperature *kappa* in the contrastive loss. + num_negatives (`int`, *optional*, defaults to 100): + Number of negative samples for the contrastive loss. + codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the quantized feature vectors. + proj_codevector_dim (`int`, *optional*, defaults to 256): + Dimensionality of the final projection of both the quantized and the transformer features. + diversity_loss_weight (`int`, *optional*, defaults to 0.1): + The weight of the codebook diversity loss component. + ctc_loss_reduction (`str`, *optional*, defaults to `"mean"`): + Specifies the reduction to apply to the output of `torch.nn.CTCLoss`. Only relevant when training an + instance of [`WavLMForCTC`]. + ctc_zero_infinity (`bool`, *optional*, defaults to `False`): + Whether to zero infinite losses and the associated gradients of `torch.nn.CTCLoss`. Infinite losses mainly + occur when the inputs are too short to be aligned to the targets. Only relevant when training an instance + of [`WavLMForCTC`]. + use_weighted_layer_sum (`bool`, *optional*, defaults to `False`): + Whether to use a weighted average of layer outputs with learned weights. Only relevant when using an + instance of [`WavLMForSequenceClassification`]. + classifier_proj_size (`int`, *optional*, defaults to 256): + Dimensionality of the projection before token mean-pooling for classification. + tdnn_dim (`Tuple[int]` or `List[int]`, *optional*, defaults to `(512, 512, 512, 512, 1500)`): + A tuple of integers defining the number of output channels of each 1D convolutional layer in the *TDNN* + module of the *XVector* model. The length of *tdnn_dim* defines the number of *TDNN* layers. + tdnn_kernel (`Tuple[int]` or `List[int]`, *optional*, defaults to `(5, 3, 3, 1, 1)`): + A tuple of integers defining the kernel size of each 1D convolutional layer in the *TDNN* module of the + *XVector* model. The length of *tdnn_kernel* has to match the length of *tdnn_dim*. + tdnn_dilation (`Tuple[int]` or `List[int]`, *optional*, defaults to `(1, 2, 3, 1, 1)`): + A tuple of integers defining the dilation factor of each 1D convolutional layer in *TDNN* module of the + *XVector* model. The length of *tdnn_dilation* has to match the length of *tdnn_dim*. + xvector_output_dim (`int`, *optional*, defaults to 512): + Dimensionality of the *XVector* embedding vectors. + add_adapter (`bool`, *optional*, defaults to `False`): + Whether a convolutional network should be stacked on top of the Wav2Vec2 Encoder. Can be very useful for + warm-starting Wav2Vec2 for SpeechEncoderDecoder models. + adapter_kernel_size (`int`, *optional*, defaults to 3): + Kernel size of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + adapter_stride (`int`, *optional*, defaults to 2): + Stride of the convolutional layers in the adapter network. Only relevant if `add_adapter is True`. + num_adapter_layers (`int`, *optional*, defaults to 3): + Number of convolutional layers that should be used in the adapter network. Only relevant if `add_adapter is + True`. + output_hidden_size (`int`, *optional*): + Dimensionality of the encoder output layer. If not defined, this defaults to *hidden-size*. Only relevant + if `add_adapter is True`. + + Example: + + ```python + + ``` + + Example: + + ```python + >>> from transformers import WavLMConfig, WavLMModel + + >>> # Initializing a WavLM facebook/wavlm-base-960h style configuration + >>> configuration = WavLMConfig() + + >>> # Initializing a model (with random weights) from the facebook/wavlm-base-960h style configuration + >>> model = WavLMModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "wavlm" + + def __init__( + self, + vocab_size=32, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout=0.1, + activation_dropout=0.1, + attention_dropout=0.1, + feat_proj_dropout=0.0, + final_dropout=0.1, + layerdrop=0.1, + initializer_range=0.02, + layer_norm_eps=1e-5, + feat_extract_norm="group", + feat_extract_activation="gelu", + conv_dim=(512, 512, 512, 512, 512, 512, 512), + conv_stride=(5, 2, 2, 2, 2, 2, 2), + conv_kernel=(10, 3, 3, 3, 3, 2, 2), + conv_bias=False, + num_conv_pos_embeddings=128, + num_conv_pos_embedding_groups=16, + num_buckets=320, + max_bucket_distance=800, + do_stable_layer_norm=False, + apply_spec_augment=True, + mask_time_prob=0.05, + mask_time_length=10, + mask_time_min_masks=2, + mask_feature_prob=0.0, + mask_feature_length=10, + num_codevectors_per_group=320, + num_codevector_groups=2, + contrastive_logits_temperature=0.1, + num_negatives=100, + codevector_dim=256, + proj_codevector_dim=256, + diversity_loss_weight=0.1, + ctc_loss_reduction="mean", + ctc_zero_infinity=False, + use_weighted_layer_sum=False, + classifier_proj_size=256, + tdnn_dim=(512, 512, 512, 512, 1500), + tdnn_kernel=(5, 3, 3, 1, 1), + tdnn_dilation=(1, 2, 3, 1, 1), + xvector_output_dim=512, + num_ctc_classes=80, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + add_adapter=False, + adapter_kernel_size=3, + adapter_stride=2, + num_adapter_layers=3, + output_hidden_size=None, + **kwargs, + ): + super().__init__(**kwargs, pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id) + self.hidden_size = hidden_size + self.feat_extract_norm = feat_extract_norm + self.feat_extract_activation = feat_extract_activation + self.conv_dim = list(conv_dim) + self.conv_stride = list(conv_stride) + self.conv_kernel = list(conv_kernel) + self.conv_bias = conv_bias + self.num_buckets = num_buckets + self.max_bucket_distance = max_bucket_distance + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_feat_extract_layers = len(self.conv_dim) + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_attention_heads = num_attention_heads + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.feat_proj_dropout = feat_proj_dropout + self.final_dropout = final_dropout + self.layerdrop = layerdrop + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.num_ctc_classes = num_ctc_classes + self.vocab_size = vocab_size + self.do_stable_layer_norm = do_stable_layer_norm + self.use_weighted_layer_sum = use_weighted_layer_sum + self.classifier_proj_size = classifier_proj_size + + if ( + (len(self.conv_stride) != self.num_feat_extract_layers) + or (len(self.conv_kernel) != self.num_feat_extract_layers) + or (len(self.conv_dim) != self.num_feat_extract_layers) + ): + raise ValueError( + "Configuration for convolutional layers is incorrect. It is required that `len(config.conv_dim)` ==" + " `len(config.conv_stride)` == `len(config.conv_kernel)`, but is `len(config.conv_dim) =" + f" {len(self.conv_dim)}`, `len(config.conv_stride) = {len(self.conv_stride)}`," + f" `len(config.conv_kernel) = {len(self.conv_kernel)}`." + ) + + # fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779 + self.apply_spec_augment = apply_spec_augment + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.mask_time_min_masks = mask_time_min_masks + self.mask_feature_prob = mask_feature_prob + self.mask_feature_length = mask_feature_length + + # parameters for pretraining with codevector quantized representations + self.num_codevectors_per_group = num_codevectors_per_group + self.num_codevector_groups = num_codevector_groups + self.contrastive_logits_temperature = contrastive_logits_temperature + self.num_negatives = num_negatives + self.codevector_dim = codevector_dim + self.proj_codevector_dim = proj_codevector_dim + self.diversity_loss_weight = diversity_loss_weight + + # ctc loss + self.ctc_loss_reduction = ctc_loss_reduction + self.ctc_zero_infinity = ctc_zero_infinity + + # adapter + self.add_adapter = add_adapter + self.adapter_kernel_size = adapter_kernel_size + self.adapter_stride = adapter_stride + self.num_adapter_layers = num_adapter_layers + self.output_hidden_size = output_hidden_size or hidden_size + + # SequenceClassification-specific parameter. Feel free to ignore for other classes. + self.classifier_proj_size = classifier_proj_size + + # XVector-specific parameters. Feel free to ignore for other classes. + self.tdnn_dim = list(tdnn_dim) + self.tdnn_kernel = list(tdnn_kernel) + self.tdnn_dilation = list(tdnn_dilation) + self.xvector_output_dim = xvector_output_dim + + @property + def inputs_to_logits_ratio(self): + return functools.reduce(operator.mul, self.conv_stride, 1) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..84e3d231ea38455b980d398f725ea9d0eec0b6d4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,207 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert WavLM checkpoint.""" + + +import argparse + +import torch + +# Step 1. clone https://github.com/microsoft/unilm +# Step 2. git checkout to https://github.com/microsoft/unilm/commit/b94ec76c36f02fb2b0bf0dcb0b8554a2185173cd +# Step 3. cd unilm +# Step 4. ln -s $(realpath wavlm/modules.py) ./ # create simlink +# import classes +from unilm.wavlm.WavLM import WavLM as WavLMOrig +from unilm.wavlm.WavLM import WavLMConfig as WavLMConfigOrig + +from transformers import WavLMConfig, WavLMModel, logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +MAPPING = { + "post_extract_proj": "feature_projection.projection", + "encoder.pos_conv.0": "encoder.pos_conv_embed.conv", + "self_attn.k_proj": "encoder.layers.*.attention.k_proj", + "self_attn.v_proj": "encoder.layers.*.attention.v_proj", + "self_attn.q_proj": "encoder.layers.*.attention.q_proj", + "self_attn.out_proj": "encoder.layers.*.attention.out_proj", + "self_attn.grep_linear": "encoder.layers.*.attention.gru_rel_pos_linear", + "self_attn.relative_attention_bias": "encoder.layers.*.attention.rel_attn_embed", + "self_attn.grep_a": "encoder.layers.*.attention.gru_rel_pos_const", + "self_attn_layer_norm": "encoder.layers.*.layer_norm", + "fc1": "encoder.layers.*.feed_forward.intermediate_dense", + "fc2": "encoder.layers.*.feed_forward.output_dense", + "final_layer_norm": "encoder.layers.*.final_layer_norm", + "encoder.layer_norm": "encoder.layer_norm", + "w2v_model.layer_norm": "feature_projection.layer_norm", + "quantizer.weight_proj": "quantizer.weight_proj", + "quantizer.vars": "quantizer.codevectors", + "project_q": "project_q", + "final_proj": "project_hid", + "w2v_encoder.proj": "ctc_proj", + "mask_emb": "masked_spec_embed", +} +TOP_LEVEL_KEYS = [ + "ctc_proj", + "quantizer.weight_proj", + "quantizer.codevectors", + "project_q", + "project_hid", +] + + +def set_recursively(hf_pointer, key, value, full_name, weight_type): + for attribute in key.split("."): + hf_pointer = getattr(hf_pointer, attribute) + + if weight_type is not None: + hf_shape = getattr(hf_pointer, weight_type).shape + else: + hf_shape = hf_pointer.shape + + assert hf_shape == value.shape, ( + f"Shape of hf {key + '.' + weight_type if weight_type is not None else ''} is {hf_shape}, but should be" + f" {value.shape} for {full_name}" + ) + + if weight_type == "weight": + hf_pointer.weight.data = value + elif weight_type == "weight_g": + hf_pointer.weight_g.data = value + elif weight_type == "weight_v": + hf_pointer.weight_v.data = value + elif weight_type == "bias": + hf_pointer.bias.data = value + else: + hf_pointer.data = value + + logger.info(f"{key + '.' + weight_type if weight_type is not None else ''} was initialized from {full_name}.") + + +def recursively_load_weights(fairseq_model, hf_model): + unused_weights = [] + fairseq_dict = fairseq_model.state_dict() + + feature_extractor = hf_model.feature_extractor + + for name, value in fairseq_dict.items(): + is_used = False + if "conv_layers" in name: + load_conv_layer( + name, + value, + feature_extractor, + unused_weights, + hf_model.config.feat_extract_norm == "group", + ) + is_used = True + else: + for key, mapped_key in MAPPING.items(): + if key in name or key.split("w2v_model.")[-1] == name.split(".")[0]: + is_used = True + if "*" in mapped_key: + layer_index = name.split(key)[0].split(".")[-2] + mapped_key = mapped_key.replace("*", layer_index) + if "weight_g" in name: + weight_type = "weight_g" + elif "weight_v" in name: + weight_type = "weight_v" + elif "bias" in name and "relative_attention_bias" not in name: + weight_type = "bias" + elif "weight" in name: + # TODO: don't match quantizer.weight_proj + weight_type = "weight" + else: + weight_type = None + + set_recursively(hf_model, mapped_key, value, name, weight_type) + continue + if not is_used: + unused_weights.append(name) + + logger.warning(f"Unused weights: {unused_weights}") + + +def load_conv_layer(full_name, value, feature_extractor, unused_weights, use_group_norm): + name = full_name.split("conv_layers.")[-1] + items = name.split(".") + layer_id = int(items[0]) + type_id = int(items[1]) + + if type_id == 0: + if "bias" in name: + assert value.shape == feature_extractor.conv_layers[layer_id].conv.bias.data.shape, ( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.bias.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + assert value.shape == feature_extractor.conv_layers[layer_id].conv.weight.data.shape, ( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].conv.weight.data = value + logger.info(f"Feat extract conv layer {layer_id} was initialized from {full_name}.") + elif (type_id == 2 and not use_group_norm) or (type_id == 2 and layer_id == 0 and use_group_norm): + if "bias" in name: + assert value.shape == feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape, ( + f"{full_name} has size {value.shape}, but {feature_extractor[layer_id].layer_norm.bias.data.shape} was" + " found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.bias.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + elif "weight" in name: + assert value.shape == feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape, ( + f"{full_name} has size {value.shape}, but" + f" {feature_extractor[layer_id].layer_norm.weight.data.shape} was found." + ) + feature_extractor.conv_layers[layer_id].layer_norm.weight.data = value + logger.info(f"Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}.") + else: + unused_weights.append(full_name) + + +@torch.no_grad() +def convert_wavlm_checkpoint(checkpoint_path, pytorch_dump_folder_path, config_path=None): + # load the pre-trained checkpoints + checkpoint = torch.load(checkpoint_path) + cfg = WavLMConfigOrig(checkpoint["cfg"]) + model = WavLMOrig(cfg) + model.load_state_dict(checkpoint["model"]) + model.eval() + + if config_path is not None: + config = WavLMConfig.from_pretrained(config_path) + else: + config = WavLMConfig() + + hf_wavlm = WavLMModel(config) + + recursively_load_weights(model, hf_wavlm) + + hf_wavlm.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.") + parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to fairseq checkpoint") + parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert") + args = parser.parse_args() + convert_wavlm_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_s3prl_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_s3prl_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..e41aa0099a60cb904a48f3b1b25a3272ec307042 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/convert_wavlm_original_s3prl_checkpoint_to_pytorch.py @@ -0,0 +1,110 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert Hubert checkpoint.""" + + +import argparse + +import torch + +from transformers import ( + Wav2Vec2FeatureExtractor, + WavLMConfig, + WavLMForAudioFrameClassification, + WavLMForSequenceClassification, + WavLMForXVector, + logging, +) + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def convert_classification(base_model_name, hf_config, downstream_dict): + model = WavLMForSequenceClassification.from_pretrained(base_model_name, config=hf_config) + model.projector.weight.data = downstream_dict["projector.weight"] + model.projector.bias.data = downstream_dict["projector.bias"] + model.classifier.weight.data = downstream_dict["model.post_net.linear.weight"] + model.classifier.bias.data = downstream_dict["model.post_net.linear.bias"] + return model + + +def convert_diarization(base_model_name, hf_config, downstream_dict): + model = WavLMForAudioFrameClassification.from_pretrained(base_model_name, config=hf_config) + model.classifier.weight.data = downstream_dict["model.linear.weight"] + model.classifier.bias.data = downstream_dict["model.linear.bias"] + return model + + +def convert_xvector(base_model_name, hf_config, downstream_dict): + model = WavLMForXVector.from_pretrained(base_model_name, config=hf_config) + model.projector.weight.data = downstream_dict["connector.weight"] + model.projector.bias.data = downstream_dict["connector.bias"] + for i, kernel_size in enumerate(hf_config.tdnn_kernel): + model.tdnn[i].kernel.weight.data = downstream_dict[ + f"model.framelevel_feature_extractor.module.{i}.kernel.weight" + ] + model.tdnn[i].kernel.bias.data = downstream_dict[f"model.framelevel_feature_extractor.module.{i}.kernel.bias"] + + model.feature_extractor.weight.data = downstream_dict["model.utterancelevel_feature_extractor.linear1.weight"] + model.feature_extractor.bias.data = downstream_dict["model.utterancelevel_feature_extractor.linear1.bias"] + model.classifier.weight.data = downstream_dict["model.utterancelevel_feature_extractor.linear2.weight"] + model.classifier.bias.data = downstream_dict["model.utterancelevel_feature_extractor.linear2.bias"] + model.objective.weight.data = downstream_dict["objective.W"] + return model + + +@torch.no_grad() +def convert_s3prl_checkpoint(base_model_name, config_path, checkpoint_path, model_dump_path): + """ + Copy/paste/tweak model's weights to transformers design. + """ + checkpoint = torch.load(checkpoint_path, map_location="cpu") + + downstream_dict = checkpoint["Downstream"] + + hf_config = WavLMConfig.from_pretrained(config_path) + hf_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained( + base_model_name, return_attention_mask=True, do_normalize=False + ) + + arch = hf_config.architectures[0] + if arch.endswith("ForSequenceClassification"): + hf_model = convert_classification(base_model_name, hf_config, downstream_dict) + elif arch.endswith("ForAudioFrameClassification"): + hf_model = convert_diarization(base_model_name, hf_config, downstream_dict) + elif arch.endswith("ForXVector"): + hf_model = convert_xvector(base_model_name, hf_config, downstream_dict) + else: + raise NotImplementedError(f"S3PRL weights conversion is not supported for {arch}") + + if hf_config.use_weighted_layer_sum: + hf_model.layer_weights.data = checkpoint["Featurizer"]["weights"] + + hf_feature_extractor.save_pretrained(model_dump_path) + hf_model.save_pretrained(model_dump_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--base_model_name", default=None, type=str, help="Name of the huggingface pretrained base model." + ) + parser.add_argument("--config_path", default=None, type=str, help="Path to the huggingface classifier config.") + parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to the s3prl checkpoint.") + parser.add_argument("--model_dump_path", default=None, type=str, help="Path to the final converted model.") + args = parser.parse_args() + convert_s3prl_checkpoint(args.base_model_name, args.config_path, args.checkpoint_path, args.model_dump_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/modeling_wavlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/modeling_wavlm.py new file mode 100644 index 0000000000000000000000000000000000000000..718c4d61dd597ceb9e53d074a47c29709f9367fd --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/wavlm/modeling_wavlm.py @@ -0,0 +1,1830 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors, Microsoft Research, and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch WavLM model.""" + +import math +import warnings +from typing import Optional, Tuple, Union + +import numpy as np +import torch +import torch.nn.functional as F +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...deepspeed import is_deepspeed_zero3_enabled +from ...modeling_outputs import ( + BaseModelOutput, + CausalLMOutput, + SequenceClassifierOutput, + TokenClassifierOutput, + Wav2Vec2BaseModelOutput, + XVectorOutput, +) +from ...modeling_utils import PreTrainedModel +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_wavlm import WavLMConfig + + +logger = logging.get_logger(__name__) + + +_HIDDEN_STATES_START_POSITION = 2 + +# General docstring +_CONFIG_FOR_DOC = "WavLMConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "patrickvonplaten/wavlm-libri-clean-100h-base-plus" +_EXPECTED_OUTPUT_SHAPE = [1, 292, 768] + +# CTC docstring +_CTC_EXPECTED_OUTPUT = "'mister quilter is the aposle of the middle classes and we are glad to welcome his gospel'" +_CTC_EXPECTED_LOSS = 12.51 + +# Frame class docstring +_FRAME_CLASS_CHECKPOINT = "microsoft/wavlm-base-plus-sd" +_FRAME_EXPECTED_OUTPUT = [0, 0] + +# Speaker Verification docstring +_XVECTOR_CHECKPOINT = "microsoft/wavlm-base-plus-sv" +_XVECTOR_EXPECTED_OUTPUT = 0.97 + +WAVLM_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "microsoft/wavlm-base", + "microsoft/wavlm-base-plus", + "microsoft/wavlm-large", + # See all WavLM models at https://huggingface.co/models?filter=wavlm +] + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2._compute_mask_indices +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + attention_mask: Optional[torch.LongTensor] = None, + min_masks: int = 0, +) -> np.ndarray: + """ + Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for + ASR](https://arxiv.org/abs/1904.08779). Note that this method is not optimized to run on TPU and should be run on + CPU as part of the preprocessing during training. + + Args: + shape: The shape for which to compute masks. This should be of a tuple of size 2 where + the first element is the batch size and the second element is the length of the axis to span. + mask_prob: The percentage of the whole axis (between 0 and 1) which will be masked. The number of + independently generated mask spans of length `mask_length` is computed by + `mask_prob*shape[1]/mask_length`. Note that due to overlaps, `mask_prob` is an upper bound and the + actual percentage will be smaller. + mask_length: size of the mask + min_masks: minimum number of masked spans + attention_mask: A (right-padded) attention mask which independently shortens the feature axis of + each batch dimension. + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + if mask_length > sequence_length: + raise ValueError( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length}" + f" and `sequence_length`: {sequence_length}`" + ) + + # epsilon is used for probabilistic rounding + epsilon = np.random.rand(1).item() + + def compute_num_masked_span(input_length): + """Given input length, compute how many spans should be masked""" + num_masked_span = int(mask_prob * input_length / mask_length + epsilon) + num_masked_span = max(num_masked_span, min_masks) + + # make sure num masked span <= sequence_length + if num_masked_span * mask_length > sequence_length: + num_masked_span = sequence_length // mask_length + + # make sure num_masked span is also <= input_length - (mask_length - 1) + if input_length - (mask_length - 1) < num_masked_span: + num_masked_span = max(input_length - (mask_length - 1), 0) + + return num_masked_span + + # compute number of masked spans in batch + input_lengths = ( + attention_mask.sum(-1).detach().tolist() + if attention_mask is not None + else [sequence_length for _ in range(batch_size)] + ) + + # SpecAugment mask to fill + spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) + spec_aug_mask_idxs = [] + + max_num_masked_span = compute_num_masked_span(sequence_length) + + if max_num_masked_span == 0: + return spec_aug_mask + + for input_length in input_lengths: + # compute num of masked spans for this input + num_masked_span = compute_num_masked_span(input_length) + + # get random indices to mask + spec_aug_mask_idx = np.random.choice( + np.arange(input_length - (mask_length - 1)), num_masked_span, replace=False + ) + + # pick first sampled index that will serve as a dummy index to pad vector + # to ensure same dimension for all batches due to probabilistic rounding + # Picking first sample just pads those vectors twice. + if len(spec_aug_mask_idx) == 0: + # this case can only happen if `input_length` is strictly smaller then + # `sequence_length` in which case the last token has to be a padding + # token which we can use as a dummy mask id + dummy_mask_idx = sequence_length - 1 + else: + dummy_mask_idx = spec_aug_mask_idx[0] + + spec_aug_mask_idx = np.concatenate( + [spec_aug_mask_idx, np.ones(max_num_masked_span - num_masked_span, dtype=np.int32) * dummy_mask_idx] + ) + spec_aug_mask_idxs.append(spec_aug_mask_idx) + + spec_aug_mask_idxs = np.array(spec_aug_mask_idxs) + + # expand masked indices to masked spans + spec_aug_mask_idxs = np.broadcast_to( + spec_aug_mask_idxs[:, :, None], (batch_size, max_num_masked_span, mask_length) + ) + spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, max_num_masked_span * mask_length) + + # add offset to the starting indexes so that indexes now create a span + offsets = np.arange(mask_length)[None, None, :] + offsets = np.broadcast_to(offsets, (batch_size, max_num_masked_span, mask_length)).reshape( + batch_size, max_num_masked_span * mask_length + ) + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # ensure that we cannot have indices larger than sequence_length + if spec_aug_mask_idxs.max() > sequence_length - 1: + spec_aug_mask_idxs[spec_aug_mask_idxs > sequence_length - 1] = sequence_length - 1 + + # scatter indices to mask + np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) + + return spec_aug_mask + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2NoLayerNormConvLayer with Wav2Vec2->WavLM +class WavLMNoLayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2LayerNormConvLayer with Wav2Vec2->WavLM +class WavLMLayerNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.layer_norm = nn.LayerNorm(self.out_conv_dim, elementwise_affine=True) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + + hidden_states = hidden_states.transpose(-2, -1) + hidden_states = self.layer_norm(hidden_states) + hidden_states = hidden_states.transpose(-2, -1) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2GroupNormConvLayer with Wav2Vec2->WavLM +class WavLMGroupNormConvLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.conv_dim[layer_id - 1] if layer_id > 0 else 1 + self.out_conv_dim = config.conv_dim[layer_id] + + self.conv = nn.Conv1d( + self.in_conv_dim, + self.out_conv_dim, + kernel_size=config.conv_kernel[layer_id], + stride=config.conv_stride[layer_id], + bias=config.conv_bias, + ) + self.activation = ACT2FN[config.feat_extract_activation] + + self.layer_norm = nn.GroupNorm(num_groups=self.out_conv_dim, num_channels=self.out_conv_dim, affine=True) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2PositionalConvEmbedding with Wav2Vec2->WavLM +class WavLMPositionalConvEmbedding(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.hidden_size, + config.hidden_size, + kernel_size=config.num_conv_pos_embeddings, + padding=config.num_conv_pos_embeddings // 2, + groups=config.num_conv_pos_embedding_groups, + ) + + if is_deepspeed_zero3_enabled(): + import deepspeed + + with deepspeed.zero.GatheredParameters(self.conv.weight, modifier_rank=0): + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + deepspeed.zero.register_external_parameter(self, self.conv.weight_v) + deepspeed.zero.register_external_parameter(self, self.conv.weight_g) + else: + self.conv = nn.utils.weight_norm(self.conv, name="weight", dim=2) + + self.padding = WavLMSamePadLayer(config.num_conv_pos_embeddings) + self.activation = ACT2FN[config.feat_extract_activation] + + def forward(self, hidden_states): + hidden_states = hidden_states.transpose(1, 2) + + hidden_states = self.conv(hidden_states) + hidden_states = self.padding(hidden_states) + hidden_states = self.activation(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2SamePadLayer with Wav2Vec2->WavLM +class WavLMSamePadLayer(nn.Module): + def __init__(self, num_conv_pos_embeddings): + super().__init__() + self.num_pad_remove = 1 if num_conv_pos_embeddings % 2 == 0 else 0 + + def forward(self, hidden_states): + if self.num_pad_remove > 0: + hidden_states = hidden_states[:, :, : -self.num_pad_remove] + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeatureEncoder with Wav2Vec2->WavLM +class WavLMFeatureEncoder(nn.Module): + """Construct the features from raw audio waveform""" + + def __init__(self, config): + super().__init__() + + if config.feat_extract_norm == "group": + conv_layers = [WavLMGroupNormConvLayer(config, layer_id=0)] + [ + WavLMNoLayerNormConvLayer(config, layer_id=i + 1) for i in range(config.num_feat_extract_layers - 1) + ] + elif config.feat_extract_norm == "layer": + conv_layers = [WavLMLayerNormConvLayer(config, layer_id=i) for i in range(config.num_feat_extract_layers)] + else: + raise ValueError( + f"`config.feat_extract_norm` is {config.feat_extract_norm}, but has to be one of ['group', 'layer']" + ) + self.conv_layers = nn.ModuleList(conv_layers) + self.gradient_checkpointing = False + self._requires_grad = True + + def _freeze_parameters(self): + for param in self.parameters(): + param.requires_grad = False + self._requires_grad = False + + def forward(self, input_values): + hidden_states = input_values[:, None] + + # make sure hidden_states require grad for gradient_checkpointing + if self._requires_grad and self.training: + hidden_states.requires_grad = True + + for conv_layer in self.conv_layers: + if self._requires_grad and self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(conv_layer), + hidden_states, + ) + else: + hidden_states = conv_layer(hidden_states) + + return hidden_states + + +class WavLMFeatureExtractor(WavLMFeatureEncoder): + def __init__(self, config): + super().__init__(config) + warnings.warn( + f"The class `{self.__class__.__name__}` has been depreciated " + "and will be removed in Transformers v5. " + f"Use `{self.__class__.__bases__[0].__name__}` instead.", + FutureWarning, + ) + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeatureProjection with Wav2Vec2->WavLM +class WavLMFeatureProjection(nn.Module): + def __init__(self, config): + super().__init__() + self.layer_norm = nn.LayerNorm(config.conv_dim[-1], eps=config.layer_norm_eps) + self.projection = nn.Linear(config.conv_dim[-1], config.hidden_size) + self.dropout = nn.Dropout(config.feat_proj_dropout) + + def forward(self, hidden_states): + # non-projected hidden states are needed for quantization + norm_hidden_states = self.layer_norm(hidden_states) + hidden_states = self.projection(norm_hidden_states) + hidden_states = self.dropout(hidden_states) + return hidden_states, norm_hidden_states + + +class WavLMAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + num_buckets: int = 320, + max_distance: int = 800, + has_relative_position_bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + + self.k_proj = nn.Linear(embed_dim, embed_dim) + self.v_proj = nn.Linear(embed_dim, embed_dim) + self.q_proj = nn.Linear(embed_dim, embed_dim) + self.out_proj = nn.Linear(embed_dim, embed_dim) + + self.num_buckets = num_buckets + self.max_distance = max_distance + + self.gru_rel_pos_const = nn.Parameter(torch.ones(1, self.num_heads, 1, 1)) + self.gru_rel_pos_linear = nn.Linear(self.head_dim, 8) + + if has_relative_position_bias: + self.rel_attn_embed = nn.Embedding(self.num_buckets, self.num_heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_bias: Optional[torch.Tensor] = None, + output_attentions: bool = False, + index=0, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Attention layer with relative attention""" + bsz, tgt_len, _ = hidden_states.size() + + # first pass of attention layer creates position bias + if position_bias is None: + position_bias = self.compute_bias(tgt_len, tgt_len) + position_bias = ( + position_bias.unsqueeze(0).repeat(bsz, 1, 1, 1).view(bsz * self.num_heads, tgt_len, tgt_len) + ) + + # Compute relative position bias: + # 1) get reshape hidden_states + gated_hidden_states = hidden_states.view(hidden_states.shape[:-1] + (self.num_heads, -1)) + gated_hidden_states = gated_hidden_states.permute(0, 2, 1, 3) + + # 2) project hidden states + relative_position_proj = self.gru_rel_pos_linear(gated_hidden_states) + relative_position_proj = relative_position_proj.view(gated_hidden_states.shape[:-1] + (2, 4)).sum(-1) + + # 3) compute gate for position bias from projected hidden states + gate_a, gate_b = torch.sigmoid(relative_position_proj).chunk(2, dim=-1) + gate_output = gate_a * (gate_b * self.gru_rel_pos_const - 1.0) + 2.0 + + # 4) apply gate to position bias to compute gated position_bias + gated_position_bias = gate_output.view(bsz * self.num_heads, -1, 1) * position_bias + gated_position_bias = gated_position_bias.view((-1, tgt_len, tgt_len)) + + attn_output, attn_weights = self.torch_multi_head_self_attention( + hidden_states, attention_mask, gated_position_bias, output_attentions + ) + + return attn_output, attn_weights, position_bias + + def torch_multi_head_self_attention( + self, + hidden_states: torch.FloatTensor, + attention_mask: Union[torch.LongTensor, torch.BoolTensor], + gated_position_bias: torch.FloatTensor, + output_attentions: bool, + ) -> (torch.FloatTensor, torch.FloatTensor): + """simple wrapper around torch's multi_head_attention_forward function""" + # self-attention assumes q = k = v + query = key = value = hidden_states.transpose(0, 1) + key_padding_mask = attention_mask.ne(1) if attention_mask is not None else None + + # disable bias and add_zero_attn + bias_k = bias_v = None + add_zero_attn = False + + # PyTorch 1.3.0 has F.multi_head_attention_forward defined + # so no problem with backwards compatibility + attn_output, attn_weights = F.multi_head_attention_forward( + query, + key, + value, + self.embed_dim, + self.num_heads, + torch.empty([0]), + torch.cat((self.q_proj.bias, self.k_proj.bias, self.v_proj.bias)), + bias_k, + bias_v, + add_zero_attn, + self.dropout, + self.out_proj.weight, + self.out_proj.bias, + self.training, + key_padding_mask, + output_attentions, + gated_position_bias, + use_separate_proj_weight=True, + q_proj_weight=self.q_proj.weight, + k_proj_weight=self.k_proj.weight, + v_proj_weight=self.v_proj.weight, + ) + + # [Seq_Len, Batch Size, ...] -> [Batch Size, Seq_Len, ...] + attn_output = attn_output.transpose(0, 1) + + if attn_weights is not None: + # IMPORTANT: Attention weights are averaged weights + # here which should not be the case. This is an open issue + # on PyTorch: https://github.com/pytorch/pytorch/issues/32590 + attn_weights = attn_weights[:, None].broadcast_to( + attn_weights.shape[:1] + (self.num_heads,) + attn_weights.shape[1:] + ) + + return attn_output, attn_weights + + def compute_bias(self, query_length: int, key_length: int) -> torch.FloatTensor: + context_position = torch.arange(query_length, dtype=torch.long)[:, None] + memory_position = torch.arange(key_length, dtype=torch.long)[None, :] + relative_position = memory_position - context_position + relative_position_bucket = self._relative_positions_bucket(relative_position) + relative_position_bucket = relative_position_bucket.to(self.rel_attn_embed.weight.device) + values = self.rel_attn_embed(relative_position_bucket) + values = values.permute([2, 0, 1]) + return values + + def _relative_positions_bucket(self, relative_positions: torch.FloatTensor) -> torch.FloatTensor: + num_buckets = self.num_buckets // 2 + + relative_buckets = (relative_positions > 0).to(torch.long) * num_buckets + relative_positions = torch.abs(relative_positions) + + max_exact = num_buckets // 2 + is_small = relative_positions < max_exact + + relative_positions_if_large = torch.log(relative_positions.float() / max_exact) + relative_positions_if_large = relative_positions_if_large / math.log(self.max_distance / max_exact) + relative_positions_if_large = relative_positions_if_large * (num_buckets - max_exact) + relative_position_if_large = (max_exact + relative_positions_if_large).to(torch.long) + relative_position_if_large = torch.min( + relative_position_if_large, torch.full_like(relative_position_if_large, num_buckets - 1) + ) + + relative_buckets += torch.where(is_small, relative_positions, relative_position_if_large) + return relative_buckets + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2FeedForward with Wav2Vec2->WavLM +class WavLMFeedForward(nn.Module): + def __init__(self, config): + super().__init__() + self.intermediate_dropout = nn.Dropout(config.activation_dropout) + + self.intermediate_dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + self.output_dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.output_dropout = nn.Dropout(config.hidden_dropout) + + def forward(self, hidden_states): + hidden_states = self.intermediate_dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + hidden_states = self.intermediate_dropout(hidden_states) + + hidden_states = self.output_dense(hidden_states) + hidden_states = self.output_dropout(hidden_states) + return hidden_states + + +class WavLMEncoderLayer(nn.Module): + def __init__(self, config: WavLMConfig, has_relative_position_bias: bool = True): + super().__init__() + self.attention = WavLMAttention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + num_buckets=config.num_buckets, + max_distance=config.max_bucket_distance, + has_relative_position_bias=has_relative_position_bias, + ) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.feed_forward = WavLMFeedForward(config) + self.final_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states, attention_mask=None, position_bias=None, output_attentions=False, index=0): + attn_residual = hidden_states + hidden_states, attn_weights, position_bias = self.attention( + hidden_states, + attention_mask=attention_mask, + position_bias=position_bias, + output_attentions=output_attentions, + index=index, + ) + hidden_states = self.dropout(hidden_states) + hidden_states = attn_residual + hidden_states + + hidden_states = self.layer_norm(hidden_states) + + hidden_states = hidden_states + self.feed_forward(hidden_states) + hidden_states = self.final_layer_norm(hidden_states) + + outputs = (hidden_states, position_bias) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class WavLMEncoderLayerStableLayerNorm(nn.Module): + def __init__(self, config: WavLMConfig, has_relative_position_bias: bool = True): + super().__init__() + self.attention = WavLMAttention( + embed_dim=config.hidden_size, + num_heads=config.num_attention_heads, + dropout=config.attention_dropout, + num_buckets=config.num_buckets, + max_distance=config.max_bucket_distance, + has_relative_position_bias=has_relative_position_bias, + ) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.feed_forward = WavLMFeedForward(config) + self.final_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states, attention_mask=None, position_bias=None, output_attentions=False): + attn_residual = hidden_states + hidden_states = self.layer_norm(hidden_states) + hidden_states, attn_weights, position_bias = self.attention( + hidden_states, + attention_mask=attention_mask, + position_bias=position_bias, + output_attentions=output_attentions, + ) + hidden_states = self.dropout(hidden_states) + hidden_states = attn_residual + hidden_states + hidden_states = hidden_states + self.feed_forward(self.final_layer_norm(hidden_states)) + + outputs = (hidden_states, position_bias) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class WavLMEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.pos_conv_embed = WavLMPositionalConvEmbedding(config) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layers = nn.ModuleList( + [WavLMEncoderLayer(config, has_relative_position_bias=(i == 0)) for i in range(config.num_hidden_layers)] + ) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + # make sure padded tokens output 0 + hidden_states[~attention_mask] = 0.0 + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.layer_norm(hidden_states) + hidden_states = self.dropout(hidden_states) + + deepspeed_zero3_is_enabled = is_deepspeed_zero3_enabled() + position_bias = None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + + skip_the_layer = self.training and i > 0 and (dropout_probability < self.config.layerdrop) + if not skip_the_layer or deepspeed_zero3_is_enabled: + # under deepspeed zero3 all gpus must run in sync + if self.gradient_checkpointing and self.training: + # create gradient checkpointing function + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer), + hidden_states, + attention_mask, + position_bias, + ) + else: + layer_outputs = layer( + hidden_states, + attention_mask=attention_mask, + position_bias=position_bias, + output_attentions=output_attentions, + index=i, + ) + + hidden_states, position_bias = layer_outputs[:2] + + if skip_the_layer: + layer_outputs = (None, None) + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class WavLMEncoderStableLayerNorm(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.pos_conv_embed = WavLMPositionalConvEmbedding(config) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout) + self.layers = nn.ModuleList( + [ + WavLMEncoderLayerStableLayerNorm(config, has_relative_position_bias=(i == 0)) + for i in range(config.num_hidden_layers) + ] + ) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if attention_mask is not None: + # make sure padded tokens are not attended to + hidden_states[~attention_mask] = 0 + + position_embeddings = self.pos_conv_embed(hidden_states) + hidden_states = hidden_states + position_embeddings + hidden_states = self.dropout(hidden_states) + + deepspeed_zero3_is_enabled = is_deepspeed_zero3_enabled() + position_bias = None + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = np.random.uniform(0, 1) + + skip_the_layer = self.training and i > 0 and (dropout_probability < self.config.layerdrop) + if not skip_the_layer or deepspeed_zero3_is_enabled: + # under deepspeed zero3 all gpus must run in sync + # XXX: could optimize this like synced_gpus in generate_utils but not sure if it's worth the code complication + if self.gradient_checkpointing and self.training: + # create gradient checkpointing function + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer), + hidden_states, + attention_mask, + position_bias, + ) + else: + layer_outputs = layer( + hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + position_bias=position_bias, + ) + hidden_states, position_bias = layer_outputs[:2] + + if skip_the_layer: + layer_outputs = (None, None) + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[2],) + + hidden_states = self.layer_norm(hidden_states) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_self_attentions + ) + + +class WavLMGumbelVectorQuantizer(nn.Module): + """ + Vector quantization using gumbel softmax. See [CATEGORICAL REPARAMETERIZATION WITH + GUMBEL-SOFTMAX](https://arxiv.org/pdf/1611.01144.pdf) for more information. + """ + + def __init__(self, config): + super().__init__() + self.num_groups = config.num_codevector_groups + self.num_vars = config.num_codevectors_per_group + + if config.codevector_dim % self.num_groups != 0: + raise ValueError( + f"`config.codevector_dim {config.codevector_dim} must be divisible" + f" by `config.num_codevector_groups` {self.num_groups} " + "for concatenation." + ) + + # storage for codebook variables (codewords) + self.codevectors = nn.Parameter( + torch.FloatTensor(1, self.num_groups * self.num_vars, config.codevector_dim // self.num_groups) + ) + self.weight_proj = nn.Linear(config.conv_dim[-1], self.num_groups * self.num_vars) + + # can be decayed for training + self.temperature = 2 + + @staticmethod + def _compute_perplexity(probs): + marginal_probs = probs.mean(dim=0) + perplexity = torch.exp(-torch.sum(marginal_probs * torch.log(marginal_probs + 1e-7), dim=-1)).sum() + return perplexity + + def forward(self, hidden_states): + batch_size, sequence_length, hidden_size = hidden_states.shape + + # project to codevector dim + hidden_states = self.weight_proj(hidden_states) + hidden_states = hidden_states.view(batch_size * sequence_length * self.num_groups, -1) + + if self.training: + # sample code vector probs via gumbel in differentiateable way + codevector_probs = nn.functional.gumbel_softmax(hidden_states.float(), tau=self.temperature, hard=True) + codevector_probs = codevector_probs.type_as(hidden_states) + + # compute perplexity + codevector_soft_dist = torch.softmax( + hidden_states.view(batch_size * sequence_length, self.num_groups, -1).float(), dim=-1 + ) + perplexity = self._compute_perplexity(codevector_soft_dist) + else: + # take argmax in non-differentiable way + # comptute hard codevector distribution (one hot) + codevector_idx = hidden_states.argmax(dim=-1) + codevector_probs = hidden_states.new_zeros(*hidden_states.shape).scatter_( + -1, codevector_idx.view(-1, 1), 1.0 + ) + codevector_probs = codevector_probs.view(batch_size * sequence_length, self.num_groups, -1) + + perplexity = self._compute_perplexity(codevector_probs) + + codevector_probs = codevector_probs.view(batch_size * sequence_length, -1) + # use probs to retrieve codevectors + codevectors_per_group = codevector_probs.unsqueeze(-1) * self.codevectors + codevectors = codevectors_per_group.view(batch_size * sequence_length, self.num_groups, self.num_vars, -1) + codevectors = codevectors.sum(-2).view(batch_size, sequence_length, -1) + + return codevectors, perplexity + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Adapter with Wav2Vec2->WavLM +class WavLMAdapter(nn.Module): + def __init__(self, config): + super().__init__() + + # feature dim might need to be down-projected + if config.output_hidden_size != config.hidden_size: + self.proj = nn.Linear(config.hidden_size, config.output_hidden_size) + self.proj_layer_norm = nn.LayerNorm(config.output_hidden_size) + else: + self.proj = self.proj_layer_norm = None + + self.layers = nn.ModuleList(WavLMAdapterLayer(config) for _ in range(config.num_adapter_layers)) + self.layerdrop = config.layerdrop + + def forward(self, hidden_states): + # down project hidden_states if necessary + if self.proj is not None and self.proj_layer_norm is not None: + hidden_states = self.proj(hidden_states) + hidden_states = self.proj_layer_norm(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + + for layer in self.layers: + layerdrop_prob = np.random.random() + if not self.training or (layerdrop_prob > self.layerdrop): + hidden_states = layer(hidden_states) + + hidden_states = hidden_states.transpose(1, 2) + return hidden_states + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2AdapterLayer with Wav2Vec2->WavLM +class WavLMAdapterLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.conv = nn.Conv1d( + config.output_hidden_size, + 2 * config.output_hidden_size, + config.adapter_kernel_size, + stride=config.adapter_stride, + padding=1, + ) + + def forward(self, hidden_states): + hidden_states = self.conv(hidden_states) + hidden_states = nn.functional.glu(hidden_states, dim=1) + + return hidden_states + + +class WavLMPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = WavLMConfig + base_model_prefix = "wavlm" + main_input_name = "input_values" + _keys_to_ignore_on_load_missing = [r"position_ids"] + supports_gradient_checkpointing = True + + def _init_weights(self, module): + """Initialize the weights""" + # gumbel softmax requires special init + if isinstance(module, WavLMGumbelVectorQuantizer): + module.weight_proj.weight.data.normal_(mean=0.0, std=1) + module.weight_proj.bias.data.zero_() + nn.init.uniform_(module.codevectors) + elif isinstance(module, WavLMPositionalConvEmbedding): + nn.init.normal_( + module.conv.weight, + mean=0, + std=2 * math.sqrt(1 / (module.conv.kernel_size[0] * module.conv.in_channels)), + ) + nn.init.constant_(module.conv.bias, 0) + elif isinstance(module, WavLMFeatureProjection): + k = math.sqrt(1 / module.projection.in_features) + nn.init.uniform_(module.projection.weight, a=-k, b=k) + nn.init.uniform_(module.projection.bias, a=-k, b=k) + elif isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, nn.Conv1d): + nn.init.kaiming_normal_(module.weight) + + if module.bias is not None: + k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0])) + nn.init.uniform_(module.bias, a=-k, b=k) + + def _get_feat_extract_output_lengths( + self, input_lengths: Union[torch.LongTensor, int], add_adapter: Optional[bool] = None + ): + """ + Computes the output length of the convolutional layers + """ + + add_adapter = self.config.add_adapter if add_adapter is None else add_adapter + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return torch.div(input_length - kernel_size, stride, rounding_mode="floor") + 1 + + for kernel_size, stride in zip(self.config.conv_kernel, self.config.conv_stride): + input_lengths = _conv_out_length(input_lengths, kernel_size, stride) + + if add_adapter: + for _ in range(self.config.num_adapter_layers): + input_lengths = _conv_out_length(input_lengths, 1, self.config.adapter_stride) + + return input_lengths + + def _get_feature_vector_attention_mask( + self, feature_vector_length: int, attention_mask: torch.LongTensor, add_adapter=None + ): + # Effectively attention_mask.sum(-1), but not inplace to be able to run + # on inference mode. + non_padded_lengths = attention_mask.cumsum(dim=-1)[:, -1] + + output_lengths = self._get_feat_extract_output_lengths(non_padded_lengths, add_adapter=add_adapter) + output_lengths = output_lengths.to(torch.long) + + batch_size = attention_mask.shape[0] + + attention_mask = torch.zeros( + (batch_size, feature_vector_length), dtype=attention_mask.dtype, device=attention_mask.device + ) + # these two operations makes sure that all values before the output lengths idxs are attended to + attention_mask[(torch.arange(attention_mask.shape[0], device=attention_mask.device), output_lengths - 1)] = 1 + attention_mask = attention_mask.flip([-1]).cumsum(-1).flip([-1]).bool() + return attention_mask + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (WavLMEncoder, WavLMEncoderStableLayerNorm, WavLMFeatureEncoder)): + module.gradient_checkpointing = value + + +WAVLM_START_DOCSTRING = r""" + WavLM was proposed in [WavLM: Unified Speech Representation Learning with Labeled and Unlabeled + Data](https://arxiv.org/abs/2101.07597) by Chengyi Wang, Yu Wu, Yao Qian, Kenichi Kumatani, Shujie Liu, Furu Wei, + Michael Zeng, Xuedong Huang. + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving etc.). + + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`WavLMConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + + +WAVLM_INPUTS_DOCSTRING = r""" + Args: + input_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)`): + Float values of input raw speech waveform. Values can be obtained by loading a `.flac` or `.wav` audio file + into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via the soundfile library (`pip install + soundfile`). To prepare the array into `input_values`, the [`AutoProcessor`] should be used for padding and + conversion into a tensor of type `torch.FloatTensor`. See [`Wav2Vec2Processor.__call__`] for details. + attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing convolution and attention on padding token indices. Mask values selected in `[0, + 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + + + + `attention_mask` should only be passed if the corresponding processor has `config.return_attention_mask == + True`. For all models whose processor has `config.return_attention_mask == False`, `attention_mask` should + **not** be passed to avoid degraded performance when doing batched inference. For such models + `input_values` should simply be padded with 0 and passed without `attention_mask`. Be aware that these + models also yield slightly different results depending on whether `input_values` is padded or not. + + + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare WavLM Model transformer outputting raw hidden-states without any specific head on top.", + WAVLM_START_DOCSTRING, +) +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2Model with Wav2Vec2->WavLM, wav2vec2->wavlm, WAV_2_VEC_2->WAVLM, WavLMBaseModelOutput->Wav2Vec2BaseModelOutput +class WavLMModel(WavLMPreTrainedModel): + def __init__(self, config: WavLMConfig): + super().__init__(config) + self.config = config + self.feature_extractor = WavLMFeatureEncoder(config) + self.feature_projection = WavLMFeatureProjection(config) + + # model only needs masking vector if mask prob is > 0.0 + if config.mask_time_prob > 0.0 or config.mask_feature_prob > 0.0: + self.masked_spec_embed = nn.Parameter(torch.FloatTensor(config.hidden_size).uniform_()) + + if config.do_stable_layer_norm: + self.encoder = WavLMEncoderStableLayerNorm(config) + else: + self.encoder = WavLMEncoder(config) + + self.adapter = WavLMAdapter(config) if config.add_adapter else None + + # Initialize weights and apply final processing + self.post_init() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.feature_extractor._freeze_parameters() + + def _mask_hidden_states( + self, + hidden_states: torch.FloatTensor, + mask_time_indices: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.LongTensor] = None, + ): + """ + Masks extracted features along time axis and/or along feature axis according to + [SpecAugment](https://arxiv.org/abs/1904.08779). + """ + + # `config.apply_spec_augment` can set masking to False + if not getattr(self.config, "apply_spec_augment", True): + return hidden_states + + # generate indices & apply SpecAugment along time axis + batch_size, sequence_length, hidden_size = hidden_states.size() + + if mask_time_indices is not None: + # apply SpecAugment along time axis with given mask_time_indices + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + elif self.config.mask_time_prob > 0 and self.training: + mask_time_indices = _compute_mask_indices( + (batch_size, sequence_length), + mask_prob=self.config.mask_time_prob, + mask_length=self.config.mask_time_length, + attention_mask=attention_mask, + min_masks=self.config.mask_time_min_masks, + ) + mask_time_indices = torch.tensor(mask_time_indices, device=hidden_states.device, dtype=torch.bool) + hidden_states[mask_time_indices] = self.masked_spec_embed.to(hidden_states.dtype) + + if self.config.mask_feature_prob > 0 and self.training: + # generate indices & apply SpecAugment along feature axis + mask_feature_indices = _compute_mask_indices( + (batch_size, hidden_size), + mask_prob=self.config.mask_feature_prob, + mask_length=self.config.mask_feature_length, + min_masks=self.config.mask_feature_min_masks, + ) + mask_feature_indices = torch.tensor(mask_feature_indices, device=hidden_states.device, dtype=torch.bool) + mask_feature_indices = mask_feature_indices[:, None].expand(-1, sequence_length, -1) + hidden_states[mask_feature_indices] = 0 + + return hidden_states + + @add_start_docstrings_to_model_forward(WAVLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=Wav2Vec2BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + mask_time_indices: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, Wav2Vec2BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + extract_features = self.feature_extractor(input_values) + extract_features = extract_features.transpose(1, 2) + + if attention_mask is not None: + # compute reduced attention_mask corresponding to feature vectors + attention_mask = self._get_feature_vector_attention_mask( + extract_features.shape[1], attention_mask, add_adapter=False + ) + + hidden_states, extract_features = self.feature_projection(extract_features) + hidden_states = self._mask_hidden_states( + hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask + ) + + encoder_outputs = self.encoder( + hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = encoder_outputs[0] + + if self.adapter is not None: + hidden_states = self.adapter(hidden_states) + + if not return_dict: + return (hidden_states, extract_features) + encoder_outputs[1:] + + return Wav2Vec2BaseModelOutput( + last_hidden_state=hidden_states, + extract_features=extract_features, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + """WavLM Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).""", + WAVLM_START_DOCSTRING, +) +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForCTC with Wav2Vec2->WavLM, wav2vec2->wavlm, WAV_2_VEC_2->WAVLM +class WavLMForCTC(WavLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.wavlm = WavLMModel(config) + self.dropout = nn.Dropout(config.final_dropout) + + if config.vocab_size is None: + raise ValueError( + f"You are trying to instantiate {self.__class__} with a configuration that " + "does not define the vocabulary size of the language model head. Please " + "instantiate the model as follows: `WavLMForCTC.from_pretrained(..., vocab_size=vocab_size)`. " + "or define `vocab_size` of your model's configuration." + ) + output_hidden_size = ( + config.output_hidden_size if hasattr(config, "add_adapter") and config.add_adapter else config.hidden_size + ) + self.lm_head = nn.Linear(output_hidden_size, config.vocab_size) + + # Initialize weights and apply final processing + self.post_init() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wavlm.feature_extractor._freeze_parameters() + + @add_start_docstrings_to_model_forward(WAVLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=CausalLMOutput, + config_class=_CONFIG_FOR_DOC, + expected_output=_CTC_EXPECTED_OUTPUT, + expected_loss=_CTC_EXPECTED_LOSS, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, CausalLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, target_length)`, *optional*): + Labels for connectionist temporal classification. Note that `target_length` has to be smaller or equal to + the sequence length of the output logits. Indices are selected in `[-100, 0, ..., config.vocab_size - 1]`. + All labels set to `-100` are ignored (masked), the loss is only computed for labels in `[0, ..., + config.vocab_size - 1]`. + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.wavlm( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states) + + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + if labels.max() >= self.config.vocab_size: + raise ValueError(f"Label values must be <= vocab_size: {self.config.vocab_size}") + + # retrieve loss input_lengths from attention_mask + attention_mask = ( + attention_mask if attention_mask is not None else torch.ones_like(input_values, dtype=torch.long) + ) + input_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(-1)).to(torch.long) + + # assuming that padded tokens are filled with -100 + # when not being attended to + labels_mask = labels >= 0 + target_lengths = labels_mask.sum(-1) + flattened_targets = labels.masked_select(labels_mask) + + # ctc_loss doesn't support fp16 + log_probs = nn.functional.log_softmax(logits, dim=-1, dtype=torch.float32).transpose(0, 1) + + with torch.backends.cudnn.flags(enabled=False): + loss = nn.functional.ctc_loss( + log_probs, + flattened_targets, + input_lengths, + target_lengths, + blank=self.config.pad_token_id, + reduction=self.config.ctc_loss_reduction, + zero_infinity=self.config.ctc_zero_infinity, + ) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return CausalLMOutput( + loss=loss, logits=logits, hidden_states=outputs.hidden_states, attentions=outputs.attentions + ) + + +@add_start_docstrings( + """ + WavLM Model with a sequence classification head on top (a linear layer over the pooled output) for tasks like + SUPERB Keyword Spotting. + """, + WAVLM_START_DOCSTRING, +) +class WavLMForSequenceClassification(WavLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Sequence classification does not support the use of WavLM adapters (config.add_adapter=True)" + ) + self.wavlm = WavLMModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.classifier_proj_size) + self.classifier = nn.Linear(config.classifier_proj_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.freeze_feature_extractor + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameters will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.freeze_feature_encoder with wav2vec2->wavlm + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wavlm.feature_extractor._freeze_parameters() + + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.freeze_base_model with wav2vec2->wavlm + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wavlm.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAVLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + ) + # Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForSequenceClassification.forward with Wav2Vec2->WavLM, wav2vec2->wavlm + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wavlm( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + if attention_mask is None: + pooled_output = hidden_states.mean(dim=1) + else: + padding_mask = self._get_feature_vector_attention_mask(hidden_states.shape[1], attention_mask) + hidden_states[~padding_mask] = 0.0 + pooled_output = hidden_states.sum(dim=1) / padding_mask.sum(dim=1).view(-1, 1) + + logits = self.classifier(pooled_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + WavLM Model with a frame classification head on top for tasks like Speaker Diarization. + """, + WAVLM_START_DOCSTRING, +) +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForAudioFrameClassification with Wav2Vec2->WavLM, wav2vec2->wavlm, WAV_2_VEC_2->WAVLM +class WavLMForAudioFrameClassification(WavLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + if hasattr(config, "add_adapter") and config.add_adapter: + raise ValueError( + "Audio frame classification does not support the use of WavLM adapters (config.add_adapter=True)" + ) + self.wavlm = WavLMModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + self.num_labels = config.num_labels + + self.init_weights() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wavlm.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wavlm.parameters(): + param.requires_grad = False + + @add_start_docstrings_to_model_forward(WAVLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_FRAME_CLASS_CHECKPOINT, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_FRAME_EXPECTED_OUTPUT, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wavlm( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + logits = self.classifier(hidden_states) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), torch.argmax(labels.view(-1, self.num_labels), axis=1)) + + if not return_dict: + output = (logits,) + outputs[_HIDDEN_STATES_START_POSITION:] + return output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.AMSoftmaxLoss +class AMSoftmaxLoss(nn.Module): + def __init__(self, input_dim, num_labels, scale=30.0, margin=0.4): + super(AMSoftmaxLoss, self).__init__() + self.scale = scale + self.margin = margin + self.num_labels = num_labels + self.weight = nn.Parameter(torch.randn(input_dim, num_labels), requires_grad=True) + self.loss = nn.CrossEntropyLoss() + + def forward(self, hidden_states, labels): + labels = labels.flatten() + weight = nn.functional.normalize(self.weight, dim=0) + hidden_states = nn.functional.normalize(hidden_states, dim=1) + cos_theta = torch.mm(hidden_states, weight) + psi = cos_theta - self.margin + + onehot = nn.functional.one_hot(labels, self.num_labels) + logits = self.scale * torch.where(onehot.bool(), psi, cos_theta) + loss = self.loss(logits, labels) + + return loss + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.TDNNLayer +class TDNNLayer(nn.Module): + def __init__(self, config, layer_id=0): + super().__init__() + self.in_conv_dim = config.tdnn_dim[layer_id - 1] if layer_id > 0 else config.tdnn_dim[layer_id] + self.out_conv_dim = config.tdnn_dim[layer_id] + self.kernel_size = config.tdnn_kernel[layer_id] + self.dilation = config.tdnn_dilation[layer_id] + + self.kernel = nn.Linear(self.in_conv_dim * self.kernel_size, self.out_conv_dim) + self.activation = nn.ReLU() + + def forward(self, hidden_states): + hidden_states = hidden_states.unsqueeze(1) + hidden_states = nn.functional.unfold( + hidden_states, + (self.kernel_size, self.in_conv_dim), + stride=(1, self.in_conv_dim), + dilation=(self.dilation, 1), + ) + hidden_states = hidden_states.transpose(1, 2) + hidden_states = self.kernel(hidden_states) + + hidden_states = self.activation(hidden_states) + return hidden_states + + +@add_start_docstrings( + """ + WavLM Model with an XVector feature extraction head on top for tasks like Speaker Verification. + """, + WAVLM_START_DOCSTRING, +) +# Copied from transformers.models.wav2vec2.modeling_wav2vec2.Wav2Vec2ForXVector with Wav2Vec2->WavLM, wav2vec2->wavlm, WAV_2_VEC_2->WAVLM +class WavLMForXVector(WavLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.wavlm = WavLMModel(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.tdnn_dim[0]) + + tdnn_layers = [TDNNLayer(config, i) for i in range(len(config.tdnn_dim))] + self.tdnn = nn.ModuleList(tdnn_layers) + + self.feature_extractor = nn.Linear(config.tdnn_dim[-1] * 2, config.xvector_output_dim) + self.classifier = nn.Linear(config.xvector_output_dim, config.xvector_output_dim) + + self.objective = AMSoftmaxLoss(config.xvector_output_dim, config.num_labels) + + self.init_weights() + + def freeze_feature_extractor(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + warnings.warn( + "The method `freeze_feature_extractor` is deprecated and will be removed in Transformers v5." + "Please use the equivalent `freeze_feature_encoder` method instead.", + FutureWarning, + ) + self.freeze_feature_encoder() + + def freeze_feature_encoder(self): + """ + Calling this function will disable the gradient computation for the feature encoder so that its parameter will + not be updated during training. + """ + self.wavlm.feature_extractor._freeze_parameters() + + def freeze_base_model(self): + """ + Calling this function will disable the gradient computation for the base model so that its parameters will not + be updated during training. Only the classification head will be updated. + """ + for param in self.wavlm.parameters(): + param.requires_grad = False + + def _get_tdnn_output_lengths(self, input_lengths: Union[torch.LongTensor, int]): + """ + Computes the output length of the TDNN layers + """ + + def _conv_out_length(input_length, kernel_size, stride): + # 1D convolutional layer output length formula taken + # from https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html + return (input_length - kernel_size) // stride + 1 + + for kernel_size in self.config.tdnn_kernel: + input_lengths = _conv_out_length(input_lengths, kernel_size, 1) + + return input_lengths + + @add_start_docstrings_to_model_forward(WAVLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_XVECTOR_CHECKPOINT, + output_type=XVectorOutput, + config_class=_CONFIG_FOR_DOC, + modality="audio", + expected_output=_XVECTOR_EXPECTED_OUTPUT, + ) + def forward( + self, + input_values: Optional[torch.Tensor], + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[torch.Tensor] = None, + ) -> Union[Tuple, XVectorOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + output_hidden_states = True if self.config.use_weighted_layer_sum else output_hidden_states + + outputs = self.wavlm( + input_values, + attention_mask=attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = outputs[_HIDDEN_STATES_START_POSITION] + hidden_states = torch.stack(hidden_states, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = outputs[0] + + hidden_states = self.projector(hidden_states) + + for tdnn_layer in self.tdnn: + hidden_states = tdnn_layer(hidden_states) + + # Statistic Pooling + if attention_mask is None: + mean_features = hidden_states.mean(dim=1) + std_features = hidden_states.std(dim=1) + else: + feat_extract_output_lengths = self._get_feat_extract_output_lengths(attention_mask.sum(dim=1)) + tdnn_output_lengths = self._get_tdnn_output_lengths(feat_extract_output_lengths) + mean_features = [] + std_features = [] + for i, length in enumerate(tdnn_output_lengths): + mean_features.append(hidden_states[i, :length].mean(dim=0)) + std_features.append(hidden_states[i, :length].std(dim=0)) + mean_features = torch.stack(mean_features) + std_features = torch.stack(std_features) + statistic_pooling = torch.cat([mean_features, std_features], dim=-1) + + output_embeddings = self.feature_extractor(statistic_pooling) + logits = self.classifier(output_embeddings) + + loss = None + if labels is not None: + loss = self.objective(logits, labels) + + if not return_dict: + output = (logits, output_embeddings) + outputs[_HIDDEN_STATES_START_POSITION:] + return ((loss,) + output) if loss is not None else output + + return XVectorOutput( + loss=loss, + logits=logits, + embeddings=output_embeddings, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cd962478e34daa35ec2cd9884a6acb412e7b68c6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/__init__.py @@ -0,0 +1,139 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_whisper": ["WHISPER_PRETRAINED_CONFIG_ARCHIVE_MAP", "WhisperConfig", "WhisperOnnxConfig"], + "feature_extraction_whisper": ["WhisperFeatureExtractor"], + "processing_whisper": ["WhisperProcessor"], + "tokenization_whisper": ["WhisperTokenizer"], +} + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_whisper_fast"] = ["WhisperTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_whisper"] = [ + "WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST", + "WhisperForConditionalGeneration", + "WhisperModel", + "WhisperPreTrainedModel", + "WhisperForAudioClassification", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_whisper"] = [ + "TF_WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFWhisperForConditionalGeneration", + "TFWhisperModel", + "TFWhisperPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_whisper"] = [ + "FlaxWhisperForConditionalGeneration", + "FlaxWhisperModel", + "FlaxWhisperPreTrainedModel", + "FlaxWhisperForAudioClassification", + ] + + +if TYPE_CHECKING: + from .configuration_whisper import WHISPER_PRETRAINED_CONFIG_ARCHIVE_MAP, WhisperConfig, WhisperOnnxConfig + from .feature_extraction_whisper import WhisperFeatureExtractor + from .processing_whisper import WhisperProcessor + from .tokenization_whisper import WhisperTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_whisper_fast import WhisperTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_whisper import ( + WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST, + WhisperForAudioClassification, + WhisperForConditionalGeneration, + WhisperModel, + WhisperPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_whisper import ( + TF_WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST, + TFWhisperForConditionalGeneration, + TFWhisperModel, + TFWhisperPreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_whisper import ( + FlaxWhisperForAudioClassification, + FlaxWhisperForConditionalGeneration, + FlaxWhisperModel, + FlaxWhisperPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/configuration_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/configuration_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..3fe936fccf345cc600afbe9354108aa6f9bb5f5f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/configuration_whisper.py @@ -0,0 +1,336 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Whisper model configuration""" + +from collections import OrderedDict +from typing import TYPE_CHECKING, Any, Mapping, Optional, Union + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig, OnnxSeq2SeqConfigWithPast +from ...utils import logging + + +if TYPE_CHECKING: + from ...feature_extraction_utils import FeatureExtractionMixin + from ...tokenization_utils_base import PreTrainedTokenizerBase + from ...utils import TensorType + +logger = logging.get_logger(__name__) + +WHISPER_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/config.json", +} + +# fmt: off +NON_SPEECH_TOKENS = [ + 1, 2, 7, 8, 9, 10, 14, 25, + 26, 27, 28, 29, 31, 58, 59, 60, 61, 62, + 63, 90, 91, 92, 93, 357, 366, 438, 532, 685, + 705, 796, 930, 1058, 1220, 1267, 1279, 1303, 1343, 1377, + 1391, 1635, 1782, 1875, 2162, 2361, 2488, 3467, 4008, 4211, + 4600, 4808, 5299, 5855, 6329, 7203, 9609, 9959, 10563, 10786, + 11420, 11709, 11907, 13163, 13697, 13700, 14808, 15306, 16410, 16791, + 17992, 19203, 19510, 20724, 22305, 22935, 27007, 30109, 30420, 33409, + 34949, 40283, 40493, 40549, 47282, 49146, 50257, 50359, 50360, 50361 +] +NON_SPEECH_TOKENS_MULTI = [ + 1, 2, 7, 8, 9, 10, 14, 25, + 26, 27, 28, 29, 31, 58, 59, 60, 61, 62, + 63, 90, 91, 92, 93, 359, 503, 522, 542, 873, + 893, 902, 918, 922, 931, 1350, 1853, 1982, 2460, 2627, + 3246, 3253, 3268, 3536, 3846, 3961, 4183, 4667, 6585, 6647, + 7273, 9061, 9383, 10428, 10929, 11938, 12033, 12331, 12562, 13793, + 14157, 14635, 15265, 15618, 16553, 16604, 18362, 18956, 20075, 21675, + 22520, 26130, 26161, 26435, 28279, 29464, 31650, 32302, 32470, 36865, + 42863, 47425, 49870, 50254, 50258, 50360, 50361, 50362 +] +# fmt: on + + +class WhisperConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`WhisperModel`]. It is used to instantiate a + Whisper model according to the specified arguments, defining the model architecture. Instantiating a configuration + with the defaults will yield a similar configuration to that of the Whisper + [openai/whisper-tiny](https://huggingface.co/openai/whisper-tiny) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 51865): + Vocabulary size of the Whisper model. Defines the number of different tokens that can be represented by the + `decoder_input_ids` passed when calling [`WhisperModel`] + num_mel_bins (`int`, *optional*, defaults to 80): + Number of mel features used per input features. Should correspond to the value used in the + `WhisperProcessor` class. + encoder_layers (`int`, *optional*, defaults to 6): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 6): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 4): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 4): + Number of attention heads for each attention layer in the Transformer decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 1536): + Dimensionality of the "intermediate" (often named feed-forward) layer in encoder. + decoder_ffn_dim (`int`, *optional*, defaults to 1536): + Dimensionality of the "intermediate" (often named feed-forward) layer in decoder. + encoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + decoder_layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the decoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + decoder_start_token_id (`int`, *optional*, defaults to 50257): + Corresponds to the "<|startoftranscript|>" token, which is automatically used when no `decoder_input_ids` + are provided to the `generate` function. It is used to guide the model`s generation process depending on + the task. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + is_encoder_decoder (`bool`, *optional*, defaults to `True`): + Whether the model is used as an encoder/decoder or not. + activation_function (`str`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + d_model (`int`, *optional*, defaults to 256): + Dimensionality of the layers. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + scale_embedding (`bool`, *optional*, defaults to False): + Scale embeddings by diving by sqrt(d_model). + max_source_positions (`int`, *optional*, defaults to 1500): + The maximum sequence length of log-mel filter-bank features that this model might ever be used with. + max_target_positions (`int`, *optional*, defaults to 448): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + pad_token_id (`int`, *optional*, defaults to 50256): + Padding token id. + bos_token_id (`int`, *optional*, defaults to 50256): + Begin of stream token id. + eos_token_id (`int`, *optional*, defaults to 50257): + End of stream token id. + suppress_tokens (`List[int]`, *optional*): + A list containing the non-speech tokens that will be used by the logit processor in the `generate` + function. NON_SPEECH_TOKENS and NON_SPEECH_TOKENS_MULTI each correspond to the `english-only` and the + `multilingual` model. + begin_suppress_tokens (`List[int]`, *optional*, defaults to `[220,50256]`): + A list containing tokens that will be supressed at the beginning of the sampling process. Initialized as + the token for `" "` (`blank_token_id`) and the `eos_token_id` + use_weighted_layer_sum (`bool`, *optional*, defaults to `False`): + Whether to use a weighted average of layer outputs with learned weights. Only relevant when using an + instance of [`WhisperForAudioClassification`]. + classifier_proj_size (`int`, *optional*, defaults to 256): + Dimensionality of the projection before token mean-pooling for classification. Only relevant when using an + instance of [`WhisperForAudioClassification`]. + apply_spec_augment (`bool`, *optional*, defaults to `False`): + Whether to apply *SpecAugment* data augmentation to the outputs of the feature encoder. For reference see + [SpecAugment: A Simple Data Augmentation Method for Automatic Speech + Recognition](https://arxiv.org/abs/1904.08779). + mask_time_prob (`float`, *optional*, defaults to 0.05): + Percentage (between 0 and 1) of all feature vectors along the time axis which will be masked. The masking + procecure generates `mask_time_prob*len(time_axis)/mask_time_length` independent masks over the axis. If + reasoning from the propability of each feature vector to be chosen as the start of the vector span to be + masked, *mask_time_prob* should be `prob_vector_start*mask_time_length`. Note that overlap may decrease the + actual percentage of masked vectors. This is only relevant if `apply_spec_augment == True`. + mask_time_length (`int`, *optional*, defaults to 10): + Length of vector span along the time axis. + mask_time_min_masks (`int`, *optional*, defaults to 2),: + The minimum number of masks of length `mask_feature_length` generated along the time axis, each time step, + irrespectively of `mask_feature_prob`. Only relevant if ''mask_time_prob*len(time_axis)/mask_time_length < + mask_time_min_masks'' + mask_feature_prob (`float`, *optional*, defaults to 0.0): + Percentage (between 0 and 1) of all feature vectors along the feature axis which will be masked. The + masking procecure generates `mask_feature_prob*len(feature_axis)/mask_time_length` independent masks over + the axis. If reasoning from the propability of each feature vector to be chosen as the start of the vector + span to be masked, *mask_feature_prob* should be `prob_vector_start*mask_feature_length`. Note that overlap + may decrease the actual percentage of masked vectors. This is only relevant if `apply_spec_augment is + True`. + mask_feature_length (`int`, *optional*, defaults to 10): + Length of vector span along the feature axis. + mask_feature_min_masks (`int`, *optional*, defaults to 0),: + The minimum number of masks of length `mask_feature_length` generated along the feature axis, each time + step, irrespectively of `mask_feature_prob`. Only relevant if + `mask_feature_prob*len(feature_axis)/mask_feature_length < mask_feature_min_masks`. + + + Example: + + ```python + >>> from transformers import WhisperConfig, WhisperModel + + >>> # Initializing a Whisper tiny style configuration + >>> configuration = WhisperConfig() + + >>> # Initializing a model (with random weights) from the tiny style configuration + >>> model = WhisperModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "whisper" + keys_to_ignore_at_inference = ["past_key_values"] + attribute_map = {"num_attention_heads": "encoder_attention_heads", "hidden_size": "d_model"} + + def __init__( + self, + vocab_size=51865, + num_mel_bins=80, + encoder_layers=6, + encoder_attention_heads=4, + decoder_layers=6, + decoder_attention_heads=4, + decoder_ffn_dim=1536, + encoder_ffn_dim=1536, + encoder_layerdrop=0.0, + decoder_layerdrop=0.0, + decoder_start_token_id=50257, + use_cache=True, + is_encoder_decoder=True, + activation_function="gelu", + d_model=256, + dropout=0.0, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + scale_embedding=False, + max_source_positions=1500, + max_target_positions=448, + pad_token_id=50256, + bos_token_id=50257, + eos_token_id=50256, + suppress_tokens=None, + begin_suppress_tokens=[220, 50256], + use_weighted_layer_sum=False, + classifier_proj_size=256, + apply_spec_augment=False, + mask_time_prob=0.05, + mask_time_length=10, + mask_time_min_masks=2, + mask_feature_prob=0.0, + mask_feature_length=10, + mask_feature_min_masks=0, + **kwargs, + ): + self.vocab_size = vocab_size + self.num_mel_bins = num_mel_bins + self.d_model = d_model + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.encoder_ffn_dim = encoder_ffn_dim + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.encoder_layerdrop = encoder_layerdrop + self.decoder_layerdrop = decoder_layerdrop + self.use_cache = use_cache + self.num_hidden_layers = encoder_layers + self.scale_embedding = scale_embedding # scale factor will be sqrt(d_model) if True + self.max_source_positions = max_source_positions + self.max_target_positions = max_target_positions + + # Audio Classification-specific parameters. Feel free to ignore for other classes. + self.classifier_proj_size = classifier_proj_size + self.use_weighted_layer_sum = use_weighted_layer_sum + + # fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779 + self.apply_spec_augment = apply_spec_augment + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.mask_time_min_masks = mask_time_min_masks + self.mask_feature_prob = mask_feature_prob + self.mask_feature_length = mask_feature_length + self.mask_feature_min_masks = mask_feature_min_masks + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + is_encoder_decoder=is_encoder_decoder, + decoder_start_token_id=decoder_start_token_id, + suppress_tokens=suppress_tokens, + begin_suppress_tokens=begin_suppress_tokens, + **kwargs, + ) + + +class WhisperOnnxConfig(OnnxSeq2SeqConfigWithPast): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + common_inputs = OrderedDict( + [ + ("input_features", {0: "batch", 1: "feature_size", 2: "encoder_sequence"}), + ] + ) + if self.use_past: + common_inputs["decoder_input_ids"] = {0: "batch"} + else: + common_inputs["decoder_input_ids"] = {0: "batch", 1: "decoder_sequence"} + + if self.use_past: + self.fill_with_past_key_values_(common_inputs, direction="inputs") + + return common_inputs + + def generate_dummy_inputs( + self, + preprocessor: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin"], + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional["TensorType"] = None, + sampling_rate: int = 22050, + time_duration: float = 5.0, + frequency: int = 220, + ) -> Mapping[str, Any]: + dummy_inputs = OrderedDict() + encoder_inputs = OnnxConfig.generate_dummy_inputs( + self, + preprocessor=preprocessor.feature_extractor, + batch_size=batch_size, + framework=framework, + sampling_rate=sampling_rate, + time_duration=time_duration, + frequency=frequency, + ) + encoder_sequence_length = encoder_inputs["input_features"].shape[2] + seq_length = encoder_sequence_length // 2 if self.use_past else seq_length + + decoder_inputs = super().generate_dummy_inputs( + preprocessor.tokenizer, batch_size, seq_length, is_pair, framework + ) + + dummy_inputs["input_features"] = encoder_inputs.pop("input_features") + dummy_inputs["decoder_input_ids"] = decoder_inputs.pop("decoder_input_ids") + + if "past_key_values" in decoder_inputs: + dummy_inputs["past_key_values"] = decoder_inputs.pop("past_key_values") + + return dummy_inputs + + @property + def atol_for_validation(self) -> float: + return 1e-3 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/convert_openai_to_hf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/convert_openai_to_hf.py new file mode 100644 index 0000000000000000000000000000000000000000..3e7d42634bad11d3d6007ceab5aec490d1daf064 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/convert_openai_to_hf.py @@ -0,0 +1,184 @@ +# Copyright 2022 The HuggingFace Inc. team and the OpenAI team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import hashlib +import os +import urllib +import warnings + +import torch +from torch import nn +from tqdm import tqdm + +from transformers import WhisperConfig, WhisperForConditionalGeneration + + +_MODELS = { + "tiny.en": "https://openaipublic.azureedge.net/main/whisper/models/d3dd57d32accea0b295c96e26691aa14d8822fac7d9d27d5dc00b4ca2826dd03/tiny.en.pt", + "tiny": "https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt", + "base.en": "https://openaipublic.azureedge.net/main/whisper/models/25a8566e1d0c1e2231d1c762132cd20e0f96a85d16145c3a00adf5d1ac670ead/base.en.pt", + "base": "https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt", + "small.en": "https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt", + "small": "https://openaipublic.azureedge.net/main/whisper/models/9ecf779972d90ba49c06d968637d720dd632c55bbf19d441fb42bf17a411e794/small.pt", + "medium.en": "https://openaipublic.azureedge.net/main/whisper/models/d7440d1dc186f76616474e0ff0b3b6b879abc9d1a4926b7adfa41db2d497ab4f/medium.en.pt", + "medium": "https://openaipublic.azureedge.net/main/whisper/models/345ae4da62f9b3d59415adc60127b97c714f32e89e936602e85993674d08dcb1/medium.pt", + "large": "https://openaipublic.azureedge.net/main/whisper/models/e4b87e7e0bf463eb8e6956e646f1e277e901512310def2c24bf0e11bd3c28e9a/large.pt", + "large-v2": "https://openaipublic.azureedge.net/main/whisper/models/81f7c96c852ee8fc832187b0132e569d6c3065a3252ed18e56effd0b6a73e524/large-v2.pt", +} + + +def remove_ignore_keys_(state_dict): + ignore_keys = ["layers", "blocks"] + for k in ignore_keys: + state_dict.pop(k, None) + + +WHISPER_MAPPING = { + "blocks": "layers", + "mlp.0": "fc1", + "mlp.2": "fc2", + "mlp_ln": "final_layer_norm", + ".attn.query": ".self_attn.q_proj", + ".attn.key": ".self_attn.k_proj", + ".attn.value": ".self_attn.v_proj", + ".attn_ln": ".self_attn_layer_norm", + ".attn.out": ".self_attn.out_proj", + ".cross_attn.query": ".encoder_attn.q_proj", + ".cross_attn.key": ".encoder_attn.k_proj", + ".cross_attn.value": ".encoder_attn.v_proj", + ".cross_attn_ln": ".encoder_attn_layer_norm", + ".cross_attn.out": ".encoder_attn.out_proj", + "decoder.ln.": "decoder.layer_norm.", + "encoder.ln.": "encoder.layer_norm.", + "token_embedding": "embed_tokens", + "encoder.positional_embedding": "encoder.embed_positions.weight", + "decoder.positional_embedding": "decoder.embed_positions.weight", + "ln_post": "layer_norm", +} + + +def rename_keys(s_dict): + keys = list(s_dict.keys()) + for key in keys: + new_key = key + for k, v in WHISPER_MAPPING.items(): + if k in key: + new_key = new_key.replace(k, v) + + print(f"{key} -> {new_key}") + + s_dict[new_key] = s_dict.pop(key) + return s_dict + + +def make_linear_from_emb(emb): + vocab_size, emb_size = emb.weight.shape + lin_layer = nn.Linear(vocab_size, emb_size, bias=False) + lin_layer.weight.data = emb.weight.data + return lin_layer + + +def _download(url: str, root: str) -> bytes: + os.makedirs(root, exist_ok=True) + filename = os.path.basename(url) + + expected_sha256 = url.split("/")[-2] + download_target = os.path.join(root, filename) + + if os.path.exists(download_target) and not os.path.isfile(download_target): + raise RuntimeError(f"{download_target} exists and is not a regular file") + + if os.path.isfile(download_target): + model_bytes = open(download_target, "rb").read() + if hashlib.sha256(model_bytes).hexdigest() == expected_sha256: + return model_bytes + else: + warnings.warn(f"{download_target} exists, but the SHA256 checksum does not match; re-downloading the file") + + with urllib.request.urlopen(url) as source, open(download_target, "wb") as output: + with tqdm( + total=int(source.info().get("Content-Length")), ncols=80, unit="iB", unit_scale=True, unit_divisor=1024 + ) as loop: + while True: + buffer = source.read(8192) + if not buffer: + break + + output.write(buffer) + loop.update(len(buffer)) + + model_bytes = open(download_target, "rb").read() + if hashlib.sha256(model_bytes).hexdigest() != expected_sha256: + raise RuntimeError( + "Model has been downloaded but the SHA256 checksum does not not match. Please retry loading the model." + ) + + return model_bytes + + +def convert_openai_whisper_to_tfms(checkpoint_path, pytorch_dump_folder_path): + if ".pt" not in checkpoint_path: + original_checkpoint = _download(_MODELS[checkpoint_path]) + else: + original_checkpoint = torch.load(checkpoint_path, map_location="cpu") + dimensions = original_checkpoint["dims"] + state_dict = original_checkpoint["model_state_dict"] + proj_out_weights = state_dict["decoder.token_embedding.weight"] + remove_ignore_keys_(state_dict) + rename_keys(state_dict) + tie_embeds = True + ffn_dim = state_dict["decoder.layers.0.fc1.weight"].shape[0] + + config = WhisperConfig( + vocab_size=dimensions["n_vocab"], + encoder_ffn_dim=ffn_dim, + decoder_ffn_dim=ffn_dim, + num_mel_bins=dimensions["n_mels"], + d_model=dimensions["n_audio_state"], + max_target_positions=dimensions["n_text_ctx"], + encoder_layers=dimensions["n_audio_layer"], + encoder_attention_heads=dimensions["n_audio_head"], + decoder_layers=dimensions["n_text_layer"], + decoder_attention_heads=dimensions["n_text_state"], + max_source_positions=dimensions["n_audio_ctx"], + ) + + model = WhisperForConditionalGeneration(config) + missing, unexpected = model.model.load_state_dict(state_dict, strict=False) + if len(missing) > 0 and not set(missing) <= { + "encoder.embed_positions.weights", + "decoder.embed_positions.weights", + }: + raise ValueError( + "Only `encoder.embed_positions.weights` and `decoder.embed_positions.weights` are allowed to be missing," + f" but all the following weights are missing {missing}" + ) + + if tie_embeds: + model.proj_out = make_linear_from_emb(model.model.decoder.embed_tokens) + else: + model.proj_out.weight.data = proj_out_weights + + model.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # # Required parameters + parser.add_argument("--checkpoint_path", type=str, help="Patht to the downloaded checkpoints") + parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.") + args = parser.parse_args() + + convert_openai_whisper_to_tfms(args.checkpoint_path, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/english_normalizer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/english_normalizer.py new file mode 100644 index 0000000000000000000000000000000000000000..7f6aab4ad29d848f5fe0e237dd7fa8b5e76fa5e0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/english_normalizer.py @@ -0,0 +1,595 @@ +# Copyright 2022 The OpenAI team and The HuggingFace Team. All rights reserved. +# Most of the code is copy pasted from the original whisper repository +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +import unicodedata +from fractions import Fraction +from typing import Iterator, List, Match, Optional, Union + +import regex + + +# non-ASCII letters that are not separated by "NFKD" normalization +ADDITIONAL_DIACRITICS = { + "œ": "oe", + "Œ": "OE", + "ø": "o", + "Ø": "O", + "æ": "ae", + "Æ": "AE", + "ß": "ss", + "ẞ": "SS", + "đ": "d", + "Đ": "D", + "ð": "d", + "Ð": "D", + "þ": "th", + "Þ": "th", + "ł": "l", + "Ł": "L", +} + + +def remove_symbols_and_diacritics(s: str, keep=""): + """ + Replace any other markers, symbols, and punctuations with a space, and drop any diacritics (category 'Mn' and some + manual mappings) + """ + + def replace_character(char): + if char in keep: + return char + elif char in ADDITIONAL_DIACRITICS: + return ADDITIONAL_DIACRITICS[char] + + elif unicodedata.category(char) == "Mn": + return "" + + elif unicodedata.category(char)[0] in "MSP": + return " " + + return char + + return "".join(replace_character(c) for c in unicodedata.normalize("NFKD", s)) + + +def remove_symbols(s: str): + """ + Replace any other markers, symbols, punctuations with a space, keeping diacritics + """ + return "".join(" " if unicodedata.category(c)[0] in "MSP" else c for c in unicodedata.normalize("NFKC", s)) + + +class BasicTextNormalizer: + def __init__(self, remove_diacritics: bool = False, split_letters: bool = False): + self.clean = remove_symbols_and_diacritics if remove_diacritics else remove_symbols + self.split_letters = split_letters + + def __call__(self, s: str): + s = s.lower() + s = re.sub(r"[<\[][^>\]]*[>\]]", "", s) # remove words between brackets + s = re.sub(r"\(([^)]+?)\)", "", s) # remove words between parenthesis + s = self.clean(s).lower() + + if self.split_letters: + s = " ".join(regex.findall(r"\X", s, regex.U)) + + s = re.sub(r"\s+", " ", s) # replace any successive whitespace characters with a space + + return s + + +class EnglishNumberNormalizer: + """ + Convert any spelled-out numbers into arabic numbers, while handling: + + - remove any commas + - keep the suffixes such as: `1960s`, `274th`, `32nd`, etc. + - spell out currency symbols after the number. e.g. `$20 million` -> `20000000 dollars` + - spell out `one` and `ones` + - interpret successive single-digit numbers as nominal: `one oh one` -> `101` + """ + + def __init__(self): + super().__init__() + + self.zeros = {"o", "oh", "zero"} + # fmt: off + self.ones = { + name: i + for i, name in enumerate( + ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"], + start=1, + ) + } + # fmt: on + self.ones_plural = { + "sixes" if name == "six" else name + "s": (value, "s") for name, value in self.ones.items() + } + self.ones_ordinal = { + "zeroth": (0, "th"), + "first": (1, "st"), + "second": (2, "nd"), + "third": (3, "rd"), + "fifth": (5, "th"), + "twelfth": (12, "th"), + **{ + name + ("h" if name.endswith("t") else "th"): (value, "th") + for name, value in self.ones.items() + if value > 3 and value != 5 and value != 12 + }, + } + self.ones_suffixed = {**self.ones_plural, **self.ones_ordinal} + + self.tens = { + "twenty": 20, + "thirty": 30, + "forty": 40, + "fifty": 50, + "sixty": 60, + "seventy": 70, + "eighty": 80, + "ninety": 90, + } + self.tens_plural = {name.replace("y", "ies"): (value, "s") for name, value in self.tens.items()} + self.tens_ordinal = {name.replace("y", "ieth"): (value, "th") for name, value in self.tens.items()} + self.tens_suffixed = {**self.tens_plural, **self.tens_ordinal} + + self.multipliers = { + "hundred": 100, + "thousand": 1_000, + "million": 1_000_000, + "billion": 1_000_000_000, + "trillion": 1_000_000_000_000, + "quadrillion": 1_000_000_000_000_000, + "quintillion": 1_000_000_000_000_000_000, + "sextillion": 1_000_000_000_000_000_000_000, + "septillion": 1_000_000_000_000_000_000_000_000, + "octillion": 1_000_000_000_000_000_000_000_000_000, + "nonillion": 1_000_000_000_000_000_000_000_000_000_000, + "decillion": 1_000_000_000_000_000_000_000_000_000_000_000, + } + self.multipliers_plural = {name + "s": (value, "s") for name, value in self.multipliers.items()} + self.multipliers_ordinal = {name + "th": (value, "th") for name, value in self.multipliers.items()} + self.multipliers_suffixed = {**self.multipliers_plural, **self.multipliers_ordinal} + self.decimals = {*self.ones, *self.tens, *self.zeros} + + self.preceding_prefixers = { + "minus": "-", + "negative": "-", + "plus": "+", + "positive": "+", + } + self.following_prefixers = { + "pound": "£", + "pounds": "£", + "euro": "€", + "euros": "€", + "dollar": "$", + "dollars": "$", + "cent": "¢", + "cents": "¢", + } + self.prefixes = set(list(self.preceding_prefixers.values()) + list(self.following_prefixers.values())) + self.suffixers = { + "per": {"cent": "%"}, + "percent": "%", + } + self.specials = {"and", "double", "triple", "point"} + + self.words = { + key + for mapping in [ + self.zeros, + self.ones, + self.ones_suffixed, + self.tens, + self.tens_suffixed, + self.multipliers, + self.multipliers_suffixed, + self.preceding_prefixers, + self.following_prefixers, + self.suffixers, + self.specials, + ] + for key in mapping + } + self.literal_words = {"one", "ones"} + + def process_words(self, words: List[str]) -> Iterator[str]: + prefix: Optional[str] = None + value: Optional[Union[str, int]] = None + skip = False + + def to_fraction(s: str): + try: + return Fraction(s) + except ValueError: + return None + + def output(result: Union[str, int]): + nonlocal prefix, value + result = str(result) + if prefix is not None: + result = prefix + result + value = None + prefix = None + return result + + if len(words) == 0: + return + + for i, current in enumerate(words): + prev = words[i - 1] if i != 0 else None + next = words[i + 1] if i != len(words) - 1 else None + if skip: + skip = False + continue + + next_is_numeric = next is not None and re.match(r"^\d+(\.\d+)?$", next) + has_prefix = current[0] in self.prefixes + current_without_prefix = current[1:] if has_prefix else current + if re.match(r"^\d+(\.\d+)?$", current_without_prefix): + # arabic numbers (potentially with signs and fractions) + f = to_fraction(current_without_prefix) + if f is None: + raise ValueError("Converting the fraction failed") + + if value is not None: + if isinstance(value, str) and value.endswith("."): + # concatenate decimals / ip address components + value = str(value) + str(current) + continue + else: + yield output(value) + + prefix = current[0] if has_prefix else prefix + if f.denominator == 1: + value = f.numerator # store integers as int + else: + value = current_without_prefix + elif current not in self.words: + # non-numeric words + if value is not None: + yield output(value) + yield output(current) + elif current in self.zeros: + value = str(value or "") + "0" + elif current in self.ones: + ones = self.ones[current] + + if value is None: + value = ones + elif isinstance(value, str) or prev in self.ones: + if prev in self.tens and ones < 10: # replace the last zero with the digit + value = value[:-1] + str(ones) + else: + value = str(value) + str(ones) + elif ones < 10: + if value % 10 == 0: + value += ones + else: + value = str(value) + str(ones) + else: # eleven to nineteen + if value % 100 == 0: + value += ones + else: + value = str(value) + str(ones) + elif current in self.ones_suffixed: + # ordinal or cardinal; yield the number right away + ones, suffix = self.ones_suffixed[current] + if value is None: + yield output(str(ones) + suffix) + elif isinstance(value, str) or prev in self.ones: + if prev in self.tens and ones < 10: + yield output(value[:-1] + str(ones) + suffix) + else: + yield output(str(value) + str(ones) + suffix) + elif ones < 10: + if value % 10 == 0: + yield output(str(value + ones) + suffix) + else: + yield output(str(value) + str(ones) + suffix) + else: # eleven to nineteen + if value % 100 == 0: + yield output(str(value + ones) + suffix) + else: + yield output(str(value) + str(ones) + suffix) + value = None + elif current in self.tens: + tens = self.tens[current] + if value is None: + value = tens + elif isinstance(value, str): + value = str(value) + str(tens) + else: + if value % 100 == 0: + value += tens + else: + value = str(value) + str(tens) + elif current in self.tens_suffixed: + # ordinal or cardinal; yield the number right away + tens, suffix = self.tens_suffixed[current] + if value is None: + yield output(str(tens) + suffix) + elif isinstance(value, str): + yield output(str(value) + str(tens) + suffix) + else: + if value % 100 == 0: + yield output(str(value + tens) + suffix) + else: + yield output(str(value) + str(tens) + suffix) + elif current in self.multipliers: + multiplier = self.multipliers[current] + if value is None: + value = multiplier + elif isinstance(value, str) or value == 0: + f = to_fraction(value) + p = f * multiplier if f is not None else None + if f is not None and p.denominator == 1: + value = p.numerator + else: + yield output(value) + value = multiplier + else: + before = value // 1000 * 1000 + residual = value % 1000 + value = before + residual * multiplier + elif current in self.multipliers_suffixed: + multiplier, suffix = self.multipliers_suffixed[current] + if value is None: + yield output(str(multiplier) + suffix) + elif isinstance(value, str): + f = to_fraction(value) + p = f * multiplier if f is not None else None + if f is not None and p.denominator == 1: + yield output(str(p.numerator) + suffix) + else: + yield output(value) + yield output(str(multiplier) + suffix) + else: # int + before = value // 1000 * 1000 + residual = value % 1000 + value = before + residual * multiplier + yield output(str(value) + suffix) + value = None + elif current in self.preceding_prefixers: + # apply prefix (positive, minus, etc.) if it precedes a number + if value is not None: + yield output(value) + + if next in self.words or next_is_numeric: + prefix = self.preceding_prefixers[current] + else: + yield output(current) + elif current in self.following_prefixers: + # apply prefix (dollars, cents, etc.) only after a number + if value is not None: + prefix = self.following_prefixers[current] + yield output(value) + else: + yield output(current) + elif current in self.suffixers: + # apply suffix symbols (percent -> '%') + if value is not None: + suffix = self.suffixers[current] + if isinstance(suffix, dict): + if next in suffix: + yield output(str(value) + suffix[next]) + skip = True + else: + yield output(value) + yield output(current) + else: + yield output(str(value) + suffix) + else: + yield output(current) + elif current in self.specials: + if next not in self.words and not next_is_numeric: + # apply special handling only if the next word can be numeric + if value is not None: + yield output(value) + yield output(current) + elif current == "and": + # ignore "and" after hundreds, thousands, etc. + if prev not in self.multipliers: + if value is not None: + yield output(value) + yield output(current) + elif current == "double" or current == "triple": + if next in self.ones or next in self.zeros: + repeats = 2 if current == "double" else 3 + ones = self.ones.get(next, 0) + value = str(value or "") + str(ones) * repeats + skip = True + else: + if value is not None: + yield output(value) + yield output(current) + elif current == "point": + if next in self.decimals or next_is_numeric: + value = str(value or "") + "." + else: + # should all have been covered at this point + raise ValueError(f"Unexpected token: {current}") + else: + # all should have been covered at this point + raise ValueError(f"Unexpected token: {current}") + + if value is not None: + yield output(value) + + def preprocess(self, s: str): + # replace " and a half" with " point five" + results = [] + + segments = re.split(r"\band\s+a\s+half\b", s) + for i, segment in enumerate(segments): + if len(segment.strip()) == 0: + continue + if i == len(segments) - 1: + results.append(segment) + else: + results.append(segment) + last_word = segment.rsplit(maxsplit=2)[-1] + if last_word in self.decimals or last_word in self.multipliers: + results.append("point five") + else: + results.append("and a half") + + s = " ".join(results) + + # put a space at number/letter boundary + s = re.sub(r"([a-z])([0-9])", r"\1 \2", s) + s = re.sub(r"([0-9])([a-z])", r"\1 \2", s) + + # but remove spaces which could be a suffix + s = re.sub(r"([0-9])\s+(st|nd|rd|th|s)\b", r"\1\2", s) + + return s + + def postprocess(self, s: str): + def combine_cents(m: Match): + try: + currency = m.group(1) + integer = m.group(2) + cents = int(m.group(3)) + return f"{currency}{integer}.{cents:02d}" + except ValueError: + return m.string + + def extract_cents(m: Match): + try: + return f"¢{int(m.group(1))}" + except ValueError: + return m.string + + # apply currency postprocessing; "$2 and ¢7" -> "$2.07" + s = re.sub(r"([€£$])([0-9]+) (?:and )?¢([0-9]{1,2})\b", combine_cents, s) + s = re.sub(r"[€£$]0.([0-9]{1,2})\b", extract_cents, s) + + # write "one(s)" instead of "1(s)", just for the readability + s = re.sub(r"\b1(s?)\b", r"one\1", s) + + return s + + def __call__(self, s: str): + s = self.preprocess(s) + s = " ".join(word for word in self.process_words(s.split()) if word is not None) + s = self.postprocess(s) + + return s + + +class EnglishSpellingNormalizer: + """ + Applies British-American spelling mappings as listed in [1]. + + [1] https://www.tysto.com/uk-us-spelling-list.html + """ + + def __init__(self, english_spelling_mapping): + self.mapping = english_spelling_mapping + + def __call__(self, s: str): + return " ".join(self.mapping.get(word, word) for word in s.split()) + + +class EnglishTextNormalizer: + def __init__(self, english_spelling_mapping): + self.ignore_patterns = r"\b(hmm|mm|mhm|mmm|uh|um)\b" + self.replacers = { + # common contractions + r"\bwon't\b": "will not", + r"\bcan't\b": "can not", + r"\blet's\b": "let us", + r"\bain't\b": "aint", + r"\by'all\b": "you all", + r"\bwanna\b": "want to", + r"\bgotta\b": "got to", + r"\bgonna\b": "going to", + r"\bi'ma\b": "i am going to", + r"\bimma\b": "i am going to", + r"\bwoulda\b": "would have", + r"\bcoulda\b": "could have", + r"\bshoulda\b": "should have", + r"\bma'am\b": "madam", + # contractions in titles/prefixes + r"\bmr\b": "mister ", + r"\bmrs\b": "missus ", + r"\bst\b": "saint ", + r"\bdr\b": "doctor ", + r"\bprof\b": "professor ", + r"\bcapt\b": "captain ", + r"\bgov\b": "governor ", + r"\bald\b": "alderman ", + r"\bgen\b": "general ", + r"\bsen\b": "senator ", + r"\brep\b": "representative ", + r"\bpres\b": "president ", + r"\brev\b": "reverend ", + r"\bhon\b": "honorable ", + r"\basst\b": "assistant ", + r"\bassoc\b": "associate ", + r"\blt\b": "lieutenant ", + r"\bcol\b": "colonel ", + r"\bjr\b": "junior ", + r"\bsr\b": "senior ", + r"\besq\b": "esquire ", + # prefect tenses, ideally it should be any past participles, but it's harder.. + r"'d been\b": " had been", + r"'s been\b": " has been", + r"'d gone\b": " had gone", + r"'s gone\b": " has gone", + r"'d done\b": " had done", # "'s done" is ambiguous + r"'s got\b": " has got", + # general contractions + r"n't\b": " not", + r"'re\b": " are", + r"'s\b": " is", + r"'d\b": " would", + r"'ll\b": " will", + r"'t\b": " not", + r"'ve\b": " have", + r"'m\b": " am", + } + self.standardize_numbers = EnglishNumberNormalizer() + self.standardize_spellings = EnglishSpellingNormalizer(english_spelling_mapping) + + def __call__(self, s: str): + s = s.lower() + + s = re.sub(r"[<\[][^>\]]*[>\]]", "", s) # remove words between brackets + s = re.sub(r"\(([^)]+?)\)", "", s) # remove words between parenthesis + s = re.sub(self.ignore_patterns, "", s) + s = re.sub(r"\s+'", "'", s) # standardize when there's a space before an apostrophe + + for pattern, replacement in self.replacers.items(): + s = re.sub(pattern, replacement, s) + + s = re.sub(r"(\d),(\d)", r"\1\2", s) # remove commas between digits + s = re.sub(r"\.([^0-9]|$)", r" \1", s) # remove periods not followed by numbers + s = remove_symbols_and_diacritics(s, keep=".%$¢€£") # keep some symbols for numerics + + s = self.standardize_numbers(s) + s = self.standardize_spellings(s) + + # now remove prefix/suffix symbols that are not preceded/followed by numbers + s = re.sub(r"[.$¢€£]([^0-9])", r" \1", s) + s = re.sub(r"([^0-9])%", r"\1 ", s) + + s = re.sub(r"\s+", " ", s) # replace any successive whitespace characters with a space + + return s diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/feature_extraction_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/feature_extraction_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..e0b772216205fecbba8d376a6c03070d065b972b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/feature_extraction_whisper.py @@ -0,0 +1,274 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Feature extractor class for Whisper +""" +import copy +from typing import Any, Dict, List, Optional, Union + +import numpy as np + +from ...audio_utils import mel_filter_bank, spectrogram, window_function +from ...feature_extraction_sequence_utils import SequenceFeatureExtractor +from ...feature_extraction_utils import BatchFeature +from ...utils import TensorType, logging + + +logger = logging.get_logger(__name__) + + +class WhisperFeatureExtractor(SequenceFeatureExtractor): + r""" + Constructs a Whisper feature extractor. + + This feature extractor inherits from [`~feature_extraction_sequence_utils.SequenceFeatureExtractor`] which contains + most of the main methods. Users should refer to this superclass for more information regarding those methods. + + This class extracts mel-filter bank features from raw speech using a custom numpy implementation of the `Short Time + Fourier Transform` which should match pytorch's `torch.stft` equivalent. + + Args: + feature_size (`int`, defaults to 80): + The feature dimension of the extracted features. + sampling_rate (`int`, defaults to 16000): + The sampling rate at which the audio files should be digitalized expressed in hertz (Hz). + hop_length (`int`, defaults to 160): + Length of the overlaping windows for the STFT used to obtain the Mel Frequency coefficients. + chunk_length (`int`, defaults to 30): + The maximum number of chuncks of `sampling_rate` samples used to trim and pad longer or shorter audio + sequences. + n_fft (`int`, defaults to 400): + Size of the Fourier transform. + padding_value (`float`, *optional*, defaults to 0.0): + Padding value used to pad the audio. Should correspond to silences. + """ + + model_input_names = ["input_features"] + + def __init__( + self, + feature_size=80, + sampling_rate=16000, + hop_length=160, + chunk_length=30, + n_fft=400, + padding_value=0.0, + return_attention_mask=False, # pad inputs to max length with silence token (zero) and no attention mask + **kwargs, + ): + super().__init__( + feature_size=feature_size, + sampling_rate=sampling_rate, + padding_value=padding_value, + return_attention_mask=return_attention_mask, + **kwargs, + ) + self.n_fft = n_fft + self.hop_length = hop_length + self.chunk_length = chunk_length + self.n_samples = chunk_length * sampling_rate + self.nb_max_frames = self.n_samples // hop_length + self.sampling_rate = sampling_rate + self.mel_filters = mel_filter_bank( + num_frequency_bins=1 + n_fft // 2, + num_mel_filters=feature_size, + min_frequency=0.0, + max_frequency=8000.0, + sampling_rate=sampling_rate, + norm="slaney", + mel_scale="slaney", + ) + + def _np_extract_fbank_features(self, waveform: np.array) -> np.ndarray: + """ + Compute the log-mel spectrogram of the provided audio, gives similar results to Whisper's original torch + implementation with 1e-5 tolerance. + """ + log_spec = spectrogram( + waveform, + window_function(self.n_fft, "hann"), + frame_length=self.n_fft, + hop_length=self.hop_length, + power=2.0, + mel_filters=self.mel_filters, + log_mel="log10", + ) + log_spec = log_spec[:, :-1] + log_spec = np.maximum(log_spec, log_spec.max() - 8.0) + log_spec = (log_spec + 4.0) / 4.0 + return log_spec + + @staticmethod + # Copied from transformers.models.wav2vec2.feature_extraction_wav2vec2.Wav2Vec2FeatureExtractor.zero_mean_unit_var_norm + def zero_mean_unit_var_norm( + input_values: List[np.ndarray], attention_mask: List[np.ndarray], padding_value: float = 0.0 + ) -> List[np.ndarray]: + """ + Every array in the list is normalized to have zero mean and unit variance + """ + if attention_mask is not None: + attention_mask = np.array(attention_mask, np.int32) + normed_input_values = [] + + for vector, length in zip(input_values, attention_mask.sum(-1)): + normed_slice = (vector - vector[:length].mean()) / np.sqrt(vector[:length].var() + 1e-7) + if length < normed_slice.shape[0]: + normed_slice[length:] = padding_value + + normed_input_values.append(normed_slice) + else: + normed_input_values = [(x - x.mean()) / np.sqrt(x.var() + 1e-7) for x in input_values] + + return normed_input_values + + def __call__( + self, + raw_speech: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]], + truncation: bool = True, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_attention_mask: Optional[bool] = None, + padding: Optional[str] = "max_length", + max_length: Optional[int] = None, + sampling_rate: Optional[int] = None, + do_normalize: Optional[bool] = None, + **kwargs, + ) -> BatchFeature: + """ + Main method to featurize and prepare for the model one or several sequence(s). + + Args: + raw_speech (`np.ndarray`, `List[float]`, `List[np.ndarray]`, `List[List[float]]`): + The sequence or batch of sequences to be padded. Each sequence can be a numpy array, a list of float + values, a list of numpy arrays or a list of list of float values. + truncation (`bool`, *optional*, default to `True`): + Activates truncation to cut input sequences longer than *max_length* to *max_length*. + pad_to_multiple_of (`int`, *optional*, defaults to None): + If set will pad the sequence to a multiple of the provided value. + + This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability + `>= 7.5` (Volta), or on TPUs which benefit from having sequence lengths be a multiple of 128. + return_attention_mask (`bool`, *optional*): + Whether to return the attention mask. If left to the default, will return the attention mask according + to the specific feature_extractor's default. + + [What are attention masks?](../glossary#attention-mask) + + + + For Whisper models, `attention_mask` should always be passed for batched inference, to avoid subtle + bugs. + + + + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + sampling_rate (`int`, *optional*): + The sampling rate at which the `raw_speech` input was sampled. It is strongly recommended to pass + `sampling_rate` at the forward call to prevent silent errors and allow automatic speech recognition + pipeline. + padding_value (`float`, defaults to 0.0): + The value that is used to fill the padding values / vectors. + do_normalize (`bool`, *optional*, defaults to `False`): + Whether or not to zero-mean unit-variance normalize the input. Normalizing can help to significantly + improve the performance of the model. + """ + + if sampling_rate is not None: + if sampling_rate != self.sampling_rate: + raise ValueError( + f"The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a" + f" sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input" + f" was sampled with {self.sampling_rate} and not {sampling_rate}." + ) + else: + logger.warning( + "It is strongly recommended to pass the `sampling_rate` argument to this function. " + "Failing to do so can result in silent errors that might be hard to debug." + ) + + is_batched = bool( + isinstance(raw_speech, (list, tuple)) + and (isinstance(raw_speech[0], np.ndarray) or isinstance(raw_speech[0], (tuple, list))) + ) + + if is_batched: + raw_speech = [np.asarray([speech], dtype=np.float32).T for speech in raw_speech] + elif not is_batched and not isinstance(raw_speech, np.ndarray): + raw_speech = np.asarray(raw_speech, dtype=np.float32) + elif isinstance(raw_speech, np.ndarray) and raw_speech.dtype is np.dtype(np.float64): + raw_speech = raw_speech.astype(np.float32) + + # always return batch + if not is_batched: + raw_speech = [np.asarray([raw_speech]).T] + + batched_speech = BatchFeature({"input_features": raw_speech}) + + # convert into correct format for padding + + padded_inputs = self.pad( + batched_speech, + padding=padding, + max_length=max_length if max_length else self.n_samples, + truncation=truncation, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=return_attention_mask or do_normalize, + ) + + # zero-mean and unit-variance normalization + if do_normalize: + padded_inputs["input_features"] = self.zero_mean_unit_var_norm( + padded_inputs["input_features"], + attention_mask=padded_inputs["attention_mask"], + padding_value=self.padding_value, + ) + padded_inputs["input_features"] = np.stack(padded_inputs["input_features"], axis=0) + + # make sure list is in array format + input_features = padded_inputs.get("input_features").transpose(2, 0, 1) + + input_features = [self._np_extract_fbank_features(waveform) for waveform in input_features[0]] + + if isinstance(input_features[0], List): + padded_inputs["input_features"] = [np.asarray(feature, dtype=np.float32) for feature in input_features] + else: + padded_inputs["input_features"] = input_features + + if return_attention_mask: + # rescale from sample (48000) to feature (3000) + padded_inputs["attention_mask"] = padded_inputs["attention_mask"][:, :: self.hop_length] + + if return_tensors is not None: + padded_inputs = padded_inputs.convert_to_tensors(return_tensors) + + return padded_inputs + + def to_dict(self) -> Dict[str, Any]: + """ + Serializes this instance to a Python dictionary. + + Returns: + `Dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance. + """ + output = copy.deepcopy(self.__dict__) + output["feature_extractor_type"] = self.__class__.__name__ + if "mel_filters" in output: + del output["mel_filters"] + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_flax_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_flax_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..1a994acea4dfeeb98fb9c41e17b9a853f659dd1f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_flax_whisper.py @@ -0,0 +1,1669 @@ +# coding=utf-8 +# Copyright 2022 The OpenAI Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Flax whisper model.""" + +import random +from functools import partial +from typing import Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen import combine_masks, make_causal_mask +from flax.linen import partitioning as nn_partitioning +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax +from jax.random import PRNGKey + +from ...generation.flax_logits_process import FlaxWhisperTimeStampLogitsProcessor +from ...modeling_flax_outputs import ( + FlaxBaseModelOutput, + FlaxBaseModelOutputWithPastAndCrossAttentions, + FlaxCausalLMOutputWithCrossAttentions, + FlaxSeq2SeqLMOutput, + FlaxSeq2SeqModelOutput, + FlaxSequenceClassifierOutput, +) +from ...modeling_flax_utils import ( + ACT2FN, + FlaxPreTrainedModel, + append_call_sample_docstring, + append_replace_return_docstrings, + overwrite_call_docstring, +) +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_whisper import WhisperConfig + + +logger = logging.get_logger(__name__) + + +_CHECKPOINT_FOR_DOC = "openai/whisper-tiny" +_CONFIG_FOR_DOC = "WhisperConfig" + +remat = nn_partitioning.remat + + +WHISPER_START_DOCSTRING = r""" + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its models (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) This model is also a Flax Linen + [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a + regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. + Finally, this model supports inherent JAX features such as: + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`WhisperConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). This can be used to enable mixed-precision training or half-precision + inference on GPUs or TPUs. If specified all the computation will be performed with the given `dtype`. + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] + and [`~FlaxPreTrainedModel.to_bf16`]. +""" + +WHISPER_INPUTS_DOCSTRING = r""" + Args: + input_features (`numpy.ndarray` of shape `(batch_size, feature_size, sequence_length)`): + Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by + loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via + the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`WhisperFeatureExtractor`] should be used for extracting the features, padding and conversion into a + tensor of type `numpy.ndarray`. See [`~WhisperFeatureExtractor.__call__`] + attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, but + is not used. By default the silence in the input log mel spectrogram are ignored. + decoder_input_ids (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. Indices can be obtained using + [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. + [What are decoder input IDs?](../glossary#decoder-input-ids) Whisper uses the `decoder_start_token_id` as + the starting token for `decoder_input_ids` generation. + decoder_attention_mask (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. If you want to change padding behavior, you should modify to your needs. See diagram 1 + in [the paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Whisper does not use `position_ids` in the encoder as `input_features` is always the same size and doesn't + use masking, but this argument is preserved for compatibility. By default the silence in the input log mel + spectrogram are ignored. + decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +WHISPER_ENCODE_INPUTS_DOCSTRING = r""" + Args: + input_features (`numpy.ndarray` of shape `(batch_size, feature_size, sequence_length)`): + Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by + loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via + the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`WhisperFeatureExtractor`] should be used for extracting the mel features, padding and conversion into a + tensor of type `numpy.ndarray`. See [`~WhisperFeatureExtractor.__call__`]. + attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, but + is not used. By default the silence in the input log mel spectrogram are ignored. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +WHISPER_DECODE_INPUTS_DOCSTRING = r""" + Args: + decoder_input_ids (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`): + Indices of decoder input sequence tokens in the vocabulary. Indices can be obtained using + [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. + [What are decoder input IDs?](../glossary#decoder-input-ids) + encoder_outputs (`tuple(tuple(numpy.ndarray)`): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + encoder_attention_mask (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, + but it is not used. By default the silence in the input log mel spectrogram are ignored. + decoder_attention_mask (`numpy.ndarray` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. If you want to change padding behavior, you should modify to your needs. See diagram 1 + in [the paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + decoder_position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + past_key_values (`Dict[str, numpy.ndarray]`, *optional*, returned by `init_cache` or when passing previous `past_key_values`): + Dictionary of pre-computed hidden-states (key and values in the attention blocks) that can be used for fast + auto-regressive decoding. Pre-computed key and value hidden-states are of shape *[batch_size, max_length]*. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class FlaxWhisperAttention(nn.Module): + config: WhisperConfig + embed_dim: int + num_heads: int + dropout: float = 0.0 + causal: bool = False + bias: bool = True + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {self.num_heads})." + ) + + dense = partial( + nn.Dense, + self.embed_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + self.q_proj = dense(use_bias=self.bias) + self.k_proj = dense(use_bias=False) + self.v_proj = dense(use_bias=self.bias) + self.out_proj = dense(use_bias=self.bias) + + if self.causal: + self.causal_mask = make_causal_mask( + jnp.ones((1, self.config.max_target_positions), dtype="bool"), dtype="bool" + ) + + def __call__( + self, + hidden_states: jnp.ndarray, + key_value_states: Optional[jnp.ndarray] = None, + attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + is_cross_attention = key_value_states is not None + batch_size = hidden_states.shape[0] + + query_states = self.q_proj(hidden_states) + + if is_cross_attention: + key_states = self.k_proj(key_value_states) + value_states = self.v_proj(key_value_states) + else: + key_states = self.k_proj(hidden_states) + value_states = self.v_proj(hidden_states) + + query_states = self._split_heads(query_states) + key_states = self._split_heads(key_states) + value_states = self._split_heads(value_states) + + if self.causal: + query_length, key_length = query_states.shape[1], key_states.shape[1] + if self.has_variable("cache", "cached_key"): + mask_shift = self.variables["cache"]["cache_index"] + max_decoder_length = self.variables["cache"]["cached_key"].shape[1] + causal_mask = lax.dynamic_slice( + self.causal_mask, + (0, 0, mask_shift, 0), + (1, 1, query_length, max_decoder_length), + ) + else: + causal_mask = self.causal_mask[:, :, :query_length, :key_length] + causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) + + # combine masks if needed + if attention_mask is not None and self.causal: + attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) + attention_mask = combine_masks(attention_mask, causal_mask) + elif self.causal: + attention_mask = causal_mask + elif attention_mask is not None: + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + + # During fast autoregressive decoding, we feed one position at a time, + # and cache the keys and values step by step. + + if self.causal and (self.has_variable("cache", "cached_key") or init_cache): + key_states, value_states, attention_mask = self._concatenate_to_cache( + key_states, value_states, query_states, attention_mask + ) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.dropout > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.dropout, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = self._merge_heads(attn_output) + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights + + def _split_heads(self, hidden_state) -> jnp.ndarray: + return hidden_state.reshape(hidden_state.shape[:2] + (self.num_heads, self.head_dim)) + + def _merge_heads(self, hidden_state) -> jnp.ndarray: + return hidden_state.reshape(hidden_state.shape[:2] + (self.embed_dim,)) + + @nn.compact + def _concatenate_to_cache(self, key, value, query, attention_mask) -> Tuple[jnp.ndarray, jnp.ndarray, jnp.ndarray]: + # detect if we're initializing by absence of existing cache data. + is_initialized = self.has_variable("cache", "cached_key") + cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) + cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) + cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) + + if is_initialized: + *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape + # update key, value caches with our new 1d spatial slices + cur_index = cache_index.value + indices = (0,) * len(batch_dims) + (cur_index, 0, 0) + key = lax.dynamic_update_slice(cached_key.value, key, indices) + value = lax.dynamic_update_slice(cached_value.value, value, indices) + cached_key.value = key + cached_value.value = value + num_updated_cache_vectors = query.shape[1] + cache_index.value = cache_index.value + num_updated_cache_vectors + # causal mask for cached decoder self-attention: our single query position should only + # attend to those key positions that have already been generated and cached, not the + # remaining zero elements. + pad_mask = jnp.broadcast_to( + jnp.arange(max_length) < cur_index + num_updated_cache_vectors, + tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), + ) + attention_mask = combine_masks(pad_mask, attention_mask) + + return key, value, attention_mask + + +# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartEncoderLayer with MBart->Whisper +class FlaxWhisperEncoderLayer(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.embed_dim = self.config.d_model + self.self_attn = FlaxWhisperAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.encoder_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + self.activation_fn = ACT2FN[self.config.activation_function] + self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) + self.fc1 = nn.Dense( + self.config.encoder_ffn_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.fc2 = nn.Dense( + self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + hidden_states: jnp.ndarray, + attention_mask: jnp.ndarray, + output_attentions: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + hidden_states, attn_weights = self.self_attn(hidden_states=hidden_states, attention_mask=attention_mask) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class FlaxWhisperEncoderLayerCollection(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + gradient_checkpointing: bool = False + + def setup(self): + if self.gradient_checkpointing: + FlaxWhisperEncoderCheckpointLayer = remat(FlaxWhisperEncoderLayer, static_argnums=(2, 3)) + self.layers = [ + FlaxWhisperEncoderCheckpointLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.encoder_layers) + ] + else: + self.layers = [ + FlaxWhisperEncoderLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.encoder_layers) + ] + self.layerdrop = self.config.encoder_layerdrop + + def __call__( + self, + hidden_states, + attention_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + + for encoder_layer in self.layers: + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if not deterministic and (dropout_probability < self.layerdrop): # skip the layer + layer_outputs = (None, None) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + output_attentions, + deterministic, + ) + hidden_states = layer_outputs[0] + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states, all_hidden_states, all_attentions) + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=all_hidden_states, attentions=all_attentions + ) + + +# Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer with MBart->Whisper +class FlaxWhisperDecoderLayer(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.embed_dim = self.config.d_model + self.self_attn = FlaxWhisperAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.decoder_attention_heads, + dropout=self.config.attention_dropout, + causal=True, + dtype=self.dtype, + ) + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + self.activation_fn = ACT2FN[self.config.activation_function] + self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) + + self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.encoder_attn = FlaxWhisperAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.decoder_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.fc1 = nn.Dense( + self.config.decoder_ffn_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.fc2 = nn.Dense( + self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + hidden_states: jnp.ndarray, + attention_mask: jnp.ndarray, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + hidden_states = self.encoder_attn_layer_norm(hidden_states) + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +class FlaxWhisperDecoderLayerCollection(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + gradient_checkpointing: bool = False + + def setup(self): + if self.gradient_checkpointing: + FlaxWhisperDecoderCheckpointLayer = remat(FlaxWhisperDecoderLayer, static_argnums=(4, 5, 6)) + self.layers = [ + FlaxWhisperDecoderCheckpointLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.decoder_layers) + ] + else: + self.layers = [ + FlaxWhisperDecoderLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.decoder_layers) + ] + self.layerdrop = self.config.decoder_layerdrop + + def __call__( + self, + hidden_states, + attention_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + deterministic: bool = True, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + + for decoder_layer in self.layers: + if output_hidden_states: + all_hidden_states += (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if not deterministic and (dropout_probability < self.layerdrop): + layer_outputs = (None, None, None) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + init_cache, + output_attentions, + deterministic, + ) + + hidden_states = layer_outputs[0] + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = [hidden_states, all_hidden_states, all_self_attns, all_cross_attentions] + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +class FlaxWhisperEncoder(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self) -> None: + self.conv1 = nn.Conv( + self.config.d_model, + kernel_size=(3,), + padding=1, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + self.conv2 = nn.Conv( + self.config.d_model, + kernel_size=(3,), + strides=2, + padding=1, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + dtype=self.dtype, + ) + + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + + self.layers = FlaxWhisperEncoderLayerCollection( + self.config, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.embed_positions = nn.Embed(self.config.max_source_positions, self.config.d_model, dtype=self.dtype) + + self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + input_features: jnp.ndarray, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + if input_features.shape[1:] != (self.config.num_mel_bins, self.config.max_source_positions * 2): + raise ValueError( + "input_features.shape[1:], must be equal to (self.config.num_mel_bins," + f" self.config.max_source_positions * 2) (got {input_features.shape[1:]}, but should be" + f" ({self.config.num_mel_bins}, {self.config.max_source_positions * 2}))" + ) + + input_features = input_features.transpose(0, 2, 1) + hidden_states = jax.nn.gelu(self.conv1(input_features), approximate=False) + hidden_states = jax.nn.gelu(self.conv2(hidden_states), approximate=False) + + embed_positions = self.embed_positions(jnp.arange(self.config.max_source_positions)) + hidden_states = hidden_states + embed_positions + + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask=None, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_states = outputs[0] + last_hidden_states = self.layer_norm(last_hidden_states) + + # update the last element in `hidden_states` after applying `layernorm` above + hidden_states = None + if output_hidden_states: + hidden_states = outputs[1] + hidden_states = hidden_states[:-1] + (last_hidden_states,) + + if not return_dict: + outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutput( + last_hidden_state=last_hidden_states, + hidden_states=hidden_states, + attentions=outputs.attentions, + ) + + +class FlaxWhisperDecoder(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self) -> None: + self.embed_tokens = nn.Embed(self.config.vocab_size, self.config.d_model, dtype=self.dtype) + self.embed_positions = nn.Embed(self.config.max_target_positions, self.config.d_model, dtype=self.dtype) + + self.layers = FlaxWhisperDecoderLayerCollection( + self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing + ) + + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + + self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-5) + + def __call__( + self, + input_ids: jnp.ndarray, + attention_mask: jnp.ndarray, + position_ids: jnp.ndarray, + encoder_hidden_states: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + input_embeds = self.embed_tokens(input_ids) + position_embeds = self.embed_positions(position_ids) + + hidden_states = input_embeds + position_embeds + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + deterministic=deterministic, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_states = outputs[0] + last_hidden_states = self.layer_norm(last_hidden_states) + + # update the last element in `hidden_states` after applying `layernorm` above + hidden_states = None + if output_hidden_states: + hidden_states = outputs[1] + hidden_states = hidden_states[:-1] + (last_hidden_states,) + + if not return_dict: + outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=last_hidden_states, + hidden_states=hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +class FlaxWhisperModule(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self) -> None: + self.encoder = FlaxWhisperEncoder( + self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing + ) + self.decoder = FlaxWhisperDecoder( + self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing + ) + + def __call__( + self, + input_features: jnp.ndarray, + decoder_input_ids: jnp.ndarray, + decoder_attention_mask: jnp.ndarray, + decoder_position_ids: jnp.ndarray, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + encoder_outputs = self.encoder( + input_features, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return FlaxSeq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + def _get_encoder_module(self): + return self.encoder + + def _get_decoder_module(self): + return self.decoder + + +class FlaxWhisperPreTrainedModel(FlaxPreTrainedModel): + config_class = WhisperConfig + base_model_prefix: str = "model" + main_input_name = "input_features" + module_class: nn.Module = None + + def __init__( + self, + config: WhisperConfig, + input_shape: Tuple[int] = (1, 80, 3000), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + gradient_checkpointing: bool = False, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def enable_gradient_checkpointing(self): + self._module = self.module_class( + config=self.config, + dtype=self.dtype, + gradient_checkpointing=True, + ) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_features = jnp.zeros(input_shape, dtype="f4") + input_features = input_features.at[(..., -1)].set(self.config.eos_token_id) + + decoder_input_ids = jnp.zeros((input_shape[0], 1), dtype="i4") + decoder_attention_mask = jnp.ones_like(decoder_input_ids) + + batch_size, sequence_length = decoder_input_ids.shape + decoder_position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init( + rngs, + input_features=input_features, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + )["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartPreTrainedModel.init_cache with Bart->Whisper + def init_cache(self, batch_size, max_length, encoder_outputs): + r""" + Args: + batch_size (`int`): + batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. + max_length (`int`): + maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized + cache. + encoder_outputs (`Union[FlaxBaseModelOutput, tuple(tuple(jnp.ndarray)]`): + `encoder_outputs` consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: + `attentions`). `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) + is a sequence of hidden-states at the output of the last layer of the encoder. Used in the + cross-attention of the decoder. + """ + # init input variables to retrieve cache + decoder_input_ids = jnp.ones((batch_size, max_length), dtype="i4") + decoder_attention_mask = jnp.ones_like(decoder_input_ids) + decoder_position_ids = jnp.broadcast_to( + jnp.arange(jnp.atleast_2d(decoder_input_ids).shape[-1]), decoder_input_ids.shape + ) + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + return decoder_module( + decoder_input_ids, + decoder_attention_mask, + decoder_position_ids, + **kwargs, + ) + + init_variables = self.module.init( + jax.random.PRNGKey(0), + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + init_cache=True, + method=_decoder_forward, # we only need to call the decoder to init the cache + ) + return unfreeze(init_variables["cache"]) + + @add_start_docstrings(WHISPER_ENCODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxBaseModelOutput, config_class=WhisperConfig) + def encode( + self, + input_features: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + **kwargs, + ): + r""" + Returns: + + Example: + + ```python + >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") + >>> input_features = inputs.input_features + >>> encoder_outputs = model.encode(input_features=input_features) + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + def _encoder_forward(module, input_features, **kwargs): + encode_module = module._get_encoder_module() + return encode_module(input_features, **kwargs) + + return self.module.apply( + {"params": params or self.params}, + input_features=jnp.array(input_features, dtype="f4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + method=_encoder_forward, + ) + + @add_start_docstrings(WHISPER_DECODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxBaseModelOutputWithPastAndCrossAttentions, config_class=WhisperConfig) + def decode( + self, + decoder_input_ids, + encoder_outputs, + encoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + past_key_values: dict = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + r""" + Returns: + + Example: + + ```python + >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") + >>> input_features = inputs.input_features + >>> encoder_outputs = model.encode(input_features=input_features) + >>> decoder_start_token_id = model.config.decoder_start_token_id + + >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id + + >>> outputs = model.decode(decoder_input_ids, encoder_outputs) + >>> last_decoder_hidden_states = outputs.last_hidden_state + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + encoder_hidden_states = encoder_outputs[0] + + batch_size, sequence_length = decoder_input_ids.shape + if decoder_position_ids is None: + if past_key_values is not None: + raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") + + if decoder_attention_mask is not None: + decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 + else: + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be + # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that + # it can be changed by FlaxWhisperAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + return decoder_module( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + **kwargs, + ) + + outputs = self.module.apply( + inputs, + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + method=_decoder_forward, + ) + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs, past = outputs + outputs["past_key_values"] = unfreeze(past["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs, past = outputs + outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] + + return outputs + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + def __call__( + self, + input_features: jnp.ndarray, + decoder_input_ids: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # prepare decoder inputs + if decoder_position_ids is None: + if decoder_attention_mask is not None: + decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 + else: + batch_size, sequence_length = decoder_input_ids.shape + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones_like(decoder_input_ids) + + # Handle any PRNG if needed + rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} + + return self.module.apply( + {"params": params or self.params}, + input_features=jnp.array(input_features, dtype="f4"), + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + ) + + +@add_start_docstrings( + "The bare Whisper Model transformer outputting raw hidden-states without any specific head on top.", + WHISPER_START_DOCSTRING, +) +class FlaxWhisperModel(FlaxWhisperPreTrainedModel): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + module_class = FlaxWhisperModule + + +append_call_sample_docstring(FlaxWhisperModel, _CHECKPOINT_FOR_DOC, FlaxSeq2SeqModelOutput, _CONFIG_FOR_DOC) + + +class FlaxWhisperForConditionalGenerationModule(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self) -> None: + self.model = FlaxWhisperModule( + config=self.config, dtype=self.dtype, gradient_checkpointing=self.gradient_checkpointing + ) + self.lm_head = nn.Dense( + self.config.vocab_size, + use_bias=False, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + def _get_encoder_module(self): + return self.model.encoder + + def _get_decoder_module(self): + return self.model.decoder + + def __call__( + self, + input_features, + decoder_input_ids, + decoder_attention_mask: jnp.ndarray = None, + decoder_position_ids: jnp.ndarray = None, + position_ids: jnp.ndarray = None, + attention_mask: jnp.ndarray = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_features=input_features, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=deterministic, + ) + + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = self.model.decoder.embed_tokens.variables["params"]["embedding"] + lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = self.lm_head(hidden_states) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return output + + return FlaxSeq2SeqLMOutput( + logits=lm_logits, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + +@add_start_docstrings("The Whisper Model with a language modeling head.", WHISPER_START_DOCSTRING) +class FlaxWhisperForConditionalGeneration(FlaxWhisperPreTrainedModel): + module_class = FlaxWhisperForConditionalGenerationModule + dtype: jnp.dtype = jnp.float32 + + @add_start_docstrings(WHISPER_DECODE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=FlaxCausalLMOutputWithCrossAttentions, config_class=WhisperConfig) + def decode( + self, + decoder_input_ids, + encoder_outputs, + encoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_attention_mask: Optional[jnp.ndarray] = None, + decoder_position_ids: Optional[jnp.ndarray] = None, + past_key_values: dict = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + ): + r""" + Returns: + + Example: + + ```python + >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") + >>> input_features = inputs.input_features + >>> encoder_outputs = model.encode(input_features=input_features) + >>> decoder_start_token_id = model.config.decoder_start_token_id + + >>> decoder_input_ids = jnp.ones((inputs.input_ids.shape[0], 1), dtype="i4") * decoder_start_token_id + + >>> outputs = model.decode(decoder_input_ids, encoder_outputs) + >>> last_decoder_hidden_states = outputs.last_hidden_state + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + encoder_hidden_states = encoder_outputs[0] + + batch_size, sequence_length = decoder_input_ids.shape + if decoder_position_ids is None: + if past_key_values is not None: + raise ValueError("Make sure to provide `decoder_position_ids` when passing `past_key_values`.") + + if decoder_attention_mask is not None: + decoder_position_ids = (decoder_attention_mask.cumsum(-1) * decoder_attention_mask) - 1 + else: + decoder_position_ids = jnp.broadcast_to( + jnp.arange(sequence_length)[None, :], (batch_size, sequence_length) + ) + if decoder_attention_mask is None: + decoder_attention_mask = jnp.ones((batch_size, sequence_length), dtype="i4") + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be + # passed down to ensure cache is used. It has to be made sure that cache is marked as mutable so that + # it can be changed by FlaxWhisperAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + def _decoder_forward(module, decoder_input_ids, decoder_attention_mask, decoder_position_ids, **kwargs): + decoder_module = module._get_decoder_module() + outputs = decoder_module( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + **kwargs, + ) + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = module.model.decoder.embed_tokens.variables["params"]["embedding"] + lm_logits = module.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = module.lm_head(hidden_states) + + return lm_logits, outputs + + outputs = self.module.apply( + inputs, + decoder_input_ids=jnp.array(decoder_input_ids, dtype="i4"), + decoder_attention_mask=jnp.array(decoder_attention_mask, dtype="i4"), + decoder_position_ids=jnp.array(decoder_position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + method=_decoder_forward, + ) + + if past_key_values is None: + lm_logits, decoder_outputs = outputs + else: + (lm_logits, decoder_outputs), past = outputs + + if return_dict: + outputs = FlaxCausalLMOutputWithCrossAttentions( + logits=lm_logits, + hidden_states=decoder_outputs.hidden_states, + attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + ) + else: + outputs = (lm_logits,) + decoder_outputs[1:] + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs["past_key_values"] = unfreeze(past["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs = outputs[:1] + (unfreeze(past["cache"]),) + outputs[1:] + + return outputs + + def generate( + self, + input_features, + generation_config=None, + logits_processor=None, + return_timestamps=None, + task=None, + language=None, + is_multilingual=None, + **kwargs, + ): + if generation_config is None: + generation_config = self.generation_config + + if return_timestamps is not None: + generation_config.return_timestamps = return_timestamps + + if task is not None: + generation_config.task = task + + if is_multilingual is not None: + generation_config.is_multilingual = is_multilingual + + if language is not None: + generation_config.language = language + + if kwargs is not None and "decoder_input_ids" in kwargs: + decoder_input_length = len(kwargs["decoder_input_ids"]) + else: + decoder_input_length = 1 + + forced_decoder_ids = [] + + if hasattr(generation_config, "is_multilingual") and generation_config.is_multilingual: + if hasattr(generation_config, "language"): + forced_decoder_ids.append((1, generation_config.lang_to_id[generation_config.language])) + else: + forced_decoder_ids.append((1, None)) + + if hasattr(generation_config, "task"): + forced_decoder_ids.append((2, generation_config.task_to_id[generation_config.task])) + else: + forced_decoder_ids.append((2, generation_config.task_to_id["transcribe"])) + + if ( + hasattr(generation_config, "return_timestamps") and generation_config.return_timestamps + ) or return_timestamps: + logits_processor = [ + FlaxWhisperTimeStampLogitsProcessor(generation_config, self.config, decoder_input_length) + ] + else: + if forced_decoder_ids and forced_decoder_ids[-1][0] != generation_config.no_timestamps_token_id: + idx = forced_decoder_ids[-1][0] + 1 if forced_decoder_ids else 1 + forced_decoder_ids.append((idx, generation_config.no_timestamps_token_id)) + + if len(forced_decoder_ids) > 0: + generation_config.forced_decoder_ids = forced_decoder_ids + + return super().generate( + input_features, + generation_config, + logits_processor=logits_processor, + **kwargs, + ) + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + max_length, + attention_mask: Optional[jnp.DeviceArray] = None, + decoder_attention_mask: Optional[jnp.DeviceArray] = None, + encoder_outputs=None, + **kwargs, + ): + # initializing the cache + batch_size, seq_length = decoder_input_ids.shape + + past_key_values = self.init_cache(batch_size, max_length, encoder_outputs) + # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. + # But since the decoder uses a causal mask, those positions are masked anyways. + # Thus we can create a single static attention_mask here, which is more efficient for compilation + extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") + if decoder_attention_mask is not None: + position_ids = decoder_attention_mask.cumsum(-1) - 1 + extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, decoder_attention_mask, (0, 0)) + else: + position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) + + return { + "past_key_values": past_key_values, + "encoder_outputs": encoder_outputs, + "encoder_attention_mask": attention_mask, + "decoder_attention_mask": extended_attention_mask, + "decoder_position_ids": position_ids, + } + + def update_inputs_for_generation(self, model_outputs, model_kwargs): + model_kwargs["past_key_values"] = model_outputs.past_key_values + model_kwargs["decoder_position_ids"] = model_kwargs["decoder_position_ids"][:, -1:] + 1 + return model_kwargs + + +FLAX_WHISPER_CONDITIONAL_GENERATION_DOCSTRING = r""" + Returns: + + Transcription example: + + ```python + >>> from transformers import WhisperProcessor, FlaxWhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = WhisperProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = FlaxWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en", from_pt=True) + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="np") + >>> input_features = inputs.input_features + >>> generated_ids = model.generate(input_ids=input_features) + >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] + >>> transcription + ' Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.' + ``` +""" + +overwrite_call_docstring( + FlaxWhisperForConditionalGeneration, WHISPER_INPUTS_DOCSTRING + FLAX_WHISPER_CONDITIONAL_GENERATION_DOCSTRING +) +append_replace_return_docstrings( + FlaxWhisperForConditionalGeneration, output_type=FlaxSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC +) + + +class FlaxWhisperForAudioClassificationModule(nn.Module): + config: WhisperConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self) -> None: + self.encoder = FlaxWhisperEncoder(config=self.config, dtype=self.dtype) + self.config.is_encoder_decoder = False + num_layers = self.config.num_hidden_layers + 1 + if self.config.use_weighted_layer_sum: + self.layer_weights = jnp.repeat(1 / num_layers, num_layers) + self.projector = nn.Dense(self.config.classifier_proj_size, dtype=self.dtype) + self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_features, + encoder_outputs=None, + output_attentions=None, + output_hidden_states: bool = True, + return_dict: bool = True, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_features, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = jnp.stack(encoder_outputs, axis=1) + norm_weights = jax.nn.softmax(self.layer_weights, axis=-1) + hidden_states = jnp.sum(hidden_states * jnp.reshape(norm_weights, [-1, 1, 1]), axis=1) + else: + hidden_states = encoder_outputs[0] + + hidden_states = self.projector(hidden_states) + pooled_output = jnp.mean(hidden_states, axis=1) + + logits = self.classifier(pooled_output) + + if not return_dict: + return (logits,) + encoder_outputs[1:] + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings("The Whisper Model with an audio classification head on top.", WHISPER_START_DOCSTRING) +class FlaxWhisperForAudioClassification(FlaxWhisperPreTrainedModel): + module_class = FlaxWhisperForAudioClassificationModule + dtype: jnp.dtype = jnp.float32 + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_features = jnp.zeros(input_shape, dtype="f4") + input_features = input_features.at[(..., -1)].set(self.config.eos_token_id) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + random_params = self.module.init( + rngs, + input_features=input_features, + )["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + def __call__( + self, + input_features: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + dropout_rng: PRNGKey = None, + **kwargs, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + return self.module.apply( + {"params": params or self.params}, + input_features=jnp.array(input_features, dtype="f4"), + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + rngs=rngs, + ) + + +FLAX_WHISPER_AUDIO_CLASSIFICATION_DOCSTRING = r""" + Returns: + + Transcription example: + + ```python + >>> import jax.numpy as jnp + >>> from transformers import AutoFeatureExtractor, FlaxWhisperForAudioClassification + >>> from datasets import load_dataset + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("sanchit-gandhi/whisper-medium-fleurs-lang-id") + >>> model = FlaxWhisperForAudioClassification.from_pretrained( + ... "sanchit-gandhi/whisper-medium-fleurs-lang-id", from_pt=True + ... ) + >>> ds = load_dataset("google/fleurs", "all", split="validation", streaming=True) + + >>> sample = next(iter(ds)) + + >>> inputs = feature_extractor( + ... sample["audio"]["array"], sampling_rate=sample["audio"]["sampling_rate"], return_tensors="np" + ... ) + >>> input_features = inputs.input_features + + >>> logits = model(input_features).logits + + >>> predicted_class_ids = jnp.argmax(logits).item() + >>> predicted_label = model.config.id2label[predicted_class_ids] + >>> predicted_label + 'af_za' + ``` +""" + +overwrite_call_docstring( + FlaxWhisperForAudioClassification, WHISPER_INPUTS_DOCSTRING + FLAX_WHISPER_AUDIO_CLASSIFICATION_DOCSTRING +) +append_replace_return_docstrings( + FlaxWhisperForAudioClassification, output_type=FlaxSequenceClassifierOutput, config_class=_CONFIG_FOR_DOC +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_tf_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_tf_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..d9a175062b36ff39323ad9bb9a6ccf94ef34f6f4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_tf_whisper.py @@ -0,0 +1,1388 @@ +# coding=utf-8 +# Copyright 2022 The OpenAI Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TensorFlow Whisper model.""" + + +import math +import random +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFBaseModelOutputWithPastAndCrossAttentions, + TFSeq2SeqLMOutput, + TFSeq2SeqModelOutput, +) +from ...modeling_tf_utils import ( + TFCausalLanguageModelingLoss, + TFModelInputType, + TFPreTrainedModel, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_whisper import WhisperConfig + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "WhisperConfig" + + +TF_WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "openai/whisper-base", + # See all Whisper models at https://huggingface.co/models?filter=whisper +] + +LARGE_NEGATIVE = -1e8 + + +# Copied from transformers.models.bart.modeling_tf_bart.shift_tokens_right +def shift_tokens_right(input_ids: tf.Tensor, pad_token_id: int, decoder_start_token_id: int): + pad_token_id = tf.cast(pad_token_id, input_ids.dtype) + decoder_start_token_id = tf.cast(decoder_start_token_id, input_ids.dtype) + start_tokens = tf.fill( + (shape_list(input_ids)[0], 1), tf.convert_to_tensor(decoder_start_token_id, input_ids.dtype) + ) + shifted_input_ids = tf.concat([start_tokens, input_ids[:, :-1]], -1) + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids = tf.where( + shifted_input_ids == -100, + tf.fill(shape_list(shifted_input_ids), tf.convert_to_tensor(pad_token_id, input_ids.dtype)), + shifted_input_ids, + ) + + # "Verify that `labels` has only positive values and -100" + assert_gte0 = tf.debugging.assert_greater_equal(shifted_input_ids, tf.constant(0, dtype=input_ids.dtype)) + + # Make sure the assertion op is called by wrapping the result in an identity no-op + with tf.control_dependencies([assert_gte0]): + shifted_input_ids = tf.identity(shifted_input_ids) + + return shifted_input_ids + + +# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask +def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz = input_ids_shape[0] + tgt_len = input_ids_shape[1] + mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE + mask_cond = tf.range(shape_list(mask)[-1]) + + mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) + + if past_key_values_length > 0: + mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) + + return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) + + +# Copied from transformers.models.bart.modeling_tf_bart._expand_mask +def _expand_mask(mask: tf.Tensor, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + src_len = shape_list(mask)[1] + tgt_len = tgt_len if tgt_len is not None else src_len + one_cst = tf.constant(1.0) + mask = tf.cast(mask, dtype=one_cst.dtype) + expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) + + return (one_cst - expanded_mask) * LARGE_NEGATIVE + + +class TFWhisperPositionalEmbedding(tf.keras.layers.Layer): + def __init__(self, num_positions: int, embedding_dim: int, padding_idx: Optional[int] = None, **kwargs): + super().__init__(**kwargs) + self.num_positions = num_positions + self.embedding_dim = embedding_dim + self.padding_idx = padding_idx + + def build(self, input_shape): + self.weight = self.add_weight( + name="weight", + shape=[self.num_positions, self.embedding_dim], + trainable=True, + ) + super().build(input_shape) + + def call(self, input_ids, past_key_values_length=0): + past_key_values_length = tf.cast(past_key_values_length, tf.int32) + gather_indices = tf.range(tf.shape(input_ids)[1], delta=1) + past_key_values_length + return tf.gather(self.weight, gather_indices) + + +class TFWhisperAttention(tf.keras.layers.Layer): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + **kwargs, + ): + super().__init__(**kwargs) + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = tf.keras.layers.Dropout(dropout) + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = tf.keras.layers.Dense(embed_dim, use_bias=False, name="k_proj") + self.v_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") + self.q_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") + self.out_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") + + # Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention._shape with BART->whisper + def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): + return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) + + # Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention.call with BART->whisper + def call( + self, + hidden_states: tf.Tensor, + key_value_states: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[Tuple[tf.Tensor]]] = None, + attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, Optional[tf.Tensor]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + bsz, tgt_len, embed_dim = shape_list(hidden_states) + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = tf.concat([past_key_value[0], key_states], axis=2) + value_states = tf.concat([past_key_value[1], value_states], axis=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) + key_states = tf.reshape(key_states, proj_shape) + value_states = tf.reshape(value_states, proj_shape) + + src_len = shape_list(key_states)[1] + attn_weights = tf.matmul(query_states, key_states, transpose_b=True) + + tf.debugging.assert_equal( + shape_list(attn_weights), + [bsz * self.num_heads, tgt_len, src_len], + message=( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {shape_list(attn_weights)}" + ), + ) + + if attention_mask is not None: + tf.debugging.assert_equal( + shape_list(attention_mask), + [bsz, 1, tgt_len, src_len], + message=( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {shape_list(attention_mask)}" + ), + ) + + attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) + attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_weights = stable_softmax(attn_weights, axis=-1) + + if layer_head_mask is not None: + tf.debugging.assert_equal( + shape_list(layer_head_mask), + [self.num_heads], + message=( + f"Head mask for a single layer should be of size {(self.num_heads)}, but is" + f" {shape_list(layer_head_mask)}" + ), + ) + + attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( + attn_weights, (bsz, self.num_heads, tgt_len, src_len) + ) + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_probs = self.dropout(attn_weights, training=training) + attn_output = tf.matmul(attn_probs, value_states) + + tf.debugging.assert_equal( + shape_list(attn_output), + [bsz * self.num_heads, tgt_len, self.head_dim], + message=( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {shape_list(attn_output)}" + ), + ) + + attn_output = tf.transpose( + tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) + ) + attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) + + attn_output = self.out_proj(attn_output) + attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + + return attn_output, attn_weights, past_key_value + + +# Copied from transformers.models.speech_to_text.modeling_tf_speech_to_text.TFSpeech2TextEncoderLayer with Speech2Text->Whisper +class TFWhisperEncoderLayer(tf.keras.layers.Layer): + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(**kwargs) + self.embed_dim = config.d_model + self.self_attn = TFWhisperAttention( + self.embed_dim, config.encoder_attention_heads, dropout=config.attention_dropout, name="self_attn" + ) + self.self_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation_fn = get_tf_activation(config.activation_function) + self.activation_dropout = tf.keras.layers.Dropout(config.activation_dropout) + self.fc1 = tf.keras.layers.Dense(config.encoder_ffn_dim, name="fc1") + self.fc2 = tf.keras.layers.Dense(self.embed_dim, name="fc2") + self.final_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") + + def call( + self, hidden_states: tf.Tensor, attention_mask: tf.Tensor, layer_head_mask: tf.Tensor, training: bool = False + ): + """ + Args: + hidden_states (`tf.Tensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`tf.Tensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)` + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + hidden_states, self_attn_weights, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + training=training, + ) + + tf.debugging.assert_equal( + shape_list(hidden_states), + shape_list(residual), + message=f"Self attn modified the shape of query {shape_list(residual)} to {shape_list(hidden_states)}", + ) + + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout(hidden_states, training=training) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + return hidden_states, self_attn_weights + + +# Copied from transformers.models.speech_to_text.modeling_tf_speech_to_text.TFSpeech2TextDecoderLayer with Speech2Text->Whisper +class TFWhisperDecoderLayer(tf.keras.layers.Layer): + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(**kwargs) + self.embed_dim = config.d_model + + self.self_attn = TFWhisperAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + name="self_attn", + is_decoder=True, + ) + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation_fn = get_tf_activation(config.activation_function) + self.activation_dropout = tf.keras.layers.Dropout(config.activation_dropout) + + self.self_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") + self.encoder_attn = TFWhisperAttention( + self.embed_dim, + config.decoder_attention_heads, + dropout=config.attention_dropout, + name="encoder_attn", + is_decoder=True, + ) + self.encoder_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="encoder_attn_layer_norm") + self.fc1 = tf.keras.layers.Dense(config.decoder_ffn_dim, name="fc1") + self.fc2 = tf.keras.layers.Dense(self.embed_dim, name="fc2") + self.final_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") + + def call( + self, + hidden_states, + attention_mask: Optional[tf.Tensor] = None, + encoder_hidden_states: Optional[tf.Tensor] = None, + encoder_attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + cross_attn_layer_head_mask: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[tf.Tensor]] = None, + training=False, + ) -> Tuple[tf.Tensor, tf.Tensor, Tuple[Tuple[tf.Tensor]]]: + """ + Args: + hidden_states (`tf.Tensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`tf.Tensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + encoder_hidden_states (`tf.Tensor`): + cross attention input to the layer of shape `(seq_len, batch, embed_dim)` + encoder_attention_mask (`tf.Tensor`): encoder attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size + `(decoder_attention_heads,)` + cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. + `(decoder_attention_heads,)` + past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + training=training, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + training=training, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout(hidden_states, training=training) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + return ( + hidden_states, + self_attn_weights, + cross_attn_weights, + present_key_value, + ) + + +class TFWhisperPreTrainedModel(TFPreTrainedModel): + config_class = WhisperConfig + base_model_prefix = "model" + main_input_name = "input_features" + + def _get_feat_extract_output_lengths(self, input_lengths: tf.Tensor) -> int: + """ + Computes the output length of the convolutional layers + """ + input_lengths = (input_lengths - 1) // 2 + 1 + + return input_lengths + + @property + def dummy_inputs(self) -> Dict[str, tf.Tensor]: + """ + Dummy inputs to build the network. + + Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + return { + self.main_input_name: tf.random.uniform( + [2, self.config.num_mel_bins, self.config.max_source_positions * 2 - 1], dtype=tf.float32 + ), + "decoder_input_ids": tf.constant([[2, 3]], dtype=tf.int32), + } + + @tf.function( + input_signature=[ + { + "input_features": tf.TensorSpec((None, None, None), tf.float32, name="input_features"), + "decoder_input_ids": tf.TensorSpec((None, None), tf.int32, name="decoder_input_ids"), + "decoder_attention_mask": tf.TensorSpec((None, None), tf.int32, name="decoder_attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + return self.serving_output(output) + + +WHISPER_START_DOCSTRING = r""" + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`WhisperConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +WHISPER_INPUTS_DOCSTRING = r""" + Args: + input_features (`tf.Tensor` of shape `(batch_size, feature_size, sequence_length)`): + Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be obtained + by loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* + via the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`AutoFeatureExtractor`] should be used for extracting the fbank features, padding and conversion into a + tensor of type `tf.Tensor`. See [`~WhisperFeatureExtractor.__call__`] + decoder_input_ids (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`SpeechToTextTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + SpeechToText uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If + `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see + `past_key_values`). + decoder_attention_mask (`tf.Tensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + + If you want to change padding behavior, you should read + [`modeling_whisper._prepare_decoder_attention_mask`] and modify to your needs. See diagram 1 in [the + paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + decoder_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + encoder_outputs (`tuple(tuple(tf.Tensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape + `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention + blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + decoder_inputs_embeds (`tf.Tensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded + representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be + input (see `past_key_values`). This is useful if you want more control over how to convert + `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@keras_serializable +class TFWhisperEncoder(tf.keras.layers.Layer): + config_class = WhisperConfig + """ + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`TFWhisperEncoderLayer`]. + + Args: + config: WhisperConfig + embed_tokens (TFWhisperEmbedding): output embedding + """ + + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + self.layerdrop = config.encoder_layerdrop + + self.embed_dim = config.d_model + self.num_mel_bins = config.num_mel_bins + self.padding_idx = config.pad_token_id + self.max_source_positions = config.max_source_positions + self.embed_scale = math.sqrt(self.embed_dim) if config.scale_embedding else 1.0 + + # Padding is added in call() to match the PyTorch implementation + self.conv1 = tf.keras.layers.Conv1D(self.embed_dim, kernel_size=3, strides=1, padding="valid", name="conv1") + self.conv2 = tf.keras.layers.Conv1D(self.embed_dim, kernel_size=3, strides=2, padding="valid", name="conv2") + + self.embed_positions = TFWhisperPositionalEmbedding( + self.max_source_positions, self.embed_dim, name="embed_positions" + ) + + self.encoder_layers = [TFWhisperEncoderLayer(config, name=f"layers.{i}") for i in range(config.encoder_layers)] + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") + + self.dropout = tf.keras.layers.Dropout(config.dropout) + + @unpack_inputs + def call( + self, + input_features=None, + head_mask=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ): + r""" + Args: + input_features (`tf.Tensor` of shape `(batch_size, feature_size, sequence_length)`): + Float values of fbank features extracted from the raw speech waveform. Raw speech waveform can be + obtained by loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a + `numpy.ndarray`, *e.g.* via the soundfile library (`pip install soundfile`). To prepare the array into + `input_features`, the [`AutoFeatureExtractor`] should be used for extracting the fbank features, + padding and conversion into a tensor of type `tf.Tensor`. See [`~WhisperFeatureExtractor.__call__`] + head_mask (`tf.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # TF 2.0 layers can't use channels first format when running on CPU. + input_features = tf.transpose(input_features, perm=(0, 2, 1)) + input_features = tf.pad(input_features, [[0, 0], [1, 1], [0, 0]]) + inputs_embeds = tf.keras.activations.gelu(self.conv1(input_features)) + inputs_embeds = tf.pad(inputs_embeds, [[0, 0], [1, 1], [0, 0]]) + inputs_embeds = tf.keras.activations.gelu(self.conv2(inputs_embeds)) + inputs_embeds = tf.transpose(inputs_embeds, perm=(0, 1, 2)) + + embed_pos = self.embed_positions(input_ids=tf.zeros((1, self.max_source_positions), dtype=tf.int32)) + + hidden_states = inputs_embeds + embed_pos + hidden_states = self.dropout(hidden_states, training=training) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + # check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + tf.debugging.assert_equal( + shape_list(head_mask)[0], + len(self.encoder_layers), + message=( + f"The head_mask should be specified for {len(self.encoder_layers)} layers, but it is for" + f" {shape_list(head_mask)[0]}." + ), + ) + + for idx, encoder_layer in enumerate(self.encoder_layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if training and (dropout_probability < self.layerdrop): # skip the layer + continue + + hidden_states, attn = encoder_layer( + hidden_states, + None, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + training=training, + ) + + if output_attentions: + all_attentions += (attn,) + + hidden_states = self.layer_norm(hidden_states) + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return TFBaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +@keras_serializable +class TFWhisperDecoder(tf.keras.layers.Layer): + config_class = WhisperConfig + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`TFWhisperDecoderLayer`] + + Args: + config: WhisperConfig + """ + + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.layerdrop = config.decoder_layerdrop + self.padding_idx = config.pad_token_id + self.max_target_positions = config.max_target_positions + self.max_source_positions = config.max_source_positions + self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 + + self.embed_tokens = tf.keras.layers.Embedding( + input_dim=config.vocab_size, + output_dim=config.d_model, + embeddings_initializer=tf.keras.initializers.TruncatedNormal(stddev=self.config.init_std), + name="embed_tokens", + ) + self.embed_positions = TFWhisperPositionalEmbedding( + self.max_target_positions, config.d_model, name="embed_positions" + ) + + self.decoder_layers = [TFWhisperDecoderLayer(config, name=f"layers.{i}") for i in range(config.decoder_layers)] + + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") + + def get_input_embeddings(self): + return self.embed_tokens + + def set_input_embeddings(self, value): + self.embed_tokens = value + + def _prepare_decoder_attention_mask(self, attention_mask, input_shape, past_key_values_length): + # create causal mask + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + batch_size, seq_len = input_shape[0], input_shape[1] + + combined_attention_mask = tf.cond( + tf.math.greater(seq_len, 1), + lambda: _make_causal_mask(input_shape, past_key_values_length=past_key_values_length), + lambda: _expand_mask(tf.ones((batch_size, seq_len + past_key_values_length)), tgt_len=seq_len), + ) + + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + expanded_attn_mask = _expand_mask(attention_mask, tgt_len=input_shape[-1]) + combined_attention_mask = ( + expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask + ) + return combined_attention_mask + + @unpack_inputs + def call( + self, + input_ids=None, + attention_mask=None, + position_ids=None, + encoder_hidden_states=None, + head_mask=None, + cross_attn_head_mask=None, + past_key_values=None, + inputs_embeds=None, + use_cache=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ): + r""" + Args: + input_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each decoder input sequence tokens in the position embeddings. Selected in the + range `[0, config.max_position_embeddings - 1]`. + encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`tf.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in encoder to avoid performing cross-attention + on hidden heads. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(tf.Tensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(tf.Tensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape + `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the + cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those + that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of + all `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`tf.Tensor` of shape + `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing `input_ids` + you can choose to directly pass an embedded representation. This is useful if you want more control + over how to convert `input_ids` indices into associated vectors than the model's internal embedding + lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") + elif input_ids is not None: + input_shape = tf.shape(input_ids) + input_ids = tf.reshape(input_ids, (-1, input_shape[-1])) + elif inputs_embeds is not None: + input_shape = tf.shape(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if inputs_embeds is None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.embed_tokens.input_dim, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.embed_tokens.input_dim})" + ), + ) + inputs_embeds = self.embed_tokens(input_ids) + + attention_mask = self._prepare_decoder_attention_mask(attention_mask, input_shape, past_key_values_length) + + # embed positions + filled_past_positions = past_key_values_length if position_ids is None else position_ids[0, -1] + positions = self.embed_positions(input_ids, past_key_values_length=filled_past_positions) + + hidden_states = inputs_embeds + positions + hidden_states = self.dropout(hidden_states, training=training) + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + next_decoder_cache = () if use_cache else None + + # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired + for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: + if attn_mask is not None: + tf.debugging.assert_equal( + shape_list(attn_mask)[0], + len(self.decoder_layers), + message=( + f"The {attn_mask_name} should be specified for {len(self.decoder_layers)} layers, but it is" + f" for {shape_list(attn_mask)[0]}." + ), + ) + + for idx, decoder_layer in enumerate(self.decoder_layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + dropout_probability = random.uniform(0, 1) + if training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=(cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None), + past_key_value=past_key_value, + training=training, + ) + hidden_states = layer_outputs[0] + + if use_cache: + next_decoder_cache += (layer_outputs[3],) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + hidden_states = self.layer_norm(hidden_states) + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + next_cache = next_decoder_cache if use_cache else None + if not return_dict: + return tuple( + v + for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] + if v is not None + ) + return TFBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_cache, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + "The bare Whisper Model outputting raw hidden-states without any specific head on top.", + WHISPER_START_DOCSTRING, +) +@keras_serializable +class TFWhisperMainLayer(tf.keras.layers.Layer): + config_class = WhisperConfig + + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + self.encoder = TFWhisperEncoder(config, name="encoder") + self.decoder = TFWhisperDecoder(config, name="decoder") + + def get_input_embeddings(self): + return self.decoder.embed_tokens + + def set_input_embeddings(self, value): + self.decoder.embed_tokens = value + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + @unpack_inputs + def call( + self, + input_features=None, + decoder_input_ids=None, + decoder_attention_mask=None, + decoder_position_ids=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, + encoder_outputs=None, + past_key_values=None, + decoder_inputs_embeds=None, + use_cache=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ): + r""" + Returns: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import TFWhisperModel, AutoFeatureExtractor + >>> from datasets import load_dataset + + >>> model = TFWhisperModel.from_pretrained("openai/whisper-base") + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base") + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="tf") + >>> input_features = inputs.input_features + >>> decoder_input_ids = tf.convert_to_tensor([[1, 1]]) * model.config.decoder_start_token_id + >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state + >>> list(last_hidden_state.shape) + [1, 2, 512] + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_features, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a TFBaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, TFBaseModelOutput): + encoder_outputs = TFBaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn) + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + position_ids=decoder_position_ids, + encoder_hidden_states=encoder_outputs[0], + head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return TFSeq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + past_key_values=decoder_outputs.past_key_values, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + "The bare Whisper Model outputting raw hidden-states without any specific head on top.", + WHISPER_START_DOCSTRING, +) +class TFWhisperModel(TFWhisperPreTrainedModel): + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(config, **kwargs) + + self.model = TFWhisperMainLayer(config, name="model") + + def get_input_embeddings(self): + return self.model.decoder.embed_tokens + + def set_input_embeddings(self, value): + self.model.decoder.embed_tokens = value + + def get_encoder(self): + return self.model.encoder + + def get_decoder(self): + return self.model.decoder + + def decoder(self): + return self.model.decoder + + def encoder(self): + return self.model.encoder + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSeq2SeqModelOutput, config_class=_CONFIG_FOR_DOC) + @unpack_inputs + def call( + self, + input_features: Optional[TFModelInputType] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + decoder_inputs_embeds: Optional[Tuple[Union[np.ndarray, tf.Tensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[Tuple[tf.Tensor], TFSeq2SeqModelOutput]: + r""" + Returns: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import TFWhisperModel, AutoFeatureExtractor + >>> from datasets import load_dataset + + >>> model = TFWhisperModel.from_pretrained("openai/whisper-base") + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base") + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="tf") + >>> input_features = inputs.input_features + >>> decoder_input_ids = tf.convert_to_tensor([[1, 1]]) * model.config.decoder_start_token_id + >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state + >>> list(last_hidden_state.shape) + [1, 2, 512] + ```""" + outputs = self.model( + input_features=input_features, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + past_key_values=past_key_values, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + return outputs + + def serving_output(self, output): + pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None + dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None + dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None + enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None + enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None + + return TFSeq2SeqModelOutput( + last_hidden_state=output.last_hidden_state, + past_key_values=pkv, + decoder_hidden_states=dec_hs, + decoder_attentions=dec_attns, + cross_attentions=cross_attns, + encoder_last_hidden_state=output.encoder_last_hidden_state, + encoder_hidden_states=enc_hs, + encoder_attentions=enc_attns, + ) + + +@add_start_docstrings( + "The Whisper Model with a language modeling head. Can be used for automatic speech recognition.", + WHISPER_START_DOCSTRING, +) +class TFWhisperForConditionalGeneration(TFWhisperPreTrainedModel, TFCausalLanguageModelingLoss): + base_model_prefix = "model" + _keys_to_ignore_on_load_missing = [ + r"encoder.version", + r"decoder.version", + r"proj_out.weight", + ] + _keys_to_ignore_on_save = [ + r"proj_out.weight", + ] + + def __init__(self, config: WhisperConfig, **kwargs): + super().__init__(config, **kwargs) + self.model = TFWhisperMainLayer(config, name="model") + + def get_encoder(self): + return self.model.get_encoder() + + def get_decoder(self): + return self.model.get_decoder() + + def get_output_embeddings(self): + return self.get_input_embeddings() + + def set_output_embeddings(self, value): + self.set_input_embeddings(value) + + def resize_token_embeddings(self, new_num_tokens: int) -> tf.keras.layers.Embedding: + new_embeddings = super().resize_token_embeddings(new_num_tokens) + return new_embeddings + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + @unpack_inputs + def call( + self, + input_features: Optional[TFModelInputType] = None, + decoder_input_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + decoder_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_outputs: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + decoder_inputs_embeds: Optional[Tuple[Union[np.ndarray, tf.Tensor]]] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[Tuple[tf.Tensor], TFSeq2SeqLMOutput]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the language modeling loss. Indices should either be in `[0, ..., config.vocab_size]` + or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored (masked), the loss is + only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Returns: + + Example: + + ```python + >>> import tensorflow as tf + >>> from transformers import AutoProcessor, TFWhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = AutoProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = TFWhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en") + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="tf") + >>> input_features = inputs.input_features + + >>> generated_ids = model.generate(input_features=input_features) + + >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] + >>> transcription + ' Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.' + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if labels is not None: + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + outputs = self.model( + input_features, + decoder_input_ids=decoder_input_ids, + encoder_outputs=encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + decoder_position_ids=decoder_position_ids, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + decoder_last_hidden_state = outputs[0] + # Decoder and encoder embeddings are tied + lm_logits = tf.matmul(decoder_last_hidden_state, self.get_output_embeddings().weights, transpose_b=True) + + loss = None if labels is None else self.hf_compute_loss(labels, lm_logits) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFSeq2SeqLMOutput( + loss=loss, + logits=lm_logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + def serving_output(self, output): + pkv = tf.tuple(output.past_key_values)[1] if self.config.use_cache else None + dec_hs = tf.convert_to_tensor(output.decoder_hidden_states) if self.config.output_hidden_states else None + dec_attns = tf.convert_to_tensor(output.decoder_attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if self.config.output_attentions else None + enc_hs = tf.convert_to_tensor(output.encoder_hidden_states) if self.config.output_hidden_states else None + enc_attns = tf.convert_to_tensor(output.encoder_attentions) if self.config.output_attentions else None + + return TFSeq2SeqLMOutput( + logits=output.logits, + past_key_values=pkv, + decoder_hidden_states=dec_hs, + decoder_attentions=dec_attns, + cross_attentions=cross_attns, + encoder_last_hidden_state=output.encoder_last_hidden_state, + encoder_hidden_states=enc_hs, + encoder_attentions=enc_attns, + ) + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + past_key_values=None, + use_cache=None, + encoder_outputs=None, + attention_mask=None, + decoder_attention_mask=None, + **kwargs, + ): + # cut decoder_input_ids if past is used + if past_key_values is not None: + decoder_input_ids = decoder_input_ids[:, -1:] + + if decoder_attention_mask is not None: # xla + decoder_position_ids = tf.math.cumsum(decoder_attention_mask, axis=-1, exclusive=True)[:, -1:] + elif past_key_values is not None: # no xla + past + decoder_position_ids = past_key_values[0][0].shape[2] + else: # no xla + no past + decoder_position_ids = tf.range(decoder_input_ids.shape[1]) + decoder_position_ids = tf.broadcast_to(decoder_position_ids, decoder_input_ids.shape) + + return { + "input_features": None, # Needs to be passed to make Keras.layer.__call__ happy + "encoder_outputs": encoder_outputs, + "past_key_values": past_key_values, + "decoder_input_ids": decoder_input_ids, + "use_cache": use_cache, + "decoder_attention_mask": decoder_attention_mask, + "decoder_position_ids": decoder_position_ids, + } diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..91de6810b17eb0444c2ebe54330e3867516413ae --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/modeling_whisper.py @@ -0,0 +1,1782 @@ +# coding=utf-8 +# Copyright 2022 The OpenAI Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch Whisper model.""" + +import math +import random +from typing import Optional, Tuple, Union + +import numpy as np +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...generation.logits_process import WhisperTimeStampLogitsProcessor +from ...modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPastAndCrossAttentions, + Seq2SeqLMOutput, + Seq2SeqModelOutput, + SequenceClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings +from .configuration_whisper import WhisperConfig +from .tokenization_whisper import TASK_IDS, TO_LANGUAGE_CODE + + +logger = logging.get_logger(__name__) + +_CONFIG_FOR_DOC = "WhisperConfig" +_CHECKPOINT_FOR_DOC = "openai/whisper-tiny" + + +WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "openai/whisper-base", + # See all Whisper models at https://huggingface.co/models?filter=whisper +] + + +# Copied from transformers.models.bart.modeling_bart.shift_tokens_right +def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int): + """ + Shift input ids one token to the right. + """ + shifted_input_ids = input_ids.new_zeros(input_ids.shape) + shifted_input_ids[:, 1:] = input_ids[:, :-1].clone() + shifted_input_ids[:, 0] = decoder_start_token_id + + if pad_token_id is None: + raise ValueError("self.model.config.pad_token_id has to be defined.") + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id) + + return shifted_input_ids + + +# Copied from transformers.models.bart.modeling_bart._make_causal_mask +def _make_causal_mask( + input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0 +): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz, tgt_len = input_ids_shape + mask = torch.full((tgt_len, tgt_len), torch.tensor(torch.finfo(dtype).min, device=device), device=device) + mask_cond = torch.arange(mask.size(-1), device=device) + mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0) + mask = mask.to(dtype) + + if past_key_values_length > 0: + mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1) + return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length) + + +# Copied from transformers.models.bart.modeling_bart._expand_mask +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + bsz, src_len = mask.size() + tgt_len = tgt_len if tgt_len is not None else src_len + + expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min) + + +# Copied from transformers.models.wav2vec2.modeling_wav2vec2._compute_mask_indices +def _compute_mask_indices( + shape: Tuple[int, int], + mask_prob: float, + mask_length: int, + attention_mask: Optional[torch.LongTensor] = None, + min_masks: int = 0, +) -> np.ndarray: + """ + Computes random mask spans for a given shape. Used to implement [SpecAugment: A Simple Data Augmentation Method for + ASR](https://arxiv.org/abs/1904.08779). Note that this method is not optimized to run on TPU and should be run on + CPU as part of the preprocessing during training. + + Args: + shape: The shape for which to compute masks. This should be of a tuple of size 2 where + the first element is the batch size and the second element is the length of the axis to span. + mask_prob: The percentage of the whole axis (between 0 and 1) which will be masked. The number of + independently generated mask spans of length `mask_length` is computed by + `mask_prob*shape[1]/mask_length`. Note that due to overlaps, `mask_prob` is an upper bound and the + actual percentage will be smaller. + mask_length: size of the mask + min_masks: minimum number of masked spans + attention_mask: A (right-padded) attention mask which independently shortens the feature axis of + each batch dimension. + """ + batch_size, sequence_length = shape + + if mask_length < 1: + raise ValueError("`mask_length` has to be bigger than 0.") + + if mask_length > sequence_length: + raise ValueError( + f"`mask_length` has to be smaller than `sequence_length`, but got `mask_length`: {mask_length}" + f" and `sequence_length`: {sequence_length}`" + ) + + # epsilon is used for probabilistic rounding + epsilon = np.random.rand(1).item() + + def compute_num_masked_span(input_length): + """Given input length, compute how many spans should be masked""" + num_masked_span = int(mask_prob * input_length / mask_length + epsilon) + num_masked_span = max(num_masked_span, min_masks) + + # make sure num masked span <= sequence_length + if num_masked_span * mask_length > sequence_length: + num_masked_span = sequence_length // mask_length + + # make sure num_masked span is also <= input_length - (mask_length - 1) + if input_length - (mask_length - 1) < num_masked_span: + num_masked_span = max(input_length - (mask_length - 1), 0) + + return num_masked_span + + # compute number of masked spans in batch + input_lengths = ( + attention_mask.sum(-1).detach().tolist() + if attention_mask is not None + else [sequence_length for _ in range(batch_size)] + ) + + # SpecAugment mask to fill + spec_aug_mask = np.zeros((batch_size, sequence_length), dtype=bool) + spec_aug_mask_idxs = [] + + max_num_masked_span = compute_num_masked_span(sequence_length) + + if max_num_masked_span == 0: + return spec_aug_mask + + for input_length in input_lengths: + # compute num of masked spans for this input + num_masked_span = compute_num_masked_span(input_length) + + # get random indices to mask + spec_aug_mask_idx = np.random.choice( + np.arange(input_length - (mask_length - 1)), num_masked_span, replace=False + ) + + # pick first sampled index that will serve as a dummy index to pad vector + # to ensure same dimension for all batches due to probabilistic rounding + # Picking first sample just pads those vectors twice. + if len(spec_aug_mask_idx) == 0: + # this case can only happen if `input_length` is strictly smaller then + # `sequence_length` in which case the last token has to be a padding + # token which we can use as a dummy mask id + dummy_mask_idx = sequence_length - 1 + else: + dummy_mask_idx = spec_aug_mask_idx[0] + + spec_aug_mask_idx = np.concatenate( + [spec_aug_mask_idx, np.ones(max_num_masked_span - num_masked_span, dtype=np.int32) * dummy_mask_idx] + ) + spec_aug_mask_idxs.append(spec_aug_mask_idx) + + spec_aug_mask_idxs = np.array(spec_aug_mask_idxs) + + # expand masked indices to masked spans + spec_aug_mask_idxs = np.broadcast_to( + spec_aug_mask_idxs[:, :, None], (batch_size, max_num_masked_span, mask_length) + ) + spec_aug_mask_idxs = spec_aug_mask_idxs.reshape(batch_size, max_num_masked_span * mask_length) + + # add offset to the starting indexes so that indexes now create a span + offsets = np.arange(mask_length)[None, None, :] + offsets = np.broadcast_to(offsets, (batch_size, max_num_masked_span, mask_length)).reshape( + batch_size, max_num_masked_span * mask_length + ) + spec_aug_mask_idxs = spec_aug_mask_idxs + offsets + + # ensure that we cannot have indices larger than sequence_length + if spec_aug_mask_idxs.max() > sequence_length - 1: + spec_aug_mask_idxs[spec_aug_mask_idxs > sequence_length - 1] = sequence_length - 1 + + # scatter indices to mask + np.put_along_axis(spec_aug_mask, spec_aug_mask_idxs, 1, -1) + + return spec_aug_mask + + +class WhisperPositionalEmbedding(nn.Embedding): + def __init__(self, num_positions: int, embedding_dim: int, padding_idx: Optional[int] = None): + super().__init__(num_positions, embedding_dim) + + def forward(self, input_ids, past_key_values_length=0): + return self.weight[past_key_values_length : past_key_values_length + input_ids.shape[1]] + + +class WhisperAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=False) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + # Copied from transformers.models.bart.modeling_bart.BartAttention._shape with BART->whisper + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + # Copied from transformers.models.bart.modeling_bart.BartAttention.forward with BART->whisper + def forward( + self, + hidden_states: torch.Tensor, + key_value_states: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + + bsz, tgt_len, _ = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + # `past_key_value[0].shape[2] == key_value_states.shape[1]` + # is checking that the `sequence_length` of the `past_key_value` is the same as + # the provided `key_value_states` to support prefix tuning + if ( + is_cross_attention + and past_key_value is not None + and past_key_value[0].shape[2] == key_value_states.shape[1] + ): + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = torch.cat([past_key_value[0], key_states], dim=2) + value_states = torch.cat([past_key_value[1], value_states], dim=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.reshape(*proj_shape) + value_states = value_states.reshape(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if layer_head_mask is not None: + if layer_head_mask.size() != (self.num_heads,): + raise ValueError( + f"Head mask for a single layer should be of size {(self.num_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to be reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz * self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + + # Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be + # partitioned across GPUs when using tensor-parallelism. + attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped, past_key_value + + +# Copied from transformers.models.mbart.modeling_mbart.MBartEncoderLayer with MBart->Whisper +class WhisperEncoderLayer(nn.Module): + def __init__(self, config: WhisperConfig): + super().__init__() + self.embed_dim = config.d_model + self.self_attn = WhisperAttention( + embed_dim=self.embed_dim, + num_heads=config.encoder_attention_heads, + dropout=config.attention_dropout, + ) + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim) + self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + layer_head_mask: torch.Tensor, + output_attentions: bool = False, + ) -> torch.Tensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(seq_len, batch, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + hidden_states, attn_weights, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + if hidden_states.dtype == torch.float16 and ( + torch.isinf(hidden_states).any() or torch.isnan(hidden_states).any() + ): + clamp_value = torch.finfo(hidden_states.dtype).max - 1000 + hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +# Copied from transformers.models.mbart.modeling_mbart.MBartDecoderLayer with MBart->Whisper +class WhisperDecoderLayer(nn.Module): + def __init__(self, config: WhisperConfig): + super().__init__() + self.embed_dim = config.d_model + + self.self_attn = WhisperAttention( + embed_dim=self.embed_dim, + num_heads=config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.encoder_attn = WhisperAttention( + self.embed_dim, + config.decoder_attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim) + self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + cross_attn_layer_head_mask: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + output_attentions: Optional[bool] = False, + use_cache: Optional[bool] = True, + ) -> torch.Tensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(batch, seq_len, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of + size `(decoder_attention_heads,)`. + past_key_value (`Tuple(torch.FloatTensor)`): cached past key and value projection states + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + if use_cache: + outputs += (present_key_value,) + + return outputs + + +class WhisperPreTrainedModel(PreTrainedModel): + config_class = WhisperConfig + base_model_prefix = "model" + main_input_name = "input_features" + supports_gradient_checkpointing = True + _no_split_modules = ["WhisperEncoderLayer", "WhisperDecoderLayer"] + + def _init_weights(self, module): + std = self.config.init_std + if isinstance(module, (nn.Linear, nn.Conv1d)): + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (WhisperDecoder, WhisperEncoder)): + module.gradient_checkpointing = value + + def _get_feat_extract_output_lengths(self, input_lengths: torch.LongTensor): + """ + Computes the output length of the convolutional layers + """ + input_lengths = (input_lengths - 1) // 2 + 1 + + return input_lengths + + +WHISPER_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`WhisperConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +WHISPER_INPUTS_DOCSTRING = r""" + Args: + input_features (`torch.FloatTensor` of shape `(batch_size, feature_size, sequence_length)`): + Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by + loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via + the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`AutoFeatureExtractor`] should be used for extracting the mel features, padding and conversion into a + tensor of type `torch.FloatTensor`. See [`~WhisperFeatureExtractor.__call__`] + attention_mask (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing *SpecAugment* data augmentation on padding token indices. Mask values selected in + `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + Whisper uses the `decoder_start_token_id` as the starting token for `decoder_input_ids` generation. If + `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see + `past_key_values`). + decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + + If you want to change padding behavior, you should read + [`modeling_whisper._prepare_decoder_attention_mask`] and modify to your needs. See diagram 1 in [the BART + paper](https://arxiv.org/abs/1910.13461) for more information on the default strategy. + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + decoder_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape + `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention + blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + decoder_inputs_embeds (`torch.FloatTensor` of shape `(batch_size, target_sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `decoder_input_ids` you can choose to directly pass an embedded + representation. If `past_key_values` is used, optionally only the last `decoder_inputs_embeds` have to be + input (see `past_key_values`). This is useful if you want more control over how to convert + `decoder_input_ids` indices into associated vectors than the model's internal embedding lookup matrix. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +WHISPER_ENCODER_INPUTS_DOCSTRING = r""" + Args: + input_features (`torch.FloatTensor` of shape `(batch_size, feature_size, sequence_length)`): + Float values mel features extracted from the raw speech waveform. Raw speech waveform can be obtained by + loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a `numpy.ndarray`, *e.g.* via + the soundfile library (`pip install soundfile`). To prepare the array into `input_features`, the + [`AutoFeatureExtractor`] should be used for extracting the mel features, padding and conversion into a + tensor of type `torch.FloatTensor`. See [`~WhisperFeatureExtractor.__call__`] + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +class WhisperEncoder(WhisperPreTrainedModel): + """ + Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a + [`WhisperEncoderLayer`]. + + Args: + config: WhisperConfig + """ + + def __init__(self, config: WhisperConfig): + super().__init__(config) + self.dropout = config.dropout + self.layerdrop = config.encoder_layerdrop + + embed_dim = config.d_model + self.num_mel_bins = config.num_mel_bins + self.padding_idx = config.pad_token_id + self.max_source_positions = config.max_source_positions + self.embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0 + + self.conv1 = nn.Conv1d(self.num_mel_bins, embed_dim, kernel_size=3, padding=1) + self.conv2 = nn.Conv1d(embed_dim, embed_dim, kernel_size=3, stride=2, padding=1) + + self.embed_positions = nn.Embedding(self.max_source_positions, embed_dim) + + self.layers = nn.ModuleList([WhisperEncoderLayer(config) for _ in range(config.encoder_layers)]) + self.layer_norm = nn.LayerNorm(config.d_model) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def _freeze_parameters(self): + for param in self.parameters(): + param.requires_grad = False + self._requires_grad = False + + def get_input_embeddings(self) -> nn.Module: + return self.conv1 + + def set_input_embeddings(self, value: nn.Module): + self.conv1 = value + + def forward( + self, + input_features, + attention_mask=None, + head_mask=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + input_features (`torch.LongTensor` of shape `(batch_size, feature_size, sequence_length)`): + Float values of mel features extracted from the raw speech waveform. Raw speech waveform can be + obtained by loading a `.flac` or `.wav` audio file into an array of type `List[float]` or a + `numpy.ndarray`, *e.g.* via the soundfile library (`pip install soundfile`). To prepare the array into + `input_features`, the [`AutoFeatureExtractor`] should be used for extracting the mel features, padding + and conversion into a tensor of type `torch.FloatTensor`. See [`~WhisperFeatureExtractor.__call__`] + attention_mask (`torch.Tensor`)`, *optional*): + Whisper does not support masking of the `input_features`, this argument is preserved for compatibility, + but it is not used. By default the silence in the input log mel spectrogram are ignored. + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + inputs_embeds = nn.functional.gelu(self.conv1(input_features)) + inputs_embeds = nn.functional.gelu(self.conv2(inputs_embeds)) + + inputs_embeds = inputs_embeds.permute(0, 2, 1) + embed_pos = self.embed_positions.weight + + hidden_states = inputs_embeds + embed_pos + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + # check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + assert head_mask.size()[0] == ( + len(self.layers) + ), f"The head_mask should be specified for {len(self.layers)} layers, but it is for {head_mask.size()[0]}." + + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): # skip the layer + layer_outputs = (None, None) + else: + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + None, + (head_mask[idx] if head_mask is not None else None), + ) + else: + layer_outputs = encoder_layer( + hidden_states, + None, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + hidden_states = self.layer_norm(hidden_states) + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class WhisperDecoder(WhisperPreTrainedModel): + """ + Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`WhisperDecoderLayer`] + + Args: + config: WhisperConfig + """ + + def __init__(self, config: WhisperConfig): + super().__init__(config) + self.dropout = config.dropout + self.layerdrop = config.decoder_layerdrop + self.padding_idx = config.pad_token_id + self.max_target_positions = config.max_target_positions + self.max_source_positions = config.max_source_positions + self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 + + self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model, self.padding_idx) + self.embed_positions = WhisperPositionalEmbedding(self.max_target_positions, config.d_model) + + self.layers = nn.ModuleList([WhisperDecoderLayer(config) for _ in range(config.decoder_layers)]) + + self.layer_norm = nn.LayerNorm(config.d_model) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embed_tokens + + def set_input_embeddings(self, value): + self.embed_tokens = value + + def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length): + # create causal mask + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + combined_attention_mask = None + + if input_shape[-1] > 1: + combined_attention_mask = _make_causal_mask( + input_shape, + inputs_embeds.dtype, + device=inputs_embeds.device, + past_key_values_length=past_key_values_length, + ) + + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) + combined_attention_mask = ( + expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask + ) + + return combined_attention_mask + + def forward( + self, + input_ids=None, + attention_mask=None, + encoder_hidden_states=None, + head_mask=None, + cross_attn_head_mask=None, + past_key_values=None, + inputs_embeds=None, + use_cache=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you + provide it. + + Indices can be obtained using [`WhisperTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention + of the decoder. + head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in encoder to avoid performing cross-attention + on hidden heads. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of + shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of + shape `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the + cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those + that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of + all `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`torch.FloatTensor` of + shape `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing + `input_ids` you can choose to directly pass an embedded representation. This is useful if you want more + control over how to convert `input_ids` indices into associated vectors than the model's internal + embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + input_ids = input_ids.view(-1, input_shape[-1]) + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds") + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + attention_mask = self._prepare_decoder_attention_mask( + attention_mask, input_shape, inputs_embeds, past_key_values_length + ) + + # embed positions + if input_ids is not None: + positions = self.embed_positions(input_ids, past_key_values_length=past_key_values_length) + else: + positions = self.embed_positions(inputs_embeds, past_key_values_length=past_key_values_length) + + hidden_states = inputs_embeds + positions + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache = True` is incompatible with gradient checkpointing. Setting `use_cache = False`..." + ) + use_cache = False + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + next_decoder_cache = () if use_cache else None + + # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired + for attn_mask, mask_name in zip([head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]): + if attn_mask is not None: + assert attn_mask.size()[0] == (len(self.layers)), ( + f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for" + f" {head_mask.size()[0]}." + ) + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + # None for past_key_value + return module(*inputs, output_attentions, use_cache) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + attention_mask, + encoder_hidden_states, + None, # encoder attention mask + head_mask[idx] if head_mask is not None else None, + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, + None, # past_key_value + ) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=( + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None + ), + past_key_value=past_key_value, + output_attentions=output_attentions, + use_cache=use_cache, + ) + hidden_states = layer_outputs[0] + + if use_cache: + next_decoder_cache += (layer_outputs[3 if output_attentions else 1],) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + hidden_states = self.layer_norm(hidden_states) + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + next_cache = next_decoder_cache if use_cache else None + if not return_dict: + return tuple( + v + for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_cache, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + "The bare Whisper Model outputting raw hidden-states without any specific head on top.", + WHISPER_START_DOCSTRING, +) +class WhisperModel(WhisperPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"proj_out.weight"] + + def __init__(self, config: WhisperConfig): + super().__init__(config) + + self.encoder = WhisperEncoder(config) + self.decoder = WhisperDecoder(config) + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.decoder.embed_tokens + + def set_input_embeddings(self, value): + self.decoder.embed_tokens = value + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + def freeze_encoder(self): + """ + Calling this function will disable the gradient computation for the Whisper encoder so that its parameters will + not be updated during training. + """ + self.encoder._freeze_parameters() + + def _mask_input_features( + self, + input_features: torch.FloatTensor, + attention_mask: Optional[torch.LongTensor] = None, + ): + """ + Masks extracted features along time axis and/or along feature axis according to + [SpecAugment](https://arxiv.org/abs/1904.08779). + """ + + # `config.apply_spec_augment` can set masking to False + if not getattr(self.config, "apply_spec_augment", True): + return input_features + + # generate indices & apply SpecAugment along time axis + batch_size, hidden_size, sequence_length = input_features.size() + + if self.config.mask_time_prob > 0 and self.training: + # generate indices & apply SpecAugment along time axis + mask_time_indices = _compute_mask_indices( + (batch_size, sequence_length), + mask_prob=self.config.mask_time_prob, + mask_length=self.config.mask_time_length, + attention_mask=attention_mask, + min_masks=self.config.mask_time_min_masks, + ) + mask_time_indices = torch.tensor(mask_time_indices, device=input_features.device, dtype=torch.bool) + mask_time_indices = mask_time_indices[:, None].expand(-1, hidden_size, -1) + input_features[mask_time_indices] = 0 + + if self.config.mask_feature_prob > 0 and self.training: + # generate indices & apply SpecAugment along feature axis + mask_feature_indices = _compute_mask_indices( + (batch_size, hidden_size), + mask_prob=self.config.mask_feature_prob, + mask_length=self.config.mask_feature_length, + min_masks=self.config.mask_feature_min_masks, + ) + mask_feature_indices = torch.tensor(mask_feature_indices, device=input_features.device, dtype=torch.bool) + input_features[mask_feature_indices] = 0 + + return input_features + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=Seq2SeqModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_features: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.LongTensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + decoder_inputs_embeds: Optional[Tuple[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], Seq2SeqModelOutput]: + r""" + Returns: + + Example: + ```python + >>> import torch + >>> from transformers import AutoFeatureExtractor, WhisperModel + >>> from datasets import load_dataset + + >>> model = WhisperModel.from_pretrained("openai/whisper-base") + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("openai/whisper-base") + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + >>> inputs = feature_extractor(ds[0]["audio"]["array"], return_tensors="pt") + >>> input_features = inputs.input_features + >>> decoder_input_ids = torch.tensor([[1, 1]]) * model.config.decoder_start_token_id + >>> last_hidden_state = model(input_features, decoder_input_ids=decoder_input_ids).last_hidden_state + >>> list(last_hidden_state.shape) + [1, 2, 512] + ```""" + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + input_features = self._mask_input_features(input_features, attention_mask=attention_mask) + + encoder_outputs = self.encoder( + input_features, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True + elif return_dict and not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn) + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + encoder_hidden_states=encoder_outputs[0], + head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + + return Seq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + past_key_values=decoder_outputs.past_key_values, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + "The Whisper Model with a language modeling head. Can be used for automatic speech recognition.", + WHISPER_START_DOCSTRING, +) +class WhisperForConditionalGeneration(WhisperPreTrainedModel): + base_model_prefix = "model" + _keys_to_ignore_on_load_missing = [ + r"encoder.version", + r"decoder.version", + r"proj_out.weight", + ] + _keys_to_ignore_on_save = [ + r"proj_out.weight", + ] + + def __init__(self, config: WhisperConfig): + super().__init__(config) + self.model = WhisperModel(config) + self.proj_out = nn.Linear(config.d_model, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_encoder(self): + return self.model.get_encoder() + + def get_decoder(self): + return self.model.get_decoder() + + def resize_token_embeddings(self, new_num_tokens: int) -> nn.Embedding: + new_embeddings = super().resize_token_embeddings(new_num_tokens) + return new_embeddings + + def get_output_embeddings(self): + return self.proj_out + + def set_output_embeddings(self, new_embeddings): + self.proj_out = new_embeddings + + def get_input_embeddings(self) -> nn.Module: + return self.model.get_input_embeddings() + + def freeze_encoder(self): + """ + Calling this function will disable the gradient computation for the Whisper encoder so that its parameters will + not be updated during training. + """ + self.model.encoder._freeze_parameters() + + @add_start_docstrings_to_model_forward(WHISPER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=Seq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_features: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.LongTensor] = None, + decoder_input_ids: Optional[torch.LongTensor] = None, + decoder_attention_mask: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + decoder_inputs_embeds: Optional[Tuple[torch.FloatTensor]] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], Seq2SeqLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the language modeling loss. Indices should either be in `[0, ..., config.vocab_size]` + or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored (masked), the loss is + only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + + Returns: + + Example: + + ```python + >>> import torch + >>> from transformers import AutoProcessor, WhisperForConditionalGeneration + >>> from datasets import load_dataset + + >>> processor = AutoProcessor.from_pretrained("openai/whisper-tiny.en") + >>> model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en") + + >>> ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + + >>> inputs = processor(ds[0]["audio"]["array"], return_tensors="pt") + >>> input_features = inputs.input_features + + >>> generated_ids = model.generate(inputs=input_features) + + >>> transcription = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] + >>> transcription + ' Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.' + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if labels is not None: + if decoder_input_ids is None and decoder_inputs_embeds is None: + decoder_input_ids = shift_tokens_right( + labels, self.config.pad_token_id, self.config.decoder_start_token_id + ) + + outputs = self.model( + input_features, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + encoder_outputs=encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + lm_logits = self.proj_out(outputs[0]) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + # move labels to correct device to enable PP + labels = labels.to(lm_logits.device) + loss = loss_fct(lm_logits.view(-1, self.config.vocab_size), labels.reshape(-1)) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return Seq2SeqLMOutput( + loss=loss, + logits=lm_logits, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_attentions=outputs.decoder_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + def generate( + self, + inputs: Optional[torch.Tensor] = None, + generation_config=None, + logits_processor=None, + stopping_criteria=None, + prefix_allowed_tokens_fn=None, + synced_gpus=False, + return_timestamps=None, + task=None, + language=None, + is_multilingual=None, + **kwargs, + ): + """ + + Generates sequences of token ids for models with a language modeling head. + + + + Most generation-controlling parameters are set in `generation_config` which, if not passed, will be set to the + model's default generation configuration. You can override any `generation_config` by passing the corresponding + parameters to generate(), e.g. `.generate(inputs, num_beams=4, do_sample=True)`. + + For an overview of generation strategies and code examples, check out the [following + guide](./generation_strategies). + + + + Parameters: + inputs (`torch.Tensor` of varying shape depending on the modality, *optional*): + The sequence used as a prompt for the generation or as model inputs to the encoder. If `None` the + method initializes it with `bos_token_id` and a batch size of 1. For decoder-only models `inputs` + should of in the format of `input_ids`. For encoder-decoder models *inputs* can represent any of + `input_ids`, `input_values`, `input_features`, or `pixel_values`. + generation_config (`~generation.GenerationConfig`, *optional*): + The generation configuration to be used as base parametrization for the generation call. `**kwargs` + passed to generate matching the attributes of `generation_config` will override them. If + `generation_config` is not provided, the default will be used, which had the following loading + priority: 1) from the `generation_config.json` model file, if it exists; 2) from the model + configuration. Please note that unspecified parameters will inherit [`~generation.GenerationConfig`]'s + default values, whose documentation should be checked to parameterize generation. + logits_processor (`LogitsProcessorList`, *optional*): + Custom logits processors that complement the default logits processors built from arguments and + generation config. If a logit processor is passed that is already created with the arguments or a + generation config an error is thrown. This feature is intended for advanced users. + stopping_criteria (`StoppingCriteriaList`, *optional*): + Custom stopping criteria that complement the default stopping criteria built from arguments and a + generation config. If a stopping criteria is passed that is already created with the arguments or a + generation config an error is thrown. This feature is intended for advanced users. + prefix_allowed_tokens_fn (`Callable[[int, torch.Tensor], List[int]]`, *optional*): + If provided, this function constraints the beam search to allowed tokens only at each step. If not + provided no constraint is applied. This function takes 2 arguments: the batch ID `batch_id` and + `input_ids`. It has to return a list with the allowed tokens for the next generation step conditioned + on the batch ID `batch_id` and the previously generated tokens `inputs_ids`. This argument is useful + for constrained generation conditioned on the prefix, as described in [Autoregressive Entity + Retrieval](https://arxiv.org/abs/2010.00904). + synced_gpus (`bool`, *optional*, defaults to `False`): + Whether to continue running the while loop until max_length (needed for ZeRO stage 3) + return_timestamps (`bool`, *optional*): + Whether to return the timestamps with the text. This enables the `WhisperTimestampsLogitsProcessor`. + task (`bool`, *optional*): + Task to use for generation, either "translate" or "transcribe". The `model.config.forced_decoder_ids` + will be updated accordingly. + language (`bool`, *optional*): + Language token to use for generation, can be either in the form of `<|en|>`, `en` or `english`. You can + find all the possible language tokens in the `model.generation_config.lang_to_id` dictionary. + is_multilingual (`bool`, *optional*): + Whether or not the model is multilingual. + kwargs: + Ad hoc parametrization of `generate_config` and/or additional model-specific kwargs that will be + forwarded to the `forward` function of the model. If the model is an encoder-decoder model, encoder + specific kwargs should not be prefixed and decoder specific kwargs should be prefixed with *decoder_*. + + Return: + [`~utils.ModelOutput`] or `torch.LongTensor`: A [`~utils.ModelOutput`] (if `return_dict_in_generate=True` + or when `config.return_dict_in_generate=True`) or a `torch.FloatTensor`. + + If the model is *not* an encoder-decoder model (`model.config.is_encoder_decoder=False`), the possible + [`~utils.ModelOutput`] types are: + + - [`~generation.GreedySearchDecoderOnlyOutput`], + - [`~generation.SampleDecoderOnlyOutput`], + - [`~generation.BeamSearchDecoderOnlyOutput`], + - [`~generation.BeamSampleDecoderOnlyOutput`] + + If the model is an encoder-decoder model (`model.config.is_encoder_decoder=True`), the possible + [`~utils.ModelOutput`] types are: + + - [`~generation.GreedySearchEncoderDecoderOutput`], + - [`~generation.SampleEncoderDecoderOutput`], + - [`~generation.BeamSearchEncoderDecoderOutput`], + - [`~generation.BeamSampleEncoderDecoderOutput`] + """ + if generation_config is None: + generation_config = self.generation_config + + if return_timestamps is not None: + if not hasattr(generation_config, "no_timestamps_token_id"): + raise ValueError( + "You are trying to return timestamps, but the generation config is not properly set." + "Make sure to initialize the generation config with the correct attributes that are needed such as `no_timestamps_token_id`." + "For more details on how to generate the approtiate config, refer to https://github.com/huggingface/transformers/issues/21878#issuecomment-1451902363" + ) + + generation_config.return_timestamps = return_timestamps + else: + generation_config.return_timestamps = False + + if language is not None: + language = language.lower() + generation_config.language = language + if task is not None: + generation_config.task = task + + forced_decoder_ids = [] + if task is not None or language is not None: + if hasattr(generation_config, "language"): + if generation_config.language in generation_config.lang_to_id.keys(): + language_token = generation_config.language + elif generation_config.language in TO_LANGUAGE_CODE.keys(): + language_token = f"<|{TO_LANGUAGE_CODE[generation_config.language]}|>" + elif generation_config.language in TO_LANGUAGE_CODE.values(): + language_token = f"<|{generation_config.language}|>" + else: + is_language_code = len(generation_config.language) == 2 + raise ValueError( + f"Unsupported language: {generation_config.language}. Language should be one of:" + f" {list(TO_LANGUAGE_CODE.values()) if is_language_code else list(TO_LANGUAGE_CODE.keys())}." + ) + forced_decoder_ids.append((1, generation_config.lang_to_id[language_token])) + else: + forced_decoder_ids.append((1, None)) # automatically detect the language + + if hasattr(generation_config, "task"): + if generation_config.task in TASK_IDS: + forced_decoder_ids.append((2, generation_config.task_to_id[generation_config.task])) + else: + raise ValueError( + f"The `{generation_config.task}`task is not supported. The task should be one of `{TASK_IDS}`" + ) + else: + forced_decoder_ids.append((2, generation_config.task_to_id["transcribe"])) # defaults to transcribe + if hasattr(generation_config, "no_timestamps_token_id") and not generation_config.return_timestamps: + idx = forced_decoder_ids[-1][0] + 1 if forced_decoder_ids else 1 + forced_decoder_ids.append((idx, generation_config.no_timestamps_token_id)) + + # Legacy code for backward compatibility + elif hasattr(self.config, "forced_decoder_ids") and self.config.forced_decoder_ids is not None: + forced_decoder_ids = self.config.forced_decoder_ids + elif ( + hasattr(self.generation_config, "forced_decoder_ids") + and self.generation_config.forced_decoder_ids is not None + ): + forced_decoder_ids = self.generation_config.forced_decoder_ids + + if generation_config.return_timestamps: + logits_processor = [WhisperTimeStampLogitsProcessor(generation_config)] + + if len(forced_decoder_ids) > 0: + generation_config.forced_decoder_ids = forced_decoder_ids + + return super().generate( + inputs, + generation_config, + logits_processor, + stopping_criteria, + prefix_allowed_tokens_fn, + synced_gpus, + **kwargs, + ) + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + past_key_values=None, + use_cache=None, + encoder_outputs=None, + attention_mask=None, + **kwargs, + ): + # cut decoder_input_ids if past is used + if past_key_values is not None: + decoder_input_ids = decoder_input_ids[:, -1:] + + return { + "encoder_outputs": encoder_outputs, + "past_key_values": past_key_values, + "decoder_input_ids": decoder_input_ids, + "use_cache": use_cache, + "decoder_attention_mask": None, + } + + # + @staticmethod + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past + + +@add_start_docstrings( + """ + Whisper Encoder Model with a sequence classification head on top (a linear layer over the pooled output) for tasks + like SUPERB Keyword Spotting. + """, + WHISPER_ENCODER_INPUTS_DOCSTRING, +) +class WhisperForAudioClassification(WhisperPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.encoder = WhisperEncoder(config) + num_layers = config.num_hidden_layers + 1 # transformer layers + input embeddings + if config.use_weighted_layer_sum: + self.layer_weights = nn.Parameter(torch.ones(num_layers) / num_layers) + self.projector = nn.Linear(config.hidden_size, config.classifier_proj_size) + self.classifier = nn.Linear(config.classifier_proj_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + def freeze_encoder(self): + """ + Calling this function will disable the gradient computation for the Whisper encoder so that its parameters will + not be updated during training. Only the projection layers and classification head will be updated. + """ + self.encoder._freeze_parameters() + + def get_input_embeddings(self) -> nn.Module: + return self.encoder.get_input_embeddings() + + def set_input_embeddings(self, value: nn.Module): + self.encoder.set_input_embeddings(value) + + @add_start_docstrings_to_model_forward(WHISPER_ENCODER_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=SequenceClassifierOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_features: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + + Returns: + + Example: + + ```python + >>> import torch + >>> from transformers import AutoFeatureExtractor, WhisperForAudioClassification + >>> from datasets import load_dataset + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("sanchit-gandhi/whisper-medium-fleurs-lang-id") + >>> model = WhisperForAudioClassification.from_pretrained("sanchit-gandhi/whisper-medium-fleurs-lang-id") + + >>> ds = load_dataset("google/fleurs", "all", split="validation", streaming=True) + >>> sample = next(iter(ds)) + + >>> inputs = feature_extractor( + ... sample["audio"]["array"], sampling_rate=sample["audio"]["sampling_rate"], return_tensors="pt" + ... ) + >>> input_features = inputs.input_features + + >>> with torch.no_grad(): + ... logits = model(input_features).logits + + >>> predicted_class_ids = torch.argmax(logits).item() + >>> predicted_label = model.config.id2label[predicted_class_ids] + >>> predicted_label + 'af_za' + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_features, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + if self.config.use_weighted_layer_sum: + hidden_states = torch.stack(encoder_outputs, dim=1) + norm_weights = nn.functional.softmax(self.layer_weights, dim=-1) + hidden_states = (hidden_states * norm_weights.view(-1, 1, 1)).sum(dim=1) + else: + hidden_states = encoder_outputs[0] + + hidden_states = self.projector(hidden_states) + pooled_output = hidden_states.mean(dim=1) + + logits = self.classifier(pooled_output) + + loss = None + + if labels is not None: + loss_fct = CrossEntropyLoss() + # move labels to correct device to enable PP + labels = labels.to(logits.device) + loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + encoder_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/processing_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/processing_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..8c158b041f7ccdeed29c6f515905b6afa4fe7551 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/processing_whisper.py @@ -0,0 +1,93 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Speech processor class for Whisper +""" + +from ...processing_utils import ProcessorMixin + + +class WhisperProcessor(ProcessorMixin): + r""" + Constructs a Whisper processor which wraps a Whisper feature extractor and a Whisper tokenizer into a single + processor. + + [`WhisperProcessor`] offers all the functionalities of [`WhisperFeatureExtractor`] and [`WhisperTokenizer`]. See + the [`~WhisperProcessor.__call__`] and [`~WhisperProcessor.decode`] for more information. + + Args: + feature_extractor (`WhisperFeatureExtractor`): + An instance of [`WhisperFeatureExtractor`]. The feature extractor is a required input. + tokenizer (`WhisperTokenizer`): + An instance of [`WhisperTokenizer`]. The tokenizer is a required input. + """ + feature_extractor_class = "WhisperFeatureExtractor" + tokenizer_class = "WhisperTokenizer" + + def __init__(self, feature_extractor, tokenizer): + super().__init__(feature_extractor, tokenizer) + self.current_processor = self.feature_extractor + self._in_target_context_manager = False + + def get_decoder_prompt_ids(self, task=None, language=None, no_timestamps=True): + return self.tokenizer.get_decoder_prompt_ids(task=task, language=language, no_timestamps=no_timestamps) + + def __call__(self, *args, **kwargs): + """ + Forwards the `audio` argument to WhisperFeatureExtractor's [`~WhisperFeatureExtractor.__call__`] and the `text` + argument to [`~WhisperTokenizer.__call__`]. Please refer to the doctsring of the above two methods for more + information. + """ + # For backward compatibility + if self._in_target_context_manager: + return self.current_processor(*args, **kwargs) + + audio = kwargs.pop("audio", None) + sampling_rate = kwargs.pop("sampling_rate", None) + text = kwargs.pop("text", None) + if len(args) > 0: + audio = args[0] + args = 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 audio is not None: + inputs = self.feature_extractor(audio, *args, sampling_rate=sampling_rate, **kwargs) + if text is not None: + encodings = self.tokenizer(text, **kwargs) + + if text is None: + return inputs + + elif audio is None: + return encodings + else: + inputs["labels"] = encodings["input_ids"] + return inputs + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to WhisperTokenizer's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to WhisperTokenizer's [`~PreTrainedTokenizer.decode`]. Please refer to + the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper.py new file mode 100644 index 0000000000000000000000000000000000000000..24eb72a0b0f99d2a8dd5a049ae822893b9a4cf5e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper.py @@ -0,0 +1,990 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for Whisper.""" +import json +import os +from typing import List, Optional, Tuple, Union + +import numpy as np +import regex as re + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import logging +from .english_normalizer import EnglishTextNormalizer + + +VOCAB_FILES_NAMES = { + "vocab_file": "vocab.json", + "tokenizer_file": "tokenizer.json", + "merges_file": "merges.txt", + "normalizer_file": "normalizer.json", +} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/vocab.json", + }, + "merges_file": {"openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/merges_file.txt"}, + "normalizer_file": { + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/normalizer.json" + }, +} + +MAX_MODEL_INPUT_SIZES = { + "openai/whisper-base": 448, +} + + +# Copied from transformers.models.gpt2.tokenization_gpt2.bytes_to_unicode +def bytes_to_unicode(): + """ + Returns list of utf-8 byte and a mapping to unicode strings. We specifically avoids mapping to whitespace/control + characters the bpe code barfs on. + + The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab + if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for + decent coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup + tables between utf-8 bytes and unicode strings. + """ + bs = ( + list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1)) + ) + cs = bs[:] + n = 0 + for b in range(2**8): + if b not in bs: + bs.append(b) + cs.append(2**8 + n) + n += 1 + cs = [chr(n) for n in cs] + return dict(zip(bs, cs)) + + +logger = logging.get_logger(__name__) + + +# Copied from transformers.models.gpt2.tokenization_gpt2.get_pairs +def get_pairs(word): + """ + Return set of symbol pairs in a word. + + Word is represented as tuple of symbols (symbols being variable-length strings). + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +LANGUAGES = { + "en": "english", + "zh": "chinese", + "de": "german", + "es": "spanish", + "ru": "russian", + "ko": "korean", + "fr": "french", + "ja": "japanese", + "pt": "portuguese", + "tr": "turkish", + "pl": "polish", + "ca": "catalan", + "nl": "dutch", + "ar": "arabic", + "sv": "swedish", + "it": "italian", + "id": "indonesian", + "hi": "hindi", + "fi": "finnish", + "vi": "vietnamese", + "he": "hebrew", + "uk": "ukrainian", + "el": "greek", + "ms": "malay", + "cs": "czech", + "ro": "romanian", + "da": "danish", + "hu": "hungarian", + "ta": "tamil", + "no": "norwegian", + "th": "thai", + "ur": "urdu", + "hr": "croatian", + "bg": "bulgarian", + "lt": "lithuanian", + "la": "latin", + "mi": "maori", + "ml": "malayalam", + "cy": "welsh", + "sk": "slovak", + "te": "telugu", + "fa": "persian", + "lv": "latvian", + "bn": "bengali", + "sr": "serbian", + "az": "azerbaijani", + "sl": "slovenian", + "kn": "kannada", + "et": "estonian", + "mk": "macedonian", + "br": "breton", + "eu": "basque", + "is": "icelandic", + "hy": "armenian", + "ne": "nepali", + "mn": "mongolian", + "bs": "bosnian", + "kk": "kazakh", + "sq": "albanian", + "sw": "swahili", + "gl": "galician", + "mr": "marathi", + "pa": "punjabi", + "si": "sinhala", + "km": "khmer", + "sn": "shona", + "yo": "yoruba", + "so": "somali", + "af": "afrikaans", + "oc": "occitan", + "ka": "georgian", + "be": "belarusian", + "tg": "tajik", + "sd": "sindhi", + "gu": "gujarati", + "am": "amharic", + "yi": "yiddish", + "lo": "lao", + "uz": "uzbek", + "fo": "faroese", + "ht": "haitian creole", + "ps": "pashto", + "tk": "turkmen", + "nn": "nynorsk", + "mt": "maltese", + "sa": "sanskrit", + "lb": "luxembourgish", + "my": "myanmar", + "bo": "tibetan", + "tl": "tagalog", + "mg": "malagasy", + "as": "assamese", + "tt": "tatar", + "haw": "hawaiian", + "ln": "lingala", + "ha": "hausa", + "ba": "bashkir", + "jw": "javanese", + "su": "sundanese", +} + +# language code lookup by name, with a few language aliases +TO_LANGUAGE_CODE = { + **{language: code for code, language in LANGUAGES.items()}, + "burmese": "my", + "valencian": "ca", + "flemish": "nl", + "haitian": "ht", + "letzeburgesch": "lb", + "pushto": "ps", + "panjabi": "pa", + "moldavian": "ro", + "moldovan": "ro", + "sinhalese": "si", + "castilian": "es", +} + +TASK_IDS = ["translate", "transcribe"] + + +class WhisperTokenizer(PreTrainedTokenizer): + """ + Construct a Whisper tokenizer. + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains some of the main methods. Users should refer to + the superclass for more information regarding such methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + merges_file (`str`): + Path to the merges file. + normalizer_file (`str`, *optional*, defaults to `None`): + Path to the normalizer_file file. + errors (`str`, *optional*, defaults to `"replace"`): + Paradigm to follow when decoding bytes to UTF-8. See + [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information. + unk_token (`str`, *optional*, defaults to `"<|endoftext|>"`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + bos_token (`str`, *optional*, defaults to `"<|startoftranscript|>"`): + The beginning of sequence token. + eos_token (`str`, *optional*, defaults to `"<|endoftext|>"`): + The end of sequence token. + add_prefix_space (`bool`, *optional*, defaults to `False`): + Whether or not to add an initial space to the input. This allows to treat the leading word just as any + other word. + language (`str`, *optional*): + The language of the transcription text. The corresponding language id token is appended to the start of the + sequence for multilingual speech recognition and speech translation tasks, e.g. for Spanish the token + `"<|es|>"` is appended to the start of sequence. This should be used for multilingual fine-tuning only. + task (`str`, *optional*): + Task identifier to append at the start of sequence (if any). This should be used for mulitlingual + fine-tuning, with `"transcribe"` for speech recognition and `"translate"` for speech translation. + predict_timestamps (`bool`, *optional*, defaults to `False`): + Whether to omit the `<|notimestamps|>` token at the start of the sequence. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = MAX_MODEL_INPUT_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + merges_file, + normalizer_file=None, + errors="replace", + unk_token="<|endoftext|>", + bos_token="<|startoftranscript|>", + eos_token="<|endoftext|>", + pad_token=None, + add_prefix_space=False, + language=None, + task=None, + predict_timestamps=False, + **kwargs, + ): + bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token + eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token + unk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_token + pad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_token + super().__init__( + errors=errors, + unk_token=unk_token, + bos_token=bos_token, + eos_token=eos_token, + pad_token=pad_token, + add_prefix_space=add_prefix_space, + **kwargs, + ) + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + self.decoder = {v: k for k, v in self.encoder.items()} + self.errors = errors # how to handle errors in decoding + self.byte_encoder = bytes_to_unicode() + self.byte_decoder = {v: k for k, v in self.byte_encoder.items()} + with open(merges_file, encoding="utf-8") as merges_handle: + bpe_merges = merges_handle.read().split("\n")[1:-1] + bpe_merges = [tuple(merge.split()) for merge in bpe_merges] + self.bpe_ranks = dict(zip(bpe_merges, range(len(bpe_merges)))) + self.cache = {} + self.add_prefix_space = add_prefix_space + + if normalizer_file is not None: + with open(normalizer_file, encoding="utf-8") as vocab_handle: + self.english_spelling_normalizer = json.load(vocab_handle) + else: + self.english_spelling_normalizer = None + + # Should have added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions + self.pat = re.compile(r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+""") + + self.language = language + self.task = task + self.predict_timestamps = predict_timestamps + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + @property + def vocab_size(self) -> int: + return len(self.encoder) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.bpe with GPT2 -> Whisper + def bpe(self, token): + if token in self.cache: + return self.cache[token] + word = tuple(token) + pairs = get_pairs(word) + + if not pairs: + return token + + while True: + bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf"))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + except ValueError: + new_word.extend(word[i:]) + break + else: + new_word.extend(word[i:j]) + i = j + + if word[i] == first and i < len(word) - 1 and word[i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = " ".join(word) + self.cache[token] = word + return word + + def set_prefix_tokens(self, language: str = None, task: str = None, predict_timestamps: bool = None): + """ + Override the prefix tokens appended to the start of the label sequence. This method can be used standalone to + update the prefix tokens as required when fine-tuning. Example: + + ```python + >>> # instantiate the tokenizer and set the prefix token to Spanish + >>> tokenizer = WhisperTokenizer.from_pretrained("openai/whisper-tiny", language="spanish") + >>> # now switch the prefix token from Spanish to French + >>> tokenizer.set_prefix_tokens(language="french") + ``` + + Args: + language (`str`, *optional*, defaults to `None`): + The language of the transcription text. + task (`str`, *optional*, defaults to `None`): + Task identifier to append at the start of sequence (if any). + predict_timestamps (`bool`, *optional*, defaults to `None`): + Whether to omit the `<|notimestamps|>` token at the start of the sequence. + """ + self.language = language if language is not None else self.language + self.task = task if task is not None else self.task + self.predict_timestamps = predict_timestamps if predict_timestamps is not None else self.predict_timestamps + + @property + def prefix_tokens(self) -> List[int]: + all_special_ids = self.all_special_ids + bos_token_id = all_special_ids[-106] + translate_token_id = all_special_ids[-6] + transcribe_token_id = all_special_ids[-5] + notimestamps_token_id = all_special_ids[-1] + langs = tuple(LANGUAGES.keys()) + + if self.language is not None: + self.language = self.language.lower() + if self.language in TO_LANGUAGE_CODE: + language_id = TO_LANGUAGE_CODE[self.language] + elif self.language in TO_LANGUAGE_CODE.values(): + language_id = self.language + else: + is_language_code = len(self.language) == 2 + raise ValueError( + f"Unsupported language: {self.language}. Language should be one of:" + f" {list(TO_LANGUAGE_CODE.values()) if is_language_code else list(TO_LANGUAGE_CODE.keys())}." + ) + + if self.task is not None: + if self.task not in TASK_IDS: + raise ValueError(f"Unsupported task: {self.task}. Task should be in: {TASK_IDS}") + + bos_sequence = [bos_token_id] + if self.language is not None: + bos_sequence.append(bos_token_id + 1 + langs.index(language_id)) + if self.task is not None: + bos_sequence.append(transcribe_token_id if self.task == "transcribe" else translate_token_id) + if not self.predict_timestamps: + bos_sequence.append(notimestamps_token_id) + return bos_sequence + + # Copied from transformers.models.speech_to_text.tokenization_speech_to_text.Speech2TextTokenizer.build_inputs_with_special_tokens + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None) -> List[int]: + """Build model inputs from a sequence by appending eos_token_id.""" + if token_ids_1 is None: + return self.prefix_tokens + token_ids_0 + [self.eos_token_id] + # We don't expect to process pairs, but leave the pair logic for API consistency + return self.prefix_tokens + token_ids_0 + token_ids_1 + [self.eos_token_id] + + # Copied from transformers.models.speech_to_text.tokenization_speech_to_text.Speech2TextTokenizer.get_special_tokens_mask + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + prefix_ones = [1] * len(self.prefix_tokens) + suffix_ones = [1] + if token_ids_1 is None: + return prefix_ones + ([0] * len(token_ids_0)) + suffix_ones + return prefix_ones + ([0] * len(token_ids_0)) + ([0] * len(token_ids_1)) + suffix_ones + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._tokenize with GPT2 -> Whisper + def _tokenize(self, text): + """Tokenize a string.""" + bpe_tokens = [] + for token in re.findall(self.pat, text): + token = "".join( + self.byte_encoder[b] for b in token.encode("utf-8") + ) # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case) + bpe_tokens.extend(bpe_token for bpe_token in self.bpe(token).split(" ")) + return bpe_tokens + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_token_to_id with GPT2 -> Whisper + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + def _convert_id_to_token(self, index): + """ + Converts an index (integer) in a token (str) using the vocab. Whisper's base tokenizer always decodes OOV + tokens as "", thus we do not use the `unk_token` here. + """ + return self.decoder.get(index, "") + + def _normalize(self, text): + """ + Normalize a given string using the `EnglishTextNormalizer` class, which preforms commons transformation on + english text. + """ + normalizer = EnglishTextNormalizer(self.english_spelling_normalizer) + return normalizer(text) + + def _decode_with_timestamps(self, token_ids, time_precision=0.02) -> str: + """ + Timestamp tokens are above the special tokens' id range and are ignored by `decode()`. This method decodes + given tokens with timestamps tokens annotated, e.g. "<|1.08|>". + """ + timestamp_begin = self.all_special_ids[-1] + 1 + outputs = [[]] + for token in token_ids: + if token >= timestamp_begin: + timestamp = f"<|{(token - timestamp_begin) * time_precision:.2f}|>" + outputs.append(timestamp) + outputs.append([]) + else: + outputs[-1].append(token) + outputs = [s if isinstance(s, str) else self.decode(s) for s in outputs] + return "".join(outputs) + + def _compute_offsets(self, token_ids, time_precision=0.02): + """ + Compute offsets for a given tokenized input + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + time_precision (`float`, `optional`, defaults to 0.02): + The time ratio to convert from token to time. + """ + offsets = [] + token_ids = np.array(token_ids) + if token_ids.shape[0] > 1 and len(token_ids.shape) > 1: + raise ValueError("Can only process a single input at a time") + timestamp_begin = self.all_special_ids[-1] + 1 + timestamp_tokens = token_ids >= timestamp_begin + + consecutive = np.where(timestamp_tokens[:-1] & timestamp_tokens[1:])[0] + 1 + if consecutive.shape[0] == 0 and timestamp_tokens.sum() <= 1: + # either there are no timestamps or there are no consecutive ones + return [] + elif np.where(timestamp_tokens)[0][-1] + 1 not in consecutive: + # we add the final timestamp if it is not already in the list + consecutive = np.append(consecutive, np.where(timestamp_tokens)[0][-1] + 1) + + last_slice = np.where(timestamp_tokens)[0][0] + for current_slice in consecutive: + sliced_tokens = token_ids[last_slice:current_slice] + if len(sliced_tokens) > 1: + start_timestamp_position = sliced_tokens[0].item() - timestamp_begin + end_timestamp_position = sliced_tokens[-1].item() - timestamp_begin + offsets.append( + { + "text": self._decode(sliced_tokens), + "timestamp": ( + start_timestamp_position * time_precision, + end_timestamp_position * time_precision, + ), + } + ) + last_slice = current_slice + + return offsets + + def decode( + self, + token_ids, + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_offsets: bool = False, + time_precision=0.02, + decode_with_timestamps: bool = False, + **kwargs, + ) -> str: + """ + Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special + tokens and clean up tokenization spaces. + + Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. If `None`, will default to + `self.clean_up_tokenization_spaces` (available in the `tokenizer_config`). + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + output_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output the offsets of the tokens. This should only be set if the model predicted + timestamps. + decode_with_timestamps (`bool`, *optional*, defaults to `False`): + WHether or not to decode with timestamps included in the raw text. + Returns: + `str`: The decoded sentence. + """ + text = super().decode( + token_ids, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + if decode_with_timestamps: + text = self._decode_with_timestamps(token_ids, time_precision=time_precision) + # retrieve offsets + if output_offsets: + offsets = None + offsets = self._compute_offsets(token_ids, time_precision=time_precision) + return {"text": text, "offsets": offsets} + return text + + def _decode( + self, token_ids: Union[int, List[int]], skip_special_tokens: bool = False, normalize: bool = False, **kwargs + ) -> str: + self._decode_use_source_tokenizer = kwargs.pop("use_source_tokenizer", False) + + filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens) + + # To avoid mixing byte-level and unicode for byte-level BPT + # we need to build string separately for added tokens and byte-level tokens + # cf. https://github.com/huggingface/transformers/issues/1133 + sub_texts = [] + current_sub_text = [] + for token in filtered_tokens: + if skip_special_tokens and token in self.all_special_ids: + continue + if token in self.added_tokens_encoder: + if current_sub_text: + sub_texts.append(self.convert_tokens_to_string(current_sub_text)) + current_sub_text = [] + sub_texts.append(token) + else: + current_sub_text.append(token) + if current_sub_text: + sub_texts.append(self.convert_tokens_to_string(current_sub_text)) + + text = "".join(sub_texts) + + if normalize: + clean_text = self._normalize(text) + return clean_text + else: + return text + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.convert_tokens_to_string with GPT2 -> Whisper + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + text = "".join(tokens) + text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors) + return text + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + merge_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"] + ) + normalizer_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["normalizer_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + index = 0 + with open(merge_file, "w", encoding="utf-8") as writer: + writer.write("#version: 0.2\n") + for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]): + if index != token_index: + logger.warning( + f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive." + " Please check that the tokenizer is not corrupted!" + ) + index = token_index + writer.write(" ".join(bpe_tokens) + "\n") + index += 1 + + if self.english_spelling_normalizer is not None: + with open(normalizer_file, "w", encoding="utf-8") as f: + f.write( + json.dumps(self.english_spelling_normalizer, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + ) + + return vocab_file, merge_file, normalizer_file + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.prepare_for_tokenization with GPT2 -> Whisper + def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): + add_prefix_space = kwargs.pop("add_prefix_space", self.add_prefix_space) + if is_split_into_words or add_prefix_space: + text = " " + text + return (text, kwargs) + + # Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._build_conversation_input_ids with GPT2 -> Whisper + def _build_conversation_input_ids(self, conversation) -> List[int]: + input_ids = [] + for is_user, text in conversation.iter_texts(): + input_ids.extend(self.encode(text, add_special_tokens=False) + [self.eos_token_id]) + if len(input_ids) > self.model_max_length: + input_ids = input_ids[-self.model_max_length :] + return input_ids + + def get_decoder_prompt_ids(self, task=None, language=None, no_timestamps=True): + self.set_prefix_tokens(task=task, language=language, predict_timestamps=not no_timestamps) + # prefix tokens are of the form: <|startoftranscript|> <|lang_id|> <|task|> <|notimestamps|> + # we don't want to force the bos token at position 1, as this is the starting token + # when we generate, so we slice the prefix tokens to: <|lang_id|> <|task|> <|notimestamps|> + # to get the forced tokens + forced_tokens = self.prefix_tokens[1:] + forced_decoder_ids = [(rank + 1, token) for rank, token in enumerate(forced_tokens)] + return forced_decoder_ids + + def _decode_asr(self, model_outputs, *, return_timestamps, return_language, time_precision): + return _decode_asr( + self, + model_outputs, + return_timestamps=return_timestamps, + return_language=return_language, + time_precision=time_precision, + ) + + +def _decode_asr(tokenizer, model_outputs, *, return_timestamps, return_language, time_precision): + """ + Internal method meant to only be used by asr pipeline. Handles all the little quirks specific to whisper to handle + the various options not allowed in other seq2seq models + """ + + # =========== Overview ============ + # - iterate over all outputs + # - all tokens within output + # - Each token can be + # - language token + # - special token + # - timestamp token + # - text token + # - We accumulate the text tokens. + # - We split on end timestamps + # - Lots of complexity comes from stride and timestamps + + last_language = None + + def new_chunk(): + return {"language": last_language, "timestamp": [None, None], "text": ""} + + # Welcome to the state machine ! + chunks = [] + chunk = new_chunk() + time_offset = 0.0 + timestamp_begin = tokenizer.convert_tokens_to_ids("<|notimestamps|>") + 1 + previous_tokens = [] + skip = False + right_stride_start = None + + all_special_ids = set(tokenizer.all_special_ids) + # - iterate over all outputs + for chunk_id, output in enumerate(model_outputs): + # We can drop everything to Python list, it's going to make + # our lives easier + token_ids = output["tokens"][0].tolist() + + # Those keep track of timestamps within strides + # Which need to be skipped and resolve all tokens in a single + # chunk. + last_timestamp = None + first_timestamp = timestamp_begin + + if "stride" in output: + chunk_len, stride_left, stride_right = output["stride"] + # Offset the timings to account for the other `model_outputs`. + time_offset -= stride_left + right_stride_start = chunk_len - stride_right + + # Keeping track of timestamps within strides + # We're going to NOT split on those, and delay until we're + # out of BOTH stride. Otherwise lots of issues occur and + # corner cases + if stride_left: + first_timestamp = stride_left / time_precision + timestamp_begin + if stride_right: + for token in reversed(token_ids): + if token >= timestamp_begin: + # There can be several token in the right stride + # But the last one is ALWAYS going to be skipped + if ( + last_timestamp is not None + and (token - timestamp_begin) * time_precision < right_stride_start + ): + break + last_timestamp = token + + current_tokens = [] + + # - all tokens within output + for i, token in enumerate(token_ids): + # 4 possible states for each token + # - 1/ Language code + # - 2/ all other special tokens (which we ignore) + # - 3/ Timestamp + # - 4/ Regular text + if token in all_special_ids: + # Either language code or other + text = tokenizer.decode([token]) + # Removing outer shell <|XX|> + text = text[2:-2] + language = LANGUAGES.get(text, None) + if language is not None: + # 1/ Indeed some language + # TODO Handle when language is different from the previous + # one, and we cannot use timestamped tokens to create chunks + if last_language and language != last_language and not return_timestamps: + previous_tokens.append(current_tokens) + resolved_tokens = _find_longest_common_sequence(previous_tokens) + resolved_text = tokenizer.decode(resolved_tokens) + chunk["text"] = resolved_text + chunks.append(chunk) + + # Flush all our temporary context + previous_tokens = [] + current_tokens = [] + chunk = new_chunk() + chunk["language"] = language + last_language = language + else: + # 2/ This is a regular special token, ignoring it + pass + elif token >= timestamp_begin: + # 3/ Timestamp token + time = (token - timestamp_begin) * time_precision + time_offset + time = round(time, 2) + if last_timestamp and token >= last_timestamp: + # Whisper outputted a timestamp token, but it falls within + # our stride, so we're going to skip it for the time being + # and resolve this later + # Skip is necessary because timestamp tokens always come + # by pair, so we need to skip the next one too (which would mark the start of another chunk). + skip = True + elif skip or (previous_tokens and token < first_timestamp): + skip = False + elif chunk["timestamp"][0] is None: + chunk["timestamp"][0] = time + else: + # This is the end of the timestamp chunk + if time == chunk["timestamp"][0]: + # This is a bug in timestamp token output + # where we're taking the duplicate token + # as a stop where it should be a start. + # This is an issue in the underlying model output + # Let's just skip it so it becomes de-factor + # a start agin + pass + else: + chunk["timestamp"][1] = time + # Handling merges. + previous_tokens.append(current_tokens) + resolved_tokens = _find_longest_common_sequence(previous_tokens) + resolved_text = tokenizer.decode(resolved_tokens) + chunk["text"] = resolved_text + chunks.append(chunk) + + # Flush all our temporary context + previous_tokens = [] + current_tokens = [] + chunk = new_chunk() + else: + # 4/ Regular token + # We just append to the list of all tokens so we can handle + # merges later and decode into text. + current_tokens.append(token) + + if "stride" in output: + time_offset += chunk_len - stride_right + + # Leftover tokens + if current_tokens: + previous_tokens.append(current_tokens) + elif not (any(p for p in previous_tokens)): + # print("Flushing previous tokens (END)") + chunk = new_chunk() + previous_tokens = [] + current_tokens = [] + + if previous_tokens: + if return_timestamps: + logger.warning( + "There was an error while processing timestamps, we haven't found a timestamp as last token. Was" + " WhisperTimeStampLogitsProcessor used?" + ) + # Happens when we don't use timestamps + resolved_tokens = _find_longest_common_sequence(previous_tokens) + # print("Flushing previous tokens (FINAL)") + resolved_text = tokenizer.decode(resolved_tokens) + chunk["text"] = resolved_text + chunks.append(chunk) + + # Preparing and cleaning up the pipeline output + full_text = "".join(chunk["text"] for chunk in chunks) + if return_timestamps or return_language: + for chunk in chunks: + if not return_timestamps: + chunk.pop("timestamp") + else: + chunk["timestamp"] = tuple(chunk["timestamp"]) + if not return_language: + chunk.pop("language") + optional = {"chunks": chunks} + else: + optional = {} + return full_text, optional + + +def _find_longest_common_sequence(sequences): + # It would be much harder to do O(n) because of fault tolerance. + # We actually have a really good property which is that the total sequence + # MUST be those subsequences in order. + left_sequence = sequences[0] + left_length = len(left_sequence) + total_sequence = [] + for right_sequence in sequences[1:]: + # index = 0 + max_ = 0.0 + max_indices = (left_length, left_length, 0, 0) + # Here we're sliding matches + # [a, b, c, d] + # [c, d, f] + # = [c] == [d] + # + # [a, b, c, d] + # [c, d, f] + # = [c, d] == [c, d] + # + # + # [a, b, c, d] + # [c, d, f] + # + # = [b, c, d] == [c, d, f] + # + # [a, b, c, d] + # [c, d, f] + # + # [a, b, c] == [c, d, f] + # + # [a, b, c, d] + # [d, f] + # + # [a, b] == [d, f] + # + # [a, b, c, d] + # [f] + # + # [a] == [f] + right_length = len(right_sequence) + for i in range(1, left_length + right_length): + # epsilon to favor long perfect matches + eps = i / 10000.0 + + # Slightly convoluted because we don't want out of bound indices + # This will be necessary for a small conflict resolution optimization + # later + left_start = max(0, left_length - i) + left_stop = min(left_length, left_length + right_length - i) + left = np.array(left_sequence[left_start:left_stop]) + + right_start = max(0, i - left_length) + right_stop = min(right_length, i) + right = np.array(right_sequence[right_start:right_stop]) + + # We can only match subsequences of the same size. + if len(left) != len(right): + raise RuntimeError( + "There is a bug within whisper `decode_asr` function, please report it. Dropping to prevent bad inference." + ) + + matches = np.sum(left == right) + matching = matches / i + eps + if matches > 1 and matching > max_: + max_ = matching + max_indices = (left_start, left_stop, right_start, right_stop) + + (left_start, left_stop, right_start, right_stop) = max_indices + + # This is a small conflict optimization since those sequences overlap + # in audio. + # We're going to give more confidence to the left sequence + # for the left of the overlap, + # and to the right of the sequence, for the right of the overlap + left_mid = (left_stop + left_start) // 2 + right_mid = (right_stop + right_start) // 2 + total_sequence.extend(left_sequence[:left_mid]) + left_sequence = right_sequence[right_mid:] + left_length = len(left_sequence) + + total_sequence.extend(left_sequence) + + return total_sequence diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..fb1bf89ed6069447d8d765b3bc38efd68984a39c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/whisper/tokenization_whisper_fast.py @@ -0,0 +1,487 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for Whisper.""" +import json +import os +from typing import List, Optional, Tuple + +import numpy as np +from tokenizers import pre_tokenizers, processors + +from ...tokenization_utils_base import BatchEncoding +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging +from .english_normalizer import EnglishTextNormalizer +from .tokenization_whisper import LANGUAGES, TASK_IDS, TO_LANGUAGE_CODE, WhisperTokenizer, _decode_asr + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = { + "vocab_file": "vocab.json", + "tokenizer_file": "tokenizer.json", + "merges_file": "merges.txt", + "normalizer_file": "normalizer.json", +} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "openai/whisper-tiny": "https://huggingface.co/openai/whisper-tiny/resolve/main/vocab.json", + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/vocab.json", + "openai/whisper-small": "https://huggingface.co/openai/whisper-small/resolve/main/vocab.json", + "openai/whisper-medium": "https://huggingface.co/openai/whisper-medium/resolve/main/vocab.json", + "openai/whisper-large": "https://huggingface.co/openai/whisper-large/resolve/main/vocab.json", + "openai/whisper-tiny.en": "https://huggingface.co/openai/whisper-tiny.en/resolve/main/vocab.json", + "openai/whisper-base.en": "https://huggingface.co/openai/whisper-base.en/resolve/main/vocab.json", + "openai/whisper-small.en": "https://huggingface.co/openai/whisper-small.en/resolve/main/vocab.json", + "openai/whisper-medium.en": "https://huggingface.co/openai/whisper-medium.en/resolve/main/vocab.json", + }, + "merges_file": { + "openai/whisper-tiny": "https://huggingface.co/openai/whisper-tiny/resolve/main/merges.txt", + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/merges.txt", + "openai/whisper-small": "https://huggingface.co/openai/whisper-small/resolve/main/merges.txt", + "openai/whisper-medium": "https://huggingface.co/openai/whisper-medium/resolve/main/merges.txt", + "openai/whisper-large": "https://huggingface.co/openai/whisper-large/resolve/main/merges.txt", + "openai/whisper-tiny.en": "https://huggingface.co/openai/whisper-tiny.en/resolve/main/merges.txt", + "openai/whisper-base.en": "https://huggingface.co/openai/whisper-base.en/resolve/main/merges.txt", + "openai/whisper-small.en": "https://huggingface.co/openai/whisper-small.en/resolve/main/merges.txt", + "openai/whisper-medium.en": "https://huggingface.co/openai/whisper-medium.en/resolve/main/merges.txt", + }, + "tokenizer_file": { + "openai/whisper-tiny": "https://huggingface.co/openai/whisper-tiny/resolve/main/tokenizer.json", + "openai/whisper-base": "https://huggingface.co/openai/whisper-base/resolve/main/tokenizer.json", + "openai/whisper-small": "https://huggingface.co/openai/whisper-small/resolve/main/tokenizer.json", + "openai/whisper-medium": "https://huggingface.co/openai/whisper-medium/resolve/main/tokenizer.json", + "openai/whisper-large": "https://huggingface.co/openai/whisper-large/resolve/main/tokenizer.json", + "openai/whisper-tiny.en": "https://huggingface.co/openai/whisper-tiny.en/resolve/main/tokenizer.json", + "openai/whisper-base.en": "https://huggingface.co/openai/whisper-base.en/resolve/main/tokenizer.json", + "openai/whisper-small.en": "https://huggingface.co/openai/whisper-small.en/resolve/main/tokenizer.json", + "openai/whisper-medium.en": "https://huggingface.co/openai/whisper-medium.en/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "openai/whisper-tiny": 1500, + "openai/whisper-base": 1500, + "openai/whisper-small": 1500, + "openai/whisper-medium": 1500, + "openai/whisper-large": 1500, + "openai/whisper-tiny.en": 1500, + "openai/whisper-base.en": 1500, + "openai/whisper-small.en": 1500, + "openai/whisper-medium.en": 1500, +} + + +class WhisperTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" Whisper tokenizer (backed by HuggingFace's *tokenizers* library). + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + merges_file (`str`): + Path to the merges file. + normalizer_file (`str`, *optional*, defaults to `None`): + Path to the normalizer_file file. + errors (`str`, *optional*, defaults to `"replace"`): + Paradigm to follow when decoding bytes to UTF-8. See + [bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information. + unk_token (`str`, *optional*, defaults to `<|endoftext|>`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + bos_token (`str`, *optional*, defaults to `<|startoftranscript|>`): + The beginning of sequence token. + eos_token (`str`, *optional*, defaults to `<|endoftext|>`): + The end of sequence token. + add_prefix_space (`bool`, *optional*, defaults to `False`): + Whether or not to add an initial space to the input. This allows to treat the leading word just as any + other word. (Whisper tokenizer detect beginning of words by the preceding space). + trim_offsets (`bool`, *optional*, defaults to `True`): + Whether or not the post-processing step should trim offsets to avoid including whitespaces. + language (`str`, *optional*): + The language of the transcription text. The corresponding language id token is appended to the start of the + sequence for multilingual speech recognition and speech translation tasks, e.g. for Spanish the token + `"<|es|>"` is appended to the start of sequence. This should be used for multilingual fine-tuning only. + task (`str`, *optional*): + Task identifier to append at the start of sequence (if any). This should be used for mulitlingual + fine-tuning, with `"transcribe"` for speech recognition and `"translate"` for speech translation. + predict_timestamps (`bool`, *optional*, defaults to `False`): + Whether to omit the `<|notimestamps|>` token at the start of the sequence. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = WhisperTokenizer + + def __init__( + self, + vocab_file=None, + merges_file=None, + normalizer_file=None, + tokenizer_file=None, + unk_token="<|endoftext|>", + bos_token="<|startoftranscript|>", + eos_token="<|endoftext|>", + add_prefix_space=False, + language=None, + task=None, + predict_timestamps=False, + **kwargs, + ): + super().__init__( + vocab_file, + merges_file, + tokenizer_file=tokenizer_file, + unk_token=unk_token, + bos_token=bos_token, + eos_token=eos_token, + add_prefix_space=add_prefix_space, + **kwargs, + ) + + self.add_bos_token = kwargs.pop("add_bos_token", False) + + pre_tok_state = json.loads(self.backend_tokenizer.pre_tokenizer.__getstate__()) + if pre_tok_state.get("add_prefix_space", add_prefix_space) != add_prefix_space: + pre_tok_class = getattr(pre_tokenizers, pre_tok_state.pop("type")) + pre_tok_state["add_prefix_space"] = add_prefix_space + self.backend_tokenizer.pre_tokenizer = pre_tok_class(**pre_tok_state) + + if normalizer_file is not None: + with open(normalizer_file, encoding="utf-8") as vocab_handle: + self.english_spelling_normalizer = json.load(vocab_handle) + else: + self.english_spelling_normalizer = None + + self.add_prefix_space = add_prefix_space + + self.language = language + self.task = task + self.predict_timestamps = predict_timestamps + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast._batch_encode_plus + def _batch_encode_plus(self, *args, **kwargs) -> BatchEncoding: + is_split_into_words = kwargs.get("is_split_into_words", False) + assert self.add_prefix_space or not is_split_into_words, ( + f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True " + "to use it with pretokenized inputs." + ) + + return super()._batch_encode_plus(*args, **kwargs) + + # Copied from transformers.models.gpt2.tokenization_gpt2_fast.GPT2TokenizerFast._encode_plus + def _encode_plus(self, *args, **kwargs) -> BatchEncoding: + is_split_into_words = kwargs.get("is_split_into_words", False) + + assert self.add_prefix_space or not is_split_into_words, ( + f"You need to instantiate {self.__class__.__name__} with add_prefix_space=True " + "to use it with pretokenized inputs." + ) + + return super()._encode_plus(*args, **kwargs) + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer._decode_with_timestamps + def _decode_with_timestamps(self, token_ids, time_precision=0.02) -> str: + """ + Timestamp tokens are above the special tokens' id range and are ignored by `decode()`. This method decodes + given tokens with timestamps tokens annotated, e.g. "<|1.08|>". + """ + timestamp_begin = self.all_special_ids[-1] + 1 + outputs = [[]] + for token in token_ids: + if token >= timestamp_begin: + timestamp = f"<|{(token - timestamp_begin) * time_precision:.2f}|>" + outputs.append(timestamp) + outputs.append([]) + else: + outputs[-1].append(token) + outputs = [s if isinstance(s, str) else self.decode(s) for s in outputs] + return "".join(outputs) + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer._compute_offsets + def _compute_offsets(self, token_ids, time_precision=0.02): + """ + Compute offsets for a given tokenized input + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + time_precision (`float`, `optional`, defaults to 0.02): + The time ratio to convert from token to time. + """ + offsets = [] + token_ids = np.array(token_ids) + if token_ids.shape[0] > 1 and len(token_ids.shape) > 1: + raise ValueError("Can only process a single input at a time") + timestamp_begin = self.all_special_ids[-1] + 1 + timestamp_tokens = token_ids >= timestamp_begin + + consecutive = np.where(timestamp_tokens[:-1] & timestamp_tokens[1:])[0] + 1 + if consecutive.shape[0] == 0 and timestamp_tokens.sum() <= 1: + # either there are no timestamps or there are no consecutive ones + return [] + elif np.where(timestamp_tokens)[0][-1] + 1 not in consecutive: + # we add the final timestamp if it is not already in the list + consecutive = np.append(consecutive, np.where(timestamp_tokens)[0][-1] + 1) + + last_slice = np.where(timestamp_tokens)[0][0] + for current_slice in consecutive: + sliced_tokens = token_ids[last_slice:current_slice] + if len(sliced_tokens) > 1: + start_timestamp_position = sliced_tokens[0].item() - timestamp_begin + end_timestamp_position = sliced_tokens[-1].item() - timestamp_begin + offsets.append( + { + "text": self._decode(sliced_tokens), + "timestamp": ( + start_timestamp_position * time_precision, + end_timestamp_position * time_precision, + ), + } + ) + last_slice = current_slice + + return offsets + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer.decode + def decode( + self, + token_ids, + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + output_offsets: bool = False, + time_precision=0.02, + decode_with_timestamps: bool = False, + **kwargs, + ) -> str: + """ + Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special + tokens and clean up tokenization spaces. + + Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. If `None`, will default to + `self.clean_up_tokenization_spaces` (available in the `tokenizer_config`). + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + output_offsets (`bool`, *optional*, defaults to `False`): + Whether or not to output the offsets of the tokens. This should only be set if the model predicted + timestamps. + decode_with_timestamps (`bool`, *optional*, defaults to `False`): + WHether or not to decode with timestamps included in the raw text. + Returns: + `str`: The decoded sentence. + """ + text = super().decode( + token_ids, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + if decode_with_timestamps: + text = self._decode_with_timestamps(token_ids, time_precision=time_precision) + # retrieve offsets + if output_offsets: + offsets = None + offsets = self._compute_offsets(token_ids, time_precision=time_precision) + return {"text": text, "offsets": offsets} + return text + + def _decode(self, *args, normalize: bool = False, **kwargs) -> str: + text = super()._decode(*args, **kwargs) + + if normalize: + clean_text = self._normalize(text) + return clean_text + else: + return text + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer._normalize + def _normalize(self, text): + """ + Normalize a given string using the `EnglishTextNormalizer` class, which preforms commons transformation on + english text. + """ + normalizer = EnglishTextNormalizer(self.english_spelling_normalizer) + return normalizer(text) + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + files = self._tokenizer.model.save(save_directory, name=filename_prefix) + + normalizer_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["normalizer_file"] + ) + + if self.english_spelling_normalizer is not None: + with open(normalizer_file, "w", encoding="utf-8") as f: + f.write( + json.dumps(self.english_spelling_normalizer, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + ) + + return tuple(files) + (normalizer_file,) + + def set_prefix_tokens(self, language: str = None, task: str = None, predict_timestamps: bool = None): + """ + Override the prefix tokens appended to the start of the label sequence. This method can be used standalone to + update the prefix tokens as required when fine-tuning. Example: + + ```python + >>> # instantiate the tokenizer and set the prefix token to Spanish + >>> tokenizer = WhisperTokenizerFast.from_pretrained("openai/whisper-tiny", language="spanish") + >>> # now switch the prefix token from Spanish to French + >>> tokenizer.set_prefix_tokens(language="french") + ``` + + Args: + language (`str`, *optional*, defaults to `None`): + The language of the transcription text. + task (`str`, *optional*, defaults to `None`): + Task identifier to append at the start of sequence (if any). + predict_timestamps (`bool`, *optional*, defaults to `None`): + Whether to omit the `<|notimestamps|>` token at the start of the sequence. + """ + self.language = language if language is not None else self.language + self.task = task if task is not None else self.task + self.predict_timestamps = predict_timestamps if predict_timestamps is not None else self.predict_timestamps + + prefix_token_ids = self.prefix_tokens + prefixes = self.convert_ids_to_tokens(prefix_token_ids) + eos = self.eos_token + eos_token_id = self.eos_token_id + prefix_template = " ".join([f"{token}:0" for token in prefixes]) + self.backend_tokenizer.post_processor = processors.TemplateProcessing( + single=f"{prefix_template} $A:0 {eos}:0", + pair=f"{prefix_template} $A:0 $B:1 {eos}:1", + special_tokens=[ + (eos, eos_token_id), + *zip(prefixes, prefix_token_ids), + ], + ) + + @property + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer.prefix_tokens + def prefix_tokens(self) -> List[int]: + all_special_ids = self.all_special_ids + bos_token_id = all_special_ids[-106] + translate_token_id = all_special_ids[-6] + transcribe_token_id = all_special_ids[-5] + notimestamps_token_id = all_special_ids[-1] + langs = tuple(LANGUAGES.keys()) + + if self.language is not None: + self.language = self.language.lower() + if self.language in TO_LANGUAGE_CODE: + language_id = TO_LANGUAGE_CODE[self.language] + elif self.language in TO_LANGUAGE_CODE.values(): + language_id = self.language + else: + is_language_code = len(self.language) == 2 + raise ValueError( + f"Unsupported language: {self.language}. Language should be one of:" + f" {list(TO_LANGUAGE_CODE.values()) if is_language_code else list(TO_LANGUAGE_CODE.keys())}." + ) + + if self.task is not None: + if self.task not in TASK_IDS: + raise ValueError(f"Unsupported task: {self.task}. Task should be in: {TASK_IDS}") + + bos_sequence = [bos_token_id] + if self.language is not None: + bos_sequence.append(bos_token_id + 1 + langs.index(language_id)) + if self.task is not None: + bos_sequence.append(transcribe_token_id if self.task == "transcribe" else translate_token_id) + if not self.predict_timestamps: + bos_sequence.append(notimestamps_token_id) + return bos_sequence + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer.build_inputs_with_special_tokens + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None) -> List[int]: + """Build model inputs from a sequence by appending eos_token_id.""" + if token_ids_1 is None: + return self.prefix_tokens + token_ids_0 + [self.eos_token_id] + # We don't expect to process pairs, but leave the pair logic for API consistency + return self.prefix_tokens + token_ids_0 + token_ids_1 + [self.eos_token_id] + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer.get_special_tokens_mask + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + prefix_ones = [1] * len(self.prefix_tokens) + suffix_ones = [1] + if token_ids_1 is None: + return prefix_ones + ([0] * len(token_ids_0)) + suffix_ones + return prefix_ones + ([0] * len(token_ids_0)) + ([0] * len(token_ids_1)) + suffix_ones + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer._build_conversation_input_ids + def _build_conversation_input_ids(self, conversation) -> List[int]: + input_ids = [] + for is_user, text in conversation.iter_texts(): + input_ids.extend(self.encode(text, add_special_tokens=False) + [self.eos_token_id]) + if len(input_ids) > self.model_max_length: + input_ids = input_ids[-self.model_max_length :] + return input_ids + + # Copied from transformers.models.whisper.tokenization_whisper.WhisperTokenizer.get_decoder_prompt_ids + def get_decoder_prompt_ids(self, task=None, language=None, no_timestamps=True): + self.set_prefix_tokens(task=task, language=language, predict_timestamps=not no_timestamps) + # prefix tokens are of the form: <|startoftranscript|> <|lang_id|> <|task|> <|notimestamps|> + # we don't want to force the bos token at position 1, as this is the starting token + # when we generate, so we slice the prefix tokens to: <|lang_id|> <|task|> <|notimestamps|> + # to get the forced tokens + forced_tokens = self.prefix_tokens[1:] + forced_decoder_ids = [(rank + 1, token) for rank, token in enumerate(forced_tokens)] + return forced_decoder_ids + + def _decode_asr(self, model_outputs, *, return_timestamps, return_language, time_precision): + return _decode_asr( + self, + model_outputs, + return_timestamps=return_timestamps, + return_language=return_language, + time_precision=time_precision, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed3d2ff515283084e2879628e627d7aa3a775531 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/__init__.py @@ -0,0 +1,69 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = { + "configuration_x_clip": [ + "XCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP", + "XCLIPConfig", + "XCLIPTextConfig", + "XCLIPVisionConfig", + ], + "processing_x_clip": ["XCLIPProcessor"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_x_clip"] = [ + "XCLIP_PRETRAINED_MODEL_ARCHIVE_LIST", + "XCLIPModel", + "XCLIPPreTrainedModel", + "XCLIPTextModel", + "XCLIPVisionModel", + ] + +if TYPE_CHECKING: + from .configuration_x_clip import ( + XCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP, + XCLIPConfig, + XCLIPTextConfig, + XCLIPVisionConfig, + ) + from .processing_x_clip import XCLIPProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_x_clip import ( + XCLIP_PRETRAINED_MODEL_ARCHIVE_LIST, + XCLIPModel, + XCLIPPreTrainedModel, + XCLIPTextModel, + XCLIPVisionModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/configuration_x_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/configuration_x_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..ddb30d2ad2be16144494ba98428b525cbf2b0e77 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/configuration_x_clip.py @@ -0,0 +1,428 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" X-CLIP model configuration""" + +import copy +import os +from typing import Union + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XCLIP_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "microsoft/xclip-base-patch32": "https://huggingface.co/microsoft/xclip-base-patch32/resolve/main/config.json", +} + + +class XCLIPTextConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XCLIPModel`]. It is used to instantiate an X-CLIP + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the X-CLIP + [microsoft/xclip-base-patch32](https://huggingface.co/microsoft/xclip-base-patch32) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 49408): + Vocabulary size of the X-CLIP text model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`XCLIPModel`]. + hidden_size (`int`, *optional*, defaults to 512): + Dimensionality of the encoder layers and the pooler layer. + intermediate_size (`int`, *optional*, defaults to 2048): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Transformer encoder. + max_position_embeddings (`int`, *optional*, defaults to 77): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported. + layer_norm_eps (`float`, *optional*, defaults to 1e-5): + The epsilon used by the layer normalization layers. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + initializer_factor (`float``, *optional*, defaults to 1): + A factor for initializing all weight matrices (should be kept to 1, used internally for initialization + testing). + + Example: + + ```python + >>> from transformers import XCLIPTextModel, XCLIPTextConfig + + >>> # Initializing a XCLIPTextModel with microsoft/xclip-base-patch32 style configuration + >>> configuration = XCLIPTextConfig() + + >>> # Initializing a XCLIPTextConfig from the microsoft/xclip-base-patch32 style configuration + >>> model = XCLIPTextModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "xclip_text_model" + + def __init__( + self, + vocab_size=49408, + hidden_size=512, + intermediate_size=2048, + num_hidden_layers=12, + num_attention_heads=8, + max_position_embeddings=77, + hidden_act="quick_gelu", + layer_norm_eps=1e-5, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.max_position_embeddings = max_position_embeddings + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.initializer_factor = initializer_factor + self.attention_dropout = attention_dropout + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig": + config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs) + + # get the text config dict if we are loading from XCLIPConfig + if config_dict.get("model_type") == "xclip": + config_dict = config_dict["text_config"] + + if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type: + logger.warning( + f"You are using a model of type {config_dict['model_type']} to instantiate a model of type " + f"{cls.model_type}. This is not supported for all configurations of models and can yield errors." + ) + + return cls.from_dict(config_dict, **kwargs) + + +class XCLIPVisionConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XCLIPModel`]. It is used to instantiate an X-CLIP + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the X-CLIP + [microsoft/xclip-base-patch32](https://huggingface.co/microsoft/xclip-base-patch32) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + mit_hidden_size (`int`, *optional*, defaults to 512): + Dimensionality of the encoder layers of the Multiframe Integration Transformer (MIT). + mit_intermediate_size (`int`, *optional*, defaults to 2048): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Multiframe Integration Transformer + (MIT). + mit_num_hidden_layers (`int`, *optional*, defaults to 1): + Number of hidden layers in the Multiframe Integration Transformer (MIT). + mit_num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads for each attention layer in the Multiframe Integration Transformer (MIT). + image_size (`int`, *optional*, defaults to 224): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to 32): + The size (resolution) of each patch. + hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"`, `"gelu_new"` and ``"quick_gelu"` are supported. + layer_norm_eps (`float`, *optional*, defaults to 1e-5): + The epsilon used by the layer normalization layers. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + initializer_factor (`float``, *optional*, defaults to 1): + A factor for initializing all weight matrices (should be kept to 1, used internally for initialization + testing). + drop_path_rate (`float`, *optional*, defaults to 0.0): + Stochastic depth rate. + + Example: + + ```python + >>> from transformers import XCLIPVisionModel, XCLIPVisionConfig + + >>> # Initializing a XCLIPVisionModel with microsoft/xclip-base-patch32 style configuration + >>> configuration = XCLIPVisionConfig() + + >>> # Initializing a XCLIPVisionModel model from the microsoft/xclip-base-patch32 style configuration + >>> model = XCLIPVisionModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "xclip_vision_model" + + def __init__( + self, + hidden_size=768, + intermediate_size=3072, + num_hidden_layers=12, + num_attention_heads=12, + mit_hidden_size=512, + mit_intermediate_size=2048, + mit_num_hidden_layers=1, + mit_num_attention_heads=8, + num_channels=3, + image_size=224, + patch_size=32, + num_frames=8, + hidden_act="quick_gelu", + layer_norm_eps=1e-5, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + drop_path_rate=0.0, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.mit_hidden_size = mit_hidden_size + self.mit_intermediate_size = mit_intermediate_size + self.mit_num_hidden_layers = mit_num_hidden_layers + self.mit_num_attention_heads = mit_num_attention_heads + self.num_channels = num_channels + self.patch_size = patch_size + self.num_frames = num_frames + self.image_size = image_size + self.initializer_range = initializer_range + self.initializer_factor = initializer_factor + self.attention_dropout = attention_dropout + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.drop_path_rate = drop_path_rate + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig": + config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs) + + # get the vision config dict if we are loading from XCLIPConfig + if config_dict.get("model_type") == "xclip": + config_dict = config_dict["vision_config"] + + if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type: + logger.warning( + f"You are using a model of type {config_dict['model_type']} to instantiate a model of type " + f"{cls.model_type}. This is not supported for all configurations of models and can yield errors." + ) + + return cls.from_dict(config_dict, **kwargs) + + +class XCLIPConfig(PretrainedConfig): + r""" + [`XCLIPConfig`] is the configuration class to store the configuration of a [`XCLIPModel`]. It is used to + instantiate X-CLIP model according to the specified arguments, defining the text model and vision model configs. + Instantiating a configuration with the defaults will yield a similar configuration to that of the X-CLIP + [microsoft/xclip-base-patch32](https://huggingface.co/microsoft/xclip-base-patch32) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + text_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`XCLIPTextConfig`]. + vision_config (`dict`, *optional*): + Dictionary of configuration options used to initialize [`XCLIPVisionConfig`]. + projection_dim (`int`, *optional*, defaults to 512): + Dimentionality of text and vision projection layers. + prompt_layers (`int`, *optional*, defaults to 2): + Number of layers in the video specific prompt generator. + prompt_alpha (`float`, *optional*, defaults to 0.1): + Alpha value to use in the video specific prompt generator. + prompt_hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`): + The non-linear activation function (function or string) in the video specific prompt generator. If string, + `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported. + prompt_num_attention_heads (`int`, *optional*, defaults to 8): + Number of attention heads in the cross-attention of the video specific prompt generator. + prompt_attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for the attention layers in the video specific prompt generator. + prompt_projection_dropout (`float`, *optional*, defaults to 0.0): + The dropout probability for the projection layers in the video specific prompt generator. + logit_scale_init_value (`float`, *optional*, defaults to 2.6592): + The inital value of the *logit_scale* parameter. Default is used as per the original XCLIP implementation. + kwargs (*optional*): + Dictionary of keyword arguments. + """ + + model_type = "xclip" + is_composition = True + + def __init__( + self, + text_config=None, + vision_config=None, + projection_dim=512, + prompt_layers=2, + prompt_alpha=0.1, + prompt_hidden_act="quick_gelu", + prompt_num_attention_heads=8, + prompt_attention_dropout=0.0, + prompt_projection_dropout=0.0, + logit_scale_init_value=2.6592, + **kwargs, + ): + # If `_config_dict` exist, we use them for the backward compatibility. + # We pop out these 2 attributes before calling `super().__init__` to avoid them being saved (which causes a lot + # of confusion!). + text_config_dict = kwargs.pop("text_config_dict", None) + vision_config_dict = kwargs.pop("vision_config_dict", None) + + super().__init__(**kwargs) + + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if text_config_dict is not None: + if text_config is None: + text_config = {} + + # This is the complete result when using `text_config_dict`. + _text_config_dict = XCLIPTextConfig(**text_config_dict).to_dict() + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key not in ["transformers_version"]: + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `XCLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overriden.' + ) + logger.warning(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + + if vision_config_dict is not None: + if vision_config is None: + vision_config = {} + + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = XCLIPVisionConfig(**vision_config_dict).to_dict() + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key not in ["transformers_version"]: + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `XCLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overriden.' + ) + logger.warning(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + + if text_config is None: + text_config = {} + logger.info("`text_config` is `None`. Initializing the `XCLIPTextConfig` with default values.") + + if vision_config is None: + vision_config = {} + logger.info("`vision_config` is `None`. initializing the `XCLIPVisionConfig` with default values.") + + self.text_config = XCLIPTextConfig(**text_config) + self.vision_config = XCLIPVisionConfig(**vision_config) + + self.projection_dim = projection_dim + self.prompt_layers = prompt_layers + self.prompt_alpha = prompt_alpha + self.prompt_hidden_act = prompt_hidden_act + self.prompt_num_attention_heads = prompt_num_attention_heads + self.prompt_attention_dropout = prompt_attention_dropout + self.prompt_projection_dropout = prompt_projection_dropout + self.logit_scale_init_value = logit_scale_init_value + self.initializer_factor = 1.0 + + @classmethod + def from_text_vision_configs(cls, text_config: XCLIPTextConfig, vision_config: XCLIPVisionConfig, **kwargs): + r""" + Instantiate a [`XCLIPConfig`] (or a derived class) from xclip text model configuration and xclip vision model + configuration. + + Returns: + [`XCLIPConfig`]: An instance of a configuration object + """ + + return cls(text_config=text_config.to_dict(), vision_config=vision_config.to_dict(), **kwargs) + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. + + Returns: + `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance, + """ + output = copy.deepcopy(self.__dict__) + output["text_config"] = self.text_config.to_dict() + output["vision_config"] = self.vision_config.to_dict() + output["model_type"] = self.__class__.model_type + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/convert_x_clip_original_pytorch_to_hf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/convert_x_clip_original_pytorch_to_hf.py new file mode 100644 index 0000000000000000000000000000000000000000..d4281fe849d61c9b4487d6fd9305c89bf4fb4e1f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/convert_x_clip_original_pytorch_to_hf.py @@ -0,0 +1,386 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse + +import gdown +import numpy as np +import torch +from huggingface_hub import hf_hub_download + +from transformers import ( + CLIPTokenizer, + CLIPTokenizerFast, + VideoMAEFeatureExtractor, + XCLIPConfig, + XCLIPModel, + XCLIPProcessor, + XCLIPTextConfig, + XCLIPVisionConfig, +) + + +def get_xclip_config(model_name, num_frames): + text_config = XCLIPTextConfig() + + # derive patch size from model name + start_idx = model_name.find("patch") + patch_size = int(model_name[start_idx + len("patch") : start_idx + len("patch") + 2]) + vision_config = XCLIPVisionConfig(patch_size=patch_size, num_frames=num_frames) + + if "large" in model_name: + text_config.hidden_size = 768 + text_config.intermediate_size = 3072 + text_config.num_attention_heads = 12 + + vision_config.hidden_size = 1024 + vision_config.intermediate_size = 4096 + vision_config.num_attention_heads = 16 + vision_config.num_hidden_layers = 24 + vision_config.mit_hidden_size = 768 + vision_config.mit_intermediate_size = 3072 + + if model_name == "xclip-large-patch14-16-frames": + vision_config.image_size = 336 + + config = XCLIPConfig.from_text_vision_configs(text_config, vision_config) + + if "large" in model_name: + config.projection_dim = 768 + + return config + + +def rename_key(name): + # text encoder + if name == "token_embedding.weight": + name = name.replace("token_embedding.weight", "text_model.embeddings.token_embedding.weight") + if name == "positional_embedding": + name = name.replace("positional_embedding", "text_model.embeddings.position_embedding.weight") + if "ln_1" in name: + name = name.replace("ln_1", "layer_norm1") + if "ln_2" in name: + name = name.replace("ln_2", "layer_norm2") + if "c_fc" in name: + name = name.replace("c_fc", "fc1") + if "c_proj" in name: + name = name.replace("c_proj", "fc2") + if name.startswith("transformer.resblocks"): + name = name.replace("transformer.resblocks", "text_model.encoder.layers") + if "attn.out_proj" in name and "message" not in name: + name = name.replace("attn.out_proj", "self_attn.out_proj") + if "ln_final" in name: + name = name.replace("ln_final", "text_model.final_layer_norm") + # visual encoder + if name == "visual.class_embedding": + name = name.replace("visual.class_embedding", "vision_model.embeddings.class_embedding") + if name == "visual.positional_embedding": + name = name.replace("visual.positional_embedding", "vision_model.embeddings.position_embedding.weight") + if name.startswith("visual.transformer.resblocks"): + name = name.replace("visual.transformer.resblocks", "vision_model.encoder.layers") + if "visual.conv1" in name: + name = name.replace("visual.conv1", "vision_model.embeddings.patch_embedding") + if "visual.ln_pre" in name: + name = name.replace("visual.ln_pre", "vision_model.pre_layernorm") + if "visual.ln_post" in name: + name = name.replace("visual.ln_post", "vision_model.post_layernorm") + if "visual.proj" in name: + name = name.replace("visual.proj", "visual_projection.weight") + if "text_projection" in name: + name = name.replace("text_projection", "text_projection.weight") + # things on top + if "prompts_visual_proj" in name: + name = name.replace("prompts_visual_proj", "prompts_visual_projection") + if "prompts_visual_ln" in name: + name = name.replace("prompts_visual_ln", "prompts_visual_layernorm") + # mit + if name == "mit.positional_embedding": + name = name.replace("positional", "position") + if name.startswith("mit.resblocks"): + name = name.replace("mit.resblocks", "mit.encoder.layers") + # prompts generator + if name.startswith("prompts_generator.norm"): + name = name.replace("prompts_generator.norm", "prompts_generator.layernorm") + + return name + + +def convert_state_dict(orig_state_dict, config): + for key in orig_state_dict.copy().keys(): + val = orig_state_dict.pop(key) + + if "attn.in_proj" in key: + key_split = key.split(".") + if key.startswith("visual"): + layer_num = key_split[3] + dim = config.vision_config.hidden_size + if "message_attn" in key: + if "weight" in key: + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.q_proj.weight"] = val[ + :dim, : + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.k_proj.weight"] = val[ + dim : dim * 2, : + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.v_proj.weight"] = val[ + -dim:, : + ] + else: + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.q_proj.bias"] = val[ + :dim + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.k_proj.bias"] = val[ + dim : dim * 2 + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.message_attn.v_proj.bias"] = val[ + -dim: + ] + else: + if "weight" in key: + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.q_proj.weight"] = val[ + :dim, : + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.k_proj.weight"] = val[ + dim : dim * 2, : + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.v_proj.weight"] = val[ + -dim:, : + ] + else: + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.q_proj.bias"] = val[:dim] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.k_proj.bias"] = val[ + dim : dim * 2 + ] + orig_state_dict[f"vision_model.encoder.layers.{layer_num}.self_attn.v_proj.bias"] = val[-dim:] + elif key.startswith("mit"): + layer_num = key_split[2] + dim = config.vision_config.mit_hidden_size + if "weight" in key: + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.q_proj.weight"] = val[:dim, :] + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.k_proj.weight"] = val[dim : dim * 2, :] + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.v_proj.weight"] = val[-dim:, :] + else: + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.q_proj.bias"] = val[:dim] + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.k_proj.bias"] = val[dim : dim * 2] + orig_state_dict[f"mit.encoder.layers.{layer_num}.self_attn.v_proj.bias"] = val[-dim:] + else: + layer_num = key_split[2] + dim = config.text_config.hidden_size + if "weight" in key: + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.q_proj.weight"] = val[:dim, :] + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.k_proj.weight"] = val[ + dim : dim * 2, : + ] + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.v_proj.weight"] = val[-dim:, :] + else: + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.q_proj.bias"] = val[:dim] + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.k_proj.bias"] = val[ + dim : dim * 2 + ] + orig_state_dict[f"text_model.encoder.layers.{layer_num}.self_attn.v_proj.bias"] = val[-dim:] + else: + new_key_name = rename_key(key) + if new_key_name in ["visual_projection.weight", "text_projection.weight"]: + val = val.T + orig_state_dict[new_key_name] = val + + return orig_state_dict + + +def prepare_video(num_frames): + if num_frames == 8: + filename = "eating_spaghetti_8_frames.npy" + elif num_frames == 16: + filename = "eating_spaghetti.npy" + elif num_frames == 32: + filename = "eating_spaghetti_32_frames.npy" + file = hf_hub_download( + repo_id="hf-internal-testing/spaghetti-video", + filename=filename, + repo_type="dataset", + ) + video = np.load(file) + return list(video) + + +def convert_xclip_checkpoint(model_name, pytorch_dump_folder_path=None, push_to_hub=False): + model_to_url = { + # fully supervised kinetics-400 checkpoints + "xclip-base-patch32": "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_32_8.pth", + "xclip-base-patch32-16-frames": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_32_16.pth" + ), + "xclip-base-patch16": "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_16_8.pth", + "xclip-base-patch16-16-frames": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_16_16.pth" + ), + "xclip-large-patch14": "https://drive.google.com/u/0/uc?id=1NUOImq0o5DlQTST17iIP3vG7DgmHQuCx&export=download&confirm=t&uuid=b26caedc-88e2-473e-830a-9d158b653cdb", + "xclip-large-patch14-16-frames": "https://drive.google.com/u/0/uc?id=1FOYgnJc097OJ4lGwtRCCydQyVPJEOH7d&export=download&confirm=t&uuid=538fa810-e671-4050-b385-9a623f89804f", + # fully supervised kinetics-600 checkpoints + "xclip-base-patch16-kinetics-600": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k600_16_8.pth" + ), + "xclip-base-patch16-kinetics-600-16-frames": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k600_16_16.pth" + ), + "xclip-large-patch14-kinetics-600": "https://drive.google.com/u/0/uc?id=1FV8C1INuM91sLAN4ImjzePLIlpMSihwV&export=download&confirm=t&uuid=141d4977-4a65-44ae-864f-4b0c19f838be", + # few shot + "xclip-base-patch16-hmdb-2-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_2.pth" + ), + "xclip-base-patch16-hmdb-4-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_4.pth" + ), + "xclip-base-patch16-hmdb-8-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_8.pth" + ), + "xclip-base-patch16-hmdb-16-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_16.pth" + ), + "xclip-base-patch16-ucf-2-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_2.pth" + ), + "xclip-base-patch16-ucf-4-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_4.pth" + ), + "xclip-base-patch16-ucf-8-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_8.pth" + ), + "xclip-base-patch16-ucf-16-shot": ( + "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_16.pth" + ), + # zero shot + "xclip-base-patch16-zero-shot": "https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/zero.pth", + } + + checkpoint_url = model_to_url[model_name] + num_frames = 8 + if "16-frames" in model_name: + num_frames = 16 + elif "shot" in model_name: + num_frames = 32 + + config = get_xclip_config(model_name, num_frames) + model = XCLIPModel(config) + model.eval() + + if "drive" in checkpoint_url: + output = "pytorch_model.bin" + gdown.cached_download(checkpoint_url, output, quiet=False) + state_dict = torch.load(output, map_location="cpu")["model"] + else: + state_dict = torch.hub.load_state_dict_from_url(checkpoint_url)["model"] + + state_dict = convert_state_dict(state_dict, config) + + model = XCLIPModel(config) + missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False) + assert missing_keys == ["text_model.embeddings.position_ids", "vision_model.embeddings.position_ids"] + model.eval() + + size = 336 if model_name == "xclip-large-patch14-16-frames" else 224 + feature_extractor = VideoMAEFeatureExtractor(size=size) + slow_tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-base-patch32") + fast_tokenizer = CLIPTokenizerFast.from_pretrained("openai/clip-vit-base-patch32") + processor = XCLIPProcessor(feature_extractor=feature_extractor, tokenizer=fast_tokenizer) + + video = prepare_video(num_frames) + inputs = processor( + text=["playing sports", "eating spaghetti", "go shopping"], videos=video, return_tensors="pt", padding=True + ) + + print("Shape of pixel values:", inputs.pixel_values.shape) + + with torch.no_grad(): + outputs = model(**inputs) + + # Verify outputs + logits_per_video = outputs.logits_per_video + probs = logits_per_video.softmax(dim=1) + print("Probs:", probs) + # kinetics-400 + if model_name == "xclip-base-patch32": + expected_probs = torch.tensor([[0.0019, 0.9951, 0.0030]]) + elif model_name == "xclip-base-patch32-16-frames": + expected_probs = torch.tensor([[7.0999e-04, 9.9883e-01, 4.5580e-04]]) + elif model_name == "xclip-base-patch16": + expected_probs = torch.tensor([[0.0083, 0.9681, 0.0236]]) + elif model_name == "xclip-base-patch16-16-frames": + expected_probs = torch.tensor([[7.6937e-04, 9.9728e-01, 1.9473e-03]]) + elif model_name == "xclip-large-patch14": + expected_probs = torch.tensor([[0.0062, 0.9864, 0.0075]]) + elif model_name == "xclip-large-patch14-16-frames": + expected_probs = torch.tensor([[3.3877e-04, 9.9937e-01, 2.8888e-04]]) + # kinetics-600 + elif model_name == "xclip-base-patch16-kinetics-600": + expected_probs = torch.tensor([[0.0555, 0.8914, 0.0531]]) + elif model_name == "xclip-base-patch16-kinetics-600-16-frames": + expected_probs = torch.tensor([[3.8554e-04, 9.9929e-01, 3.2754e-04]]) + elif model_name == "xclip-large-patch14-kinetics-600": + expected_probs = torch.tensor([[0.0036, 0.9920, 0.0045]]) + # few shot + elif model_name == "xclip-base-patch16-hmdb-2-shot": + expected_probs = torch.tensor([[7.1890e-06, 9.9994e-01, 5.6559e-05]]) + elif model_name == "xclip-base-patch16-hmdb-4-shot": + expected_probs = torch.tensor([[1.0320e-05, 9.9993e-01, 6.2435e-05]]) + elif model_name == "xclip-base-patch16-hmdb-8-shot": + expected_probs = torch.tensor([[4.1377e-06, 9.9990e-01, 9.8386e-05]]) + elif model_name == "xclip-base-patch16-hmdb-16-shot": + expected_probs = torch.tensor([[4.1347e-05, 9.9962e-01, 3.3411e-04]]) + elif model_name == "xclip-base-patch16-ucf-2-shot": + expected_probs = torch.tensor([[8.5857e-05, 9.9928e-01, 6.3291e-04]]) + elif model_name == "xclip-base-patch16-ucf-4-shot": + expected_probs = torch.tensor([[8.5857e-05, 9.9928e-01, 6.3291e-04]]) + elif model_name == "xclip-base-patch16-ucf-8-shot": + expected_probs = torch.tensor([[0.0027, 0.9904, 0.0070]]) + elif model_name == "xclip-base-patch16-ucf-16-shot": + expected_probs = torch.tensor([[9.8219e-04, 9.9593e-01, 3.0863e-03]]) + # zero shot + elif model_name == "xclip-base-patch16-zero-shot": + expected_probs = torch.tensor([[3.5082e-04, 9.9785e-01, 1.7966e-03]]) + else: + raise ValueError(f"Model name {model_name} not supported") + assert torch.allclose(probs, expected_probs, atol=1e-3) + print("Looks ok!") + + if pytorch_dump_folder_path is not None: + print(f"Saving model {model_name} to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + print("Pushing model, processor and slow tokenizer files to the hub...") + model.push_to_hub(model_name, organization="nielsr") + processor.push_to_hub(model_name, organization="nielsr") + slow_tokenizer.push_to_hub(model_name, organization="nielsr") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--model_name", + default="xclip-base-patch32", + type=str, + help="Name of the model.", + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + + args = parser.parse_args() + convert_xclip_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/modeling_x_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/modeling_x_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..337d919cf4a6a48aa14886b0301c597374f33fa0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/modeling_x_clip.py @@ -0,0 +1,1640 @@ +# coding=utf-8 +# Copyright 2022 Microsoft Research and The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch X-CLIP model.""" + + +from copy import copy +from dataclasses import dataclass +from typing import Any, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_x_clip import XCLIPConfig, XCLIPTextConfig, XCLIPVisionConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "microsoft/xclip-base-patch32" + +XCLIP_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "microsoft/xclip-base-patch32", + # See all X-CLIP models at https://huggingface.co/models?filter=x-clip +] + + +# Copied from transformers.models.bart.modeling_bart._expand_mask +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + bsz, src_len = mask.size() + tgt_len = tgt_len if tgt_len is not None else src_len + + expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min) + + +# contrastive loss function, adapted from +# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html +def contrastive_loss(logits: torch.Tensor) -> torch.Tensor: + return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device)) + + +# Copied from transformers.models.clip.modeling_clip.clip_loss with clip->x_clip +def x_clip_loss(similarity: torch.Tensor) -> torch.Tensor: + caption_loss = contrastive_loss(similarity) + image_loss = contrastive_loss(similarity.t()) + return (caption_loss + image_loss) / 2.0 + + +@dataclass +class XCLIPOutput(ModelOutput): + """ + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`): + Contrastive loss for video-text similarity. + logits_per_video (`torch.FloatTensor` of shape `(video_batch_size, text_batch_size)`): + The scaled dot product scores between `video_embeds` and `text_embeds`. This represents the video-text + similarity scores. + logits_per_text (`torch.FloatTensor` of shape `(text_batch_size, video_batch_size)`): + The scaled dot product scores between `text_embeds` and `video_embeds`. This represents the text-video + similarity scores. + text_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The text embeddings obtained by applying the projection layer to the pooled output of [`XCLIPTextModel`]. + video_embeds(`torch.FloatTensor` of shape `(batch_size, output_dim`): + The video embeddings obtained by applying the projection layer to the pooled output of + [`XCLIPVisionModel`]. + text_model_output (`BaseModelOutputWithPooling`): + The output of the [`XCLIPTextModel`]. + vision_model_output (`BaseModelOutputWithPooling`): + The output of the [`XCLIPVisionModel`]. + mit_output (`BaseModelOutputWithPooling`): + The output of `XCLIPMultiframeIntegrationTransformer` (MIT for short). + """ + + loss: Optional[torch.FloatTensor] = None + logits_per_video: torch.FloatTensor = None + logits_per_text: torch.FloatTensor = None + text_embeds: torch.FloatTensor = None + video_embeds: torch.FloatTensor = None + text_model_output: BaseModelOutputWithPooling = None + vision_model_output: BaseModelOutputWithPooling = None + mit_output: BaseModelOutputWithPooling = None + + def to_tuple(self) -> Tuple[Any]: + return tuple( + self[k] + if k not in ["text_model_output", "vision_model_output", "mit_output"] + else getattr(self, k).to_tuple() + for k in self.keys() + ) + + +# Copied from transformers.models.clip.modeling_clip.CLIPVisionEmbeddings with CLIP->XCLIP +class XCLIPVisionEmbeddings(nn.Module): + def __init__(self, config: XCLIPVisionConfig): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.image_size = config.image_size + self.patch_size = config.patch_size + + self.class_embedding = nn.Parameter(torch.randn(self.embed_dim)) + + self.patch_embedding = nn.Conv2d( + in_channels=config.num_channels, + out_channels=self.embed_dim, + kernel_size=self.patch_size, + stride=self.patch_size, + bias=False, + ) + + self.num_patches = (self.image_size // self.patch_size) ** 2 + self.num_positions = self.num_patches + 1 + self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim) + self.register_buffer("position_ids", torch.arange(self.num_positions).expand((1, -1))) + + def forward(self, pixel_values: torch.FloatTensor) -> torch.Tensor: + batch_size = pixel_values.shape[0] + patch_embeds = self.patch_embedding(pixel_values) # shape = [*, width, grid, grid] + patch_embeds = patch_embeds.flatten(2).transpose(1, 2) + + class_embeds = self.class_embedding.expand(batch_size, 1, -1) + embeddings = torch.cat([class_embeds, patch_embeds], dim=1) + embeddings = embeddings + self.position_embedding(self.position_ids) + return embeddings + + +# Copied from transformers.models.clip.modeling_clip.CLIPTextEmbeddings with CLIP->XCLIP +class XCLIPTextEmbeddings(nn.Module): + def __init__(self, config: XCLIPTextConfig): + super().__init__() + embed_dim = config.hidden_size + + self.token_embedding = nn.Embedding(config.vocab_size, embed_dim) + self.position_embedding = nn.Embedding(config.max_position_embeddings, embed_dim) + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + ) -> torch.Tensor: + seq_length = input_ids.shape[-1] if input_ids is not None else inputs_embeds.shape[-2] + + if position_ids is None: + position_ids = self.position_ids[:, :seq_length] + + if inputs_embeds is None: + inputs_embeds = self.token_embedding(input_ids) + + position_embeddings = self.position_embedding(position_ids) + embeddings = inputs_embeds + position_embeddings + + return embeddings + + +# Copied from transformers.models.clip.modeling_clip.CLIPAttention with CLIP->XCLIP +class XCLIPAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.num_heads = config.num_attention_heads + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {self.num_heads})." + ) + self.scale = self.head_dim**-0.5 + self.dropout = config.attention_dropout + + self.k_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.v_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.q_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.out_proj = nn.Linear(self.embed_dim, self.embed_dim) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + bsz, tgt_len, embed_dim = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scale + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + # apply the causal_attention_mask first + if causal_attention_mask is not None: + if causal_attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {causal_attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + causal_attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if output_attentions: + # this operation is a bit akward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + attn_output = attn_output.reshape(bsz, tgt_len, embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped + + +# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->XCLIP +class XCLIPMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.activation_fn = ACT2FN[config.hidden_act] + self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size) + self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.fc1(hidden_states) + hidden_states = self.activation_fn(hidden_states) + hidden_states = self.fc2(hidden_states) + return hidden_states + + +# Copied from transformers.models.clip.modeling_clip.CLIPEncoderLayer with CLIP->XCLIP +class XCLIPEncoderLayer(nn.Module): + def __init__(self, config: XCLIPConfig): + super().__init__() + self.embed_dim = config.hidden_size + self.self_attn = XCLIPAttention(config) + self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.mlp = XCLIPMLP(config) + self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + causal_attention_mask: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.FloatTensor]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + `(config.encoder_attention_heads,)`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + hidden_states = self.layer_norm1(hidden_states) + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + causal_attention_mask=causal_attention_mask, + output_attentions=output_attentions, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.layer_norm2(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +# Copied from transformers.models.beit.modeling_beit.drop_path +def drop_path(input, drop_prob: float = 0.0, training: bool = False): + """ + Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). + + Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks, + however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... + See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the + layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the + argument. + """ + if drop_prob == 0.0 or not training: + return input + keep_prob = 1 - drop_prob + shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device) + random_tensor.floor_() # binarize + output = input.div(keep_prob) * random_tensor + return output + + +# Copied from transformers.models.beit.modeling_beit.BeitDropPath with Beit->XCLIP +class XCLIPDropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob: Optional[float] = None) -> None: + super().__init__() + self.drop_prob = drop_prob + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + return drop_path(hidden_states, self.drop_prob, self.training) + + def extra_repr(self) -> str: + return "p={}".format(self.drop_prob) + + +class XCLIPVisionEncoderLayer(nn.Module): + """ + This corresponds to the `CrossFramelAttentionBlock` class in the original implementation. + """ + + def __init__(self, config: XCLIPConfig): + super().__init__() + self.num_frames = config.num_frames + self.embed_dim = config.hidden_size + + self.message_fc = nn.Linear(self.embed_dim, self.embed_dim) + self.message_ln = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.message_attn = XCLIPAttention(config) + + self.drop_path = XCLIPDropPath(config.drop_path_rate) if config.drop_path_rate > 0.0 else nn.Identity() + + self.self_attn = XCLIPAttention(config) + self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.mlp = XCLIPMLP(config) + self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + causal_attention_mask: torch.Tensor, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.FloatTensor]: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + `(config.encoder_attention_heads,)`. + causal_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Causal mask for the text model. Mask values selected in `[0, 1]`: + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + batch_time, seq_length, hidden_size = hidden_states.size() + batch_size = batch_time // self.num_frames + msg_token = self.message_fc(hidden_states[:, 0, :]) + msg_token = msg_token.view(batch_size, self.num_frames, hidden_size) + + msg_token = msg_token + self.drop_path(self.message_attn(self.message_ln(msg_token))[0]) + # add dummy sequence dimension + msg_token = msg_token.view(-1, 1, hidden_size) + + hidden_states = torch.cat([hidden_states, msg_token], dim=1) + + residual = hidden_states + + hidden_states = self.layer_norm1(hidden_states) + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + causal_attention_mask=causal_attention_mask, + output_attentions=output_attentions, + ) + hidden_states = residual + hidden_states + + hidden_states = hidden_states[:, :seq_length, :] + + residual = hidden_states + hidden_states = self.layer_norm2(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class XCLIPPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XCLIPConfig + base_model_prefix = "x_clip" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + factor = self.config.initializer_factor + if isinstance(module, XCLIPTextEmbeddings): + module.token_embedding.weight.data.normal_(mean=0.0, std=factor * 0.02) + module.position_embedding.weight.data.normal_(mean=0.0, std=factor * 0.02) + elif isinstance(module, XCLIPVisionEmbeddings): + factor = self.config.initializer_factor + nn.init.normal_(module.class_embedding, mean=0.0, std=module.embed_dim**-0.5 * factor) + nn.init.normal_(module.patch_embedding.weight, std=module.config.initializer_range * factor) + nn.init.normal_(module.position_embedding.weight, std=module.config.initializer_range * factor) + elif isinstance(module, XCLIPAttention): + factor = self.config.initializer_factor + in_proj_std = (module.embed_dim**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + out_proj_std = (module.embed_dim**-0.5) * factor + nn.init.normal_(module.q_proj.weight, std=in_proj_std) + nn.init.normal_(module.k_proj.weight, std=in_proj_std) + nn.init.normal_(module.v_proj.weight, std=in_proj_std) + nn.init.normal_(module.out_proj.weight, std=out_proj_std) + elif isinstance(module, XCLIPMLP): + factor = self.config.initializer_factor + in_proj_std = ( + (module.config.hidden_size**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + ) + fc_std = (2 * module.config.hidden_size) ** -0.5 * factor + nn.init.normal_(module.fc1.weight, std=fc_std) + nn.init.normal_(module.fc2.weight, std=in_proj_std) + elif isinstance(module, XCLIPModel): + factor = self.config.initializer_factor + nn.init.normal_( + module.text_projection.weight, + std=module.text_embed_dim**-0.5 * factor, + ) + nn.init.normal_( + module.visual_projection.weight, + std=module.vision_embed_dim**-0.5 * factor, + ) + nn.init.normal_(module.prompts_visual_projection, mean=0.0, std=module.vision_embed_dim**-0.5 * factor) + elif isinstance(module, XCLIPMultiframeIntegrationTransformer): + nn.init.normal_(module.position_embedding, std=self.config.initializer_factor) + + if isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_factor) + if module.bias is not None: + module.bias.data.zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (XCLIPEncoder, XCLIPVisionEncoder)): + module.gradient_checkpointing = value + + +X_CLIP_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`XCLIPConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +X_CLIP_TEXT_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +X_CLIP_VISION_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + +X_CLIP_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using + [`AutoImageProcessor`]. See [`CLIPImageProcessor.__call__`] for details. + return_loss (`bool`, *optional*): + Whether or not to return the contrastive loss. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from transformers.models.clip.modeling_clip.CLIPEncoder with CLIP->XCLIP +class XCLIPEncoder(nn.Module): + """ + Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a + [`XCLIPEncoderLayer`]. + + Args: + config: XCLIPConfig + """ + + def __init__(self, config: XCLIPConfig): + super().__init__() + self.config = config + self.layers = nn.ModuleList([XCLIPEncoderLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + inputs_embeds, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + causal_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Causal mask for the text model. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + hidden_states = inputs_embeds + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + attention_mask, + causal_attention_mask, + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + causal_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class XCLIPTextTransformer(nn.Module): + def __init__(self, config: XCLIPTextConfig): + super().__init__() + self.config = config + embed_dim = config.hidden_size + self.embeddings = XCLIPTextEmbeddings(config) + self.encoder = XCLIPEncoder(config) + self.final_layer_norm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + + @add_start_docstrings_to_model_forward(X_CLIP_TEXT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=XCLIPTextConfig) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is None: + raise ValueError("You have to specify either input_ids") + + input_shape = input_ids.size() + input_ids = input_ids.view(-1, input_shape[-1]) + + hidden_states = self.embeddings(input_ids=input_ids, position_ids=position_ids) + + batch_size, seq_len = input_shape + # X_CLIP's text model uses causal mask, prepare it here. + # https://github.com/openai/CLIP/blob/cfcffb90e69f37bf2ff1e988237a0fbe41f33c04/clip/model.py#L324 + causal_attention_mask = self._build_causal_attention_mask(batch_size, seq_len, hidden_states.dtype).to( + hidden_states.device + ) + # expand attention_mask + if attention_mask is not None: + # [batch_size, seq_len] -> [batch_size, 1, tgt_seq_len, src_seq_len] + attention_mask = _expand_mask(attention_mask, hidden_states.dtype) + + encoder_outputs = self.encoder( + inputs_embeds=hidden_states, + attention_mask=attention_mask, + causal_attention_mask=causal_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_state = encoder_outputs[0] + last_hidden_state = self.final_layer_norm(last_hidden_state) + + # text_embeds.shape = [batch_size, sequence_length, transformer.width] + # take features from the eot embedding (eot_token is the highest number in each sequence) + pooled_output = last_hidden_state[torch.arange(last_hidden_state.shape[0]), input_ids.argmax(dim=-1)] + + if not return_dict: + return (last_hidden_state, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=last_hidden_state, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + def _build_causal_attention_mask(self, batch_size, seq_len, dtype): + # lazily create causal attention mask, with full attention between the vision tokens + # pytorch uses additive attention mask; fill with -inf + mask = torch.empty(batch_size, seq_len, seq_len, dtype=dtype) + mask.fill_(torch.tensor(torch.finfo(dtype).min)) + mask.triu_(1) # zero out the lower diagonal + mask = mask.unsqueeze(1) # expand mask + return mask + + +class XCLIPTextModel(XCLIPPreTrainedModel): + config_class = XCLIPTextConfig + + def __init__(self, config: XCLIPTextConfig): + super().__init__(config) + self.text_model = XCLIPTextTransformer(config) + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.text_model.embeddings.token_embedding + + def set_input_embeddings(self, value): + self.text_model.embeddings.token_embedding = value + + @add_start_docstrings_to_model_forward(X_CLIP_TEXT_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=XCLIPTextConfig) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + Examples: + + ```python + >>> from transformers import AutoTokenizer, XCLIPTextModel + + >>> model = XCLIPTextModel.from_pretrained("microsoft/xclip-base-patch32") + >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/xclip-base-patch32") + + >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt") + + >>> outputs = model(**inputs) + >>> last_hidden_state = outputs.last_hidden_state + >>> pooled_output = outputs.pooler_output # pooled (EOS token) states + ```""" + return self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +class XCLIPVisionEncoder(nn.Module): + """ + Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a + [`XCLIPVisionEncoderLayer`]. + + Args: + config: XCLIPConfig + """ + + def __init__(self, config: XCLIPConfig): + super().__init__() + self.config = config + self.layers = nn.ModuleList([XCLIPVisionEncoderLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + inputs_embeds, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + causal_attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Causal mask for the text model. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + hidden_states = inputs_embeds + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + attention_mask, + causal_attention_mask, + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + causal_attention_mask, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions + ) + + +class XCLIPVisionTransformer(nn.Module): + """ + This corresponds to the `CrossFrameCommunicationTransformer` class in the original implementation. + """ + + def __init__(self, config: XCLIPVisionConfig): + super().__init__() + self.config = config + embed_dim = config.hidden_size + + self.embeddings = XCLIPVisionEmbeddings(config) + self.pre_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + self.encoder = XCLIPVisionEncoder(config) + self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + + @add_start_docstrings_to_model_forward(X_CLIP_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=XCLIPVisionConfig) + def forward( + self, + pixel_values: torch.FloatTensor, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + hidden_states = self.embeddings(pixel_values) + hidden_states = self.pre_layernorm(hidden_states) + + encoder_outputs = self.encoder( + inputs_embeds=hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_state = encoder_outputs[0] + pooled_output = last_hidden_state[:, 0, :] + pooled_output = self.post_layernorm(pooled_output) + + if not return_dict: + return (last_hidden_state, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=last_hidden_state, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class XCLIPVisionModel(XCLIPPreTrainedModel): + config_class = XCLIPVisionConfig + main_input_name = "pixel_values" + + def __init__(self, config: XCLIPVisionConfig): + super().__init__(config) + self.vision_model = XCLIPVisionTransformer(config) + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.vision_model.embeddings.patch_embedding + + @add_start_docstrings_to_model_forward(X_CLIP_VISION_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutputWithPooling, config_class=XCLIPVisionConfig) + def forward( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + r""" + Returns: + + Examples: + + ```python + >>> import av + >>> import torch + >>> import numpy as np + + >>> from transformers import AutoProcessor, XCLIPVisionModel + >>> from huggingface_hub import hf_hub_download + + >>> np.random.seed(0) + + + >>> def read_video_pyav(container, indices): + ... ''' + ... Decode the video with PyAV decoder. + ... Args: + ... container (`av.container.input.InputContainer`): PyAV container. + ... indices (`List[int]`): List of frame indices to decode. + ... Returns: + ... result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3). + ... ''' + ... frames = [] + ... container.seek(0) + ... start_index = indices[0] + ... end_index = indices[-1] + ... for i, frame in enumerate(container.decode(video=0)): + ... if i > end_index: + ... break + ... if i >= start_index and i in indices: + ... frames.append(frame) + ... return np.stack([x.to_ndarray(format="rgb24") for x in frames]) + + + >>> def sample_frame_indices(clip_len, frame_sample_rate, seg_len): + ... converted_len = int(clip_len * frame_sample_rate) + ... end_idx = np.random.randint(converted_len, seg_len) + ... start_idx = end_idx - converted_len + ... indices = np.linspace(start_idx, end_idx, num=clip_len) + ... indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64) + ... return indices + + + >>> # video clip consists of 300 frames (10 seconds at 30 FPS) + >>> file_path = hf_hub_download( + ... repo_id="nielsr/video-demo", filename="eating_spaghetti.mp4", repo_type="dataset" + ... ) + >>> container = av.open(file_path) + + >>> # sample 16 frames + >>> indices = sample_frame_indices(clip_len=8, frame_sample_rate=1, seg_len=container.streams.video[0].frames) + >>> video = read_video_pyav(container, indices) + + >>> processor = AutoProcessor.from_pretrained("microsoft/xclip-base-patch32") + >>> model = XCLIPVisionModel.from_pretrained("microsoft/xclip-base-patch32") + + >>> pixel_values = processor(videos=list(video), return_tensors="pt").pixel_values + + >>> batch_size, num_frames, num_channels, height, width = pixel_values.shape + >>> pixel_values = pixel_values.reshape(-1, num_channels, height, width) + + >>> outputs = model(pixel_values) + >>> last_hidden_state = outputs.last_hidden_state + ```""" + return self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +class XCLIPMultiframeIntegrationTransformer(nn.Module): + """ + This corresponds to the `MultiframeIntegrationTransformer` class in the original implementation. + """ + + def __init__(self, config: XCLIPVisionConfig): + super().__init__() + + self.position_embedding = nn.Parameter(torch.empty(1, config.num_frames, config.hidden_size)) + self.encoder = XCLIPEncoder(config) + + def forward( + self, + hidden_states, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + residual = hidden_states + + # add position embeddings + hidden_states = hidden_states + self.position_embedding + + encoder_outputs = self.encoder( + inputs_embeds=hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + last_hidden_state = encoder_outputs[0] + + last_hidden_state = last_hidden_state.type(hidden_states.dtype) + residual + + pooled_output = last_hidden_state.mean(dim=1, keepdim=False) + + if not return_dict: + return (last_hidden_state, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=last_hidden_state, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class XCLIPCrossAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config): + super().__init__() + self.num_heads = config.prompt_num_attention_heads + + dim = config.projection_dim + head_dim = dim // self.num_heads + self.scale = head_dim**-0.5 + + self.q_proj = nn.Linear(dim, dim, bias=False) + self.k_proj = nn.Linear(dim, dim, bias=False) + self.v_proj = nn.Linear(dim, dim, bias=False) + + self.attn_drop = nn.Dropout(config.prompt_attention_dropout) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(config.prompt_projection_dropout) + + def _shape(self, tensor: torch.Tensor, seq_len: int, batch_size: int): + return tensor.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward(self, queries, keys, values): + """Input shape: Batch x Time x Channel""" + batch_size, query_seq_len, hidden_size = queries.shape + batch_size, key_seq_len, hidden_size = keys.shape + queries = ( + self.q_proj(queries) + .reshape(batch_size, query_seq_len, self.num_heads, hidden_size // self.num_heads) + .permute(0, 2, 1, 3) + ) + keys = ( + self.k_proj(keys) + .reshape(batch_size, key_seq_len, self.num_heads, hidden_size // self.num_heads) + .permute(0, 2, 1, 3) + ) + values = ( + self.v_proj(values) + .reshape(batch_size, key_seq_len, self.num_heads, hidden_size // self.num_heads) + .permute(0, 2, 1, 3) + ) + + attn = (queries @ keys.transpose(-2, -1)) * self.scale + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ values).transpose(1, 2).reshape(batch_size, query_seq_len, hidden_size) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +class PromptGeneratorLayer(nn.Module): + def __init__(self, config): + super().__init__() + + embed_dim = config.projection_dim + self.cross_attn = XCLIPCrossAttention(config) + self.norm1 = nn.LayerNorm(embed_dim, eps=config.text_config.layer_norm_eps) + self.norm3 = nn.LayerNorm(embed_dim, eps=config.text_config.layer_norm_eps) + self.mlp = nn.Sequential( + nn.Linear(embed_dim, embed_dim * 4), + ACT2FN[config.prompt_hidden_act], + nn.Dropout(config.prompt_attention_dropout), + nn.Linear(embed_dim * 4, embed_dim), + ) + + def forward(self, x, visual): + x = x + self.cross_attn(self.norm1(x), visual, visual) + x = x + self.mlp(self.norm3(x)) + return x + + +class XCLIPPromptGenerator(nn.Module): + """This corresponds to the `VideoSpecificPrompt` class in the original implementation.""" + + def __init__(self, config): + super().__init__() + embed_dim = config.projection_dim + self.layernorm = nn.LayerNorm(embed_dim, eps=config.vision_config.layer_norm_eps) + self.decoder = nn.ModuleList([PromptGeneratorLayer(config) for _ in range(config.prompt_layers)]) + self.alpha = nn.Parameter(torch.ones(embed_dim) * config.prompt_alpha) + + def forward(self, text, visual): + visual = self.layernorm(visual) + for layer in self.decoder: + text = layer(text, visual) + + return self.alpha * text + + +@add_start_docstrings(X_CLIP_START_DOCSTRING) +class XCLIPModel(XCLIPPreTrainedModel): + config_class = XCLIPConfig + + def __init__(self, config: XCLIPConfig): + super().__init__(config) + + if not isinstance(config.text_config, XCLIPTextConfig): + raise ValueError( + "config.text_config is expected to be of type XCLIPTextConfig but is of type" + f" {type(config.text_config)}." + ) + + if not isinstance(config.vision_config, XCLIPVisionConfig): + raise ValueError( + "config.vision_config is expected to be of type XCLIPVisionConfig but is of type" + f" {type(config.vision_config)}." + ) + + text_config = config.text_config + vision_config = config.vision_config + + self.projection_dim = config.projection_dim + self.text_embed_dim = text_config.hidden_size + self.vision_embed_dim = vision_config.hidden_size + + self.text_model = XCLIPTextTransformer(text_config) + self.vision_model = XCLIPVisionTransformer(vision_config) + + self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False) + self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False) + self.logit_scale = nn.Parameter(torch.ones([]) * self.config.logit_scale_init_value) + + self.prompts_visual_layernorm = nn.LayerNorm(self.vision_embed_dim, eps=config.vision_config.layer_norm_eps) + self.prompts_visual_projection = nn.Parameter(torch.randn(self.vision_embed_dim, self.projection_dim)) + + mit_config = copy(vision_config) + mit_config.hidden_size = vision_config.mit_hidden_size + mit_config.intermediate_size = vision_config.mit_intermediate_size + mit_config.num_hidden_layers = vision_config.mit_num_hidden_layers + mit_config.num_attention_heads = vision_config.mit_num_attention_heads + self.mit = XCLIPMultiframeIntegrationTransformer(mit_config) + + self.prompts_generator = XCLIPPromptGenerator(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(X_CLIP_TEXT_INPUTS_DOCSTRING) + def get_text_features( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + text_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The text embeddings obtained by + applying the projection layer to the pooled output of [`XCLIPTextModel`]. + + Examples: + + ```python + >>> from transformers import AutoTokenizer, AutoModel + + >>> tokenizer = AutoTokenizer.from_pretrained("microsoft/xclip-base-patch32") + >>> model = AutoModel.from_pretrained("microsoft/xclip-base-patch32") + + >>> inputs = tokenizer(["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt") + >>> text_features = model.get_text_features(**inputs) + ```""" + # Use X_CLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + text_embeds = text_outputs[1] + text_embeds = self.text_projection(text_embeds) + + return text_embeds + + @add_start_docstrings_to_model_forward(X_CLIP_VISION_INPUTS_DOCSTRING) + def get_video_features( + self, + pixel_values: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> torch.FloatTensor: + r""" + Returns: + video_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The video embeddings obtained by + applying the projection layer to the pooled output of [`XCLIPVisionModel`] and + [`XCLIPMultiframeIntegrationTransformer`]. + + Examples: + + ```python + >>> import av + >>> import torch + >>> import numpy as np + + >>> from transformers import AutoProcessor, AutoModel + >>> from huggingface_hub import hf_hub_download + + >>> np.random.seed(0) + + + >>> def read_video_pyav(container, indices): + ... ''' + ... Decode the video with PyAV decoder. + ... Args: + ... container (`av.container.input.InputContainer`): PyAV container. + ... indices (`List[int]`): List of frame indices to decode. + ... Returns: + ... result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3). + ... ''' + ... frames = [] + ... container.seek(0) + ... start_index = indices[0] + ... end_index = indices[-1] + ... for i, frame in enumerate(container.decode(video=0)): + ... if i > end_index: + ... break + ... if i >= start_index and i in indices: + ... frames.append(frame) + ... return np.stack([x.to_ndarray(format="rgb24") for x in frames]) + + + >>> def sample_frame_indices(clip_len, frame_sample_rate, seg_len): + ... converted_len = int(clip_len * frame_sample_rate) + ... end_idx = np.random.randint(converted_len, seg_len) + ... start_idx = end_idx - converted_len + ... indices = np.linspace(start_idx, end_idx, num=clip_len) + ... indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64) + ... return indices + + + >>> # video clip consists of 300 frames (10 seconds at 30 FPS) + >>> file_path = hf_hub_download( + ... repo_id="nielsr/video-demo", filename="eating_spaghetti.mp4", repo_type="dataset" + ... ) + >>> container = av.open(file_path) + + >>> # sample 8 frames + >>> indices = sample_frame_indices(clip_len=8, frame_sample_rate=1, seg_len=container.streams.video[0].frames) + >>> video = read_video_pyav(container, indices) + + >>> processor = AutoProcessor.from_pretrained("microsoft/xclip-base-patch32") + >>> model = AutoModel.from_pretrained("microsoft/xclip-base-patch32") + + >>> inputs = processor(videos=list(video), return_tensors="pt") + + >>> video_features = model.get_video_features(**inputs) + ```""" + # Use X_CLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_frames, num_channels, height, width = pixel_values.shape + pixel_values = pixel_values.reshape(-1, num_channels, height, width) + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + video_embeds = vision_outputs[1] + video_embeds = self.visual_projection(video_embeds) + + cls_features = video_embeds.view(batch_size, num_frames, -1) + + mit_outputs = self.mit( + cls_features, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + video_embeds = mit_outputs[1] + + return video_embeds + + @add_start_docstrings_to_model_forward(X_CLIP_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=XCLIPOutput, config_class=XCLIPConfig) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + pixel_values: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + return_loss: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XCLIPOutput]: + r""" + Returns: + + Examples: + + ```python + >>> import av + >>> import torch + >>> import numpy as np + + >>> from transformers import AutoProcessor, AutoModel + >>> from huggingface_hub import hf_hub_download + + >>> np.random.seed(0) + + + >>> def read_video_pyav(container, indices): + ... ''' + ... Decode the video with PyAV decoder. + ... Args: + ... container (`av.container.input.InputContainer`): PyAV container. + ... indices (`List[int]`): List of frame indices to decode. + ... Returns: + ... result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3). + ... ''' + ... frames = [] + ... container.seek(0) + ... start_index = indices[0] + ... end_index = indices[-1] + ... for i, frame in enumerate(container.decode(video=0)): + ... if i > end_index: + ... break + ... if i >= start_index and i in indices: + ... frames.append(frame) + ... return np.stack([x.to_ndarray(format="rgb24") for x in frames]) + + + >>> def sample_frame_indices(clip_len, frame_sample_rate, seg_len): + ... converted_len = int(clip_len * frame_sample_rate) + ... end_idx = np.random.randint(converted_len, seg_len) + ... start_idx = end_idx - converted_len + ... indices = np.linspace(start_idx, end_idx, num=clip_len) + ... indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64) + ... return indices + + + >>> # video clip consists of 300 frames (10 seconds at 30 FPS) + >>> file_path = hf_hub_download( + ... repo_id="nielsr/video-demo", filename="eating_spaghetti.mp4", repo_type="dataset" + ... ) + >>> container = av.open(file_path) + + >>> # sample 8 frames + >>> indices = sample_frame_indices(clip_len=8, frame_sample_rate=1, seg_len=container.streams.video[0].frames) + >>> video = read_video_pyav(container, indices) + + >>> processor = AutoProcessor.from_pretrained("microsoft/xclip-base-patch32") + >>> model = AutoModel.from_pretrained("microsoft/xclip-base-patch32") + + >>> inputs = processor( + ... text=["playing sports", "eating spaghetti", "go shopping"], + ... videos=list(video), + ... return_tensors="pt", + ... padding=True, + ... ) + + >>> # forward pass + >>> with torch.no_grad(): + ... outputs = model(**inputs) + + >>> logits_per_video = outputs.logits_per_video # this is the video-text similarity score + >>> probs = logits_per_video.softmax(dim=1) # we can take the softmax to get the label probabilities + >>> print(probs) + tensor([[1.9496e-04, 9.9960e-01, 2.0825e-04]]) + ```""" + # Use X_CLIP model's config for some fields (if specified) instead of those of vision & text components. + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + batch_size, num_frames, num_channels, height, width = pixel_values.shape + pixel_values = pixel_values.reshape(-1, num_channels, height, width) + + vision_outputs = self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + video_embeds = vision_outputs[1] + video_embeds = self.visual_projection(video_embeds) + + cls_features = video_embeds.view(batch_size, num_frames, -1) + + mit_outputs = self.mit( + cls_features, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + video_embeds = mit_outputs[1] + + img_features = vision_outputs[0][:, 1:, :] + img_features = self.prompts_visual_layernorm(img_features) + img_features = img_features @ self.prompts_visual_projection + img_features = img_features.view(batch_size, num_frames, -1, video_embeds.shape[-1]) + img_features = img_features.mean(dim=1, keepdim=False) + + text_outputs = self.text_model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + text_embeds = text_outputs[1] + text_embeds = self.text_projection(text_embeds) + + text_embeds = text_embeds.unsqueeze(0).expand(batch_size, -1, -1) + text_embeds = text_embeds + self.prompts_generator(text_embeds, img_features) + + # normalized features + video_embeds = video_embeds / video_embeds.norm(p=2, dim=-1, keepdim=True) + text_embeds = text_embeds / text_embeds.norm(p=2, dim=-1, keepdim=True) + + # cosine similarity as logits + logit_scale = self.logit_scale.exp() + logits_per_video = torch.einsum("bd,bkd->bk", video_embeds, logit_scale * text_embeds) + logits_per_text = logits_per_video.T + + loss = None + if return_loss: + loss = x_clip_loss(logits_per_text) + + if not return_dict: + output = (logits_per_video, logits_per_text, text_embeds, video_embeds, text_outputs, vision_outputs) + return ((loss,) + output) if loss is not None else output + + return XCLIPOutput( + loss=loss, + logits_per_video=logits_per_video, + logits_per_text=logits_per_text, + text_embeds=text_embeds, + video_embeds=video_embeds, + text_model_output=text_outputs, + vision_model_output=vision_outputs, + mit_output=mit_outputs, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/processing_x_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/processing_x_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..0854c1d868902d78f134ab128449a1fee1995538 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/x_clip/processing_x_clip.py @@ -0,0 +1,146 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Image/Text processor class for XCLIP +""" + +import warnings + +from ...processing_utils import ProcessorMixin +from ...tokenization_utils_base import BatchEncoding + + +class XCLIPProcessor(ProcessorMixin): + r""" + Constructs an X-CLIP processor which wraps a VideoMAE image processor and a CLIP tokenizer into a single processor. + + [`XCLIPProcessor`] offers all the functionalities of [`VideoMAEImageProcessor`] and [`CLIPTokenizerFast`]. See the + [`~XCLIPProcessor.__call__`] and [`~XCLIPProcessor.decode`] for more information. + + Args: + image_processor ([`VideoMAEImageProcessor`]): + The image processor is a required input. + tokenizer ([`CLIPTokenizerFast`]): + The tokenizer is a required input. + """ + attributes = ["image_processor", "tokenizer"] + image_processor_class = "VideoMAEImageProcessor" + tokenizer_class = ("CLIPTokenizer", "CLIPTokenizerFast") + + def __init__(self, image_processor=None, tokenizer=None, **kwargs): + if "feature_extractor" in kwargs: + warnings.warn( + "The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`" + " instead.", + FutureWarning, + ) + feature_extractor = kwargs.pop("feature_extractor") + + image_processor = image_processor if image_processor is not None else feature_extractor + if image_processor is None: + raise ValueError("You need to specify an `image_processor`.") + if tokenizer is None: + raise ValueError("You need to specify a `tokenizer`.") + + super().__init__(image_processor, tokenizer) + self.current_processor = self.image_processor + + def __call__(self, text=None, videos=None, return_tensors=None, **kwargs): + """ + Main method to prepare for the model one or several sequences(s) and image(s). This method forwards the `text` + and `kwargs` arguments to CLIPTokenizerFast's [`~CLIPTokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the image(s), this method forwards the `videos` and `kwargs` arguments to + VideoMAEImageProcessor's [`~VideoMAEImageProcessor.__call__`] if `videos` is not `None`. Please refer to the + doctsring of the above two methods for more information. + + Args: + text (`str`, `List[str]`, `List[List[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + videos (`List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`, `List[List[PIL.Image.Image]]`, `List[List[np.ndarrray]]`,: + `List[List[torch.Tensor]]`): The video or batch of videos to be prepared. Each video should be a list + of frames, which can be either PIL images or NumPy arrays. In case of NumPy arrays/PyTorch tensors, + each frame should be of shape (H, W, C), where H and W are frame height and width, and C is a number of + channels. + + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `videos` is not `None`. + """ + + if text is None and videos is None: + raise ValueError("You have to specify either text or videos. Both cannot be none.") + + if text is not None: + encoding = self.tokenizer(text, return_tensors=return_tensors, **kwargs) + + if videos is not None: + image_features = self.image_processor(videos, return_tensors=return_tensors, **kwargs) + + if text is not None and videos is not None: + encoding["pixel_values"] = image_features.pixel_values + return encoding + elif text is not None: + return encoding + else: + return BatchEncoding(data=dict(**image_features), tensor_type=return_tensors) + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to CLIPTokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to CLIPTokenizerFast's [`~PreTrainedTokenizer.decode`]. Please refer to + the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + @property + def model_input_names(self): + return ["input_ids", "attention_mask", "position_ids", "pixel_values"] + + @property + def feature_extractor_class(self): + warnings.warn( + "`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead.", + FutureWarning, + ) + return self.image_processor_class + + @property + def feature_extractor(self): + warnings.warn( + "`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead.", + FutureWarning, + ) + return self.image_processor diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..747a4ddb4ed9c77048748341446b2eec8227570a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/__init__.py @@ -0,0 +1,138 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_sentencepiece_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = {"configuration_xglm": ["XGLM_PRETRAINED_CONFIG_ARCHIVE_MAP", "XGLMConfig"]} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xglm"] = ["XGLMTokenizer"] + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xglm_fast"] = ["XGLMTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xglm"] = [ + "XGLM_PRETRAINED_MODEL_ARCHIVE_LIST", + "XGLMForCausalLM", + "XGLMModel", + "XGLMPreTrainedModel", + ] + + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_xglm"] = [ + "FlaxXGLMForCausalLM", + "FlaxXGLMModel", + "FlaxXGLMPreTrainedModel", + ] + + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_xglm"] = [ + "TF_XGLM_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFXGLMForCausalLM", + "TFXGLMModel", + "TFXGLMPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_xglm import XGLM_PRETRAINED_CONFIG_ARCHIVE_MAP, XGLMConfig + + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xglm import XGLMTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xglm_fast import XGLMTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xglm import XGLM_PRETRAINED_MODEL_ARCHIVE_LIST, XGLMForCausalLM, XGLMModel, XGLMPreTrainedModel + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_xglm import FlaxXGLMForCausalLM, FlaxXGLMModel, FlaxXGLMPreTrainedModel + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_xglm import ( + TF_XGLM_PRETRAINED_MODEL_ARCHIVE_LIST, + TFXGLMForCausalLM, + TFXGLMModel, + TFXGLMPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/configuration_xglm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/configuration_xglm.py new file mode 100644 index 0000000000000000000000000000000000000000..8a59ee6682d6eaabea31da4d2d4d286a20c33b35 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/configuration_xglm.py @@ -0,0 +1,140 @@ +# coding=utf-8 +# Copyright The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XGLM model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XGLM_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/xglm-564M": "https://huggingface.co/facebook/xglm-564M/resolve/main/config.json", + # See all XGLM models at https://huggingface.co/models?filter=xglm +} + + +class XGLMConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XGLMModel`]. It is used to instantiate an XGLM + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the XGLM + [facebook/xglm-564M](https://huggingface.co/facebook/xglm-564M) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 256008): + Vocabulary size of the XGLM model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`XGLMModel`] or [`FlaxXGLMModel`]. + max_position_embeddings (`int`, *optional*, defaults to 2048): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + d_model (`int`, *optional*, defaults to 1024): + Dimension of the layers and the pooler layer. + ffn_dim (`int`, *optional*, defaults to 4096): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + num_layers (`int`, *optional*, defaults to 24): + Number of hidden layers Transformer decoder. + attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer decoder. + activation_function (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, dencoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + layerdrop (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see https://arxiv.org/abs/1909.11556) + for more details. + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + scale_embedding (`bool`, *optional*, defaults to `True`): + Scale embeddings by diving by sqrt(d_model). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + + Example: + + ```python + >>> from transformers import XGLMModel, XGLMConfig + + >>> # Initializing a XGLM facebook/xglm-564M style configuration + >>> configuration = XGLMConfig() + + >>> # Initializing a model from the facebook/xglm-564M style configuration + >>> model = XGLMModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "xglm" + keys_to_ignore_at_inference = ["past_key_values"] + + attribute_map = { + "num_attention_heads": "attention_heads", + "hidden_size": "d_model", + "num_hidden_layers": "num_layers", + } + + def __init__( + self, + vocab_size=256008, + max_position_embeddings=2048, + d_model=1024, + ffn_dim=4096, + num_layers=24, + attention_heads=16, + activation_function="gelu", + dropout=0.1, + attention_dropout=0.1, + activation_dropout=0.0, + layerdrop=0.0, + init_std=0.02, + scale_embedding=True, + use_cache=True, + decoder_start_token_id=2, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + **kwargs, + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.d_model = d_model + self.ffn_dim = ffn_dim + self.num_layers = num_layers + self.attention_heads = attention_heads + self.activation_function = activation_function + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.layerdrop = layerdrop + self.init_std = init_std + self.scale_embedding = scale_embedding # scale factor will be sqrt(d_model) if True + self.use_cache = use_cache + + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + decoder_start_token_id=decoder_start_token_id, + **kwargs, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/convert_xglm_original_ckpt_to_trfms.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/convert_xglm_original_ckpt_to_trfms.py new file mode 100644 index 0000000000000000000000000000000000000000..f8b5dba3c1e47bb9cee6c23c4281746c4dde4761 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/convert_xglm_original_ckpt_to_trfms.py @@ -0,0 +1,68 @@ +import argparse +from argparse import Namespace + +import torch +from torch import nn + +from transformers import XGLMConfig, XGLMForCausalLM + + +def remove_ignore_keys_(state_dict): + ignore_keys = [ + "decoder.version", + "decoder.output_projection.weight", + "_float_tensor", + "decoder.embed_positions._float_tensor", + ] + for k in ignore_keys: + state_dict.pop(k, None) + + +def make_linear_from_emb(emb): + vocab_size, emb_size = emb.weight.shape + lin_layer = nn.Linear(vocab_size, emb_size, bias=False) + lin_layer.weight.data = emb.weight.data + return lin_layer + + +def convert_fairseq_xglm_checkpoint_from_disk(checkpoint_path): + checkpoint = torch.load(checkpoint_path, map_location="cpu") + args = Namespace(**checkpoint["cfg"]["model"]) + state_dict = checkpoint["model"] + remove_ignore_keys_(state_dict) + vocab_size = state_dict["decoder.embed_tokens.weight"].shape[0] + + state_dict = {key.replace("decoder", "model"): val for key, val in state_dict.items()} + + config = XGLMConfig( + vocab_size=vocab_size, + max_position_embeddings=args.max_target_positions, + num_layers=args.decoder_layers, + attention_heads=args.decoder_attention_heads, + ffn_dim=args.decoder_ffn_embed_dim, + d_model=args.decoder_embed_dim, + layerdrop=args.decoder_layerdrop, + dropout=args.dropout, + attention_dropout=args.attention_dropout, + activation_dropout=args.activation_dropout, + activation_function="gelu", + scale_embedding=not args.no_scale_embedding, + tie_word_embeddings=args.share_decoder_input_output_embed, + ) + + model = XGLMForCausalLM(config) + missing = model.load_state_dict(state_dict, strict=False) + print(missing) + model.lm_head = make_linear_from_emb(model.model.embed_tokens) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument("fairseq_path", type=str, help="path to a model.pt on local filesystem.") + parser.add_argument("pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.") + args = parser.parse_args() + model = convert_fairseq_xglm_checkpoint_from_disk(args.fairseq_path) + model.save_pretrained(args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_flax_xglm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_flax_xglm.py new file mode 100644 index 0000000000000000000000000000000000000000..b2acd66f44765b5eb9d03ab835c59d8532425ae9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_flax_xglm.py @@ -0,0 +1,801 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Flax XGLM model.""" + + +import math +import random +from functools import partial +from typing import Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen import combine_masks, make_causal_mask +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax +from jax.random import PRNGKey + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutputWithPastAndCrossAttentions, + FlaxCausalLMOutputWithCrossAttentions, +) +from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_xglm import XGLMConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/xglm-564M" +_CONFIG_FOR_DOC = "XGLMConfig" + +XGLM_START_DOCSTRING = r""" + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a Flax Linen + [flax.nn.Module](https://flax.readthedocs.io/en/latest/_autosummary/flax.nn.module.html) subclass. Use it as a + regular Flax Module and refer to the Flax documentation for all matter related to general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`XGLMConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. + dtype (`jax.numpy.dtype`, *optional*, defaults to `jax.numpy.float32`): + The data type of the computation. Can be one of `jax.numpy.float32`, `jax.numpy.float16` (on GPUs) and + `jax.numpy.bfloat16` (on TPUs). + + This can be used to enable mixed-precision training or half-precision inference on GPUs or TPUs. If + specified all the computation will be performed with the given `dtype`. + + **Note that this only specifies the dtype of the computation and does not influence the dtype of model + parameters.** + + If you wish to change the dtype of the model parameters, see [`~FlaxPreTrainedModel.to_fp16`] and + [`~FlaxPreTrainedModel.to_bf16`]. +""" + +XGLM_INPUTS_DOCSTRING = r""" + Args: + input_ids (`jnp.ndarray` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`jnp.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`numpy.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +def create_sinusoidal_positions(n_pos, dim, padding_idx=1): + half_dim = dim // 2 + emb = math.log(10000) / (half_dim - 1) + emb = np.exp(np.arange(half_dim) * -emb) + emb = np.expand_dims(np.arange(n_pos), 1) * np.expand_dims(emb, 0) + emb = np.concatenate([np.sin(emb), np.cos(emb)], 1) + emb = np.reshape(emb, (n_pos, dim)) + + if padding_idx is not None: + emb[padding_idx, :] = 0 + + return jnp.array(emb) + + +class FlaxXGLMAttention(nn.Module): + config: XGLMConfig + embed_dim: int + num_heads: int + dropout: float = 0.0 + causal: bool = False + bias: bool = True + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self) -> None: + self.head_dim = self.embed_dim // self.num_heads + + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} " + f"and `num_heads`: {self.num_heads})." + ) + + dense = partial( + nn.Dense, + self.embed_dim, + use_bias=self.bias, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + self.q_proj, self.k_proj, self.v_proj = dense(), dense(), dense() + self.out_proj = dense() + + self.dropout_layer = nn.Dropout(rate=self.dropout) + + if self.causal: + self.causal_mask = make_causal_mask( + jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" + ) + + def _split_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.num_heads, self.head_dim)) + + def _merge_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.embed_dim,)) + + @nn.compact + def _concatenate_to_cache(self, key, value, query, attention_mask): + """ + This function takes projected key, value states from a single input token and concatenates the states to cached + states from previous steps. This function is slighly adapted from the official Flax repository: + https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 + """ + # detect if we're initializing by absence of existing cache data. + is_initialized = self.has_variable("cache", "cached_key") + cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) + cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) + cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) + + if is_initialized: + *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape + # update key, value caches with our new 1d spatial slices + cur_index = cache_index.value + indices = (0,) * len(batch_dims) + (cur_index, 0, 0) + key = lax.dynamic_update_slice(cached_key.value, key, indices) + value = lax.dynamic_update_slice(cached_value.value, value, indices) + cached_key.value = key + cached_value.value = value + num_updated_cache_vectors = query.shape[1] + cache_index.value = cache_index.value + num_updated_cache_vectors + # causal mask for cached decoder self-attention: our single query position should only attend + # to those key positions that have already been generated and cached, not the remaining zero elements. + pad_mask = jnp.broadcast_to( + jnp.arange(max_length) < cur_index + num_updated_cache_vectors, + tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), + ) + attention_mask = combine_masks(pad_mask, attention_mask) + return key, value, attention_mask + + def __call__( + self, + hidden_states: jnp.ndarray, + key_value_states: Optional[jnp.ndarray] = None, + attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + batch_size = hidden_states.shape[0] + + # get query proj + query_states = self.q_proj(hidden_states) + # get key, value proj + if is_cross_attention: + # cross_attentions + key_states = self.k_proj(key_value_states) + value_states = self.v_proj(key_value_states) + else: + # self_attention + key_states = self.k_proj(hidden_states) + value_states = self.v_proj(hidden_states) + + query_states = self._split_heads(query_states) + key_states = self._split_heads(key_states) + value_states = self._split_heads(value_states) + + # handle cache prepare causal attention mask + if self.causal: + query_length, key_length = query_states.shape[1], key_states.shape[1] + if self.has_variable("cache", "cached_key"): + mask_shift = self.variables["cache"]["cache_index"] + max_decoder_length = self.variables["cache"]["cached_key"].shape[1] + causal_mask = lax.dynamic_slice( + self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) + ) + else: + causal_mask = self.causal_mask[:, :, :query_length, :key_length] + causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) + + # combine masks if needed + if attention_mask is not None and self.causal: + attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) + attention_mask = combine_masks(attention_mask, causal_mask) + elif self.causal: + attention_mask = causal_mask + elif attention_mask is not None: + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + + # During fast autoregressive decoding, we feed one position at a time, + # and cache the keys and values step by step. + if self.causal and (self.has_variable("cache", "cached_key") or init_cache): + key_states, value_states, attention_mask = self._concatenate_to_cache( + key_states, value_states, query_states, attention_mask + ) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.dropout > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.dropout, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = self._merge_heads(attn_output) + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights + + +class FlaxXGLMDecoderLayer(nn.Module): + config: XGLMConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self) -> None: + self.embed_dim = self.config.d_model + self.self_attn = FlaxXGLMAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.attention_heads, + dropout=self.config.attention_dropout, + causal=True, + dtype=self.dtype, + ) + self.self_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + self.activation_fn = ACT2FN[self.config.activation_function] + self.activation_dropout_layer = nn.Dropout(rate=self.config.activation_dropout) + + if self.config.add_cross_attention: + self.encoder_attn = FlaxXGLMAttention( + config=self.config, + embed_dim=self.embed_dim, + num_heads=self.config.decoder_attention_heads, + dropout=self.config.attention_dropout, + dtype=self.dtype, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + self.fc1 = nn.Dense( + self.config.ffn_dim, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + self.fc2 = nn.Dense( + self.embed_dim, dtype=self.dtype, kernel_init=jax.nn.initializers.normal(self.config.init_std) + ) + self.final_layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + # Copied from transformers.models.mbart.modeling_flax_mbart.FlaxMBartDecoderLayer.__call__ + def __call__( + self, + hidden_states: jnp.ndarray, + attention_mask: jnp.ndarray, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = True, + deterministic: bool = True, + ) -> Tuple[jnp.ndarray]: + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + hidden_states, self_attn_weights = self.self_attn( + hidden_states=hidden_states, attention_mask=attention_mask, init_cache=init_cache + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + + hidden_states = self.encoder_attn_layer_norm(hidden_states) + hidden_states, cross_attn_weights = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + ) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + return outputs + + +class FlaxXGLMDecoderLayerCollection(nn.Module): + config: XGLMConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.layers = [ + FlaxXGLMDecoderLayer(self.config, name=str(i), dtype=self.dtype) for i in range(self.config.num_layers) + ] + self.layerdrop = self.config.layerdrop + + def __call__( + self, + hidden_states, + attention_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + deterministic: bool = True, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + + for decoder_layer in self.layers: + if output_hidden_states: + all_hidden_states += (hidden_states,) + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + dropout_probability = random.uniform(0, 1) + if not deterministic and (dropout_probability < self.layerdrop): + layer_outputs = (None, None, None) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + init_cache=init_cache, + output_attentions=output_attentions, + deterministic=deterministic, + ) + + hidden_states = layer_outputs[0] + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states, all_hidden_states, all_self_attns, all_cross_attentions) + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +class FlaxXGLMModule(nn.Module): + config: XGLMConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dropout_layer = nn.Dropout(rate=self.config.dropout) + + embed_dim = self.config.d_model + self.padding_idx = self.config.pad_token_id + self.max_target_positions = self.config.max_position_embeddings + self.embed_scale = math.sqrt(self.config.d_model) if self.config.scale_embedding else 1.0 + + self.embed_tokens = nn.Embed( + self.config.vocab_size, + embed_dim, + embedding_init=jax.nn.initializers.normal(self.config.init_std), + ) + + # XGLM is set up so that if padding_idx is specified then offset the embedding ids by 2 + # and adjust num_embeddings appropriately. Other models don't have this hack + self.offset = 2 + self.embed_positions = create_sinusoidal_positions( + self.config.max_position_embeddings + self.offset, embed_dim + ) + self.layers = FlaxXGLMDecoderLayerCollection(self.config, self.dtype) + self.layer_norm = nn.LayerNorm(dtype=self.dtype, epsilon=1e-05) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + input_shape = input_ids.shape + input_ids = input_ids.reshape(-1, input_shape[-1]) + + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + # embed positions + position_ids = position_ids + self.offset + positions = jnp.take(self.embed_positions, position_ids, axis=0) + + hidden_states = inputs_embeds + positions + hidden_states = self.dropout_layer(hidden_states, deterministic=deterministic) + + outputs = self.layers( + hidden_states, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + deterministic=deterministic, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + last_hidden_states = outputs[0] + last_hidden_states = self.layer_norm(last_hidden_states) + + hidden_states = None + if output_hidden_states: + hidden_states = outputs[1] + hidden_states = hidden_states[:-1] + (last_hidden_states,) + + if not return_dict: + outputs = (last_hidden_states, hidden_states) + (outputs[2:] if output_hidden_states else outputs[1:]) + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=last_hidden_states, + hidden_states=hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +class FlaxXGLMPreTrainedModel(FlaxPreTrainedModel): + config_class = XGLMConfig + base_model_prefix: str = "model" + module_class: nn.Module = None + + def __init__( + self, + config: XGLMConfig, + input_shape: Tuple[int] = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + attention_mask = jnp.ones_like(input_ids) + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_shape) + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + if self.config.add_cross_attention: + encoder_hidden_states = jnp.zeros(input_shape + (self.config.n_embd,)) + encoder_attention_mask = attention_mask + module_init_outputs = self.module.init( + rngs, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states, + encoder_attention_mask, + return_dict=False, + ) + else: + module_init_outputs = self.module.init(rngs, input_ids, attention_mask, position_ids, return_dict=False) + + random_params = module_init_outputs["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + def init_cache(self, batch_size, max_length): + r""" + Args: + batch_size (`int`): + batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. + max_length (`int`): + maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized + cache. + """ + # init input variables to retrieve cache + input_ids = jnp.ones((batch_size, max_length), dtype="i4") + attention_mask = jnp.ones_like(input_ids, dtype="i4") + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + init_variables = self.module.init( + jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True + ) + return unfreeze(init_variables["cache"]) + + @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) + def __call__( + self, + input_ids: jnp.ndarray, + attention_mask: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + train: bool = False, + params: dict = None, + past_key_values: dict = None, + dropout_rng: PRNGKey = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + if encoder_hidden_states is not None and encoder_attention_mask is None: + batch_size, sequence_length = encoder_hidden_states.shape[:2] + encoder_attention_mask = jnp.ones((batch_size, sequence_length)) + + # prepare encoder inputs + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + if position_ids is None: + batch_size, sequence_length = input_ids.shape + position_ids = jnp.broadcast_to(jnp.arange(sequence_length)[None, :], (batch_size, sequence_length)) + + # Handle any PRNG if needed + rngs = {"dropout": dropout_rng} if dropout_rng is not None else {} + + inputs = {"params": params or self.params} + + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed + # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be + # changed by FlaxXGLMAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + outputs = self.module.apply( + inputs, + input_ids=jnp.array(input_ids, dtype="i4"), + attention_mask=jnp.array(attention_mask, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + deterministic=not train, + rngs=rngs, + mutable=mutable, + ) + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs, past_key_values = outputs + outputs["past_key_values"] = unfreeze(past_key_values["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs, past_key_values = outputs + outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] + + return outputs + + +@add_start_docstrings( + "The bare XGLM Model transformer outputting raw hidden-states without any specific head on top.", + XGLM_START_DOCSTRING, +) +class FlaxXGLMModel(FlaxXGLMPreTrainedModel): + module_class = FlaxXGLMModule + + +append_call_sample_docstring( + FlaxXGLMModel, + _CHECKPOINT_FOR_DOC, + FlaxBaseModelOutputWithPastAndCrossAttentions, + _CONFIG_FOR_DOC, +) + + +class FlaxXGLMForCausalLMModule(nn.Module): + config: XGLMConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.model = FlaxXGLMModule(self.config, self.dtype) + self.lm_head = nn.Dense( + self.config.vocab_size, + use_bias=False, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.init_std), + ) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + deterministic: bool = True, + ): + outputs = self.model( + input_ids, + attention_mask, + position_ids, + encoder_hidden_states, + encoder_attention_mask, + deterministic=deterministic, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + + if self.config.tie_word_embeddings: + shared_embedding = self.model.variables["params"]["embed_tokens"]["embedding"] + lm_logits = self.lm_head.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + lm_logits = self.lm_head(hidden_states) + + if not return_dict: + return (lm_logits,) + outputs[1:] + + return FlaxCausalLMOutputWithCrossAttentions( + logits=lm_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@add_start_docstrings( + """ + The XGLM Model transformer with a language modeling head on top (linear layer with weights tied to the input + embeddings). + """, + XGLM_START_DOCSTRING, +) +class FlaxXGLMForCausalLM(FlaxXGLMPreTrainedModel): + module_class = FlaxXGLMForCausalLMModule + + def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jnp.DeviceArray] = None): + # initializing the cache + batch_size, seq_length = input_ids.shape + + past_key_values = self.init_cache(batch_size, max_length) + # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. + # But since GPT2 uses a causal mask, those positions are masked anyways. + # Thus we can create a single static attention_mask here, which is more efficient for compilation + extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") + if attention_mask is not None: + position_ids = attention_mask.cumsum(axis=-1) - 1 + extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) + else: + position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) + + return { + "past_key_values": past_key_values, + "attention_mask": extended_attention_mask, + "position_ids": position_ids, + } + + def update_inputs_for_generation(self, model_outputs, model_kwargs): + model_kwargs["past_key_values"] = model_outputs.past_key_values + model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 + return model_kwargs + + +append_call_sample_docstring( + FlaxXGLMForCausalLM, + _CHECKPOINT_FOR_DOC, + FlaxCausalLMOutputWithCrossAttentions, + _CONFIG_FOR_DOC, +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_tf_xglm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_tf_xglm.py new file mode 100644 index 0000000000000000000000000000000000000000..d112e641a93e05bf78038c480e83a31dc06e73da --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_tf_xglm.py @@ -0,0 +1,999 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 XGLM model.""" + + +import math +import random +from typing import Any, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation + +# Public API +from ...file_utils import ( + DUMMY_INPUTS, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + replace_return_docstrings, +) +from ...modeling_tf_outputs import TFBaseModelOutputWithPastAndCrossAttentions, TFCausalLMOutputWithCrossAttentions +from ...modeling_tf_utils import ( + TFCausalLanguageModelingLoss, + TFModelInputType, + TFPreTrainedModel, + TFSharedEmbeddings, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import logging +from .configuration_xglm import XGLMConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/xglm-564M" +_CONFIG_FOR_DOC = "XGLMConfig" + + +TF_XGLM_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/xglm-564M", + # See all XGLM models at https://huggingface.co/models?filter=xglm +] + + +LARGE_NEGATIVE = -1e8 + + +def create_sinusiodal_positions(num_positions: int, embedding_dim: int, padding_idx: Optional[int]) -> tf.Tensor: + half_dim = embedding_dim // 2 + emb = math.log(10000) / (half_dim - 1) + emb = tf.exp(tf.range(half_dim, dtype=tf.float32) * -emb) + emb = tf.expand_dims(tf.range(num_positions, dtype=tf.float32), axis=1) * tf.expand_dims(emb, axis=0) + emb = tf.reshape(tf.concat([tf.sin(emb), tf.cos(emb)], axis=1), (num_positions, -1)) + if embedding_dim % 2 == 1: + # zero pad + emb = tf.concat([emb, tf.zeros((num_positions, 1))], axis=1) + if padding_idx is not None: + _padding_mask = tf.concat( + [ + tf.ones((padding_idx, shape_list(emb)[1])), + tf.zeros((1, shape_list(emb)[1])), + tf.ones((shape_list(emb)[0] - padding_idx - 1, shape_list(emb)[1])), + ], + axis=0, + ) + emb *= _padding_mask + + return tf.Variable(emb, trainable=False, name="model.embed_positions.weights") + + +def _create_position_ids_from_input_ids( + input_ids: tf.Tensor, past_key_values_length: int, padding_idx: Optional[int] +) -> tf.Tensor: + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = tf.where(input_ids != padding_idx, 1, 0) + incremental_indices = (tf.cast(tf.cumsum(mask, axis=1), dtype=mask.dtype) + past_key_values_length) * mask + return tf.cast(incremental_indices, dtype=tf.int64) + padding_idx + + +def _create_position_ids_from_inputs_embeds( + inputs_embeds: tf.Tensor, past_key_values_length: int, padding_idx: Optional[int] +) -> tf.Tensor: + """ + Args: + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + inputs_embeds: tf.Tensor + Returns: tf.Tensor + """ + input_shape = shape_list(inputs_embeds)[:-1] + sequence_length = input_shape[1] + + position_ids = tf.range(padding_idx + 1, sequence_length + padding_idx + 1, dtype=tf.int64) + + return tf.broadcast_to(tf.expand_dims(position_ids, axis=0), input_shape) + past_key_values_length + + +# Copied from transformers.models.bart.modeling_tf_bart._make_causal_mask +def _make_causal_mask(input_ids_shape: tf.TensorShape, past_key_values_length: int = 0): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz = input_ids_shape[0] + tgt_len = input_ids_shape[1] + mask = tf.ones((tgt_len, tgt_len)) * LARGE_NEGATIVE + mask_cond = tf.range(shape_list(mask)[-1]) + + mask = tf.where(mask_cond < tf.reshape(mask_cond + 1, (shape_list(mask)[-1], 1)), 0.0, mask) + + if past_key_values_length > 0: + mask = tf.concat([tf.zeros((tgt_len, past_key_values_length)), mask], axis=-1) + + return tf.tile(mask[None, None, :, :], (bsz, 1, 1, 1)) + + +# Copied from transformers.models.bart.modeling_tf_bart._expand_mask +def _expand_mask(mask: tf.Tensor, tgt_len: Optional[int] = None, past_key_values_length: int = 0): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + src_len = shape_list(mask)[1] + tgt_len = tgt_len if tgt_len is not None else src_len + one_cst = tf.constant(1.0) + mask = tf.cast(mask, dtype=one_cst.dtype) + expanded_mask = tf.tile(mask[:, None, None, :], (1, 1, tgt_len, 1)) + + return (one_cst - expanded_mask) * LARGE_NEGATIVE + + +# Copied from transformers.models.bart.modeling_tf_bart.TFBartAttention with Bart->XGLM +class TFXGLMAttention(tf.keras.layers.Layer): + """Multi-headed attention from "Attention Is All You Need""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + **kwargs, + ): + super().__init__(**kwargs) + self.embed_dim = embed_dim + + self.num_heads = num_heads + self.dropout = tf.keras.layers.Dropout(dropout) + self.head_dim = embed_dim // num_heads + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="k_proj") + self.q_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="q_proj") + self.v_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="v_proj") + self.out_proj = tf.keras.layers.Dense(embed_dim, use_bias=bias, name="out_proj") + + def _shape(self, tensor: tf.Tensor, seq_len: int, bsz: int): + return tf.transpose(tf.reshape(tensor, (bsz, seq_len, self.num_heads, self.head_dim)), (0, 2, 1, 3)) + + def call( + self, + hidden_states: tf.Tensor, + key_value_states: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[Tuple[tf.Tensor]]] = None, + attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, Optional[tf.Tensor]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + bsz, tgt_len, embed_dim = shape_list(hidden_states) + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = tf.concat([past_key_value[0], key_states], axis=2) + value_states = tf.concat([past_key_value[1], value_states], axis=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = tf.reshape(self._shape(query_states, tgt_len, bsz), proj_shape) + key_states = tf.reshape(key_states, proj_shape) + value_states = tf.reshape(value_states, proj_shape) + + src_len = shape_list(key_states)[1] + attn_weights = tf.matmul(query_states, key_states, transpose_b=True) + + tf.debugging.assert_equal( + shape_list(attn_weights), + [bsz * self.num_heads, tgt_len, src_len], + message=( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {shape_list(attn_weights)}" + ), + ) + + if attention_mask is not None: + tf.debugging.assert_equal( + shape_list(attention_mask), + [bsz, 1, tgt_len, src_len], + message=( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is" + f" {shape_list(attention_mask)}" + ), + ) + + attention_mask = tf.cast(attention_mask, dtype=attn_weights.dtype) + attn_weights = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + attention_mask + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_weights = stable_softmax(attn_weights, axis=-1) + + if layer_head_mask is not None: + tf.debugging.assert_equal( + shape_list(layer_head_mask), + [self.num_heads], + message=( + f"Head mask for a single layer should be of size {(self.num_heads)}, but is" + f" {shape_list(layer_head_mask)}" + ), + ) + + attn_weights = tf.reshape(layer_head_mask, (1, -1, 1, 1)) * tf.reshape( + attn_weights, (bsz, self.num_heads, tgt_len, src_len) + ) + attn_weights = tf.reshape(attn_weights, (bsz * self.num_heads, tgt_len, src_len)) + + attn_probs = self.dropout(attn_weights, training=training) + attn_output = tf.matmul(attn_probs, value_states) + + tf.debugging.assert_equal( + shape_list(attn_output), + [bsz * self.num_heads, tgt_len, self.head_dim], + message=( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {shape_list(attn_output)}" + ), + ) + + attn_output = tf.transpose( + tf.reshape(attn_output, (bsz, self.num_heads, tgt_len, self.head_dim)), (0, 2, 1, 3) + ) + attn_output = tf.reshape(attn_output, (bsz, tgt_len, embed_dim)) + + attn_output = self.out_proj(attn_output) + attn_weights: tf.Tensor = tf.reshape(attn_weights, (bsz, self.num_heads, tgt_len, src_len)) + + return attn_output, attn_weights, past_key_value + + +class TFXGLMDecoderLayer(tf.keras.layers.Layer): + def __init__(self, config: XGLMConfig, **kwargs: Any) -> None: + super().__init__(**kwargs) + self.embed_dim = config.d_model + self.self_attn = TFXGLMAttention( + embed_dim=self.embed_dim, + num_heads=config.attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + name="self_attn", + ) + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.activation_fn = get_tf_activation(config.activation_function) + self.activation_dropout = tf.keras.layers.Dropout(config.activation_dropout) + + if config.add_cross_attention: + self.encoder_attn = TFXGLMAttention( + embed_dim=self.embed_dim, + num_heads=config.attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + name="encoder_attn", + ) + self.encoder_attn_layer_norm = tf.keras.layers.LayerNormalization( + epsilon=1e-5, name="encoder_attn_layer_norm" + ) + + self.self_attn_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="self_attn_layer_norm") + self.fc1 = tf.keras.layers.Dense(config.ffn_dim, name="fc1") + self.fc2 = tf.keras.layers.Dense(self.embed_dim, name="fc2") + self.final_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="final_layer_norm") + + # Copied from transformers.models.mbart.modeling_tf_mbart.TFMBartDecoderLayer.call + def call( + self, + hidden_states: tf.Tensor, + attention_mask: Optional[tf.Tensor] = None, + encoder_hidden_states: Optional[tf.Tensor] = None, + encoder_attention_mask: Optional[tf.Tensor] = None, + layer_head_mask: Optional[tf.Tensor] = None, + cross_attn_layer_head_mask: Optional[tf.Tensor] = None, + past_key_value: Optional[Tuple[tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Tuple[tf.Tensor, tf.Tensor, Tuple[Tuple[tf.Tensor]]]: + """ + Args: + hidden_states (`tf.Tensor`): input to the layer of shape *(seq_len, batch, embed_dim)* + attention_mask (`tf.Tensor`): attention mask of size + *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. + encoder_hidden_states (`tf.Tensor`): + cross attention input to the layer of shape *(seq_len, batch, embed_dim)* + encoder_attention_mask (`tf.Tensor`): encoder attention mask of size + *(batch, 1, tgt_len, src_len)* where padding elements are indicated by very large negative values. + layer_head_mask (`tf.Tensor`): mask for attention heads in a given layer of size + *(decoder_attention_heads,)* + cross_attn_layer_head_mask (`tf.Tensor`): mask for heads of the cross-attention module. + *(decoder_attention_heads,)* + past_key_value (`Tuple(tf.Tensor)`): cached past key and value projection states + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + ) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = self.activation_dropout(hidden_states, training=training) + hidden_states = self.fc2(hidden_states) + hidden_states = self.dropout(hidden_states, training=training) + hidden_states = residual + hidden_states + + return ( + hidden_states, + self_attn_weights, + cross_attn_weights, + present_key_value, + ) + + +@keras_serializable +class TFXGLMMainLayer(tf.keras.layers.Layer): + config_class = XGLMConfig + + def __init__( + self, config: XGLMConfig, embed_tokens: Optional[TFSharedEmbeddings] = None, *inputs, **kwargs: Any + ) -> None: + super().__init__(*inputs, **kwargs) + + self.config = config + self.padding_idx = config.pad_token_id + self.max_target_positions = config.max_position_embeddings + self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 + + if embed_tokens is not None: + self.embed_tokens = embed_tokens + else: + self.embed_tokens = TFSharedEmbeddings( + config.vocab_size, config.d_model, self.padding_idx, name="embed_tokens" + ) + + self.offset = 2 + self._embed_positions_weights = create_sinusiodal_positions( + num_positions=config.max_position_embeddings + self.offset, + embedding_dim=config.d_model, + padding_idx=config.pad_token_id, + ) + + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.layers = [TFXGLMDecoderLayer(config, name=f"layers.{i}") for i in range(config.num_layers)] + self.layerdrop = config.layerdrop + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-5, name="layer_norm") + + def get_input_embeddings(self) -> TFSharedEmbeddings: + return self.embed_tokens + + def set_input_embeddings(self, value: TFSharedEmbeddings) -> None: + self.embed_tokens = value + + def _prepare_decoder_attention_mask( + self, + attention_mask: Optional[tf.Tensor], + input_shape: tf.TensorShape, + past_key_values_length: int, + ) -> tf.Tensor: + # create causal mask + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + combined_attention_mask: Optional[tf.Tensor] = None + if input_shape[-1] > 1: + combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length) + + if attention_mask is not None: + expand_attention_mask = _expand_mask(attention_mask, tgt_len=input_shape[-1]) + combined_attention_mask = ( + expand_attention_mask + if combined_attention_mask is None + else expand_attention_mask + combined_attention_mask + ) + + return combined_attention_mask + + def embed_positions(self, position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None) -> tf.Tensor: + position_ids += self.offset + positions = tf.gather(self._embed_positions_weights, position_ids, axis=0) + return positions + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + **kwargs: Any, + ) -> Union[TFBaseModelOutputWithPastAndCrossAttentions, Tuple[tf.Tensor]]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + input_ids = tf.reshape(input_ids, (-1, input_shape[-1])) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if position_ids is None: + position_ids = tf.expand_dims( + tf.range(past_key_values_length, input_shape[-1] + past_key_values_length), axis=0 + ) + position_ids = tf.reshape(position_ids, [-1, shape_list(position_ids)[-1]]) + + if inputs_embeds is None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.embed_tokens.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.embed_tokens.vocab_size})" + ), + ) + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + attention_mask = self._prepare_decoder_attention_mask(attention_mask, input_shape, past_key_values_length) + + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _expand_mask(encoder_attention_mask, tgt_len=input_shape[-1]) + + # embed positions + positions = self.embed_positions(position_ids) + + hidden_states = tf.cast(inputs_embeds, dtype=tf.float32) + positions + + hidden_states = self.dropout(hidden_states, training=training) + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + next_decoder_cache = () if use_cache else None + + # check if head_mask and cross_attn_head_mask have a correct number of layers specified if desired + for attn_mask_name, attn_mask in [("head_mask", head_mask), ("cross_attn_head_mask", cross_attn_head_mask)]: + if attn_mask is not None: + tf.debugging.assert_equal( + shape_list(attn_mask)[0], + len(self.layers), + message=( + f"The {attn_mask_name} should be specified for {len(self.layers)} layers, but it is for" + f" {shape_list(attn_mask)[0]}." + ), + ) + + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + + dropout_probability = random.uniform(0, 1) + if training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + hidden_states, layer_self_attn, layer_cross_attn, present_key_value = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=(cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None), + past_key_value=past_key_value, + ) + + if use_cache: + next_decoder_cache += (present_key_value,) + + if output_attentions: + all_self_attns += (layer_self_attn,) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_cross_attn,) + + hidden_states = self.layer_norm(hidden_states) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + next_cache = next_decoder_cache if use_cache else None + if not return_dict: + return tuple( + v + for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] + if v is not None + ) + return TFBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_cache, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +class TFXGLMPreTrainedModel(TFPreTrainedModel): + config_class = XGLMConfig + base_model_prefix = "model" + + @property + def dummy_inputs(self): + pad_token = 1 + input_ids = tf.cast(tf.convert_to_tensor(DUMMY_INPUTS), tf.int32) + dummy_inputs = { + "input_ids": input_ids, + "attention_mask": tf.cast(input_ids != pad_token, tf.int32), + } + return dummy_inputs + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + +XGLM_START_DOCSTRING = r""" + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Args: + config ([`XGLMConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XGLM_INPUTS_DOCSTRING = r""" + Args: + input_ids (`tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`tf.Tensor` or `Numpy array` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + encoder_hidden_states (`tf.Tensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention of + the decoder. + encoder_attention_mask (`tf.Tensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values + selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`tf.Tensor` of shape `(num_layers, attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`tf.Tensor` of shape `(num_layers, attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`Tuple[Tuple[tf.Tensor]]` of length `config.num_layers`) + contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + inputs_embeds (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + use_cache (`bool`, *optional*, defaults to `True`): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). Set to `False` during training, `True` during generation + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare XGLM Model transformer outputting raw hidden-states without any specific head on top.", + XGLM_START_DOCSTRING, +) +class TFXGLMModel(TFXGLMPreTrainedModel): + """ + Transformer decoder consisting of *config.num_layers* layers. Each layer is a [`TFXGLMDecoderLayer`] + + Args: + config: XGLMConfig + embed_tokens: [TFSharedEmbeddings]: output embedding + """ + + def __init__( + self, config: XGLMConfig, embed_tokens: Optional[TFSharedEmbeddings] = None, *inputs: Any, **kwargs: Any + ) -> None: + super().__init__(config, *inputs, **kwargs) + + self.model = TFXGLMMainLayer(config, embed_tokens=embed_tokens, name="model") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutputWithPastAndCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + **kwargs: Any, + ) -> Union[TFBaseModelOutputWithPastAndCrossAttentions, Tuple[tf.Tensor]]: + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + head_mask=head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output): + pkv = tf.convert_to_tensor(output.past_key_values) if self.config.use_cache else None + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + cross_attns = ( + tf.convert_to_tensor(output.cross_attentions) + if self.config.output_attentions and self.config.add_cross_attention + else None + ) + + return TFBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=output.hidden_states, + past_key_values=pkv, + hidden_states=hs, + attentions=attns, + cross_attentions=cross_attns, + ) + + +@add_start_docstrings( + """ + The XGLM Model transformer with a language modeling head on top (linear layer with weights tied to the input + embeddings). + """, + XGLM_START_DOCSTRING, +) +class TFXGLMForCausalLM(TFXGLMPreTrainedModel, TFCausalLanguageModelingLoss): + base_model_prefix = "model" + _keys_to_ignore_on_load_missing = [ + r"model.embed_positions.weights", + r"lm_head.weight", + ] + _keys_to_ignore_on_save = [ + r"model.embed_positions.weights", + ] + + def __init__( + self, config: XGLMConfig, embed_tokens: Optional[TFSharedEmbeddings] = None, *inputs: Any, **kwargs: Any + ) -> None: + super().__init__(config, *inputs, **kwargs) + + self.model = TFXGLMMainLayer(config, embed_tokens=embed_tokens, name="model") + self.lm_head = tf.keras.layers.Dense( + config.vocab_size, + use_bias=False, + kernel_initializer=get_initializer(config.init_std), + name="lm_head", + ) + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_cache=None, **kwargs): + # only last token for inputs_ids if past is defined in kwargs + if past_key_values: + inputs = tf.expand_dims(inputs[:, -1], -1) + + position_ids = kwargs.get("position_ids", None) + attention_mask = kwargs.get("attention_mask", None) + + if attention_mask is not None and position_ids is None: + position_ids = tf.math.cumsum(attention_mask, axis=-1, exclusive=True) + if past_key_values: + position_ids = tf.expand_dims(position_ids[:, -1], -1) + + return { + "input_ids": inputs, + "attention_mask": attention_mask, + "position_ids": position_ids, + "past_key_values": past_key_values, + "use_cache": use_cache, + } + + @unpack_inputs + @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=TFCausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFCausalLMOutputWithCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + cross_attn_head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + **kwargs: Any, + ) -> Union[TFCausalLMOutputWithCrossAttentions, Tuple[tf.Tensor]]: + r""" + labels (`np.ndarray` or `tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set + `labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100` + are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]` + """ + + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + head_mask=head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_states = outputs[0] + lm_logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + # shift labels to the left and cut last logit token + labels = tf.concat( + [labels[:, 1:], tf.fill((labels.shape[0], 1), tf.cast(self.config.pad_token_id, labels.dtype))], + axis=-1, + ) + loss = self.hf_compute_loss(labels, lm_logits) + + if not return_dict: + output = (lm_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFCausalLMOutputWithCrossAttentions( + loss=loss, + logits=lm_logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + def serving_output(self, output): + pkv = tf.convert_to_tensor(output.past_key_values) if self.config.use_cache else None + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + cross_attns = ( + tf.convert_to_tensor(output.cross_attentions) + if self.config.output_attentions and self.config.add_cross_attention + else None + ) + + return TFCausalLMOutputWithCrossAttentions( + loss=output.loss, + logits=output.logits, + past_key_values=pkv, + hidden_states=hs, + attentions=attns, + cross_attentions=cross_attns, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_xglm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_xglm.py new file mode 100644 index 0000000000000000000000000000000000000000..3cf16352a70cc1a98e6195742053700823b59b8b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/modeling_xglm.py @@ -0,0 +1,889 @@ +# coding=utf-8 +# Copyright 2021 The Fairseq Authors The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch XGLM model.""" + + +import math +import random +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import CrossEntropyLoss + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutputWithPastAndCrossAttentions, CausalLMOutputWithCrossAttentions +from ...modeling_utils import PreTrainedModel +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_xglm import XGLMConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "facebook/xglm-564M" +_CONFIG_FOR_DOC = "XGLMConfig" + + +XGLM_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/xglm-564M", + # See all XGLM models at https://huggingface.co/models?filter=xglm +] + +XGLM_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`XGLMConfig`]): + Model configuration class with all the parameters of the model. Initializing with a config file does not + load the weights associated with the model, only the configuration. Check out the + [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XGLM_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention of + the decoder. + encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*): + Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values + selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`torch.Tensor` of shape `(num_layers, attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(num_layers, attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape + `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. + + Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention + blocks) that can be used (see `past_key_values` input) to speed up sequential decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. inputs_embeds (`torch.FloatTensor` of shape + `(batch_size, sequence_length, hidden_size)`, *optional*): Optionally, instead of passing `input_ids` you + can choose to directly pass an embedded representation. This is useful if you want more control over how to + convert `input_ids` indices into associated vectors than the model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from transformers.models.bart.modeling_bart._make_causal_mask +def _make_causal_mask( + input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0 +): + """ + Make causal mask used for bi-directional self-attention. + """ + bsz, tgt_len = input_ids_shape + mask = torch.full((tgt_len, tgt_len), torch.tensor(torch.finfo(dtype).min, device=device), device=device) + mask_cond = torch.arange(mask.size(-1), device=device) + mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0) + mask = mask.to(dtype) + + if past_key_values_length > 0: + mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1) + return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length) + + +# Copied from transformers.models.bart.modeling_bart._expand_mask +def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None): + """ + Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`. + """ + bsz, src_len = mask.size() + tgt_len = tgt_len if tgt_len is not None else src_len + + expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype) + + inverted_mask = 1.0 - expanded_mask + + return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min) + + +class XGLMSinusoidalPositionalEmbedding(nn.Module): + """This module produces sinusoidal positional embeddings of any length.""" + + def __init__(self, num_positions: int, embedding_dim: int, padding_idx: Optional[int] = None): + super().__init__() + self.offset = 2 + self.embedding_dim = embedding_dim + self.padding_idx = padding_idx + self.make_weights(num_positions + self.offset, embedding_dim, padding_idx) + + def make_weights(self, num_embeddings: int, embedding_dim: int, padding_idx: Optional[int] = None): + emb_weights = self.get_embedding(num_embeddings, embedding_dim, padding_idx) + if hasattr(self, "weights"): + # in forward put the weights on the correct dtype and device of the param + emb_weights = emb_weights.to(dtype=self.weights.dtype, device=self.weights.device) + + self.register_buffer("weights", emb_weights) + + @staticmethod + def get_embedding(num_embeddings: int, embedding_dim: int, padding_idx: Optional[int] = None): + """ + Build sinusoidal embeddings. + + This matches the implementation in tensor2tensor, but differs slightly from the description in Section 3.5 of + "Attention Is All You Need". + """ + half_dim = embedding_dim // 2 + emb = math.log(10000) / (half_dim - 1) + emb = torch.exp(torch.arange(half_dim, dtype=torch.float) * -emb) + emb = torch.arange(num_embeddings, dtype=torch.float).unsqueeze(1) * emb.unsqueeze(0) + emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1).view(num_embeddings, -1) + if embedding_dim % 2 == 1: + # zero pad + emb = torch.cat([emb, torch.zeros(num_embeddings, 1)], dim=1) + if padding_idx is not None: + emb[padding_idx, :] = 0 + + return emb.to(torch.get_default_dtype()) + + @torch.no_grad() + def forward(self, position_ids: torch.Tensor = None, past_key_values_length: int = 0): + bsz, seq_len = position_ids.size() + position_ids += self.offset + + # Expand embeddings if needed. `position_ids.max()` is NOT used to keep torch.fx compatibility. + max_pos = 2 + seq_len + past_key_values_length + if max_pos > self.weights.size(0): + self.make_weights(max_pos, self.embedding_dim, self.padding_idx) + + return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach() + + +class XGLMAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + embed_dim: int, + num_heads: int, + dropout: float = 0.0, + is_decoder: bool = False, + bias: bool = True, + ): + super().__init__() + self.embed_dim = embed_dim + self.num_heads = num_heads + self.dropout = dropout + self.head_dim = embed_dim // num_heads + + if (self.head_dim * num_heads) != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}" + f" and `num_heads`: {num_heads})." + ) + self.scaling = self.head_dim**-0.5 + self.is_decoder = is_decoder + + self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states: torch.Tensor, + key_value_states: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]: + """Input shape: Batch x Time x Channel""" + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + + bsz, tgt_len, _ = hidden_states.size() + + # get query proj + query_states = self.q_proj(hidden_states) * self.scaling + # get key, value proj + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.k_proj(key_value_states), -1, bsz) + value_states = self._shape(self.v_proj(key_value_states), -1, bsz) + elif past_key_value is not None: + # reuse k, v, self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + key_states = torch.cat([past_key_value[0], key_states], dim=2) + value_states = torch.cat([past_key_value[1], value_states], dim=2) + else: + # self_attention + key_states = self._shape(self.k_proj(hidden_states), -1, bsz) + value_states = self._shape(self.v_proj(hidden_states), -1, bsz) + + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + proj_shape = (bsz * self.num_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + src_len = key_states.size(1) + attn_weights = torch.bmm(query_states, key_states.transpose(1, 2)) + + if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len): + raise ValueError( + f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is" + f" {attn_weights.size()}" + ) + + if attention_mask is not None: + if attention_mask.size() != (bsz, 1, tgt_len, src_len): + raise ValueError( + f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}" + ) + attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask + attn_weights = torch.max(attn_weights, torch.tensor(torch.finfo(attn_weights.dtype).min)) + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + # upcast to fp32 if the weights are in fp16. Please see https://github.com/huggingface/transformers/pull/17437 + if attn_weights.dtype == torch.float16: + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(torch.float16) + else: + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if layer_head_mask is not None: + if layer_head_mask.size() != (self.num_heads,): + raise ValueError( + f"Head mask for a single layer should be of size {(self.num_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len) + + if output_attentions: + # this operation is a bit awkward, but it's required to + # make sure that attn_weights keeps its gradient. + # In order to do so, attn_weights have to be reshaped + # twice and have to be reused in the following + attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len) + else: + attn_weights_reshaped = None + + attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) + + attn_output = torch.bmm(attn_probs, value_states) + + if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim): + raise ValueError( + f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is" + f" {attn_output.size()}" + ) + + attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim) + attn_output = attn_output.transpose(1, 2) + + # Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be + # partitioned aross GPUs when using tensor-parallelism. + attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim) + + attn_output = self.out_proj(attn_output) + + return attn_output, attn_weights_reshaped, past_key_value + + +class XGLMDecoderLayer(nn.Module): + def __init__(self, config: XGLMConfig): + super().__init__() + self.embed_dim = config.d_model + + self.self_attn = XGLMAttention( + embed_dim=self.embed_dim, + num_heads=config.attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.dropout = config.dropout + self.activation_fn = ACT2FN[config.activation_function] + self.activation_dropout = config.activation_dropout + + if config.add_cross_attention: + self.encoder_attn = XGLMAttention( + embed_dim=self.embed_dim, + num_heads=config.attention_heads, + dropout=config.attention_dropout, + is_decoder=True, + ) + self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim) + + self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim) + self.fc1 = nn.Linear(self.embed_dim, config.ffn_dim) + self.fc2 = nn.Linear(config.ffn_dim, self.embed_dim) + self.final_layer_norm = nn.LayerNorm(self.embed_dim) + + # Copied from transformers.models.mbart.modeling_mbart.MBartDecoderLayer.forward + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + layer_head_mask: Optional[torch.Tensor] = None, + cross_attn_layer_head_mask: Optional[torch.Tensor] = None, + past_key_value: Optional[Tuple[torch.Tensor]] = None, + output_attentions: Optional[bool] = False, + use_cache: Optional[bool] = True, + ) -> torch.Tensor: + """ + Args: + hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)` + attention_mask (`torch.FloatTensor`): attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + encoder_hidden_states (`torch.FloatTensor`): + cross attention input to the layer of shape `(batch, seq_len, embed_dim)` + encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size + `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values. + layer_head_mask (`torch.FloatTensor`): mask for attention heads in a given layer of size + `(encoder_attention_heads,)`. + cross_attn_layer_head_mask (`torch.FloatTensor`): mask for cross-attention heads in a given layer of + size `(decoder_attention_heads,)`. + past_key_value (`Tuple(torch.FloatTensor)`): cached past key and value projection states + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + hidden_states = self.self_attn_layer_norm(hidden_states) + + # Self Attention + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + # add present self-attn cache to positions 1,2 of present_key_value tuple + hidden_states, self_attn_weights, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + # Cross-Attention Block + cross_attn_present_key_value = None + cross_attn_weights = None + if encoder_hidden_states is not None: + residual = hidden_states + hidden_states = self.encoder_attn_layer_norm(hidden_states) + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + hidden_states, cross_attn_weights, cross_attn_present_key_value = self.encoder_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + output_attentions=output_attentions, + ) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # Fully Connected + residual = hidden_states + hidden_states = self.final_layer_norm(hidden_states) + hidden_states = self.activation_fn(self.fc1(hidden_states)) + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.fc2(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, cross_attn_weights) + + if use_cache: + outputs += (present_key_value,) + + return outputs + + +class XGLMPreTrainedModel(PreTrainedModel): + config_class = XGLMConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["XGLMDecoderLayer"] + + def _init_weights(self, module): + std = self.config.init_std + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, XGLMModel): + module.gradient_checkpointing = value + + +@add_start_docstrings( + "The bare XGLM Model transformer outputting raw hidden-states without any specific head on top.", + XGLM_START_DOCSTRING, +) +class XGLMModel(XGLMPreTrainedModel): + """ + Transformer decoder consisting of *config.num_layers* layers. Each layer is a [`XGLMDecoderLayer`] + + Args: + config: XGLMConfig + embed_tokens (nn.Embedding): output embedding + """ + + def __init__(self, config: XGLMConfig, embed_tokens: Optional[nn.Embedding] = None): + super().__init__(config) + self.dropout = config.dropout + self.layerdrop = config.layerdrop + self.padding_idx = config.pad_token_id + self.max_target_positions = config.max_position_embeddings + self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 + + if embed_tokens is not None: + self.embed_tokens = embed_tokens + else: + self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model, self.padding_idx) + + self.embed_positions = XGLMSinusoidalPositionalEmbedding( + config.max_position_embeddings, + config.d_model, + config.pad_token_id, + ) + self.layers = nn.ModuleList([XGLMDecoderLayer(config) for _ in range(config.num_layers)]) + self.layer_norm = nn.LayerNorm(config.d_model) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embed_tokens + + def set_input_embeddings(self, value): + self.embed_tokens = value + + def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length): + # create causal mask + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + combined_attention_mask = None + if input_shape[-1] > 1: + combined_attention_mask = _make_causal_mask( + input_shape, + inputs_embeds.dtype, + device=inputs_embeds.device, + past_key_values_length=past_key_values_length, + ) + + if attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) + combined_attention_mask = ( + expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask + ) + + return combined_attention_mask + + @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPastAndCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + use_cache = use_cache if use_cache is not None else self.config.use_cache + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # retrieve input_ids and inputs_embeds + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + input_ids = input_ids.view(-1, input_shape[-1]) + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if position_ids is None: + position_ids = torch.arange( + past_key_values_length, + input_shape[-1] + past_key_values_length, + dtype=torch.long, + device=input_ids.device if input_ids is not None else inputs_embeds.device, + ) + position_ids = position_ids.unsqueeze(0).view(-1, input_shape[-1]) + else: + position_ids = position_ids.view(-1, input_shape[-1]) + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale + + attention_mask = self._prepare_decoder_attention_mask( + attention_mask, input_shape, inputs_embeds, past_key_values_length + ) + + # expand encoder attention mask + if encoder_hidden_states is not None and encoder_attention_mask is not None: + # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len] + encoder_attention_mask = _expand_mask(encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]) + + hidden_states = inputs_embeds + self.embed_positions(position_ids, past_key_values_length) + hidden_states = nn.functional.dropout(hidden_states, p=float(self.dropout), training=self.training) + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache = True` is incompatible with gradient checkpointing`. Setting `use_cache =" + " False`..." + ) + use_cache = False + + # decoder layers + all_hidden_states = () if output_hidden_states else None + all_self_attns = () if output_attentions else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + next_decoder_cache = () if use_cache else None + + # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired + for attn_mask, mask_name in zip([head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]): + if attn_mask is not None: + if attn_mask.size()[0] != len(self.layers): + raise ValueError( + f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for" + f" {head_mask.size()[0]}." + ) + for idx, decoder_layer in enumerate(self.layers): + # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description) + if output_hidden_states: + all_hidden_states += (hidden_states,) + dropout_probability = random.uniform(0, 1) + if self.training and (dropout_probability < self.layerdrop): + continue + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + # None for past_key_value + return module(*inputs, output_attentions, use_cache) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + head_mask[idx] if head_mask is not None else None, + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=( + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None + ), + past_key_value=past_key_value, + output_attentions=output_attentions, + use_cache=use_cache, + ) + hidden_states = layer_outputs[0] + + if use_cache: + next_decoder_cache += (layer_outputs[3 if output_attentions else 1],) + + if output_attentions: + all_self_attns += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + hidden_states = self.layer_norm(hidden_states) + + # add hidden states from the last decoder layer + if output_hidden_states: + all_hidden_states += (hidden_states,) + + next_cache = next_decoder_cache if use_cache else None + if not return_dict: + return tuple( + v + for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_cache, + hidden_states=all_hidden_states, + attentions=all_self_attns, + cross_attentions=all_cross_attentions, + ) + + +@add_start_docstrings( + """ + The XGLM Model transformer with a language modeling head on top (linear layer with weights tied to the input + embeddings). + """, + XGLM_START_DOCSTRING, +) +class XGLMForCausalLM(XGLMPreTrainedModel): + base_model_prefix = "model" + _keys_to_ignore_on_load_missing = [ + r"model.embed_positions.weights", + r"embed_positions.weights", + r"lm_head.weight", + ] + _keys_to_ignore_on_save = [ + r"model.embed_positions.weights", + ] + + def __init__(self, config): + super().__init__(config) + self.model = XGLMModel(config) + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.model.embed_tokens + + def set_input_embeddings(self, value): + self.model.embed_tokens = value + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + @add_start_docstrings_to_model_forward(XGLM_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=CausalLMOutputWithCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + """ + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn) + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + head_mask=head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + logits = self.lm_head(outputs[0]) + + loss = None + if labels is not None: + # shift labels and add a pad token to the end + shift_labels = labels.new_zeros(labels.shape) + shift_labels[:, :-1] = labels[:, 1:].clone() + shift_labels[:, -1] = self.config.pad_token_id + + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.config.vocab_size), shift_labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return (loss,) + output if loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + def prepare_inputs_for_generation( + self, input_ids, past_key_values=None, attention_mask=None, use_cache=None, **kwargs + ): + position_ids = kwargs.get("position_ids", None) + if attention_mask is not None and position_ids is None: + # create position_ids on the fly for batch generation + position_ids = attention_mask.long().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + if past_key_values: + position_ids = position_ids[:, -1].unsqueeze(-1) + else: + position_ids = None + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_ids.shape) + + if past_key_values: + input_ids = input_ids[:, -1:] + # first step, decoder_cached_states are empty + return { + "input_ids": input_ids, # encoder_outputs is defined. input_ids not needed + "attention_mask": attention_mask, + "position_ids": position_ids, + "past_key_values": past_key_values, + "use_cache": use_cache, + } + + @staticmethod + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm.py new file mode 100644 index 0000000000000000000000000000000000000000..f27c827134bf37260432640f6573a4c30ad8bedf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm.py @@ -0,0 +1,313 @@ +# coding=utf-8 +# Copyright The HuggingFace Team and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for .""" +import os +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as spm + +from ...tokenization_utils import PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) + +SPIECE_UNDERLINE = "▁" + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/xglm-564M": "https://huggingface.co/facebook/xglm-564M/resolve/main/sentencepiece.bpe.model", + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/xglm-564M": 2048, +} + + +class XGLMTokenizer(PreTrainedTokenizer): + """ + Adapted from [`RobertaTokenizer`] and [`XLNetTokenizer`]. Based on + [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + # Compatibility with the original tokenizer + self.num_madeup_words = 7 + madeup_words = [f"" for i in range(self.num_madeup_words)] + + kwargs["additional_special_tokens"] = kwargs.get("additional_special_tokens", []) + kwargs["additional_special_tokens"] += [ + word for word in madeup_words if word not in kwargs["additional_special_tokens"] + ] + + super().__init__( + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(str(vocab_file)) + self.vocab_file = vocab_file + + # Original fairseq vocab and spm vocab must be "aligned": + # Vocab | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 + # -------- | ------- | ------- | ------ | ------- | --- | --- | --- | ----- | ----- | ---- + # fairseq | '' | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' + # spm | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' | '▁a' + + # The first "real" token "," has position 4 in the original fairseq vocab and position 3 in the spm vocab + self.fairseq_offset = 1 + + # Mimic fairseq token-to-id alignment for the first 4 token + self.fairseq_tokens_to_ids = {"": 0, "": 1, "": 2, "": 3} + + sp_size = len(self.sp_model) + madeup_words = {f"": sp_size + i + self.fairseq_offset for i in range(self.num_madeup_words)} + self.fairseq_tokens_to_ids.update(madeup_words) + + self.fairseq_ids_to_tokens = {v: k for k, v in self.fairseq_tokens_to_ids.items()} + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + state["sp_model_proto"] = self.sp_model.serialized_model_proto() + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.LoadFromSerializedProto(self.sp_model_proto) + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLM-RoBERTa sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.sep_token_id] + token_ids_0 + sep = [self.sep_token_id] + return sep + token_ids_0 + sep + sep + token_ids_1 + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return [1] + ([0] * len(token_ids_0)) + return [1] + ([0] * len(token_ids_0)) + [1, 1] + ([0] * len(token_ids_1)) + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. XLM-RoBERTa does + not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + + if token_ids_1 is None: + return len(sep + token_ids_0) * [0] + return len(sep + token_ids_0 + sep + sep + token_ids_1) * [0] + + @property + def vocab_size(self): + return len(self.sp_model) + self.fairseq_offset + self.num_madeup_words + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def _tokenize(self, text: str) -> List[str]: + return self.sp_model.encode(text, out_type=str) + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + if token in self.fairseq_tokens_to_ids: + return self.fairseq_tokens_to_ids[token] + spm_id = self.sp_model.PieceToId(token) + + # Need to return unknown token if the SP model returned 0 + return spm_id + self.fairseq_offset if spm_id else self.unk_token_id + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + if index in self.fairseq_ids_to_tokens: + return self.fairseq_ids_to_tokens[index] + return self.sp_model.IdToPiece(index - self.fairseq_offset) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (strings for sub-words) in a single string.""" + out_string = "".join(tokens).replace(SPIECE_UNDERLINE, " ").strip() + return out_string + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..834b8a47ecb9206f08c14fe8b983e2245972ca92 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xglm/tokenization_xglm_fast.py @@ -0,0 +1,205 @@ +# coding=utf-8 +# Copyright The HuggingFace Team and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for XGLM.""" + +import os +from shutil import copyfile +from typing import List, Optional, Tuple + +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import is_sentencepiece_available, logging + + +if is_sentencepiece_available(): + from .tokenization_xglm import XGLMTokenizer +else: + XGLMTokenizer = None + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "facebook/xglm-564M": "https://huggingface.co/facebook/xglm-564M/resolve/main/sentencepiece.bpe.model", + }, + "tokenizer_file": { + "facebook/xglm-564M": "https://huggingface.co/facebook/xglm-564M/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "facebook/xglm-564M": 2048, +} + + +class XGLMTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" XGLM tokenizer (backed by HuggingFace's *tokenizers* library). Adapted from [`RobertaTokenizer`] + and [`XLNetTokenizer`]. Based on + [BPE](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=BPE#models). + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = XGLMTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + **kwargs, + ): + # Compatibility with the original tokenizer + self.num_madeup_words = 7 + madeup_words = [f"" for i in range(self.num_madeup_words)] + + kwargs["additional_special_tokens"] = kwargs.get("additional_special_tokens", []) + kwargs["additional_special_tokens"] += [ + word for word in madeup_words if word not in kwargs["additional_special_tokens"] + ] + + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + bos_token=bos_token, + eos_token=eos_token, + sep_token=sep_token, + cls_token=cls_token, + unk_token=unk_token, + pad_token=pad_token, + **kwargs, + ) + + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLM-RoBERTa sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.sep_token_id] + token_ids_0 + sep = [self.sep_token_id] + return sep + token_ids_0 + sep + sep + token_ids_1 + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. XLM-RoBERTa does + not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + + if token_ids_1 is None: + return len(sep + token_ids_0) * [0] + return len(sep + token_ids_0 + sep + sep + token_ids_1) * [0] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory.") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1dd57a90b92744f3fb2be5fc29fead5ee974021e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/__init__.py @@ -0,0 +1,105 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tf_available, is_torch_available + + +_import_structure = { + "configuration_xlm": ["XLM_PRETRAINED_CONFIG_ARCHIVE_MAP", "XLMConfig", "XLMOnnxConfig"], + "tokenization_xlm": ["XLMTokenizer"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xlm"] = [ + "XLM_PRETRAINED_MODEL_ARCHIVE_LIST", + "XLMForMultipleChoice", + "XLMForQuestionAnswering", + "XLMForQuestionAnsweringSimple", + "XLMForSequenceClassification", + "XLMForTokenClassification", + "XLMModel", + "XLMPreTrainedModel", + "XLMWithLMHeadModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_xlm"] = [ + "TF_XLM_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFXLMForMultipleChoice", + "TFXLMForQuestionAnsweringSimple", + "TFXLMForSequenceClassification", + "TFXLMForTokenClassification", + "TFXLMMainLayer", + "TFXLMModel", + "TFXLMPreTrainedModel", + "TFXLMWithLMHeadModel", + ] + + +if TYPE_CHECKING: + from .configuration_xlm import XLM_PRETRAINED_CONFIG_ARCHIVE_MAP, XLMConfig, XLMOnnxConfig + from .tokenization_xlm import XLMTokenizer + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xlm import ( + XLM_PRETRAINED_MODEL_ARCHIVE_LIST, + XLMForMultipleChoice, + XLMForQuestionAnswering, + XLMForQuestionAnsweringSimple, + XLMForSequenceClassification, + XLMForTokenClassification, + XLMModel, + XLMPreTrainedModel, + XLMWithLMHeadModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_xlm import ( + TF_XLM_PRETRAINED_MODEL_ARCHIVE_LIST, + TFXLMForMultipleChoice, + TFXLMForQuestionAnsweringSimple, + TFXLMForSequenceClassification, + TFXLMForTokenClassification, + TFXLMMainLayer, + TFXLMModel, + TFXLMPreTrainedModel, + TFXLMWithLMHeadModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/configuration_xlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/configuration_xlm.py new file mode 100644 index 0000000000000000000000000000000000000000..cd8d721bfc37d25947722d3ad0b4a45dd85503fe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/configuration_xlm.py @@ -0,0 +1,250 @@ +# coding=utf-8 +# Copyright 2019-present, Facebook, Inc and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XLM configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XLM_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "xlm-mlm-en-2048": "https://huggingface.co/xlm-mlm-en-2048/resolve/main/config.json", + "xlm-mlm-ende-1024": "https://huggingface.co/xlm-mlm-ende-1024/resolve/main/config.json", + "xlm-mlm-enfr-1024": "https://huggingface.co/xlm-mlm-enfr-1024/resolve/main/config.json", + "xlm-mlm-enro-1024": "https://huggingface.co/xlm-mlm-enro-1024/resolve/main/config.json", + "xlm-mlm-tlm-xnli15-1024": "https://huggingface.co/xlm-mlm-tlm-xnli15-1024/resolve/main/config.json", + "xlm-mlm-xnli15-1024": "https://huggingface.co/xlm-mlm-xnli15-1024/resolve/main/config.json", + "xlm-clm-enfr-1024": "https://huggingface.co/xlm-clm-enfr-1024/resolve/main/config.json", + "xlm-clm-ende-1024": "https://huggingface.co/xlm-clm-ende-1024/resolve/main/config.json", + "xlm-mlm-17-1280": "https://huggingface.co/xlm-mlm-17-1280/resolve/main/config.json", + "xlm-mlm-100-1280": "https://huggingface.co/xlm-mlm-100-1280/resolve/main/config.json", +} + + +class XLMConfig(PretrainedConfig): + """ + This is the configuration class to store the configuration of a [`XLMModel`] or a [`TFXLMModel`]. It is used to + instantiate a XLM model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the + [xlm-mlm-en-2048](https://huggingface.co/xlm-mlm-en-2048) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vocab_size (`int`, *optional*, defaults to 30145): + Vocabulary size of the BERT model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`XLMModel`] or [`TFXLMModel`]. + emb_dim (`int`, *optional*, defaults to 2048): + Dimensionality of the encoder layers and the pooler layer. + n_layer (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + n_head (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for the attention mechanism + gelu_activation (`bool`, *optional*, defaults to `True`): + Whether or not to use *gelu* for the activations instead of *relu*. + sinusoidal_embeddings (`bool`, *optional*, defaults to `False`): + Whether or not to use sinusoidal positional embeddings instead of absolute positional embeddings. + causal (`bool`, *optional*, defaults to `False`): + Whether or not the model should behave in a causal manner. Causal models use a triangular attention mask in + order to only attend to the left-side context instead if a bidirectional context. + asm (`bool`, *optional*, defaults to `False`): + Whether or not to use an adaptive log softmax projection layer instead of a linear layer for the prediction + layer. + n_langs (`int`, *optional*, defaults to 1): + The number of languages the model handles. Set to 1 for monolingual models. + use_lang_emb (`bool`, *optional*, defaults to `True`) + Whether to use language embeddings. Some models use additional language embeddings, see [the multilingual + models page](http://huggingface.co/transformers/multilingual.html#xlm-language-embeddings) for information + on how to use them. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + embed_init_std (`float`, *optional*, defaults to 2048^-0.5): + The standard deviation of the truncated_normal_initializer for initializing the embedding matrices. + init_std (`int`, *optional*, defaults to 50257): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices except the + embedding matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + bos_index (`int`, *optional*, defaults to 0): + The index of the beginning of sentence token in the vocabulary. + eos_index (`int`, *optional*, defaults to 1): + The index of the end of sentence token in the vocabulary. + pad_index (`int`, *optional*, defaults to 2): + The index of the padding token in the vocabulary. + unk_index (`int`, *optional*, defaults to 3): + The index of the unknown token in the vocabulary. + mask_index (`int`, *optional*, defaults to 5): + The index of the masking token in the vocabulary. + is_encoder(`bool`, *optional*, defaults to `True`): + Whether or not the initialized model should be a transformer encoder or decoder as seen in Vaswani et al. + summary_type (`string`, *optional*, defaults to "first"): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Has to be one of the following options: + + - `"last"`: Take the last token hidden state (like XLNet). + - `"first"`: Take the first token hidden state (like BERT). + - `"mean"`: Take the mean of all tokens hidden states. + - `"cls_index"`: Supply a Tensor of classification token position (like GPT/GPT-2). + - `"attn"`: Not implemented now, use multi-head attention. + summary_use_proj (`bool`, *optional*, defaults to `True`): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Whether or not to add a projection after the vector extraction. + summary_activation (`str`, *optional*): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Pass `"tanh"` for a tanh activation to the output, any other value will result in no activation. + summary_proj_to_labels (`bool`, *optional*, defaults to `True`): + Used in the sequence classification and multiple choice models. + + Whether the projection outputs should have `config.num_labels` or `config.hidden_size` classes. + summary_first_dropout (`float`, *optional*, defaults to 0.1): + Used in the sequence classification and multiple choice models. + + The dropout ratio to be used after the projection and activation. + start_n_top (`int`, *optional*, defaults to 5): + Used in the SQuAD evaluation script. + end_n_top (`int`, *optional*, defaults to 5): + Used in the SQuAD evaluation script. + mask_token_id (`int`, *optional*, defaults to 0): + Model agnostic parameter to identify masked tokens when generating text in an MLM context. + lang_id (`int`, *optional*, defaults to 1): + The ID of the language used by the model. This parameter is used when generating text in a given language. + + Examples: + + ```python + >>> from transformers import XLMConfig, XLMModel + + >>> # Initializing a XLM configuration + >>> configuration = XLMConfig() + + >>> # Initializing a model (with random weights) from the configuration + >>> model = XLMModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "xlm" + attribute_map = { + "hidden_size": "emb_dim", + "num_attention_heads": "n_heads", + "num_hidden_layers": "n_layers", + "n_words": "vocab_size", # For backward compatibility + } + + def __init__( + self, + vocab_size=30145, + emb_dim=2048, + n_layers=12, + n_heads=16, + dropout=0.1, + attention_dropout=0.1, + gelu_activation=True, + sinusoidal_embeddings=False, + causal=False, + asm=False, + n_langs=1, + use_lang_emb=True, + max_position_embeddings=512, + embed_init_std=2048**-0.5, + layer_norm_eps=1e-12, + init_std=0.02, + bos_index=0, + eos_index=1, + pad_index=2, + unk_index=3, + mask_index=5, + is_encoder=True, + summary_type="first", + summary_use_proj=True, + summary_activation=None, + summary_proj_to_labels=True, + summary_first_dropout=0.1, + start_n_top=5, + end_n_top=5, + mask_token_id=0, + lang_id=0, + pad_token_id=2, + bos_token_id=0, + **kwargs, + ): + """Constructs XLMConfig.""" + self.vocab_size = vocab_size + self.emb_dim = emb_dim + self.n_layers = n_layers + self.n_heads = n_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.gelu_activation = gelu_activation + self.sinusoidal_embeddings = sinusoidal_embeddings + self.causal = causal + self.asm = asm + self.n_langs = n_langs + self.use_lang_emb = use_lang_emb + self.layer_norm_eps = layer_norm_eps + self.bos_index = bos_index + self.eos_index = eos_index + self.pad_index = pad_index + self.unk_index = unk_index + self.mask_index = mask_index + self.is_encoder = is_encoder + self.max_position_embeddings = max_position_embeddings + self.embed_init_std = embed_init_std + self.init_std = init_std + self.summary_type = summary_type + self.summary_use_proj = summary_use_proj + self.summary_activation = summary_activation + self.summary_proj_to_labels = summary_proj_to_labels + self.summary_first_dropout = summary_first_dropout + self.start_n_top = start_n_top + self.end_n_top = end_n_top + self.mask_token_id = mask_token_id + self.lang_id = lang_id + + if "n_words" in kwargs: + self.n_words = kwargs["n_words"] + + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, **kwargs) + + +# Copied from transformers.models.bert.configuration_bert.BertOnnxConfig +class XLMOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ("token_type_ids", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/convert_xlm_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/convert_xlm_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..6f3cdf920a0e1ba34aac737b7672c2b71182e465 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/convert_xlm_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,78 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert OpenAI GPT checkpoint.""" + + +import argparse +import json + +import numpy +import torch + +from transformers.models.xlm.tokenization_xlm import VOCAB_FILES_NAMES +from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging + + +logging.set_verbosity_info() + + +def convert_xlm_checkpoint_to_pytorch(xlm_checkpoint_path, pytorch_dump_folder_path): + # Load checkpoint + chkpt = torch.load(xlm_checkpoint_path, map_location="cpu") + + state_dict = chkpt["model"] + + # We have the base model one level deeper than the original XLM repository + two_levels_state_dict = {} + for k, v in state_dict.items(): + if "pred_layer" in k: + two_levels_state_dict[k] = v + else: + two_levels_state_dict["transformer." + k] = v + + config = chkpt["params"] + config = {n: v for n, v in config.items() if not isinstance(v, (torch.FloatTensor, numpy.ndarray))} + + vocab = chkpt["dico_word2id"] + vocab = {s + "" if s.find("@@") == -1 and i > 13 else s.replace("@@", ""): i for s, i in vocab.items()} + + # Save pytorch-model + pytorch_weights_dump_path = pytorch_dump_folder_path + "/" + WEIGHTS_NAME + pytorch_config_dump_path = pytorch_dump_folder_path + "/" + CONFIG_NAME + pytorch_vocab_dump_path = pytorch_dump_folder_path + "/" + VOCAB_FILES_NAMES["vocab_file"] + + print(f"Save PyTorch model to {pytorch_weights_dump_path}") + torch.save(two_levels_state_dict, pytorch_weights_dump_path) + + print(f"Save configuration file to {pytorch_config_dump_path}") + with open(pytorch_config_dump_path, "w", encoding="utf-8") as f: + f.write(json.dumps(config, indent=2) + "\n") + + print(f"Save vocab file to {pytorch_config_dump_path}") + with open(pytorch_vocab_dump_path, "w", encoding="utf-8") as f: + f.write(json.dumps(vocab, indent=2) + "\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--xlm_checkpoint_path", default=None, type=str, required=True, help="Path the official PyTorch dump." + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + args = parser.parse_args() + convert_xlm_checkpoint_to_pytorch(args.xlm_checkpoint_path, args.pytorch_dump_folder_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_tf_xlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_tf_xlm.py new file mode 100644 index 0000000000000000000000000000000000000000..f77111cee450a86e3cc8fb4f5c93ab4a210ebebb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_tf_xlm.py @@ -0,0 +1,1302 @@ +# coding=utf-8 +# Copyright 2019-present, Facebook, Inc and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + TF 2.0 XLM model. +""" + +import itertools +import warnings +from dataclasses import dataclass +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutput, + TFMultipleChoiceModelOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFModelInputType, + TFMultipleChoiceLoss, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFSequenceSummary, + TFSharedEmbeddings, + TFTokenClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + MULTIPLE_CHOICE_DUMMY_INPUTS, + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, +) +from .configuration_xlm import XLMConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-mlm-en-2048" +_CONFIG_FOR_DOC = "XLMConfig" + +TF_XLM_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlm-mlm-en-2048", + "xlm-mlm-ende-1024", + "xlm-mlm-enfr-1024", + "xlm-mlm-enro-1024", + "xlm-mlm-tlm-xnli15-1024", + "xlm-mlm-xnli15-1024", + "xlm-clm-enfr-1024", + "xlm-clm-ende-1024", + "xlm-mlm-17-1280", + "xlm-mlm-100-1280", + # See all XLM models at https://huggingface.co/models?filter=xlm +] + + +def create_sinusoidal_embeddings(n_pos, dim, out): + position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) + out[:, 0::2] = tf.constant(np.sin(position_enc[:, 0::2])) + out[:, 1::2] = tf.constant(np.cos(position_enc[:, 1::2])) + + +def get_masks(slen, lengths, causal, padding_mask=None): + """ + Generate hidden states mask, and optionally an attention mask. + """ + bs = shape_list(lengths)[0] + if padding_mask is not None: + mask = padding_mask + else: + # assert lengths.max().item() <= slen + alen = tf.range(slen, dtype=lengths.dtype) + mask = alen < tf.expand_dims(lengths, axis=1) + + # attention mask is the same as mask, or triangular inferior attention (causal) + if causal: + attn_mask = tf.less_equal( + tf.tile(tf.reshape(alen, (1, 1, slen)), (bs, slen, 1)), tf.reshape(alen, (1, slen, 1)) + ) + else: + attn_mask = mask + + # sanity check + # assert shape_list(mask) == [bs, slen] + tf.debugging.assert_equal(shape_list(mask), [bs, slen]) + if causal: + tf.debugging.assert_equal(shape_list(attn_mask), [bs, slen, slen]) + + return mask, attn_mask + + +class TFXLMMultiHeadAttention(tf.keras.layers.Layer): + NEW_ID = itertools.count() + + def __init__(self, n_heads, dim, config, **kwargs): + super().__init__(**kwargs) + self.layer_id = next(TFXLMMultiHeadAttention.NEW_ID) + self.dim = dim + self.n_heads = n_heads + self.output_attentions = config.output_attentions + assert self.dim % self.n_heads == 0 + + self.q_lin = tf.keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="q_lin") + self.k_lin = tf.keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="k_lin") + self.v_lin = tf.keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="v_lin") + self.out_lin = tf.keras.layers.Dense(dim, kernel_initializer=get_initializer(config.init_std), name="out_lin") + self.dropout = tf.keras.layers.Dropout(config.attention_dropout) + self.pruned_heads = set() + + def prune_heads(self, heads): + raise NotImplementedError + + def call(self, input, mask, kv, cache, head_mask, output_attentions, training=False): + """ + Self-attention (if kv is None) or attention over source sentence (provided by kv). + """ + # Input is (bs, qlen, dim) + # Mask is (bs, klen) (non-causal) or (bs, klen, klen) + bs, qlen, dim = shape_list(input) + + if kv is None: + klen = qlen if cache is None else cache["slen"] + qlen + else: + klen = shape_list(kv)[1] + + # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' + dim_per_head = self.dim // self.n_heads + mask_reshape = (bs, 1, qlen, klen) if len(shape_list(mask)) == 3 else (bs, 1, 1, klen) + + def shape(x): + """projection""" + return tf.transpose(tf.reshape(x, (bs, -1, self.n_heads, dim_per_head)), perm=(0, 2, 1, 3)) + + def unshape(x): + """compute context""" + return tf.reshape(tf.transpose(x, perm=(0, 2, 1, 3)), (bs, -1, self.n_heads * dim_per_head)) + + q = shape(self.q_lin(input)) # (bs, n_heads, qlen, dim_per_head) + + if kv is None: + k = shape(self.k_lin(input)) # (bs, n_heads, qlen, dim_per_head) + v = shape(self.v_lin(input)) # (bs, n_heads, qlen, dim_per_head) + elif cache is None or self.layer_id not in cache: + k = v = kv + k = shape(self.k_lin(k)) # (bs, n_heads, qlen, dim_per_head) + v = shape(self.v_lin(v)) # (bs, n_heads, qlen, dim_per_head) + + if cache is not None: + if self.layer_id in cache: + if kv is None: + k_, v_ = cache[self.layer_id] + k = tf.concat([k_, k], axis=2) # (bs, n_heads, klen, dim_per_head) + v = tf.concat([v_, v], axis=2) # (bs, n_heads, klen, dim_per_head) + else: + k, v = cache[self.layer_id] + + cache[self.layer_id] = (k, v) + + f_dim_per_head = tf.cast(dim_per_head, dtype=q.dtype) + q = tf.multiply(q, tf.math.rsqrt(f_dim_per_head)) # (bs, n_heads, qlen, dim_per_head) + k = tf.cast(k, dtype=q.dtype) + scores = tf.matmul(q, k, transpose_b=True) # (bs, n_heads, qlen, klen) + mask = tf.reshape(mask, mask_reshape) # (bs, n_heads, qlen, klen) + # scores.masked_fill_(mask, -float('inf')) # (bs, n_heads, qlen, klen) + mask = tf.cast(mask, dtype=scores.dtype) + scores = scores - 1e30 * (1.0 - mask) + weights = stable_softmax(scores, axis=-1) # (bs, n_heads, qlen, klen) + weights = self.dropout(weights, training=training) # (bs, n_heads, qlen, klen) + + # Mask heads if we want to + if head_mask is not None: + weights = weights * head_mask + + context = tf.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) + context = unshape(context) # (bs, qlen, dim) + outputs = (self.out_lin(context),) + + if output_attentions: + outputs = outputs + (weights,) + + return outputs + + +class TFXLMTransformerFFN(tf.keras.layers.Layer): + def __init__(self, in_dim, dim_hidden, out_dim, config, **kwargs): + super().__init__(**kwargs) + + self.lin1 = tf.keras.layers.Dense(dim_hidden, kernel_initializer=get_initializer(config.init_std), name="lin1") + self.lin2 = tf.keras.layers.Dense(out_dim, kernel_initializer=get_initializer(config.init_std), name="lin2") + self.act = get_tf_activation("gelu") if config.gelu_activation else get_tf_activation("relu") + self.dropout = tf.keras.layers.Dropout(config.dropout) + + def call(self, input, training=False): + x = self.lin1(input) + x = self.act(x) + x = self.lin2(x) + x = self.dropout(x, training=training) + + return x + + +@keras_serializable +class TFXLMMainLayer(tf.keras.layers.Layer): + config_class = XLMConfig + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.output_hidden_states = config.output_hidden_states + self.output_attentions = config.output_attentions + self.return_dict = config.use_return_dict + + # encoder / decoder, output layer + self.is_encoder = config.is_encoder + self.is_decoder = not config.is_encoder + + if self.is_decoder: + raise NotImplementedError("Currently XLM can only be used as an encoder") + + # self.with_output = with_output + self.causal = config.causal + + # dictionary / languages + self.n_langs = config.n_langs + self.use_lang_emb = config.use_lang_emb + self.n_words = config.n_words + self.eos_index = config.eos_index + self.pad_index = config.pad_index + # self.dico = dico + # self.id2lang = config.id2lang + # self.lang2id = config.lang2id + # assert len(self.dico) == self.n_words + # assert len(self.id2lang) == len(self.lang2id) == self.n_langs + + # model parameters + self.dim = config.emb_dim # 512 by default + self.hidden_dim = self.dim * 4 # 2048 by default + self.n_heads = config.n_heads # 8 by default + self.n_layers = config.n_layers + self.max_position_embeddings = config.max_position_embeddings + self.embed_init_std = config.embed_init_std + if self.dim % self.n_heads != 0: + raise ValueError("transformer dim must be a multiple of n_heads") + + # embeddings + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.attention_dropout = tf.keras.layers.Dropout(config.attention_dropout) + + if config.sinusoidal_embeddings: + raise NotImplementedError + # create_sinusoidal_embeddings(config.max_position_embeddings, self.dim, out=self.position_embeddings.weight) + + self.embeddings = TFSharedEmbeddings( + self.n_words, self.dim, initializer_range=config.embed_init_std, name="embeddings" + ) # padding_idx=self.pad_index) + self.layer_norm_emb = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm_emb") + + # transformer layers + self.attentions = [] + self.layer_norm1 = [] + self.ffns = [] + self.layer_norm2 = [] + # if self.is_decoder: + # self.layer_norm15 = [] + # self.encoder_attn = [] + + for i in range(self.n_layers): + self.attentions.append( + TFXLMMultiHeadAttention(self.n_heads, self.dim, config=config, name=f"attentions_._{i}") + ) + self.layer_norm1.append( + tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm1_._{i}") + ) + # if self.is_decoder: + # self.layer_norm15.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) + # self.encoder_attn.append(MultiHeadAttention(self.n_heads, self.dim, dropout=self.attention_dropout)) + self.ffns.append( + TFXLMTransformerFFN(self.dim, self.hidden_dim, self.dim, config=config, name=f"ffns_._{i}") + ) + self.layer_norm2.append( + tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name=f"layer_norm2_._{i}") + ) + + if hasattr(config, "pruned_heads"): + pruned_heads = config.pruned_heads.copy().items() + config.pruned_heads = {} + + for layer, heads in pruned_heads: + if self.attentions[int(layer)].n_heads == config.n_heads: + self.prune_heads({int(layer): list(map(int, heads))}) + + def build(self, input_shape): + with tf.name_scope("position_embeddings"): + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.dim], + initializer=get_initializer(self.embed_init_std), + ) + + if self.n_langs > 1 and self.use_lang_emb: + with tf.name_scope("lang_embeddings"): + self.lang_embeddings = self.add_weight( + name="embeddings", + shape=[self.n_langs, self.dim], + initializer=get_initializer(self.embed_init_std), + ) + + super().build(input_shape) + + def get_input_embeddings(self): + return self.embeddings + + def set_input_embeddings(self, value): + self.embeddings.weight = value + self.embeddings.vocab_size = shape_list(value)[0] + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + def call( + self, + input_ids=None, + attention_mask=None, + langs=None, + token_type_ids=None, + position_ids=None, + lengths=None, + cache=None, + head_mask=None, + inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + # removed: src_enc=None, src_len=None + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + bs, slen = shape_list(input_ids) + elif inputs_embeds is not None: + bs, slen = shape_list(inputs_embeds)[:2] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + if lengths is None: + if input_ids is not None: + lengths = tf.reduce_sum( + tf.cast(tf.not_equal(input_ids, self.pad_index), dtype=input_ids.dtype), axis=1 + ) + else: + lengths = tf.convert_to_tensor([slen] * bs) + # mask = input_ids != self.pad_index + + # check inputs + # assert shape_list(lengths)[0] == bs + tf.debugging.assert_equal( + shape_list(lengths)[0], bs + ), f"Expected batch size {shape_list(lengths)[0]} and received batch size {bs} mismatched" + # assert lengths.max().item() <= slen + # input_ids = input_ids.transpose(0, 1) # batch size as dimension 0 + # assert (src_enc is None) == (src_len is None) + # if src_enc is not None: + # assert self.is_decoder + # assert src_enc.size(0) == bs + + # generate masks + mask, attn_mask = get_masks(slen, lengths, self.causal, padding_mask=attention_mask) + # if self.is_decoder and src_enc is not None: + # src_mask = torch.arange(src_len.max(), dtype=torch.long, device=lengths.device) < src_len[:, None] + + # position_ids + if position_ids is None: + position_ids = tf.expand_dims(tf.range(slen), axis=0) + position_ids = tf.tile(position_ids, (bs, 1)) + + # assert shape_list(position_ids) == [bs, slen] # (slen, bs) + tf.debugging.assert_equal( + shape_list(position_ids), [bs, slen] + ), f"Position id shape {shape_list(position_ids)} and input shape {[bs, slen]} mismatched" + # position_ids = position_ids.transpose(0, 1) + + # langs + if langs is not None: + # assert shape_list(langs) == [bs, slen] # (slen, bs) + tf.debugging.assert_equal( + shape_list(langs), [bs, slen] + ), f"Lang shape {shape_list(langs)} and input shape {[bs, slen]} mismatched" + # langs = langs.transpose(0, 1) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x qlen x klen] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.n_layers + + # do not recompute cached elements + if cache is not None and input_ids is not None: + _slen = slen - cache["slen"] + input_ids = input_ids[:, -_slen:] + position_ids = position_ids[:, -_slen:] + if langs is not None: + langs = langs[:, -_slen:] + mask = mask[:, -_slen:] + attn_mask = attn_mask[:, -_slen:] + + # embeddings + if inputs_embeds is None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.embeddings.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.embeddings.vocab_size})" + ), + ) + inputs_embeds = self.embeddings(input_ids) + + tensor = inputs_embeds + tf.gather(self.position_embeddings, position_ids) + + if langs is not None and self.use_lang_emb and self.n_langs > 1: + tensor = tensor + tf.gather(self.lang_embeddings, langs) + if token_type_ids is not None: + tensor = tensor + self.embeddings(token_type_ids) + + tensor = self.layer_norm_emb(tensor) + tensor = self.dropout(tensor, training=training) + mask = tf.cast(mask, dtype=tensor.dtype) + tensor = tensor * tf.expand_dims(mask, axis=-1) + + # transformer layers + hidden_states = () if output_hidden_states else None + attentions = () if output_attentions else None + + for i in range(self.n_layers): + if output_hidden_states: + hidden_states = hidden_states + (tensor,) + + # self attention + attn_outputs = self.attentions[i]( + tensor, + attn_mask, + None, + cache, + head_mask[i], + output_attentions, + training=training, + ) + attn = attn_outputs[0] + + if output_attentions: + attentions = attentions + (attn_outputs[1],) + + attn = self.dropout(attn, training=training) + tensor = tensor + attn + tensor = self.layer_norm1[i](tensor) + + # encoder attention (for decoder only) + # if self.is_decoder and src_enc is not None: + # attn = self.encoder_attn[i](tensor, src_mask, kv=src_enc, cache=cache) + # attn = nn.functional.dropout(attn, p=self.dropout, training=self.training) + # tensor = tensor + attn + # tensor = self.layer_norm15[i](tensor) + + # FFN + tensor = tensor + self.ffns[i](tensor) + tensor = self.layer_norm2[i](tensor) + tensor = tensor * tf.expand_dims(mask, axis=-1) + + # Add last hidden state + if output_hidden_states: + hidden_states = hidden_states + (tensor,) + + # update cache length + if cache is not None: + cache["slen"] += tensor.size(1) + + # move back sequence length to dimension 0 + # tensor = tensor.transpose(0, 1) + + if not return_dict: + return tuple(v for v in [tensor, hidden_states, attentions] if v is not None) + + return TFBaseModelOutput(last_hidden_state=tensor, hidden_states=hidden_states, attentions=attentions) + + +class TFXLMPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMConfig + base_model_prefix = "transformer" + + @property + def dummy_inputs(self): + # Sometimes XLM has language embeddings so don't forget to build them as well if needed + inputs_list = tf.constant([[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]], dtype=tf.int32) + attns_list = tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32) + if self.config.use_lang_emb and self.config.n_langs > 1: + return { + "input_ids": inputs_list, + "attention_mask": attns_list, + "langs": tf.constant([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]], dtype=tf.int32), + } + else: + return {"input_ids": inputs_list, "attention_mask": attns_list} + + +# Remove when XLMWithLMHead computes loss like other LM models +@dataclass +class TFXLMWithLMHeadModelOutput(ModelOutput): + """ + Base class for [`TFXLMWithLMHeadModel`] outputs. + + Args: + logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + logits: tf.Tensor = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +XLM_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`XLMConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and + [`PreTrainedTokenizer.encode`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + langs (`tf.Tensor` or `Numpy array` of shape `({0})`, *optional*): + A parallel sequence of tokens to be used to indicate the language of each token in the input. Indices are + languages ids which can be obtained from the language names by using two conversion mappings provided in + the configuration of the model (only provided for multilingual models). More precisely, the *language name + to language id* mapping is in `model.config.lang2id` (which is a dictionary string to int) and the + *language id to language name* mapping is in `model.config.id2lang` (dictionary int to string). + + See usage examples detailed in the [multilingual documentation](../multilingual). + token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + lengths (`tf.Tensor` or `Numpy array` of shape `(batch_size,)`, *optional*): + Length of each sentence that can be used to avoid performing attention on padding token indices. You can + also use *attention_mask* for the same result (see above), kept here for compatibility. Indices selected in + `[0, ..., input_ids.size(-1)]`. + cache (`Dict[str, tf.Tensor]`, *optional*): + Dictionary string to `torch.FloatTensor` that contains precomputed hidden states (key and values in the + attention blocks) as computed by the model (see `cache` output below). Can be used to speed up sequential + decoding. + + The dictionary object will be modified in-place during the forward pass to add newly computed + hidden-states. + head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +@add_start_docstrings( + "The bare XLM Model transformer outputting raw hidden-states without any specific head on top.", + XLM_START_DOCSTRING, +) +class TFXLMModel(TFXLMPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLMMainLayer(config, name="transformer") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids=None, + attention_mask=None, + langs=None, + token_type_ids=None, + position_ids=None, + lengths=None, + cache=None, + head_mask=None, + inputs_embeds=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + training=False, + ) -> Union[TFBaseModelOutput, Tuple[tf.Tensor]]: + outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + # Copied from transformers.models.distilbert.modeling_tf_distilbert.TFDistilBertModel.serving_output + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFBaseModelOutput(last_hidden_state=output.last_hidden_state, hidden_states=hs, attentions=attns) + + +class TFXLMPredLayer(tf.keras.layers.Layer): + """ + Prediction layer (cross_entropy or adaptive_softmax). + """ + + def __init__(self, config, input_embeddings, **kwargs): + super().__init__(**kwargs) + + self.asm = config.asm + self.n_words = config.n_words + self.pad_index = config.pad_index + + if config.asm is False: + self.input_embeddings = input_embeddings + else: + raise NotImplementedError + # self.proj = nn.AdaptiveLogSoftmaxWithLoss( + # in_features=dim, + # n_classes=config.n_words, + # cutoffs=config.asm_cutoffs, + # div_value=config.asm_div_value, + # head_bias=True, # default is False + # ) + + def build(self, input_shape): + # The output weights are the same as the input embeddings, but there is an output-only bias for each token. + self.bias = self.add_weight(shape=(self.n_words,), initializer="zeros", trainable=True, name="bias") + + super().build(input_shape) + + def get_output_embeddings(self): + return self.input_embeddings + + def set_output_embeddings(self, value): + self.input_embeddings.weight = value + self.input_embeddings.vocab_size = shape_list(value)[0] + + def get_bias(self): + return {"bias": self.bias} + + def set_bias(self, value): + self.bias = value["bias"] + self.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states): + hidden_states = self.input_embeddings(hidden_states, mode="linear") + hidden_states = hidden_states + self.bias + + return hidden_states + + +@add_start_docstrings( + """ + The XLM Model transformer with a language modeling head on top (linear layer with weights tied to the input + embeddings). + """, + XLM_START_DOCSTRING, +) +class TFXLMWithLMHeadModel(TFXLMPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLMMainLayer(config, name="transformer") + self.pred_layer = TFXLMPredLayer(config, self.transformer.embeddings, name="pred_layer_._proj") + # XLM does not have past caching features + self.supports_xla_generation = False + + def get_lm_head(self): + return self.pred_layer + + def get_prefix_bias_name(self): + warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) + return self.name + "/" + self.pred_layer.name + + def prepare_inputs_for_generation(self, inputs, **kwargs): + mask_token_id = self.config.mask_token_id + lang_id = self.config.lang_id + + effective_batch_size = inputs.shape[0] + mask_token = tf.fill((effective_batch_size, 1), 1) * mask_token_id + inputs = tf.concat([inputs, mask_token], axis=1) + + if lang_id is not None: + langs = tf.ones_like(inputs) * lang_id + else: + langs = None + return {"input_ids": inputs, "langs": langs} + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLMWithLMHeadModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + langs: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + lengths: Optional[Union[np.ndarray, tf.Tensor]] = None, + cache: Optional[Dict[str, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFXLMWithLMHeadModelOutput, Tuple[tf.Tensor]]: + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + output = transformer_outputs[0] + outputs = self.pred_layer(output) + + if not return_dict: + return (outputs,) + transformer_outputs[1:] + + return TFXLMWithLMHeadModelOutput( + logits=outputs, hidden_states=transformer_outputs.hidden_states, attentions=transformer_outputs.attentions + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFXLMWithLMHeadModelOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. + for GLUE tasks. + """, + XLM_START_DOCSTRING, +) +class TFXLMForSequenceClassification(TFXLMPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.transformer = TFXLMMainLayer(config, name="transformer") + self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + langs: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + lengths: Optional[Union[np.ndarray, tf.Tensor]] = None, + cache: Optional[Dict[str, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + output = transformer_outputs[0] + + logits = self.sequence_summary(output) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForSequenceClassification.serving_output + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_START_DOCSTRING, +) +class TFXLMForMultipleChoice(TFXLMPreTrainedModel, TFMultipleChoiceLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.transformer = TFXLMMainLayer(config, name="transformer") + self.sequence_summary = TFSequenceSummary(config, initializer_range=config.init_std, name="sequence_summary") + self.logits_proj = tf.keras.layers.Dense( + 1, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" + ) + + @property + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + tf.Tensor with dummy inputs + """ + # Sometimes XLM has language embeddings so don't forget to build them as well if needed + if self.config.use_lang_emb and self.config.n_langs > 1: + return { + "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), + "langs": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), + } + else: + return { + "input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32), + } + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + langs: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + lengths: Optional[Union[np.ndarray, tf.Tensor]] = None, + cache: Optional[Dict[str, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFMultipleChoiceModelOutput, Tuple[tf.Tensor]]: + if input_ids is not None: + num_choices = shape_list(input_ids)[1] + seq_length = shape_list(input_ids)[2] + else: + num_choices = shape_list(inputs_embeds)[1] + seq_length = shape_list(inputs_embeds)[2] + + flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None + flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None + flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None + flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None + flat_langs = tf.reshape(langs, (-1, seq_length)) if langs is not None else None + flat_inputs_embeds = ( + tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) + if inputs_embeds is not None + else None + ) + + if lengths is not None: + logger.warning( + "The `lengths` parameter cannot be used with the XLM multiple choice models. Please use the " + "attention mask instead.", + ) + lengths = None + + transformer_outputs = self.transformer( + flat_input_ids, + flat_attention_mask, + flat_langs, + flat_token_type_ids, + flat_position_ids, + lengths, + cache, + head_mask, + flat_inputs_embeds, + output_attentions, + output_hidden_states, + return_dict=return_dict, + training=training, + ) + output = transformer_outputs[0] + logits = self.sequence_summary(output) + logits = self.logits_proj(logits) + reshaped_logits = tf.reshape(logits, (-1, num_choices)) + + loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) + + if not return_dict: + output = (reshaped_logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFMultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), + "token_type_ids": tf.TensorSpec((None, None, None), tf.int32, name="token_type_ids"), + } + ] + ) + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving + def serving(self, inputs: Dict[str, tf.Tensor]): + output = self.call(input_ids=inputs) + + return self.serving_output(output) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving_output + def serving_output(self, output: TFMultipleChoiceModelOutput) -> TFMultipleChoiceModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMultipleChoiceModelOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + XLM_START_DOCSTRING, +) +class TFXLMForTokenClassification(TFXLMPreTrainedModel, TFTokenClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.transformer = TFXLMMainLayer(config, name="transformer") + self.dropout = tf.keras.layers.Dropout(config.dropout) + self.classifier = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.init_std), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + langs: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + lengths: Optional[Union[np.ndarray, tf.Tensor]] = None, + cache: Optional[Dict[str, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = transformer_outputs[0] + + sequence_output = self.dropout(sequence_output, training=training) + logits = self.classifier(sequence_output) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForTokenClassification.serving_output + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear layer + on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_START_DOCSTRING, +) +class TFXLMForQuestionAnsweringSimple(TFXLMPreTrainedModel, TFQuestionAnsweringLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLMMainLayer(config, name="transformer") + self.qa_outputs = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.init_std), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + langs: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + lengths: Optional[Union[np.ndarray, tf.Tensor]] = None, + cache: Optional[Dict[str, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = transformer_outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = tf.split(logits, 2, axis=-1) + start_logits = tf.squeeze(start_logits, axis=-1) + end_logits = tf.squeeze(end_logits, axis=-1) + + loss = None + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels, (start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForQuestionAnswering.serving_output + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_xlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_xlm.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0adcddf95c2103494c32f8b81ea02df7382f35 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/modeling_xlm.py @@ -0,0 +1,1273 @@ +# coding=utf-8 +# Copyright 2019-present, Facebook, Inc and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + PyTorch XLM model. +""" + +import itertools +import math +from dataclasses import dataclass +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import torch +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import gelu +from ...modeling_outputs import ( + BaseModelOutput, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel, SequenceSummary, SQuADHead +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlm import XLMConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-mlm-en-2048" +_CONFIG_FOR_DOC = "XLMConfig" + +XLM_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlm-mlm-en-2048", + "xlm-mlm-ende-1024", + "xlm-mlm-enfr-1024", + "xlm-mlm-enro-1024", + "xlm-mlm-tlm-xnli15-1024", + "xlm-mlm-xnli15-1024", + "xlm-clm-enfr-1024", + "xlm-clm-ende-1024", + "xlm-mlm-17-1280", + "xlm-mlm-100-1280", + # See all XLM models at https://huggingface.co/models?filter=xlm +] + + +def create_sinusoidal_embeddings(n_pos, dim, out): + position_enc = np.array([[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]) + out[:, 0::2] = torch.FloatTensor(np.sin(position_enc[:, 0::2])) + out[:, 1::2] = torch.FloatTensor(np.cos(position_enc[:, 1::2])) + out.detach_() + out.requires_grad = False + + +def get_masks(slen, lengths, causal, padding_mask=None): + """ + Generate hidden states mask, and optionally an attention mask. + """ + alen = torch.arange(slen, dtype=torch.long, device=lengths.device) + if padding_mask is not None: + mask = padding_mask + else: + assert lengths.max().item() <= slen + mask = alen < lengths[:, None] + + # attention mask is the same as mask, or triangular inferior attention (causal) + bs = lengths.size(0) + if causal: + attn_mask = alen[None, None, :].repeat(bs, slen, 1) <= alen[None, :, None] + else: + attn_mask = mask + + # sanity check + assert mask.size() == (bs, slen) + assert causal is False or attn_mask.size() == (bs, slen, slen) + + return mask, attn_mask + + +class MultiHeadAttention(nn.Module): + NEW_ID = itertools.count() + + def __init__(self, n_heads, dim, config): + super().__init__() + self.layer_id = next(MultiHeadAttention.NEW_ID) + self.dim = dim + self.n_heads = n_heads + self.dropout = config.attention_dropout + assert self.dim % self.n_heads == 0 + + self.q_lin = nn.Linear(dim, dim) + self.k_lin = nn.Linear(dim, dim) + self.v_lin = nn.Linear(dim, dim) + self.out_lin = nn.Linear(dim, dim) + self.pruned_heads = set() + + def prune_heads(self, heads): + attention_head_size = self.dim // self.n_heads + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices(heads, self.n_heads, attention_head_size, self.pruned_heads) + # Prune linear layers + self.q_lin = prune_linear_layer(self.q_lin, index) + self.k_lin = prune_linear_layer(self.k_lin, index) + self.v_lin = prune_linear_layer(self.v_lin, index) + self.out_lin = prune_linear_layer(self.out_lin, index, dim=1) + # Update hyper params + self.n_heads = self.n_heads - len(heads) + self.dim = attention_head_size * self.n_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward(self, input, mask, kv=None, cache=None, head_mask=None, output_attentions=False): + """ + Self-attention (if kv is None) or attention over source sentence (provided by kv). + """ + # Input is (bs, qlen, dim) + # Mask is (bs, klen) (non-causal) or (bs, klen, klen) + bs, qlen, dim = input.size() + if kv is None: + klen = qlen if cache is None else cache["slen"] + qlen + else: + klen = kv.size(1) + # assert dim == self.dim, f'Dimensions do not match: {dim} input vs {self.dim} configured' + n_heads = self.n_heads + dim_per_head = self.dim // n_heads + mask_reshape = (bs, 1, qlen, klen) if mask.dim() == 3 else (bs, 1, 1, klen) + + def shape(x): + """projection""" + return x.view(bs, -1, self.n_heads, dim_per_head).transpose(1, 2) + + def unshape(x): + """compute context""" + return x.transpose(1, 2).contiguous().view(bs, -1, self.n_heads * dim_per_head) + + q = shape(self.q_lin(input)) # (bs, n_heads, qlen, dim_per_head) + if kv is None: + k = shape(self.k_lin(input)) # (bs, n_heads, qlen, dim_per_head) + v = shape(self.v_lin(input)) # (bs, n_heads, qlen, dim_per_head) + elif cache is None or self.layer_id not in cache: + k = v = kv + k = shape(self.k_lin(k)) # (bs, n_heads, qlen, dim_per_head) + v = shape(self.v_lin(v)) # (bs, n_heads, qlen, dim_per_head) + + if cache is not None: + if self.layer_id in cache: + if kv is None: + k_, v_ = cache[self.layer_id] + k = torch.cat([k_, k], dim=2) # (bs, n_heads, klen, dim_per_head) + v = torch.cat([v_, v], dim=2) # (bs, n_heads, klen, dim_per_head) + else: + k, v = cache[self.layer_id] + cache[self.layer_id] = (k, v) + + q = q / math.sqrt(dim_per_head) # (bs, n_heads, qlen, dim_per_head) + scores = torch.matmul(q, k.transpose(2, 3)) # (bs, n_heads, qlen, klen) + mask = (mask == 0).view(mask_reshape).expand_as(scores) # (bs, n_heads, qlen, klen) + scores.masked_fill_(mask, torch.finfo(scores.dtype).min) # (bs, n_heads, qlen, klen) + + weights = nn.functional.softmax(scores.float(), dim=-1).type_as(scores) # (bs, n_heads, qlen, klen) + weights = nn.functional.dropout(weights, p=self.dropout, training=self.training) # (bs, n_heads, qlen, klen) + + # Mask heads if we want to + if head_mask is not None: + weights = weights * head_mask + + context = torch.matmul(weights, v) # (bs, n_heads, qlen, dim_per_head) + context = unshape(context) # (bs, qlen, dim) + + outputs = (self.out_lin(context),) + if output_attentions: + outputs = outputs + (weights,) + return outputs + + +class TransformerFFN(nn.Module): + def __init__(self, in_dim, dim_hidden, out_dim, config): + super().__init__() + self.dropout = config.dropout + self.lin1 = nn.Linear(in_dim, dim_hidden) + self.lin2 = nn.Linear(dim_hidden, out_dim) + self.act = gelu if config.gelu_activation else nn.functional.relu + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + + def forward(self, input): + return apply_chunking_to_forward(self.ff_chunk, self.chunk_size_feed_forward, self.seq_len_dim, input) + + def ff_chunk(self, input): + x = self.lin1(input) + x = self.act(x) + x = self.lin2(x) + x = nn.functional.dropout(x, p=self.dropout, training=self.training) + return x + + +class XLMPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMConfig + load_tf_weights = None + base_model_prefix = "transformer" + + def __init__(self, *inputs, **kwargs): + super().__init__(*inputs, **kwargs) + + @property + def dummy_inputs(self): + inputs_list = torch.tensor([[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]]) + attns_list = torch.tensor([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]]) + if self.config.use_lang_emb and self.config.n_langs > 1: + langs_list = torch.tensor([[1, 1, 0, 0, 1], [1, 1, 1, 0, 0], [1, 0, 0, 1, 1]]) + else: + langs_list = None + return {"input_ids": inputs_list, "attention_mask": attns_list, "langs": langs_list} + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, nn.Embedding): + if self.config is not None and self.config.embed_init_std is not None: + nn.init.normal_(module.weight, mean=0, std=self.config.embed_init_std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + if isinstance(module, nn.Linear): + if self.config is not None and self.config.init_std is not None: + nn.init.normal_(module.weight, mean=0, std=self.config.init_std) + if module.bias is not None: + nn.init.constant_(module.bias, 0.0) + if isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +@dataclass +class XLMForQuestionAnsweringOutput(ModelOutput): + """ + Base class for outputs of question answering models using a `SquadHead`. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned if both `start_positions` and `end_positions` are provided): + Classification loss as the sum of start token, end token (and is_impossible if provided) classification + losses. + start_top_log_probs (`torch.FloatTensor` of shape `(batch_size, config.start_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the top config.start_n_top start token possibilities (beam-search). + start_top_index (`torch.LongTensor` of shape `(batch_size, config.start_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Indices for the top config.start_n_top start token possibilities (beam-search). + end_top_log_probs (`torch.FloatTensor` of shape `(batch_size, config.start_n_top * config.end_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the top `config.start_n_top * config.end_n_top` end token possibilities + (beam-search). + end_top_index (`torch.LongTensor` of shape `(batch_size, config.start_n_top * config.end_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Indices for the top `config.start_n_top * config.end_n_top` end token possibilities (beam-search). + cls_logits (`torch.FloatTensor` of shape `(batch_size,)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the `is_impossible` label of the answers. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + start_top_log_probs: Optional[torch.FloatTensor] = None + start_top_index: Optional[torch.LongTensor] = None + end_top_log_probs: Optional[torch.FloatTensor] = None + end_top_index: Optional[torch.LongTensor] = None + cls_logits: Optional[torch.FloatTensor] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +XLM_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`XLMConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + langs (`torch.LongTensor` of shape `({0})`, *optional*): + A parallel sequence of tokens to be used to indicate the language of each token in the input. Indices are + languages ids which can be obtained from the language names by using two conversion mappings provided in + the configuration of the model (only provided for multilingual models). More precisely, the *language name + to language id* mapping is in `model.config.lang2id` (which is a dictionary string to int) and the + *language id to language name* mapping is in `model.config.id2lang` (dictionary int to string). + + See usage examples detailed in the [multilingual documentation](../multilingual). + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + lengths (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Length of each sentence that can be used to avoid performing attention on padding token indices. You can + also use *attention_mask* for the same result (see above), kept here for compatibility. Indices selected in + `[0, ..., input_ids.size(-1)]`. + cache (`Dict[str, torch.FloatTensor]`, *optional*): + Dictionary string to `torch.FloatTensor` that contains precomputed hidden states (key and values in the + attention blocks) as computed by the model (see `cache` output below). Can be used to speed up sequential + decoding. + + The dictionary object will be modified in-place during the forward pass to add newly computed + hidden-states. + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare XLM Model transformer outputting raw hidden-states without any specific head on top.", + XLM_START_DOCSTRING, +) +class XLMModel(XLMPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + + # encoder / decoder, output layer + self.is_encoder = config.is_encoder + self.is_decoder = not config.is_encoder + if self.is_decoder: + raise NotImplementedError("Currently XLM can only be used as an encoder") + # self.with_output = with_output + self.causal = config.causal + + # dictionary / languages + self.n_langs = config.n_langs + self.use_lang_emb = config.use_lang_emb + self.n_words = config.n_words + self.eos_index = config.eos_index + self.pad_index = config.pad_index + # self.dico = dico + # self.id2lang = config.id2lang + # self.lang2id = config.lang2id + # assert len(self.dico) == self.n_words + # assert len(self.id2lang) == len(self.lang2id) == self.n_langs + + # model parameters + self.dim = config.emb_dim # 512 by default + self.hidden_dim = self.dim * 4 # 2048 by default + self.n_heads = config.n_heads # 8 by default + self.n_layers = config.n_layers + self.dropout = config.dropout + self.attention_dropout = config.attention_dropout + assert self.dim % self.n_heads == 0, "transformer dim must be a multiple of n_heads" + + # embeddings + self.position_embeddings = nn.Embedding(config.max_position_embeddings, self.dim) + if config.sinusoidal_embeddings: + create_sinusoidal_embeddings(config.max_position_embeddings, self.dim, out=self.position_embeddings.weight) + if config.n_langs > 1 and config.use_lang_emb: + self.lang_embeddings = nn.Embedding(self.n_langs, self.dim) + self.embeddings = nn.Embedding(self.n_words, self.dim, padding_idx=self.pad_index) + self.layer_norm_emb = nn.LayerNorm(self.dim, eps=config.layer_norm_eps) + + # transformer layers + self.attentions = nn.ModuleList() + self.layer_norm1 = nn.ModuleList() + self.ffns = nn.ModuleList() + self.layer_norm2 = nn.ModuleList() + # if self.is_decoder: + # self.layer_norm15 = nn.ModuleList() + # self.encoder_attn = nn.ModuleList() + + for _ in range(self.n_layers): + self.attentions.append(MultiHeadAttention(self.n_heads, self.dim, config=config)) + self.layer_norm1.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) + # if self.is_decoder: + # self.layer_norm15.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) + # self.encoder_attn.append(MultiHeadAttention(self.n_heads, self.dim, dropout=self.attention_dropout)) + self.ffns.append(TransformerFFN(self.dim, self.hidden_dim, self.dim, config=config)) + self.layer_norm2.append(nn.LayerNorm(self.dim, eps=config.layer_norm_eps)) + + if hasattr(config, "pruned_heads"): + pruned_heads = config.pruned_heads.copy().items() + config.pruned_heads = {} + for layer, heads in pruned_heads: + if self.attentions[int(layer)].n_heads == config.n_heads: + self.prune_heads({int(layer): list(map(int, heads))}) + + # Initialize weights and apply final processing + self.post_init() + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + + def get_input_embeddings(self): + return self.embeddings + + def set_input_embeddings(self, new_embeddings): + self.embeddings = new_embeddings + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.attentions[layer].prune_heads(heads) + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None: + bs, slen = input_ids.size() + else: + bs, slen = inputs_embeds.size()[:-1] + + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if lengths is None: + if input_ids is not None: + lengths = (input_ids != self.pad_index).sum(dim=1).long() + else: + lengths = torch.tensor([slen] * bs, device=device) + # mask = input_ids != self.pad_index + + # check inputs + assert lengths.size(0) == bs + assert lengths.max().item() <= slen + # input_ids = input_ids.transpose(0, 1) # batch size as dimension 0 + # assert (src_enc is None) == (src_len is None) + # if src_enc is not None: + # assert self.is_decoder + # assert src_enc.size(0) == bs + + # generate masks + mask, attn_mask = get_masks(slen, lengths, self.causal, padding_mask=attention_mask) + # if self.is_decoder and src_enc is not None: + # src_mask = torch.arange(src_len.max(), dtype=torch.long, device=lengths.device) < src_len[:, None] + + # position_ids + if position_ids is None: + position_ids = self.position_ids[:, :slen] + else: + assert position_ids.size() == (bs, slen) # (slen, bs) + # position_ids = position_ids.transpose(0, 1) + + # langs + if langs is not None: + assert langs.size() == (bs, slen) # (slen, bs) + # langs = langs.transpose(0, 1) + + # Prepare head mask if needed + head_mask = self.get_head_mask(head_mask, self.config.n_layers) + + # do not recompute cached elements + if cache is not None and input_ids is not None: + _slen = slen - cache["slen"] + input_ids = input_ids[:, -_slen:] + position_ids = position_ids[:, -_slen:] + if langs is not None: + langs = langs[:, -_slen:] + mask = mask[:, -_slen:] + attn_mask = attn_mask[:, -_slen:] + + # embeddings + if inputs_embeds is None: + inputs_embeds = self.embeddings(input_ids) + + tensor = inputs_embeds + self.position_embeddings(position_ids).expand_as(inputs_embeds) + if langs is not None and self.use_lang_emb and self.n_langs > 1: + tensor = tensor + self.lang_embeddings(langs) + if token_type_ids is not None: + tensor = tensor + self.embeddings(token_type_ids) + tensor = self.layer_norm_emb(tensor) + tensor = nn.functional.dropout(tensor, p=self.dropout, training=self.training) + tensor *= mask.unsqueeze(-1).to(tensor.dtype) + + # transformer layers + hidden_states = () if output_hidden_states else None + attentions = () if output_attentions else None + for i in range(self.n_layers): + if output_hidden_states: + hidden_states = hidden_states + (tensor,) + + # self attention + attn_outputs = self.attentions[i]( + tensor, + attn_mask, + cache=cache, + head_mask=head_mask[i], + output_attentions=output_attentions, + ) + attn = attn_outputs[0] + if output_attentions: + attentions = attentions + (attn_outputs[1],) + attn = nn.functional.dropout(attn, p=self.dropout, training=self.training) + tensor = tensor + attn + tensor = self.layer_norm1[i](tensor) + + # encoder attention (for decoder only) + # if self.is_decoder and src_enc is not None: + # attn = self.encoder_attn[i](tensor, src_mask, kv=src_enc, cache=cache) + # attn = nn.functional.dropout(attn, p=self.dropout, training=self.training) + # tensor = tensor + attn + # tensor = self.layer_norm15[i](tensor) + + # FFN + tensor = tensor + self.ffns[i](tensor) + tensor = self.layer_norm2[i](tensor) + tensor *= mask.unsqueeze(-1).to(tensor.dtype) + + # Add last hidden state + if output_hidden_states: + hidden_states = hidden_states + (tensor,) + + # update cache length + if cache is not None: + cache["slen"] += tensor.size(1) + + # move back sequence length to dimension 0 + # tensor = tensor.transpose(0, 1) + + if not return_dict: + return tuple(v for v in [tensor, hidden_states, attentions] if v is not None) + return BaseModelOutput(last_hidden_state=tensor, hidden_states=hidden_states, attentions=attentions) + + +class XLMPredLayer(nn.Module): + """ + Prediction layer (cross_entropy or adaptive_softmax). + """ + + def __init__(self, config): + super().__init__() + self.asm = config.asm + self.n_words = config.n_words + self.pad_index = config.pad_index + dim = config.emb_dim + + if config.asm is False: + self.proj = nn.Linear(dim, config.n_words, bias=True) + else: + self.proj = nn.AdaptiveLogSoftmaxWithLoss( + in_features=dim, + n_classes=config.n_words, + cutoffs=config.asm_cutoffs, + div_value=config.asm_div_value, + head_bias=True, # default is False + ) + + def forward(self, x, y=None): + """Compute the loss, and optionally the scores.""" + outputs = () + if self.asm is False: + scores = self.proj(x) + outputs = (scores,) + outputs + if y is not None: + loss = nn.functional.cross_entropy(scores.view(-1, self.n_words), y.view(-1), reduction="mean") + outputs = (loss,) + outputs + else: + scores = self.proj.log_prob(x) + outputs = (scores,) + outputs + if y is not None: + _, loss = self.proj(x, y) + outputs = (loss,) + outputs + + return outputs + + +@add_start_docstrings( + """ + The XLM Model transformer with a language modeling head on top (linear layer with weights tied to the input + embeddings). + """, + XLM_START_DOCSTRING, +) +class XLMWithLMHeadModel(XLMPreTrainedModel): + _keys_to_ignore_on_load_missing = ["pred_layer.proj.weight"] + + def __init__(self, config): + super().__init__(config) + self.transformer = XLMModel(config) + self.pred_layer = XLMPredLayer(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.pred_layer.proj + + def set_output_embeddings(self, new_embeddings): + self.pred_layer.proj = new_embeddings + + def prepare_inputs_for_generation(self, input_ids, **kwargs): + mask_token_id = self.config.mask_token_id + lang_id = self.config.lang_id + + effective_batch_size = input_ids.shape[0] + mask_token = torch.full((effective_batch_size, 1), mask_token_id, dtype=torch.long, device=input_ids.device) + input_ids = torch.cat([input_ids, mask_token], dim=1) + if lang_id is not None: + langs = torch.full_like(input_ids, lang_id) + else: + langs = None + return {"input_ids": input_ids, "langs": langs} + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="", + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set + `labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100` + are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]` + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + output = transformer_outputs[0] + outputs = self.pred_layer(output, labels) # (loss, logits) or (logits,) depending on if labels are provided. + + if not return_dict: + return outputs + transformer_outputs[1:] + + return MaskedLMOutput( + loss=outputs[0] if labels is not None else None, + logits=outputs[0] if labels is None else outputs[1], + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. + for GLUE tasks. + """, + XLM_START_DOCSTRING, +) +class XLMForSequenceClassification(XLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.transformer = XLMModel(config) + self.sequence_summary = SequenceSummary(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + output = transformer_outputs[0] + logits = self.sequence_summary(output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_START_DOCSTRING, +) +class XLMForQuestionAnsweringSimple(XLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.transformer = XLMModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = transformer_outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + transformer_outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Model with a beam-search span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_START_DOCSTRING, +) +class XLMForQuestionAnswering(XLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.transformer = XLMModel(config) + self.qa_outputs = SQuADHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=XLMForQuestionAnsweringOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + is_impossible: Optional[torch.Tensor] = None, + cls_index: Optional[torch.Tensor] = None, + p_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XLMForQuestionAnsweringOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + is_impossible (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels whether a question has an answer or no answer (SQuAD 2.0) + cls_index (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the classification token to use as input for computing plausibility of the + answer. + p_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Optional mask of tokens which can't be in answers (e.g. [CLS], [PAD], ...). 1.0 means token should be + masked. 0.0 mean token is not masked. + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMForQuestionAnswering + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("xlm-mlm-en-2048") + >>> model = XLMForQuestionAnswering.from_pretrained("xlm-mlm-en-2048") + + >>> input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze( + ... 0 + ... ) # Batch size 1 + >>> start_positions = torch.tensor([1]) + >>> end_positions = torch.tensor([3]) + + >>> outputs = model(input_ids, start_positions=start_positions, end_positions=end_positions) + >>> loss = outputs.loss + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + output = transformer_outputs[0] + + outputs = self.qa_outputs( + output, + start_positions=start_positions, + end_positions=end_positions, + cls_index=cls_index, + is_impossible=is_impossible, + p_mask=p_mask, + return_dict=return_dict, + ) + + if not return_dict: + return outputs + transformer_outputs[1:] + + return XLMForQuestionAnsweringOutput( + loss=outputs.loss, + start_top_log_probs=outputs.start_top_log_probs, + start_top_index=outputs.start_top_index, + end_top_log_probs=outputs.end_top_log_probs, + end_top_index=outputs.end_top_index, + cls_logits=outputs.cls_logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + XLM_START_DOCSTRING, +) +class XLMForTokenClassification(XLMPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.transformer = XLMModel(config) + self.dropout = nn.Dropout(config.dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_START_DOCSTRING, +) +class XLMForMultipleChoice(XLMPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.transformer = XLMModel(config) + self.sequence_summary = SequenceSummary(config) + self.logits_proj = nn.Linear(config.num_labels, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + langs: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + lengths: Optional[torch.Tensor] = None, + cache: Optional[Dict[str, torch.Tensor]] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + langs = langs.view(-1, langs.size(-1)) if langs is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + if lengths is not None: + logger.warning( + "The `lengths` parameter cannot be used with the XLM multiple choice models. Please use the " + "attention mask instead." + ) + lengths = None + + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + langs=langs, + token_type_ids=token_type_ids, + position_ids=position_ids, + lengths=lengths, + cache=cache, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + output = transformer_outputs[0] + logits = self.sequence_summary(output) + logits = self.logits_proj(logits) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/tokenization_xlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/tokenization_xlm.py new file mode 100644 index 0000000000000000000000000000000000000000..5cab4fc996793771ce250bb6aa67e75fb20f1ca3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm/tokenization_xlm.py @@ -0,0 +1,999 @@ +# coding=utf-8 +# Copyright 2019 The Open AI Team Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for XLM.""" + + +import json +import os +import re +import sys +import unicodedata +from typing import List, Optional, Tuple + +from ...tokenization_utils import PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = { + "vocab_file": "vocab.json", + "merges_file": "merges.txt", +} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "xlm-mlm-en-2048": "https://huggingface.co/xlm-mlm-en-2048/resolve/main/vocab.json", + "xlm-mlm-ende-1024": "https://huggingface.co/xlm-mlm-ende-1024/resolve/main/vocab.json", + "xlm-mlm-enfr-1024": "https://huggingface.co/xlm-mlm-enfr-1024/resolve/main/vocab.json", + "xlm-mlm-enro-1024": "https://huggingface.co/xlm-mlm-enro-1024/resolve/main/vocab.json", + "xlm-mlm-tlm-xnli15-1024": "https://huggingface.co/xlm-mlm-tlm-xnli15-1024/resolve/main/vocab.json", + "xlm-mlm-xnli15-1024": "https://huggingface.co/xlm-mlm-xnli15-1024/resolve/main/vocab.json", + "xlm-clm-enfr-1024": "https://huggingface.co/xlm-clm-enfr-1024/resolve/main/vocab.json", + "xlm-clm-ende-1024": "https://huggingface.co/xlm-clm-ende-1024/resolve/main/vocab.json", + "xlm-mlm-17-1280": "https://huggingface.co/xlm-mlm-17-1280/resolve/main/vocab.json", + "xlm-mlm-100-1280": "https://huggingface.co/xlm-mlm-100-1280/resolve/main/vocab.json", + }, + "merges_file": { + "xlm-mlm-en-2048": "https://huggingface.co/xlm-mlm-en-2048/resolve/main/merges.txt", + "xlm-mlm-ende-1024": "https://huggingface.co/xlm-mlm-ende-1024/resolve/main/merges.txt", + "xlm-mlm-enfr-1024": "https://huggingface.co/xlm-mlm-enfr-1024/resolve/main/merges.txt", + "xlm-mlm-enro-1024": "https://huggingface.co/xlm-mlm-enro-1024/resolve/main/merges.txt", + "xlm-mlm-tlm-xnli15-1024": "https://huggingface.co/xlm-mlm-tlm-xnli15-1024/resolve/main/merges.txt", + "xlm-mlm-xnli15-1024": "https://huggingface.co/xlm-mlm-xnli15-1024/resolve/main/merges.txt", + "xlm-clm-enfr-1024": "https://huggingface.co/xlm-clm-enfr-1024/resolve/main/merges.txt", + "xlm-clm-ende-1024": "https://huggingface.co/xlm-clm-ende-1024/resolve/main/merges.txt", + "xlm-mlm-17-1280": "https://huggingface.co/xlm-mlm-17-1280/resolve/main/merges.txt", + "xlm-mlm-100-1280": "https://huggingface.co/xlm-mlm-100-1280/resolve/main/merges.txt", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "xlm-mlm-en-2048": 512, + "xlm-mlm-ende-1024": 512, + "xlm-mlm-enfr-1024": 512, + "xlm-mlm-enro-1024": 512, + "xlm-mlm-tlm-xnli15-1024": 512, + "xlm-mlm-xnli15-1024": 512, + "xlm-clm-enfr-1024": 512, + "xlm-clm-ende-1024": 512, + "xlm-mlm-17-1280": 512, + "xlm-mlm-100-1280": 512, +} + +PRETRAINED_INIT_CONFIGURATION = { + "xlm-mlm-en-2048": {"do_lowercase_and_remove_accent": True}, + "xlm-mlm-ende-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": {0: "de", 1: "en"}, + "lang2id": {"de": 0, "en": 1}, + }, + "xlm-mlm-enfr-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": {0: "en", 1: "fr"}, + "lang2id": {"en": 0, "fr": 1}, + }, + "xlm-mlm-enro-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": {0: "en", 1: "ro"}, + "lang2id": {"en": 0, "ro": 1}, + }, + "xlm-mlm-tlm-xnli15-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": { + 0: "ar", + 1: "bg", + 2: "de", + 3: "el", + 4: "en", + 5: "es", + 6: "fr", + 7: "hi", + 8: "ru", + 9: "sw", + 10: "th", + 11: "tr", + 12: "ur", + 13: "vi", + 14: "zh", + }, + "lang2id": { + "ar": 0, + "bg": 1, + "de": 2, + "el": 3, + "en": 4, + "es": 5, + "fr": 6, + "hi": 7, + "ru": 8, + "sw": 9, + "th": 10, + "tr": 11, + "ur": 12, + "vi": 13, + "zh": 14, + }, + }, + "xlm-mlm-xnli15-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": { + 0: "ar", + 1: "bg", + 2: "de", + 3: "el", + 4: "en", + 5: "es", + 6: "fr", + 7: "hi", + 8: "ru", + 9: "sw", + 10: "th", + 11: "tr", + 12: "ur", + 13: "vi", + 14: "zh", + }, + "lang2id": { + "ar": 0, + "bg": 1, + "de": 2, + "el": 3, + "en": 4, + "es": 5, + "fr": 6, + "hi": 7, + "ru": 8, + "sw": 9, + "th": 10, + "tr": 11, + "ur": 12, + "vi": 13, + "zh": 14, + }, + }, + "xlm-clm-enfr-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": {0: "en", 1: "fr"}, + "lang2id": {"en": 0, "fr": 1}, + }, + "xlm-clm-ende-1024": { + "do_lowercase_and_remove_accent": True, + "id2lang": {0: "de", 1: "en"}, + "lang2id": {"de": 0, "en": 1}, + }, + "xlm-mlm-17-1280": { + "do_lowercase_and_remove_accent": False, + "id2lang": { + 0: "ar", + 1: "de", + 2: "en", + 3: "es", + 4: "fr", + 5: "hi", + 6: "it", + 7: "ja", + 8: "ko", + 9: "nl", + 10: "pl", + 11: "pt", + 12: "ru", + 13: "sv", + 14: "tr", + 15: "vi", + 16: "zh", + }, + "lang2id": { + "ar": 0, + "de": 1, + "en": 2, + "es": 3, + "fr": 4, + "hi": 5, + "it": 6, + "ja": 7, + "ko": 8, + "nl": 9, + "pl": 10, + "pt": 11, + "ru": 12, + "sv": 13, + "tr": 14, + "vi": 15, + "zh": 16, + }, + }, + "xlm-mlm-100-1280": { + "do_lowercase_and_remove_accent": False, + "id2lang": { + 0: "af", + 1: "als", + 2: "am", + 3: "an", + 4: "ang", + 5: "ar", + 6: "arz", + 7: "ast", + 8: "az", + 9: "bar", + 10: "be", + 11: "bg", + 12: "bn", + 13: "br", + 14: "bs", + 15: "ca", + 16: "ceb", + 17: "ckb", + 18: "cs", + 19: "cy", + 20: "da", + 21: "de", + 22: "el", + 23: "en", + 24: "eo", + 25: "es", + 26: "et", + 27: "eu", + 28: "fa", + 29: "fi", + 30: "fr", + 31: "fy", + 32: "ga", + 33: "gan", + 34: "gl", + 35: "gu", + 36: "he", + 37: "hi", + 38: "hr", + 39: "hu", + 40: "hy", + 41: "ia", + 42: "id", + 43: "is", + 44: "it", + 45: "ja", + 46: "jv", + 47: "ka", + 48: "kk", + 49: "kn", + 50: "ko", + 51: "ku", + 52: "la", + 53: "lb", + 54: "lt", + 55: "lv", + 56: "mk", + 57: "ml", + 58: "mn", + 59: "mr", + 60: "ms", + 61: "my", + 62: "nds", + 63: "ne", + 64: "nl", + 65: "nn", + 66: "no", + 67: "oc", + 68: "pl", + 69: "pt", + 70: "ro", + 71: "ru", + 72: "scn", + 73: "sco", + 74: "sh", + 75: "si", + 76: "simple", + 77: "sk", + 78: "sl", + 79: "sq", + 80: "sr", + 81: "sv", + 82: "sw", + 83: "ta", + 84: "te", + 85: "th", + 86: "tl", + 87: "tr", + 88: "tt", + 89: "uk", + 90: "ur", + 91: "uz", + 92: "vi", + 93: "war", + 94: "wuu", + 95: "yi", + 96: "zh", + 97: "zh_classical", + 98: "zh_min_nan", + 99: "zh_yue", + }, + "lang2id": { + "af": 0, + "als": 1, + "am": 2, + "an": 3, + "ang": 4, + "ar": 5, + "arz": 6, + "ast": 7, + "az": 8, + "bar": 9, + "be": 10, + "bg": 11, + "bn": 12, + "br": 13, + "bs": 14, + "ca": 15, + "ceb": 16, + "ckb": 17, + "cs": 18, + "cy": 19, + "da": 20, + "de": 21, + "el": 22, + "en": 23, + "eo": 24, + "es": 25, + "et": 26, + "eu": 27, + "fa": 28, + "fi": 29, + "fr": 30, + "fy": 31, + "ga": 32, + "gan": 33, + "gl": 34, + "gu": 35, + "he": 36, + "hi": 37, + "hr": 38, + "hu": 39, + "hy": 40, + "ia": 41, + "id": 42, + "is": 43, + "it": 44, + "ja": 45, + "jv": 46, + "ka": 47, + "kk": 48, + "kn": 49, + "ko": 50, + "ku": 51, + "la": 52, + "lb": 53, + "lt": 54, + "lv": 55, + "mk": 56, + "ml": 57, + "mn": 58, + "mr": 59, + "ms": 60, + "my": 61, + "nds": 62, + "ne": 63, + "nl": 64, + "nn": 65, + "no": 66, + "oc": 67, + "pl": 68, + "pt": 69, + "ro": 70, + "ru": 71, + "scn": 72, + "sco": 73, + "sh": 74, + "si": 75, + "simple": 76, + "sk": 77, + "sl": 78, + "sq": 79, + "sr": 80, + "sv": 81, + "sw": 82, + "ta": 83, + "te": 84, + "th": 85, + "tl": 86, + "tr": 87, + "tt": 88, + "uk": 89, + "ur": 90, + "uz": 91, + "vi": 92, + "war": 93, + "wuu": 94, + "yi": 95, + "zh": 96, + "zh_classical": 97, + "zh_min_nan": 98, + "zh_yue": 99, + }, + }, +} + + +def get_pairs(word): + """ + Return set of symbol pairs in a word. word is represented as tuple of symbols (symbols being variable-length + strings) + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +def lowercase_and_remove_accent(text): + """ + Lowercase and strips accents from a piece of text based on + https://github.com/facebookresearch/XLM/blob/master/tools/lowercase_and_remove_accent.py + """ + text = " ".join(text) + text = text.lower() + text = unicodedata.normalize("NFD", text) + output = [] + for char in text: + cat = unicodedata.category(char) + if cat == "Mn": + continue + output.append(char) + return "".join(output).lower().split(" ") + + +def replace_unicode_punct(text): + """ + Port of https://github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/replace-unicode-punctuation.perl + """ + text = text.replace(",", ",") + text = re.sub(r"。\s*", ". ", text) + text = text.replace("、", ",") + text = text.replace("”", '"') + text = text.replace("“", '"') + text = text.replace("∶", ":") + text = text.replace(":", ":") + text = text.replace("?", "?") + text = text.replace("《", '"') + text = text.replace("》", '"') + text = text.replace(")", ")") + text = text.replace("!", "!") + text = text.replace("(", "(") + text = text.replace(";", ";") + text = text.replace("1", "1") + text = text.replace("」", '"') + text = text.replace("「", '"') + text = text.replace("0", "0") + text = text.replace("3", "3") + text = text.replace("2", "2") + text = text.replace("5", "5") + text = text.replace("6", "6") + text = text.replace("9", "9") + text = text.replace("7", "7") + text = text.replace("8", "8") + text = text.replace("4", "4") + text = re.sub(r".\s*", ". ", text) + text = text.replace("~", "~") + text = text.replace("’", "'") + text = text.replace("…", "...") + text = text.replace("━", "-") + text = text.replace("〈", "<") + text = text.replace("〉", ">") + text = text.replace("【", "[") + text = text.replace("】", "]") + text = text.replace("%", "%") + return text + + +def remove_non_printing_char(text): + """ + Port of https://github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/remove-non-printing-char.perl + """ + output = [] + for char in text: + cat = unicodedata.category(char) + if cat.startswith("C"): + continue + output.append(char) + return "".join(output) + + +def romanian_preprocessing(text): + """Sennrich's WMT16 scripts for Romanian preprocessing, used by model `xlm-mlm-enro-1024`""" + # https://github.com/rsennrich/wmt16-scripts/blob/master/preprocess/normalise-romanian.py + text = text.replace("\u015e", "\u0218").replace("\u015f", "\u0219") + text = text.replace("\u0162", "\u021a").replace("\u0163", "\u021b") + # https://github.com/rsennrich/wmt16-scripts/blob/master/preprocess/remove-diacritics.py + text = text.replace("\u0218", "S").replace("\u0219", "s") # s-comma + text = text.replace("\u021a", "T").replace("\u021b", "t") # t-comma + text = text.replace("\u0102", "A").replace("\u0103", "a") + text = text.replace("\u00C2", "A").replace("\u00E2", "a") + text = text.replace("\u00CE", "I").replace("\u00EE", "i") + return text + + +class XLMTokenizer(PreTrainedTokenizer): + """ + Construct an XLM tokenizer. Based on Byte-Pair Encoding. The tokenization process is the following: + + - Moses preprocessing and tokenization for most supported languages. + - Language specific tokenization for Chinese (Jieba), Japanese (KyTea) and Thai (PyThaiNLP). + - Optionally lowercases and normalizes all inputs text. + - The arguments `special_tokens` and the function `set_special_tokens`, can be used to add additional symbols (like + "__classify__") to a vocabulary. + - The `lang2id` attribute maps the languages supported by the model with their IDs if provided (automatically set + for pretrained vocabularies). + - The `id2lang` attributes does reverse mapping if provided (automatically set for pretrained vocabularies). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Vocabulary file. + merges_file (`str`): + Merges file. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["","","","","","","","","",""]`): + List of additional special tokens. + lang2id (`Dict[str, int]`, *optional*): + Dictionary mapping languages string identifiers to their IDs. + id2lang (`Dict[int, str]`, *optional*): + Dictionary mapping language IDs to their string identifiers. + do_lowercase_and_remove_accent (`bool`, *optional*, defaults to `True`): + Whether to lowercase and remove accents when tokenizing. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + + def __init__( + self, + vocab_file, + merges_file, + unk_token="", + bos_token="", + sep_token="", + pad_token="", + cls_token="", + mask_token="", + additional_special_tokens=[ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ], + lang2id=None, + id2lang=None, + do_lowercase_and_remove_accent=True, + **kwargs, + ): + super().__init__( + unk_token=unk_token, + bos_token=bos_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + additional_special_tokens=additional_special_tokens, + lang2id=lang2id, + id2lang=id2lang, + do_lowercase_and_remove_accent=do_lowercase_and_remove_accent, + **kwargs, + ) + + try: + import sacremoses + except ImportError: + raise ImportError( + "You need to install sacremoses to use XLMTokenizer. " + "See https://pypi.org/project/sacremoses/ for installation." + ) + + self.sm = sacremoses + + # cache of sm.MosesPunctNormalizer instance + self.cache_moses_punct_normalizer = {} + # cache of sm.MosesTokenizer instance + self.cache_moses_tokenizer = {} + self.lang_with_custom_tokenizer = {"zh", "th", "ja"} + # True for current supported model (v1.2.0), False for XLM-17 & 100 + self.do_lowercase_and_remove_accent = do_lowercase_and_remove_accent + self.lang2id = lang2id + self.id2lang = id2lang + if lang2id is not None and id2lang is not None: + assert len(lang2id) == len(id2lang) + + self.ja_word_tokenizer = None + self.zh_word_tokenizer = None + + with open(vocab_file, encoding="utf-8") as vocab_handle: + self.encoder = json.load(vocab_handle) + self.decoder = {v: k for k, v in self.encoder.items()} + with open(merges_file, encoding="utf-8") as merges_handle: + merges = merges_handle.read().split("\n")[:-1] + merges = [tuple(merge.split()[:2]) for merge in merges] + self.bpe_ranks = dict(zip(merges, range(len(merges)))) + self.cache = {} + + @property + def do_lower_case(self): + return self.do_lowercase_and_remove_accent + + def moses_punct_norm(self, text, lang): + if lang not in self.cache_moses_punct_normalizer: + punct_normalizer = self.sm.MosesPunctNormalizer(lang=lang) + self.cache_moses_punct_normalizer[lang] = punct_normalizer + else: + punct_normalizer = self.cache_moses_punct_normalizer[lang] + return punct_normalizer.normalize(text) + + def moses_tokenize(self, text, lang): + if lang not in self.cache_moses_tokenizer: + moses_tokenizer = self.sm.MosesTokenizer(lang=lang) + self.cache_moses_tokenizer[lang] = moses_tokenizer + else: + moses_tokenizer = self.cache_moses_tokenizer[lang] + return moses_tokenizer.tokenize(text, return_str=False, escape=False) + + def moses_pipeline(self, text, lang): + text = replace_unicode_punct(text) + text = self.moses_punct_norm(text, lang) + text = remove_non_printing_char(text) + return text + + def ja_tokenize(self, text): + if self.ja_word_tokenizer is None: + try: + import Mykytea + + self.ja_word_tokenizer = Mykytea.Mykytea( + f"-model {os.path.expanduser('~')}/local/share/kytea/model.bin" + ) + except (AttributeError, ImportError): + logger.error( + "Make sure you install KyTea (https://github.com/neubig/kytea) and it's python wrapper" + " (https://github.com/chezou/Mykytea-python) with the following steps" + ) + logger.error("1. git clone git@github.com:neubig/kytea.git && cd kytea") + logger.error("2. autoreconf -i") + logger.error("3. ./configure --prefix=$HOME/local") + logger.error("4. make && make install") + logger.error("5. pip install kytea") + raise + return list(self.ja_word_tokenizer.getWS(text)) + + @property + def vocab_size(self): + return len(self.encoder) + + def get_vocab(self): + return dict(self.encoder, **self.added_tokens_encoder) + + def bpe(self, token): + word = tuple(token[:-1]) + (token[-1] + "",) + if token in self.cache: + return self.cache[token] + pairs = get_pairs(word) + + if not pairs: + return token + "" + + while True: + bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf"))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + except ValueError: + new_word.extend(word[i:]) + break + else: + new_word.extend(word[i:j]) + i = j + + if word[i] == first and i < len(word) - 1 and word[i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = " ".join(word) + if word == "\n ": + word = "\n" + self.cache[token] = word + return word + + def _tokenize(self, text, lang="en", bypass_tokenizer=False): + """ + Tokenize a string given language code. For Chinese, Japanese and Thai, we use a language specific tokenizer. + Otherwise, we use Moses. + + Details of tokenization: + + - [sacremoses](https://github.com/alvations/sacremoses): port of Moses + - Install with `pip install sacremoses` + - [pythainlp](https://github.com/PyThaiNLP/pythainlp): Thai tokenizer + - Install with `pip install pythainlp` + - [kytea](https://github.com/chezou/Mykytea-python): Japanese tokenizer, wrapper of + [KyTea](https://github.com/neubig/kytea) + - Install with the following steps: + + :: + + git clone git@github.com:neubig/kytea.git && cd kytea autoreconf -i ./configure --prefix=$HOME/local + make && make install pip install kytea + + - [jieba](https://github.com/fxsjy/jieba): Chinese tokenizer (*) + - Install with `pip install jieba` + + (*) The original XLM used [Stanford + Segmenter](https://nlp.stanford.edu/software/stanford-segmenter-2018-10-16.zip). However, the wrapper + (`nltk.tokenize.stanford_segmenter`) is slow due to JVM overhead, and it will be deprecated. Jieba is a lot + faster and pip-installable. Note there is some mismatch with the Stanford Segmenter. It should be fine if you + fine-tune the model with Chinese supervisionself. If you want the same exact behaviour, use the original XLM + [preprocessing script](https://github.com/facebookresearch/XLM/tree/master/tools) to tokenize the sentence + externally, and set `bypass_tokenizer=True` to bypass the tokenizer. + + Args: + - lang: ISO language code (default = 'en') (string). Languages should belong of the model supported + languages. However, we don't enforce it. + - bypass_tokenizer: Allow users to preprocess and tokenize the sentences externally (default = False) + (bool). If True, we only apply BPE. + + Returns: + List of tokens. + """ + if lang and self.lang2id and lang not in self.lang2id: + logger.error( + "Supplied language code not found in lang2id mapping. Please check that your language is supported by" + " the loaded pretrained model." + ) + if bypass_tokenizer: + text = text.split() + elif lang not in self.lang_with_custom_tokenizer: + text = self.moses_pipeline(text, lang=lang) + # TODO: make sure we are using `xlm-mlm-enro-1024`, since XLM-100 doesn't have this step + if lang == "ro": + text = romanian_preprocessing(text) + text = self.moses_tokenize(text, lang=lang) + elif lang == "th": + text = self.moses_pipeline(text, lang=lang) + try: + if "pythainlp" not in sys.modules: + from pythainlp.tokenize import word_tokenize as th_word_tokenize + else: + th_word_tokenize = sys.modules["pythainlp"].word_tokenize + except (AttributeError, ImportError): + logger.error( + "Make sure you install PyThaiNLP (https://github.com/PyThaiNLP/pythainlp) with the following steps" + ) + logger.error("1. pip install pythainlp") + raise + text = th_word_tokenize(text) + elif lang == "zh": + try: + if "jieba" not in sys.modules: + import jieba + else: + jieba = sys.modules["jieba"] + except (AttributeError, ImportError): + logger.error("Make sure you install Jieba (https://github.com/fxsjy/jieba) with the following steps") + logger.error("1. pip install jieba") + raise + text = " ".join(jieba.cut(text)) + text = self.moses_pipeline(text, lang=lang) + text = text.split() + elif lang == "ja": + text = self.moses_pipeline(text, lang=lang) + text = self.ja_tokenize(text) + else: + raise ValueError("It should not reach here") + + if self.do_lowercase_and_remove_accent and not bypass_tokenizer: + text = lowercase_and_remove_accent(text) + + split_tokens = [] + for token in text: + if token: + split_tokens.extend(list(self.bpe(token).split(" "))) + + return split_tokens + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.encoder.get(token, self.encoder.get(self.unk_token)) + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.decoder.get(index, self.unk_token) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (string) in a single string.""" + out_string = "".join(tokens).replace("", " ").strip() + return out_string + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLM sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + + """ + bos = [self.bos_token_id] + sep = [self.sep_token_id] + + if token_ids_1 is None: + return bos + token_ids_0 + sep + return bos + token_ids_0 + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. An XLM sequence + pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + merge_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"] + ) + + with open(vocab_file, "w", encoding="utf-8") as f: + f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n") + + index = 0 + with open(merge_file, "w", encoding="utf-8") as writer: + for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]): + if index != token_index: + logger.warning( + f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive." + " Please check that the tokenizer is not corrupted!" + ) + index = token_index + writer.write(" ".join(bpe_tokens) + "\n") + index += 1 + + return vocab_file, merge_file + + def __getstate__(self): + state = self.__dict__.copy() + state["sm"] = None + return state + + def __setstate__(self, d): + self.__dict__ = d + + try: + import sacremoses + except ImportError: + raise ImportError( + "You need to install sacremoses to use XLMTokenizer. " + "See https://pypi.org/project/sacremoses/ for installation." + ) + + self.sm = sacremoses diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ff14e5b987a789c86f3ca37e11d79afe540a177e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/__init__.py @@ -0,0 +1,78 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_sentencepiece_available, is_torch_available + + +_import_structure = { + "configuration_xlm_prophetnet": ["XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP", "XLMProphetNetConfig"], +} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xlm_prophetnet"] = ["XLMProphetNetTokenizer"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xlm_prophetnet"] = [ + "XLM_PROPHETNET_PRETRAINED_MODEL_ARCHIVE_LIST", + "XLMProphetNetDecoder", + "XLMProphetNetEncoder", + "XLMProphetNetForCausalLM", + "XLMProphetNetForConditionalGeneration", + "XLMProphetNetModel", + "XLMProphetNetPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_xlm_prophetnet import XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP, XLMProphetNetConfig + + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xlm_prophetnet import XLMProphetNetTokenizer + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xlm_prophetnet import ( + XLM_PROPHETNET_PRETRAINED_MODEL_ARCHIVE_LIST, + XLMProphetNetDecoder, + XLMProphetNetEncoder, + XLMProphetNetForCausalLM, + XLMProphetNetForConditionalGeneration, + XLMProphetNetModel, + XLMProphetNetPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/configuration_xlm_prophetnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/configuration_xlm_prophetnet.py new file mode 100644 index 0000000000000000000000000000000000000000..29c8678f279981321b945d07b411261cfb010233 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/configuration_xlm_prophetnet.py @@ -0,0 +1,184 @@ +# coding=utf-8 +# Copyright 2020 The Microsoft Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XLM-ProphetNet model configuration""" + + +from typing import Callable, Optional, Union + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "microsoft/xprophetnet-large-wiki100-cased": ( + "https://huggingface.co/microsoft/xprophetnet-large-wiki100-cased/resolve/main/config.json" + ), +} + + +class XLMProphetNetConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XLMProphetNetModel`]. It is used to instantiate a + XLMProphetNet model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the XLMProphetNet + [microsoft/xprophetnet-large-wiki100-cased](https://huggingface.co/microsoft/xprophetnet-large-wiki100-cased) + architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + activation_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for activations inside the fully connected layer. + activation_function (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the ProphetNET model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`XLMProphetNetModel`]. + hidden_size (`int`, *optional*, defaults to 1024): + Dimensionality of the layers and the pooler layer. + encoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimensionality of the "intermediate" (often named feed-forward) layer in decoder. + num_encoder_layers (`int`, *optional*, defaults to 12): + Number of encoder layers. + num_encoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimensionality of the `intermediate` (often named feed-forward) layer in decoder. + num_decoder_layers (`int`, *optional*, defaults to 12): + Number of decoder layers. + num_decoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer decoder. + attention_dropout (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + add_cross_attention (`bool`, *optional*, defaults to `True`): + Whether cross-attention layers should be added to the model. + is_encoder_decoder (`bool`, *optional*, defaults to `True`): + Whether this is an encoder/decoder model. + pad_token_id (`int`, *optional*, defaults to 1) + Padding token id. + bos_token_id (`int`, *optional*, defaults to 0) + Beginning of stream token id. + eos_token_id (`int`, *optional*, defaults to 2) + End of stream token id. + ngram (`int`, *optional*, defaults to 2) + Number of future tokens to predict. Set to 1 to be same as traditional Language model to predict next first + token. + num_buckets (`int`, *optional*, defaults to 32) + The number of buckets to use for each attention layer. This is for relative position calculation. See the + [T5 paper](see https://arxiv.org/abs/1910.10683) for more details. + relative_max_distance (`int`, *optional*, defaults to 128) + Relative distances greater than this number will be put into the last same bucket. This is for relative + position calculation. See the [T5 paper](see https://arxiv.org/abs/1910.10683) for more details. + disable_ngram_loss (`bool`, *optional*, defaults to `False`): + Whether be trained predicting only the next first token. + eps (`float`, *optional*, defaults to 0.0): + Controls the `epsilon` parameter value for label smoothing in the loss calculation. If set to 0, no label + smoothing is performed. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + """ + model_type = "xlm-prophetnet" + keys_to_ignore_at_inference = ["past_key_values"] + attribute_map = { + "num_attention_heads": "num_encoder_attention_heads", + } + + def __init__( + self, + activation_dropout: Optional[float] = 0.1, + activation_function: Optional[Union[str, Callable]] = "gelu", + vocab_size: Optional[int] = 30522, + hidden_size: Optional[int] = 1024, + encoder_ffn_dim: Optional[int] = 4096, + num_encoder_layers: Optional[int] = 12, + num_encoder_attention_heads: Optional[int] = 16, + decoder_ffn_dim: Optional[int] = 4096, + num_decoder_layers: Optional[int] = 12, + num_decoder_attention_heads: Optional[int] = 16, + attention_dropout: Optional[float] = 0.1, + dropout: Optional[float] = 0.1, + max_position_embeddings: Optional[int] = 512, + init_std: Optional[float] = 0.02, + is_encoder_decoder: Optional[bool] = True, + add_cross_attention: Optional[bool] = True, + decoder_start_token_id: Optional[int] = 0, + ngram: Optional[int] = 2, + num_buckets: Optional[int] = 32, + relative_max_distance: Optional[int] = 128, + disable_ngram_loss: Optional[bool] = False, + eps: Optional[float] = 0.0, + use_cache: Optional[bool] = True, + pad_token_id: Optional[int] = 0, + bos_token_id: Optional[int] = 1, + eos_token_id: Optional[int] = 2, + **kwargs, + ): + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.encoder_ffn_dim = encoder_ffn_dim + self.num_encoder_layers = num_encoder_layers + self.num_encoder_attention_heads = num_encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.num_decoder_layers = num_decoder_layers + self.num_decoder_attention_heads = num_decoder_attention_heads + self.max_position_embeddings = max_position_embeddings + self.init_std = init_std # Normal(0, this parameter) + self.activation_function = activation_function + + # parameters for xlmprophetnet + self.ngram = ngram + self.num_buckets = num_buckets + self.relative_max_distance = relative_max_distance + self.disable_ngram_loss = disable_ngram_loss + self.eps = eps + + # 3 Types of Dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.dropout = dropout + + self.use_cache = use_cache + + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + is_encoder_decoder=is_encoder_decoder, + add_cross_attention=add_cross_attention, + decoder_start_token_id=decoder_start_token_id, + **kwargs, + ) + + @property + def num_hidden_layers(self) -> int: + return self.num_encoder_layers + self.num_decoder_layers + + @num_hidden_layers.setter + def num_hidden_layers(self, value): + raise NotImplementedError( + "This model does not support the setting of `num_hidden_layers`. Please set `num_encoder_layers` and" + " `num_decoder_layers`." + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/modeling_xlm_prophetnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/modeling_xlm_prophetnet.py new file mode 100644 index 0000000000000000000000000000000000000000..0e2567f99c9b1658abbbb3aa14f193eade37a042 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/modeling_xlm_prophetnet.py @@ -0,0 +1,2363 @@ +# coding=utf-8 +# Copyright 2020 The Microsoft Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch XLM-ProphetNet model.""" + + +import copy +import math +import warnings +from dataclasses import dataclass +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import Tensor, nn +from torch.nn import LayerNorm + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput +from ...modeling_utils import PreTrainedModel +from ...utils import ( + ModelOutput, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlm_prophetnet import XLMProphetNetConfig + + +logger = logging.get_logger(__name__) + + +_CONFIG_FOR_DOC = "XLMProphetNetConfig" + +XLM_PROPHETNET_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "microsoft/xprophetnet-large-wiki100-cased", + # See all XLMProphetNet models at https://huggingface.co/models?filter=xprophetnet +] + +# Copied from src.transformers.models.prophetnet.modeling_prophetnet.PROPHETNET_START_DOCSTRING with ProphetNetConfig->XLMProphetNetConfig +XLM_PROPHETNET_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + Original ProphetNet code can be found [here](https://github.com/microsoft/ProphetNet). Checkpoints were converted + from original Fairseq checkpoints. For more information on the checkpoint conversion, please take a look at the + file `convert_prophetnet_original_pytorch_checkpoint_to_pytorch.py`. + + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matters related to general usage and + behavior. + + Parameters: + config ([`XLMProphetNetConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +# Copied from src.transformers.models.prophetnet.modeling_prophetnet.PROPHETNET_INPUTS_DOCSTRING with ProphetNet->XLMProphetNet +XLM_PROPHETNET_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Indices of decoder input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are decoder input IDs?](../glossary#decoder-input-ids) + + XLMProphetNet uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If + `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see + `past_key_values`). + + decoder_attention_mask (`torch.BoolTensor` of shape `(batch_size, target_sequence_length)`, *optional*): + Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also + be used by default. + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + decoder_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the decoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*): + Tuple consists of (`last_hidden_state`, *optional*: `hidden_states`, *optional*: `attentions`) + `last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)`, *optional*) is a sequence of + hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder. + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from src.transformers.models.prophetnet.modeling_prophetnet.PROPHETNET_STANDALONE_INPUTS_DOCSTRING with ProphetNet->XLMProphetNet +XLM_PROPHETNET_STANDALONE_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + head_mask (`torch.Tensor` of shape `(encoder_layers, encoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the attention modules in the encoder. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.softmax +def softmax(hidden_state, dim, onnx_trace=False): + if onnx_trace: + return nn.functional.softmax(hidden_state.float(), dim=dim) + else: + return nn.functional.softmax(hidden_state, dim=dim, dtype=torch.float32) + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ngram_attention_bias +def ngram_attention_bias(sequence_length, ngram, device, dtype): + """ + This function computes the bias for the predict stream + """ + left_block = ( + torch.ones((ngram, sequence_length, sequence_length), device=device, dtype=dtype) * torch.finfo(dtype).min + ) + right_block = left_block.detach().clone() + # create bias + for stream_idx in range(ngram): + right_block[stream_idx].fill_diagonal_(0, wrap=False) + left_block[stream_idx].triu_(-stream_idx + 1) + + left_block[:, :, 0] = 0 + return torch.cat([left_block, right_block], dim=2) + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.compute_relative_buckets +def compute_relative_buckets(num_buckets, max_distance, relative_positions, is_bidirectional=False): + """ + This function computes individual parts of the relative position buckets. For more detail, see paper. + """ + inv_relative_positions = -relative_positions + rel_positions_bucket = 0 + + if is_bidirectional: + num_buckets = num_buckets // 2 + rel_positions_bucket = ( + rel_positions_bucket + + torch.lt(inv_relative_positions, torch.zeros_like(inv_relative_positions)).int() * num_buckets + ) + inv_relative_positions = torch.abs(inv_relative_positions) + else: + inv_relative_positions = torch.max(inv_relative_positions, torch.zeros_like(inv_relative_positions)) + + max_exact = num_buckets // 2 + is_small = torch.lt(inv_relative_positions, max_exact) + val_if_large = max_exact + torch.log(inv_relative_positions.float() / max_exact) / math.log( + max_distance / max_exact + ) * (num_buckets - max_exact) + val_if_large = torch.min(val_if_large, torch.ones_like(val_if_large) * (num_buckets - 1)).int() + rel_positions_bucket = rel_positions_bucket + torch.where(is_small, inv_relative_positions.int(), val_if_large) + return rel_positions_bucket + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.compute_all_stream_relative_buckets +def compute_all_stream_relative_buckets(num_buckets, max_distance, position_ids): + """ + This function computes both main and predict relative position buckets. For more detail, see paper. + """ + # main stream + main_stream_relative_positions = position_ids.unsqueeze(1).repeat(1, position_ids.size(-1), 1) + main_stream_relative_positions = main_stream_relative_positions - position_ids.unsqueeze(-1) + + # predicting stream + predicting_stream_relative_positions = torch.cat((position_ids - 1, position_ids), dim=-1).unsqueeze(1) + predicting_stream_relative_positions = predicting_stream_relative_positions.repeat(1, position_ids.size(-1), 1) + predicting_stream_relative_positions = predicting_stream_relative_positions - position_ids.unsqueeze(-1) + + # get both position buckets + main_relative_position_buckets = compute_relative_buckets( + num_buckets, max_distance, main_stream_relative_positions, is_bidirectional=False + ) + predict_relative_position_buckets = compute_relative_buckets( + num_buckets, max_distance, predicting_stream_relative_positions, is_bidirectional=False + ) + return main_relative_position_buckets, predict_relative_position_buckets + + +@dataclass +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetSeq2SeqLMOutput with ProphetNet->XLMProphetNet all-casing +class XLMProphetNetSeq2SeqLMOutput(ModelOutput): + """ + Base class for sequence-to-sequence language models outputs. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss. + logits (`torch.FloatTensor` of shape `(batch_size, decoder_sequence_length, config.vocab_size)`): + Prediction scores of the main stream language modeling head (scores for each vocabulary token before + SoftMax). + logits_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): + Prediction scores of the predict stream language modeling head (scores for each vocabulary token before + SoftMax). + past_key_values (`List[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, + num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + + Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be + used (see `past_key_values` input) to speed up sequential decoding. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, decoder_sequence_length, hidden_size)`. + + Hidden-states of main stream of the decoder at the output of each layer plus the initial embedding outputs. + decoder_ngram_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, ngram * decoder_sequence_length, hidden_size)`. + + Hidden-states of the predict stream of the decoder at the output of each layer plus the initial embedding + outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + decoder_ngram_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the predict stream of the decoder, after the attention softmax, used to compute the + weighted average in the self-attention heads. + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the cross-attention layer of the decoder, after the attention softmax, used to + compute the weighted average in the + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, encoder_sequence_length, hidden_size)`. + + Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, encoder_sequence_length)`. Attentions weights of the encoder, after the attention + softmax, used to compute the weighted average in the self-attention heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + logits_ngram: Optional[torch.FloatTensor] = None + past_key_values: Optional[Tuple[torch.FloatTensor]] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_ngram_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + decoder_ngram_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + + @property + def decoder_cross_attentions(self): + warnings.warn( + "`decoder_cross_attentions` is deprecated and will be removed soon. Please use `cross_attentions`" + " instead.", + FutureWarning, + ) + return self.cross_attentions + + +@dataclass +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetSeq2SeqModelOutput with ProphetNet->XLMProphetNet all-casing +class XLMProphetNetSeq2SeqModelOutput(ModelOutput): + """ + Base class for model encoder's outputs that also contains : pre-computed hidden states that can speed up sequential + decoding. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, decoder_sequence_length, hidden_size)`): + Sequence of main stream hidden-states at the output of the last layer of the decoder of the model. + + If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, + hidden_size)` is output. + last_hidden_state_ngram (`torch.FloatTensor` of shape `(batch_size,ngram * decoder_sequence_length, config.vocab_size)`, *optional*): + Sequence of predict stream hidden-states at the output of the last layer of the decoder of the model. + past_key_values (`List[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, + num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + + Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be + used (see `past_key_values` input) to speed up sequential decoding. + decoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, decoder_sequence_length, hidden_size)`. + + Hidden-states of main stream of the decoder at the output of each layer plus the initial embedding outputs. + decoder_ngram_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, ngram * decoder_sequence_length, hidden_size)`. + + Hidden-states of the predict stream of the decoder at the output of each layer plus the initial embedding + outputs. + decoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + decoder_ngram_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the predict stream of the decoder, after the attention softmax, used to compute the + weighted average in the + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the cross-attention layer of the decoder, after the attention softmax, used to + compute the weighted average in the + encoder_last_hidden_state (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder of the model. + encoder_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, encoder_sequence_length, hidden_size)`. + + Hidden-states of the encoder at the output of each layer plus the initial embedding outputs. + encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, encoder_sequence_length)`. + + Attentions weights of the encoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + """ + + last_hidden_state: torch.FloatTensor + last_hidden_state_ngram: Optional[torch.FloatTensor] = None + past_key_values: Optional[Tuple[torch.FloatTensor]] = None + decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_ngram_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + decoder_ngram_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + encoder_last_hidden_state: Optional[torch.FloatTensor] = None + encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None + encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None + + @property + def decoder_cross_attentions(self): + warnings.warn( + "`decoder_cross_attentions` is deprecated and will be removed soon. Please use `cross_attentions`" + " instead.", + FutureWarning, + ) + return self.cross_attentions + + +@dataclass +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetDecoderModelOutput with ProphetNet->XLMProphetNet all-casing +class XLMProphetNetDecoderModelOutput(ModelOutput): + """ + Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, decoder_sequence_length, hidden_size)`): + Sequence of main stream hidden-states at the output of the last layer of the decoder of the model. + + If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1, + hidden_size)` is output. + last_hidden_state_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): + Sequence of predict stream hidden-states at the output of the last layer of the decoder of the model. + past_key_values (`List[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, + num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + + Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be + used (see `past_key_values` input) to speed up sequential decoding. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, decoder_sequence_length, hidden_size)`. + + Hidden-states of main stream of the decoder at the output of each layer plus the initial embedding outputs. + ngram_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, ngram * decoder_sequence_length, hidden_size)`. + + Hidden-states of the predict stream of the decoder at the output of each layer plus the initial embedding + outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + ngram_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the predict stream of the decoder, after the attention softmax, used to compute the + weighted average in the + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the cross-attention layer of the decoder, after the attention softmax, used to + compute the weighted average in the + """ + + last_hidden_state: torch.FloatTensor + last_hidden_state_ngram: Optional[torch.FloatTensor] = None + past_key_values: Optional[Tuple[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + hidden_states_ngram: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + ngram_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetDecoderLMOutput with ProphetNet->XLMProphetNet all-casing +class XLMProphetNetDecoderLMOutput(ModelOutput): + """ + Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding). + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss. + logits (`torch.FloatTensor` of shape `(batch_size, decoder_sequence_length, config.vocab_size)`): + Prediction scores of the main stream language modeling head (scores for each vocabulary token before + SoftMax). + logits_ngram (`torch.FloatTensor` of shape `(batch_size, ngram * decoder_sequence_length, config.vocab_size)`): + Prediction scores of the predict stream language modeling head (scores for each vocabulary token before + SoftMax). + past_key_values (`List[torch.FloatTensor]`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + List of `torch.FloatTensor` of length `config.n_layers`, with each tensor of shape `(2, batch_size, + num_attn_heads, decoder_sequence_length, embed_size_per_head)`). + + Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be + used (see `past_key_values` input) to speed up sequential decoding. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, decoder_sequence_length, hidden_size)`. + + Hidden-states of main stream of the decoder at the output of each layer plus the initial embedding outputs. + ngram_hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, ngram * decoder_sequence_length, hidden_size)`. + + Hidden-states of the predict stream of the decoder at the output of each layer plus the initial embedding + outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the + self-attention heads. + ngram_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + decoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the predict stream of the decoder, after the attention softmax, used to compute the + weighted average in the + cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_attn_heads, + encoder_sequence_length, decoder_sequence_length)`. + + Attentions weights of the cross-attention layer of the decoder, after the attention softmax, used to + compute the weighted average in the + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + logits_ngram: Optional[torch.FloatTensor] = None + past_key_values: Optional[Tuple[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + hidden_states_ngram: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + ngram_attentions: Optional[Tuple[torch.FloatTensor]] = None + cross_attentions: Optional[Tuple[torch.FloatTensor]] = None + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetPreTrainedModel with ProphetNet->XLMProphetNet +class XLMProphetNetPreTrainedModel(PreTrainedModel): + config_class = XLMProphetNetConfig + base_model_prefix = "prophetnet" + supports_gradient_checkpointing = True + + def _init_weights(self, module): + if isinstance(module, nn.Linear): + module.weight.data.normal_(mean=0.0, std=self.config.init_std) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.init_std) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (XLMProphetNetDecoder, XLMProphetNetEncoder)): + module.gradient_checkpointing = value + + def _shift_right(self, input_ids): + decoder_start_token_id = self.config.decoder_start_token_id + pad_token_id = self.config.pad_token_id + + assert decoder_start_token_id is not None, ( + "self.model.config.decoder_start_token_id has to be defined. In XLMProphetNet it is usually set to the" + " pad_token_id. See XLMProphetNet docs for more information" + ) + + # shift inputs to the right + shifted_input_ids = input_ids.new_zeros(input_ids.shape) + shifted_input_ids[..., 1:] = input_ids[..., :-1].clone() + shifted_input_ids[..., 0] = decoder_start_token_id + + assert pad_token_id is not None, "self.model.config.pad_token_id has to be defined." + # replace possible -100 values in labels by `pad_token_id` + shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id) + + assert torch.all(shifted_input_ids >= 0).item(), "Verify that `shifted_input_ids` has only positive values" + + return shifted_input_ids + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetPositionalEmbeddings with ProphetNet->XLMProphetNet +class XLMProphetNetPositionalEmbeddings(nn.Embedding): + """ + This module learns positional embeddings up to a fixed maximum size. Padding ids are ignored by either offsetting + based on padding_idx or by setting padding_idx to None and ensuring that the appropriate position ids are passed to + the forward function. + """ + + def __init__(self, config: XLMProphetNetConfig) -> None: + self.max_length = config.max_position_embeddings + super().__init__(config.max_position_embeddings, config.hidden_size, config.pad_token_id) + + def forward(self, inputs_shape, device, attention_mask=None, past_key_values=None, position_ids=None): + assert (position_ids is None) or ( + self.padding_idx is None + ), "If position_ids is pre-computed then padding_idx should not be set." + + if position_ids is None: + if past_key_values is not None: + # position_ids is the same for every token when decoding a single step + # Without the int() cast, it doesn't work in some cases when exporting to ONNX + prev_num_input_ids = past_key_values[0][0].shape[2] + num_input_ids = inputs_shape[1] + prev_num_input_ids + position_ids = torch.ones((1, 1), dtype=torch.long, device=device) * ( + int(self.padding_idx + num_input_ids) + ) + else: + if attention_mask is None: + attention_mask = torch.ones(inputs_shape, dtype=torch.long, device=device) + + # retrieve position_ids from input_ids / attention_mask + position_ids = ( + torch.cumsum(attention_mask, dim=1).type_as(attention_mask) * attention_mask + ).long() + self.padding_idx + + # make sure position_ids are not bigger then max_length + position_ids = position_ids.clamp(0, self.max_length - 1) + + return super().forward(position_ids), position_ids + + def _forward(self, position_ids): + return super().forward(position_ids) + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetAttention with ProphetNet->XLMProphetNet +class XLMProphetNetAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__( + self, + config: XLMProphetNetConfig, + num_attn_heads: int, + ): + super().__init__() + hidden_size = config.hidden_size + + self.attention_dropout = config.attention_dropout + self.dropout = config.dropout + self.num_attn_heads = num_attn_heads + self.head_dim = hidden_size // num_attn_heads + + assert self.head_dim * num_attn_heads == hidden_size, ( + "`config.hidden_size` must be divisible by `config.num_encoder_attention_heads` and" + " `config.num_decoder_attention_heads`" + ) + + self.key_proj = nn.Linear(hidden_size, hidden_size) + self.value_proj = nn.Linear(hidden_size, hidden_size) + self.query_proj = nn.Linear(hidden_size, hidden_size) + + self.out_proj = nn.Linear(hidden_size, hidden_size) + + def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int): + return tensor.view(bsz, seq_len, self.num_attn_heads, self.head_dim).transpose(1, 2).contiguous() + + def forward( + self, + hidden_states, + key_value_states: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + layer_head_mask: Optional[Tensor] = None, + past_key_value: Optional[Tuple[Tensor]] = None, + output_attentions: bool = False, + ) -> Tuple[Tensor, Optional[Tensor]]: + batch_size, tgt_len, hidden_size = hidden_states.size() + + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + assert list(hidden_states.size()) == [ + batch_size, + tgt_len, + hidden_size, + ], f"Size of hidden states should be {batch_size, tgt_len, hidden_size}, but is {hidden_states.size()}" + + # previous time steps are cached - no need to recompute key and value if they are static + query_states = self.query_proj(hidden_states) / (self.head_dim**0.5) + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_states = past_key_value[0] + value_states = past_key_value[1] + elif is_cross_attention: + # cross_attentions + key_states = self._shape(self.key_proj(key_value_states), -1, batch_size) + value_states = self._shape(self.value_proj(key_value_states), -1, batch_size) + else: + # self_attention + key_states = self._shape(self.key_proj(hidden_states), -1, batch_size) + value_states = self._shape(self.value_proj(hidden_states), -1, batch_size) + + if is_cross_attention: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_states, value_states) + + # project states into the correct shape + proj_shape = (batch_size, self.num_attn_heads, -1, self.head_dim) + query_states = self._shape(query_states, tgt_len, batch_size).view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + src_len = key_states.size(2) + attn_weights = torch.einsum("bsij,bsjk->bsik", query_states, key_states.transpose(2, 3)) + expected_shape = (batch_size, self.num_attn_heads, tgt_len, src_len) + if attn_weights.size() != expected_shape: + raise ValueError(f"Attention weights should have size {expected_shape}, but is {attn_weights.size()}") + + # This is part of a workaround to get around fork/join parallelism not supporting Optional types. + if attention_mask is not None and attention_mask.dim() == 0: + attention_mask = None + + expected_shape = (batch_size, self.num_attn_heads, 1, src_len) + if attention_mask is not None and attention_mask.size() != expected_shape: + raise ValueError(f"Attention mask should have size {expected_shape}, but is {attention_mask.size()}") + if attention_mask is not None: # don't attend to padding symbols + attn_weights = attn_weights + attention_mask + if output_attentions: + attn_weights_reshaped = attn_weights + else: + attn_weights_reshaped = None + + attn_weights = nn.functional.softmax(attn_weights, dim=-1) + + if layer_head_mask is not None: + assert layer_head_mask.size() == (self.num_attn_heads,), ( + f"Head mask for a single layer should be of size {(self.num_attn_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + attn_weights = layer_head_mask.view(1, -1, 1, 1) * attn_weights.view( + batch_size, self.num_attn_heads, tgt_len, src_len + ) + + # apply head_mask also on attn_weights_reshaped which is used for n-gram attention inside the model + attn_weights_reshaped = layer_head_mask.view(1, -1, 1, 1) * attn_weights_reshaped + + attn_probs = nn.functional.dropout( + attn_weights, + p=self.attention_dropout, + training=self.training, + ) + attn_output = torch.einsum("bsij,bsjk->bsik", attn_probs, value_states) + expected_shape = (batch_size, self.num_attn_heads, tgt_len, self.head_dim) + if attn_output.size() != expected_shape: + raise ValueError(f"`attn_output` should have shape {expected_shape}, but is of shape {attn_output.size()}") + + attn_output = attn_output.transpose(1, 2).reshape(batch_size, tgt_len, hidden_size) + attn_output = self.out_proj(attn_output) + + attn_output = nn.functional.dropout(attn_output, p=self.dropout, training=self.training) + return attn_output, attn_weights_reshaped, past_key_value + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetFeedForward with ProphetNet->XLMProphetNet +class XLMProphetNetFeedForward(nn.Module): + """ + This is the residual two feed-forward layer block based on the original Transformer implementation. + """ + + def __init__(self, config: XLMProphetNetConfig, ffn_dim: int): + super().__init__() + self.activation_fn = ACT2FN[config.activation_function] + self.intermediate = nn.Linear(config.hidden_size, ffn_dim) + self.output = nn.Linear(ffn_dim, config.hidden_size) + self.activation_dropout = config.activation_dropout + self.dropout = config.dropout + + def forward(self, hidden_states): + hidden_states = self.intermediate(hidden_states) + hidden_states = self.activation_fn(hidden_states) + + hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training) + hidden_states = self.output(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + return hidden_states + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetNgramSelfAttention with ProphetNet->XLMProphetNet +class XLMProphetNetNgramSelfAttention(nn.Module): + def __init__(self, config: XLMProphetNetConfig): + super().__init__() + self.hidden_size = config.hidden_size + + self.num_buckets = config.num_buckets + self.relative_max_distance = config.relative_max_distance + self.num_attn_heads = config.num_decoder_attention_heads + self.dropout = config.dropout + self.attention_dropout = config.attention_dropout + self.head_dim = config.hidden_size // self.num_attn_heads + self.ngram = config.ngram + + assert ( + self.head_dim * self.num_attn_heads == config.hidden_size + ), "config.hidden_size must be divisible by num_attn_heads" + # key, value, query projection + self.key_proj = nn.Linear(config.hidden_size, config.hidden_size) + self.value_proj = nn.Linear(config.hidden_size, config.hidden_size) + self.query_proj = nn.Linear(config.hidden_size, config.hidden_size) + + # out projection + self.out_proj = nn.Linear(config.hidden_size, config.hidden_size) + + # rel position embeddings + self.relative_pos_embeddings = nn.Linear(config.hidden_size, self.num_buckets * self.num_attn_heads) + + # for onnx runtime + self.onnx_trace = False + + def _shape(self, tensor, seq_len, batch_size): + return tensor.view(batch_size, seq_len, self.num_attn_heads, self.head_dim).transpose(1, 2).contiguous() + + def prepare_for_onnx_export_(self): + self.onnx_trace = True + + def forward( + self, + hidden_states, + past_key_value: Optional[Tuple[Tensor]] = None, + attention_mask=None, + layer_head_mask=None, + extended_predict_attention_mask=None, + main_relative_position_buckets=None, + predict_relative_position_buckets=None, + position_ids=None, + ): + batch_size, ngram_sequence_length, hidden_size = hidden_states.size() + assert list(hidden_states.size()) == [batch_size, ngram_sequence_length, hidden_size], ( + f"`hidden_states` should be of shape {batch_size, ngram_sequence_length, hidden_size}, but is of shape" + f" {hidden_states.shape}" + ) + + # project + query_states = self.query_proj(hidden_states) + key_states = self.key_proj(hidden_states) + value_states = self.value_proj(hidden_states) + + # normalize + query_states = query_states / (self.head_dim**0.5) + + # reshape + query_states = self._shape(query_states, ngram_sequence_length, batch_size) + key_states = self._shape(key_states, -1, batch_size) + value_states = self._shape(value_states, -1, batch_size) + proj_shape = (batch_size, self.num_attn_heads, -1, self.head_dim) + + query_states = query_states.view(*proj_shape) + key_states = key_states.view(*proj_shape) + value_states = value_states.view(*proj_shape) + + # chunk into main stream and predict stream + hidden_states_list = hidden_states.chunk(1 + self.ngram, dim=1) + query_states_list = query_states.chunk(1 + self.ngram, dim=2) + key_states_list = key_states.chunk(1 + self.ngram, dim=2) + value_states_list = value_states.chunk(1 + self.ngram, dim=2) + + main_hidden_states, hidden_states_predict_list = hidden_states_list[0], hidden_states_list[1:] + main_query_states, predict_query_states_list = query_states_list[0], query_states_list[1:] + main_key_states, predict_key_states_list = key_states_list[0], key_states_list[1:] + main_value_states, predict_value_states_list = value_states_list[0], value_states_list[1:] + + # saved states are stored with shape (batch_size, num_attn_heads, seq_len, head_dim) + if past_key_value is not None: + prev_main_key_states = past_key_value[0] + main_key_states = torch.cat((prev_main_key_states, main_key_states), dim=2) + prev_main_value_states = past_key_value[1] + main_value_states = torch.cat((prev_main_value_states, main_value_states), dim=2) + + # Update cache + past_key_value = (main_key_states, main_value_states) + + # get seq_length of main stream only + sequence_length = ngram_sequence_length // (1 + self.ngram) + + # MAIN-STREAM + # main attn weights + # [batch_size, number_heads, sequence_length, head_dimesion] + # x [batch_size, number_heads, head_dimesion, sequence_length] + # -> [batch_size, number_heads, sequence_length, sequence_length] + main_attn_weights = torch.einsum("bntc,bncs->bnts", main_query_states, main_key_states.transpose(2, 3)) + + # retrieve relative position embeddings for each layer -> see paper for more details + main_relative_pos_embeddings = self.get_main_relative_pos_embeddings( + main_hidden_states, main_attn_weights, position_ids, main_relative_position_buckets + ) + + main_attn_weights = main_attn_weights + main_relative_pos_embeddings + + if attention_mask is not None: + main_attn_weights = main_attn_weights + attention_mask + + main_attn_probs = softmax( + main_attn_weights, + dim=-1, + onnx_trace=self.onnx_trace, + ).type_as(main_attn_weights) + + if layer_head_mask is not None: + assert layer_head_mask.size() == (self.num_attn_heads,), ( + f"Head mask for a single layer should be of size {(self.num_attn_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + main_attn_probs = layer_head_mask.view(1, -1, 1, 1) * main_attn_probs.view( + batch_size, self.num_attn_heads, -1, sequence_length + ) + + main_attn_probs = nn.functional.dropout(main_attn_probs, p=self.attention_dropout, training=self.training) + # project to attn_output + # [batch_size, number_heads, sequence_length, sequence_length] + # x [batch_size, number_heads, sequence_length, head_dimesion] + # -> [batch_size, number_heads, sequence_length, head_dimesion] + main_attn_output = torch.einsum("bntc,bncs->bnts", main_attn_probs, main_value_states) + # reshape so that num_heads dim is merged into last `head_dim` axis + main_attn_output = main_attn_output.transpose(1, 2).reshape(batch_size, 1, sequence_length, hidden_size) + main_attn_output = self.out_proj(main_attn_output) + + # PREDICT-STREAM + # [batch_size, ngram, number_heads, sequence_length, head_dimesion] + predict_query_states = torch.stack(predict_query_states_list, 1).view( + batch_size, self.ngram, self.num_attn_heads, sequence_length, self.head_dim + ) + + # [batch_size, ngram, number_heads, 2*sequence_length, head_dimesion] + predict_key_states = torch.stack([torch.cat([main_key_states, key], 2) for key in predict_key_states_list], 1) + + # [batch_size, sequence_length, ngram, hidden_size] + predict_hidden_states = torch.stack(hidden_states_predict_list, dim=2) + + # [batch_size, number_heads, ngram, 2*sequence_length, head_dimesion] + predict_value_states = torch.cat( + [torch.cat([main_value_states, v_p], 2).unsqueeze(2) for v_p in predict_value_states_list], 2 + ) + + # [batch_size, ngram, number_heads, sequence_length, head_dimesion] + # x [batch_size, ngram, number_heads, 2*sequence_length, head_dimesion] + # -> [batch_size, ngram, number_heads, sequence_length, 2*sequence_length] + predict_attn_weights = torch.einsum("bnhtc,bnhsc->bnhts", (predict_query_states, predict_key_states)) + + # retrieve relative position embeddings for each layer -> see paper for more details + # [batch_size, ngram, number_heads, sequence_length, predict_relative_pos_embeddings] + predict_relative_pos_embeddings = self.get_predict_relative_pos_embeddings( + predict_hidden_states, predict_attn_weights, position_ids, predict_relative_position_buckets + ) + + # [batch_size, ngram, number_heads, sequence_length, 2*sequence_length] + predict_attn_weights = predict_attn_weights + predict_relative_pos_embeddings + + if extended_predict_attention_mask is not None: + # Permuting Predict attention mask to [batch_size, ngram, number_heads, sequence_length, 2*sequence_length] + extended_predict_attention_mask = extended_predict_attention_mask.permute(0, 2, 1, 3, 4) + extended_predict_attention_mask = extended_predict_attention_mask.to(predict_attn_weights.dtype) + predict_attn_weights = predict_attn_weights + extended_predict_attention_mask + + predict_attn_probs = softmax( + predict_attn_weights, + dim=-1, + onnx_trace=self.onnx_trace, + ).type_as(predict_attn_weights) + + if layer_head_mask is not None: + assert layer_head_mask.size() == (self.num_attn_heads,), ( + f"Head mask for a single layer should be of size {(self.num_attn_heads,)}, but is" + f" {layer_head_mask.size()}" + ) + predict_attn_probs = layer_head_mask.view(1, 1, -1, 1, 1) * predict_attn_probs + + predict_attn_probs = nn.functional.dropout( + predict_attn_probs, p=self.attention_dropout, training=self.training + ) + # project to attention output + # [batch_size, ngram, number_heads, sequence_length, 2*sequence_length] + # x [batch_size, ngram, number_heads, 2*sequence_length, head_dimesion] + # -> [batch_size, ngram, number_heads, sequence_length, head_dimesion] + predict_attn_output = torch.einsum( + "bnhts,bnhsc->bnhtc", (predict_attn_probs, predict_value_states.transpose(1, 2)) + ) + + # reshape so that num_heads dim is merged into last `head_dim` axis + # [batch_size, ngram, number_heads, sequence_length, head_dimesion] -> [batch_size, ngram, sequence_length, hidden_size] + predict_attn_output = predict_attn_output.transpose(2, 3) + predict_attn_output = predict_attn_output.reshape(batch_size, self.ngram, sequence_length, hidden_size) + predict_attn_output = self.out_proj(predict_attn_output) + + # concat to single attn output + # [batch_size, (1+ngram)*sequence_length, hidden_size] + attn_output = torch.cat([main_attn_output, predict_attn_output], 1).view(batch_size, -1, hidden_size) + # reshape into better form for `config.output_attentions` + main_attn_probs = main_attn_probs.view(batch_size, self.num_attn_heads, sequence_length, -1) + + attn_output = nn.functional.dropout(attn_output, p=self.dropout, training=self.training) + + return attn_output, main_attn_probs, predict_attn_probs, past_key_value + + def get_main_relative_pos_embeddings( + self, hidden_states, attn_weights, position_ids, main_relative_position_buckets + ): + # input hidden_states [batch_size, sequence_length, hidden_size] + # input attn_weights [batch_size, num_heads, sequence_length, sequence_length] + # input position_ids [batch_size, sequence_length] or [1,1] + batch_size, num_attn_heads, tgt_len, src_len = attn_weights.shape + attn_weights = attn_weights.view(batch_size, num_attn_heads, tgt_len, src_len) + if main_relative_position_buckets is None: + batch_size, sequence_length = hidden_states.shape[:2] + relative_positions = ( + torch.arange(1, attn_weights.shape[-1] + 1) + .unsqueeze(0) + .unsqueeze(0) + .repeat(batch_size, sequence_length, 1) + .to(position_ids.device) + ) + # [batch_size, sequence_length, sequence_length+1] + relative_positions = relative_positions - position_ids.unsqueeze(0).repeat(batch_size, sequence_length, 1) + main_relative_position_buckets = compute_relative_buckets( + self.num_buckets, self.relative_max_distance, relative_positions, False + ) + + # [batch_size, sequence_length, num_buckets * num_heads] + rel_pos_embeddings = self.relative_pos_embeddings(hidden_states) + rel_pos_embeddings = rel_pos_embeddings.view( + rel_pos_embeddings.shape[:2] + (self.num_buckets, self.num_attn_heads) + ) + rel_pos_embeddings = rel_pos_embeddings.permute(0, 3, 1, 2) + # [batch_size, num_heads, sequence_length, num_buckets] + rel_pos_embeddings = rel_pos_embeddings.reshape(attn_weights.shape[:3] + (-1,)) + + main_relative_position_buckets = main_relative_position_buckets.repeat(1, self.num_attn_heads, 1) + # [batch_size * num_heads * sequence_length, sequence_length] + main_relative_position_buckets = main_relative_position_buckets.view( + -1, main_relative_position_buckets.shape[-1] + ) + main_relative_position_buckets = main_relative_position_buckets.long() + # [batch_size * num_heads * sequence_length, sequence_length] + rel_pos_embeddings = rel_pos_embeddings.reshape(-1, rel_pos_embeddings.size(-1)) + + main_relative_pos_embeddings = torch.gather(rel_pos_embeddings, dim=1, index=main_relative_position_buckets) + main_relative_pos_embeddings = main_relative_pos_embeddings.view(batch_size, num_attn_heads, tgt_len, -1) + return main_relative_pos_embeddings + + def get_predict_relative_pos_embeddings( + self, hidden_states, attn_weights, position_ids, predict_relative_position_buckets + ): + # input hidden_states [batch_size, sequence_length, ngram, hidden_size] + # input attn_weights [batch_size, ngram, num_heads, sequence_length, 2*sequence_length] + # input position_ids [batch_size, sequence_length] or [1,1] + # input predict_relative_position_buckets [batch_size, sequence_length, 2*sequence_length] or None + batch_size, sequence_length = hidden_states.shape[0:2] + + if predict_relative_position_buckets is None: + key_sequence_length = attn_weights.shape[-1] + assert ( + position_ids[0][0] == key_sequence_length - 1 + ), "`position_ids` are incorrect. They should be of the format 1 2 3 4 5 ... (key_sequence_length - 1)" + relative_positions = ( + torch.arange(0, key_sequence_length) + .unsqueeze(0) + .unsqueeze(0) + .repeat(batch_size, sequence_length, 1) + .to(position_ids.device) + ) + + relative_positions = relative_positions - position_ids.unsqueeze(0).repeat(batch_size, sequence_length, 1) + predict_relative_position_buckets = compute_relative_buckets( + self.num_buckets, self.relative_max_distance, relative_positions, False + ) + + # [batch_size, ngram, sequence_length, hidden_size] + hidden_states = hidden_states.transpose(1, 2) + rel_pos_embeddings = self.relative_pos_embeddings(hidden_states) + + # [batch_size, ngram, sequence_length, num_buckets, num_heads] + rel_pos_embeddings = rel_pos_embeddings.view( + hidden_states.shape[:-1] + (self.num_buckets, self.num_attn_heads) + ) + rel_pos_embeddings = rel_pos_embeddings.permute(0, 2, 1, 4, 3) + # [batch_size * ngram * sequence_length * num_heads, num_buckets] + rel_pos_embeddings = rel_pos_embeddings.reshape(-1, self.num_buckets) + # [ngram, batch_size, num_heads * sequence_length, -1] + predict_relative_position_buckets = predict_relative_position_buckets.unsqueeze(0) + predict_relative_position_buckets = predict_relative_position_buckets.repeat( + self.ngram, 1, self.num_attn_heads, 1 + ) + # [ngram * batch_size * num_heads * sequence_length, -1] + predict_relative_position_buckets = predict_relative_position_buckets.view( + -1, predict_relative_position_buckets.size(-1) + ).long() + + predict_relative_pos_embeddings = torch.gather( + rel_pos_embeddings, dim=1, index=predict_relative_position_buckets + ) + + # [batch_size, gram, num_heads, sequence_length, -1] + predict_relative_pos_embeddings = predict_relative_pos_embeddings.view( + batch_size, self.ngram, self.num_attn_heads, sequence_length, -1 + ) + + return predict_relative_pos_embeddings + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetEncoderLayer with ProphetNet->XLMProphetNet, Prophetnet->XLMProphetnet +class XLMProphetNetEncoderLayer(nn.Module): + """ + Encoder block for XLMProphetnet + """ + + def __init__(self, config: XLMProphetNetConfig): + super().__init__() + # 1st residual block + self.self_attn = XLMProphetNetAttention(config, config.num_encoder_attention_heads) + self.self_attn_layer_norm = LayerNorm(config.hidden_size) + + # 2nd residual block + self.feed_forward = XLMProphetNetFeedForward(config, config.encoder_ffn_dim) + self.feed_forward_layer_norm = LayerNorm(config.hidden_size) + + def forward( + self, + hidden_states, + attention_mask, + layer_head_mask, + output_attentions: bool = False, + ): + # 1st residual block + attention_output, attn_weights, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + output_attentions=output_attentions, + ) + hidden_states = self.self_attn_layer_norm(attention_output + hidden_states) + + # 2nd residual block + feed_forward_output = self.feed_forward(hidden_states) + hidden_states = self.feed_forward_layer_norm(feed_forward_output + hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetDecoderLayer with Prophetnet->XLMProphetnet, ProphetNet->XLMProphetNet +class XLMProphetNetDecoderLayer(nn.Module): + """ + Decoder block for XLMProphetnet + """ + + def __init__(self, config: XLMProphetNetConfig): + super().__init__() + # 1st residual block + self.self_attn = XLMProphetNetNgramSelfAttention(config) + self.self_attn_layer_norm = LayerNorm(config.hidden_size) + + # 2nd residual block + if config.add_cross_attention: + self.cross_attn = XLMProphetNetAttention(config, config.num_decoder_attention_heads) + self.cross_attn_layer_norm = LayerNorm(config.hidden_size) + + # 3rd residual block + self.feed_forward = XLMProphetNetFeedForward(config, config.decoder_ffn_dim) + self.feed_forward_layer_norm = LayerNorm(config.hidden_size) + + def forward( + self, + hidden_states, + attention_mask=None, + encoder_hidden_states=None, + encoder_attn_mask=None, + layer_head_mask=None, + cross_attn_layer_head_mask=None, + extended_predict_attention_mask=None, + main_relative_position_buckets=None, + predict_relative_position_buckets=None, + position_ids=None, + past_key_value=None, + use_cache: bool = True, + output_attentions: bool = False, + ): + # 1st residual block + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + ngram_attention_output, self_attn_weights, self_attn_weights_ngram, present_key_value = self.self_attn( + hidden_states=hidden_states, + past_key_value=self_attn_past_key_value, + attention_mask=attention_mask, + layer_head_mask=layer_head_mask, + extended_predict_attention_mask=extended_predict_attention_mask, + main_relative_position_buckets=main_relative_position_buckets, + predict_relative_position_buckets=predict_relative_position_buckets, + position_ids=position_ids, + ) + hidden_states = self.self_attn_layer_norm(hidden_states + ngram_attention_output) + + # cross_attn cached key/values tuple is at positions 3,4 of present_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attn_weights = None + if encoder_hidden_states is not None: + # 2nd residual block + attention_output, cross_attn_weights, cross_attn_present_key_value = self.cross_attn( + hidden_states=hidden_states, + key_value_states=encoder_hidden_states, + attention_mask=encoder_attn_mask, + layer_head_mask=cross_attn_layer_head_mask, + past_key_value=cross_attn_past_key_value, + output_attentions=output_attentions, + ) + hidden_states = self.cross_attn_layer_norm(attention_output + hidden_states) + + # add cross-attn to positions 3,4 of present_key_value tuple + present_key_value = present_key_value + cross_attn_present_key_value + + # 3rd residual block + feed_forward_output = self.feed_forward(hidden_states) + hidden_states = self.feed_forward_layer_norm(feed_forward_output + hidden_states) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (self_attn_weights, self_attn_weights_ngram, cross_attn_weights) + + if use_cache: + outputs += (present_key_value,) + + return outputs + + +@add_start_docstrings( + "The standalone encoder part of the XLMProphetNetModel.", + XLM_PROPHETNET_START_DOCSTRING, +) +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetEncoder with microsoft/prophetnet-large-uncased->patrickvonplaten/xprophetnet-large-uncased-standalone, ProphetNet->XLMProphetNet, PROPHETNET->XLM_PROPHETNET +class XLMProphetNetEncoder(XLMProphetNetPreTrainedModel): + r""" + word_embeddings (`torch.nn.Embeddings` of shape `(config.vocab_size, config.hidden_size)`, *optional*): + The word embedding parameters. This can be used to initialize [`XLMProphetNetEncoder`] with pre-defined word + embeddings instead of randomly initialized word embeddings. + """ + + def __init__(self, config: XLMProphetNetConfig, word_embeddings: nn.Embedding = None): + super().__init__(config) + + self.word_embeddings = ( + word_embeddings + if word_embeddings is not None + else nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + ) + self.position_embeddings = XLMProphetNetPositionalEmbeddings(config) + self.embeddings_layer_norm = LayerNorm(config.hidden_size) + + self.layers = nn.ModuleList([XLMProphetNetEncoderLayer(config) for _ in range(config.num_encoder_layers)]) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.word_embeddings + + def set_input_embeddings(self, value): + self.word_embeddings = value + + @add_start_docstrings_to_model_forward(XLM_PROPHETNET_STANDALONE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=BaseModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutput]: + r""" + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMProphetNetEncoder + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = XLMProphetNetEncoder.from_pretrained("patrickvonplaten/prophetnet-large-uncased-standalone") + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + ```""" + + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is None and inputs_embeds is None: + raise ValueError("Either input_ids or inputs_embeds has to be passed.") + elif input_ids is not None and inputs_embeds is not None: + raise ValueError("Make sure to only pass input_ids or inputs_embeds.") + elif input_ids is not None and inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + + # prepare attention mask + if attention_mask is not None: + extended_attention_mask = ( + 1.0 - attention_mask[:, None, None, :].repeat(1, self.config.num_encoder_attention_heads, 1, 1) + ) * torch.finfo(self.dtype).min + extended_attention_mask = extended_attention_mask.to(inputs_embeds.dtype) + else: + extended_attention_mask = None + + position_embeddings, position_ids = self.position_embeddings(inputs_embeds.shape[:2], inputs_embeds.device) + + hidden_states = inputs_embeds + position_embeddings + hidden_states = self.embeddings_layer_norm(hidden_states) + hidden_states = nn.functional.dropout(hidden_states, p=self.config.dropout, training=self.training) + + encoder_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + # check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + assert head_mask.size()[0] == ( + len(self.layers) + ), f"The head_mask should be specified for {len(self.layers)} layers, but it is for {head_mask.size()[0]}." + for idx, encoder_layer in enumerate(self.layers): + if output_hidden_states: + encoder_hidden_states = encoder_hidden_states + (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(encoder_layer), + hidden_states, + extended_attention_mask, + (head_mask[idx] if head_mask is not None else None), + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask=extended_attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if output_hidden_states: + encoder_hidden_states = encoder_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, encoder_hidden_states, all_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, hidden_states=encoder_hidden_states, attentions=all_attentions + ) + + +@add_start_docstrings( + "The standalone decoder part of the XLMProphetNetModel.", + XLM_PROPHETNET_START_DOCSTRING, +) +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetDecoder with microsoft/prophetnet-large-uncased->patrickvonplaten/xprophetnet-large-uncased-standalone, ProphetNet->XLMProphetNet, PROPHETNET->XLM_PROPHETNET, +class XLMProphetNetDecoder(XLMProphetNetPreTrainedModel): + r""" + word_embeddings (`torch.nn.Embeddings` of shape `(config.vocab_size, config.hidden_size)`, *optional*): + The word embedding parameters. This can be used to initialize [`XLMProphetNetEncoder`] with pre-defined word + embeddings instead of randomly initialized word embeddings. + """ + + def __init__(self, config: XLMProphetNetConfig, word_embeddings: Optional[nn.Embedding] = None): + super().__init__(config) + + self.ngram = config.ngram + self.num_buckets = config.num_buckets + self.relative_max_distance = config.relative_max_distance + self.dropout = config.dropout + self.max_target_positions = config.max_position_embeddings + + self.word_embeddings = ( + word_embeddings + if word_embeddings is not None + else nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + ) + self.position_embeddings = XLMProphetNetPositionalEmbeddings(config) + + self.ngram_embeddings = nn.Embedding(self.ngram, config.hidden_size, None) + self.layers = nn.ModuleList([XLMProphetNetDecoderLayer(config) for _ in range(config.num_decoder_layers)]) + self.embeddings_layer_norm = LayerNorm(config.hidden_size) + + self.gradient_checkpointing = False + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.word_embeddings + + def set_input_embeddings(self, value): + self.word_embeddings = value + + @add_start_docstrings_to_model_forward(XLM_PROPHETNET_STANDALONE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=XLMProphetNetDecoderModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XLMProphetNetDecoderModelOutput]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMProphetNetDecoder + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = XLMProphetNetDecoder.from_pretrained( + ... "patrickvonplaten/xprophetnet-large-uncased-standalone", add_cross_attention=False + ... ) + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + ```""" + use_cache = use_cache if use_cache is not None else self.config.use_cache + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is None and inputs_embeds is None: + raise ValueError("Either `decoder_input_ids` or `decoder_inputs_embeds` has to be passed.") + elif input_ids is not None and inputs_embeds is not None: + raise ValueError("Make sure to only pass `decoder_input_ids` or `decoder_inputs_embeds`.") + elif input_ids is not None and inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + + batch_size, sequence_length = inputs_embeds.shape[:2] + + main_stream_pos_embed, position_ids = self.position_embeddings( + (batch_size, sequence_length), + device=inputs_embeds.device, + past_key_values=past_key_values, + ) + + if past_key_values is not None: + main_relative_position_buckets, predict_relative_position_buckets = None, None + else: + ( + main_relative_position_buckets, + predict_relative_position_buckets, + ) = self.compute_buffered_relative_buckets(position_ids) + predicting_stream_pos_embed = self.position_embeddings._forward(position_ids + 1) + + # add position embeddings + hidden_states = inputs_embeds + main_stream_pos_embed + + ngram_embeddings = self.ngram_embeddings.weight + + # prepare attention mask + if past_key_values is not None: + assert ( + hidden_states.size(1) == 1 + ), "At the moment `use_cache` is only supported for `decoder_input_ids` of length 1" + + ngram_hidden_states = [ + (ngram_embeddings[ngram - 1] + predicting_stream_pos_embed).repeat(batch_size, 1, 1) + for ngram in range(self.ngram) + ] + extended_attention_mask = None + extended_predict_attention_mask = None + else: + ngram_hidden_states = [ + (ngram_embeddings[ngram - 1] + predicting_stream_pos_embed) for ngram in range(self.ngram) + ] + extended_attention_mask = self.prepare_attention_mask(hidden_states, attention_mask) + extended_predict_attention_mask = self.prepare_predict_attention_mask(hidden_states, attention_mask) + + # prepare encoder attention mask + if encoder_attention_mask is not None: + extended_encoder_attention_mask = ( + 1.0 - encoder_attention_mask[:, None, None, :].repeat(1, self.config.num_decoder_attention_heads, 1, 1) + ) * torch.finfo(self.dtype).min + extended_encoder_attention_mask = extended_encoder_attention_mask.to(inputs_embeds.dtype) + else: + extended_encoder_attention_mask = None + + hidden_states = torch.cat([hidden_states] + ngram_hidden_states, 1) + + if self.embeddings_layer_norm: + hidden_states = self.embeddings_layer_norm(hidden_states) + + hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training) + + # init attentions, hidden_states and cache with empty tuples + all_main_stream_hidden_states = () if output_hidden_states else None + all_ngram_stream_hidden_states = () if output_hidden_states and self.config.ngram > 0 else None + + all_main_stream_attns = () if output_attentions else None + all_ngram_stream_attns = () if output_attentions else None + all_cross_attns = () if output_attentions and self.config.add_cross_attention else None + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + present_key_values = () if use_cache else None + + # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired + for attn_mask, mask_name in zip([head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]): + if attn_mask is not None: + assert attn_mask.size()[0] == (len(self.layers)), ( + f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for" + f" {head_mask.size()[0]}." + ) + for idx, decoder_layer in enumerate(self.layers): + if output_hidden_states: + # grad cannot be kept because tensor is sliced + all_main_stream_hidden_states += (hidden_states[:, :sequence_length],) + if self.config.ngram > 0: + all_ngram_stream_hidden_states += (hidden_states[:, sequence_length:],) + + past_key_value = past_key_values[idx] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + # None for past_key_value + return module(*inputs, use_cache, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(decoder_layer), + hidden_states, + extended_attention_mask, + encoder_hidden_states, + extended_encoder_attention_mask, + (head_mask[idx] if head_mask is not None else None), + (cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None), + extended_predict_attention_mask, + main_relative_position_buckets, + predict_relative_position_buckets, + position_ids, + None, + ) + else: + layer_outputs = decoder_layer( + hidden_states, + attention_mask=extended_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attn_mask=extended_encoder_attention_mask, + layer_head_mask=(head_mask[idx] if head_mask is not None else None), + cross_attn_layer_head_mask=( + cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None + ), + extended_predict_attention_mask=extended_predict_attention_mask, + main_relative_position_buckets=main_relative_position_buckets, + predict_relative_position_buckets=predict_relative_position_buckets, + position_ids=position_ids, + past_key_value=past_key_value, + use_cache=use_cache, + output_attentions=output_attentions, + ) + + hidden_states = layer_outputs[0] + + if use_cache: + present_key_values += (layer_outputs[4 if output_attentions else 1],) + + if output_attentions: + all_main_stream_attns += (layer_outputs[1],) + all_ngram_stream_attns += (layer_outputs[2],) + + if self.config.add_cross_attention: + all_cross_attns += (layer_outputs[3],) + + if output_hidden_states: + all_main_stream_hidden_states += (hidden_states[:, :sequence_length],) + if self.config.ngram > 0: + all_ngram_stream_hidden_states += (hidden_states[:, sequence_length:],) + + # split last_hidden_state for return + last_hidden_state = hidden_states[:, :sequence_length] + last_hidden_state_ngram = hidden_states[:, sequence_length:] if self.config.ngram > 0 else None + + if not return_dict: + return tuple( + v + for v in [ + last_hidden_state, + last_hidden_state_ngram, + present_key_values, + all_main_stream_hidden_states, + all_ngram_stream_hidden_states, + all_main_stream_attns, + all_ngram_stream_attns, + all_cross_attns, + ] + if v is not None + ) + return XLMProphetNetDecoderModelOutput( + last_hidden_state=last_hidden_state, + last_hidden_state_ngram=last_hidden_state_ngram, + past_key_values=present_key_values, + hidden_states=all_main_stream_hidden_states, + hidden_states_ngram=all_ngram_stream_hidden_states, + attentions=all_main_stream_attns, + ngram_attentions=all_ngram_stream_attns, + cross_attentions=all_cross_attns, + ) + + def compute_buffered_relative_buckets(self, position_ids): + batch_size, sequence_length = position_ids.shape + + position_ids = torch.arange(1, self.max_target_positions).to(position_ids.device).repeat(1, 1) + main_relative_buckets, predict_relative_buckets = compute_all_stream_relative_buckets( + self.num_buckets, self.relative_max_distance, position_ids + ) + + # buffer relative buckets + main_relative_buckets = main_relative_buckets[:, :sequence_length, :sequence_length].repeat(batch_size, 1, 1) + predict_relative_buckets = torch.cat( + [ + predict_relative_buckets[:, :sequence_length, :sequence_length], + predict_relative_buckets[ + :, :sequence_length, self.max_target_positions : self.max_target_positions + sequence_length + ], + ], + 2, + ).repeat(batch_size, 1, 1) + + return main_relative_buckets, predict_relative_buckets + + def prepare_attention_mask(self, hidden_states, attention_mask): + batch_size, seq_length = hidden_states.shape[:2] + + # get causal mask + causal_mask = torch.full( + (seq_length, seq_length), + torch.finfo(hidden_states.dtype).min, + dtype=hidden_states.dtype, + device=hidden_states.device, + ) + causal_mask = torch.triu(causal_mask, 1) + + extended_causal_mask = causal_mask[:seq_length, :seq_length][None, None, :, :].expand( + (batch_size, self.config.num_decoder_attention_heads) + causal_mask.shape + ) + + # add usual attention mask + if attention_mask is not None: + extended_attention_mask = (1.0 - attention_mask[:, None, None, :]) * torch.finfo(self.dtype).min + extended_attention_mask = extended_causal_mask + extended_attention_mask + else: + extended_attention_mask = extended_causal_mask + return extended_attention_mask.to(hidden_states.dtype) + + def prepare_predict_attention_mask(self, hidden_states, attention_mask): + batch_size, seq_length = hidden_states.shape[:2] + + # get causal mask + predict_causal_mask = ngram_attention_bias( + self.max_target_positions, self.ngram, hidden_states.device, hidden_states.dtype + ) + predict_causal_mask = torch.cat( + [ + predict_causal_mask[:, :seq_length, :seq_length], + predict_causal_mask[ + :, :seq_length, self.max_target_positions : self.max_target_positions + seq_length + ], + ], + dim=-1, + ) + extended_predict_causal_mask = predict_causal_mask[None, None, :, :, :].expand( + (batch_size, self.config.num_decoder_attention_heads) + predict_causal_mask.shape + ) + + # add usual attention mask + if attention_mask is not None: + extended_attention_mask = (1.0 - attention_mask[:, None, None, None, :]) * torch.finfo(self.dtype).min + extended_attention_mask = extended_attention_mask.expand( + (batch_size, self.config.num_decoder_attention_heads, self.ngram, seq_length, seq_length) + ) + # predicted stream attention_mask should always be 0 + extended_attention_mask = torch.cat( + [extended_attention_mask, torch.zeros_like(extended_attention_mask)], dim=-1 + ) + extended_predict_attention_mask = extended_predict_causal_mask + extended_attention_mask + else: + extended_predict_attention_mask = extended_predict_causal_mask + return extended_predict_attention_mask.to(hidden_states.dtype) + + +@add_start_docstrings( + "The bare XLMProphetNet Model outputting raw hidden-states without any specific head on top.", + XLM_PROPHETNET_START_DOCSTRING, +) +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetModel with microsoft/prophetnet-large-uncased->patrickvonplaten/xprophetnet-large-uncased-standalone, ProphetNet->XLMProphetNet, PROPHETNET->XLM_PROPHETNET +class XLMProphetNetModel(XLMProphetNetPreTrainedModel): + _keys_to_ignore_on_load_missing = ["decoder.word_embeddings.weight", "encoder.word_embeddings.weight"] + + def __init__(self, config: XLMProphetNetConfig): + super().__init__(config) + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + + encoder_config = copy.deepcopy(config) + encoder_config.is_encoder_decoder = False + encoder_config.use_cache = False + self.encoder = XLMProphetNetEncoder(encoder_config, self.word_embeddings) + + decoder_config = copy.deepcopy(config) + decoder_config.is_decoder = True + decoder_config.is_encoder_decoder = False + self.decoder = XLMProphetNetDecoder(decoder_config, self.word_embeddings) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.word_embeddings + + def set_input_embeddings(self, value): + self.word_embeddings = value + self.encoder.word_embeddings = self.word_embeddings + self.decoder.word_embeddings = self.word_embeddings + + def get_encoder(self): + return self.encoder + + def get_decoder(self): + return self.decoder + + @add_start_docstrings_to_model_forward(XLM_PROPHETNET_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=XLMProphetNetSeq2SeqModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.Tensor] = None, + decoder_attention_mask: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[Tuple] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + decoder_inputs_embeds: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XLMProphetNetSeq2SeqModelOutput]: + r""" + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMProphetNetModel + + >>> tokenizer = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = XLMProphetNetModel.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + + >>> input_ids = tokenizer( + ... "Studies have been shown that owning a dog is good for you", return_tensors="pt" + ... ).input_ids # Batch size 1 + >>> decoder_input_ids = tokenizer("Studies show that", return_tensors="pt").input_ids # Batch size 1 + >>> outputs = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) + + >>> last_hidden_states = outputs.last_hidden_state # main stream hidden states + >>> last_hidden_states_ngram = outputs.last_hidden_state_ngram # predict hidden states + ```""" + use_cache = use_cache if use_cache is not None else self.config.use_cache + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if encoder_outputs is None: + encoder_outputs = self.encoder( + input_ids=input_ids, + attention_mask=attention_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + # decoder outputs consists of (dec_features, past_key_values, dec_hidden, dec_attn) + decoder_outputs = self.decoder( + input_ids=decoder_input_ids, + attention_mask=decoder_attention_mask, + encoder_hidden_states=encoder_outputs[0], + encoder_attention_mask=attention_mask, + head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=decoder_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + use_cache=use_cache, + return_dict=return_dict, + ) + + if not return_dict: + return decoder_outputs + encoder_outputs + return XLMProphetNetSeq2SeqModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + last_hidden_state_ngram=decoder_outputs.last_hidden_state_ngram, + past_key_values=decoder_outputs.past_key_values, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_ngram_hidden_states=decoder_outputs.hidden_states_ngram, + decoder_attentions=decoder_outputs.attentions, + decoder_ngram_attentions=decoder_outputs.ngram_attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + ) + + +@add_start_docstrings( + "The XLMProphetNet Model with a language modeling head. Can be used for sequence generation tasks.", + XLM_PROPHETNET_START_DOCSTRING, +) +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetForConditionalGeneration with microsoft/prophetnet-large-uncased->patrickvonplaten/xprophetnet-large-uncased-standalone, ProphetNet->XLMProphetNet, PROPHETNET->XLM_PROPHETNET +class XLMProphetNetForConditionalGeneration(XLMProphetNetPreTrainedModel): + _keys_to_ignore_on_load_missing = [ + "decoder.word_embeddings.weight", + "encoder.word_embeddings.weight", + "lm_head.weight", + ] + + def __init__(self, config: XLMProphetNetConfig): + super().__init__(config) + self.prophetnet = XLMProphetNetModel(config) + self.padding_idx = config.pad_token_id + self.disable_ngram_loss = config.disable_ngram_loss + + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def get_input_embeddings(self): + return self.prophetnet.word_embeddings + + @add_start_docstrings_to_model_forward(XLM_PROPHETNET_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=XLMProphetNetSeq2SeqLMOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + decoder_input_ids: Optional[torch.Tensor] = None, + decoder_attention_mask: Optional[torch.BoolTensor] = None, + head_mask: Optional[torch.Tensor] = None, + decoder_head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + encoder_outputs: Optional[torch.Tensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + decoder_inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XLMProphetNetSeq2SeqLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[-100, 0, ..., + config.vocab_size - 1]`. All labels set to `-100` are ignored (masked), the loss is only computed for + labels in `[0, ..., config.vocab_size]` + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMProphetNetForConditionalGeneration + + >>> tokenizer = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = XLMProphetNetForConditionalGeneration.from_pretrained( + ... "patrickvonplaten/xprophetnet-large-uncased-standalone" + ... ) + + >>> input_ids = tokenizer( + ... "Studies have been shown that owning a dog is good for you", return_tensors="pt" + ... ).input_ids # Batch size 1 + >>> decoder_input_ids = tokenizer("Studies show that", return_tensors="pt").input_ids # Batch size 1 + >>> outputs = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) + + >>> logits_next_token = outputs.logits # logits to predict next token as usual + >>> logits_ngram_next_tokens = outputs.logits_ngram # logits to predict 2nd, 3rd, ... next tokens + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if labels is not None and decoder_input_ids is None and decoder_inputs_embeds is None: + # get decoder inputs from shifting lm labels to the right + decoder_input_ids = self._shift_right(labels) + + outputs = self.prophetnet( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + head_mask=head_mask, + decoder_head_mask=decoder_head_mask, + cross_attn_head_mask=cross_attn_head_mask, + encoder_outputs=encoder_outputs, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + decoder_inputs_embeds=decoder_inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + batch_size, sequence_length = ( + decoder_input_ids.shape if decoder_input_ids is not None else decoder_inputs_embeds.shape[:2] + ) + + predicting_streams = outputs[1].view(batch_size, self.config.ngram, sequence_length, -1) + predict_logits = self.lm_head(predicting_streams) + + logits = predict_logits[:, 0] + logits_ngram = predict_logits[:, 1:] if self.config.ngram > 1 else None + + # To use .view in loss computation, make sure that logits is contiguous. + if not logits.is_contiguous(): + logits = logits.contiguous() + + loss = None + if labels is not None: + loss = self._compute_loss(predict_logits, labels) + + if not return_dict: + all_logits = tuple(v for v in [logits, logits_ngram] if v is not None) + return (loss,) + all_logits + outputs[2:] if loss is not None else all_logits + outputs[2:] + else: + return XLMProphetNetSeq2SeqLMOutput( + loss=loss, + logits=logits, + logits_ngram=logits_ngram, + past_key_values=outputs.past_key_values, + decoder_hidden_states=outputs.decoder_hidden_states, + decoder_ngram_hidden_states=outputs.decoder_ngram_hidden_states, + decoder_attentions=outputs.decoder_attentions, + decoder_ngram_attentions=outputs.decoder_ngram_attentions, + cross_attentions=outputs.cross_attentions, + encoder_last_hidden_state=outputs.encoder_last_hidden_state, + encoder_hidden_states=outputs.encoder_hidden_states, + encoder_attentions=outputs.encoder_attentions, + ) + + def _compute_loss(self, logits, labels, ignore_index=-100): + expend_targets = labels.new_zeros(self.config.ngram, labels.size(0), labels.size(1)).fill_(ignore_index) + + for i in range(self.config.ngram): + if i > 0 and self.disable_ngram_loss: + break + expend_targets[i, :, :] = labels + + logits = logits.transpose(0, 1).contiguous() + lprobs = nn.functional.log_softmax( + logits.view(-1, logits.size(-1)), + dim=-1, + dtype=torch.float32, + ) + + loss = nn.functional.nll_loss(lprobs, expend_targets.view(-1), reduction="mean") + + if self.config.eps > 0.0: + smooth_loss = -lprobs.sum(dim=-1, keepdim=True) + non_masked_tokens = expend_targets.ne(ignore_index).view(-1) + smooth_loss = smooth_loss[non_masked_tokens] + smooth_loss = smooth_loss.mean() + + eps_i = self.config.eps / lprobs.size(-1) + loss = (1.0 - self.config.eps) * loss + eps_i * smooth_loss + + return loss + + def prepare_inputs_for_generation( + self, + decoder_input_ids, + past_key_values=None, + attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, + use_cache=None, + encoder_outputs=None, + **kwargs, + ): + assert encoder_outputs is not None, "`encoder_outputs` have to be passed for generation." + + if past_key_values: + decoder_input_ids = decoder_input_ids[:, -1:] + # first step, decoder_cached_states are empty + return { + "input_ids": None, # encoder_outputs is defined. input_ids not needed + "encoder_outputs": encoder_outputs, + "past_key_values": past_key_values, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + "cross_attn_head_mask": cross_attn_head_mask, + "use_cache": use_cache, + } + + def prepare_decoder_input_ids_from_labels(self, labels: torch.Tensor): + return self._shift_right(labels) + + @staticmethod + # Copied from transformers.models.bart.modeling_bart.BartForConditionalGeneration._reorder_cache + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + # cached cross_attention states don't have to be reordered -> they are always the same + reordered_past += ( + tuple(past_state.index_select(0, beam_idx) for past_state in layer_past[:2]) + layer_past[2:], + ) + return reordered_past + + def get_encoder(self): + return self.prophetnet.encoder + + def get_decoder(self): + return self.prophetnet.decoder + + +@add_start_docstrings( + "The standalone decoder part of the XLMProphetNetModel with a lm head on top. The model can be used for causal" + " language modeling.", + XLM_PROPHETNET_START_DOCSTRING, +) +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetForCausalLM with microsoft/prophetnet-large-uncased->patrickvonplaten/xprophetnet-large-uncased-standalone, ProphetNet->XLMProphetNet, PROPHETNET->XLM_PROPHETNET +class XLMProphetNetForCausalLM(XLMProphetNetPreTrainedModel): + _keys_to_ignore_on_load_missing = ["lm_head.weight"] + + def __init__(self, config: XLMProphetNetConfig): + # set config for CLM + config = copy.deepcopy(config) + config.is_decoder = True + config.is_encoder_decoder = False + super().__init__(config) + self.prophetnet = XLMProphetNetDecoderWrapper(config) + + self.padding_idx = config.pad_token_id + self.disable_ngram_loss = config.disable_ngram_loss + + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.prophetnet.decoder.word_embeddings + + def set_input_embeddings(self, value): + self.prophetnet.decoder.word_embeddings = value + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def set_decoder(self, decoder): + self.prophetnet.decoder = decoder + + def get_decoder(self): + return self.prophetnet.decoder + + @add_start_docstrings_to_model_forward(XLM_PROPHETNET_STANDALONE_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=XLMProphetNetDecoderLMOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + cross_attn_head_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.Tensor]]] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, XLMProphetNetDecoderLMOutput]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + cross_attn_head_mask (`torch.Tensor` of shape `(decoder_layers, decoder_attention_heads)`, *optional*): + Mask to nullify selected heads of the cross-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden-states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]` + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMProphetNetForCausalLM + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = XLMProphetNetForCausalLM.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> assert model.config.is_decoder, f"{model.__class__} has to be configured as a decoder." + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> logits = outputs.logits + + >>> # Model can also be used with EncoderDecoder framework + >>> from transformers import BertTokenizer, EncoderDecoderModel, AutoTokenizer + >>> import torch + + >>> tokenizer_enc = BertTokenizer.from_pretrained("bert-large-uncased") + >>> tokenizer_dec = AutoTokenizer.from_pretrained("patrickvonplaten/xprophetnet-large-uncased-standalone") + >>> model = EncoderDecoderModel.from_encoder_decoder_pretrained( + ... "bert-large-uncased", "patrickvonplaten/xprophetnet-large-uncased-standalone" + ... ) + + >>> ARTICLE = ( + ... "the us state department said wednesday it had received no " + ... "formal word from bolivia that it was expelling the us ambassador there " + ... "but said the charges made against him are `` baseless ." + ... ) + >>> input_ids = tokenizer_enc(ARTICLE, return_tensors="pt").input_ids + >>> labels = tokenizer_dec( + ... "us rejects charges against its ambassador in bolivia", return_tensors="pt" + ... ).input_ids + >>> outputs = model(input_ids=input_ids, decoder_input_ids=labels[:, :-1], labels=labels[:, 1:]) + + >>> loss = outputs.loss + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # decoder outputs consists of (dec_features, past_key_values, dec_hidden, dec_attn) + outputs = self.prophetnet.decoder( + input_ids=input_ids, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + head_mask=head_mask, + cross_attn_head_mask=cross_attn_head_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + batch_size, sequence_length = input_ids.shape if input_ids is not None else inputs_embeds.shape[:2] + + predicting_streams = outputs[1].view(batch_size, self.config.ngram, sequence_length, -1) + predict_logits = self.lm_head(predicting_streams) + + logits = predict_logits[:, 0] + logits_ngram = predict_logits[:, 1:] if self.config.ngram > 1 else None + + loss = None + if labels is not None: + loss = self._compute_loss(predict_logits, labels) + + if not return_dict: + all_logits = tuple(v for v in [logits, logits_ngram] if v is not None) + return (loss,) + all_logits + outputs[2:] if loss is not None else all_logits + outputs[2:] + else: + return XLMProphetNetDecoderLMOutput( + loss=loss, + logits=logits, + logits_ngram=logits_ngram, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + hidden_states_ngram=outputs.hidden_states_ngram, + attentions=outputs.attentions, + ngram_attentions=outputs.ngram_attentions, + cross_attentions=outputs.cross_attentions, + ) + + def _compute_loss(self, logits, labels, ignore_index=-100): + expend_targets = labels.new_zeros(self.config.ngram, labels.size(0), labels.size(1)).fill_(ignore_index) + + for i in range(self.config.ngram): + if i > 0 and self.disable_ngram_loss: + break + expend_targets[i, :, :] = labels + + logits = logits.transpose(0, 1).contiguous() + lprobs = nn.functional.log_softmax( + logits.view(-1, logits.size(-1)), + dim=-1, + dtype=torch.float32, + ) + + loss = nn.functional.nll_loss(lprobs, expend_targets.view(-1), reduction="mean") + + if self.config.eps > 0.0: + smooth_loss = -lprobs.sum(dim=-1, keepdim=True) + non_masked_tokens = expend_targets.ne(ignore_index).view(-1) + smooth_loss = smooth_loss[non_masked_tokens] + smooth_loss = smooth_loss.mean() + + eps_i = self.config.eps / lprobs.size(-1) + loss = (1.0 - self.config.eps) * loss + eps_i * smooth_loss + + return loss + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + head_mask=None, + use_cache=None, + **kwargs, + ): + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_ids.shape) + + if past_key_values: + input_ids = input_ids[:, -1:] + # first step, decoder_cached_states are empty + return { + "input_ids": input_ids, # encoder_outputs is defined. input_ids not needed + "attention_mask": attention_mask, + "head_mask": head_mask, + "past_key_values": past_key_values, + "use_cache": use_cache, + } + + @staticmethod + # Copied from transformers.models.bart.modeling_bart.BartForCausalLM._reorder_cache + def _reorder_cache(past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past + + +# Copied from transformers.models.prophetnet.modeling_prophetnet.ProphetNetDecoderWrapper with ProphetNet->XLMProphetNet, prophetnet->XLMProphetNet +class XLMProphetNetDecoderWrapper(XLMProphetNetPreTrainedModel): + """ + This is a wrapper class, so that [`XLMProphetNetForCausalLM`] can correctly be loaded from pretrained XLMProphetNet + classes. + """ + + def __init__(self, config: XLMProphetNetConfig): + super().__init__(config) + self.decoder = XLMProphetNetDecoder(config) + + def forward(self, *args, **kwargs): + return self.decoder(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/tokenization_xlm_prophetnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/tokenization_xlm_prophetnet.py new file mode 100644 index 0000000000000000000000000000000000000000..8468eb49d64d5ad1b31199d4f33eae52cd784a8b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_prophetnet/tokenization_xlm_prophetnet.py @@ -0,0 +1,339 @@ +# coding=utf-8 +# Copyright 2020 The Microsoft Authors and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import os +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +from ...tokenization_utils import PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) + +SPIECE_UNDERLINE = "▁" + +VOCAB_FILES_NAMES = {"vocab_file": "prophetnet.tokenizer"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "microsoft/xprophetnet-large-wiki100-cased": ( + "https://huggingface.co/microsoft/xprophetnet-large-wiki100-cased/resolve/main/prophetnet.tokenizer" + ), + } +} + +PRETRAINED_INIT_CONFIGURATION = { + "microsoft/xprophetnet-large-wiki100-cased": {"do_lower_case": False}, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "microsoft/xprophetnet-large-wiki100-cased": 512, +} + + +def load_vocab(vocab_file): + """Loads a vocabulary file into a dictionary.""" + vocab = collections.OrderedDict() + with open(vocab_file, "r", encoding="utf-8") as reader: + tokens = reader.readlines() + for index, token in enumerate(tokens): + token = token.rstrip("\n") + vocab[token] = index + return vocab + + +class XLMProphetNetTokenizer(PreTrainedTokenizer): + """ + Adapted from [`RobertaTokenizer`] and [`XLNetTokenizer`]. Based on + [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="[SEP]", + eos_token="[SEP]", + sep_token="[SEP]", + unk_token="[UNK]", + pad_token="[PAD]", + cls_token="[CLS]", + mask_token="[MASK]", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + bos_token=bos_token, + eos_token=eos_token, + sep_token=sep_token, + unk_token=unk_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + try: + import sentencepiece as spm + except ImportError: + logger.warning( + "You need to install SentencePiece to use XLMRobertaTokenizer: https://github.com/google/sentencepiece" + " pip install sentencepiece" + ) + raise + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(str(vocab_file)) + self.vocab_file = vocab_file + + # Original fairseq vocab and spm vocab must be "aligned": + # Vocab | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 + # -------- | ------- | ------- | ------ | ------- | --- | --- | --- | ----- | ----- | ---- + # fairseq | '' | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' + # spm | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' | '▁a' + + # put special tokens and [unused] tokens into the vocab + self.fairseq_tokens_to_ids = {"[PAD]": 0, "[CLS]": 1, "[SEP]": 2, "[UNK]": 3, "[MASK]": 4} + + for i in range(10): + tok = f"[unused{i}]" + self.fairseq_tokens_to_ids[tok] = 5 + i + + # The first "real" token "," has position 15 in the embedding vocab and position 3 in the spm vocab + self.fairseq_offset = 12 + self.fairseq_ids_to_tokens = {v: k for k, v in self.fairseq_tokens_to_ids.items()} + for k in self.fairseq_tokens_to_ids.keys(): + self.unique_no_split_tokens.append(k) + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + return state + + def __setstate__(self, d): + self.__dict__ = d + try: + import sentencepiece as spm + except ImportError: + logger.warning( + "You need to install SentencePiece to use XLMRobertaTokenizer: https://github.com/google/sentencepiece" + " pip install sentencepiece" + ) + raise + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(self.vocab_file) + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return ([0] * len(token_ids_0)) + [1] + return ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. XLMProphetNet + does not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + + if token_ids_1 is None: + return len(token_ids_0 + sep) * [0] + return len(token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + @property + def vocab_size(self): + return len(self.sp_model) + self.fairseq_offset + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def _tokenize(self, text: str) -> str: + return self.sp_model.encode(text, out_type=str) + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + if token in self.fairseq_tokens_to_ids: + return self.fairseq_tokens_to_ids[token] + spm_id = self.sp_model.PieceToId(token) + + # Need to return unknown token if the SP model returned 0 + return spm_id + self.fairseq_offset if spm_id else self.unk_token_id + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + if index in self.fairseq_ids_to_tokens: + return self.fairseq_ids_to_tokens[index] + return self.sp_model.IdToPiece(index - self.fairseq_offset) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (strings for sub-words) in a single string.""" + out_string = "".join(tokens).replace(SPIECE_UNDERLINE, " ").strip() + return out_string + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + return (out_vocab_file,) + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. A XLMProphetNet sequence has the following format: + + - single sequence: `X [SEP]` + - pair of sequences: `A [SEP] B [SEP]` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: list of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return token_ids_0 + [self.sep_token_id] + sep = [self.sep_token_id] + return token_ids_0 + sep + token_ids_1 + sep diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..813cba9fe17c1df2f3cef3d2a523fd93f99348f0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/__init__.py @@ -0,0 +1,186 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_flax_available, + is_sentencepiece_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = { + "configuration_xlm_roberta": [ + "XLM_ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP", + "XLMRobertaConfig", + "XLMRobertaOnnxConfig", + ], +} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xlm_roberta"] = ["XLMRobertaTokenizer"] + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xlm_roberta_fast"] = ["XLMRobertaTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xlm_roberta"] = [ + "XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST", + "XLMRobertaForCausalLM", + "XLMRobertaForMaskedLM", + "XLMRobertaForMultipleChoice", + "XLMRobertaForQuestionAnswering", + "XLMRobertaForSequenceClassification", + "XLMRobertaForTokenClassification", + "XLMRobertaModel", + "XLMRobertaPreTrainedModel", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_xlm_roberta"] = [ + "TF_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFXLMRobertaForCausalLM", + "TFXLMRobertaForMaskedLM", + "TFXLMRobertaForMultipleChoice", + "TFXLMRobertaForQuestionAnswering", + "TFXLMRobertaForSequenceClassification", + "TFXLMRobertaForTokenClassification", + "TFXLMRobertaModel", + "TFXLMRobertaPreTrainedModel", + ] + +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_xlm_roberta"] = [ + "FLAX_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST", + "FlaxXLMRobertaForMaskedLM", + "FlaxXLMRobertaForCausalLM", + "FlaxXLMRobertaForMultipleChoice", + "FlaxXLMRobertaForQuestionAnswering", + "FlaxXLMRobertaForSequenceClassification", + "FlaxXLMRobertaForTokenClassification", + "FlaxXLMRobertaModel", + "FlaxXLMRobertaPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_xlm_roberta import ( + XLM_ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP, + XLMRobertaConfig, + XLMRobertaOnnxConfig, + ) + + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xlm_roberta import XLMRobertaTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xlm_roberta_fast import XLMRobertaTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xlm_roberta import ( + XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST, + XLMRobertaForCausalLM, + XLMRobertaForMaskedLM, + XLMRobertaForMultipleChoice, + XLMRobertaForQuestionAnswering, + XLMRobertaForSequenceClassification, + XLMRobertaForTokenClassification, + XLMRobertaModel, + XLMRobertaPreTrainedModel, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_xlm_roberta import ( + TF_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST, + TFXLMRobertaForCausalLM, + TFXLMRobertaForMaskedLM, + TFXLMRobertaForMultipleChoice, + TFXLMRobertaForQuestionAnswering, + TFXLMRobertaForSequenceClassification, + TFXLMRobertaForTokenClassification, + TFXLMRobertaModel, + TFXLMRobertaPreTrainedModel, + ) + + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_flax_xlm_roberta import ( + FLAX_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST, + FlaxXLMRobertaForCausalLM, + FlaxXLMRobertaForMaskedLM, + FlaxXLMRobertaForMultipleChoice, + FlaxXLMRobertaForQuestionAnswering, + FlaxXLMRobertaForSequenceClassification, + FlaxXLMRobertaForTokenClassification, + FlaxXLMRobertaModel, + FlaxXLMRobertaPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/configuration_xlm_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/configuration_xlm_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..98e12d07826edcac4368d0a9b9983f5fa021f571 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/configuration_xlm_roberta.py @@ -0,0 +1,169 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XLM-RoBERTa configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XLM_ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "xlm-roberta-base": "https://huggingface.co/xlm-roberta-base/resolve/main/config.json", + "xlm-roberta-large": "https://huggingface.co/xlm-roberta-large/resolve/main/config.json", + "xlm-roberta-large-finetuned-conll02-dutch": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-dutch/resolve/main/config.json" + ), + "xlm-roberta-large-finetuned-conll02-spanish": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-spanish/resolve/main/config.json" + ), + "xlm-roberta-large-finetuned-conll03-english": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-english/resolve/main/config.json" + ), + "xlm-roberta-large-finetuned-conll03-german": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-german/resolve/main/config.json" + ), +} + + +class XLMRobertaConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XLMRobertaModel`] or a [`TFXLMRobertaModel`]. It + is used to instantiate a XLM-RoBERTa model according to the specified arguments, defining the model architecture. + Instantiating a configuration with the defaults will yield a similar configuration to that of the XLMRoBERTa + [xlm-roberta-base](https://huggingface.co/xlm-roberta-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the XLM-RoBERTa model. Defines the number of different tokens that can be represented by + the `inputs_ids` passed when calling [`XLMRobertaModel`] or [`TFXLMRobertaModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`XLMRobertaModel`] or + [`TFXLMRobertaModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + is_decoder (`bool`, *optional*, defaults to `False`): + Whether the model is used as a decoder or not. If `False`, the model is used as an encoder. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + classifier_dropout (`float`, *optional*): + The dropout ratio for the classification head. + + Examples: + + ```python + >>> from transformers import XLMRobertaConfig, XLMRobertaModel + + >>> # Initializing a XLM-RoBERTa xlm-roberta-base style configuration + >>> configuration = XLMRobertaConfig() + + >>> # Initializing a model (with random weights) from the xlm-roberta-base style configuration + >>> model = XLMRobertaModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "xlm-roberta" + + def __init__( + self, + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + position_embedding_type="absolute", + use_cache=True, + classifier_dropout=None, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.classifier_dropout = classifier_dropout + + +# Copied from transformers.models.roberta.configuration_roberta.RobertaOnnxConfig with Roberta->XLMRoberta +class XLMRobertaOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5e113770e544f871c08cd50545e298d531b5f0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_flax_xlm_roberta.py @@ -0,0 +1,1504 @@ +# coding=utf-8 +# Copyright 2022 Facebook AI Research and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Flax XLM-RoBERTa model.""" + +from typing import Callable, Optional, Tuple + +import flax.linen as nn +import jax +import jax.numpy as jnp +import numpy as np +from flax.core.frozen_dict import FrozenDict, freeze, unfreeze +from flax.linen import combine_masks, make_causal_mask +from flax.linen import partitioning as nn_partitioning +from flax.linen.attention import dot_product_attention_weights +from flax.traverse_util import flatten_dict, unflatten_dict +from jax import lax + +from ...modeling_flax_outputs import ( + FlaxBaseModelOutputWithPastAndCrossAttentions, + FlaxBaseModelOutputWithPooling, + FlaxBaseModelOutputWithPoolingAndCrossAttentions, + FlaxCausalLMOutputWithCrossAttentions, + FlaxMaskedLMOutput, + FlaxMultipleChoiceModelOutput, + FlaxQuestionAnsweringModelOutput, + FlaxSequenceClassifierOutput, + FlaxTokenClassifierOutput, +) +from ...modeling_flax_utils import ACT2FN, FlaxPreTrainedModel, append_call_sample_docstring, overwrite_call_docstring +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_xlm_roberta import XLMRobertaConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-roberta-base" +_CONFIG_FOR_DOC = "XLMRobertaConfig" + +remat = nn_partitioning.remat + +FLAX_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlm-roberta-base", + "xlm-roberta-large", + # See all XLM-RoBERTa models at https://huggingface.co/models?filter=xlm-roberta +] + + +# Copied from transformers.models.roberta.modeling_flax_roberta.create_position_ids_from_input_ids +def create_position_ids_from_input_ids(input_ids, padding_idx): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + input_ids: jnp.ndarray + padding_idx: int + + Returns: jnp.ndarray + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = (input_ids != padding_idx).astype("i4") + + if mask.ndim > 2: + mask = mask.reshape((-1, mask.shape[-1])) + incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask + incremental_indices = incremental_indices.reshape(input_ids.shape) + else: + incremental_indices = jnp.cumsum(mask, axis=1).astype("i4") * mask + + return incremental_indices.astype("i4") + padding_idx + + +XLM_ROBERTA_START_DOCSTRING = r""" + + This model inherits from [`FlaxPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading, saving and converting weights from PyTorch models) + + This model is also a Flax Linen [flax.linen.Module](https://flax.readthedocs.io/en/latest/flax.linen.html#module) + subclass. Use it as a regular Flax linen Module and refer to the Flax documentation for all matter related to + general usage and behavior. + + Finally, this model supports inherent JAX features such as: + + - [Just-In-Time (JIT) compilation](https://jax.readthedocs.io/en/latest/jax.html#just-in-time-compilation-jit) + - [Automatic Differentiation](https://jax.readthedocs.io/en/latest/jax.html#automatic-differentiation) + - [Vectorization](https://jax.readthedocs.io/en/latest/jax.html#vectorization-vmap) + - [Parallelization](https://jax.readthedocs.io/en/latest/jax.html#parallelization-pmap) + + Parameters: + config ([`XLMRobertaConfig`]): Model configuration class with all the parameters of the + model. Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~FlaxPreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_ROBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`numpy.ndarray` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`numpy.ndarray` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`numpy.ndarray` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`numpy.ndarray` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + head_mask (`numpy.ndarray` of shape `({0})`, `optional): + Mask to nullify selected heads of the attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEmbeddings with Bert->XLMRoberta +class FlaxXLMRobertaEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.word_embeddings = nn.Embed( + self.config.vocab_size, + self.config.hidden_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + dtype=self.dtype, + ) + self.position_embeddings = nn.Embed( + self.config.max_position_embeddings, + self.config.hidden_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + dtype=self.dtype, + ) + self.token_type_embeddings = nn.Embed( + self.config.type_vocab_size, + self.config.hidden_size, + embedding_init=jax.nn.initializers.normal(stddev=self.config.initializer_range), + dtype=self.dtype, + ) + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, input_ids, token_type_ids, position_ids, attention_mask, deterministic: bool = True): + # Embed + inputs_embeds = self.word_embeddings(input_ids.astype("i4")) + position_embeds = self.position_embeddings(position_ids.astype("i4")) + token_type_embeddings = self.token_type_embeddings(token_type_ids.astype("i4")) + + # Sum all embeddings + hidden_states = inputs_embeds + token_type_embeddings + position_embeds + + # Layer Norm + hidden_states = self.LayerNorm(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + return hidden_states + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfAttention with Bert->XLMRoberta +class FlaxXLMRobertaSelfAttention(nn.Module): + config: XLMRobertaConfig + causal: bool = False + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.head_dim = self.config.hidden_size // self.config.num_attention_heads + if self.config.hidden_size % self.config.num_attention_heads != 0: + raise ValueError( + "`config.hidden_size`: {self.config.hidden_size} has to be a multiple of `config.num_attention_heads` " + " : {self.config.num_attention_heads}" + ) + + self.query = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.key = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.value = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + + if self.causal: + self.causal_mask = make_causal_mask( + jnp.ones((1, self.config.max_position_embeddings), dtype="bool"), dtype="bool" + ) + + def _split_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.config.num_attention_heads, self.head_dim)) + + def _merge_heads(self, hidden_states): + return hidden_states.reshape(hidden_states.shape[:2] + (self.config.hidden_size,)) + + @nn.compact + # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartAttention._concatenate_to_cache + def _concatenate_to_cache(self, key, value, query, attention_mask): + """ + This function takes projected key, value states from a single input token and concatenates the states to cached + states from previous steps. This function is slighly adapted from the official Flax repository: + https://github.com/google/flax/blob/491ce18759622506588784b4fca0e4bf05f8c8cd/flax/linen/attention.py#L252 + """ + # detect if we're initializing by absence of existing cache data. + is_initialized = self.has_variable("cache", "cached_key") + cached_key = self.variable("cache", "cached_key", jnp.zeros, key.shape, key.dtype) + cached_value = self.variable("cache", "cached_value", jnp.zeros, value.shape, value.dtype) + cache_index = self.variable("cache", "cache_index", lambda: jnp.array(0, dtype=jnp.int32)) + + if is_initialized: + *batch_dims, max_length, num_heads, depth_per_head = cached_key.value.shape + # update key, value caches with our new 1d spatial slices + cur_index = cache_index.value + indices = (0,) * len(batch_dims) + (cur_index, 0, 0) + key = lax.dynamic_update_slice(cached_key.value, key, indices) + value = lax.dynamic_update_slice(cached_value.value, value, indices) + cached_key.value = key + cached_value.value = value + num_updated_cache_vectors = query.shape[1] + cache_index.value = cache_index.value + num_updated_cache_vectors + # causal mask for cached decoder self-attention: our single query position should only attend to those key positions that have already been generated and cached, not the remaining zero elements. + pad_mask = jnp.broadcast_to( + jnp.arange(max_length) < cur_index + num_updated_cache_vectors, + tuple(batch_dims) + (1, num_updated_cache_vectors, max_length), + ) + attention_mask = combine_masks(pad_mask, attention_mask) + return key, value, attention_mask + + def __call__( + self, + hidden_states, + attention_mask, + layer_head_mask, + key_value_states: Optional[jnp.array] = None, + init_cache: bool = False, + deterministic=True, + output_attentions: bool = False, + ): + # if key_value_states are provided this layer is used as a cross-attention layer + # for the decoder + is_cross_attention = key_value_states is not None + batch_size = hidden_states.shape[0] + + # get query proj + query_states = self.query(hidden_states) + # get key, value proj + if is_cross_attention: + # cross_attentions + key_states = self.key(key_value_states) + value_states = self.value(key_value_states) + else: + # self_attention + key_states = self.key(hidden_states) + value_states = self.value(hidden_states) + + query_states = self._split_heads(query_states) + key_states = self._split_heads(key_states) + value_states = self._split_heads(value_states) + + # handle cache prepare causal attention mask + if self.causal: + query_length, key_length = query_states.shape[1], key_states.shape[1] + if self.has_variable("cache", "cached_key"): + mask_shift = self.variables["cache"]["cache_index"] + max_decoder_length = self.variables["cache"]["cached_key"].shape[1] + causal_mask = lax.dynamic_slice( + self.causal_mask, (0, 0, mask_shift, 0), (1, 1, query_length, max_decoder_length) + ) + else: + causal_mask = self.causal_mask[:, :, :query_length, :key_length] + causal_mask = jnp.broadcast_to(causal_mask, (batch_size,) + causal_mask.shape[1:]) + + # combine masks if needed + if attention_mask is not None and self.causal: + attention_mask = jnp.broadcast_to(jnp.expand_dims(attention_mask, axis=(-3, -2)), causal_mask.shape) + attention_mask = combine_masks(attention_mask, causal_mask) + elif self.causal: + attention_mask = causal_mask + elif attention_mask is not None: + attention_mask = jnp.expand_dims(attention_mask, axis=(-3, -2)) + + # During fast autoregressive decoding, we feed one position at a time, + # and cache the keys and values step by step. + if self.causal and (self.has_variable("cache", "cached_key") or init_cache): + key_states, value_states, attention_mask = self._concatenate_to_cache( + key_states, value_states, query_states, attention_mask + ) + + # Convert the boolean attention mask to an attention bias. + if attention_mask is not None: + # attention mask in the form of attention bias + attention_bias = lax.select( + attention_mask > 0, + jnp.full(attention_mask.shape, 0.0).astype(self.dtype), + jnp.full(attention_mask.shape, jnp.finfo(self.dtype).min).astype(self.dtype), + ) + else: + attention_bias = None + + dropout_rng = None + if not deterministic and self.config.attention_probs_dropout_prob > 0.0: + dropout_rng = self.make_rng("dropout") + + attn_weights = dot_product_attention_weights( + query_states, + key_states, + bias=attention_bias, + dropout_rng=dropout_rng, + dropout_rate=self.config.attention_probs_dropout_prob, + broadcast_dropout=True, + deterministic=deterministic, + dtype=self.dtype, + precision=None, + ) + + # Mask heads if we want to + if layer_head_mask is not None: + attn_weights = jnp.einsum("...hqk,h->...hqk", attn_weights, layer_head_mask) + + attn_output = jnp.einsum("...hqk,...khd->...qhd", attn_weights, value_states) + attn_output = attn_output.reshape(attn_output.shape[:2] + (-1,)) + + outputs = (attn_output, attn_weights) if output_attentions else (attn_output,) + return outputs + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertSelfOutput with Bert->XLMRoberta +class FlaxXLMRobertaSelfOutput(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + + def __call__(self, hidden_states, input_tensor, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertAttention with Bert->XLMRoberta +class FlaxXLMRobertaAttention(nn.Module): + config: XLMRobertaConfig + causal: bool = False + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.self = FlaxXLMRobertaSelfAttention(self.config, causal=self.causal, dtype=self.dtype) + self.output = FlaxXLMRobertaSelfOutput(self.config, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask, + layer_head_mask, + key_value_states=None, + init_cache=False, + deterministic=True, + output_attentions: bool = False, + ): + # Attention mask comes in as attention_mask.shape == (*batch_sizes, kv_length) + # FLAX expects: attention_mask.shape == (*batch_sizes, 1, 1, kv_length) such that it is broadcastable + # with attn_weights.shape == (*batch_sizes, num_heads, q_length, kv_length) + attn_outputs = self.self( + hidden_states, + attention_mask, + layer_head_mask=layer_head_mask, + key_value_states=key_value_states, + init_cache=init_cache, + deterministic=deterministic, + output_attentions=output_attentions, + ) + attn_output = attn_outputs[0] + hidden_states = self.output(attn_output, hidden_states, deterministic=deterministic) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_outputs[1],) + + return outputs + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertIntermediate with Bert->XLMRoberta +class FlaxXLMRobertaIntermediate(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.intermediate_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.activation = ACT2FN[self.config.hidden_act] + + def __call__(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.activation(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertOutput with Bert->XLMRoberta +class FlaxXLMRobertaOutput(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + self.LayerNorm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + + def __call__(self, hidden_states, attention_output, deterministic: bool = True): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.LayerNorm(hidden_states + attention_output) + return hidden_states + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayer with Bert->XLMRoberta +class FlaxXLMRobertaLayer(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.attention = FlaxXLMRobertaAttention(self.config, causal=self.config.is_decoder, dtype=self.dtype) + self.intermediate = FlaxXLMRobertaIntermediate(self.config, dtype=self.dtype) + self.output = FlaxXLMRobertaOutput(self.config, dtype=self.dtype) + if self.config.add_cross_attention: + self.crossattention = FlaxXLMRobertaAttention(self.config, causal=False, dtype=self.dtype) + + def __call__( + self, + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + output_attentions: bool = False, + ): + # Self Attention + attention_outputs = self.attention( + hidden_states, + attention_mask, + layer_head_mask=layer_head_mask, + init_cache=init_cache, + deterministic=deterministic, + output_attentions=output_attentions, + ) + attention_output = attention_outputs[0] + + # Cross-Attention Block + if encoder_hidden_states is not None: + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask=encoder_attention_mask, + layer_head_mask=layer_head_mask, + key_value_states=encoder_hidden_states, + deterministic=deterministic, + output_attentions=output_attentions, + ) + attention_output = cross_attention_outputs[0] + + hidden_states = self.intermediate(attention_output) + hidden_states = self.output(hidden_states, attention_output, deterministic=deterministic) + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attention_outputs[1],) + if encoder_hidden_states is not None: + outputs += (cross_attention_outputs[1],) + return outputs + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertLayerCollection with Bert->XLMRoberta +class FlaxXLMRobertaLayerCollection(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + gradient_checkpointing: bool = False + + def setup(self): + if self.gradient_checkpointing: + FlaxXLMRobertaCheckpointLayer = remat(FlaxXLMRobertaLayer, static_argnums=(5, 6, 7)) + self.layers = [ + FlaxXLMRobertaCheckpointLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.num_hidden_layers) + ] + else: + self.layers = [ + FlaxXLMRobertaLayer(self.config, name=str(i), dtype=self.dtype) + for i in range(self.config.num_hidden_layers) + ] + + def __call__( + self, + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + all_attentions = () if output_attentions else None + all_hidden_states = () if output_hidden_states else None + all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None + + # Check if head_mask has a correct number of layers specified if desired + if head_mask is not None: + if head_mask.shape[0] != (len(self.layers)): + raise ValueError( + f"The head_mask should be specified for {len(self.layers)} layers, but it is for " + f" {head_mask.shape[0]}." + ) + + for i, layer in enumerate(self.layers): + if output_hidden_states: + all_hidden_states += (hidden_states,) + + layer_outputs = layer( + hidden_states, + attention_mask, + head_mask[i] if head_mask is not None else None, + encoder_hidden_states, + encoder_attention_mask, + init_cache, + deterministic, + output_attentions, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions += (layer_outputs[1],) + + if encoder_hidden_states is not None: + all_cross_attentions += (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states += (hidden_states,) + + outputs = (hidden_states, all_hidden_states, all_attentions, all_cross_attentions) + + if not return_dict: + return tuple(v for v in outputs if v is not None) + + return FlaxBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertEncoder with Bert->XLMRoberta +class FlaxXLMRobertaEncoder(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + gradient_checkpointing: bool = False + + def setup(self): + self.layer = FlaxXLMRobertaLayerCollection( + self.config, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + + def __call__( + self, + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + return self.layer( + hidden_states, + attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + init_cache=init_cache, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPooler with Bert->XLMRoberta +class FlaxXLMRobertaPooler(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + dtype=self.dtype, + ) + + def __call__(self, hidden_states): + cls_hidden_state = hidden_states[:, 0] + cls_hidden_state = self.dense(cls_hidden_state) + return nn.tanh(cls_hidden_state) + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaLMHead with Roberta->XLMRoberta +class FlaxXLMRobertaLMHead(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + bias_init: Callable[..., np.ndarray] = jax.nn.initializers.zeros + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.layer_norm = nn.LayerNorm(epsilon=self.config.layer_norm_eps, dtype=self.dtype) + self.decoder = nn.Dense( + self.config.vocab_size, + dtype=self.dtype, + use_bias=False, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + self.bias = self.param("bias", self.bias_init, (self.config.vocab_size,)) + + def __call__(self, hidden_states, shared_embedding=None): + hidden_states = self.dense(hidden_states) + hidden_states = ACT2FN["gelu"](hidden_states) + hidden_states = self.layer_norm(hidden_states) + + if shared_embedding is not None: + hidden_states = self.decoder.apply({"params": {"kernel": shared_embedding.T}}, hidden_states) + else: + hidden_states = self.decoder(hidden_states) + + bias = jnp.asarray(self.bias, self.dtype) + hidden_states += bias + return hidden_states + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaClassificationHead with Roberta->XLMRoberta +class FlaxXLMRobertaClassificationHead(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + + def setup(self): + self.dense = nn.Dense( + self.config.hidden_size, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + classifier_dropout = ( + self.config.classifier_dropout + if self.config.classifier_dropout is not None + else self.config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(rate=classifier_dropout) + self.out_proj = nn.Dense( + self.config.num_labels, + dtype=self.dtype, + kernel_init=jax.nn.initializers.normal(self.config.initializer_range), + ) + + def __call__(self, hidden_states, deterministic=True): + hidden_states = hidden_states[:, 0, :] # take token (equiv. to [CLS]) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.dense(hidden_states) + hidden_states = nn.tanh(hidden_states) + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + hidden_states = self.out_proj(hidden_states) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaPreTrainedModel with Roberta->XLMRoberta, roberta->xlm-roberta, ROBERTA->XLM_ROBERTA +class FlaxXLMRobertaPreTrainedModel(FlaxPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMRobertaConfig + base_model_prefix = "xlm-roberta" + + module_class: nn.Module = None + + def __init__( + self, + config: XLMRobertaConfig, + input_shape: Tuple = (1, 1), + seed: int = 0, + dtype: jnp.dtype = jnp.float32, + _do_init: bool = True, + gradient_checkpointing: bool = False, + **kwargs, + ): + module = self.module_class(config=config, dtype=dtype, gradient_checkpointing=gradient_checkpointing, **kwargs) + super().__init__(config, module, input_shape=input_shape, seed=seed, dtype=dtype, _do_init=_do_init) + + # Copied from transformers.models.bert.modeling_flax_bert.FlaxBertPreTrainedModel.enable_gradient_checkpointing + def enable_gradient_checkpointing(self): + self._module = self.module_class( + config=self.config, + dtype=self.dtype, + gradient_checkpointing=True, + ) + + def init_weights(self, rng: jax.random.PRNGKey, input_shape: Tuple, params: FrozenDict = None) -> FrozenDict: + # init input tensors + input_ids = jnp.zeros(input_shape, dtype="i4") + token_type_ids = jnp.ones_like(input_ids) + position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) + attention_mask = jnp.ones_like(input_ids) + head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) + + params_rng, dropout_rng = jax.random.split(rng) + rngs = {"params": params_rng, "dropout": dropout_rng} + + if self.config.add_cross_attention: + encoder_hidden_states = jnp.zeros(input_shape + (self.config.hidden_size,)) + encoder_attention_mask = attention_mask + module_init_outputs = self.module.init( + rngs, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + return_dict=False, + ) + else: + module_init_outputs = self.module.init( + rngs, input_ids, attention_mask, token_type_ids, position_ids, head_mask, return_dict=False + ) + + random_params = module_init_outputs["params"] + + if params is not None: + random_params = flatten_dict(unfreeze(random_params)) + params = flatten_dict(unfreeze(params)) + for missing_key in self._missing_keys: + params[missing_key] = random_params[missing_key] + self._missing_keys = set() + return freeze(unflatten_dict(params)) + else: + return random_params + + # Copied from transformers.models.bart.modeling_flax_bart.FlaxBartDecoderPreTrainedModel.init_cache + def init_cache(self, batch_size, max_length): + r""" + Args: + batch_size (`int`): + batch_size used for fast auto-regressive decoding. Defines the batch size of the initialized cache. + max_length (`int`): + maximum possible length for auto-regressive decoding. Defines the sequence length of the initialized + cache. + """ + # init input variables to retrieve cache + input_ids = jnp.ones((batch_size, max_length), dtype="i4") + attention_mask = jnp.ones_like(input_ids, dtype="i4") + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + init_variables = self.module.init( + jax.random.PRNGKey(0), input_ids, attention_mask, position_ids, return_dict=False, init_cache=True + ) + return unfreeze(init_variables["cache"]) + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def __call__( + self, + input_ids, + attention_mask=None, + token_type_ids=None, + position_ids=None, + head_mask=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + params: dict = None, + dropout_rng: jax.random.PRNGKey = None, + train: bool = False, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + past_key_values: dict = None, + ): + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.return_dict + + # init input tensors if not passed + if token_type_ids is None: + token_type_ids = jnp.zeros_like(input_ids) + + if position_ids is None: + position_ids = create_position_ids_from_input_ids(input_ids, self.config.pad_token_id) + + if attention_mask is None: + attention_mask = jnp.ones_like(input_ids) + + if head_mask is None: + head_mask = jnp.ones((self.config.num_hidden_layers, self.config.num_attention_heads)) + + # Handle any PRNG if needed + rngs = {} + if dropout_rng is not None: + rngs["dropout"] = dropout_rng + + inputs = {"params": params or self.params} + + if self.config.add_cross_attention: + # if past_key_values are passed then cache is already initialized a private flag init_cache has to be passed + # down to ensure cache is used. It has to be made sure that cache is marked as mutable so that it can be + # changed by FlaxXLMRobertaAttention module + if past_key_values: + inputs["cache"] = past_key_values + mutable = ["cache"] + else: + mutable = False + + outputs = self.module.apply( + inputs, + jnp.array(input_ids, dtype="i4"), + jnp.array(attention_mask, dtype="i4"), + token_type_ids=jnp.array(token_type_ids, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + head_mask=jnp.array(head_mask, dtype="i4"), + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + deterministic=not train, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + rngs=rngs, + mutable=mutable, + ) + + # add updated cache to model output + if past_key_values is not None and return_dict: + outputs, past_key_values = outputs + outputs["past_key_values"] = unfreeze(past_key_values["cache"]) + return outputs + elif past_key_values is not None and not return_dict: + outputs, past_key_values = outputs + outputs = outputs[:1] + (unfreeze(past_key_values["cache"]),) + outputs[1:] + + else: + outputs = self.module.apply( + inputs, + jnp.array(input_ids, dtype="i4"), + jnp.array(attention_mask, dtype="i4"), + token_type_ids=jnp.array(token_type_ids, dtype="i4"), + position_ids=jnp.array(position_ids, dtype="i4"), + head_mask=jnp.array(head_mask, dtype="i4"), + deterministic=not train, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + rngs=rngs, + ) + + return outputs + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertModule with Bert->XLMRoberta +class FlaxXLMRobertaModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 # the dtype of the computation + add_pooling_layer: bool = True + gradient_checkpointing: bool = False + + def setup(self): + self.embeddings = FlaxXLMRobertaEmbeddings(self.config, dtype=self.dtype) + self.encoder = FlaxXLMRobertaEncoder( + self.config, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.pooler = FlaxXLMRobertaPooler(self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids: Optional[jnp.ndarray] = None, + position_ids: Optional[jnp.ndarray] = None, + head_mask: Optional[jnp.ndarray] = None, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # make sure `token_type_ids` is correctly initialized when not passed + if token_type_ids is None: + token_type_ids = jnp.zeros_like(input_ids) + + # make sure `position_ids` is correctly initialized when not passed + if position_ids is None: + position_ids = jnp.broadcast_to(jnp.arange(jnp.atleast_2d(input_ids).shape[-1]), input_ids.shape) + + hidden_states = self.embeddings( + input_ids, token_type_ids, position_ids, attention_mask, deterministic=deterministic + ) + outputs = self.encoder( + hidden_states, + attention_mask, + head_mask=head_mask, + deterministic=deterministic, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + init_cache=init_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + hidden_states = outputs[0] + pooled = self.pooler(hidden_states) if self.add_pooling_layer else None + + if not return_dict: + # if pooled is None, don't return it + if pooled is None: + return (hidden_states,) + outputs[1:] + return (hidden_states, pooled) + outputs[1:] + + return FlaxBaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=hidden_states, + pooler_output=pooled, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@add_start_docstrings( + "The bare XLM RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", + XLM_ROBERTA_START_DOCSTRING, +) +class FlaxXLMRobertaModel(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaModule + + +append_call_sample_docstring(FlaxXLMRobertaModel, _CHECKPOINT_FOR_DOC, FlaxBaseModelOutputWithPooling, _CONFIG_FOR_DOC) + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForMaskedLMModule with Roberta->XLMRoberta +class FlaxXLMRobertaForMaskedLMModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + add_pooling_layer=False, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.lm_head = FlaxXLMRobertaLMHead(config=self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + if self.config.tie_word_embeddings: + shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] + else: + shared_embedding = None + + # Compute the prediction scores + logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxMaskedLMOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings("""XLM RoBERTa Model with a `language modeling` head on top.""", XLM_ROBERTA_START_DOCSTRING) +class FlaxXLMRobertaForMaskedLM(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForMaskedLMModule + + +append_call_sample_docstring( + FlaxXLMRobertaForMaskedLM, + _CHECKPOINT_FOR_DOC, + FlaxBaseModelOutputWithPooling, + _CONFIG_FOR_DOC, + mask="", +) + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForSequenceClassificationModule with Roberta->XLMRoberta +class FlaxXLMRobertaForSequenceClassificationModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + dtype=self.dtype, + add_pooling_layer=False, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.classifier = FlaxXLMRobertaClassificationHead(config=self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + logits = self.classifier(sequence_output, deterministic=deterministic) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxSequenceClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Roberta Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +class FlaxXLMRobertaForSequenceClassification(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForSequenceClassificationModule + + +append_call_sample_docstring( + FlaxXLMRobertaForSequenceClassification, + _CHECKPOINT_FOR_DOC, + FlaxSequenceClassifierOutput, + _CONFIG_FOR_DOC, +) + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForMultipleChoiceModule with Bert->XLMRoberta, with self.bert->self.roberta +class FlaxXLMRobertaForMultipleChoiceModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.dropout = nn.Dropout(rate=self.config.hidden_dropout_prob) + self.classifier = nn.Dense(1, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + num_choices = input_ids.shape[1] + input_ids = input_ids.reshape(-1, input_ids.shape[-1]) if input_ids is not None else None + attention_mask = attention_mask.reshape(-1, attention_mask.shape[-1]) if attention_mask is not None else None + token_type_ids = token_type_ids.reshape(-1, token_type_ids.shape[-1]) if token_type_ids is not None else None + position_ids = position_ids.reshape(-1, position_ids.shape[-1]) if position_ids is not None else None + + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + pooled_output = outputs[1] + pooled_output = self.dropout(pooled_output, deterministic=deterministic) + logits = self.classifier(pooled_output) + + reshaped_logits = logits.reshape(-1, num_choices) + + if not return_dict: + return (reshaped_logits,) + outputs[2:] + + return FlaxMultipleChoiceModelOutput( + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +class FlaxXLMRobertaForMultipleChoice(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForMultipleChoiceModule + + +overwrite_call_docstring( + FlaxXLMRobertaForMultipleChoice, XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") +) +append_call_sample_docstring( + FlaxXLMRobertaForMultipleChoice, + _CHECKPOINT_FOR_DOC, + FlaxMultipleChoiceModelOutput, + _CONFIG_FOR_DOC, +) + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForTokenClassificationModule with Bert->XLMRoberta, with self.bert->self.roberta +class FlaxXLMRobertaForTokenClassificationModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + dtype=self.dtype, + add_pooling_layer=False, + gradient_checkpointing=self.gradient_checkpointing, + ) + classifier_dropout = ( + self.config.classifier_dropout + if self.config.classifier_dropout is not None + else self.config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(rate=classifier_dropout) + self.classifier = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + hidden_states = self.dropout(hidden_states, deterministic=deterministic) + logits = self.classifier(hidden_states) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxTokenClassifierOutput( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Roberta Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +class FlaxXLMRobertaForTokenClassification(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForTokenClassificationModule + + +append_call_sample_docstring( + FlaxXLMRobertaForTokenClassification, + _CHECKPOINT_FOR_DOC, + FlaxTokenClassifierOutput, + _CONFIG_FOR_DOC, +) + + +# Copied from transformers.models.bert.modeling_flax_bert.FlaxBertForQuestionAnsweringModule with Bert->XLMRoberta, with self.bert->self.roberta +class FlaxXLMRobertaForQuestionAnsweringModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + dtype=self.dtype, + add_pooling_layer=False, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.qa_outputs = nn.Dense(self.config.num_labels, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + + logits = self.qa_outputs(hidden_states) + start_logits, end_logits = logits.split(self.config.num_labels, axis=-1) + start_logits = start_logits.squeeze(-1) + end_logits = end_logits.squeeze(-1) + + if not return_dict: + return (start_logits, end_logits) + outputs[1:] + + return FlaxQuestionAnsweringModelOutput( + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM Roberta Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_ROBERTA_START_DOCSTRING, +) +class FlaxXLMRobertaForQuestionAnswering(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForQuestionAnsweringModule + + +append_call_sample_docstring( + FlaxXLMRobertaForQuestionAnswering, + _CHECKPOINT_FOR_DOC, + FlaxQuestionAnsweringModelOutput, + _CONFIG_FOR_DOC, +) + + +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLMModule with Roberta->XLMRoberta +class FlaxXLMRobertaForCausalLMModule(nn.Module): + config: XLMRobertaConfig + dtype: jnp.dtype = jnp.float32 + gradient_checkpointing: bool = False + + def setup(self): + self.roberta = FlaxXLMRobertaModule( + config=self.config, + add_pooling_layer=False, + dtype=self.dtype, + gradient_checkpointing=self.gradient_checkpointing, + ) + self.lm_head = FlaxXLMRobertaLMHead(config=self.config, dtype=self.dtype) + + def __call__( + self, + input_ids, + attention_mask, + position_ids, + token_type_ids: Optional[jnp.ndarray] = None, + head_mask: Optional[jnp.ndarray] = None, + encoder_hidden_states: Optional[jnp.ndarray] = None, + encoder_attention_mask: Optional[jnp.ndarray] = None, + init_cache: bool = False, + deterministic: bool = True, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ): + # Model + outputs = self.roberta( + input_ids, + attention_mask, + token_type_ids, + position_ids, + head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + init_cache=init_cache, + deterministic=deterministic, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = outputs[0] + if self.config.tie_word_embeddings: + shared_embedding = self.roberta.variables["params"]["embeddings"]["word_embeddings"]["embedding"] + else: + shared_embedding = None + + # Compute the prediction scores + logits = self.lm_head(hidden_states, shared_embedding=shared_embedding) + + if not return_dict: + return (logits,) + outputs[1:] + + return FlaxCausalLMOutputWithCrossAttentions( + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + +@add_start_docstrings( + """ + XLM Roberta Model with a language modeling head on top (a linear layer on top of the hidden-states output) e.g for + autoregressive tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_flax_roberta.FlaxRobertaForCausalLM with Roberta->XLMRoberta +class FlaxXLMRobertaForCausalLM(FlaxXLMRobertaPreTrainedModel): + module_class = FlaxXLMRobertaForCausalLMModule + + def prepare_inputs_for_generation(self, input_ids, max_length, attention_mask: Optional[jnp.DeviceArray] = None): + # initializing the cache + batch_size, seq_length = input_ids.shape + + past_key_values = self.init_cache(batch_size, max_length) + # Note that usually one would have to put 0's in the attention_mask for x > input_ids.shape[-1] and x < cache_length. + # But since the decoder uses a causal mask, those positions are masked anyway. + # Thus, we can create a single static attention_mask here, which is more efficient for compilation + extended_attention_mask = jnp.ones((batch_size, max_length), dtype="i4") + if attention_mask is not None: + position_ids = attention_mask.cumsum(axis=-1) - 1 + extended_attention_mask = lax.dynamic_update_slice(extended_attention_mask, attention_mask, (0, 0)) + else: + position_ids = jnp.broadcast_to(jnp.arange(seq_length, dtype="i4")[None, :], (batch_size, seq_length)) + + return { + "past_key_values": past_key_values, + "attention_mask": extended_attention_mask, + "position_ids": position_ids, + } + + def update_inputs_for_generation(self, model_outputs, model_kwargs): + model_kwargs["past_key_values"] = model_outputs.past_key_values + model_kwargs["position_ids"] = model_kwargs["position_ids"][:, -1:] + 1 + return model_kwargs + + +append_call_sample_docstring( + FlaxXLMRobertaForCausalLM, + _CHECKPOINT_FOR_DOC, + FlaxCausalLMOutputWithCrossAttentions, + _CONFIG_FOR_DOC, +) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..b5fc694148e724f6aebb3870474ae83e36a54877 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_tf_xlm_roberta.py @@ -0,0 +1,1711 @@ +# coding=utf-8 +# Copyright 2019 Facebook AI Research and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" TF 2.0 XLM-RoBERTa model.""" + +import math +import warnings +from typing import Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_outputs import ( + TFBaseModelOutputWithPastAndCrossAttentions, + TFBaseModelOutputWithPoolingAndCrossAttentions, + TFCausalLMOutputWithCrossAttentions, + TFMaskedLMOutput, + TFMultipleChoiceModelOutput, + TFQuestionAnsweringModelOutput, + TFSequenceClassifierOutput, + TFTokenClassifierOutput, +) +from ...modeling_tf_utils import ( + TFCausalLanguageModelingLoss, + TFMaskedLanguageModelingLoss, + TFModelInputType, + TFMultipleChoiceLoss, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFTokenClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + DUMMY_INPUTS, + MULTIPLE_CHOICE_DUMMY_INPUTS, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, +) +from .configuration_xlm_roberta import XLMRobertaConfig + + +logger = logging.get_logger(__name__) + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-roberta-base" +_CONFIG_FOR_DOC = "XLMRobertaConfig" + +TF_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlm-roberta-base", + "xlm-roberta-large", + "joeddav/xlm-roberta-large-xnli", + "cardiffnlp/twitter-xlm-roberta-base-sentiment", + # See all XLM-RoBERTa models at https://huggingface.co/models?filter=xlm-roberta +] + +XLM_ROBERTA_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`XLMRobertaConfig`]): Model configuration class with all the parameters of the + model. Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_ROBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`Numpy array` or `tf.Tensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. Indices can be obtained using [`AutoTokenizer`]. See + [`PreTrainedTokenizer.__call__`] and [`PreTrainedTokenizer.encode`] for details. [What are input + IDs?](../glossary#input-ids) + attention_mask (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`Numpy array` or `tf.Tensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. [What are position IDs?](../glossary#position-ids) + head_mask (`Numpy array` or `tf.Tensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + inputs_embeds (`tf.Tensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. This argument can be used only in eager mode, in graph mode the value in the + config will be used instead. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. This argument can be used only in eager mode, in graph mode the value in the config will be + used instead. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. This argument can be used in + eager mode, in graph mode the value will always be set to True. + training (`bool`, *optional*, defaults to `False`): + Whether or not to use the model in training mode (some modules like dropout modules have different + behaviors between training and evaluation). +""" + + +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaEmbeddings with Roberta->XLMRoberta +class TFXLMRobertaEmbeddings(tf.keras.layers.Layer): + """ + Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. + """ + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.padding_idx = 1 + self.config = config + self.hidden_size = config.hidden_size + self.max_position_embeddings = config.max_position_embeddings + self.initializer_range = config.initializer_range + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def build(self, input_shape: tf.TensorShape): + with tf.name_scope("word_embeddings"): + self.weight = self.add_weight( + name="weight", + shape=[self.config.vocab_size, self.hidden_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("token_type_embeddings"): + self.token_type_embeddings = self.add_weight( + name="embeddings", + shape=[self.config.type_vocab_size, self.hidden_size], + initializer=get_initializer(self.initializer_range), + ) + + with tf.name_scope("position_embeddings"): + self.position_embeddings = self.add_weight( + name="embeddings", + shape=[self.max_position_embeddings, self.hidden_size], + initializer=get_initializer(self.initializer_range), + ) + + super().build(input_shape) + + def create_position_ids_from_input_ids(self, input_ids, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding + symbols are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + input_ids: tf.Tensor + Returns: tf.Tensor + """ + mask = tf.cast(tf.math.not_equal(input_ids, self.padding_idx), dtype=input_ids.dtype) + incremental_indices = (tf.math.cumsum(mask, axis=1) + past_key_values_length) * mask + + return incremental_indices + self.padding_idx + + def call( + self, + input_ids=None, + position_ids=None, + token_type_ids=None, + inputs_embeds=None, + past_key_values_length=0, + training=False, + ): + """ + Applies embedding based on inputs tensor. + + Returns: + final_embeddings (`tf.Tensor`): output embedding tensor. + """ + assert not (input_ids is None and inputs_embeds is None) + + if input_ids is not None: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.config.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.config.vocab_size})" + ), + ) + inputs_embeds = tf.gather(params=self.weight, indices=input_ids) + + input_shape = shape_list(inputs_embeds)[:-1] + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = self.create_position_ids_from_input_ids( + input_ids=input_ids, past_key_values_length=past_key_values_length + ) + else: + position_ids = tf.expand_dims( + tf.range(start=self.padding_idx + 1, limit=input_shape[-1] + self.padding_idx + 1), axis=0 + ) + + position_embeds = tf.gather(params=self.position_embeddings, indices=position_ids) + token_type_embeds = tf.gather(params=self.token_type_embeddings, indices=token_type_ids) + final_embeddings = inputs_embeds + position_embeds + token_type_embeds + final_embeddings = self.LayerNorm(inputs=final_embeddings) + final_embeddings = self.dropout(inputs=final_embeddings, training=training) + + return final_embeddings + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertPooler with Bert->XLMRoberta +class TFXLMRobertaPooler(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + activation="tanh", + name="dense", + ) + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(inputs=first_token_tensor) + + return pooled_output + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfAttention with Bert->XLMRoberta +class TFXLMRobertaSelfAttention(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number " + f"of attention heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + self.sqrt_att_head_size = math.sqrt(self.attention_head_size) + + self.query = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query" + ) + self.key = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key" + ) + self.value = tf.keras.layers.Dense( + units=self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value" + ) + self.dropout = tf.keras.layers.Dropout(rate=config.attention_probs_dropout_prob) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, tensor: tf.Tensor, batch_size: int) -> tf.Tensor: + # Reshape from [batch_size, seq_length, all_head_size] to [batch_size, seq_length, num_attention_heads, attention_head_size] + tensor = tf.reshape(tensor=tensor, shape=(batch_size, -1, self.num_attention_heads, self.attention_head_size)) + + # Transpose the tensor from [batch_size, seq_length, num_attention_heads, attention_head_size] to [batch_size, num_attention_heads, seq_length, attention_head_size] + return tf.transpose(tensor, perm=[0, 2, 1, 3]) + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + encoder_hidden_states: tf.Tensor, + encoder_attention_mask: tf.Tensor, + past_key_value: Tuple[tf.Tensor], + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + batch_size = shape_list(hidden_states)[0] + mixed_query_layer = self.query(inputs=hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(inputs=encoder_hidden_states), batch_size) + value_layer = self.transpose_for_scores(self.value(inputs=encoder_hidden_states), batch_size) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) + value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) + key_layer = tf.concat([past_key_value[0], key_layer], axis=2) + value_layer = tf.concat([past_key_value[1], value_layer], axis=2) + else: + key_layer = self.transpose_for_scores(self.key(inputs=hidden_states), batch_size) + value_layer = self.transpose_for_scores(self.value(inputs=hidden_states), batch_size) + + query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) + + if self.is_decoder: + # if cross_attention save Tuple(tf.Tensor, tf.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(tf.Tensor, tf.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + # (batch size, num_heads, seq_len_q, seq_len_k) + attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) + dk = tf.cast(self.sqrt_att_head_size, dtype=attention_scores.dtype) + attention_scores = tf.divide(attention_scores, dk) + + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in TFXLMRobertaModel call() function) + attention_scores = tf.add(attention_scores, attention_mask) + + # Normalize the attention scores to probabilities. + attention_probs = stable_softmax(logits=attention_scores, axis=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(inputs=attention_probs, training=training) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = tf.multiply(attention_probs, head_mask) + + attention_output = tf.matmul(attention_probs, value_layer) + attention_output = tf.transpose(attention_output, perm=[0, 2, 1, 3]) + + # (batch_size, seq_len_q, all_head_size) + attention_output = tf.reshape(tensor=attention_output, shape=(batch_size, -1, self.all_head_size)) + outputs = (attention_output, attention_probs) if output_attentions else (attention_output,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertSelfOutput with Bert->XLMRoberta +class TFXLMRobertaSelfOutput(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) + + return hidden_states + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertAttention with Bert->XLMRoberta +class TFXLMRobertaAttention(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.self_attention = TFXLMRobertaSelfAttention(config, name="self") + self.dense_output = TFXLMRobertaSelfOutput(config, name="output") + + def prune_heads(self, heads): + raise NotImplementedError + + def call( + self, + input_tensor: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + encoder_hidden_states: tf.Tensor, + encoder_attention_mask: tf.Tensor, + past_key_value: Tuple[tf.Tensor], + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + self_outputs = self.self_attention( + hidden_states=input_tensor, + attention_mask=attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_value, + output_attentions=output_attentions, + training=training, + ) + attention_output = self.dense_output( + hidden_states=self_outputs[0], input_tensor=input_tensor, training=training + ) + # add attentions (possibly with past_key_value) if we output them + outputs = (attention_output,) + self_outputs[1:] + + return outputs + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertIntermediate with Bert->XLMRoberta +class TFXLMRobertaIntermediate(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.intermediate_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = get_tf_activation(config.hidden_act) + else: + self.intermediate_act_fn = config.hidden_act + + def call(self, hidden_states: tf.Tensor) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertOutput with Bert->XLMRoberta +class TFXLMRobertaOutput(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.dense = tf.keras.layers.Dense( + units=config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.LayerNorm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="LayerNorm") + self.dropout = tf.keras.layers.Dropout(rate=config.hidden_dropout_prob) + + def call(self, hidden_states: tf.Tensor, input_tensor: tf.Tensor, training: bool = False) -> tf.Tensor: + hidden_states = self.dense(inputs=hidden_states) + hidden_states = self.dropout(inputs=hidden_states, training=training) + hidden_states = self.LayerNorm(inputs=hidden_states + input_tensor) + + return hidden_states + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertLayer with Bert->XLMRoberta +class TFXLMRobertaLayer(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + + self.attention = TFXLMRobertaAttention(config, name="attention") + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = TFXLMRobertaAttention(config, name="crossattention") + self.intermediate = TFXLMRobertaIntermediate(config, name="intermediate") + self.bert_output = TFXLMRobertaOutput(config, name="output") + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + encoder_hidden_states: Optional[tf.Tensor], + encoder_attention_mask: Optional[tf.Tensor], + past_key_value: Optional[Tuple[tf.Tensor]], + output_attentions: bool, + training: bool = False, + ) -> Tuple[tf.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + input_tensor=hidden_states, + attention_mask=attention_mask, + head_mask=head_mask, + encoder_hidden_states=None, + encoder_attention_mask=None, + past_key_value=self_attn_past_key_value, + output_attentions=output_attentions, + training=training, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + input_tensor=attention_output, + attention_mask=attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_value=cross_attn_past_key_value, + output_attentions=output_attentions, + training=training, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + intermediate_output = self.intermediate(hidden_states=attention_output) + layer_output = self.bert_output( + hidden_states=intermediate_output, input_tensor=attention_output, training=training + ) + outputs = (layer_output,) + outputs # add attentions if we output them + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + +# Copied from transformers.models.bert.modeling_tf_bert.TFBertEncoder with Bert->XLMRoberta +class TFXLMRobertaEncoder(tf.keras.layers.Layer): + def __init__(self, config: XLMRobertaConfig, **kwargs): + super().__init__(**kwargs) + self.config = config + self.layer = [TFXLMRobertaLayer(config, name=f"layer_._{i}") for i in range(config.num_hidden_layers)] + + def call( + self, + hidden_states: tf.Tensor, + attention_mask: tf.Tensor, + head_mask: tf.Tensor, + encoder_hidden_states: Optional[tf.Tensor], + encoder_attention_mask: Optional[tf.Tensor], + past_key_values: Optional[Tuple[Tuple[tf.Tensor]]], + use_cache: Optional[bool], + output_attentions: bool, + output_hidden_states: bool, + return_dict: bool, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPastAndCrossAttentions, Tuple[tf.Tensor]]: + all_hidden_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + past_key_value = past_key_values[i] if past_key_values is not None else None + + layer_outputs = layer_module( + hidden_states=hidden_states, + attention_mask=attention_mask, + head_mask=head_mask[i], + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_value=past_key_value, + output_attentions=output_attentions, + training=training, + ) + hidden_states = layer_outputs[0] + + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + if self.config.add_cross_attention and encoder_hidden_states is not None: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + # Add last layer + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v for v in [hidden_states, all_hidden_states, all_attentions, all_cross_attentions] if v is not None + ) + + return TFBaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_attentions, + cross_attentions=all_cross_attentions, + ) + + +@keras_serializable +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaMainLayer with Roberta->XLMRoberta +class TFXLMRobertaMainLayer(tf.keras.layers.Layer): + config_class = XLMRobertaConfig + + def __init__(self, config, add_pooling_layer=True, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.is_decoder = config.is_decoder + + self.num_hidden_layers = config.num_hidden_layers + self.initializer_range = config.initializer_range + self.output_attentions = config.output_attentions + self.output_hidden_states = config.output_hidden_states + self.return_dict = config.use_return_dict + self.encoder = TFXLMRobertaEncoder(config, name="encoder") + self.pooler = TFXLMRobertaPooler(config, name="pooler") if add_pooling_layer else None + # The embeddings must be the last declaration in order to follow the weights order + self.embeddings = TFXLMRobertaEmbeddings(config, name="embeddings") + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.get_input_embeddings + def get_input_embeddings(self) -> tf.keras.layers.Layer: + return self.embeddings + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.set_input_embeddings + def set_input_embeddings(self, value: tf.Variable): + self.embeddings.weight = value + self.embeddings.vocab_size = shape_list(value)[0] + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer._prune_heads + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + raise NotImplementedError + + @unpack_inputs + # Copied from transformers.models.bert.modeling_tf_bert.TFBertMainLayer.call + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFBaseModelOutputWithPoolingAndCrossAttentions, Tuple[tf.Tensor]]: + if not self.config.is_decoder: + use_cache = False + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = shape_list(input_ids) + elif inputs_embeds is not None: + input_shape = shape_list(inputs_embeds)[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + + if past_key_values is None: + past_key_values_length = 0 + past_key_values = [None] * len(self.encoder.layer) + else: + past_key_values_length = shape_list(past_key_values[0][0])[-2] + + if attention_mask is None: + attention_mask = tf.fill(dims=(batch_size, seq_length + past_key_values_length), value=1) + + if token_type_ids is None: + token_type_ids = tf.fill(dims=input_shape, value=0) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + training=training, + ) + + # We create a 3D attention mask from a 2D tensor mask. + # Sizes are [batch_size, 1, 1, to_seq_length] + # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length] + # this attention mask is more simple than the triangular masking of causal attention + # used in OpenAI GPT, we just need to prepare the broadcast dimension here. + attention_mask_shape = shape_list(attention_mask) + + mask_seq_length = seq_length + past_key_values_length + # Copied from `modeling_tf_t5.py` + # Provided a padding mask of dimensions [batch_size, mask_seq_length] + # - if the model is a decoder, apply a causal mask in addition to the padding mask + # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] + if self.is_decoder: + seq_ids = tf.range(mask_seq_length) + causal_mask = tf.less_equal( + tf.tile(seq_ids[None, None, :], (batch_size, mask_seq_length, 1)), + seq_ids[None, :, None], + ) + causal_mask = tf.cast(causal_mask, dtype=attention_mask.dtype) + extended_attention_mask = causal_mask * attention_mask[:, None, :] + attention_mask_shape = shape_list(extended_attention_mask) + extended_attention_mask = tf.reshape( + extended_attention_mask, (attention_mask_shape[0], 1, attention_mask_shape[1], attention_mask_shape[2]) + ) + if past_key_values[0] is not None: + # attention_mask needs to be sliced to the shape `[batch_size, 1, from_seq_length - cached_seq_length, to_seq_length] + extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :] + else: + extended_attention_mask = tf.reshape( + attention_mask, (attention_mask_shape[0], 1, 1, attention_mask_shape[1]) + ) + + # Since attention_mask is 1.0 for positions we want to attend and 0.0 for + # masked positions, this operation will create a tensor which is 0.0 for + # positions we want to attend and -10000.0 for masked positions. + # Since we are adding it to the raw scores before the softmax, this is + # effectively the same as removing these entirely. + extended_attention_mask = tf.cast(extended_attention_mask, dtype=embedding_output.dtype) + one_cst = tf.constant(1.0, dtype=embedding_output.dtype) + ten_thousand_cst = tf.constant(-10000.0, dtype=embedding_output.dtype) + extended_attention_mask = tf.multiply(tf.subtract(one_cst, extended_attention_mask), ten_thousand_cst) + + # Copied from `modeling_tf_t5.py` with -1e9 -> -10000 + if self.is_decoder and encoder_attention_mask is not None: + # If a 2D ou 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, mask_seq_length, mask_seq_length] + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + encoder_attention_mask = tf.cast(encoder_attention_mask, dtype=extended_attention_mask.dtype) + num_dims_encoder_attention_mask = len(shape_list(encoder_attention_mask)) + if num_dims_encoder_attention_mask == 3: + encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :] + if num_dims_encoder_attention_mask == 2: + encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :] + + # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition + # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow/transformer/transformer_layers.py#L270 + # encoder_extended_attention_mask = tf.math.equal(encoder_extended_attention_mask, + # tf.transpose(encoder_extended_attention_mask, perm=(-1, -2))) + + encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -10000.0 + else: + encoder_extended_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.config.num_hidden_layers + + encoder_outputs = self.encoder( + hidden_states=embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(hidden_states=sequence_output) if self.pooler is not None else None + + if not return_dict: + return ( + sequence_output, + pooled_output, + ) + encoder_outputs[1:] + + return TFBaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaPreTrainedModel with Roberta->XLMRoberta +class TFXLMRobertaPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMRobertaConfig + base_model_prefix = "roberta" + + @property + # Copied from transformers.models.bert.modeling_tf_bert.TFBertPreTrainedModel.dummy_inputs + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + `Dict[str, tf.Tensor]`: The dummy inputs. + """ + dummy = {"input_ids": tf.constant(DUMMY_INPUTS, dtype=tf.int32)} + # Add `encoder_hidden_states` to make the cross-attention layers' weights initialized + if self.config.add_cross_attention: + batch_size, seq_len = tf.constant(DUMMY_INPUTS).shape + shape = (batch_size, seq_len) + (self.config.hidden_size,) + h = tf.random.uniform(shape=shape) + dummy["encoder_hidden_states"] = h + + return dummy + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + +@add_start_docstrings( + "The bare XLM RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaModel with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaModel(TFXLMRobertaPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.roberta = TFXLMRobertaMainLayer(config, name="roberta") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFBaseModelOutputWithPoolingAndCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: Optional[bool] = False, + ) -> Union[Tuple, TFBaseModelOutputWithPoolingAndCrossAttentions]: + r""" + encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + past_key_values (`Tuple[Tuple[tf.Tensor]]` of length `config.n_layers`) + contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*, defaults to `True`): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). Set to `False` during training, `True` during generation + """ + outputs = self.roberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertModel.serving_output + def serving_output( + self, output: TFBaseModelOutputWithPoolingAndCrossAttentions + ) -> TFBaseModelOutputWithPoolingAndCrossAttentions: + output_cache = self.config.use_cache and self.config.is_decoder + pkv = tf.convert_to_tensor(output.past_key_values) if output_cache else None + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if output.cross_attentions is not None else None + if not (self.config.output_attentions and self.config.add_cross_attention): + cross_attns = None + + return TFBaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=output.last_hidden_state, + pooler_output=output.pooler_output, + past_key_values=pkv, + hidden_states=hs, + attentions=attns, + cross_attentions=cross_attns, + ) + + +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaLMHead with Roberta->XLMRoberta +class TFXLMRobertaLMHead(tf.keras.layers.Layer): + """XLMRoberta Head for masked language modeling.""" + + def __init__(self, config, input_embeddings, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.hidden_size = config.hidden_size + self.dense = tf.keras.layers.Dense( + config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense" + ) + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.act = get_tf_activation("gelu") + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.decoder = input_embeddings + + def build(self, input_shape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + + super().build(input_shape) + + def get_output_embeddings(self): + return self.decoder + + def set_output_embeddings(self, value): + self.decoder.weight = value + self.decoder.vocab_size = shape_list(value)[0] + + def get_bias(self): + return {"bias": self.bias} + + def set_bias(self, value): + self.bias = value["bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states): + hidden_states = self.dense(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.layer_norm(hidden_states) + + # project back to size of vocabulary with bias + seq_length = shape_list(tensor=hidden_states)[1] + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, self.hidden_size]) + hidden_states = tf.matmul(a=hidden_states, b=self.decoder.weight, transpose_b=True) + hidden_states = tf.reshape(tensor=hidden_states, shape=[-1, seq_length, self.config.vocab_size]) + hidden_states = tf.nn.bias_add(value=hidden_states, bias=self.bias) + + return hidden_states + + +@add_start_docstrings("""XLM RoBERTa Model with a `language modeling` head on top.""", XLM_ROBERTA_START_DOCSTRING) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMaskedLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForMaskedLM(TFXLMRobertaPreTrainedModel, TFMaskedLanguageModelingLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") + self.lm_head = TFXLMRobertaLMHead(config, self.roberta.embeddings, name="lm_head") + + def get_lm_head(self): + return self.lm_head + + def get_prefix_bias_name(self): + warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) + return self.name + "/" + self.lm_head.name + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="", + expected_output="' Paris'", + expected_loss=0.1, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMaskedLMOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + loss = None if labels is None else self.hf_compute_loss(labels, prediction_scores) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFMaskedLMOutput( + loss=loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMaskedLM.serving_output + def serving_output(self, output: TFMaskedLMOutput) -> TFMaskedLMOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMaskedLMOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + "XLM-RoBERTa Model with a `language modeling` head on top for CLM fine-tuning.", + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForCausalLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForCausalLM(TFXLMRobertaPreTrainedModel, TFCausalLanguageModelingLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head.decoder.weight"] + + def __init__(self, config: XLMRobertaConfig, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + if not config.is_decoder: + logger.warning("If you want to use `TFXLMRobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") + self.lm_head = TFXLMRobertaLMHead(config, input_embeddings=self.roberta.embeddings, name="lm_head") + + def get_lm_head(self): + return self.lm_head + + def get_prefix_bias_name(self): + warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) + return self.name + "/" + self.lm_head.name + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.prepare_inputs_for_generation + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): + input_shape = input_ids.shape + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = tf.ones(input_shape) + + # cut decoder_input_ids if past is used + if past_key_values is not None: + input_ids = input_ids[:, -1:] + + return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFCausalLMOutputWithCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_hidden_states: Optional[Union[np.ndarray, tf.Tensor]] = None, + encoder_attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + past_key_values: Optional[Tuple[Tuple[Union[np.ndarray, tf.Tensor]]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFCausalLMOutputWithCrossAttentions, Tuple[tf.Tensor]]: + r""" + encoder_hidden_states (`tf.Tensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + past_key_values (`Tuple[Tuple[tf.Tensor]]` of length `config.n_layers`) + contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*, defaults to `True`): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). Set to `False` during training, `True` during generation + labels (`tf.Tensor` or `np.ndarray` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., + config.vocab_size - 1]`. + """ + outputs = self.roberta( + input_ids=input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + sequence_output = outputs[0] + logits = self.lm_head(hidden_states=sequence_output, training=training) + loss = None + + if labels is not None: + # shift labels to the left and cut last logit token + shifted_logits = logits[:, :-1] + labels = labels[:, 1:] + loss = self.hf_compute_loss(labels=labels, logits=shifted_logits) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFCausalLMOutputWithCrossAttentions( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertLMHeadModel.serving_output + def serving_output(self, output: TFCausalLMOutputWithCrossAttentions) -> TFCausalLMOutputWithCrossAttentions: + output_cache = self.config.use_cache and self.config.is_decoder + pkv = tf.convert_to_tensor(output.past_key_values) if output_cache else None + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + cross_attns = tf.convert_to_tensor(output.cross_attentions) if output.cross_attentions is not None else None + if not (self.config.output_attentions and self.config.add_cross_attention): + cross_attns = None + + return TFCausalLMOutputWithCrossAttentions( + logits=output.logits, past_key_values=pkv, hidden_states=hs, attentions=attns, cross_attentions=cross_attns + ) + + +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaClassificationHead with Roberta->XLMRoberta +class TFXLMRobertaClassificationHead(tf.keras.layers.Layer): + """Head for sentence-level classification tasks.""" + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.dense = tf.keras.layers.Dense( + config.hidden_size, + kernel_initializer=get_initializer(config.initializer_range), + activation="tanh", + name="dense", + ) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = tf.keras.layers.Dropout(classifier_dropout) + self.out_proj = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="out_proj" + ) + + def call(self, features, training=False): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x, training=training) + x = self.dense(x) + x = self.dropout(x, training=training) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """ + XLM RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForSequenceClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForSequenceClassification(TFXLMRobertaPreTrainedModel, TFSequenceClassificationLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") + self.classifier = TFXLMRobertaClassificationHead(config, name="classifier") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="cardiffnlp/twitter-roberta-base-emotion", + output_type=TFSequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="'optimism'", + expected_loss=0.08, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output, training=training) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFSequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForSequenceClassification.serving_output + def serving_output(self, output: TFSequenceClassifierOutput) -> TFSequenceClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFSequenceClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM Roberta Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForMultipleChoice with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForMultipleChoice(TFXLMRobertaPreTrainedModel, TFMultipleChoiceLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"lm_head"] + _keys_to_ignore_on_load_missing = [r"dropout"] + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.roberta = TFXLMRobertaMainLayer(config, name="roberta") + self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) + self.classifier = tf.keras.layers.Dense( + 1, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @property + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + tf.Tensor with dummy inputs + """ + return {"input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32)} + + @unpack_inputs + @add_start_docstrings_to_model_forward( + XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") + ) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFMultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFMultipleChoiceModelOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` + where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) + """ + + if input_ids is not None: + num_choices = shape_list(input_ids)[1] + seq_length = shape_list(input_ids)[2] + else: + num_choices = shape_list(inputs_embeds)[1] + seq_length = shape_list(inputs_embeds)[2] + + flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None + flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None + flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None + flat_position_ids = tf.reshape(position_ids, (-1, seq_length)) if position_ids is not None else None + outputs = self.roberta( + flat_input_ids, + flat_attention_mask, + flat_token_type_ids, + flat_position_ids, + head_mask, + inputs_embeds, + output_attentions, + output_hidden_states, + return_dict=return_dict, + training=training, + ) + pooled_output = outputs[1] + pooled_output = self.dropout(pooled_output, training=training) + logits = self.classifier(pooled_output) + reshaped_logits = tf.reshape(logits, (-1, num_choices)) + + loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFMultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForMultipleChoice.serving_output + def serving_output(self, output: TFMultipleChoiceModelOutput) -> TFMultipleChoiceModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFMultipleChoiceModelOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM RoBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForTokenClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForTokenClassification(TFXLMRobertaPreTrainedModel, TFTokenClassificationLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] + _keys_to_ignore_on_load_missing = [r"dropout"] + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = tf.keras.layers.Dropout(classifier_dropout) + self.classifier = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="ydshieh/roberta-large-ner-english", + output_type=TFTokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="['O', 'ORG', 'ORG', 'O', 'O', 'O', 'O', 'O', 'LOC', 'O', 'LOC', 'LOC']", + expected_loss=0.01, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFTokenClassifierOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output, training=training) + logits = self.classifier(sequence_output) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFTokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForTokenClassification.serving_output + def serving_output(self, output: TFTokenClassifierOutput) -> TFTokenClassifierOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFTokenClassifierOutput(logits=output.logits, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLM RoBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_tf_roberta.TFRobertaForQuestionAnswering with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class TFXLMRobertaForQuestionAnswering(TFXLMRobertaPreTrainedModel, TFQuestionAnsweringLoss): + # names with a '.' represents the authorized unexpected/missing layers when a TF model is loaded from a PT model + _keys_to_ignore_on_load_unexpected = [r"pooler", r"lm_head"] + + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.roberta = TFXLMRobertaMainLayer(config, add_pooling_layer=False, name="roberta") + self.qa_outputs = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="ydshieh/roberta-base-squad2", + output_type=TFQuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="' puppet'", + expected_loss=0.86, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + position_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: Optional[bool] = False, + ) -> Union[TFQuestionAnsweringModelOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = tf.split(logits, 2, axis=-1) + start_logits = tf.squeeze(start_logits, axis=-1) + end_logits = tf.squeeze(end_logits, axis=-1) + + loss = None + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels, (start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TFQuestionAnsweringModelOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + # Copied from transformers.models.bert.modeling_tf_bert.TFBertForQuestionAnswering.serving_output + def serving_output(self, output: TFQuestionAnsweringModelOutput) -> TFQuestionAnsweringModelOutput: + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + + return TFQuestionAnsweringModelOutput( + start_logits=output.start_logits, end_logits=output.end_logits, hidden_states=hs, attentions=attns + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..fbd9dbb151c0b9f9092ba0166ec286d6d5d81f0d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/modeling_xlm_roberta.py @@ -0,0 +1,1605 @@ +# coding=utf-8 +# Copyright 2019 Facebook AI Research and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTorch XLM-RoBERTa model.""" + +import math +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN, gelu +from ...modeling_outputs import ( + BaseModelOutputWithPastAndCrossAttentions, + BaseModelOutputWithPoolingAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlm_roberta import XLMRobertaConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-roberta-base" +_CONFIG_FOR_DOC = "XLMRobertaConfig" + +XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlm-roberta-base", + "xlm-roberta-large", + "xlm-roberta-large-finetuned-conll02-dutch", + "xlm-roberta-large-finetuned-conll02-spanish", + "xlm-roberta-large-finetuned-conll03-english", + "xlm-roberta-large-finetuned-conll03-german", + # See all XLM-RoBERTa models at https://huggingface.co/models?filter=xlm-roberta +] + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->XLMRoberta +class XLMRobertaEmbeddings(nn.Module): + """ + Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. + """ + + # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # End copy + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 + ): + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + def create_position_ids_from_inputs_embeds(self, inputs_embeds): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->XLMRoberta +class XLMRobertaSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in XLMRobertaModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput with Roberta->XLMRoberta +class XLMRobertaSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaAttention with Roberta->XLMRoberta +class XLMRobertaAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = XLMRobertaSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = XLMRobertaSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + self_outputs = self.self( + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate with Roberta->XLMRoberta +class XLMRobertaIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaOutput with Roberta->XLMRoberta +class XLMRobertaOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaLayer with Roberta->XLMRoberta +class XLMRobertaLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = XLMRobertaAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = XLMRobertaAttention(config, position_embedding_type="absolute") + self.intermediate = XLMRobertaIntermediate(config) + self.output = XLMRobertaOutput(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaEncoder with Roberta->XLMRoberta +class XLMRobertaEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([XLMRobertaLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaPooler with Roberta->XLMRoberta +class XLMRobertaPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaPreTrainedModel with Roberta->XLMRoberta +class XLMRobertaPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMRobertaConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + _no_split_modules = [] + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, XLMRobertaEncoder): + module.gradient_checkpointing = value + + def update_keys_to_ignore(self, config, del_keys_to_ignore): + """Remove some keys from ignore list""" + if not config.tie_word_embeddings: + # must make a new list, or the class variable gets modified! + self._keys_to_ignore_on_save = [k for k in self._keys_to_ignore_on_save if k not in del_keys_to_ignore] + self._keys_to_ignore_on_load_missing = [ + k for k in self._keys_to_ignore_on_load_missing if k not in del_keys_to_ignore + ] + + +XLM_ROBERTA_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`XLMRobertaConfig`]): Model configuration class with all the parameters of the + model. Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_ROBERTA_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare XLM-RoBERTa Model transformer outputting raw hidden-states without any specific head on top.", + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaModel with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaModel(XLMRobertaPreTrainedModel): + """ + + The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of + cross-attention is added between the self-attention layers, following the architecture described in *Attention is + all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz + Kaiser and Illia Polosukhin. + + To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set + to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. + + .. _*Attention is all you need*: https://arxiv.org/abs/1706.03762 + + """ + + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.bert.modeling_bert.BertModel.__init__ with Bert->XLMRoberta + def __init__(self, config, add_pooling_layer=True): + super().__init__(config) + self.config = config + + self.embeddings = XLMRobertaEmbeddings(config) + self.encoder = XLMRobertaEncoder(config) + + self.pooler = XLMRobertaPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPoolingAndCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + # Copied from transformers.models.bert.modeling_bert.BertModel.forward + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache + else: + use_cache = False + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.is_decoder and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_extended_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + encoder_outputs = self.encoder( + embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +@add_start_docstrings( + "XLM-RoBERTa Model with a `language modeling` head on top for CLM fine-tuning.", + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForCausalLM(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `XLMRobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=CausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Tuple[Tuple[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLMRobertaForCausalLM, AutoConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("roberta-base") + >>> config = AutoConfig.from_pretrained("roberta-base") + >>> config.is_decoder = True + >>> model = XLMRobertaForCausalLM.from_pretrained("roberta-base", config=config) + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + # we are doing next-token prediction; shift prediction scores and input ids by one + shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous() + labels = labels[:, 1:].contiguous() + loss_fct = CrossEntropyLoss() + lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((lm_loss,) + output) if lm_loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): + input_shape = input_ids.shape + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_shape) + + # cut decoder_input_ids if past is used + if past_key_values is not None: + input_ids = input_ids[:, -1:] + + return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} + + def _reorder_cache(self, past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past + + +@add_start_docstrings( + """XLM-RoBERTa Model with a `language modeling` head on top.""", + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForMaskedLM(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `XLMRobertaForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="", + expected_output="' Paris'", + expected_loss=0.1, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + kwargs (`Dict[str, any]`, optional, defaults to *{}*): + Used to hide legacy arguments that have been deprecated. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(prediction_scores.device) + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaLMHead +class XLMRobertaLMHead(nn.Module): + """Roberta Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +@add_start_docstrings( + """ + XLM-RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer on top of the + pooled output) e.g. for GLUE tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForSequenceClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForSequenceClassification(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + self.classifier = XLMRobertaClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="cardiffnlp/twitter-roberta-base-emotion", + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="'optimism'", + expected_loss=0.08, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM-RoBERTa Model with a multiple choice classification head on top (a linear layer on top of the pooled output and + a softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForMultipleChoice with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForMultipleChoice(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + + self.roberta = XLMRobertaModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward( + XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") + ) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(reshaped_logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM-RoBERTa Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. + for Named-Entity-Recognition (NER) tasks. + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForTokenClassification with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForTokenClassification(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="Jean-Baptiste/roberta-large-ner-english", + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="['O', 'ORG', 'ORG', 'O', 'O', 'O', 'O', 'O', 'LOC', 'O', 'LOC', 'LOC']", + expected_loss=0.01, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + # move labels to correct device to enable model parallelism + labels = labels.to(logits.device) + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaClassificationHead with Roberta->XLMRoberta +class XLMRobertaClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """ + XLM-RoBERTa Model with a span classification head on top for extractive question-answering tasks like SQuAD (a + linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_ROBERTA_START_DOCSTRING, +) +# Copied from transformers.models.roberta.modeling_roberta.RobertaForQuestionAnswering with Roberta->XLMRoberta, ROBERTA->XLM_ROBERTA +class XLMRobertaForQuestionAnswering(XLMRobertaPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint="deepset/roberta-base-squad2", + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + expected_output="' puppet'", + expected_loss=0.86, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids +def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..54a46842ff156d7c4fda79d7f623ec5819fe748e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta.py @@ -0,0 +1,328 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +""" Tokenization classes for XLM-RoBERTa model.""" + + +import os +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as spm + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import logging + + +logger = logging.get_logger(__name__) + +SPIECE_UNDERLINE = "▁" + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "xlm-roberta-base": "https://huggingface.co/xlm-roberta-base/resolve/main/sentencepiece.bpe.model", + "xlm-roberta-large": "https://huggingface.co/xlm-roberta-large/resolve/main/sentencepiece.bpe.model", + "xlm-roberta-large-finetuned-conll02-dutch": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-dutch/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll02-spanish": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-spanish/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll03-english": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-english/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll03-german": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-german/resolve/main/sentencepiece.bpe.model" + ), + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "xlm-roberta-base": 512, + "xlm-roberta-large": 512, + "xlm-roberta-large-finetuned-conll02-dutch": 512, + "xlm-roberta-large-finetuned-conll02-spanish": 512, + "xlm-roberta-large-finetuned-conll03-english": 512, + "xlm-roberta-large-finetuned-conll03-german": 512, +} + + +class XLMRobertaTokenizer(PreTrainedTokenizer): + """ + Adapted from [`RobertaTokenizer`] and [`XLNetTokenizer`]. Based on + [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + mask_token="", + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + cls_token=cls_token, + pad_token=pad_token, + mask_token=mask_token, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(str(vocab_file)) + self.vocab_file = vocab_file + + # Original fairseq vocab and spm vocab must be "aligned": + # Vocab | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 + # -------- | ------- | ------- | ------ | ------- | --- | --- | --- | ----- | ----- | ---- + # fairseq | '' | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' + # spm | '' | '' | '' | ',' | '.' | '▁' | 's' | '▁de' | '-' | '▁a' + + # Mimic fairseq token-to-id alignment for the first 4 token + self.fairseq_tokens_to_ids = {"": 0, "": 1, "": 2, "": 3} + + # The first "real" token "," has position 4 in the original fairseq vocab and position 3 in the spm vocab + self.fairseq_offset = 1 + + self.fairseq_tokens_to_ids[""] = len(self.sp_model) + self.fairseq_offset + self.fairseq_ids_to_tokens = {v: k for k, v in self.fairseq_tokens_to_ids.items()} + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + state["sp_model_proto"] = self.sp_model.serialized_model_proto() + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.LoadFromSerializedProto(self.sp_model_proto) + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLM-RoBERTa sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return [1] + ([0] * len(token_ids_0)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1, 1] + ([0] * len(token_ids_1)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. XLM-RoBERTa does + not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + @property + def vocab_size(self): + return len(self.sp_model) + self.fairseq_offset + 1 # Add the token + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def _tokenize(self, text: str) -> List[str]: + return self.sp_model.encode(text, out_type=str) + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + if token in self.fairseq_tokens_to_ids: + return self.fairseq_tokens_to_ids[token] + spm_id = self.sp_model.PieceToId(token) + + # Need to return unknown token if the SP model returned 0 + return spm_id + self.fairseq_offset if spm_id else self.unk_token_id + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + if index in self.fairseq_ids_to_tokens: + return self.fairseq_ids_to_tokens[index] + return self.sp_model.IdToPiece(index - self.fairseq_offset) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (strings for sub-words) in a single string.""" + out_string = "".join(tokens).replace(SPIECE_UNDERLINE, " ").strip() + return out_string + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..68f8df06ff3d24ca3f5a034b313ca64512bb482e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta/tokenization_xlm_roberta_fast.py @@ -0,0 +1,239 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +""" Tokenization classes for XLM-RoBERTa model.""" + + +import os +from shutil import copyfile +from typing import List, Optional, Tuple + +from ...tokenization_utils import AddedToken +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import is_sentencepiece_available, logging + + +if is_sentencepiece_available(): + from .tokenization_xlm_roberta import XLMRobertaTokenizer +else: + XLMRobertaTokenizer = None + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "xlm-roberta-base": "https://huggingface.co/xlm-roberta-base/resolve/main/sentencepiece.bpe.model", + "xlm-roberta-large": "https://huggingface.co/xlm-roberta-large/resolve/main/sentencepiece.bpe.model", + "xlm-roberta-large-finetuned-conll02-dutch": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-dutch/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll02-spanish": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-spanish/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll03-english": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-english/resolve/main/sentencepiece.bpe.model" + ), + "xlm-roberta-large-finetuned-conll03-german": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-german/resolve/main/sentencepiece.bpe.model" + ), + }, + "tokenizer_file": { + "xlm-roberta-base": "https://huggingface.co/xlm-roberta-base/resolve/main/tokenizer.json", + "xlm-roberta-large": "https://huggingface.co/xlm-roberta-large/resolve/main/tokenizer.json", + "xlm-roberta-large-finetuned-conll02-dutch": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-dutch/resolve/main/tokenizer.json" + ), + "xlm-roberta-large-finetuned-conll02-spanish": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll02-spanish/resolve/main/tokenizer.json" + ), + "xlm-roberta-large-finetuned-conll03-english": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-english/resolve/main/tokenizer.json" + ), + "xlm-roberta-large-finetuned-conll03-german": ( + "https://huggingface.co/xlm-roberta-large-finetuned-conll03-german/resolve/main/tokenizer.json" + ), + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "xlm-roberta-base": 512, + "xlm-roberta-large": 512, + "xlm-roberta-large-finetuned-conll02-dutch": 512, + "xlm-roberta-large-finetuned-conll02-spanish": 512, + "xlm-roberta-large-finetuned-conll03-english": 512, + "xlm-roberta-large-finetuned-conll03-german": 512, +} + + +class XLMRobertaTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" XLM-RoBERTa tokenizer (backed by HuggingFace's *tokenizers* library). Adapted from + [`RobertaTokenizer`] and [`XLNetTokenizer`]. Based on + [BPE](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=BPE#models). + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["NOTUSED", "NOTUSED"]`): + Additional special tokens used by the tokenizer. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + slow_tokenizer_class = XLMRobertaTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + bos_token="", + eos_token="", + sep_token="", + cls_token="", + unk_token="", + pad_token="", + mask_token="", + **kwargs, + ): + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + super().__init__( + vocab_file, + tokenizer_file=tokenizer_file, + bos_token=bos_token, + eos_token=eos_token, + sep_token=sep_token, + cls_token=cls_token, + unk_token=unk_token, + pad_token=pad_token, + mask_token=mask_token, + **kwargs, + ) + + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLM-RoBERTa sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + sep + token_ids_1 + sep + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. XLM-RoBERTa does + not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + + """ + + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory.") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2df95dbc49200e76b2e18f0744a2e33e05cd9cd6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/__init__.py @@ -0,0 +1,74 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = { + "configuration_xlm_roberta_xl": [ + "XLM_ROBERTA_XL_PRETRAINED_CONFIG_ARCHIVE_MAP", + "XLMRobertaXLConfig", + "XLMRobertaXLOnnxConfig", + ], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xlm_roberta_xl"] = [ + "XLM_ROBERTA_XL_PRETRAINED_MODEL_ARCHIVE_LIST", + "XLMRobertaXLForCausalLM", + "XLMRobertaXLForMaskedLM", + "XLMRobertaXLForMultipleChoice", + "XLMRobertaXLForQuestionAnswering", + "XLMRobertaXLForSequenceClassification", + "XLMRobertaXLForTokenClassification", + "XLMRobertaXLModel", + "XLMRobertaXLPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_xlm_roberta_xl import ( + XLM_ROBERTA_XL_PRETRAINED_CONFIG_ARCHIVE_MAP, + XLMRobertaXLConfig, + XLMRobertaXLOnnxConfig, + ) + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xlm_roberta_xl import ( + XLM_ROBERTA_XL_PRETRAINED_MODEL_ARCHIVE_LIST, + XLMRobertaXLForCausalLM, + XLMRobertaXLForMaskedLM, + XLMRobertaXLForMultipleChoice, + XLMRobertaXLForQuestionAnswering, + XLMRobertaXLForSequenceClassification, + XLMRobertaXLForTokenClassification, + XLMRobertaXLModel, + XLMRobertaXLPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/configuration_xlm_roberta_xl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/configuration_xlm_roberta_xl.py new file mode 100644 index 0000000000000000000000000000000000000000..acf30bf3878a880ba11256aea89a503da22c2d83 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/configuration_xlm_roberta_xl.py @@ -0,0 +1,155 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XLM_ROBERTa_XL configuration""" + +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XLM_ROBERTA_XL_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/xlm-roberta-xl": "https://huggingface.co/facebook/xlm-roberta-xl/resolve/main/config.json", + "facebook/xlm-roberta-xxl": "https://huggingface.co/facebook/xlm-roberta-xxl/resolve/main/config.json", + # See all XLM-RoBERTa-XL models at https://huggingface.co/models?filter=xlm-roberta-xl +} + + +class XLMRobertaXLConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XLMRobertaXLModel`] or a [`TFXLMRobertaXLModel`]. + It is used to instantiate a XLM_ROBERTA_XL model according to the specified arguments, defining the model + architecture. Instantiating a configuration with the defaults will yield a similar configuration to that of the + XLM_ROBERTA_XL [facebook/xlm-roberta-xl](https://huggingface.co/facebook/xlm-roberta-xl) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 250880): + Vocabulary size of the XLM_ROBERTA_XL model. Defines the number of different tokens that can be represented + by the `inputs_ids` passed when calling [`XLMRobertaXLModel`]. + hidden_size (`int`, *optional*, defaults to 2560): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 36): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 32): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 10240): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 514): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 1): + The vocabulary size of the `token_type_ids` passed when calling [`XLMRobertaXLModel`] or + [`TFXLMRobertaXLModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-5): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + classifier_dropout (`float`, *optional*): + The dropout ratio for the classification head. + + Examples: + + ```python + >>> from transformers import XLMRobertaXLConfig, XLMRobertaXLModel + + >>> # Initializing a XLM_ROBERTA_XL bert-base-uncased style configuration + >>> configuration = XLMRobertaXLConfig() + + >>> # Initializing a model (with random weights) from the bert-base-uncased style configuration + >>> model = XLMRobertaXLModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "xlm-roberta-xl" + + def __init__( + self, + vocab_size=250880, + hidden_size=2560, + num_hidden_layers=36, + num_attention_heads=32, + intermediate_size=10240, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=514, + type_vocab_size=1, + initializer_range=0.02, + layer_norm_eps=1e-05, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + position_embedding_type="absolute", + use_cache=True, + classifier_dropout=None, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.classifier_dropout = classifier_dropout + + +# Copied from transformers.models.roberta.configuration_roberta.RobertaOnnxConfig with Roberta->XLMRobertaXL +class XLMRobertaXLOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/convert_xlm_roberta_xl_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/convert_xlm_roberta_xl_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..7f0fec32c387852535b90a2db111b2a487b1f61d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/convert_xlm_roberta_xl_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,183 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert RoBERTa checkpoint.""" + +import argparse +import pathlib + +import fairseq +import torch +from fairseq.models.roberta import RobertaModel as FairseqRobertaModel +from fairseq.modules import TransformerSentenceEncoderLayer +from packaging import version + +from transformers import XLMRobertaConfig, XLMRobertaXLForMaskedLM, XLMRobertaXLForSequenceClassification +from transformers.models.bert.modeling_bert import ( + BertIntermediate, + BertLayer, + BertOutput, + BertSelfAttention, + BertSelfOutput, +) +from transformers.models.roberta.modeling_roberta import RobertaAttention +from transformers.utils import logging + + +if version.parse(fairseq.__version__) < version.parse("1.0.0a"): + raise Exception("requires fairseq >= 1.0.0a") + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +SAMPLE_TEXT = "Hello world! cécé herlolip" + + +def convert_xlm_roberta_xl_checkpoint_to_pytorch( + roberta_checkpoint_path: str, pytorch_dump_folder_path: str, classification_head: bool +): + """ + Copy/paste/tweak roberta's weights to our BERT structure. + """ + roberta = FairseqRobertaModel.from_pretrained(roberta_checkpoint_path) + roberta.eval() # disable dropout + roberta_sent_encoder = roberta.model.encoder.sentence_encoder + config = XLMRobertaConfig( + vocab_size=roberta_sent_encoder.embed_tokens.num_embeddings, + hidden_size=roberta.cfg.model.encoder_embed_dim, + num_hidden_layers=roberta.cfg.model.encoder_layers, + num_attention_heads=roberta.cfg.model.encoder_attention_heads, + intermediate_size=roberta.cfg.model.encoder_ffn_embed_dim, + max_position_embeddings=514, + type_vocab_size=1, + layer_norm_eps=1e-5, # PyTorch default used in fairseq + ) + if classification_head: + config.num_labels = roberta.model.classification_heads["mnli"].out_proj.weight.shape[0] + + print("Our RoBERTa config:", config) + + model = XLMRobertaXLForSequenceClassification(config) if classification_head else XLMRobertaXLForMaskedLM(config) + model.eval() + + # Now let's copy all the weights. + # Embeddings + model.roberta.embeddings.word_embeddings.weight = roberta_sent_encoder.embed_tokens.weight + model.roberta.embeddings.position_embeddings.weight = roberta_sent_encoder.embed_positions.weight + model.roberta.embeddings.token_type_embeddings.weight.data = torch.zeros_like( + model.roberta.embeddings.token_type_embeddings.weight + ) # just zero them out b/c RoBERTa doesn't use them. + + model.roberta.encoder.LayerNorm.weight = roberta_sent_encoder.layer_norm.weight + model.roberta.encoder.LayerNorm.bias = roberta_sent_encoder.layer_norm.bias + + for i in range(config.num_hidden_layers): + # Encoder: start of layer + layer: BertLayer = model.roberta.encoder.layer[i] + roberta_layer: TransformerSentenceEncoderLayer = roberta_sent_encoder.layers[i] + + attention: RobertaAttention = layer.attention + attention.self_attn_layer_norm.weight = roberta_layer.self_attn_layer_norm.weight + attention.self_attn_layer_norm.bias = roberta_layer.self_attn_layer_norm.bias + + # self attention + self_attn: BertSelfAttention = layer.attention.self + assert ( + roberta_layer.self_attn.k_proj.weight.data.shape + == roberta_layer.self_attn.q_proj.weight.data.shape + == roberta_layer.self_attn.v_proj.weight.data.shape + == torch.Size((config.hidden_size, config.hidden_size)) + ) + + self_attn.query.weight.data = roberta_layer.self_attn.q_proj.weight + self_attn.query.bias.data = roberta_layer.self_attn.q_proj.bias + self_attn.key.weight.data = roberta_layer.self_attn.k_proj.weight + self_attn.key.bias.data = roberta_layer.self_attn.k_proj.bias + self_attn.value.weight.data = roberta_layer.self_attn.v_proj.weight + self_attn.value.bias.data = roberta_layer.self_attn.v_proj.bias + + # self-attention output + self_output: BertSelfOutput = layer.attention.output + assert self_output.dense.weight.shape == roberta_layer.self_attn.out_proj.weight.shape + self_output.dense.weight = roberta_layer.self_attn.out_proj.weight + self_output.dense.bias = roberta_layer.self_attn.out_proj.bias + + # this one is final layer norm + layer.LayerNorm.weight = roberta_layer.final_layer_norm.weight + layer.LayerNorm.bias = roberta_layer.final_layer_norm.bias + + # intermediate + intermediate: BertIntermediate = layer.intermediate + assert intermediate.dense.weight.shape == roberta_layer.fc1.weight.shape + intermediate.dense.weight = roberta_layer.fc1.weight + intermediate.dense.bias = roberta_layer.fc1.bias + + # output + bert_output: BertOutput = layer.output + assert bert_output.dense.weight.shape == roberta_layer.fc2.weight.shape + bert_output.dense.weight = roberta_layer.fc2.weight + bert_output.dense.bias = roberta_layer.fc2.bias + # end of layer + + if classification_head: + model.classifier.dense.weight = roberta.model.classification_heads["mnli"].dense.weight + model.classifier.dense.bias = roberta.model.classification_heads["mnli"].dense.bias + model.classifier.out_proj.weight = roberta.model.classification_heads["mnli"].out_proj.weight + model.classifier.out_proj.bias = roberta.model.classification_heads["mnli"].out_proj.bias + else: + # LM Head + model.lm_head.dense.weight = roberta.model.encoder.lm_head.dense.weight + model.lm_head.dense.bias = roberta.model.encoder.lm_head.dense.bias + model.lm_head.layer_norm.weight = roberta.model.encoder.lm_head.layer_norm.weight + model.lm_head.layer_norm.bias = roberta.model.encoder.lm_head.layer_norm.bias + model.lm_head.decoder.weight = roberta.model.encoder.lm_head.weight + model.lm_head.decoder.bias = roberta.model.encoder.lm_head.bias + + # Let's check that we get the same results. + input_ids: torch.Tensor = roberta.encode(SAMPLE_TEXT).unsqueeze(0) # batch of size 1 + + our_output = model(input_ids)[0] + if classification_head: + their_output = roberta.model.classification_heads["mnli"](roberta.extract_features(input_ids)) + else: + their_output = roberta.model(input_ids)[0] + print(our_output.shape, their_output.shape) + max_absolute_diff = torch.max(torch.abs(our_output - their_output)).item() + print(f"max_absolute_diff = {max_absolute_diff}") # ~ 1e-7 + success = torch.allclose(our_output, their_output, atol=1e-3) + print("Do both models output the same tensors?", "🔥" if success else "💩") + if not success: + raise Exception("Something went wRoNg") + + pathlib.Path(pytorch_dump_folder_path).mkdir(parents=True, exist_ok=True) + print(f"Saving model to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--roberta_checkpoint_path", default=None, type=str, required=True, help="Path the official PyTorch dump." + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + parser.add_argument( + "--classification_head", action="store_true", help="Whether to convert a final classification head." + ) + args = parser.parse_args() + convert_xlm_roberta_xl_checkpoint_to_pytorch( + args.roberta_checkpoint_path, args.pytorch_dump_folder_path, args.classification_head + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py new file mode 100644 index 0000000000000000000000000000000000000000..e96e20f8969560d53622ec06ebafea536ea7b391 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlm_roberta_xl/modeling_xlm_roberta_xl.py @@ -0,0 +1,1540 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTorch XLM RoBERTa xl,xxl model.""" + +import math +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN, gelu +from ...modeling_outputs import ( + BaseModelOutputWithPastAndCrossAttentions, + BaseModelOutputWithPoolingAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlm_roberta_xl import XLMRobertaXLConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlm-roberta-xlarge" +_CONFIG_FOR_DOC = "XLMRobertaXLConfig" + +XLM_ROBERTA_XL_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/xlm-roberta-xl", + "facebook/xlm-roberta-xxl", + # See all RoBERTa models at https://huggingface.co/models?filter=xlm-roberta-xl +] + + +class XLMRobertaXLEmbeddings(nn.Module): + """ + Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. + """ + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # End copy + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 + ): + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + + embeddings = self.dropout(embeddings) + return embeddings + + # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_inputs_embeds + def create_position_ids_from_inputs_embeds(self, inputs_embeds): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + +# Copied from transformers.models.bert.modeling_bert.BertSelfAttention with Bert->XLMRobertaXL +class XLMRobertaXLSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in XLMRobertaXLModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +class XLMRobertaXLSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states + + +class XLMRobertaXLAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self_attn_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.self = XLMRobertaXLSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = XLMRobertaXLSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states, + attention_mask=None, + head_mask=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + past_key_value=None, + output_attentions=False, + ): + intermediate = self.self_attn_layer_norm(hidden_states) + self_outputs = self.self( + intermediate, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate +class XLMRobertaXLIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +class XLMRobertaXLOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states, input_tensor): + hidden_states = self.dense(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states + + +class XLMRobertaXLLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = XLMRobertaXLAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = XLMRobertaXLAttention(config, position_embedding_type="absolute") + self.intermediate = XLMRobertaXLIntermediate(config) + self.output = XLMRobertaXLOutput(config) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states, + attention_mask=None, + head_mask=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + past_key_value=None, + output_attentions=False, + ): + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.LayerNorm(attention_output) + intermediate_output = self.intermediate(intermediate_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +class XLMRobertaXLEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([XLMRobertaXLLayer(config) for _ in range(config.num_hidden_layers)]) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + head_mask=None, + encoder_hidden_states=None, + encoder_attention_mask=None, + past_key_values=None, + use_cache=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + hidden_states = self.LayerNorm(hidden_states) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.bert.modeling_bert.BertPooler +class XLMRobertaXLPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +class XLMRobertaXLPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLMRobertaXLConfig + base_model_prefix = "roberta" + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def update_keys_to_ignore(self, config, del_keys_to_ignore): + """Remove some keys from ignore list""" + if not config.tie_word_embeddings: + # must make a new list, or the class variable gets modified! + self._keys_to_ignore_on_save = [k for k in self._keys_to_ignore_on_save if k not in del_keys_to_ignore] + self._keys_to_ignore_on_load_missing = [ + k for k in self._keys_to_ignore_on_load_missing if k not in del_keys_to_ignore + ] + + +XLM_ROBERTA_XL_START_DOCSTRING = r""" + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) + subclass. Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to + general usage and behavior. + + Parameters: + config ([`XLMRobertaXLConfig`]): Model configuration class with all the parameters of the + model. Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLM_ROBERTA_XL_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. Indices can be obtained using [`AutoTokenizer`]. See + [`PreTrainedTokenizer.encode`] and [`PreTrainedTokenizer.__call__`] for details. [What are input + IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare XLM-RoBERTa-xlarge Model transformer outputting raw hidden-states without any specific head on top.", + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLModel(XLMRobertaXLPreTrainedModel): + """ + The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of + cross-attention is added between the self-attention layers, following the architecture described in *Attention is + all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz + Kaiser and Illia Polosukhin. To behave as an decoder the model needs to be initialized with the `is_decoder` + argument of the configuration set to `True`. To be used in a Seq2Seq model, the model needs to initialized with + both `is_decoder` argument and `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as + an input to the forward pass. .. _*Attention is all you need*: https://arxiv.org/abs/1706.03762 + """ + + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.bert.modeling_bert.BertModel.__init__ with Bert->XLMRobertaXL + def __init__(self, config, add_pooling_layer=True): + super().__init__(config) + self.config = config + + self.embeddings = XLMRobertaXLEmbeddings(config) + self.encoder = XLMRobertaXLEncoder(config) + + self.pooler = XLMRobertaXLPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPoolingAndCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + # Copied from transformers.models.bert.modeling_bert.BertModel.forward + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache + else: + use_cache = False + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.is_decoder and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_extended_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + encoder_outputs = self.encoder( + embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +@add_start_docstrings( + """XLM-RoBERTa-xlarge Model with a `language modeling` head on top for CLM fine-tuning.""", + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLForCausalLM(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `RobertaLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaXLLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + self.init_weights() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=CausalLMOutputWithCrossAttentions, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, CausalLMOutputWithCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, RobertaForCausalLM, RobertaConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("roberta-base") + >>> config = RobertaConfig.from_pretrained("roberta-base") + >>> config.is_decoder = True + >>> model = RobertaForCausalLM.from_pretrained("roberta-base", config=config) + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + >>> prediction_logits = outputs.logits + ``` + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # we are doing next-token prediction; shift prediction scores and input ids by one + shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous() + labels = labels[:, 1:].contiguous() + loss_fct = CrossEntropyLoss() + lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((lm_loss,) + output) if lm_loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): + input_shape = input_ids.shape + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_shape) + + # cut decoder_input_ids if past is used + if past_key_values is not None: + input_ids = input_ids[:, -1:] + + return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} + + def _reorder_cache(self, past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past + + +@add_start_docstrings( + """XLM-RoBERTa-xlarge Model with a `language modeling` head on top.""", XLM_ROBERTA_XL_START_DOCSTRING +) +class XLMRobertaXLForMaskedLM(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `RobertaForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.lm_head = XLMRobertaXLLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + self.init_weights() + + def get_output_embeddings(self): + return self.lm_head.decoder + + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + mask="", + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + kwargs (`Dict[str, any]`, optional, defaults to *{}*): + Used to hide legacy arguments that have been deprecated. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class XLMRobertaXLLMHead(nn.Module): + """XLM-Roberta-xlarge Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + self.bias = self.decoder.bias + + +@add_start_docstrings( + """ + XLM-RoBERTa-xlarge Model transformer with a sequence classification/regression head on top (a linear layer on top + of the pooled output) e.g. for GLUE tasks. + """, + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLForSequenceClassification(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.classifier = XLMRobertaXLClassificationHead(config) + + self.init_weights() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM-Roberta-xlarge Model with a multiple choice classification head on top (a linear layer on top of the pooled + output and a softmax) e.g. for RocStories/SWAG tasks. + """, + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLForMultipleChoice(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + + self.roberta = XLMRobertaXLModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + self.init_weights() + + @add_start_docstrings_to_model_forward( + XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length") + ) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLM-Roberta-xlarge Model with a token classification head on top (a linear layer on top of the hidden-states + output) e.g. for Named-Entity-Recognition (NER) tasks. + """, + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLForTokenClassification(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + self.init_weights() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + # Only keep active parts of the loss + if attention_mask is not None: + active_loss = attention_mask.view(-1) == 1 + active_logits = logits.view(-1, self.num_labels) + active_labels = torch.where( + active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels) + ) + loss = loss_fct(active_logits, active_labels) + else: + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class XLMRobertaXLClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """ + XLM-Roberta-xlarge Model with a span classification head on top for extractive question-answering tasks like SQuAD + (a linear layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLM_ROBERTA_XL_START_DOCSTRING, +) +class XLMRobertaXLForQuestionAnswering(XLMRobertaXLPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XLMRobertaXLModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + self.init_weights() + + @add_start_docstrings_to_model_forward(XLM_ROBERTA_XL_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids +def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f5e1d4568a66a4864af0d991f7ddf05cf5857bd0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/__init__.py @@ -0,0 +1,142 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_sentencepiece_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, +) + + +_import_structure = {"configuration_xlnet": ["XLNET_PRETRAINED_CONFIG_ARCHIVE_MAP", "XLNetConfig"]} + +try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xlnet"] = ["XLNetTokenizer"] + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_xlnet_fast"] = ["XLNetTokenizerFast"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xlnet"] = [ + "XLNET_PRETRAINED_MODEL_ARCHIVE_LIST", + "XLNetForMultipleChoice", + "XLNetForQuestionAnswering", + "XLNetForQuestionAnsweringSimple", + "XLNetForSequenceClassification", + "XLNetForTokenClassification", + "XLNetLMHeadModel", + "XLNetModel", + "XLNetPreTrainedModel", + "load_tf_weights_in_xlnet", + ] + +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_xlnet"] = [ + "TF_XLNET_PRETRAINED_MODEL_ARCHIVE_LIST", + "TFXLNetForMultipleChoice", + "TFXLNetForQuestionAnsweringSimple", + "TFXLNetForSequenceClassification", + "TFXLNetForTokenClassification", + "TFXLNetLMHeadModel", + "TFXLNetMainLayer", + "TFXLNetModel", + "TFXLNetPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_xlnet import XLNET_PRETRAINED_CONFIG_ARCHIVE_MAP, XLNetConfig + + try: + if not is_sentencepiece_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xlnet import XLNetTokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_xlnet_fast import XLNetTokenizerFast + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xlnet import ( + XLNET_PRETRAINED_MODEL_ARCHIVE_LIST, + XLNetForMultipleChoice, + XLNetForQuestionAnswering, + XLNetForQuestionAnsweringSimple, + XLNetForSequenceClassification, + XLNetForTokenClassification, + XLNetLMHeadModel, + XLNetModel, + XLNetPreTrainedModel, + load_tf_weights_in_xlnet, + ) + + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_xlnet import ( + TF_XLNET_PRETRAINED_MODEL_ARCHIVE_LIST, + TFXLNetForMultipleChoice, + TFXLNetForQuestionAnsweringSimple, + TFXLNetForSequenceClassification, + TFXLNetForTokenClassification, + TFXLNetLMHeadModel, + TFXLNetMainLayer, + TFXLNetModel, + TFXLNetPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/configuration_xlnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/configuration_xlnet.py new file mode 100644 index 0000000000000000000000000000000000000000..9ebc1f8bb9fb6f950075dd2024eb9aeb114a2289 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/configuration_xlnet.py @@ -0,0 +1,242 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" XLNet configuration""" + +import warnings + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XLNET_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "xlnet-base-cased": "https://huggingface.co/xlnet-base-cased/resolve/main/config.json", + "xlnet-large-cased": "https://huggingface.co/xlnet-large-cased/resolve/main/config.json", +} + + +class XLNetConfig(PretrainedConfig): + """ + This is the configuration class to store the configuration of a [`XLNetModel`] or a [`TFXLNetModel`]. It is used to + instantiate a XLNet model according to the specified arguments, defining the model architecture. Instantiating a + configuration with the defaults will yield a similar configuration to that of the + [xlnet-large-cased](https://huggingface.co/xlnet-large-cased) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + vocab_size (`int`, *optional*, defaults to 32000): + Vocabulary size of the XLNet model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`XLNetModel`] or [`TFXLNetModel`]. + d_model (`int`, *optional*, defaults to 1024): + Dimensionality of the encoder layers and the pooler layer. + n_layer (`int`, *optional*, defaults to 24): + Number of hidden layers in the Transformer encoder. + n_head (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + d_inner (`int`, *optional*, defaults to 4096): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + ff_activation (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the If string, `"gelu"`, `"relu"`, `"silu"` and + `"gelu_new"` are supported. + untie_r (`bool`, *optional*, defaults to `True`): + Whether or not to untie relative position biases + attn_type (`str`, *optional*, defaults to `"bi"`): + The attention type used by the model. Set `"bi"` for XLNet, `"uni"` for Transformer-XL. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + mem_len (`int` or `None`, *optional*): + The number of tokens to cache. The key/value pairs that have already been pre-computed in a previous + forward pass won't be re-computed. See the + [quickstart](https://huggingface.co/transformers/quickstart.html#using-the-past) for more information. + reuse_len (`int`, *optional*): + The number of tokens in the current batch to be cached and reused in the future. + bi_data (`bool`, *optional*, defaults to `False`): + Whether or not to use bidirectional input pipeline. Usually set to `True` during pretraining and `False` + during finetuning. + clamp_len (`int`, *optional*, defaults to -1): + Clamp all relative distances larger than clamp_len. Setting this attribute to -1 means no clamping. + same_length (`bool`, *optional*, defaults to `False`): + Whether or not to use the same attention length for each token. + summary_type (`str`, *optional*, defaults to "last"): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Has to be one of the following options: + + - `"last"`: Take the last token hidden state (like XLNet). + - `"first"`: Take the first token hidden state (like BERT). + - `"mean"`: Take the mean of all tokens hidden states. + - `"cls_index"`: Supply a Tensor of classification token position (like GPT/GPT-2). + - `"attn"`: Not implemented now, use multi-head attention. + summary_use_proj (`bool`, *optional*, defaults to `True`): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Whether or not to add a projection after the vector extraction. + summary_activation (`str`, *optional*): + Argument used when doing sequence summary. Used in the sequence classification and multiple choice models. + + Pass `"tanh"` for a tanh activation to the output, any other value will result in no activation. + summary_proj_to_labels (`boo`, *optional*, defaults to `True`): + Used in the sequence classification and multiple choice models. + + Whether the projection outputs should have `config.num_labels` or `config.hidden_size` classes. + summary_last_dropout (`float`, *optional*, defaults to 0.1): + Used in the sequence classification and multiple choice models. + + The dropout ratio to be used after the projection and activation. + start_n_top (`int`, *optional*, defaults to 5): + Used in the SQuAD evaluation script. + end_n_top (`int`, *optional*, defaults to 5): + Used in the SQuAD evaluation script. + use_mems_eval (`bool`, *optional*, defaults to `True`): + Whether or not the model should make use of the recurrent memory mechanism in evaluation mode. + use_mems_train (`bool`, *optional*, defaults to `False`): + Whether or not the model should make use of the recurrent memory mechanism in train mode. + + + + For pretraining, it is recommended to set `use_mems_train` to `True`. For fine-tuning, it is recommended to + set `use_mems_train` to `False` as discussed + [here](https://github.com/zihangdai/xlnet/issues/41#issuecomment-505102587). If `use_mems_train` is set to + `True`, one has to make sure that the train batches are correctly pre-processed, *e.g.* `batch_1 = [[This + line is], [This is the]]` and `batch_2 = [[ the first line], [ second line]]` and that all batches are of + equal size. + + + + Examples: + + ```python + >>> from transformers import XLNetConfig, XLNetModel + + >>> # Initializing a XLNet configuration + >>> configuration = XLNetConfig() + + >>> # Initializing a model (with random weights) from the configuration + >>> model = XLNetModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + + model_type = "xlnet" + keys_to_ignore_at_inference = ["mems"] + attribute_map = { + "n_token": "vocab_size", # Backward compatibility + "hidden_size": "d_model", + "num_attention_heads": "n_head", + "num_hidden_layers": "n_layer", + } + + def __init__( + self, + vocab_size=32000, + d_model=1024, + n_layer=24, + n_head=16, + d_inner=4096, + ff_activation="gelu", + untie_r=True, + attn_type="bi", + initializer_range=0.02, + layer_norm_eps=1e-12, + dropout=0.1, + mem_len=512, + reuse_len=None, + use_mems_eval=True, + use_mems_train=False, + bi_data=False, + clamp_len=-1, + same_length=False, + summary_type="last", + summary_use_proj=True, + summary_activation="tanh", + summary_last_dropout=0.1, + start_n_top=5, + end_n_top=5, + pad_token_id=5, + bos_token_id=1, + eos_token_id=2, + **kwargs, + ): + """Constructs XLNetConfig.""" + self.vocab_size = vocab_size + self.d_model = d_model + self.n_layer = n_layer + self.n_head = n_head + if d_model % n_head != 0: + raise ValueError(f"'d_model % n_head' ({d_model % n_head}) should be equal to 0") + if "d_head" in kwargs: + if kwargs["d_head"] != d_model // n_head: + raise ValueError( + f"`d_head` ({kwargs['d_head']}) should be equal to `d_model // n_head` ({d_model // n_head})" + ) + self.d_head = d_model // n_head + self.ff_activation = ff_activation + self.d_inner = d_inner + self.untie_r = untie_r + self.attn_type = attn_type + + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + + self.dropout = dropout + self.mem_len = mem_len + self.reuse_len = reuse_len + self.bi_data = bi_data + self.clamp_len = clamp_len + self.same_length = same_length + + self.summary_type = summary_type + self.summary_use_proj = summary_use_proj + self.summary_activation = summary_activation + self.summary_last_dropout = summary_last_dropout + self.start_n_top = start_n_top + self.end_n_top = end_n_top + + self.bos_token_id = bos_token_id + self.pad_token_id = pad_token_id + self.eos_token_id = eos_token_id + + if "use_cache" in kwargs: + warnings.warn( + "The `use_cache` argument is deprecated and will be removed in a future version, use `use_mems_eval`" + " instead.", + FutureWarning, + ) + use_mems_eval = kwargs["use_cache"] + + self.use_mems_eval = use_mems_eval + self.use_mems_train = use_mems_train + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + @property + def max_position_embeddings(self): + logger.info(f"The model {self.model_type} is one of the few models that has no sequence length limit.") + return -1 + + @max_position_embeddings.setter + def max_position_embeddings(self, value): + # Message copied from Transformer-XL documentation + raise NotImplementedError( + f"The model {self.model_type} is one of the few models that has no sequence length limit." + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..804b52b0dc87924fa5ee3eda7aa56e875d075a22 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/convert_xlnet_original_tf_checkpoint_to_pytorch.py @@ -0,0 +1,114 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert BERT checkpoint.""" + + +import argparse +import os + +import torch + +from transformers import ( + XLNetConfig, + XLNetForQuestionAnswering, + XLNetForSequenceClassification, + XLNetLMHeadModel, + load_tf_weights_in_xlnet, +) +from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging + + +GLUE_TASKS_NUM_LABELS = { + "cola": 2, + "mnli": 3, + "mrpc": 2, + "sst-2": 2, + "sts-b": 1, + "qqp": 2, + "qnli": 2, + "rte": 2, + "wnli": 2, +} + + +logging.set_verbosity_info() + + +def convert_xlnet_checkpoint_to_pytorch( + tf_checkpoint_path, bert_config_file, pytorch_dump_folder_path, finetuning_task=None +): + # Initialise PyTorch model + config = XLNetConfig.from_json_file(bert_config_file) + + finetuning_task = finetuning_task.lower() if finetuning_task is not None else "" + if finetuning_task in GLUE_TASKS_NUM_LABELS: + print(f"Building PyTorch XLNetForSequenceClassification model from configuration: {config}") + config.finetuning_task = finetuning_task + config.num_labels = GLUE_TASKS_NUM_LABELS[finetuning_task] + model = XLNetForSequenceClassification(config) + elif "squad" in finetuning_task: + config.finetuning_task = finetuning_task + model = XLNetForQuestionAnswering(config) + else: + model = XLNetLMHeadModel(config) + + # Load weights from tf checkpoint + load_tf_weights_in_xlnet(model, config, tf_checkpoint_path) + + # Save pytorch-model + pytorch_weights_dump_path = os.path.join(pytorch_dump_folder_path, WEIGHTS_NAME) + pytorch_config_dump_path = os.path.join(pytorch_dump_folder_path, CONFIG_NAME) + print(f"Save PyTorch model to {os.path.abspath(pytorch_weights_dump_path)}") + torch.save(model.state_dict(), pytorch_weights_dump_path) + print(f"Save configuration file to {os.path.abspath(pytorch_config_dump_path)}") + with open(pytorch_config_dump_path, "w", encoding="utf-8") as f: + f.write(config.to_json_string()) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path." + ) + parser.add_argument( + "--xlnet_config_file", + default=None, + type=str, + required=True, + help=( + "The config json file corresponding to the pre-trained XLNet model. \n" + "This specifies the model architecture." + ), + ) + parser.add_argument( + "--pytorch_dump_folder_path", + default=None, + type=str, + required=True, + help="Path to the folder to store the PyTorch model or dataset/vocab.", + ) + parser.add_argument( + "--finetuning_task", + default=None, + type=str, + help="Name of a task on which the XLNet TensorFlow model was fine-tuned", + ) + args = parser.parse_args() + print(args) + + convert_xlnet_checkpoint_to_pytorch( + args.tf_checkpoint_path, args.xlnet_config_file, args.pytorch_dump_folder_path, args.finetuning_task + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_tf_xlnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_tf_xlnet.py new file mode 100644 index 0000000000000000000000000000000000000000..080dd91f2301cd9c1e54a0d99dbb705a6ee95309 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_tf_xlnet.py @@ -0,0 +1,1781 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + TF 2.0 XLNet model. +""" + +import warnings +from dataclasses import dataclass +from typing import List, Optional, Tuple, Union + +import numpy as np +import tensorflow as tf + +from ...activations_tf import get_tf_activation +from ...modeling_tf_utils import ( + TFCausalLanguageModelingLoss, + TFModelInputType, + TFMultipleChoiceLoss, + TFPreTrainedModel, + TFQuestionAnsweringLoss, + TFSequenceClassificationLoss, + TFSequenceSummary, + TFSharedEmbeddings, + TFTokenClassificationLoss, + get_initializer, + keras_serializable, + unpack_inputs, +) +from ...tf_utils import shape_list, stable_softmax +from ...utils import ( + MULTIPLE_CHOICE_DUMMY_INPUTS, + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlnet import XLNetConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlnet-base-cased" +_CONFIG_FOR_DOC = "XLNetConfig" + +TF_XLNET_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlnet-base-cased", + "xlnet-large-cased", + # See all XLNet models at https://huggingface.co/models?filter=xlnet +] + + +class TFXLNetRelativeAttention(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + if config.d_model % config.n_head != 0: + raise ValueError( + f"The hidden size ({config.d_model}) is not a multiple of the number of attention " + f"heads ({config.n_head}" + ) + + self.n_head = config.n_head + self.d_head = config.d_head + self.d_model = config.d_model + self.scale = 1 / (config.d_head**0.5) + self.initializer_range = config.initializer_range + self.output_attentions = config.output_attentions + + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.dropout = tf.keras.layers.Dropout(config.dropout) + + def build(self, input_shape): + initializer = get_initializer(self.initializer_range) + self.q = self.add_weight( + shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="q" + ) + self.k = self.add_weight( + shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="k" + ) + self.v = self.add_weight( + shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="v" + ) + self.o = self.add_weight( + shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="o" + ) + self.r = self.add_weight( + shape=(self.d_model, self.n_head, self.d_head), initializer=initializer, trainable=True, name="r" + ) + self.r_r_bias = self.add_weight( + shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias" + ) + self.r_s_bias = self.add_weight( + shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_s_bias" + ) + self.r_w_bias = self.add_weight( + shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias" + ) + self.seg_embed = self.add_weight( + shape=(2, self.n_head, self.d_head), initializer=initializer, trainable=True, name="seg_embed" + ) + super().build(input_shape) + + def prune_heads(self, heads): + raise NotImplementedError + + def rel_shift(self, x, klen=-1): + """perform relative shift to form the relative attention score.""" + x_size = shape_list(x) + + x = tf.reshape(x, (x_size[1], x_size[0], x_size[2], x_size[3])) + x = x[1:, ...] + x = tf.reshape(x, (x_size[0], x_size[1] - 1, x_size[2], x_size[3])) + x = x[:, 0:klen, :, :] + # x = torch.index_select(x, 1, torch.arange(klen, device=x.device, dtype=torch.long)) + + return x + + def rel_attn_core( + self, q_head, k_head_h, v_head_h, k_head_r, seg_mat, attn_mask, head_mask, output_attentions, training=False + ): + """Core relative positional attention operations.""" + # content based attention score + ac = tf.einsum("ibnd,jbnd->ijbn", q_head + self.r_w_bias, k_head_h) + + # position based attention score + bd = tf.einsum("ibnd,jbnd->ijbn", q_head + self.r_r_bias, k_head_r) + bd = self.rel_shift(bd, klen=shape_list(ac)[1]) + + # segment based attention score + if seg_mat is None: + ef = 0 + else: + ef = tf.einsum("ibnd,snd->ibns", q_head + self.r_s_bias, self.seg_embed) + ef = tf.einsum("ijbs,ibns->ijbn", seg_mat, ef) + + # merge attention scores and perform masking + attn_score = (ac + bd + ef) * self.scale + if attn_mask is not None: + # attn_score = attn_score * (1 - attn_mask) - 1e30 * attn_mask + if attn_mask.dtype == tf.float16 or attn_mask.dtype == tf.bfloat16: + attn_score = attn_score - 65500 * attn_mask + else: + attn_score = attn_score - 1e30 * attn_mask + + # attention probability + attn_prob = stable_softmax(attn_score, axis=1) + + attn_prob = self.dropout(attn_prob, training=training) + + # Mask heads if we want to + if head_mask is not None: + attn_prob = attn_prob * head_mask + + # attention output + attn_vec = tf.einsum("ijbn,jbnd->ibnd", attn_prob, v_head_h) + + if output_attentions: + return attn_vec, attn_prob + + return attn_vec + + def post_attention(self, h, attn_vec, residual=True, training=False): + """Post-attention processing.""" + # post-attention projection (back to `d_model`) + attn_out = tf.einsum("ibnd,hnd->ibh", attn_vec, self.o) + + attn_out = self.dropout(attn_out, training=training) + + if residual: + attn_out = attn_out + h + output = self.layer_norm(attn_out) + + return output + + def call( + self, + h, + g, + attn_mask_h, + attn_mask_g, + r, + seg_mat, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = False, + training: bool = False, + ): + if g is not None: + # Two-stream attention with relative positional encoding. + # content based attention score + if mems is not None and len(shape_list(mems)) > 1: + cat = tf.concat([mems, h], axis=0) + else: + cat = h + + # content-based key head + k_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.k) + + # content-based value head + v_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.v) + + # position-based key head + k_head_r = tf.einsum("ibh,hnd->ibnd", r, self.r) + + # h-stream + # content-stream query head + q_head_h = tf.einsum("ibh,hnd->ibnd", h, self.q) + + # core attention ops + attn_vec_h = self.rel_attn_core( + q_head_h, + k_head_h, + v_head_h, + k_head_r, + seg_mat, + attn_mask_h, + head_mask, + output_attentions, + training=training, + ) + + if output_attentions: + attn_vec_h, attn_prob_h = attn_vec_h + + # post processing + output_h = self.post_attention(h, attn_vec_h, training=training) + + # g-stream + # query-stream query head + q_head_g = tf.einsum("ibh,hnd->ibnd", g, self.q) + + # core attention ops + if target_mapping is not None: + q_head_g = tf.einsum("mbnd,mlb->lbnd", q_head_g, target_mapping) + attn_vec_g = self.rel_attn_core( + q_head_g, + k_head_h, + v_head_h, + k_head_r, + seg_mat, + attn_mask_g, + head_mask, + output_attentions, + training=training, + ) + + if output_attentions: + attn_vec_g, attn_prob_g = attn_vec_g + + attn_vec_g = tf.einsum("lbnd,mlb->mbnd", attn_vec_g, target_mapping) + else: + attn_vec_g = self.rel_attn_core( + q_head_g, + k_head_h, + v_head_h, + k_head_r, + seg_mat, + attn_mask_g, + head_mask, + output_attentions, + training=training, + ) + + if output_attentions: + attn_vec_g, attn_prob_g = attn_vec_g + + # post processing + output_g = self.post_attention(g, attn_vec_g, training=training) + + if output_attentions: + attn_prob = attn_prob_h, attn_prob_g + + else: + # Multi-head attention with relative positional encoding + if mems is not None and len(shape_list(mems)) > 1: + cat = tf.concat([mems, h], axis=0) + else: + cat = h + + # content heads + q_head_h = tf.einsum("ibh,hnd->ibnd", h, self.q) + k_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.k) + v_head_h = tf.einsum("ibh,hnd->ibnd", cat, self.v) + + # positional heads + k_head_r = tf.einsum("ibh,hnd->ibnd", r, self.r) + + # core attention ops + attn_vec = self.rel_attn_core( + q_head_h, + k_head_h, + v_head_h, + k_head_r, + seg_mat, + attn_mask_h, + head_mask, + output_attentions, + training=training, + ) + + if output_attentions: + attn_vec, attn_prob = attn_vec + + # post processing + output_h = self.post_attention(h, attn_vec, training=training) + output_g = None + + outputs = (output_h, output_g) + if output_attentions: + outputs = outputs + (attn_prob,) + return outputs + + +class TFXLNetFeedForward(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=config.layer_norm_eps, name="layer_norm") + self.layer_1 = tf.keras.layers.Dense( + config.d_inner, kernel_initializer=get_initializer(config.initializer_range), name="layer_1" + ) + self.layer_2 = tf.keras.layers.Dense( + config.d_model, kernel_initializer=get_initializer(config.initializer_range), name="layer_2" + ) + self.dropout = tf.keras.layers.Dropout(config.dropout) + if isinstance(config.ff_activation, str): + self.activation_function = get_tf_activation(config.ff_activation) + else: + self.activation_function = config.ff_activation + + def call(self, inp, training=False): + output = inp + output = self.layer_1(output) + output = self.activation_function(output) + output = self.dropout(output, training=training) + output = self.layer_2(output) + output = self.dropout(output, training=training) + output = self.layer_norm(output + inp) + return output + + +class TFXLNetLayer(tf.keras.layers.Layer): + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + self.rel_attn = TFXLNetRelativeAttention(config, name="rel_attn") + self.ff = TFXLNetFeedForward(config, name="ff") + self.dropout = tf.keras.layers.Dropout(config.dropout) + + def call( + self, + output_h, + output_g, + non_tgt_mask, + attn_mask, + pos_emb, + seg_mat, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + output_attentions: Optional[bool] = False, + training: bool = False, + ): + outputs = self.rel_attn( + output_h, + output_g, + non_tgt_mask, + attn_mask, + pos_emb, + seg_mat, + mems, + target_mapping, + head_mask, + output_attentions, + training=training, + ) + output_h, output_g = outputs[:2] + + if output_g is not None: + output_g = self.ff(output_g, training=training) + output_h = self.ff(output_h, training=training) + + outputs = (output_h, output_g) + outputs[2:] # Add again attentions if there are there + return outputs + + +class TFXLNetLMHead(tf.keras.layers.Layer): + def __init__(self, config, input_embeddings, **kwargs): + super().__init__(**kwargs) + self.config = config + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.input_embeddings = input_embeddings + + def build(self, input_shape): + self.bias = self.add_weight(shape=(self.config.vocab_size,), initializer="zeros", trainable=True, name="bias") + super().build(input_shape) + + def get_output_embeddings(self): + return self.input_embeddings + + def set_output_embeddings(self, value): + self.input_embeddings.weight = value + self.input_embeddings.vocab_size = shape_list(value)[0] + + def get_bias(self): + return {"bias": self.bias} + + def set_bias(self, value): + self.bias = value["bias"] + self.config.vocab_size = shape_list(value["bias"])[0] + + def call(self, hidden_states): + hidden_states = self.input_embeddings(hidden_states, mode="linear") + hidden_states = hidden_states + self.bias + return hidden_states + + +@keras_serializable +class TFXLNetMainLayer(tf.keras.layers.Layer): + config_class = XLNetConfig + + def __init__(self, config, **kwargs): + super().__init__(**kwargs) + + self.config = config + self.output_hidden_states = config.output_hidden_states + self.output_attentions = config.output_attentions + self.return_dict = config.return_dict + + self.mem_len = config.mem_len + self.reuse_len = config.reuse_len + self.d_model = config.d_model + self.same_length = config.same_length + self.attn_type = config.attn_type + self.bi_data = config.bi_data + self.clamp_len = config.clamp_len + self.n_layer = config.n_layer + self.use_bfloat16 = config.use_bfloat16 + self.initializer_range = config.initializer_range + + self.word_embedding = TFSharedEmbeddings( + config.vocab_size, config.d_model, initializer_range=config.initializer_range, name="word_embedding" + ) + self.layer = [TFXLNetLayer(config, name=f"layer_._{i}") for i in range(config.n_layer)] + self.dropout = tf.keras.layers.Dropout(config.dropout) + + self.use_mems_eval = config.use_mems_eval + self.use_mems_train = config.use_mems_train + + def get_input_embeddings(self): + return self.word_embedding + + def set_input_embeddings(self, value): + self.word_embedding.weight = value + self.word_embedding.vocab_size = shape_list(value)[0] + + def build(self, input_shape): + initializer = get_initializer(self.initializer_range) + self.mask_emb = self.add_weight( + shape=(1, 1, self.d_model), initializer=initializer, trainable=True, name="mask_emb" + ) + + def _prune_heads(self, heads_to_prune): + raise NotImplementedError + + def create_mask(self, qlen, mlen): + """ + Creates causal attention mask. Float mask where 1.0 indicates masked, 0.0 indicates not-masked. + + Args: + qlen: TODO Lysandre didn't fill + mlen: TODO Lysandre didn't fill + + ``` + + same_length=False: same_length=True: + < qlen > < qlen > + ^ [0 0 0 0 0 1 1 1 1] [0 0 0 0 0 1 1 1 1] + [0 0 0 0 0 0 1 1 1] [1 0 0 0 0 0 1 1 1] + qlen [0 0 0 0 0 0 0 1 1] [1 1 0 0 0 0 0 1 1] + [0 0 0 0 0 0 0 0 1] [1 1 1 0 0 0 0 0 1] + v [0 0 0 0 0 0 0 0 0] [1 1 1 1 0 0 0 0 0] + ``` + """ + attn_mask = tf.ones([qlen, qlen]) + mask_u = tf.linalg.band_part(attn_mask, 0, -1) + mask_dia = tf.linalg.band_part(attn_mask, 0, 0) + attn_mask_pad = tf.zeros([qlen, mlen]) + ret = tf.concat([attn_mask_pad, mask_u - mask_dia], 1) + if self.same_length: + mask_l = tf.linalg.band_part(attn_mask, -1, 0) + ret = tf.concat([ret[:, :qlen] + mask_l - mask_dia, ret[:, qlen:]], 1) + return ret + + def cache_mem(self, curr_out, prev_mem): + # cache hidden states into memory. + if self.reuse_len is not None and self.reuse_len > 0: + curr_out = curr_out[: self.reuse_len] + + if self.mem_len is None or self.mem_len == 0: + # If `use_mems` is active but no `mem_len` is defined, the model behaves like GPT-2 at inference time + # and returns all of the past and current hidden states. + cutoff = 0 + else: + # If `use_mems` is active and `mem_len` is defined, the model returns the last `mem_len` hidden + # states. This is the preferred setting for training and long-form generation. + cutoff = -self.mem_len + if prev_mem is None: + # if `use_mems` is active and `mem_len` is defined, the model + new_mem = curr_out[cutoff:] + else: + new_mem = tf.concat([prev_mem, curr_out], 0)[cutoff:] + + return tf.stop_gradient(new_mem) + + @staticmethod + def positional_embedding(pos_seq, inv_freq, bsz=None): + sinusoid_inp = tf.einsum("i,d->id", pos_seq, inv_freq) + pos_emb = tf.concat([tf.sin(sinusoid_inp), tf.cos(sinusoid_inp)], axis=-1) + pos_emb = pos_emb[:, None, :] + + if bsz is not None: + pos_emb = tf.tile(pos_emb, [1, bsz, 1]) + + return pos_emb + + def relative_positional_encoding(self, qlen, klen, bsz=None): + """create relative positional encoding.""" + freq_seq = tf.range(0, self.d_model, 2.0) + inv_freq = 1 / (10000 ** (freq_seq / self.d_model)) + + if self.attn_type == "bi": + # beg, end = klen - 1, -qlen + beg, end = klen, -qlen + elif self.attn_type == "uni": + # beg, end = klen - 1, -1 + beg, end = klen, -1 + else: + raise ValueError(f"Unknown `attn_type` {self.attn_type}.") + + if self.bi_data: + fwd_pos_seq = tf.range(beg, end, -1.0) + bwd_pos_seq = tf.range(-beg, -end, 1.0) + + if self.clamp_len > 0: + fwd_pos_seq = tf.clip_by_value(fwd_pos_seq, -self.clamp_len, self.clamp_len) + bwd_pos_seq = tf.clip_by_value(bwd_pos_seq, -self.clamp_len, self.clamp_len) + + if bsz is not None: + if bsz % 2 != 0: + raise ValueError(f"With bi_data, the batch size {bsz} should be divisible by 2") + fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz // 2) + bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq, bsz // 2) + else: + fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq) + bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq) + + pos_emb = tf.concat([fwd_pos_emb, bwd_pos_emb], axis=1) + else: + fwd_pos_seq = tf.range(beg, end, -1.0) + if self.clamp_len > 0: + fwd_pos_seq = tf.clip_by_value(fwd_pos_seq, -self.clamp_len, self.clamp_len) + pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz) + + return pos_emb + + @unpack_inputs + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ): + if training and use_mems is None: + use_mems = self.use_mems_train + else: + use_mems = self.use_mems_eval + + # the original code for XLNet uses shapes [len, bsz] with the batch dimension at the end + # but we want a unified interface in the library with the batch size on the first dimension + # so we move here the first dimension (batch) to the end + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_ids = tf.transpose(input_ids, perm=(1, 0)) + qlen, bsz = shape_list(input_ids)[:2] + elif inputs_embeds is not None: + inputs_embeds = tf.transpose(inputs_embeds, perm=(1, 0, 2)) + qlen, bsz = shape_list(inputs_embeds)[:2] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + token_type_ids = tf.transpose(token_type_ids, perm=(1, 0)) if token_type_ids is not None else None + input_mask = tf.transpose(input_mask, perm=(1, 0)) if input_mask is not None else None + attention_mask = tf.transpose(attention_mask, perm=(1, 0)) if attention_mask is not None else None + perm_mask = tf.transpose(perm_mask, perm=(1, 2, 0)) if perm_mask is not None else None + target_mapping = tf.transpose(target_mapping, perm=(1, 2, 0)) if target_mapping is not None else None + + mlen = shape_list(mems[0])[0] if mems is not None and mems[0] is not None else 0 + klen = mlen + qlen + + # Attention mask + # causal attention mask + if self.attn_type == "uni": + attn_mask = self.create_mask(qlen, mlen) + attn_mask = attn_mask[:, :, None, None] + elif self.attn_type == "bi": + attn_mask = None + else: + raise ValueError(f"Unsupported attention type: {self.attn_type}") + + # data mask: input mask & perm mask + assert input_mask is None or attention_mask is None, ( + "You can only use one of input_mask (uses 1 for padding) " + "or attention_mask (uses 0 for padding, added for compatibility with BERT). Please choose one." + ) + if input_mask is None and attention_mask is not None: + one_cst = tf.constant(1.0) + input_mask = 1.0 - tf.cast(attention_mask, dtype=one_cst.dtype) + if input_mask is not None and perm_mask is not None: + data_mask = input_mask[None] + perm_mask + elif input_mask is not None and perm_mask is None: + data_mask = input_mask[None] + elif input_mask is None and perm_mask is not None: + data_mask = perm_mask + else: + data_mask = None + + if data_mask is not None: + # all mems can be attended to + if mlen > 0: + mems_mask = tf.zeros([shape_list(data_mask)[0], mlen, bsz]) + data_mask = tf.concat([mems_mask, data_mask], axis=1) + if attn_mask is None: + attn_mask = data_mask[:, :, :, None] + else: + attn_mask += data_mask[:, :, :, None] + + if attn_mask is not None: + attn_mask = tf.cast(attn_mask > 0, dtype=attn_mask.dtype) + + if attn_mask is not None: + non_tgt_mask = -tf.eye(qlen) + if mlen > 0: + non_tgt_mask = tf.concat([tf.zeros([qlen, mlen]), non_tgt_mask], axis=-1) + non_tgt_mask = tf.cast((attn_mask + non_tgt_mask[:, :, None, None]) > 0, dtype=non_tgt_mask.dtype) + else: + non_tgt_mask = None + + # Word embeddings and prepare h & g hidden states + if inputs_embeds is not None: + word_emb_k = inputs_embeds + else: + # Note: tf.gather, on which the embedding layer is based, won't check positive out of bound + # indices on GPU, returning zeros instead. This is a dangerous silent behavior. + tf.debugging.assert_less( + input_ids, + tf.cast(self.word_embedding.vocab_size, dtype=input_ids.dtype), + message=( + "input_ids must be smaller than the embedding layer's input dimension (got" + f" {tf.math.reduce_max(input_ids)} >= {self.word_embedding.vocab_size})" + ), + ) + word_emb_k = self.word_embedding(input_ids) + output_h = self.dropout(word_emb_k, training=training) + if target_mapping is not None: + word_emb_q = tf.tile(self.mask_emb, [shape_list(target_mapping)[0], bsz, 1]) + # else: # We removed the inp_q input which was same as target mapping + # inp_q_ext = inp_q[:, :, None] + # word_emb_q = inp_q_ext * self.mask_emb + (1 - inp_q_ext) * word_emb_k + output_g = self.dropout(word_emb_q, training=training) + else: + output_g = None + + # Segment embedding + if token_type_ids is not None: + # Convert `token_type_ids` to one-hot `seg_mat` + if mlen > 0: + mem_pad = tf.zeros([mlen, bsz], dtype=token_type_ids.dtype) + cat_ids = tf.concat([mem_pad, token_type_ids], 0) + else: + cat_ids = token_type_ids + + # `1` indicates not in the same segment [qlen x klen x bsz] + seg_mat = tf.cast( + tf.logical_not(tf.equal(token_type_ids[:, None], cat_ids[None, :])), + dtype=token_type_ids.dtype, + ) + seg_mat = tf.one_hot(seg_mat, 2) + else: + seg_mat = None + + # Positional encoding + pos_emb = self.relative_positional_encoding(qlen, klen, bsz=bsz) + pos_emb = self.dropout(pos_emb, training=training) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] (a head_mask for each layer) + # and head_mask is converted to shape [num_hidden_layers x qlen x klen x bsz x n_head] + if head_mask is not None: + raise NotImplementedError + else: + head_mask = [None] * self.n_layer + + new_mems = () + if mems is None: + mems = [None] * len(self.layer) + + attentions = [] if output_attentions else None + hidden_states = [] if output_hidden_states else None + for i, layer_module in enumerate(self.layer): + # cache new mems + if use_mems: + new_mems = new_mems + (self.cache_mem(output_h, mems[i]),) + if output_hidden_states: + hidden_states.append((output_h, output_g) if output_g is not None else output_h) + + outputs = layer_module( + output_h, + output_g, + non_tgt_mask, + attn_mask, + pos_emb, + seg_mat, + mems[i], + target_mapping, + head_mask[i], + output_attentions, + training=training, + ) + output_h, output_g = outputs[:2] + if output_attentions: + attentions.append(outputs[2]) + + # Add last hidden state + if output_hidden_states: + hidden_states.append((output_h, output_g) if output_g is not None else output_h) + + output = self.dropout(output_g if output_g is not None else output_h, training=training) + + # Prepare outputs, we transpose back here to shape [bsz, len, hidden_dim] (cf. beginning of forward() method) + output = tf.transpose(output, perm=(1, 0, 2)) + + if not use_mems: + new_mems = None + if output_hidden_states: + if output_g is not None: + hidden_states = tuple(tf.transpose(h, perm=(1, 0, 2)) for hs in hidden_states for h in hs) + else: + hidden_states = tuple(tf.transpose(hs, perm=(1, 0, 2)) for hs in hidden_states) + if output_attentions: + if target_mapping is not None: + # when target_mapping is provided, there are 2-tuple of attentions + attentions = tuple( + tuple(tf.transpose(attn_stream, perm=(2, 3, 0, 1)) for attn_stream in t) for t in attentions + ) + else: + attentions = tuple(tf.transpose(t, perm=(2, 3, 0, 1)) for t in attentions) + + if not return_dict: + return tuple(v for v in [output, new_mems, hidden_states, attentions] if v is not None) + + return TFXLNetModelOutput( + last_hidden_state=output, mems=new_mems, hidden_states=hidden_states, attentions=attentions + ) + + +class TFXLNetPreTrainedModel(TFPreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLNetConfig + base_model_prefix = "transformer" + + +@dataclass +class TFXLNetModelOutput(ModelOutput): + """ + Output type of [`TFXLNetModel`]. + + Args: + last_hidden_state (`tf.Tensor` of shape `(batch_size, num_predict, hidden_size)`): + Sequence of hidden-states at the last layer of the model. + + `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` + corresponds to `sequence_length`. + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + last_hidden_state: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFXLNetLMHeadModelOutput(ModelOutput): + """ + Output type of [`TFXLNetLMHeadModel`]. + + Args: + loss (`tf.Tensor` of shape *(1,)*, *optional*, returned when `labels` is provided) + Language modeling loss (for next-token prediction). + logits (`tf.Tensor` of shape `(batch_size, num_predict, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + + `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` + corresponds to `sequence_length`. + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[tf.Tensor] = None + logits: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFXLNetForSequenceClassificationOutput(ModelOutput): + """ + Output type of [`TFXLNetForSequenceClassification`]. + + Args: + loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `label` is provided): + Classification (or regression if config.num_labels==1) loss. + logits (`tf.Tensor` of shape `(batch_size, config.num_labels)`): + Classification (or regression if config.num_labels==1) scores (before SoftMax). + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[tf.Tensor] = None + logits: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFXLNetForTokenClassificationOutput(ModelOutput): + """ + Output type of [`TFXLNetForTokenClassificationOutput`]. + + Args: + loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided) : + Classification loss. + logits (`tf.Tensor` of shape `(batch_size, sequence_length, config.num_labels)`): + Classification scores (before SoftMax). + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[tf.Tensor] = None + logits: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFXLNetForMultipleChoiceOutput(ModelOutput): + """ + Output type of [`TFXLNetForMultipleChoice`]. + + Args: + loss (`tf.Tensor` of shape *(1,)*, *optional*, returned when `labels` is provided): + Classification loss. + logits (`tf.Tensor` of shape `(batch_size, num_choices)`): + *num_choices* is the second dimension of the input tensors. (see *input_ids* above). + + Classification scores (before SoftMax). + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[tf.Tensor] = None + logits: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +@dataclass +class TFXLNetForQuestionAnsweringSimpleOutput(ModelOutput): + """ + Output type of [`TFXLNetForQuestionAnsweringSimple`]. + + Args: + loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. + start_logits (`tf.Tensor` of shape `(batch_size, sequence_length,)`): + Span-start scores (before SoftMax). + end_logits (`tf.Tensor` of shape `(batch_size, sequence_length,)`): + Span-end scores (before SoftMax). + mems (`List[tf.Tensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(tf.Tensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `tf.Tensor` (one for the output of the embeddings + one for the output of each layer) of shape + `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(tf.Tensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `tf.Tensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[tf.Tensor] = None + start_logits: tf.Tensor = None + end_logits: tf.Tensor = None + mems: Optional[List[tf.Tensor]] = None + hidden_states: Optional[Tuple[tf.Tensor]] = None + attentions: Optional[Tuple[tf.Tensor]] = None + + +XLNET_START_DOCSTRING = r""" + + This model inherits from [`TFPreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a [tf.keras.Model](https://www.tensorflow.org/api_docs/python/tf/keras/Model) subclass. Use it + as a regular TF 2.0 Keras Model and refer to the TF 2.0 documentation for all matter related to general usage and + behavior. + + + + TensorFlow models and layers in `transformers` accept two formats as input: + + - having all inputs as keyword arguments (like PyTorch models), or + - having all inputs as a list, tuple or dict in the first positional argument. + + The reason the second format is supported is that Keras methods prefer this format when passing inputs to models + and layers. Because of this support, when using methods like `model.fit()` things should "just work" for you - just + pass your inputs and labels in any format that `model.fit()` supports! If, however, you want to use the second + format outside of Keras methods like `fit()` and `predict()`, such as when creating your own layers or models with + the Keras `Functional` API, there are three possibilities you can use to gather all the input Tensors in the first + positional argument: + + - a single Tensor with `input_ids` only and nothing else: `model(input_ids)` + - a list of varying length with one or several input Tensors IN THE ORDER given in the docstring: + `model([input_ids, attention_mask])` or `model([input_ids, attention_mask, token_type_ids])` + - a dictionary with one or several input Tensors associated to the input names given in the docstring: + `model({"input_ids": input_ids, "token_type_ids": token_type_ids})` + + Note that when creating models and layers with + [subclassing](https://keras.io/guides/making_new_layers_and_models_via_subclassing/) then you don't need to worry + about any of this, as you can just pass inputs like you would to any other Python function! + + + + Parameters: + config ([`XLNetConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLNET_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states (see `mems` output below) . Can be used to speed up sequential + decoding. The token ids which have their past given to this model should not be passed as `input_ids` as + they have already been computed. + + `use_mems` has to be set to `True` to make use of `mems`. + perm_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length, sequence_length)`, *optional*): + Mask to indicate the attention pattern for each input token with values selected in `[0, 1]`: + + - if `perm_mask[k, i, j] = 0`, i attend to j in batch k; + - if `perm_mask[k, i, j] = 1`, i does not attend to j in batch k. + + If not set, each token attends to all the others (full bidirectional attention). Only used during + pretraining (to define factorization order) or for sequential decoding (generation). + target_mapping (`torch.FloatTensor` of shape `(batch_size, num_predict, sequence_length)`, *optional*): + Mask to indicate the output tokens to use. If `target_mapping[k, i, j] = 1`, the i-th predict in batch k is + on the j-th token. Only used during pretraining for partial prediction or for sequential decoding + (generation). + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + input_mask (`torch.FloatTensor` of shape `{0}`, *optional*): + Mask to avoid performing attention on padding token indices. Negative of `attention_mask`, i.e. with 0 for + real tokens and 1 for padding which is kept for compatibility with the original code base. + + Mask values selected in `[0, 1]`: + + - 1 for tokens that are **masked**, + - 0 for tokens that are **not masked**. + + You can only uses one of `input_mask` and `attention_mask`. + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare XLNet Model transformer outputting raw hidden-states without any specific head on top.", + XLNET_START_DOCSTRING, +) +class TFXLNetModel(TFXLNetPreTrainedModel): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLNetMainLayer(config, name="transformer") + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLNetModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + training: bool = False, + ) -> Union[TFXLNetModelOutput, Tuple[tf.Tensor]]: + outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + + return outputs + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetModelOutput( + last_hidden_state=output.last_hidden_state, mems=mems, hidden_states=hs, attentions=attns + ) + + +@add_start_docstrings( + """ + XLNet Model with a language modeling head on top (linear layer with weights tied to the input embeddings). + """, + XLNET_START_DOCSTRING, +) +class TFXLNetLMHeadModel(TFXLNetPreTrainedModel, TFCausalLanguageModelingLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLNetMainLayer(config, name="transformer") + self.lm_loss = TFXLNetLMHead(config, self.transformer.word_embedding, name="lm_loss") + # generate fails to convert to a graph with XLNet + self.supports_xla_generation = False + + def get_lm_head(self): + return self.lm_loss + + def get_prefix_bias_name(self): + warnings.warn("The method get_prefix_bias_name is deprecated. Please use `get_bias` instead.", FutureWarning) + return self.name + "/" + self.lm_loss.name + + def prepare_inputs_for_generation(self, inputs, past_key_values=None, use_mems=None, **kwargs): + # Add dummy token at the end (no attention on this one) + effective_batch_size = inputs.shape[0] + dummy_token = tf.zeros((effective_batch_size, 1), dtype=inputs.dtype) + + # At every pass, the attention values for the new token and the two last generated tokens + # are computed, the rest is reloaded from the `past` cache. A purely auto-regressive model would have + # offset = 1; offset = 2 seems to have slightly better computation. + offset = 2 + + if past_key_values: + input_ids = tf.concat([inputs[:, -offset:], dummy_token], axis=1) + else: + input_ids = tf.concat([inputs, dummy_token], axis=1) + + # Build permutation mask so that previous tokens don't see last token + sequence_length = input_ids.shape[1] + perm_mask = tf.zeros((effective_batch_size, sequence_length, sequence_length - 1)) + perm_mask_seq_end = tf.ones((effective_batch_size, sequence_length, 1)) + perm_mask = tf.concat([perm_mask, perm_mask_seq_end], axis=-1) + + # We'll only predict the last token + target_mapping = tf.zeros((effective_batch_size, 1, sequence_length - 1)) + target_mapping_seq_end = tf.ones((effective_batch_size, 1, 1)) + target_mapping = tf.concat([target_mapping, target_mapping_seq_end], axis=-1) + + inputs = { + "input_ids": input_ids, + "perm_mask": perm_mask, + "target_mapping": target_mapping, + "use_mems": use_mems, + } + + # if past is defined in model kwargs then use it for faster decoding + if past_key_values: + inputs["mems"] = tuple(layer_past[:-offset, :, :] for layer_past in past_key_values) + + return inputs + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=TFXLNetLMHeadModelOutput, config_class=_CONFIG_FOR_DOC) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFXLNetLMHeadModelOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the cross entropy classification loss. Indices should be in `[0, ..., + config.vocab_size - 1]`. + + Return: + + Examples: + + ```python + >>> import tensorflow as tf + >>> import numpy as np + >>> from transformers import AutoTokenizer, TFXLNetLMHeadModel + + >>> tokenizer = AutoTokenizer.from_pretrained("xlnet-large-cased") + >>> model = TFXLNetLMHeadModel.from_pretrained("xlnet-large-cased") + + >>> # We show how to setup inputs to predict a next token using a bi-directional context. + >>> input_ids = tf.constant(tokenizer.encode("Hello, my dog is very ", add_special_tokens=True))[ + ... None, : + ... ] # We will predict the masked token + + >>> perm_mask = np.zeros((1, input_ids.shape[1], input_ids.shape[1])) + >>> perm_mask[:, :, -1] = 1.0 # Previous tokens don't see last token + + >>> target_mapping = np.zeros( + ... (1, 1, input_ids.shape[1]) + ... ) # Shape [1, 1, seq_length] => let's predict one token + >>> target_mapping[ + ... 0, 0, -1 + ... ] = 1.0 # Our first (and only) prediction will be the last token of the sequence (the masked token) + + >>> outputs = model( + ... input_ids, + ... perm_mask=tf.constant(perm_mask, dtype=tf.float32), + ... target_mapping=tf.constant(target_mapping, dtype=tf.float32), + ... ) + + >>> next_token_logits = outputs[ + ... 0 + ... ] # Output has shape [target_mapping.size(0), target_mapping.size(1), config.vocab_size] + ```""" + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + hidden_state = transformer_outputs[0] + logits = self.lm_loss(hidden_state, training=training) + + loss = None + if labels is not None: + loss = self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFXLNetLMHeadModelOutput( + loss=loss, + logits=logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetLMHeadModelOutput(logits=output.logits, mems=mems, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLNet Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. + for GLUE tasks. + """, + XLNET_START_DOCSTRING, +) +class TFXLNetForSequenceClassification(TFXLNetPreTrainedModel, TFSequenceClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.transformer = TFXLNetMainLayer(config, name="transformer") + self.sequence_summary = TFSequenceSummary( + config, initializer_range=config.initializer_range, name="sequence_summary" + ) + self.logits_proj = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLNetForSequenceClassificationOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFXLNetForSequenceClassificationOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + output = transformer_outputs[0] + + output = self.sequence_summary(output) + logits = self.logits_proj(output) + + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFXLNetForSequenceClassificationOutput( + loss=loss, + logits=logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetForSequenceClassificationOutput( + logits=output.logits, mems=mems, hidden_states=hs, attentions=attns + ) + + +@add_start_docstrings( + """ + XLNET Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + XLNET_START_DOCSTRING, +) +class TFXLNetForMultipleChoice(TFXLNetPreTrainedModel, TFMultipleChoiceLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + + self.transformer = TFXLNetMainLayer(config, name="transformer") + self.sequence_summary = TFSequenceSummary( + config, initializer_range=config.initializer_range, name="sequence_summary" + ) + self.logits_proj = tf.keras.layers.Dense( + 1, kernel_initializer=get_initializer(config.initializer_range), name="logits_proj" + ) + + @property + def dummy_inputs(self): + """ + Dummy inputs to build the network. + + Returns: + tf.Tensor with dummy inputs + """ + return {"input_ids": tf.constant(MULTIPLE_CHOICE_DUMMY_INPUTS, dtype=tf.int32)} + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLNetForMultipleChoiceOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFXLNetForMultipleChoiceOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` + where `num_choices` is the size of the second dimension of the input tensors. (See `input_ids` above) + """ + + if input_ids is not None: + num_choices = shape_list(input_ids)[1] + seq_length = shape_list(input_ids)[2] + else: + num_choices = shape_list(inputs_embeds)[1] + seq_length = shape_list(inputs_embeds)[2] + + flat_input_ids = tf.reshape(input_ids, (-1, seq_length)) if input_ids is not None else None + flat_attention_mask = tf.reshape(attention_mask, (-1, seq_length)) if attention_mask is not None else None + flat_token_type_ids = tf.reshape(token_type_ids, (-1, seq_length)) if token_type_ids is not None else None + flat_input_mask = tf.reshape(input_mask, (-1, seq_length)) if input_mask is not None else None + flat_inputs_embeds = ( + tf.reshape(inputs_embeds, (-1, seq_length, shape_list(inputs_embeds)[3])) + if inputs_embeds is not None + else None + ) + transformer_outputs = self.transformer( + flat_input_ids, + flat_attention_mask, + mems, + perm_mask, + target_mapping, + flat_token_type_ids, + flat_input_mask, + head_mask, + flat_inputs_embeds, + use_mems, + output_attentions, + output_hidden_states, + return_dict=return_dict, + training=training, + ) + output = transformer_outputs[0] + logits = self.sequence_summary(output) + logits = self.logits_proj(logits) + reshaped_logits = tf.reshape(logits, (-1, num_choices)) + loss = None if labels is None else self.hf_compute_loss(labels, reshaped_logits) + + if not return_dict: + output = (reshaped_logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFXLNetForMultipleChoiceOutput( + loss=loss, + logits=reshaped_logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + @tf.function( + input_signature=[ + { + "input_ids": tf.TensorSpec((None, None, None), tf.int32, name="input_ids"), + "attention_mask": tf.TensorSpec((None, None, None), tf.int32, name="attention_mask"), + "token_type_ids": tf.TensorSpec((None, None, None), tf.int32, name="token_type_ids"), + } + ] + ) + def serving(self, inputs): + output = self.call(inputs) + + return self.serving_output(output) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetForMultipleChoiceOutput(logits=output.logits, mems=mems, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLNet Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + XLNET_START_DOCSTRING, +) +class TFXLNetForTokenClassification(TFXLNetPreTrainedModel, TFTokenClassificationLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.num_labels = config.num_labels + + self.transformer = TFXLNetMainLayer(config, name="transformer") + self.classifier = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="classifier" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLNetForTokenClassificationOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + labels: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFXLNetForTokenClassificationOutput, Tuple[tf.Tensor]]: + r""" + labels (`tf.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + output = transformer_outputs[0] + logits = self.classifier(output) + loss = None if labels is None else self.hf_compute_loss(labels, logits) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFXLNetForTokenClassificationOutput( + loss=loss, + logits=logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetForTokenClassificationOutput(logits=output.logits, mems=mems, hidden_states=hs, attentions=attns) + + +@add_start_docstrings( + """ + XLNet Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLNET_START_DOCSTRING, +) +class TFXLNetForQuestionAnsweringSimple(TFXLNetPreTrainedModel, TFQuestionAnsweringLoss): + def __init__(self, config, *inputs, **kwargs): + super().__init__(config, *inputs, **kwargs) + self.transformer = TFXLNetMainLayer(config, name="transformer") + self.qa_outputs = tf.keras.layers.Dense( + config.num_labels, kernel_initializer=get_initializer(config.initializer_range), name="qa_outputs" + ) + + @unpack_inputs + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TFXLNetForQuestionAnsweringSimpleOutput, + config_class=_CONFIG_FOR_DOC, + ) + def call( + self, + input_ids: Optional[TFModelInputType] = None, + attention_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + mems: Optional[Union[np.ndarray, tf.Tensor]] = None, + perm_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + target_mapping: Optional[Union[np.ndarray, tf.Tensor]] = None, + token_type_ids: Optional[Union[np.ndarray, tf.Tensor]] = None, + input_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + head_mask: Optional[Union[np.ndarray, tf.Tensor]] = None, + inputs_embeds: Optional[Union[np.ndarray, tf.Tensor]] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + start_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + end_positions: Optional[Union[np.ndarray, tf.Tensor]] = None, + training: bool = False, + ) -> Union[TFXLNetForQuestionAnsweringSimpleOutput, Tuple[tf.Tensor]]: + r""" + start_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`tf.Tensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + transformer_outputs = self.transformer( + input_ids=input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + training=training, + ) + sequence_output = transformer_outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = tf.split(logits, 2, axis=-1) + start_logits = tf.squeeze(start_logits, axis=-1) + end_logits = tf.squeeze(end_logits, axis=-1) + + loss = None + if start_positions is not None and end_positions is not None: + labels = {"start_position": start_positions} + labels["end_position"] = end_positions + loss = self.hf_compute_loss(labels, (start_logits, end_logits)) + + if not return_dict: + output = (start_logits, end_logits) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TFXLNetForQuestionAnsweringSimpleOutput( + loss=loss, + start_logits=start_logits, + end_logits=end_logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + def serving_output(self, output): + hs = tf.convert_to_tensor(output.hidden_states) if self.config.output_hidden_states else None + attns = tf.convert_to_tensor(output.attentions) if self.config.output_attentions else None + mems = tf.convert_to_tensor(output.mems) if output.mems is not None else None + + return TFXLNetForQuestionAnsweringSimpleOutput( + start_logits=output.start_logits, + end_logits=output.end_logits, + mems=mems, + hidden_states=hs, + attentions=attns, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_xlnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_xlnet.py new file mode 100644 index 0000000000000000000000000000000000000000..d6ed227ff886aa3437850985d996d54b3754c848 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/modeling_xlnet.py @@ -0,0 +1,2087 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + PyTorch XLNet model. +""" +import warnings +from dataclasses import dataclass +from typing import List, Optional, Tuple, Union + +import torch +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_utils import PoolerAnswerClass, PoolerEndLogits, PoolerStartLogits, PreTrainedModel, SequenceSummary +from ...pytorch_utils import apply_chunking_to_forward +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + logging, + replace_return_docstrings, +) +from .configuration_xlnet import XLNetConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "xlnet-base-cased" +_CONFIG_FOR_DOC = "XLNetConfig" + +XLNET_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "xlnet-base-cased", + "xlnet-large-cased", + # See all XLNet models at https://huggingface.co/models?filter=xlnet +] + + +def build_tf_xlnet_to_pytorch_map(model, config, tf_weights=None): + """ + A map of modules from TF to PyTorch. I use a map to keep the PyTorch model as identical to the original PyTorch + model as possible. + """ + + tf_to_pt_map = {} + + if hasattr(model, "transformer"): + if hasattr(model, "lm_loss"): + # We will load also the output bias + tf_to_pt_map["model/lm_loss/bias"] = model.lm_loss.bias + if hasattr(model, "sequence_summary") and "model/sequnece_summary/summary/kernel" in tf_weights: + # We will load also the sequence summary + tf_to_pt_map["model/sequnece_summary/summary/kernel"] = model.sequence_summary.summary.weight + tf_to_pt_map["model/sequnece_summary/summary/bias"] = model.sequence_summary.summary.bias + if ( + hasattr(model, "logits_proj") + and config.finetuning_task is not None + and f"model/regression_{config.finetuning_task}/logit/kernel" in tf_weights + ): + tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/kernel"] = model.logits_proj.weight + tf_to_pt_map[f"model/regression_{config.finetuning_task}/logit/bias"] = model.logits_proj.bias + + # Now load the rest of the transformer + model = model.transformer + + # Embeddings and output + tf_to_pt_map.update( + { + "model/transformer/word_embedding/lookup_table": model.word_embedding.weight, + "model/transformer/mask_emb/mask_emb": model.mask_emb, + } + ) + + # Transformer blocks + for i, b in enumerate(model.layer): + layer_str = f"model/transformer/layer_{i}/" + tf_to_pt_map.update( + { + layer_str + "rel_attn/LayerNorm/gamma": b.rel_attn.layer_norm.weight, + layer_str + "rel_attn/LayerNorm/beta": b.rel_attn.layer_norm.bias, + layer_str + "rel_attn/o/kernel": b.rel_attn.o, + layer_str + "rel_attn/q/kernel": b.rel_attn.q, + layer_str + "rel_attn/k/kernel": b.rel_attn.k, + layer_str + "rel_attn/r/kernel": b.rel_attn.r, + layer_str + "rel_attn/v/kernel": b.rel_attn.v, + layer_str + "ff/LayerNorm/gamma": b.ff.layer_norm.weight, + layer_str + "ff/LayerNorm/beta": b.ff.layer_norm.bias, + layer_str + "ff/layer_1/kernel": b.ff.layer_1.weight, + layer_str + "ff/layer_1/bias": b.ff.layer_1.bias, + layer_str + "ff/layer_2/kernel": b.ff.layer_2.weight, + layer_str + "ff/layer_2/bias": b.ff.layer_2.bias, + } + ) + + # Relative positioning biases + if config.untie_r: + r_r_list = [] + r_w_list = [] + r_s_list = [] + seg_embed_list = [] + for b in model.layer: + r_r_list.append(b.rel_attn.r_r_bias) + r_w_list.append(b.rel_attn.r_w_bias) + r_s_list.append(b.rel_attn.r_s_bias) + seg_embed_list.append(b.rel_attn.seg_embed) + else: + r_r_list = [model.r_r_bias] + r_w_list = [model.r_w_bias] + r_s_list = [model.r_s_bias] + seg_embed_list = [model.seg_embed] + tf_to_pt_map.update( + { + "model/transformer/r_r_bias": r_r_list, + "model/transformer/r_w_bias": r_w_list, + "model/transformer/r_s_bias": r_s_list, + "model/transformer/seg_embed": seg_embed_list, + } + ) + return tf_to_pt_map + + +def load_tf_weights_in_xlnet(model, config, tf_path): + """Load tf checkpoints in a pytorch model""" + try: + import numpy as np + import tensorflow as tf + except ImportError: + logger.error( + "Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see " + "https://www.tensorflow.org/install/ for installation instructions." + ) + raise + # Load weights from TF model + init_vars = tf.train.list_variables(tf_path) + tf_weights = {} + for name, shape in init_vars: + logger.info(f"Loading TF weight {name} with shape {shape}") + array = tf.train.load_variable(tf_path, name) + tf_weights[name] = array + + # Build TF to PyTorch weights loading map + tf_to_pt_map = build_tf_xlnet_to_pytorch_map(model, config, tf_weights) + + for name, pointer in tf_to_pt_map.items(): + logger.info(f"Importing {name}") + if name not in tf_weights: + logger.info(f"{name} not in tf pre-trained weights, skipping") + continue + array = tf_weights[name] + # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v + # which are not required for using pretrained model + if "kernel" in name and ("ff" in name or "summary" in name or "logit" in name): + logger.info("Transposing") + array = np.transpose(array) + if isinstance(pointer, list): + # Here we will split the TF weights + assert ( + len(pointer) == array.shape[0] + ), f"Pointer length {len(pointer)} and array length {array.shape[0]} mismatched" + for i, p_i in enumerate(pointer): + arr_i = array[i, ...] + try: + assert ( + p_i.shape == arr_i.shape + ), f"Pointer shape {p_i.shape} and array shape {arr_i.shape} mismatched" + except AssertionError as e: + e.args += (p_i.shape, arr_i.shape) + raise + logger.info(f"Initialize PyTorch weight {name} for layer {i}") + p_i.data = torch.from_numpy(arr_i) + else: + try: + assert ( + pointer.shape == array.shape + ), f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched" + except AssertionError as e: + e.args += (pointer.shape, array.shape) + raise + logger.info(f"Initialize PyTorch weight {name}") + pointer.data = torch.from_numpy(array) + tf_weights.pop(name, None) + tf_weights.pop(name + "/Adam", None) + tf_weights.pop(name + "/Adam_1", None) + + logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}") + return model + + +class XLNetRelativeAttention(nn.Module): + def __init__(self, config): + super().__init__() + + if config.d_model % config.n_head != 0: + raise ValueError( + f"The hidden size ({config.d_model}) is not a multiple of the number of attention " + f"heads ({config.n_head}" + ) + + self.n_head = config.n_head + self.d_head = config.d_head + self.d_model = config.d_model + self.scale = 1 / (config.d_head**0.5) + + self.q = nn.Parameter(torch.FloatTensor(config.d_model, self.n_head, self.d_head)) + self.k = nn.Parameter(torch.FloatTensor(config.d_model, self.n_head, self.d_head)) + self.v = nn.Parameter(torch.FloatTensor(config.d_model, self.n_head, self.d_head)) + self.o = nn.Parameter(torch.FloatTensor(config.d_model, self.n_head, self.d_head)) + self.r = nn.Parameter(torch.FloatTensor(config.d_model, self.n_head, self.d_head)) + + self.r_r_bias = nn.Parameter(torch.FloatTensor(self.n_head, self.d_head)) + self.r_s_bias = nn.Parameter(torch.FloatTensor(self.n_head, self.d_head)) + self.r_w_bias = nn.Parameter(torch.FloatTensor(self.n_head, self.d_head)) + self.seg_embed = nn.Parameter(torch.FloatTensor(2, self.n_head, self.d_head)) + + self.layer_norm = nn.LayerNorm(config.d_model, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.dropout) + + def prune_heads(self, heads): + raise NotImplementedError + + @staticmethod + def rel_shift(x, klen=-1): + """perform relative shift to form the relative attention score.""" + x_size = x.shape + + x = x.reshape(x_size[1], x_size[0], x_size[2], x_size[3]) + x = x[1:, ...] + x = x.reshape(x_size[0], x_size[1] - 1, x_size[2], x_size[3]) + # x = x[:, 0:klen, :, :] + x = torch.index_select(x, 1, torch.arange(klen, device=x.device, dtype=torch.long)) + + return x + + @staticmethod + def rel_shift_bnij(x, klen=-1): + x_size = x.shape + + x = x.reshape(x_size[0], x_size[1], x_size[3], x_size[2]) + x = x[:, :, 1:, :] + x = x.reshape(x_size[0], x_size[1], x_size[2], x_size[3] - 1) + # Note: the tensor-slice form was faster in my testing than torch.index_select + # However, tracing doesn't like the nature of the slice, and if klen changes + # during the run then it'll fail, whereas index_select will be fine. + x = torch.index_select(x, 3, torch.arange(klen, device=x.device, dtype=torch.long)) + # x = x[:, :, :, :klen] + + return x + + def rel_attn_core( + self, + q_head, + k_head_h, + v_head_h, + k_head_r, + seg_mat=None, + attn_mask=None, + head_mask=None, + output_attentions=False, + ): + """Core relative positional attention operations.""" + + # content based attention score + ac = torch.einsum("ibnd,jbnd->bnij", q_head + self.r_w_bias, k_head_h) + + # position based attention score + bd = torch.einsum("ibnd,jbnd->bnij", q_head + self.r_r_bias, k_head_r) + bd = self.rel_shift_bnij(bd, klen=ac.shape[3]) + + # segment based attention score + if seg_mat is None: + ef = 0 + else: + ef = torch.einsum("ibnd,snd->ibns", q_head + self.r_s_bias, self.seg_embed) + ef = torch.einsum("ijbs,ibns->bnij", seg_mat, ef) + + # merge attention scores and perform masking + attn_score = (ac + bd + ef) * self.scale + if attn_mask is not None: + # attn_score = attn_score * (1 - attn_mask) - 1e30 * attn_mask + if attn_mask.dtype == torch.float16: + attn_score = attn_score - 65500 * torch.einsum("ijbn->bnij", attn_mask) + else: + attn_score = attn_score - 1e30 * torch.einsum("ijbn->bnij", attn_mask) + + # attention probability + attn_prob = nn.functional.softmax(attn_score, dim=3) + attn_prob = self.dropout(attn_prob) + + # Mask heads if we want to + if head_mask is not None: + attn_prob = attn_prob * torch.einsum("ijbn->bnij", head_mask) + + # attention output + attn_vec = torch.einsum("bnij,jbnd->ibnd", attn_prob, v_head_h) + + if output_attentions: + return attn_vec, torch.einsum("bnij->ijbn", attn_prob) + + return attn_vec + + def post_attention(self, h, attn_vec, residual=True): + """Post-attention processing.""" + # post-attention projection (back to `d_model`) + attn_out = torch.einsum("ibnd,hnd->ibh", attn_vec, self.o) + + attn_out = self.dropout(attn_out) + if residual: + attn_out = attn_out + h + output = self.layer_norm(attn_out) + + return output + + def forward( + self, + h, + g, + attn_mask_h, + attn_mask_g, + r, + seg_mat, + mems=None, + target_mapping=None, + head_mask=None, + output_attentions=False, + ): + if g is not None: + # Two-stream attention with relative positional encoding. + # content based attention score + if mems is not None and mems.dim() > 1: + cat = torch.cat([mems, h], dim=0) + else: + cat = h + + # content-based key head + k_head_h = torch.einsum("ibh,hnd->ibnd", cat, self.k) + + # content-based value head + v_head_h = torch.einsum("ibh,hnd->ibnd", cat, self.v) + + # position-based key head + k_head_r = torch.einsum("ibh,hnd->ibnd", r, self.r) + + # h-stream + # content-stream query head + q_head_h = torch.einsum("ibh,hnd->ibnd", h, self.q) + + # core attention ops + attn_vec_h = self.rel_attn_core( + q_head_h, + k_head_h, + v_head_h, + k_head_r, + seg_mat=seg_mat, + attn_mask=attn_mask_h, + head_mask=head_mask, + output_attentions=output_attentions, + ) + + if output_attentions: + attn_vec_h, attn_prob_h = attn_vec_h + + # post processing + output_h = self.post_attention(h, attn_vec_h) + + # g-stream + # query-stream query head + q_head_g = torch.einsum("ibh,hnd->ibnd", g, self.q) + + # core attention ops + if target_mapping is not None: + q_head_g = torch.einsum("mbnd,mlb->lbnd", q_head_g, target_mapping) + attn_vec_g = self.rel_attn_core( + q_head_g, + k_head_h, + v_head_h, + k_head_r, + seg_mat=seg_mat, + attn_mask=attn_mask_g, + head_mask=head_mask, + output_attentions=output_attentions, + ) + + if output_attentions: + attn_vec_g, attn_prob_g = attn_vec_g + + attn_vec_g = torch.einsum("lbnd,mlb->mbnd", attn_vec_g, target_mapping) + else: + attn_vec_g = self.rel_attn_core( + q_head_g, + k_head_h, + v_head_h, + k_head_r, + seg_mat=seg_mat, + attn_mask=attn_mask_g, + head_mask=head_mask, + output_attentions=output_attentions, + ) + + if output_attentions: + attn_vec_g, attn_prob_g = attn_vec_g + + # post processing + output_g = self.post_attention(g, attn_vec_g) + + if output_attentions: + attn_prob = attn_prob_h, attn_prob_g + + else: + # Multi-head attention with relative positional encoding + if mems is not None and mems.dim() > 1: + cat = torch.cat([mems, h], dim=0) + else: + cat = h + + # content heads + q_head_h = torch.einsum("ibh,hnd->ibnd", h, self.q) + k_head_h = torch.einsum("ibh,hnd->ibnd", cat, self.k) + v_head_h = torch.einsum("ibh,hnd->ibnd", cat, self.v) + + # positional heads + # type casting for fp16 support + k_head_r = torch.einsum("ibh,hnd->ibnd", r.type(self.r.dtype), self.r) + + # core attention ops + attn_vec = self.rel_attn_core( + q_head_h, + k_head_h, + v_head_h, + k_head_r, + seg_mat=seg_mat, + attn_mask=attn_mask_h, + head_mask=head_mask, + output_attentions=output_attentions, + ) + + if output_attentions: + attn_vec, attn_prob = attn_vec + + # post processing + output_h = self.post_attention(h, attn_vec) + output_g = None + + outputs = (output_h, output_g) + if output_attentions: + outputs = outputs + (attn_prob,) + return outputs + + +class XLNetFeedForward(nn.Module): + def __init__(self, config): + super().__init__() + self.layer_norm = nn.LayerNorm(config.d_model, eps=config.layer_norm_eps) + self.layer_1 = nn.Linear(config.d_model, config.d_inner) + self.layer_2 = nn.Linear(config.d_inner, config.d_model) + self.dropout = nn.Dropout(config.dropout) + if isinstance(config.ff_activation, str): + self.activation_function = ACT2FN[config.ff_activation] + else: + self.activation_function = config.ff_activation + + def forward(self, inp): + output = inp + output = self.layer_1(output) + output = self.activation_function(output) + output = self.dropout(output) + output = self.layer_2(output) + output = self.dropout(output) + output = self.layer_norm(output + inp) + return output + + +class XLNetLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.rel_attn = XLNetRelativeAttention(config) + self.ff = XLNetFeedForward(config) + self.dropout = nn.Dropout(config.dropout) + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + + def forward( + self, + output_h, + output_g, + attn_mask_h, + attn_mask_g, + r, + seg_mat, + mems=None, + target_mapping=None, + head_mask=None, + output_attentions=False, + ): + outputs = self.rel_attn( + output_h, + output_g, + attn_mask_h, + attn_mask_g, + r, + seg_mat, + mems=mems, + target_mapping=target_mapping, + head_mask=head_mask, + output_attentions=output_attentions, + ) + output_h, output_g = outputs[:2] + + if output_g is not None: + output_g = apply_chunking_to_forward( + self.ff_chunk, self.chunk_size_feed_forward, self.seq_len_dim, output_g + ) + output_h = apply_chunking_to_forward(self.ff_chunk, self.chunk_size_feed_forward, self.seq_len_dim, output_h) + + outputs = (output_h, output_g) + outputs[2:] # Add again attentions if there are there + return outputs + + def ff_chunk(self, output_x): + output_x = self.ff(output_x) + return output_x + + +class XLNetPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XLNetConfig + load_tf_weights = load_tf_weights_in_xlnet + base_model_prefix = "transformer" + + def _init_weights(self, module): + """Initialize the weights.""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + elif isinstance(module, XLNetRelativeAttention): + for param in [ + module.q, + module.k, + module.v, + module.o, + module.r, + module.r_r_bias, + module.r_s_bias, + module.r_w_bias, + module.seg_embed, + ]: + param.data.normal_(mean=0.0, std=self.config.initializer_range) + elif isinstance(module, XLNetModel): + module.mask_emb.data.normal_(mean=0.0, std=self.config.initializer_range) + + +@dataclass +class XLNetModelOutput(ModelOutput): + """ + Output type of [`XLNetModel`]. + + Args: + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, num_predict, hidden_size)`): + Sequence of hidden-states at the last layer of the model. + + `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` + corresponds to `sequence_length`. + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + last_hidden_state: torch.FloatTensor + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetLMHeadModelOutput(ModelOutput): + """ + Output type of [`XLNetLMHeadModel`]. + + Args: + loss (`torch.FloatTensor` of shape *(1,)*, *optional*, returned when `labels` is provided) + Language modeling loss (for next-token prediction). + logits (`torch.FloatTensor` of shape `(batch_size, num_predict, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + + `num_predict` corresponds to `target_mapping.shape[1]`. If `target_mapping` is `None`, then `num_predict` + corresponds to `sequence_length`. + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetForSequenceClassificationOutput(ModelOutput): + """ + Output type of [`XLNetForSequenceClassification`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `label` is provided): + Classification (or regression if config.num_labels==1) loss. + logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`): + Classification (or regression if config.num_labels==1) scores (before SoftMax). + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetForTokenClassificationOutput(ModelOutput): + """ + Output type of [`XLNetForTokenClassificationOutput`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided) : + Classification loss. + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`): + Classification scores (before SoftMax). + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetForMultipleChoiceOutput(ModelOutput): + """ + Output type of [`XLNetForMultipleChoice`]. + + Args: + loss (`torch.FloatTensor` of shape *(1,)*, *optional*, returned when `labels` is provided): + Classification loss. + logits (`torch.FloatTensor` of shape `(batch_size, num_choices)`): + *num_choices* is the second dimension of the input tensors. (see *input_ids* above). + + Classification scores (before SoftMax). + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetForQuestionAnsweringSimpleOutput(ModelOutput): + """ + Output type of [`XLNetForQuestionAnsweringSimple`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Total span extraction loss is the sum of a Cross-Entropy for the start and end positions. + start_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length,)`): + Span-start scores (before SoftMax). + end_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length,)`): + Span-end scores (before SoftMax). + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + start_logits: torch.FloatTensor = None + end_logits: torch.FloatTensor = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +@dataclass +class XLNetForQuestionAnsweringOutput(ModelOutput): + """ + Output type of [`XLNetForQuestionAnswering`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned if both `start_positions` and `end_positions` are provided): + Classification loss as the sum of start token, end token (and is_impossible if provided) classification + losses. + start_top_log_probs (`torch.FloatTensor` of shape `(batch_size, config.start_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the top config.start_n_top start token possibilities (beam-search). + start_top_index (`torch.LongTensor` of shape `(batch_size, config.start_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Indices for the top config.start_n_top start token possibilities (beam-search). + end_top_log_probs (`torch.FloatTensor` of shape `(batch_size, config.start_n_top * config.end_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the top `config.start_n_top * config.end_n_top` end token possibilities + (beam-search). + end_top_index (`torch.LongTensor` of shape `(batch_size, config.start_n_top * config.end_n_top)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Indices for the top `config.start_n_top * config.end_n_top` end token possibilities (beam-search). + cls_logits (`torch.FloatTensor` of shape `(batch_size,)`, *optional*, returned if `start_positions` or `end_positions` is not provided): + Log probabilities for the `is_impossible` label of the answers. + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states. Can be used (see `mems` input) to speed up sequential decoding. The + token ids which have their past given to this model should not be passed as `input_ids` as they have + already been computed. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer) of + shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + """ + + loss: Optional[torch.FloatTensor] = None + start_top_log_probs: Optional[torch.FloatTensor] = None + start_top_index: Optional[torch.LongTensor] = None + end_top_log_probs: Optional[torch.FloatTensor] = None + end_top_index: Optional[torch.LongTensor] = None + cls_logits: Optional[torch.FloatTensor] = None + mems: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +XLNET_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`XLNetConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XLNET_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + mems (`List[torch.FloatTensor]` of length `config.n_layers`): + Contains pre-computed hidden-states (see `mems` output below) . Can be used to speed up sequential + decoding. The token ids which have their past given to this model should not be passed as `input_ids` as + they have already been computed. + + `use_mems` has to be set to `True` to make use of `mems`. + perm_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length, sequence_length)`, *optional*): + Mask to indicate the attention pattern for each input token with values selected in `[0, 1]`: + + - if `perm_mask[k, i, j] = 0`, i attend to j in batch k; + - if `perm_mask[k, i, j] = 1`, i does not attend to j in batch k. + + If not set, each token attends to all the others (full bidirectional attention). Only used during + pretraining (to define factorization order) or for sequential decoding (generation). + target_mapping (`torch.FloatTensor` of shape `(batch_size, num_predict, sequence_length)`, *optional*): + Mask to indicate the output tokens to use. If `target_mapping[k, i, j] = 1`, the i-th predict in batch k is + on the j-th token. Only used during pretraining for partial prediction or for sequential decoding + (generation). + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + input_mask (`torch.FloatTensor` of shape `{0}`, *optional*): + Mask to avoid performing attention on padding token indices. Negative of `attention_mask`, i.e. with 0 for + real tokens and 1 for padding which is kept for compatibility with the original code base. + + Mask values selected in `[0, 1]`: + + - 1 for tokens that are **masked**, + - 0 for tokens that are **not masked**. + + You can only uses one of `input_mask` and `attention_mask`. + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare XLNet Model transformer outputting raw hidden-states without any specific head on top.", + XLNET_START_DOCSTRING, +) +class XLNetModel(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.mem_len = config.mem_len + self.reuse_len = config.reuse_len + self.d_model = config.d_model + self.same_length = config.same_length + self.attn_type = config.attn_type + self.bi_data = config.bi_data + self.clamp_len = config.clamp_len + self.n_layer = config.n_layer + + self.word_embedding = nn.Embedding(config.vocab_size, config.d_model) + self.mask_emb = nn.Parameter(torch.FloatTensor(1, 1, config.d_model)) + self.layer = nn.ModuleList([XLNetLayer(config) for _ in range(config.n_layer)]) + self.dropout = nn.Dropout(config.dropout) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.word_embedding + + def set_input_embeddings(self, new_embeddings): + self.word_embedding = new_embeddings + + def _prune_heads(self, heads_to_prune): + raise NotImplementedError + + def create_mask(self, qlen, mlen): + """ + Creates causal attention mask. Float mask where 1.0 indicates masked, 0.0 indicates not-masked. + + Args: + qlen: Sequence length + mlen: Mask length + + :: + + same_length=False: same_length=True: < qlen > < qlen > + ^ [0 0 0 0 0 1 1 1 1] [0 0 0 0 0 1 1 1 1] + [0 0 0 0 0 0 1 1 1] [1 0 0 0 0 0 1 1 1] + qlen [0 0 0 0 0 0 0 1 1] [1 1 0 0 0 0 0 1 1] + [0 0 0 0 0 0 0 0 1] [1 1 1 0 0 0 0 0 1] + v [0 0 0 0 0 0 0 0 0] [1 1 1 1 0 0 0 0 0] + + """ + attn_mask = torch.ones([qlen, qlen]) + mask_up = torch.triu(attn_mask, diagonal=1) + attn_mask_pad = torch.zeros([qlen, mlen]) + ret = torch.cat([attn_mask_pad, mask_up], dim=1) + if self.same_length: + mask_lo = torch.tril(attn_mask, diagonal=-1) + ret = torch.cat([ret[:, :qlen] + mask_lo, ret[:, qlen:]], dim=1) + + ret = ret.to(self.device) + return ret + + def cache_mem(self, curr_out, prev_mem): + # cache hidden states into memory. + if self.reuse_len is not None and self.reuse_len > 0: + curr_out = curr_out[: self.reuse_len] + + if self.mem_len is None or self.mem_len == 0: + # If `use_mems` is active but no `mem_len` is defined, the model behaves like GPT-2 at inference time + # and returns all of the past and current hidden states. + cutoff = 0 + else: + # If `use_mems` is active and `mem_len` is defined, the model returns the last `mem_len` hidden + # states. This is the preferred setting for training and long-form generation. + cutoff = -self.mem_len + if prev_mem is None: + # if `use_mems` is active and `mem_len` is defined, the model + new_mem = curr_out[cutoff:] + else: + new_mem = torch.cat([prev_mem, curr_out], dim=0)[cutoff:] + + return new_mem.detach() + + @staticmethod + def positional_embedding(pos_seq, inv_freq, bsz=None): + sinusoid_inp = torch.einsum("i,d->id", pos_seq, inv_freq) + pos_emb = torch.cat([torch.sin(sinusoid_inp), torch.cos(sinusoid_inp)], dim=-1) + pos_emb = pos_emb[:, None, :] + + if bsz is not None: + pos_emb = pos_emb.expand(-1, bsz, -1) + + return pos_emb + + def relative_positional_encoding(self, qlen, klen, bsz=None): + # create relative positional encoding. + freq_seq = torch.arange(0, self.d_model, 2.0, dtype=torch.float) + inv_freq = 1 / torch.pow(10000, (freq_seq / self.d_model)) + + if self.attn_type == "bi": + # beg, end = klen - 1, -qlen + beg, end = klen, -qlen + elif self.attn_type == "uni": + # beg, end = klen - 1, -1 + beg, end = klen, -1 + else: + raise ValueError(f"Unknown `attn_type` {self.attn_type}.") + + if self.bi_data: + fwd_pos_seq = torch.arange(beg, end, -1.0, dtype=torch.float) + bwd_pos_seq = torch.arange(-beg, -end, 1.0, dtype=torch.float) + + if self.clamp_len > 0: + fwd_pos_seq = fwd_pos_seq.clamp(-self.clamp_len, self.clamp_len) + bwd_pos_seq = bwd_pos_seq.clamp(-self.clamp_len, self.clamp_len) + + if bsz is not None: + fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz // 2) + bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq, bsz // 2) + else: + fwd_pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq) + bwd_pos_emb = self.positional_embedding(bwd_pos_seq, inv_freq) + + pos_emb = torch.cat([fwd_pos_emb, bwd_pos_emb], dim=1) + else: + fwd_pos_seq = torch.arange(beg, end, -1.0) + if self.clamp_len > 0: + fwd_pos_seq = fwd_pos_seq.clamp(-self.clamp_len, self.clamp_len) + pos_emb = self.positional_embedding(fwd_pos_seq, inv_freq, bsz) + + return pos_emb + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XLNetModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete after depreciation warning is removed + ) -> Union[Tuple, XLNetModelOutput]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if "use_cache" in kwargs: + warnings.warn( + "The `use_cache` argument is deprecated and will be removed in a future version, use `use_mems`" + " instead.", + FutureWarning, + ) + use_mems = kwargs["use_cache"] + + if self.training: + use_mems = use_mems if use_mems is not None else self.config.use_mems_train + else: + use_mems = use_mems if use_mems is not None else self.config.use_mems_eval + + # the original code for XLNet uses shapes [len, bsz] with the batch dimension at the end + # but we want a unified interface in the library with the batch size on the first dimension + # so we move here the first dimension (batch) to the end + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_ids = input_ids.transpose(0, 1).contiguous() + qlen, bsz = input_ids.shape[0], input_ids.shape[1] + elif inputs_embeds is not None: + inputs_embeds = inputs_embeds.transpose(0, 1).contiguous() + qlen, bsz = inputs_embeds.shape[0], inputs_embeds.shape[1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + token_type_ids = token_type_ids.transpose(0, 1).contiguous() if token_type_ids is not None else None + input_mask = input_mask.transpose(0, 1).contiguous() if input_mask is not None else None + attention_mask = attention_mask.transpose(0, 1).contiguous() if attention_mask is not None else None + perm_mask = perm_mask.permute(1, 2, 0).contiguous() if perm_mask is not None else None + target_mapping = target_mapping.permute(1, 2, 0).contiguous() if target_mapping is not None else None + + mlen = mems[0].shape[0] if mems is not None and mems[0] is not None else 0 + klen = mlen + qlen + + dtype_float = self.dtype + device = self.device + + # Attention mask + # causal attention mask + if self.attn_type == "uni": + attn_mask = self.create_mask(qlen, mlen) + attn_mask = attn_mask[:, :, None, None] + elif self.attn_type == "bi": + attn_mask = None + else: + raise ValueError(f"Unsupported attention type: {self.attn_type}") + + # data mask: input mask & perm mask + assert input_mask is None or attention_mask is None, "You can only use one of input_mask (uses 1 for padding) " + "or attention_mask (uses 0 for padding, added for compatibility with BERT). Please choose one." + if input_mask is None and attention_mask is not None: + input_mask = 1.0 - attention_mask + if input_mask is not None and perm_mask is not None: + data_mask = input_mask[None] + perm_mask + elif input_mask is not None and perm_mask is None: + data_mask = input_mask[None] + elif input_mask is None and perm_mask is not None: + data_mask = perm_mask + else: + data_mask = None + + if data_mask is not None: + # all mems can be attended to + if mlen > 0: + mems_mask = torch.zeros([data_mask.shape[0], mlen, bsz]).to(data_mask) + data_mask = torch.cat([mems_mask, data_mask], dim=1) + if attn_mask is None: + attn_mask = data_mask[:, :, :, None] + else: + attn_mask += data_mask[:, :, :, None] + + if attn_mask is not None: + attn_mask = (attn_mask > 0).to(dtype_float) + + if attn_mask is not None: + non_tgt_mask = -torch.eye(qlen).to(attn_mask) + if mlen > 0: + non_tgt_mask = torch.cat([torch.zeros([qlen, mlen]).to(attn_mask), non_tgt_mask], dim=-1) + non_tgt_mask = ((attn_mask + non_tgt_mask[:, :, None, None]) > 0).to(attn_mask) + else: + non_tgt_mask = None + + # Word embeddings and prepare h & g hidden states + if inputs_embeds is not None: + word_emb_k = inputs_embeds + else: + word_emb_k = self.word_embedding(input_ids) + output_h = self.dropout(word_emb_k) + if target_mapping is not None: + word_emb_q = self.mask_emb.expand(target_mapping.shape[0], bsz, -1) + # else: # We removed the inp_q input which was same as target mapping + # inp_q_ext = inp_q[:, :, None] + # word_emb_q = inp_q_ext * self.mask_emb + (1 - inp_q_ext) * word_emb_k + output_g = self.dropout(word_emb_q) + else: + output_g = None + + # Segment embedding + if token_type_ids is not None: + # Convert `token_type_ids` to one-hot `seg_mat` + if mlen > 0: + mem_pad = torch.zeros([mlen, bsz], dtype=torch.long, device=device) + cat_ids = torch.cat([mem_pad, token_type_ids], dim=0) + else: + cat_ids = token_type_ids + + # `1` indicates not in the same segment [qlen x klen x bsz] + seg_mat = (token_type_ids[:, None] != cat_ids[None, :]).long() + seg_mat = nn.functional.one_hot(seg_mat, num_classes=2).to(dtype_float) + else: + seg_mat = None + + # Positional encoding + pos_emb = self.relative_positional_encoding(qlen, klen, bsz=bsz) + pos_emb = pos_emb.to(output_h.device) + pos_emb = self.dropout(pos_emb) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] (a head_mask for each layer) + # and head_mask is converted to shape [num_hidden_layers x qlen x klen x bsz x n_head] + if head_mask is not None: + if head_mask.dim() == 1: + head_mask = head_mask.unsqueeze(0).unsqueeze(0).unsqueeze(0).unsqueeze(0) + head_mask = head_mask.expand(self.n_layer, -1, -1, -1, -1) + elif head_mask.dim() == 2: + head_mask = head_mask.unsqueeze(1).unsqueeze(1).unsqueeze(1) + head_mask = head_mask.to( + dtype=next(self.parameters()).dtype + ) # switch to float if need + fp16 compatibility + else: + head_mask = [None] * self.n_layer + + new_mems = () + if mems is None: + mems = [None] * len(self.layer) + + attentions = [] if output_attentions else None + hidden_states = [] if output_hidden_states else None + for i, layer_module in enumerate(self.layer): + if use_mems: + # cache new mems + new_mems = new_mems + (self.cache_mem(output_h, mems[i]),) + if output_hidden_states: + hidden_states.append((output_h, output_g) if output_g is not None else output_h) + + outputs = layer_module( + output_h, + output_g, + attn_mask_h=non_tgt_mask, + attn_mask_g=attn_mask, + r=pos_emb, + seg_mat=seg_mat, + mems=mems[i], + target_mapping=target_mapping, + head_mask=head_mask[i], + output_attentions=output_attentions, + ) + output_h, output_g = outputs[:2] + if output_attentions: + attentions.append(outputs[2]) + + # Add last hidden state + if output_hidden_states: + hidden_states.append((output_h, output_g) if output_g is not None else output_h) + + output = self.dropout(output_g if output_g is not None else output_h) + + # Prepare outputs, we transpose back here to shape [bsz, len, hidden_dim] (cf. beginning of forward() method) + output = output.permute(1, 0, 2).contiguous() + + if not use_mems: + new_mems = None + + if output_hidden_states: + if output_g is not None: + hidden_states = tuple(h.permute(1, 0, 2).contiguous() for hs in hidden_states for h in hs) + else: + hidden_states = tuple(hs.permute(1, 0, 2).contiguous() for hs in hidden_states) + + if output_attentions: + if target_mapping is not None: + # when target_mapping is provided, there are 2-tuple of attentions + attentions = tuple( + tuple(att_stream.permute(2, 3, 0, 1).contiguous() for att_stream in t) for t in attentions + ) + else: + attentions = tuple(t.permute(2, 3, 0, 1).contiguous() for t in attentions) + + if not return_dict: + return tuple(v for v in [output, new_mems, hidden_states, attentions] if v is not None) + + return XLNetModelOutput( + last_hidden_state=output, mems=new_mems, hidden_states=hidden_states, attentions=attentions + ) + + +@add_start_docstrings( + """ + XLNet Model with a language modeling head on top (linear layer with weights tied to the input embeddings). + """, + XLNET_START_DOCSTRING, +) +class XLNetLMHeadModel(XLNetPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"lm_loss.weight"] + + def __init__(self, config): + super().__init__(config) + self.attn_type = config.attn_type + self.same_length = config.same_length + + self.transformer = XLNetModel(config) + self.lm_loss = nn.Linear(config.d_model, config.vocab_size, bias=True) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.lm_loss + + def set_output_embeddings(self, new_embeddings): + self.lm_loss = new_embeddings + + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, use_mems=None, **kwargs): + # Add dummy token at the end (no attention on this one) + + effective_batch_size = input_ids.shape[0] + dummy_token = torch.zeros((effective_batch_size, 1), dtype=torch.long, device=input_ids.device) + + # At every pass, the attention values for the new token and the two last generated tokens + # are computed, the rest is reloaded from the `past` cache. A purely auto-regressive model would have + # offset = 1; offset = 2 seems to have slightly better computation. + offset = 2 + + if past_key_values: + input_ids = torch.cat([input_ids[:, -offset:], dummy_token], dim=1) + else: + input_ids = torch.cat([input_ids, dummy_token], dim=1) + + # Build permutation mask so that previous tokens don't see last token + sequence_length = input_ids.shape[1] + perm_mask = torch.zeros( + (effective_batch_size, sequence_length, sequence_length), dtype=torch.float, device=input_ids.device + ) + perm_mask[:, :, -1] = 1.0 + + # We'll only predict the last token + target_mapping = torch.zeros( + (effective_batch_size, 1, sequence_length), dtype=torch.float, device=input_ids.device + ) + target_mapping[:, 0, -1] = 1.0 + + inputs = { + "input_ids": input_ids, + "perm_mask": perm_mask, + "target_mapping": target_mapping, + "use_mems": use_mems, + } + + # if past is defined in model kwargs then use it for faster decoding + if past_key_values: + inputs["mems"] = tuple(layer_past[:-offset, :, :] for layer_past in past_key_values) + + return inputs + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=XLNetLMHeadModelOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetLMHeadModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, num_predict)`, *optional*): + Labels for masked language modeling. `num_predict` corresponds to `target_mapping.shape[1]`. If + `target_mapping` is `None`, then `num_predict` corresponds to `sequence_length`. + + The labels should correspond to the masked input words that should be predicted and depends on + `target_mapping`. Note in order to perform standard auto-regressive language modeling a ** token has + to be added to the `input_ids` (see the `prepare_inputs_for_generation` function and examples below) + + Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100` are ignored, the loss + is only computed for labels in `[0, ..., config.vocab_size]` + + Return: + + Examples: + + ```python + >>> from transformers import AutoTokenizer, XLNetLMHeadModel + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("xlnet-large-cased") + >>> model = XLNetLMHeadModel.from_pretrained("xlnet-large-cased") + + >>> # We show how to setup inputs to predict a next token using a bi-directional context. + >>> input_ids = torch.tensor( + ... tokenizer.encode("Hello, my dog is very ", add_special_tokens=False) + ... ).unsqueeze( + ... 0 + ... ) # We will predict the masked token + >>> perm_mask = torch.zeros((1, input_ids.shape[1], input_ids.shape[1]), dtype=torch.float) + >>> perm_mask[:, :, -1] = 1.0 # Previous tokens don't see last token + >>> target_mapping = torch.zeros( + ... (1, 1, input_ids.shape[1]), dtype=torch.float + ... ) # Shape [1, 1, seq_length] => let's predict one token + >>> target_mapping[ + ... 0, 0, -1 + ... ] = 1.0 # Our first (and only) prediction will be the last token of the sequence (the masked token) + + >>> outputs = model(input_ids, perm_mask=perm_mask, target_mapping=target_mapping) + >>> next_token_logits = outputs[ + ... 0 + ... ] # Output has shape [target_mapping.size(0), target_mapping.size(1), config.vocab_size] + + >>> # The same way can the XLNetLMHeadModel be used to be trained by standard auto-regressive language modeling. + >>> input_ids = torch.tensor( + ... tokenizer.encode("Hello, my dog is very ", add_special_tokens=False) + ... ).unsqueeze( + ... 0 + ... ) # We will predict the masked token + >>> labels = torch.tensor(tokenizer.encode("cute", add_special_tokens=False)).unsqueeze(0) + >>> assert labels.shape[0] == 1, "only one word will be predicted" + >>> perm_mask = torch.zeros((1, input_ids.shape[1], input_ids.shape[1]), dtype=torch.float) + >>> perm_mask[ + ... :, :, -1 + ... ] = 1.0 # Previous tokens don't see last token as is done in standard auto-regressive lm training + >>> target_mapping = torch.zeros( + ... (1, 1, input_ids.shape[1]), dtype=torch.float + ... ) # Shape [1, 1, seq_length] => let's predict one token + >>> target_mapping[ + ... 0, 0, -1 + ... ] = 1.0 # Our first (and only) prediction will be the last token of the sequence (the masked token) + + >>> outputs = model(input_ids, perm_mask=perm_mask, target_mapping=target_mapping, labels=labels) + >>> loss = outputs.loss + >>> next_token_logits = ( + ... outputs.logits + ... ) # Logits have shape [target_mapping.size(0), target_mapping.size(1), config.vocab_size] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + + logits = self.lm_loss(transformer_outputs[0]) + + loss = None + if labels is not None: + # Flatten the tokens + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, logits.size(-1)), labels.view(-1)) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return XLNetLMHeadModelOutput( + loss=loss, + logits=logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + @staticmethod + def _reorder_cache(mems: List[torch.Tensor], beam_idx: torch.Tensor) -> List[torch.Tensor]: + """ + This function is used to re-order the `mems` cache if [`~PreTrainedModel.beam_search`] or + [`~PreTrainedModel.beam_sample`] is called. This is required to match `mems` with the correct beam_idx at every + generation step. + """ + return [layer_past.index_select(1, beam_idx.to(layer_past.device)) for layer_past in mems] + + +@add_start_docstrings( + """ + XLNet Model with a sequence classification/regression head on top (a linear layer on top of the pooled output) e.g. + for GLUE tasks. + """, + XLNET_START_DOCSTRING, +) +class XLNetForSequenceClassification(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.transformer = XLNetModel(config) + self.sequence_summary = SequenceSummary(config) + self.logits_proj = nn.Linear(config.d_model, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XLNetForSequenceClassificationOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetForSequenceClassificationOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + output = transformer_outputs[0] + + output = self.sequence_summary(output) + logits = self.logits_proj(output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return XLNetForSequenceClassificationOutput( + loss=loss, + logits=logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLNet Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + XLNET_START_DOCSTRING, +) +class XLNetForTokenClassification(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.transformer = XLNetModel(config) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XLNetForTokenClassificationOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetForTokenClassificationOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., num_choices]` + where *num_choices* is the size of the second dimension of the input tensors. (see *input_ids* above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return XLNetForTokenClassificationOutput( + loss=loss, + logits=logits, + mems=outputs.mems, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLNet Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RACE/SWAG tasks. + """, + XLNET_START_DOCSTRING, +) +class XLNetForMultipleChoice(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.transformer = XLNetModel(config) + self.sequence_summary = SequenceSummary(config) + self.logits_proj = nn.Linear(config.d_model, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XLNetForMultipleChoiceOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetForMultipleChoiceOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_input_mask = input_mask.view(-1, input_mask.size(-1)) if input_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + transformer_outputs = self.transformer( + flat_input_ids, + token_type_ids=flat_token_type_ids, + input_mask=flat_input_mask, + attention_mask=flat_attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + + output = transformer_outputs[0] + + output = self.sequence_summary(output) + logits = self.logits_proj(output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels.view(-1)) + + if not return_dict: + output = (reshaped_logits,) + transformer_outputs[1:] + return ((loss,) + output) if loss is not None else output + + return XLNetForMultipleChoiceOutput( + loss=loss, + logits=reshaped_logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLNet Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLNET_START_DOCSTRING, +) +class XLNetForQuestionAnsweringSimple(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.transformer = XLNetModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=XLNetForQuestionAnsweringSimpleOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetForQuestionAnsweringSimpleOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return XLNetForQuestionAnsweringSimpleOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + mems=outputs.mems, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + XLNet Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XLNET_START_DOCSTRING, +) +class XLNetForQuestionAnswering(XLNetPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.start_n_top = config.start_n_top + self.end_n_top = config.end_n_top + + self.transformer = XLNetModel(config) + self.start_logits = PoolerStartLogits(config) + self.end_logits = PoolerEndLogits(config) + self.answer_class = PoolerAnswerClass(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XLNET_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @replace_return_docstrings(output_type=XLNetForQuestionAnsweringOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + mems: Optional[torch.Tensor] = None, + perm_mask: Optional[torch.Tensor] = None, + target_mapping: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + input_mask: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + is_impossible: Optional[torch.Tensor] = None, + cls_index: Optional[torch.Tensor] = None, + p_mask: Optional[torch.Tensor] = None, + use_mems: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + **kwargs, # delete when `use_cache` is removed in XLNetModel + ) -> Union[Tuple, XLNetForQuestionAnsweringOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + is_impossible (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels whether a question has an answer or no answer (SQuAD 2.0) + cls_index (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the classification token to use as input for computing plausibility of the + answer. + p_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Optional mask of tokens which can't be in answers (e.g. [CLS], [PAD], ...). 1.0 means token should be + masked. 0.0 mean token is not masked. + + Returns: + + Example: + + ```python + >>> from transformers import AutoTokenizer, XLNetForQuestionAnswering + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("xlnet-base-cased") + >>> model = XLNetForQuestionAnswering.from_pretrained("xlnet-base-cased") + + >>> input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze( + ... 0 + ... ) # Batch size 1 + >>> start_positions = torch.tensor([1]) + >>> end_positions = torch.tensor([3]) + >>> outputs = model(input_ids, start_positions=start_positions, end_positions=end_positions) + + >>> loss = outputs.loss + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + transformer_outputs = self.transformer( + input_ids, + attention_mask=attention_mask, + mems=mems, + perm_mask=perm_mask, + target_mapping=target_mapping, + token_type_ids=token_type_ids, + input_mask=input_mask, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + use_mems=use_mems, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + hidden_states = transformer_outputs[0] + start_logits = self.start_logits(hidden_states, p_mask=p_mask) + + outputs = transformer_outputs[1:] # Keep mems, hidden states, attentions if there are in it + + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, let's remove the dimension added by batch splitting + for x in (start_positions, end_positions, cls_index, is_impossible): + if x is not None and x.dim() > 1: + x.squeeze_(-1) + + # during training, compute the end logits based on the ground truth of the start position + end_logits = self.end_logits(hidden_states, start_positions=start_positions, p_mask=p_mask) + + loss_fct = CrossEntropyLoss() + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if cls_index is not None and is_impossible is not None: + # Predict answerability from the representation of CLS and START + cls_logits = self.answer_class(hidden_states, start_positions=start_positions, cls_index=cls_index) + loss_fct_cls = nn.BCEWithLogitsLoss() + cls_loss = loss_fct_cls(cls_logits, is_impossible) + + # note(zhiliny): by default multiply the loss by 0.5 so that the scale is comparable to start_loss and end_loss + total_loss += cls_loss * 0.5 + + if not return_dict: + return (total_loss,) + transformer_outputs[1:] + else: + return XLNetForQuestionAnsweringOutput( + loss=total_loss, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) + + else: + # during inference, compute the end logits based on beam search + bsz, slen, hsz = hidden_states.size() + start_log_probs = nn.functional.softmax(start_logits, dim=-1) # shape (bsz, slen) + + start_top_log_probs, start_top_index = torch.topk( + start_log_probs, self.start_n_top, dim=-1 + ) # shape (bsz, start_n_top) + start_top_index_exp = start_top_index.unsqueeze(-1).expand(-1, -1, hsz) # shape (bsz, start_n_top, hsz) + start_states = torch.gather(hidden_states, -2, start_top_index_exp) # shape (bsz, start_n_top, hsz) + start_states = start_states.unsqueeze(1).expand(-1, slen, -1, -1) # shape (bsz, slen, start_n_top, hsz) + + hidden_states_expanded = hidden_states.unsqueeze(2).expand_as( + start_states + ) # shape (bsz, slen, start_n_top, hsz) + p_mask = p_mask.unsqueeze(-1) if p_mask is not None else None + end_logits = self.end_logits(hidden_states_expanded, start_states=start_states, p_mask=p_mask) + end_log_probs = nn.functional.softmax(end_logits, dim=1) # shape (bsz, slen, start_n_top) + + end_top_log_probs, end_top_index = torch.topk( + end_log_probs, self.end_n_top, dim=1 + ) # shape (bsz, end_n_top, start_n_top) + end_top_log_probs = end_top_log_probs.view(-1, self.start_n_top * self.end_n_top) + end_top_index = end_top_index.view(-1, self.start_n_top * self.end_n_top) + + start_states = torch.einsum( + "blh,bl->bh", hidden_states, start_log_probs + ) # get the representation of START as weighted sum of hidden states + cls_logits = self.answer_class( + hidden_states, start_states=start_states, cls_index=cls_index + ) # Shape (batch size,): one single `cls_logits` for each sample + + if not return_dict: + outputs = (start_top_log_probs, start_top_index, end_top_log_probs, end_top_index, cls_logits) + return outputs + transformer_outputs[1:] + else: + return XLNetForQuestionAnsweringOutput( + start_top_log_probs=start_top_log_probs, + start_top_index=start_top_index, + end_top_log_probs=end_top_log_probs, + end_top_index=end_top_index, + cls_logits=cls_logits, + mems=transformer_outputs.mems, + hidden_states=transformer_outputs.hidden_states, + attentions=transformer_outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet.py new file mode 100644 index 0000000000000000000000000000000000000000..ec72df8c8b71c437c4631683e69c07664c854f28 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet.py @@ -0,0 +1,396 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization classes for XLNet model.""" + + +import os +import unicodedata +from shutil import copyfile +from typing import Any, Dict, List, Optional, Tuple + +import sentencepiece as spm + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...utils import SPIECE_UNDERLINE, logging + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "spiece.model"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "xlnet-base-cased": "https://huggingface.co/xlnet-base-cased/resolve/main/spiece.model", + "xlnet-large-cased": "https://huggingface.co/xlnet-large-cased/resolve/main/spiece.model", + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "xlnet-base-cased": None, + "xlnet-large-cased": None, +} + +# Segments (not really needed) +SEG_ID_A = 0 +SEG_ID_B = 1 +SEG_ID_CLS = 2 +SEG_ID_SEP = 3 +SEG_ID_PAD = 4 + + +class XLNetTokenizer(PreTrainedTokenizer): + """ + Construct an XLNet tokenizer. Based on [SentencePiece](https://github.com/google/sentencepiece). + + This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to + this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a .spm extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether to lowercase the input when tokenizing. + remove_space (`bool`, *optional*, defaults to `True`): + Whether to strip the text when tokenizing (removing excess spaces before and after the string). + keep_accents (`bool`, *optional*, defaults to `False`): + Whether to keep accents when tokenizing. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["", ""]`): + Additional special tokens used by the tokenizer. + sp_model_kwargs (`dict`, *optional*): + Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for + SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things, + to set: + + - `enable_sampling`: Enable subword regularization. + - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout. + + - `nbest_size = {0,1}`: No sampling is performed. + - `nbest_size > 1`: samples from the nbest_size results. + - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice) + using forward-filtering-and-backward-sampling algorithm. + + - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for + BPE-dropout. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + padding_side = "left" + + def __init__( + self, + vocab_file, + do_lower_case=False, + remove_space=True, + keep_accents=False, + bos_token="", + eos_token="", + unk_token="", + sep_token="", + pad_token="", + cls_token="", + mask_token="", + additional_special_tokens=["", ""], + sp_model_kwargs: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> None: + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs + + super().__init__( + do_lower_case=do_lower_case, + remove_space=remove_space, + keep_accents=keep_accents, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + additional_special_tokens=additional_special_tokens, + sp_model_kwargs=self.sp_model_kwargs, + **kwargs, + ) + + self._pad_token_type_id = 3 + + self.do_lower_case = do_lower_case + self.remove_space = remove_space + self.keep_accents = keep_accents + self.vocab_file = vocab_file + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(vocab_file) + + @property + def vocab_size(self): + return len(self.sp_model) + + def get_vocab(self): + vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)} + vocab.update(self.added_tokens_encoder) + return vocab + + def __getstate__(self): + state = self.__dict__.copy() + state["sp_model"] = None + return state + + def __setstate__(self, d): + self.__dict__ = d + + # for backward compatibility + if not hasattr(self, "sp_model_kwargs"): + self.sp_model_kwargs = {} + + self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs) + self.sp_model.Load(self.vocab_file) + + def preprocess_text(self, inputs): + if self.remove_space: + outputs = " ".join(inputs.strip().split()) + else: + outputs = inputs + outputs = outputs.replace("``", '"').replace("''", '"') + + if not self.keep_accents: + outputs = unicodedata.normalize("NFKD", outputs) + outputs = "".join([c for c in outputs if not unicodedata.combining(c)]) + if self.do_lower_case: + outputs = outputs.lower() + + return outputs + + def _tokenize(self, text: str) -> List[str]: + """Tokenize a string.""" + text = self.preprocess_text(text) + pieces = self.sp_model.encode(text, out_type=str) + new_pieces = [] + for piece in pieces: + if len(piece) > 1 and piece[-1] == str(",") and piece[-2].isdigit(): + cur_pieces = self.sp_model.EncodeAsPieces(piece[:-1].replace(SPIECE_UNDERLINE, "")) + if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE: + if len(cur_pieces[0]) == 1: + cur_pieces = cur_pieces[1:] + else: + cur_pieces[0] = cur_pieces[0][1:] + cur_pieces.append(piece[-1]) + new_pieces.extend(cur_pieces) + else: + new_pieces.append(piece) + + return new_pieces + + def _convert_token_to_id(self, token): + """Converts a token (str) in an id using the vocab.""" + return self.sp_model.PieceToId(token) + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + return self.sp_model.IdToPiece(index) + + def convert_tokens_to_string(self, tokens): + """Converts a sequence of tokens (strings for sub-words) in a single string.""" + out_string = "".join(tokens).replace(SPIECE_UNDERLINE, " ").strip() + return out_string + + def _decode( + self, + token_ids: List[int], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + spaces_between_special_tokens: bool = True, + **kwargs, + ) -> str: + self._decode_use_source_tokenizer = kwargs.pop("use_source_tokenizer", False) + + filtered_tokens = self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens) + + # To avoid mixing byte-level and unicode for byte-level BPT + # we need to build string separately for added tokens and byte-level tokens + # cf. https://github.com/huggingface/transformers/issues/1133 + sub_texts = [] + current_sub_text = [] + for token in filtered_tokens: + if skip_special_tokens and token in self.all_special_ids: + continue + if token in self.added_tokens_encoder: + if current_sub_text: + sub_texts.append(self.convert_tokens_to_string(current_sub_text)) + current_sub_text = [] + sub_texts.append(token) + else: + current_sub_text.append(token) + if current_sub_text: + sub_texts.append(self.convert_tokens_to_string(current_sub_text)) + + # Mimic the behavior of the Rust tokenizer: + # By default, there are no spaces between special tokens + text = "".join(sub_texts) + + clean_up_tokenization_spaces = ( + clean_up_tokenization_spaces + if clean_up_tokenization_spaces is not None + else self.clean_up_tokenization_spaces + ) + if clean_up_tokenization_spaces: + clean_text = self.clean_up_tokenization(text) + return clean_text + else: + return text + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLNet sequence has the following format: + + - single sequence: `X ` + - pair of sequences: `A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return token_ids_0 + sep + cls + return token_ids_0 + sep + token_ids_1 + sep + cls + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is not None: + return ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1, 1] + return ([0] * len(token_ids_0)) + [1, 1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. An XLNet + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls_segment_id = [2] + + if token_ids_1 is None: + return len(token_ids_0 + sep) * [0] + cls_segment_id + return len(token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + cls_segment_id + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file) and os.path.isfile(self.vocab_file): + copyfile(self.vocab_file, out_vocab_file) + elif not os.path.isfile(self.vocab_file): + with open(out_vocab_file, "wb") as fi: + content_spiece_model = self.sp_model.serialized_model_proto() + fi.write(content_spiece_model) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..3f6ff200a84ac31cb27e39cdfbf7e61b3ae29db5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xlnet/tokenization_xlnet_fast.py @@ -0,0 +1,246 @@ +# coding=utf-8 +# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Tokenization classes for XLNet model.""" + + +import os +from shutil import copyfile +from typing import List, Optional, Tuple + +from ...tokenization_utils import AddedToken +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import is_sentencepiece_available, logging + + +if is_sentencepiece_available(): + from .tokenization_xlnet import XLNetTokenizer +else: + XLNetTokenizer = None + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "spiece.model", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "xlnet-base-cased": "https://huggingface.co/xlnet-base-cased/resolve/main/spiece.model", + "xlnet-large-cased": "https://huggingface.co/xlnet-large-cased/resolve/main/spiece.model", + }, + "tokenizer_file": { + "xlnet-base-cased": "https://huggingface.co/xlnet-base-cased/resolve/main/tokenizer.json", + "xlnet-large-cased": "https://huggingface.co/xlnet-large-cased/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "xlnet-base-cased": None, + "xlnet-large-cased": None, +} + +SPIECE_UNDERLINE = "▁" + +# Segments (not really needed) +SEG_ID_A = 0 +SEG_ID_B = 1 +SEG_ID_CLS = 2 +SEG_ID_SEP = 3 +SEG_ID_PAD = 4 + + +class XLNetTokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" XLNet tokenizer (backed by HuggingFace's *tokenizers* library). Based on + [Unigram](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=unigram#models). + + This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should + refer to this superclass for more information regarding those methods. + + Args: + vocab_file (`str`): + [SentencePiece](https://github.com/google/sentencepiece) file (generally has a .spm extension) that + contains the vocabulary necessary to instantiate a tokenizer. + do_lower_case (`bool`, *optional*, defaults to `True`): + Whether to lowercase the input when tokenizing. + remove_space (`bool`, *optional*, defaults to `True`): + Whether to strip the text when tokenizing (removing excess spaces before and after the string). + keep_accents (`bool`, *optional*, defaults to `False`): + Whether to keep accents when tokenizing. + bos_token (`str`, *optional*, defaults to `""`): + The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token. + + + + When building a sequence using special tokens, this is not the token that is used for the beginning of + sequence. The token used is the `cls_token`. + + + + eos_token (`str`, *optional*, defaults to `""`): + The end of sequence token. + + + + When building a sequence using special tokens, this is not the token that is used for the end of sequence. + The token used is the `sep_token`. + + + + unk_token (`str`, *optional*, defaults to `""`): + The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this + token instead. + sep_token (`str`, *optional*, defaults to `""`): + The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for + sequence classification or for a text and a question for question answering. It is also used as the last + token of a sequence built with special tokens. + pad_token (`str`, *optional*, defaults to `""`): + The token used for padding, for example when batching sequences of different lengths. + cls_token (`str`, *optional*, defaults to `""`): + The classifier token which is used when doing sequence classification (classification of the whole sequence + instead of per-token classification). It is the first token of the sequence when built with special tokens. + mask_token (`str`, *optional*, defaults to `""`): + The token used for masking values. This is the token used when training this model with masked language + modeling. This is the token which the model will try to predict. + additional_special_tokens (`List[str]`, *optional*, defaults to `["", ""]`): + Additional special tokens used by the tokenizer. + + Attributes: + sp_model (`SentencePieceProcessor`): + The *SentencePiece* processor that is used for every conversion (string, tokens and IDs). + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + padding_side = "left" + slow_tokenizer_class = XLNetTokenizer + + def __init__( + self, + vocab_file=None, + tokenizer_file=None, + do_lower_case=False, + remove_space=True, + keep_accents=False, + bos_token="", + eos_token="", + unk_token="", + sep_token="", + pad_token="", + cls_token="", + mask_token="", + additional_special_tokens=["", ""], + **kwargs, + ): + # Mask token behave like a normal word, i.e. include the space before it + mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token + + super().__init__( + vocab_file=vocab_file, + tokenizer_file=tokenizer_file, + do_lower_case=do_lower_case, + remove_space=remove_space, + keep_accents=keep_accents, + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + sep_token=sep_token, + pad_token=pad_token, + cls_token=cls_token, + mask_token=mask_token, + additional_special_tokens=additional_special_tokens, + **kwargs, + ) + + self._pad_token_type_id = 3 + self.do_lower_case = do_lower_case + self.remove_space = remove_space + self.keep_accents = keep_accents + self.vocab_file = vocab_file + self.can_save_slow_tokenizer = False if not self.vocab_file else True + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. An XLNet sequence has the following format: + + - single sequence: `X ` + - pair of sequences: `A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + if token_ids_1 is None: + return token_ids_0 + sep + cls + return token_ids_0 + sep + token_ids_1 + sep + cls + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. An XLNet + sequence pair mask has the following format: + + ``` + 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 + | first sequence | second sequence | + ``` + + If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s). + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [token type IDs](../glossary#token-type-ids) according to the given sequence(s). + """ + sep = [self.sep_token_id] + cls_segment_id = [2] + + if token_ids_1 is None: + return len(token_ids_0 + sep) * [0] + cls_segment_id + return len(token_ids_0 + sep) * [0] + len(token_ids_1 + sep) * [1] + cls_segment_id + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + if not self.can_save_slow_tokenizer: + raise ValueError( + "Your fast tokenizer does not have the necessary information to save the vocabulary for a slow " + "tokenizer." + ) + + if not os.path.isdir(save_directory): + logger.error(f"Vocabulary path ({save_directory}) should be a directory") + return + out_vocab_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"] + ) + + if os.path.abspath(self.vocab_file) != os.path.abspath(out_vocab_file): + copyfile(self.vocab_file, out_vocab_file) + + return (out_vocab_file,) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3cb6f195bd4585412d72b1db6549caa6e969edf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/__init__.py @@ -0,0 +1,74 @@ +# flake8: noqa +# There's no way to ignore "F401 '...' imported but unused" warnings in this +# module, but to preserve other warnings. So, don't check this module at all. + +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available + + +_import_structure = { + "configuration_xmod": [ + "XMOD_PRETRAINED_CONFIG_ARCHIVE_MAP", + "XmodConfig", + "XmodOnnxConfig", + ], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_xmod"] = [ + "XMOD_PRETRAINED_MODEL_ARCHIVE_LIST", + "XmodForCausalLM", + "XmodForMaskedLM", + "XmodForMultipleChoice", + "XmodForQuestionAnswering", + "XmodForSequenceClassification", + "XmodForTokenClassification", + "XmodModel", + "XmodPreTrainedModel", + ] + +if TYPE_CHECKING: + from .configuration_xmod import XMOD_PRETRAINED_CONFIG_ARCHIVE_MAP, XmodConfig, XmodOnnxConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_xmod import ( + XMOD_PRETRAINED_MODEL_ARCHIVE_LIST, + XmodForCausalLM, + XmodForMaskedLM, + XmodForMultipleChoice, + XmodForQuestionAnswering, + XmodForSequenceClassification, + XmodForTokenClassification, + XmodModel, + XmodPreTrainedModel, + ) + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/configuration_xmod.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/configuration_xmod.py new file mode 100644 index 0000000000000000000000000000000000000000..012b7446c4c4c7b28feabd5d2ef31abacb2a6044 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/configuration_xmod.py @@ -0,0 +1,192 @@ +# coding=utf-8 +# Copyright 2023 The Meta AI Team Authors and The HuggingFace Inc. team. +# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" X-MOD configuration""" +from collections import OrderedDict +from typing import Mapping + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +XMOD_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "facebook/xmod-base": "https://huggingface.co/facebook/xmod-base/resolve/main/config.json", + "facebook/xmod-large-prenorm": "https://huggingface.co/facebook/xmod-large-prenorm/resolve/main/config.json", + "facebook/xmod-base-13-125k": "https://huggingface.co/facebook/xmod-base-13-125k/resolve/main/config.json", + "facebook/xmod-base-30-125k": "https://huggingface.co/facebook/xmod-base-30-125k/resolve/main/config.json", + "facebook/xmod-base-30-195k": "https://huggingface.co/facebook/xmod-base-30-195k/resolve/main/config.json", + "facebook/xmod-base-60-125k": "https://huggingface.co/facebook/xmod-base-60-125k/resolve/main/config.json", + "facebook/xmod-base-60-265k": "https://huggingface.co/facebook/xmod-base-60-265k/resolve/main/config.json", + "facebook/xmod-base-75-125k": "https://huggingface.co/facebook/xmod-base-75-125k/resolve/main/config.json", + "facebook/xmod-base-75-269k": "https://huggingface.co/facebook/xmod-base-75-269k/resolve/main/config.json", +} + + +class XmodConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`XmodModel`]. It is used to instantiate an X-MOD + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the + [facebook/xmod-base](https://huggingface.co/facebook/xmod-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the X-MOD model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`XmodModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `Callable`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"silu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`XmodModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. For + positional embeddings use `"absolute"`. For more information on `"relative_key"`, please refer to + [Self-Attention with Relative Position Representations (Shaw et al.)](https://arxiv.org/abs/1803.02155). + For more information on `"relative_key_query"`, please refer to *Method 4* in [Improve Transformer Models + with Better Relative Position Embeddings (Huang et al.)](https://arxiv.org/abs/2009.13658). + is_decoder (`bool`, *optional*, defaults to `False`): + Whether the model is used as a decoder or not. If `False`, the model is used as an encoder. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + classifier_dropout (`float`, *optional*): + The dropout ratio for the classification head. + pre_norm (`bool`, *optional*, defaults to `False`): + Whether to apply layer normalization before each block. + adapter_reduction_factor (`int` or `float`, *optional*, defaults to 2): + The factor by which the dimensionality of the adapter is reduced relative to `hidden_size`. + adapter_layer_norm (`bool`, *optional*, defaults to `False`): + Whether to apply a new layer normalization before the adapter modules (shared across all adapters). + adapter_reuse_layer_norm (`bool`, *optional*, defaults to `True`): + Whether to reuse the second layer normalization and apply it before the adapter modules as well. + ln_before_adapter (`bool`, *optional*, defaults to `True`): + Whether to apply the layer normalization before the residual connection around the adapter module. + languages (`Iterable[str]`, *optional*, defaults to `["en_XX"]`): + An iterable of language codes for which adapter modules should be initialized. + default_language (`str`, *optional*): + Language code of a default language. It will be assumed that the input is in this language if no language + codes are explicitly passed to the forward method. + + Examples: + + ```python + >>> from transformers import XmodConfig, XmodModel + + >>> # Initializing an X-MOD facebook/xmod-base style configuration + >>> configuration = XmodConfig() + + >>> # Initializing a model (with random weights) from the facebook/xmod-base style configuration + >>> model = XmodModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "xmod" + + def __init__( + self, + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + position_embedding_type="absolute", + use_cache=True, + classifier_dropout=None, + pre_norm=False, + adapter_reduction_factor=2, + adapter_layer_norm=False, + adapter_reuse_layer_norm=True, + ln_before_adapter=True, + languages=("en_XX",), + default_language=None, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_act = hidden_act + self.intermediate_size = intermediate_size + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_cache = use_cache + self.classifier_dropout = classifier_dropout + self.pre_norm = pre_norm + self.adapter_reduction_factor = adapter_reduction_factor + self.adapter_layer_norm = adapter_layer_norm + self.adapter_reuse_layer_norm = adapter_reuse_layer_norm + self.ln_before_adapter = ln_before_adapter + self.languages = list(languages) + self.default_language = default_language + + +# Copied from transformers.models.roberta.configuration_roberta.RobertaOnnxConfig with Roberta->Xmod +class XmodOnnxConfig(OnnxConfig): + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + if self.task == "multiple-choice": + dynamic_axis = {0: "batch", 1: "choice", 2: "sequence"} + else: + dynamic_axis = {0: "batch", 1: "sequence"} + return OrderedDict( + [ + ("input_ids", dynamic_axis), + ("attention_mask", dynamic_axis), + ] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/convert_xmod_original_pytorch_checkpoint_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/convert_xmod_original_pytorch_checkpoint_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..6352b713005518a3bba0af6c32aa425a6c5e8e78 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/convert_xmod_original_pytorch_checkpoint_to_pytorch.py @@ -0,0 +1,212 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert X-MOD checkpoint.""" + +import argparse +from pathlib import Path + +import fairseq +import torch +from fairseq.models.xmod import XMODModel as FairseqXmodModel +from packaging import version + +from transformers import XmodConfig, XmodForMaskedLM, XmodForSequenceClassification +from transformers.utils import logging + + +if version.parse(fairseq.__version__) < version.parse("0.12.2"): + raise Exception("requires fairseq >= 0.12.2") +if version.parse(fairseq.__version__) > version.parse("2"): + raise Exception("requires fairseq < v2") + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + +SAMPLE_TEXT = "Hello, World!" +SAMPLE_LANGUAGE = "en_XX" + + +def convert_xmod_checkpoint_to_pytorch( + xmod_checkpoint_path: str, pytorch_dump_folder_path: str, classification_head: bool +): + data_dir = Path("data_bin") + xmod = FairseqXmodModel.from_pretrained( + model_name_or_path=str(Path(xmod_checkpoint_path).parent), + checkpoint_file=Path(xmod_checkpoint_path).name, + _name="xmod_base", + arch="xmod_base", + task="multilingual_masked_lm", + data_name_or_path=str(data_dir), + bpe="sentencepiece", + sentencepiece_model=str(Path(xmod_checkpoint_path).parent / "sentencepiece.bpe.model"), + src_dict=str(data_dir / "dict.txt"), + ) + xmod.eval() # disable dropout + print(xmod) + + xmod_sent_encoder = xmod.model.encoder.sentence_encoder + config = XmodConfig( + vocab_size=xmod_sent_encoder.embed_tokens.num_embeddings, + hidden_size=xmod.cfg.model.encoder_embed_dim, + num_hidden_layers=xmod.cfg.model.encoder_layers, + num_attention_heads=xmod.cfg.model.encoder_attention_heads, + intermediate_size=xmod.cfg.model.encoder_ffn_embed_dim, + max_position_embeddings=514, + type_vocab_size=1, + layer_norm_eps=1e-5, # PyTorch default used in fairseq + pre_norm=xmod.cfg.model.encoder_normalize_before, + adapter_reduction_factor=getattr(xmod.cfg.model, "bottleneck", 2), + adapter_layer_norm=xmod.cfg.model.adapter_layer_norm, + adapter_reuse_layer_norm=xmod.cfg.model.adapter_reuse_layer_norm, + ln_before_adapter=xmod.cfg.model.ln_before_adapter, + languages=xmod.cfg.model.languages, + ) + if classification_head: + config.num_labels = xmod.model.classification_heads["mnli"].out_proj.weight.shape[0] + + print("Our X-MOD config:", config) + + model = XmodForSequenceClassification(config) if classification_head else XmodForMaskedLM(config) + model.eval() + + # Now let's copy all the weights. + # Embeddings + model.roberta.embeddings.word_embeddings.weight = xmod_sent_encoder.embed_tokens.weight + model.roberta.embeddings.position_embeddings.weight = xmod_sent_encoder.embed_positions.weight + model.roberta.embeddings.token_type_embeddings.weight.data = torch.zeros_like( + model.roberta.embeddings.token_type_embeddings.weight + ) # just zero them out b/c xmod doesn't use them. + + model.roberta.embeddings.LayerNorm.weight = xmod_sent_encoder.layernorm_embedding.weight + model.roberta.embeddings.LayerNorm.bias = xmod_sent_encoder.layernorm_embedding.bias + + for i in range(config.num_hidden_layers): + # Encoder: start of layer + layer = model.roberta.encoder.layer[i] + xmod_layer = xmod_sent_encoder.layers[i] + + # self attention + self_attn = layer.attention.self + if not ( + xmod_layer.self_attn.k_proj.weight.data.shape + == xmod_layer.self_attn.q_proj.weight.data.shape + == xmod_layer.self_attn.v_proj.weight.data.shape + == torch.Size((config.hidden_size, config.hidden_size)) + ): + raise AssertionError("Dimensions of self-attention weights do not match.") + + self_attn.query.weight.data = xmod_layer.self_attn.q_proj.weight + self_attn.query.bias.data = xmod_layer.self_attn.q_proj.bias + self_attn.key.weight.data = xmod_layer.self_attn.k_proj.weight + self_attn.key.bias.data = xmod_layer.self_attn.k_proj.bias + self_attn.value.weight.data = xmod_layer.self_attn.v_proj.weight + self_attn.value.bias.data = xmod_layer.self_attn.v_proj.bias + + # self-attention output + self_output = layer.attention.output + if self_output.dense.weight.shape != xmod_layer.self_attn.out_proj.weight.shape: + raise AssertionError("Dimensions of self-attention output weights do not match.") + self_output.dense.weight = xmod_layer.self_attn.out_proj.weight + self_output.dense.bias = xmod_layer.self_attn.out_proj.bias + self_output.LayerNorm.weight = xmod_layer.self_attn_layer_norm.weight + self_output.LayerNorm.bias = xmod_layer.self_attn_layer_norm.bias + + # intermediate + intermediate = layer.intermediate + if intermediate.dense.weight.shape != xmod_layer.fc1.weight.shape: + raise AssertionError("Dimensions of intermediate weights do not match.") + intermediate.dense.weight = xmod_layer.fc1.weight + intermediate.dense.bias = xmod_layer.fc1.bias + + # output + bert_output = layer.output + if bert_output.dense.weight.shape != xmod_layer.fc2.weight.shape: + raise AssertionError("Dimensions of feed-forward weights do not match.") + bert_output.dense.weight = xmod_layer.fc2.weight + bert_output.dense.bias = xmod_layer.fc2.bias + bert_output.LayerNorm.weight = xmod_layer.final_layer_norm.weight + bert_output.LayerNorm.bias = xmod_layer.final_layer_norm.bias + if bert_output.adapter_layer_norm is not None: + bert_output.adapter_layer_norm.weight = xmod_layer.adapter_layer_norm.weight + bert_output.adapter_layer_norm.bias = xmod_layer.adapter_layer_norm.bias + + if sorted(bert_output.adapter_modules.keys()) != sorted(xmod_layer.adapter_modules.keys()): + raise AssertionError("Lists of language adapters do not match.") + for lang_code, adapter in xmod_layer.adapter_modules.items(): + to_adapter = bert_output.adapter_modules[lang_code] + from_adapter = xmod_layer.adapter_modules[lang_code] + to_adapter.dense1.weight = from_adapter.fc1.weight + to_adapter.dense1.bias = from_adapter.fc1.bias + to_adapter.dense2.weight = from_adapter.fc2.weight + to_adapter.dense2.bias = from_adapter.fc2.bias + + # end of layer + + if xmod_sent_encoder.layer_norm is not None: + model.roberta.encoder.LayerNorm.weight = xmod_sent_encoder.layer_norm.weight + model.roberta.encoder.LayerNorm.bias = xmod_sent_encoder.layer_norm.bias + + if classification_head: + model.classifier.dense.weight = xmod.model.classification_heads["mnli"].dense.weight + model.classifier.dense.bias = xmod.model.classification_heads["mnli"].dense.bias + model.classifier.out_proj.weight = xmod.model.classification_heads["mnli"].out_proj.weight + model.classifier.out_proj.bias = xmod.model.classification_heads["mnli"].out_proj.bias + else: + # LM Head + model.lm_head.dense.weight = xmod.model.encoder.lm_head.dense.weight + model.lm_head.dense.bias = xmod.model.encoder.lm_head.dense.bias + model.lm_head.layer_norm.weight = xmod.model.encoder.lm_head.layer_norm.weight + model.lm_head.layer_norm.bias = xmod.model.encoder.lm_head.layer_norm.bias + model.lm_head.decoder.weight = xmod.model.encoder.lm_head.weight + model.lm_head.decoder.bias = xmod.model.encoder.lm_head.bias + + # Let's check that we get the same results. + input_ids = xmod.encode(SAMPLE_TEXT).unsqueeze(0) # batch of size 1 + model.roberta.set_default_language(SAMPLE_LANGUAGE) + + our_output = model(input_ids)[0] + if classification_head: + their_output = xmod.model.classification_heads["mnli"](xmod.extract_features(input_ids)) + else: + their_output = xmod.model(input_ids, lang_id=[SAMPLE_LANGUAGE])[0] + print(our_output.shape, their_output.shape) + max_absolute_diff = torch.max(torch.abs(our_output - their_output)).item() + print(f"max_absolute_diff = {max_absolute_diff}") # ~ 1e-7 + success = torch.allclose(our_output, their_output, atol=1e-3) + print("Do both models output the same tensors?", "🔥" if success else "💩") + if not success: + raise Exception("Something went wRoNg") + + Path(pytorch_dump_folder_path).mkdir(parents=True, exist_ok=True) + print(f"Saving model to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--xmod_checkpoint_path", default=None, type=str, required=True, help="Path the official PyTorch dump." + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + parser.add_argument( + "--classification_head", action="store_true", help="Whether to convert a final classification head." + ) + args = parser.parse_args() + convert_xmod_checkpoint_to_pytorch( + args.xmod_checkpoint_path, args.pytorch_dump_folder_path, args.classification_head + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/modeling_xmod.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/modeling_xmod.py new file mode 100644 index 0000000000000000000000000000000000000000..6453701fe93c63d56c68678098b5fba91a8a346f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/xmod/modeling_xmod.py @@ -0,0 +1,1683 @@ +# coding=utf-8 +# Copyright 2023 Meta AI Team and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTorch X-MOD model.""" + +import math +from typing import List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN, gelu +from ...modeling_outputs import ( + BaseModelOutputWithPastAndCrossAttentions, + BaseModelOutputWithPoolingAndCrossAttentions, + CausalLMOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_xmod import XmodConfig + + +logger = logging.get_logger(__name__) + +XMOD_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "facebook/xmod-base", + "facebook/xmod-large-prenorm", + "facebook/xmod-base-13-125k", + "facebook/xmod-base-30-125k", + "facebook/xmod-base-30-195k", + "facebook/xmod-base-60-125k", + "facebook/xmod-base-60-265k", + "facebook/xmod-base-75-125k", + "facebook/xmod-base-75-269k", + # See all X-MOD models at https://huggingface.co/models?filter=xmod +] + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->Xmod +class XmodEmbeddings(nn.Module): + """ + Same as BertEmbeddings with a tiny tweak for positional embeddings indexing. + """ + + # Copied from transformers.models.bert.modeling_bert.BertEmbeddings.__init__ + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1))) + self.register_buffer( + "token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False + ) + + # End copy + self.padding_idx = config.pad_token_id + self.position_embeddings = nn.Embedding( + config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx + ) + + def forward( + self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None, past_key_values_length=0 + ): + if position_ids is None: + if input_ids is not None: + # Create the position ids from the input token ids. Any padded tokens remain padded. + position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx, past_key_values_length) + else: + position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds) + + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + def create_position_ids_from_inputs_embeds(self, inputs_embeds): + """ + We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids. + + Args: + inputs_embeds: torch.Tensor + + Returns: torch.Tensor + """ + input_shape = inputs_embeds.size()[:-1] + sequence_length = input_shape[1] + + position_ids = torch.arange( + self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device + ) + return position_ids.unsqueeze(0).expand(input_shape) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfAttention with Roberta->Xmod +class XmodSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = position_embedding_type or getattr( + config, "position_embedding_type", "absolute" + ) + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + self.max_position_embeddings = config.max_position_embeddings + self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size) + + self.is_decoder = config.is_decoder + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + mixed_query_layer = self.query(hidden_states) + + # If this is instantiated as a cross-attention module, the keys + # and values come from an encoder; the attention mask needs to be + # such that the encoder's padding tokens are not attended to. + is_cross_attention = encoder_hidden_states is not None + + if is_cross_attention and past_key_value is not None: + # reuse k,v, cross_attentions + key_layer = past_key_value[0] + value_layer = past_key_value[1] + attention_mask = encoder_attention_mask + elif is_cross_attention: + key_layer = self.transpose_for_scores(self.key(encoder_hidden_states)) + value_layer = self.transpose_for_scores(self.value(encoder_hidden_states)) + attention_mask = encoder_attention_mask + elif past_key_value is not None: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + key_layer = torch.cat([past_key_value[0], key_layer], dim=2) + value_layer = torch.cat([past_key_value[1], value_layer], dim=2) + else: + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + + query_layer = self.transpose_for_scores(mixed_query_layer) + + use_cache = past_key_value is not None + if self.is_decoder: + # if cross_attention save Tuple(torch.Tensor, torch.Tensor) of all cross attention key/value_states. + # Further calls to cross_attention layer can then reuse all cross-attention + # key/value_states (first "if" case) + # if uni-directional self-attention (decoder) save Tuple(torch.Tensor, torch.Tensor) of + # all previous decoder key/value_states. Further calls to uni-directional self-attention + # can concat previous decoder key/value_states to current projected key/value_states (third "elif" case) + # if encoder bi-directional self-attention `past_key_value` is always `None` + past_key_value = (key_layer, value_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query": + query_length, key_length = query_layer.shape[2], key_layer.shape[2] + if use_cache: + position_ids_l = torch.tensor(key_length - 1, dtype=torch.long, device=hidden_states.device).view( + -1, 1 + ) + else: + position_ids_l = torch.arange(query_length, dtype=torch.long, device=hidden_states.device).view(-1, 1) + position_ids_r = torch.arange(key_length, dtype=torch.long, device=hidden_states.device).view(1, -1) + distance = position_ids_l - position_ids_r + + positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1) + positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility + + if self.position_embedding_type == "relative_key": + relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores + elif self.position_embedding_type == "relative_key_query": + relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding) + relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding) + attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + if attention_mask is not None: + # Apply the attention mask is (precomputed for all layers in XmodModel forward() function) + attention_scores = attention_scores + attention_mask + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + if self.is_decoder: + outputs = outputs + (past_key_value,) + return outputs + + +class XmodSelfOutput(nn.Module): + # Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput.__init__ + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states + input_tensor + return hidden_states + + +class XmodAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = XmodSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = XmodSelfOutput(config) + self.pruned_heads = set() + self.pre_norm = config.pre_norm + + # Copied from transformers.models.roberta.modeling_roberta.RobertaAttention.prune_heads + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + residual = hidden_states + if self.pre_norm: + hidden_states = self.output.LayerNorm(hidden_states) + self_outputs = self.self( + hidden_states, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + attention_output = self.output(self_outputs[0], residual) + if not self.pre_norm: + attention_output = self.output.LayerNorm(attention_output) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate +class XmodIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +class XmodAdapter(nn.Module): + def __init__(self, config): + super().__init__() + self.bottleneck_size = config.hidden_size // config.adapter_reduction_factor + self.dense1 = nn.Linear(config.hidden_size, self.bottleneck_size) + self.dense2 = nn.Linear(self.bottleneck_size, config.hidden_size) + if isinstance(config.hidden_act, str): + self.adapter_act_fn = ACT2FN[config.hidden_act] + else: + self.adapter_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense1(hidden_states) + hidden_states = self.adapter_act_fn(hidden_states) + hidden_states = self.dense2(hidden_states) + return hidden_states + + +class XmodOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.ln_before_adapter = config.ln_before_adapter + self.dropout = nn.Dropout(config.hidden_dropout_prob) + if config.adapter_layer_norm: + self.adapter_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + else: + self.adapter_layer_norm = None + self.adapter_reuse_layer_norm = config.adapter_reuse_layer_norm + self.adapter_modules = nn.ModuleDict({}) + for language in config.languages: + self.adapter_modules[str(language)] = XmodAdapter(config) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor, lang_ids: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = hidden_states + input_tensor + hidden_states = self.lang_adapter(lang_ids, hidden_states) + return hidden_states + + def lang_adapter(self, lang_ids: torch.Tensor, hidden_states: torch.Tensor): + # Process subsequent samples with the same lang_id in parallel + lang_ids, lang_lengths = torch.unique_consecutive(lang_ids, return_counts=True) + + if not self.ln_before_adapter: + residual = hidden_states + + if self.adapter_layer_norm is not None: + hidden_states = self.adapter_layer_norm(hidden_states) + elif self.adapter_reuse_layer_norm: + hidden_states = self.LayerNorm(hidden_states) + + if self.ln_before_adapter: + residual = hidden_states + + split_hidden_states = torch.split(hidden_states, lang_lengths.tolist(), 0) + lang_wise_outputs = [] + for i, (lang_id, split_hidden_state) in enumerate(zip(lang_ids, split_hidden_states)): + lang = list(self.adapter_modules.keys())[int(lang_id.item())] + lang_wise_outputs.append(self.adapter_modules[lang](split_hidden_state)) + hidden_states = torch.cat(lang_wise_outputs, 0) + + hidden_states = self.dropout(hidden_states) + hidden_states += residual + return hidden_states + + +class XmodLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = XmodAttention(config) + self.is_decoder = config.is_decoder + self.add_cross_attention = config.add_cross_attention + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = XmodAttention(config, position_embedding_type="absolute") + self.intermediate = XmodIntermediate(config) + self.output = XmodOutput(config) + self.pre_norm = config.pre_norm + + def forward( + self, + hidden_states: torch.Tensor, + lang_ids: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + output_attentions: Optional[bool] = False, + ) -> Tuple[torch.Tensor]: + # decoder uni-directional self-attention cached key/values tuple is at positions 1,2 + self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None + self_attention_outputs = self.attention( + hidden_states, + attention_mask, + head_mask, + output_attentions=output_attentions, + past_key_value=self_attn_past_key_value, + ) + attention_output = self_attention_outputs[0] + + # if decoder, the last output is tuple of self-attn cache + if self.is_decoder: + outputs = self_attention_outputs[1:-1] + present_key_value = self_attention_outputs[-1] + else: + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + cross_attn_present_key_value = None + if self.is_decoder and encoder_hidden_states is not None: + if not hasattr(self, "crossattention"): + raise ValueError( + f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers" + " by setting `config.add_cross_attention=True`" + ) + + # cross_attn cached key/values tuple is at positions 3,4 of past_key_value tuple + cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None + cross_attention_outputs = self.crossattention( + attention_output, + attention_mask, + head_mask, + encoder_hidden_states, + encoder_attention_mask, + cross_attn_past_key_value, + output_attentions, + ) + attention_output = cross_attention_outputs[0] + outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights + + # add cross-attn cache to positions 3,4 of present_key_value tuple + cross_attn_present_key_value = cross_attention_outputs[-1] + present_key_value = present_key_value + cross_attn_present_key_value + + residual = attention_output + if self.pre_norm: + attention_output = self.output.LayerNorm(attention_output) + intermediate_output = apply_chunking_to_forward( + self.feed_forward_chunk, + self.chunk_size_feed_forward, + self.seq_len_dim, + attention_output, + ) + layer_output = self.output(intermediate_output, residual, lang_ids) + if not self.pre_norm: + layer_output = self.output.LayerNorm(layer_output) + outputs = (layer_output,) + outputs + + # if decoder, return the attn key/values as the last output + if self.is_decoder: + outputs = outputs + (present_key_value,) + + return outputs + + def feed_forward_chunk(self, attention_output): + return self.intermediate(attention_output) + + +class XmodEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([XmodLayer(config) for _ in range(config.num_hidden_layers)]) + self.is_pre_norm = config.pre_norm + if self.is_pre_norm: + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.Tensor, + lang_ids: torch.Tensor, + attention_mask: Optional[torch.FloatTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = False, + output_hidden_states: Optional[bool] = False, + return_dict: Optional[bool] = True, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: + if self.gradient_checkpointing and self.training: + if use_cache: + logger.warning_once( + "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." + ) + use_cache = False + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None + + next_decoder_cache = () if use_cache else None + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + past_key_value = past_key_values[i] if past_key_values is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, past_key_value, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + lang_ids, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + else: + layer_outputs = layer_module( + hidden_states, + lang_ids, + attention_mask, + layer_head_mask, + encoder_hidden_states, + encoder_attention_mask, + past_key_value, + output_attentions, + ) + + hidden_states = layer_outputs[0] + if use_cache: + next_decoder_cache += (layer_outputs[-1],) + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + if self.config.add_cross_attention: + all_cross_attentions = all_cross_attentions + (layer_outputs[2],) + + if self.is_pre_norm: + hidden_states = self.LayerNorm(hidden_states) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple( + v + for v in [ + hidden_states, + next_decoder_cache, + all_hidden_states, + all_self_attentions, + all_cross_attentions, + ] + if v is not None + ) + return BaseModelOutputWithPastAndCrossAttentions( + last_hidden_state=hidden_states, + past_key_values=next_decoder_cache, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + cross_attentions=all_cross_attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaPooler +class XmodPooler(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +class XmodPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = XmodConfig + base_model_prefix = "roberta" + supports_gradient_checkpointing = True + + # Copied from transformers.models.bert.modeling_bert.BertPreTrainedModel._init_weights + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + # Copied from transformers.models.roberta.modeling_roberta.RobertaPreTrainedModel._set_gradient_checkpointing with Roberta->Xmod + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, XmodEncoder): + module.gradient_checkpointing = value + + # Copied from transformers.models.roberta.modeling_roberta.RobertaPreTrainedModel.update_keys_to_ignore + def update_keys_to_ignore(self, config, del_keys_to_ignore): + """Remove some keys from ignore list""" + if not config.tie_word_embeddings: + # must make a new list, or the class variable gets modified! + self._keys_to_ignore_on_save = [k for k in self._keys_to_ignore_on_save if k not in del_keys_to_ignore] + self._keys_to_ignore_on_load_missing = [ + k for k in self._keys_to_ignore_on_load_missing if k not in del_keys_to_ignore + ] + + def set_default_language(self, language: str): + """ + Set the default language code for the model. This is used when the language is not specified in the input. + + Args: + language (`str`): The language code, such as `"en_XX"` or `"de_DE"`. + """ + if language not in self.config.languages: + raise ValueError( + f"{self} does not have an adapter for {language}. Supported languages: {list(self.config.languages)}" + ) + self.config.default_language = language + + def freeze_embeddings_and_language_adapters(self): + """ + Freeze the embeddings and language adapters of the model. Usually, this is applied before the model is + fine-tuned on a downstream task. + """ + logger.info("Freezing embeddings") + for parameter in self.roberta.embeddings.parameters(): + parameter.requires_grad = False + logger.info("Freezing adapters") + for layer in self.roberta.encoder.layer: + if layer.output.adapter_layer_norm is not None: + for parameter in layer.output.adapter_layer_norm.parameters(): + parameter.requires_grad = False + for parameter in layer.output.adapter_modules.parameters(): + parameter.requires_grad = False + + +XMOD_START_DOCSTRING = r""" + + This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the + library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads + etc.) + + This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. + Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage + and behavior. + + Parameters: + config ([`XmodConfig`]): Model configuration class with all the parameters of the + model. Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +XMOD_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + lang_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of the language adapters that should be activated for each sample, respectively. Default: the index + that corresponds to `self.config.default_language`. + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert `input_ids` indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare X-MOD Model transformer outputting raw hidden-states without any specific head on top.", + XMOD_START_DOCSTRING, +) +class XmodModel(XmodPreTrainedModel): + """ + + The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of + cross-attention is added between the self-attention layers, following the architecture described in *Attention is + all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz + Kaiser and Illia Polosukhin. + + To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set + to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and + `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. + + .. _*Attention is all you need*: https://arxiv.org/abs/1706.03762 + + """ + + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.bert.modeling_bert.BertModel.__init__ with Bert->Xmod + def __init__(self, config, add_pooling_layer=True): + super().__init__(config) + self.config = config + + self.embeddings = XmodEmbeddings(config) + self.encoder = XmodEncoder(config) + + self.pooler = XmodPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.roberta.modeling_roberta.RobertaModel.get_input_embeddings + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + # Copied from transformers.models.roberta.modeling_roberta.RobertaModel.set_input_embeddings + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + # Copied from transformers.models.roberta.modeling_roberta.RobertaModel._prune_heads + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors: + of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + """ + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if self.config.is_decoder: + use_cache = use_cache if use_cache is not None else self.config.use_cache + else: + use_cache = False + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + # past_key_values_length + past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 + + if lang_ids is None: + if self.config.default_language is None: + raise ValueError("Input language unknown. Please call `XmodPreTrainedModel.set_default_language()`") + adapter_languages = list(self.encoder.layer[0].output.adapter_modules.keys()) + default_lang_id = adapter_languages.index(self.config.default_language) + lang_ids = default_lang_id * torch.ones(batch_size, device=device) + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # If a 2D or 3D attention mask is provided for the cross-attention + # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] + if self.config.is_decoder and encoder_hidden_states is not None: + encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() + encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) + if encoder_attention_mask is None: + encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) + encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) + else: + encoder_extended_attention_mask = None + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + past_key_values_length=past_key_values_length, + ) + encoder_outputs = self.encoder( + embedding_output, + lang_ids=lang_ids, + attention_mask=extended_attention_mask, + head_mask=head_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_extended_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + return (sequence_output, pooled_output) + encoder_outputs[1:] + + return BaseModelOutputWithPoolingAndCrossAttentions( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + past_key_values=encoder_outputs.past_key_values, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +@add_start_docstrings( + "X-MOD Model with a `language modeling` head on top for CLM fine-tuning.", + XMOD_START_DOCSTRING, +) +class XmodForCausalLM(XmodPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + + if not config.is_decoder: + logger.warning("If you want to use `XmodLMHeadModel` as a standalone, add `is_decoder=True.`") + + self.roberta = XmodModel(config, add_pooling_layer=False) + self.lm_head = XmodLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM.get_output_embeddings + def get_output_embeddings(self): + return self.lm_head.decoder + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM.set_output_embeddings + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + past_key_values: Tuple[Tuple[torch.FloatTensor]] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithCrossAttentions]: + r""" + encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if + the model is configured as a decoder. + encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in + the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in + `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are + ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): + Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. + + If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that + don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all + `decoder_input_ids` of shape `(batch_size, sequence_length)`. + use_cache (`bool`, *optional*): + If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see + `past_key_values`). + + Returns: `transformers.modeling_outputs.CausalLMOutputWithCrossAttentions` or `tuple(torch.FloatTensor)` + + Example: + + ```python + >>> from transformers import AutoTokenizer, XmodForCausalLM, AutoConfig + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base") + >>> config = AutoConfig.from_pretrained("facebook/xmod-base") + >>> config.is_decoder = True + >>> model = XmodForCausalLM.from_pretrained("facebook/xmod-base", config=config) + >>> model.set_default_language("en_XX") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> prediction_logits = outputs.logits + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + if labels is not None: + use_cache = False + + outputs = self.roberta( + input_ids, + lang_ids=lang_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + lm_loss = None + if labels is not None: + # we are doing next-token prediction; shift prediction scores and input ids by one + shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous() + labels = labels[:, 1:].contiguous() + loss_fct = CrossEntropyLoss() + lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((lm_loss,) + output) if lm_loss is not None else output + + return CausalLMOutputWithCrossAttentions( + loss=lm_loss, + logits=prediction_scores, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + cross_attentions=outputs.cross_attentions, + ) + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM.prepare_inputs_for_generation + def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs): + input_shape = input_ids.shape + # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly + if attention_mask is None: + attention_mask = input_ids.new_ones(input_shape) + + # cut decoder_input_ids if past is used + if past_key_values is not None: + input_ids = input_ids[:, -1:] + + return {"input_ids": input_ids, "attention_mask": attention_mask, "past_key_values": past_key_values} + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForCausalLM._reorder_cache + def _reorder_cache(self, past_key_values, beam_idx): + reordered_past = () + for layer_past in past_key_values: + reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),) + return reordered_past + + +@add_start_docstrings( + """X-MOD Model with a `language modeling` head on top.""", + XMOD_START_DOCSTRING, +) +class XmodForMaskedLM(XmodPreTrainedModel): + _keys_to_ignore_on_save = [r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_missing = [r"position_ids", r"lm_head.decoder.weight", r"lm_head.decoder.bias"] + _keys_to_ignore_on_load_unexpected = [r"pooler"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + + if config.is_decoder: + logger.warning( + "If you want to use `XmodForMaskedLM` make sure `config.is_decoder=False` for " + "bi-directional self-attention." + ) + + self.roberta = XmodModel(config, add_pooling_layer=False) + self.lm_head = XmodLMHead(config) + + # The LM head weights require special treatment only when they are tied with the word embeddings + self.update_keys_to_ignore(config, ["lm_head.decoder.weight"]) + + # Initialize weights and apply final processing + self.post_init() + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM.get_output_embeddings + def get_output_embeddings(self): + return self.lm_head.decoder + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForMaskedLM.set_output_embeddings + def set_output_embeddings(self, new_embeddings): + self.lm_head.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]` + kwargs (`Dict[str, any]`, optional, defaults to *{}*): + Used to hide legacy arguments that have been deprecated. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + lang_ids=lang_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + prediction_scores = self.lm_head(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[2:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaLMHead +class XmodLMHead(nn.Module): + """Roberta Head for masked language modeling.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + self.decoder = nn.Linear(config.hidden_size, config.vocab_size) + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + self.decoder.bias = self.bias + + def forward(self, features, **kwargs): + x = self.dense(features) + x = gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + x = self.decoder(x) + + return x + + def _tie_weights(self): + # To tie those two weights if they get disconnected (on TPU or when the bias is resized) + # For accelerate compatibility and to not break backward compatibility + if self.decoder.bias.device.type == "meta": + self.decoder.bias = self.bias + else: + self.bias = self.decoder.bias + + +@add_start_docstrings( + """ + X-MOD Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled + output) e.g. for GLUE tasks. + """, + XMOD_START_DOCSTRING, +) +class XmodForSequenceClassification(XmodPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForSequenceClassification.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.config = config + + self.roberta = XmodModel(config, add_pooling_layer=False) + self.classifier = XmodClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + lang_ids=lang_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + X-MOD Model with a multiple choice classification head on top (a linear layer on top of the pooled output and a + softmax) e.g. for RocStories/SWAG tasks. + """, + XMOD_START_DOCSTRING, +) +class XmodForMultipleChoice(XmodPreTrainedModel): + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForMultipleChoice.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + + self.roberta = XmodModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + flat_lang_ids = lang_ids.repeat(input_ids.size(0) * input_ids.size(1)) if lang_ids is not None else None + flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + flat_inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.roberta( + flat_input_ids, + lang_ids=flat_lang_ids, + position_ids=flat_position_ids, + token_type_ids=flat_token_type_ids, + attention_mask=flat_attention_mask, + head_mask=head_mask, + inputs_embeds=flat_inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + pooled_output = outputs[1] + + pooled_output = self.dropout(pooled_output) + logits = self.classifier(pooled_output) + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """ + X-MOD Model with a token classification head on top (a linear layer on top of the hidden-states output) e.g. for + Named-Entity-Recognition (NER) tasks. + """, + XMOD_START_DOCSTRING, +) +class XmodForTokenClassification(XmodPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForTokenClassification.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XmodModel(config, add_pooling_layer=False) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + lang_ids=lang_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[2:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.RobertaClassificationHead +class XmodClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + classifier_dropout = ( + config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob + ) + self.dropout = nn.Dropout(classifier_dropout) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """ + X-MOD Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`). + """, + XMOD_START_DOCSTRING, +) +class XmodForQuestionAnswering(XmodPreTrainedModel): + _keys_to_ignore_on_load_unexpected = [r"pooler"] + _keys_to_ignore_on_load_missing = [r"position_ids"] + + # Copied from transformers.models.roberta.modeling_roberta.RobertaForQuestionAnswering.__init__ with Roberta->Xmod + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.roberta = XmodModel(config, add_pooling_layer=False) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(XMOD_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + lang_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + token_type_ids: Optional[torch.LongTensor] = None, + position_ids: Optional[torch.LongTensor] = None, + head_mask: Optional[torch.FloatTensor] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + start_positions: Optional[torch.LongTensor] = None, + end_positions: Optional[torch.LongTensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple[torch.Tensor], QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.roberta( + input_ids, + lang_ids=lang_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1).contiguous() + end_logits = end_logits.squeeze(-1).contiguous() + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[2:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.roberta.modeling_roberta.create_position_ids_from_input_ids +def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0): + """ + Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols + are ignored. This is modified from fairseq's `utils.make_positions`. + + Args: + x: torch.Tensor x: + + Returns: torch.Tensor + """ + # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA. + mask = input_ids.ne(padding_idx).int() + incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask + return incremental_indices.long() + padding_idx diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..28d59763bb85503b4ebc8c5aa8e8b299c45e586f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/__init__.py @@ -0,0 +1,73 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available + + +_import_structure = {"configuration_yolos": ["YOLOS_PRETRAINED_CONFIG_ARCHIVE_MAP", "YolosConfig", "YolosOnnxConfig"]} + +try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["feature_extraction_yolos"] = ["YolosFeatureExtractor"] + _import_structure["image_processing_yolos"] = ["YolosImageProcessor"] + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_yolos"] = [ + "YOLOS_PRETRAINED_MODEL_ARCHIVE_LIST", + "YolosForObjectDetection", + "YolosModel", + "YolosPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_yolos import YOLOS_PRETRAINED_CONFIG_ARCHIVE_MAP, YolosConfig, YolosOnnxConfig + + try: + if not is_vision_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .feature_extraction_yolos import YolosFeatureExtractor + from .image_processing_yolos import YolosImageProcessor + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_yolos import ( + YOLOS_PRETRAINED_MODEL_ARCHIVE_LIST, + YolosForObjectDetection, + YolosModel, + YolosPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/configuration_yolos.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/configuration_yolos.py new file mode 100644 index 0000000000000000000000000000000000000000..538f85b1eb29e81aa54db00c4293dda05c801630 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/configuration_yolos.py @@ -0,0 +1,179 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" YOLOS model configuration""" + +from collections import OrderedDict +from typing import Mapping + +from packaging import version + +from ...configuration_utils import PretrainedConfig +from ...onnx import OnnxConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +YOLOS_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "hustvl/yolos-small": "https://huggingface.co/hustvl/yolos-small/resolve/main/config.json", + # See all YOLOS models at https://huggingface.co/models?filter=yolos +} + + +class YolosConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`YolosModel`]. It is used to instantiate a YOLOS + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the YOLOS + [hustvl/yolos-base](https://huggingface.co/hustvl/yolos-base) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + Args: + hidden_size (`int`, *optional*, defaults to 768): + Dimensionality of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + image_size (`List[int]`, *optional*, defaults to `[512, 864]`): + The size (resolution) of each image. + patch_size (`int`, *optional*, defaults to `16`): + The size (resolution) of each patch. + num_channels (`int`, *optional*, defaults to `3`): + The number of input channels. + qkv_bias (`bool`, *optional*, defaults to `True`): + Whether to add a bias to the queries, keys and values. + num_detection_tokens (`int`, *optional*, defaults to `100`): + The number of detection tokens. + use_mid_position_embeddings (`bool`, *optional*, defaults to `True`): + Whether to use the mid-layer position encodings. + auxiliary_loss (`bool`, *optional*, defaults to `False`): + Whether auxiliary decoding losses (loss at each decoder layer) are to be used. + class_cost (`float`, *optional*, defaults to 1): + Relative weight of the classification error in the Hungarian matching cost. + bbox_cost (`float`, *optional*, defaults to 5): + Relative weight of the L1 error of the bounding box coordinates in the Hungarian matching cost. + giou_cost (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss of the bounding box in the Hungarian matching cost. + bbox_loss_coefficient (`float`, *optional*, defaults to 5): + Relative weight of the L1 bounding box loss in the object detection loss. + giou_loss_coefficient (`float`, *optional*, defaults to 2): + Relative weight of the generalized IoU loss in the object detection loss. + eos_coefficient (`float`, *optional*, defaults to 0.1): + Relative classification weight of the 'no-object' class in the object detection loss. + + Example: + + ```python + >>> from transformers import YolosConfig, YolosModel + + >>> # Initializing a YOLOS hustvl/yolos-base style configuration + >>> configuration = YolosConfig() + + >>> # Initializing a model (with random weights) from the hustvl/yolos-base style configuration + >>> model = YolosModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "yolos" + + def __init__( + self, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + image_size=[512, 864], + patch_size=16, + num_channels=3, + qkv_bias=True, + num_detection_tokens=100, + use_mid_position_embeddings=True, + auxiliary_loss=False, + class_cost=1, + bbox_cost=5, + giou_cost=2, + bbox_loss_coefficient=5, + giou_loss_coefficient=2, + eos_coefficient=0.1, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias + self.num_detection_tokens = num_detection_tokens + self.use_mid_position_embeddings = use_mid_position_embeddings + self.auxiliary_loss = auxiliary_loss + # Hungarian matcher + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + # Loss coefficients + self.bbox_loss_coefficient = bbox_loss_coefficient + self.giou_loss_coefficient = giou_loss_coefficient + self.eos_coefficient = eos_coefficient + + +class YolosOnnxConfig(OnnxConfig): + torch_onnx_minimum_version = version.parse("1.11") + + @property + def inputs(self) -> Mapping[str, Mapping[int, str]]: + return OrderedDict( + [ + ("pixel_values", {0: "batch", 1: "num_channels", 2: "height", 3: "width"}), + ] + ) + + @property + def atol_for_validation(self) -> float: + return 1e-4 + + @property + def default_onnx_opset(self) -> int: + return 12 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/convert_yolos_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/convert_yolos_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..02279518832bd1d944a643898a25700249bae19b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/convert_yolos_to_pytorch.py @@ -0,0 +1,268 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert YOLOS checkpoints from the original repository. URL: https://github.com/hustvl/YOLOS""" + + +import argparse +import json +from pathlib import Path + +import requests +import torch +from huggingface_hub import hf_hub_download +from PIL import Image + +from transformers import YolosConfig, YolosFeatureExtractor, YolosForObjectDetection +from transformers.utils import logging + + +logging.set_verbosity_info() +logger = logging.get_logger(__name__) + + +def get_yolos_config(yolos_name: str) -> YolosConfig: + config = YolosConfig() + + # size of the architecture + if "yolos_ti" in yolos_name: + config.hidden_size = 192 + config.intermediate_size = 768 + config.num_hidden_layers = 12 + config.num_attention_heads = 3 + config.image_size = [800, 1333] + config.use_mid_position_embeddings = False + elif yolos_name == "yolos_s_dWr": + config.hidden_size = 330 + config.num_hidden_layers = 14 + config.num_attention_heads = 6 + config.intermediate_size = 1320 + elif "yolos_s" in yolos_name: + config.hidden_size = 384 + config.intermediate_size = 1536 + config.num_hidden_layers = 12 + config.num_attention_heads = 6 + elif "yolos_b" in yolos_name: + config.image_size = [800, 1344] + + config.num_labels = 91 + repo_id = "huggingface/label-files" + filename = "coco-detection-id2label.json" + id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r")) + id2label = {int(k): v for k, v in id2label.items()} + config.id2label = id2label + config.label2id = {v: k for k, v in id2label.items()} + + return config + + +# we split up the matrix of each encoder layer into queries, keys and values +def read_in_q_k_v(state_dict: dict, config: YolosConfig, base_model: bool = False): + for i in range(config.num_hidden_layers): + # read in weights + bias of input projection layer (in timm, this is a single matrix + bias) + in_proj_weight = state_dict.pop(f"blocks.{i}.attn.qkv.weight") + in_proj_bias = state_dict.pop(f"blocks.{i}.attn.qkv.bias") + # next, add query, keys and values (in that order) to the state dict + state_dict[f"encoder.layer.{i}.attention.attention.query.weight"] = in_proj_weight[: config.hidden_size, :] + state_dict[f"encoder.layer.{i}.attention.attention.query.bias"] = in_proj_bias[: config.hidden_size] + state_dict[f"encoder.layer.{i}.attention.attention.key.weight"] = in_proj_weight[ + config.hidden_size : config.hidden_size * 2, : + ] + state_dict[f"encoder.layer.{i}.attention.attention.key.bias"] = in_proj_bias[ + config.hidden_size : config.hidden_size * 2 + ] + state_dict[f"encoder.layer.{i}.attention.attention.value.weight"] = in_proj_weight[-config.hidden_size :, :] + state_dict[f"encoder.layer.{i}.attention.attention.value.bias"] = in_proj_bias[-config.hidden_size :] + + +def rename_key(name: str) -> str: + if "backbone" in name: + name = name.replace("backbone", "vit") + if "cls_token" in name: + name = name.replace("cls_token", "embeddings.cls_token") + if "det_token" in name: + name = name.replace("det_token", "embeddings.detection_tokens") + if "mid_pos_embed" in name: + name = name.replace("mid_pos_embed", "encoder.mid_position_embeddings") + if "pos_embed" in name: + name = name.replace("pos_embed", "embeddings.position_embeddings") + if "patch_embed.proj" in name: + name = name.replace("patch_embed.proj", "embeddings.patch_embeddings.projection") + if "blocks" in name: + name = name.replace("blocks", "encoder.layer") + if "attn.proj" in name: + name = name.replace("attn.proj", "attention.output.dense") + if "attn" in name: + name = name.replace("attn", "attention.self") + if "norm1" in name: + name = name.replace("norm1", "layernorm_before") + if "norm2" in name: + name = name.replace("norm2", "layernorm_after") + if "mlp.fc1" in name: + name = name.replace("mlp.fc1", "intermediate.dense") + if "mlp.fc2" in name: + name = name.replace("mlp.fc2", "output.dense") + if "class_embed" in name: + name = name.replace("class_embed", "class_labels_classifier") + if "bbox_embed" in name: + name = name.replace("bbox_embed", "bbox_predictor") + if "vit.norm" in name: + name = name.replace("vit.norm", "vit.layernorm") + + return name + + +def convert_state_dict(orig_state_dict: dict, model: YolosForObjectDetection) -> dict: + for key in orig_state_dict.copy().keys(): + val = orig_state_dict.pop(key) + + if "qkv" in key: + key_split = key.split(".") + layer_num = int(key_split[2]) + dim = model.vit.encoder.layer[layer_num].attention.attention.all_head_size + if "weight" in key: + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.query.weight"] = val[:dim, :] + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.key.weight"] = val[ + dim : dim * 2, : + ] + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.value.weight"] = val[-dim:, :] + else: + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.query.bias"] = val[:dim] + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.key.bias"] = val[dim : dim * 2] + orig_state_dict[f"vit.encoder.layer.{layer_num}.attention.attention.value.bias"] = val[-dim:] + else: + orig_state_dict[rename_key(key)] = val + + return orig_state_dict + + +# We will verify our results on an image of cute cats +def prepare_img() -> torch.Tensor: + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@torch.no_grad() +def convert_yolos_checkpoint( + yolos_name: str, checkpoint_path: str, pytorch_dump_folder_path: str, push_to_hub: bool = False +): + """ + Copy/paste/tweak model's weights to our YOLOS structure. + """ + config = get_yolos_config(yolos_name) + + # load original state_dict + state_dict = torch.load(checkpoint_path, map_location="cpu")["model"] + + # load 🤗 model + model = YolosForObjectDetection(config) + model.eval() + new_state_dict = convert_state_dict(state_dict, model) + model.load_state_dict(new_state_dict) + + # Check outputs on an image, prepared by YolosFeatureExtractor + size = 800 if yolos_name != "yolos_ti" else 512 + feature_extractor = YolosFeatureExtractor(format="coco_detection", size=size) + encoding = feature_extractor(images=prepare_img(), return_tensors="pt") + outputs = model(**encoding) + logits, pred_boxes = outputs.logits, outputs.pred_boxes + + expected_slice_logits, expected_slice_boxes = None, None + if yolos_name == "yolos_ti": + expected_slice_logits = torch.tensor( + [[-39.5022, -11.9820, -17.6888], [-29.9574, -9.9769, -17.7691], [-42.3281, -20.7200, -30.6294]] + ) + expected_slice_boxes = torch.tensor( + [[0.4021, 0.0836, 0.7979], [0.0184, 0.2609, 0.0364], [0.1781, 0.2004, 0.2095]] + ) + elif yolos_name == "yolos_s_200_pre": + expected_slice_logits = torch.tensor( + [[-24.0248, -10.3024, -14.8290], [-42.0392, -16.8200, -27.4334], [-27.2743, -11.8154, -18.7148]] + ) + expected_slice_boxes = torch.tensor( + [[0.2559, 0.5455, 0.4706], [0.2989, 0.7279, 0.1875], [0.7732, 0.4017, 0.4462]] + ) + elif yolos_name == "yolos_s_300_pre": + expected_slice_logits = torch.tensor( + [[-36.2220, -14.4385, -23.5457], [-35.6970, -14.7583, -21.3935], [-31.5939, -13.6042, -16.8049]] + ) + expected_slice_boxes = torch.tensor( + [[0.7614, 0.2316, 0.4728], [0.7168, 0.4495, 0.3855], [0.4996, 0.1466, 0.9996]] + ) + elif yolos_name == "yolos_s_dWr": + expected_slice_logits = torch.tensor( + [[-42.8668, -24.1049, -41.1690], [-34.7456, -14.1274, -24.9194], [-33.7898, -12.1946, -25.6495]] + ) + expected_slice_boxes = torch.tensor( + [[0.5587, 0.2773, 0.0605], [0.5004, 0.3014, 0.9994], [0.4999, 0.1548, 0.9994]] + ) + elif yolos_name == "yolos_base": + expected_slice_logits = torch.tensor( + [[-40.6064, -24.3084, -32.6447], [-55.1990, -30.7719, -35.5877], [-51.4311, -33.3507, -35.6462]] + ) + expected_slice_boxes = torch.tensor( + [[0.5555, 0.2794, 0.0655], [0.9049, 0.2664, 0.1894], [0.9183, 0.1984, 0.1635]] + ) + else: + raise ValueError(f"Unknown yolos_name: {yolos_name}") + + assert torch.allclose(logits[0, :3, :3], expected_slice_logits, atol=1e-4) + assert torch.allclose(pred_boxes[0, :3, :3], expected_slice_boxes, atol=1e-4) + + Path(pytorch_dump_folder_path).mkdir(exist_ok=True) + print(f"Saving model {yolos_name} to {pytorch_dump_folder_path}") + model.save_pretrained(pytorch_dump_folder_path) + print(f"Saving feature extractor to {pytorch_dump_folder_path}") + feature_extractor.save_pretrained(pytorch_dump_folder_path) + + if push_to_hub: + model_mapping = { + "yolos_ti": "yolos-tiny", + "yolos_s_200_pre": "yolos-small", + "yolos_s_300_pre": "yolos-small-300", + "yolos_s_dWr": "yolos-small-dwr", + "yolos_base": "yolos-base", + } + + print("Pushing to the hub...") + model_name = model_mapping[yolos_name] + feature_extractor.push_to_hub(model_name, organization="hustvl") + model.push_to_hub(model_name, organization="hustvl") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--yolos_name", + default="yolos_s_200_pre", + type=str, + help=( + "Name of the YOLOS model you'd like to convert. Should be one of 'yolos_ti', 'yolos_s_200_pre'," + " 'yolos_s_300_pre', 'yolos_s_dWr', 'yolos_base'." + ), + ) + parser.add_argument( + "--checkpoint_path", default=None, type=str, help="Path to the original state dict (.pth file)." + ) + parser.add_argument( + "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory." + ) + parser.add_argument( + "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub." + ) + + args = parser.parse_args() + convert_yolos_checkpoint(args.yolos_name, args.checkpoint_path, args.pytorch_dump_folder_path, args.push_to_hub) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/feature_extraction_yolos.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/feature_extraction_yolos.py new file mode 100644 index 0000000000000000000000000000000000000000..a19c87c503e57129e0ac0afc6c4eecf8359a8c80 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/feature_extraction_yolos.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Feature extractor class for YOLOS.""" + +import warnings + +from ...utils import logging +from .image_processing_yolos import YolosImageProcessor + + +logger = logging.get_logger(__name__) + + +class YolosFeatureExtractor(YolosImageProcessor): + def __init__(self, *args, **kwargs) -> None: + warnings.warn( + "The class YolosFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please" + " use YolosImageProcessor instead.", + FutureWarning, + ) + super().__init__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/image_processing_yolos.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/image_processing_yolos.py new file mode 100644 index 0000000000000000000000000000000000000000..1aa37fec4219d98a305b424b6c58724c1bebd066 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/image_processing_yolos.py @@ -0,0 +1,1244 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Image processor class for YOLOS.""" + +import pathlib +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union + +import numpy as np + +from ...feature_extraction_utils import BatchFeature +from ...image_processing_utils import BaseImageProcessor, get_size_dict +from ...image_transforms import ( + PaddingMode, + center_to_corners_format, + corners_to_center_format, + id_to_rgb, + normalize, + pad, + rescale, + resize, + rgb_to_id, + to_channel_dimension_format, +) +from ...image_utils import ( + IMAGENET_DEFAULT_MEAN, + IMAGENET_DEFAULT_STD, + ChannelDimension, + ImageInput, + PILImageResampling, + get_image_size, + infer_channel_dimension_format, + make_list_of_images, + to_numpy_array, + valid_coco_detection_annotations, + valid_coco_panoptic_annotations, + valid_images, +) +from ...utils import ( + ExplicitEnum, + TensorType, + is_flax_available, + is_jax_tensor, + is_scipy_available, + is_tf_available, + is_tf_tensor, + is_torch_available, + is_torch_tensor, + is_vision_available, + logging, +) + + +if is_torch_available(): + import torch + from torch import nn + + +if is_vision_available(): + import PIL + + +if is_scipy_available(): + import scipy.special + import scipy.stats + +logger = logging.get_logger(__name__) + +AnnotationType = Dict[str, Union[int, str, List[Dict]]] + + +class AnnotionFormat(ExplicitEnum): + COCO_DETECTION = "coco_detection" + COCO_PANOPTIC = "coco_panoptic" + + +SUPPORTED_ANNOTATION_FORMATS = (AnnotionFormat.COCO_DETECTION, AnnotionFormat.COCO_PANOPTIC) + + +# Copied from transformers.models.detr.image_processing_detr.get_max_height_width +def get_max_height_width(images: List[np.ndarray]) -> List[int]: + """ + Get the maximum height and width across all images in a batch. + """ + input_channel_dimension = infer_channel_dimension_format(images[0]) + + if input_channel_dimension == ChannelDimension.FIRST: + _, max_height, max_width = max_across_indices([img.shape for img in images]) + elif input_channel_dimension == ChannelDimension.LAST: + max_height, max_width, _ = max_across_indices([img.shape for img in images]) + else: + raise ValueError(f"Invalid channel dimension format: {input_channel_dimension}") + return (max_height, max_width) + + +# Copied from transformers.models.detr.image_processing_detr.get_size_with_aspect_ratio +def get_size_with_aspect_ratio(image_size, size, max_size=None) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + height, width = image_size + if max_size is not None: + min_original_size = float(min((height, width))) + max_original_size = float(max((height, width))) + if max_original_size / min_original_size * size > max_size: + size = int(round(max_size * min_original_size / max_original_size)) + + if (height <= width and height == size) or (width <= height and width == size): + return height, width + + if width < height: + ow = size + oh = int(size * height / width) + else: + oh = size + ow = int(size * width / height) + return (oh, ow) + + +# Copied from transformers.models.detr.image_processing_detr.get_resize_output_image_size +def get_resize_output_image_size( + input_image: np.ndarray, size: Union[int, Tuple[int, int], List[int]], max_size: Optional[int] = None +) -> Tuple[int, int]: + """ + Computes the output image size given the input image size and the desired output size. If the desired output size + is a tuple or list, the output image size is returned as is. If the desired output size is an integer, the output + image size is computed by keeping the aspect ratio of the input image size. + + Args: + image_size (`Tuple[int, int]`): + The input image size. + size (`int`): + The desired output size. + max_size (`int`, *optional*): + The maximum allowed output size. + """ + image_size = get_image_size(input_image) + if isinstance(size, (list, tuple)): + return size + + return get_size_with_aspect_ratio(image_size, size, max_size) + + +# Copied from transformers.models.detr.image_processing_detr.get_numpy_to_framework_fn +def get_numpy_to_framework_fn(arr) -> Callable: + """ + Returns a function that converts a numpy array to the framework of the input array. + + Args: + arr (`np.ndarray`): The array to convert. + """ + if isinstance(arr, np.ndarray): + return np.array + if is_tf_available() and is_tf_tensor(arr): + import tensorflow as tf + + return tf.convert_to_tensor + if is_torch_available() and is_torch_tensor(arr): + import torch + + return torch.tensor + if is_flax_available() and is_jax_tensor(arr): + import jax.numpy as jnp + + return jnp.array + raise ValueError(f"Cannot convert arrays of type {type(arr)}") + + +# Copied from transformers.models.detr.image_processing_detr.safe_squeeze +def safe_squeeze(arr: np.ndarray, axis: Optional[int] = None) -> np.ndarray: + """ + Squeezes an array, but only if the axis specified has dim 1. + """ + if axis is None: + return arr.squeeze() + + try: + return arr.squeeze(axis=axis) + except ValueError: + return arr + + +# Copied from transformers.models.detr.image_processing_detr.normalize_annotation +def normalize_annotation(annotation: Dict, image_size: Tuple[int, int]) -> Dict: + image_height, image_width = image_size + norm_annotation = {} + for key, value in annotation.items(): + if key == "boxes": + boxes = value + boxes = corners_to_center_format(boxes) + boxes /= np.asarray([image_width, image_height, image_width, image_height], dtype=np.float32) + norm_annotation[key] = boxes + else: + norm_annotation[key] = value + return norm_annotation + + +# Copied from transformers.models.detr.image_processing_detr.max_across_indices +def max_across_indices(values: Iterable[Any]) -> List[Any]: + """ + Return the maximum value across all indices of an iterable of values. + """ + return [max(values_i) for values_i in zip(*values)] + + +# Copied from transformers.models.detr.image_processing_detr.make_pixel_mask +def make_pixel_mask(image: np.ndarray, output_size: Tuple[int, int]) -> np.ndarray: + """ + Make a pixel mask for the image, where 1 indicates a valid pixel and 0 indicates padding. + + Args: + image (`np.ndarray`): + Image to make the pixel mask for. + output_size (`Tuple[int, int]`): + Output size of the mask. + """ + input_height, input_width = get_image_size(image) + mask = np.zeros(output_size, dtype=np.int64) + mask[:input_height, :input_width] = 1 + return mask + + +# Copied from transformers.models.detr.image_processing_detr.convert_coco_poly_to_mask +def convert_coco_poly_to_mask(segmentations, height: int, width: int) -> np.ndarray: + """ + Convert a COCO polygon annotation to a mask. + + Args: + segmentations (`List[List[float]]`): + List of polygons, each polygon represented by a list of x-y coordinates. + height (`int`): + Height of the mask. + width (`int`): + Width of the mask. + """ + try: + from pycocotools import mask as coco_mask + except ImportError: + raise ImportError("Pycocotools is not installed in your environment.") + + masks = [] + for polygons in segmentations: + rles = coco_mask.frPyObjects(polygons, height, width) + mask = coco_mask.decode(rles) + if len(mask.shape) < 3: + mask = mask[..., None] + mask = np.asarray(mask, dtype=np.uint8) + mask = np.any(mask, axis=2) + masks.append(mask) + if masks: + masks = np.stack(masks, axis=0) + else: + masks = np.zeros((0, height, width), dtype=np.uint8) + + return masks + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_detection_annotation +def prepare_coco_detection_annotation(image, target, return_segmentation_masks: bool = False): + """ + Convert the target in COCO format into the format expected by DETR. + """ + image_height, image_width = get_image_size(image) + + image_id = target["image_id"] + image_id = np.asarray([image_id], dtype=np.int64) + + # Get all COCO annotations for the given image. + annotations = target["annotations"] + annotations = [obj for obj in annotations if "iscrowd" not in obj or obj["iscrowd"] == 0] + + classes = [obj["category_id"] for obj in annotations] + classes = np.asarray(classes, dtype=np.int64) + + # for conversion to coco api + area = np.asarray([obj["area"] for obj in annotations], dtype=np.float32) + iscrowd = np.asarray([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in annotations], dtype=np.int64) + + boxes = [obj["bbox"] for obj in annotations] + # guard against no boxes via resizing + boxes = np.asarray(boxes, dtype=np.float32).reshape(-1, 4) + boxes[:, 2:] += boxes[:, :2] + boxes[:, 0::2] = boxes[:, 0::2].clip(min=0, max=image_width) + boxes[:, 1::2] = boxes[:, 1::2].clip(min=0, max=image_height) + + keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0]) + + new_target = {} + new_target["image_id"] = image_id + new_target["class_labels"] = classes[keep] + new_target["boxes"] = boxes[keep] + new_target["area"] = area[keep] + new_target["iscrowd"] = iscrowd[keep] + new_target["orig_size"] = np.asarray([int(image_height), int(image_width)], dtype=np.int64) + + if annotations and "keypoints" in annotations[0]: + keypoints = [obj["keypoints"] for obj in annotations] + keypoints = np.asarray(keypoints, dtype=np.float32) + num_keypoints = keypoints.shape[0] + keypoints = keypoints.reshape((-1, 3)) if num_keypoints else keypoints + new_target["keypoints"] = keypoints[keep] + + if return_segmentation_masks: + segmentation_masks = [obj["segmentation"] for obj in annotations] + masks = convert_coco_poly_to_mask(segmentation_masks, image_height, image_width) + new_target["masks"] = masks[keep] + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.masks_to_boxes +def masks_to_boxes(masks: np.ndarray) -> np.ndarray: + """ + Compute the bounding boxes around the provided panoptic segmentation masks. + + Args: + masks: masks in format `[number_masks, height, width]` where N is the number of masks + + Returns: + boxes: bounding boxes in format `[number_masks, 4]` in xyxy format + """ + if masks.size == 0: + return np.zeros((0, 4)) + + h, w = masks.shape[-2:] + y = np.arange(0, h, dtype=np.float32) + x = np.arange(0, w, dtype=np.float32) + # see https://github.com/pytorch/pytorch/issues/50276 + y, x = np.meshgrid(y, x, indexing="ij") + + x_mask = masks * np.expand_dims(x, axis=0) + x_max = x_mask.reshape(x_mask.shape[0], -1).max(-1) + x = np.ma.array(x_mask, mask=~(np.array(masks, dtype=bool))) + x_min = x.filled(fill_value=1e8) + x_min = x_min.reshape(x_min.shape[0], -1).min(-1) + + y_mask = masks * np.expand_dims(y, axis=0) + y_max = y_mask.reshape(x_mask.shape[0], -1).max(-1) + y = np.ma.array(y_mask, mask=~(np.array(masks, dtype=bool))) + y_min = y.filled(fill_value=1e8) + y_min = y_min.reshape(y_min.shape[0], -1).min(-1) + + return np.stack([x_min, y_min, x_max, y_max], 1) + + +# Copied from transformers.models.detr.image_processing_detr.prepare_coco_panoptic_annotation with DETR->YOLOS +def prepare_coco_panoptic_annotation( + image: np.ndarray, target: Dict, masks_path: Union[str, pathlib.Path], return_masks: bool = True +) -> Dict: + """ + Prepare a coco panoptic annotation for YOLOS. + """ + image_height, image_width = get_image_size(image) + annotation_path = pathlib.Path(masks_path) / target["file_name"] + + new_target = {} + new_target["image_id"] = np.asarray([target["image_id"] if "image_id" in target else target["id"]], dtype=np.int64) + new_target["size"] = np.asarray([image_height, image_width], dtype=np.int64) + new_target["orig_size"] = np.asarray([image_height, image_width], dtype=np.int64) + + if "segments_info" in target: + masks = np.asarray(PIL.Image.open(annotation_path), dtype=np.uint32) + masks = rgb_to_id(masks) + + ids = np.array([segment_info["id"] for segment_info in target["segments_info"]]) + masks = masks == ids[:, None, None] + masks = masks.astype(np.uint8) + if return_masks: + new_target["masks"] = masks + new_target["boxes"] = masks_to_boxes(masks) + new_target["class_labels"] = np.array( + [segment_info["category_id"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["iscrowd"] = np.asarray( + [segment_info["iscrowd"] for segment_info in target["segments_info"]], dtype=np.int64 + ) + new_target["area"] = np.asarray( + [segment_info["area"] for segment_info in target["segments_info"]], dtype=np.float32 + ) + + return new_target + + +# Copied from transformers.models.detr.image_processing_detr.get_segmentation_image +def get_segmentation_image( + masks: np.ndarray, input_size: Tuple, target_size: Tuple, stuff_equiv_classes, deduplicate=False +): + h, w = input_size + final_h, final_w = target_size + + m_id = scipy.special.softmax(masks.transpose(0, 1), -1) + + if m_id.shape[-1] == 0: + # We didn't detect any mask :( + m_id = np.zeros((h, w), dtype=np.int64) + else: + m_id = m_id.argmax(-1).reshape(h, w) + + if deduplicate: + # Merge the masks corresponding to the same stuff class + for equiv in stuff_equiv_classes.values(): + for eq_id in equiv: + m_id[m_id == eq_id] = equiv[0] + + seg_img = id_to_rgb(m_id) + seg_img = resize(seg_img, (final_w, final_h), resample=PILImageResampling.NEAREST) + return seg_img + + +# Copied from transformers.models.detr.image_processing_detr.get_mask_area +def get_mask_area(seg_img: np.ndarray, target_size: Tuple[int, int], n_classes: int) -> np.ndarray: + final_h, final_w = target_size + np_seg_img = seg_img.astype(np.uint8) + np_seg_img = np_seg_img.reshape(final_h, final_w, 3) + m_id = rgb_to_id(np_seg_img) + area = [(m_id == i).sum() for i in range(n_classes)] + return area + + +# Copied from transformers.models.detr.image_processing_detr.score_labels_from_class_probabilities +def score_labels_from_class_probabilities(logits: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + probs = scipy.special.softmax(logits, axis=-1) + labels = probs.argmax(-1, keepdims=True) + scores = np.take_along_axis(probs, labels, axis=-1) + scores, labels = scores.squeeze(-1), labels.squeeze(-1) + return scores, labels + + +# Copied from transformers.models.detr.image_processing_detr.resize_annotation +def resize_annotation( + annotation: Dict[str, Any], + orig_size: Tuple[int, int], + target_size: Tuple[int, int], + threshold: float = 0.5, + resample: PILImageResampling = PILImageResampling.NEAREST, +): + """ + Resizes an annotation to a target size. + + Args: + annotation (`Dict[str, Any]`): + The annotation dictionary. + orig_size (`Tuple[int, int]`): + The original size of the input image. + target_size (`Tuple[int, int]`): + The target size of the image, as returned by the preprocessing `resize` step. + threshold (`float`, *optional*, defaults to 0.5): + The threshold used to binarize the segmentation masks. + resample (`PILImageResampling`, defaults to `PILImageResampling.NEAREST`): + The resampling filter to use when resizing the masks. + """ + ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(target_size, orig_size)) + ratio_height, ratio_width = ratios + + new_annotation = {} + new_annotation["size"] = target_size + + for key, value in annotation.items(): + if key == "boxes": + boxes = value + scaled_boxes = boxes * np.asarray([ratio_width, ratio_height, ratio_width, ratio_height], dtype=np.float32) + new_annotation["boxes"] = scaled_boxes + elif key == "area": + area = value + scaled_area = area * (ratio_width * ratio_height) + new_annotation["area"] = scaled_area + elif key == "masks": + masks = value[:, None] + masks = np.array([resize(mask, target_size, resample=resample) for mask in masks]) + masks = masks.astype(np.float32) + masks = masks[:, 0] > threshold + new_annotation["masks"] = masks + elif key == "size": + new_annotation["size"] = target_size + else: + new_annotation[key] = value + + return new_annotation + + +# Copied from transformers.models.detr.image_processing_detr.binary_mask_to_rle +def binary_mask_to_rle(mask): + """ + Converts given binary mask of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + mask (`torch.Tensor` or `numpy.array`): + A binary mask tensor of shape `(height, width)` where 0 denotes background and 1 denotes the target + segment_id or class_id. + Returns: + `List`: Run-length encoded list of the binary mask. Refer to COCO API for more information about the RLE + format. + """ + if is_torch_tensor(mask): + mask = mask.numpy() + + pixels = mask.flatten() + pixels = np.concatenate([[0], pixels, [0]]) + runs = np.where(pixels[1:] != pixels[:-1])[0] + 1 + runs[1::2] -= runs[::2] + return list(runs) + + +# Copied from transformers.models.detr.image_processing_detr.convert_segmentation_to_rle +def convert_segmentation_to_rle(segmentation): + """ + Converts given segmentation map of shape `(height, width)` to the run-length encoding (RLE) format. + + Args: + segmentation (`torch.Tensor` or `numpy.array`): + A segmentation map of shape `(height, width)` where each value denotes a segment or class id. + Returns: + `List[List]`: A list of lists, where each list is the run-length encoding of a segment / class id. + """ + segment_ids = torch.unique(segmentation) + + run_length_encodings = [] + for idx in segment_ids: + mask = torch.where(segmentation == idx, 1, 0) + rle = binary_mask_to_rle(mask) + run_length_encodings.append(rle) + + return run_length_encodings + + +# Copied from transformers.models.detr.image_processing_detr.remove_low_and_no_objects +def remove_low_and_no_objects(masks, scores, labels, object_mask_threshold, num_labels): + """ + Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and + `labels`. + + Args: + masks (`torch.Tensor`): + A tensor of shape `(num_queries, height, width)`. + scores (`torch.Tensor`): + A tensor of shape `(num_queries)`. + labels (`torch.Tensor`): + A tensor of shape `(num_queries)`. + object_mask_threshold (`float`): + A number between 0 and 1 used to binarize the masks. + Raises: + `ValueError`: Raised when the first dimension doesn't match in all input tensors. + Returns: + `Tuple[`torch.Tensor`, `torch.Tensor`, `torch.Tensor`]`: The `masks`, `scores` and `labels` without the region + < `object_mask_threshold`. + """ + if not (masks.shape[0] == scores.shape[0] == labels.shape[0]): + raise ValueError("mask, scores and labels must have the same shape!") + + to_keep = labels.ne(num_labels) & (scores > object_mask_threshold) + + return masks[to_keep], scores[to_keep], labels[to_keep] + + +# Copied from transformers.models.detr.image_processing_detr.check_segment_validity +def check_segment_validity(mask_labels, mask_probs, k, mask_threshold=0.5, overlap_mask_area_threshold=0.8): + # Get the mask associated with the k class + mask_k = mask_labels == k + mask_k_area = mask_k.sum() + + # Compute the area of all the stuff in query k + original_area = (mask_probs[k] >= mask_threshold).sum() + mask_exists = mask_k_area > 0 and original_area > 0 + + # Eliminate disconnected tiny segments + if mask_exists: + area_ratio = mask_k_area / original_area + if not area_ratio.item() > overlap_mask_area_threshold: + mask_exists = False + + return mask_exists, mask_k + + +# Copied from transformers.models.detr.image_processing_detr.compute_segments +def compute_segments( + mask_probs, + pred_scores, + pred_labels, + mask_threshold: float = 0.5, + overlap_mask_area_threshold: float = 0.8, + label_ids_to_fuse: Optional[Set[int]] = None, + target_size: Tuple[int, int] = None, +): + height = mask_probs.shape[1] if target_size is None else target_size[0] + width = mask_probs.shape[2] if target_size is None else target_size[1] + + segmentation = torch.zeros((height, width), dtype=torch.int32, device=mask_probs.device) + segments: List[Dict] = [] + + if target_size is not None: + mask_probs = nn.functional.interpolate( + mask_probs.unsqueeze(0), size=target_size, mode="bilinear", align_corners=False + )[0] + + current_segment_id = 0 + + # Weigh each mask by its prediction score + mask_probs *= pred_scores.view(-1, 1, 1) + mask_labels = mask_probs.argmax(0) # [height, width] + + # Keep track of instances of each class + stuff_memory_list: Dict[str, int] = {} + for k in range(pred_labels.shape[0]): + pred_class = pred_labels[k].item() + should_fuse = pred_class in label_ids_to_fuse + + # Check if mask exists and large enough to be a segment + mask_exists, mask_k = check_segment_validity( + mask_labels, mask_probs, k, mask_threshold, overlap_mask_area_threshold + ) + + if mask_exists: + if pred_class in stuff_memory_list: + current_segment_id = stuff_memory_list[pred_class] + else: + current_segment_id += 1 + + # Add current object segment to final segmentation map + segmentation[mask_k] = current_segment_id + segment_score = round(pred_scores[k].item(), 6) + segments.append( + { + "id": current_segment_id, + "label_id": pred_class, + "was_fused": should_fuse, + "score": segment_score, + } + ) + if should_fuse: + stuff_memory_list[pred_class] = current_segment_id + + return segmentation, segments + + +class YolosImageProcessor(BaseImageProcessor): + r""" + Constructs a Detr image processor. + + Args: + format (`str`, *optional*, defaults to `"coco_detection"`): + Data format of the annotations. One of "coco_detection" or "coco_panoptic". + do_resize (`bool`, *optional*, defaults to `True`): + Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be + overridden by the `do_resize` parameter in the `preprocess` method. + size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 800, "longest_edge": 1333}`): + Size of the image's (height, width) dimensions after resizing. Can be overridden by the `size` parameter in + the `preprocess` method. + resample (`PILImageResampling`, *optional*, defaults to `PILImageResampling.BILINEAR`): + Resampling filter to use if resizing the image. + do_rescale (`bool`, *optional*, defaults to `True`): + Controls whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by the + `do_rescale` parameter in the `preprocess` method. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. Can be overridden by the `rescale_factor` parameter in the + `preprocess` method. + do_normalize: + Controls whether to normalize the image. Can be overridden by the `do_normalize` parameter in the + `preprocess` method. + image_mean (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_MEAN`): + Mean values to use when normalizing the image. Can be a single value or a list of values, one for each + channel. Can be overridden by the `image_mean` parameter in the `preprocess` method. + image_std (`float` or `List[float]`, *optional*, defaults to `IMAGENET_DEFAULT_STD`): + Standard deviation values to use when normalizing the image. Can be a single value or a list of values, one + for each channel. Can be overridden by the `image_std` parameter in the `preprocess` method. + do_pad (`bool`, *optional*, defaults to `True`): + Controls whether to pad the image to the largest image in a batch and create a pixel mask. Can be + overridden by the `do_pad` parameter in the `preprocess` method. + """ + + model_input_names = ["pixel_values", "pixel_mask"] + + def __init__( + self, + format: Union[str, AnnotionFormat] = AnnotionFormat.COCO_DETECTION, + do_resize: bool = True, + size: Dict[str, int] = None, + resample: PILImageResampling = PILImageResampling.BILINEAR, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Union[float, List[float]] = None, + image_std: Union[float, List[float]] = None, + do_pad: bool = True, + **kwargs, + ) -> None: + if "pad_and_return_pixel_mask" in kwargs: + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None if size is None else 1333 + + size = size if size is not None else {"shortest_edge": 800, "longest_edge": 1333} + size = get_size_dict(size, max_size=max_size, default_to_square=False) + + super().__init__(**kwargs) + self.format = format + self.do_resize = do_resize + self.size = size + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN + self.image_std = image_std if image_std is not None else IMAGENET_DEFAULT_STD + self.do_pad = do_pad + + @property + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.max_size + def max_size(self): + logger.warning( + "The `max_size` parameter is deprecated and will be removed in v4.27. " + "Please specify in `size['longest_edge'] instead`.", + ) + return self.size["longest_edge"] + + @classmethod + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.from_dict with Detr->Yolos + def from_dict(cls, image_processor_dict: Dict[str, Any], **kwargs): + """ + Overrides the `from_dict` method from the base class to make sure parameters are updated if image processor is + created using from_dict and kwargs e.g. `YolosImageProcessor.from_pretrained(checkpoint, size=600, + max_size=800)` + """ + image_processor_dict = image_processor_dict.copy() + if "max_size" in kwargs: + image_processor_dict["max_size"] = kwargs.pop("max_size") + if "pad_and_return_pixel_mask" in kwargs: + image_processor_dict["pad_and_return_pixel_mask"] = kwargs.pop("pad_and_return_pixel_mask") + return super().from_dict(image_processor_dict, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_annotation + def prepare_annotation( + self, + image: np.ndarray, + target: Dict, + format: Optional[AnnotionFormat] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + ) -> Dict: + """ + Prepare an annotation for feeding into DETR model. + """ + format = format if format is not None else self.format + + if format == AnnotionFormat.COCO_DETECTION: + return_segmentation_masks = False if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_detection_annotation(image, target, return_segmentation_masks) + elif format == AnnotionFormat.COCO_PANOPTIC: + return_segmentation_masks = True if return_segmentation_masks is None else return_segmentation_masks + target = prepare_coco_panoptic_annotation( + image, target, masks_path=masks_path, return_masks=return_segmentation_masks + ) + else: + raise ValueError(f"Format {format} is not supported.") + return target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare + def prepare(self, image, target, return_segmentation_masks=False, masks_path=None): + logger.warning_once( + "The `prepare` method is deprecated and will be removed in a future version. " + "Please use `prepare_annotation` instead. Note: the `prepare_annotation` method " + "does not return the image anymore.", + ) + target = self.prepare_annotation(image, target, return_segmentation_masks, masks_path, self.format) + return image, target + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.convert_coco_poly_to_mask + def convert_coco_poly_to_mask(self, *args, **kwargs): + logger.warning_once( + "The `convert_coco_poly_to_mask` method is deprecated and will be removed in a future version. " + ) + return convert_coco_poly_to_mask(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_detection with DETR->Yolos + def prepare_coco_detection(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_detection` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_detection_annotation(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.prepare_coco_panoptic + def prepare_coco_panoptic(self, *args, **kwargs): + logger.warning_once( + "The `prepare_coco_panoptic` method is deprecated and will be removed in a future version. " + ) + return prepare_coco_panoptic_annotation(*args, **kwargs) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.resize + def resize( + self, + image: np.ndarray, + size: Dict[str, int], + resample: PILImageResampling = PILImageResampling.BILINEAR, + data_format: Optional[ChannelDimension] = None, + **kwargs, + ) -> np.ndarray: + """ + Resize the image to the given size. Size can be `min_size` (scalar) or `(height, width)` tuple. If size is an + int, smaller edge of the image will be matched to this number. + """ + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` parameter is deprecated and will be removed in v4.26. " + "Please specify in `size['longest_edge'] instead`.", + ) + max_size = kwargs.pop("max_size") + else: + max_size = None + size = get_size_dict(size, max_size=max_size, default_to_square=False) + if "shortest_edge" in size and "longest_edge" in size: + size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"]) + elif "height" in size and "width" in size: + size = (size["height"], size["width"]) + else: + raise ValueError( + "Size must contain 'height' and 'width' keys or 'shortest_edge' and 'longest_edge' keys. Got" + f" {size.keys()}." + ) + image = resize(image, size=size, resample=resample, data_format=data_format) + return image + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.resize_annotation + def resize_annotation( + self, + annotation, + orig_size, + size, + resample: PILImageResampling = PILImageResampling.NEAREST, + ) -> Dict: + """ + Resize the annotation to match the resized image. If size is an int, smaller edge of the mask will be matched + to this number. + """ + return resize_annotation(annotation, orig_size=orig_size, target_size=size, resample=resample) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.rescale + def rescale( + self, image: np.ndarray, rescale_factor: Union[float, int], data_format: Optional[ChannelDimension] = None + ) -> np.ndarray: + """ + Rescale the image by the given factor. + """ + return rescale(image, rescale_factor, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize + def normalize( + self, + image: np.ndarray, + mean: Union[float, Iterable[float]], + std: Union[float, Iterable[float]], + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Normalize the image with the given mean and standard deviation. + """ + return normalize(image, mean=mean, std=std, data_format=data_format) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.normalize_annotation + def normalize_annotation(self, annotation: Dict, image_size: Tuple[int, int]) -> Dict: + """ + Normalize the boxes in the annotation from `[top_left_x, top_left_y, bottom_right_x, bottom_right_y]` to + `[center_x, center_y, width, height]` format. + """ + return normalize_annotation(annotation, image_size=image_size) + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor._pad_image + def _pad_image( + self, + image: np.ndarray, + output_size: Tuple[int, int], + constant_values: Union[float, Iterable[float]] = 0, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pad an image with zeros to the given size. + """ + input_height, input_width = get_image_size(image) + output_height, output_width = output_size + + pad_bottom = output_height - input_height + pad_right = output_width - input_width + padding = ((0, pad_bottom), (0, pad_right)) + padded_image = pad( + image, padding, mode=PaddingMode.CONSTANT, constant_values=constant_values, data_format=data_format + ) + return padded_image + + def pad( + self, + images: List[np.ndarray], + return_pixel_mask: bool = False, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = None, + ) -> np.ndarray: + """ + Pads a batch of images to the bottom and right of the image with zeros to the size of largest height and width + in the batch and optionally returns their corresponding pixel mask. + + Args: + image (`np.ndarray`): + Image to pad. + return_pixel_mask (`bool`, *optional*, defaults to `True`): + Whether to return a pixel mask. + input_channel_dimension (`ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be inferred from the input image. + data_format (`str` or `ChannelDimension`, *optional*): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + pad_size = get_max_height_width(images) + + padded_images = [self._pad_image(image, pad_size, data_format=data_format) for image in images] + data = {"pixel_values": padded_images} + + if return_pixel_mask: + masks = [make_pixel_mask(image=image, output_size=pad_size) for image in images] + data["pixel_mask"] = masks + + return BatchFeature(data=data, tensor_type=return_tensors) + + def preprocess( + self, + images: ImageInput, + annotations: Optional[Union[AnnotationType, List[AnnotationType]]] = None, + return_segmentation_masks: bool = None, + masks_path: Optional[Union[str, pathlib.Path]] = None, + do_resize: Optional[bool] = None, + size: Optional[Dict[str, int]] = None, + resample=None, # PILImageResampling + do_rescale: Optional[bool] = None, + rescale_factor: Optional[Union[int, float]] = None, + do_normalize: Optional[bool] = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_pad: Optional[bool] = None, + format: Optional[Union[str, AnnotionFormat]] = None, + return_tensors: Optional[Union[TensorType, str]] = None, + data_format: Union[str, ChannelDimension] = ChannelDimension.FIRST, + **kwargs, + ) -> BatchFeature: + """ + Preprocess an image or a batch of images so that it can be used by the model. + + Args: + images (`ImageInput`): + Image or batch of images to preprocess. + annotations (`AnnotationType` or `List[AnnotationType]`, *optional*): + List of annotations associated with the image or batch of images. If annotionation is for object + detection, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "annotations" (`List[Dict]`): List of annotations for an image. Each annotation should be a + dictionary. An image can have no annotations, in which case the list should be empty. + If annotionation is for segmentation, the annotations should be a dictionary with the following keys: + - "image_id" (`int`): The image id. + - "segments_info" (`List[Dict]`): List of segments for an image. Each segment should be a dictionary. + An image can have no segments, in which case the list should be empty. + - "file_name" (`str`): The file name of the image. + return_segmentation_masks (`bool`, *optional*, defaults to self.return_segmentation_masks): + Whether to return segmentation masks. + masks_path (`str` or `pathlib.Path`, *optional*): + Path to the directory containing the segmentation masks. + do_resize (`bool`, *optional*, defaults to self.do_resize): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to self.size): + Size of the image after resizing. + resample (`PILImageResampling`, *optional*, defaults to self.resample): + Resampling filter to use when resizing the image. + do_rescale (`bool`, *optional*, defaults to self.do_rescale): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to self.rescale_factor): + Rescale factor to use when rescaling the image. + do_normalize (`bool`, *optional*, defaults to self.do_normalize): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to self.image_mean): + Mean to use when normalizing the image. + image_std (`float` or `List[float]`, *optional*, defaults to self.image_std): + Standard deviation to use when normalizing the image. + do_pad (`bool`, *optional*, defaults to self.do_pad): + Whether to pad the image. + format (`str` or `AnnotionFormat`, *optional*, defaults to self.format): + Format of the annotations. + return_tensors (`str` or `TensorType`, *optional*, defaults to self.return_tensors): + Type of tensors to return. If `None`, will return the list of images. + data_format (`str` or `ChannelDimension`, *optional*, defaults to self.data_format): + The channel dimension format of the image. If not provided, it will be the same as the input image. + """ + if "pad_and_return_pixel_mask" in kwargs: + logger.warning_once( + "The `pad_and_return_pixel_mask` argument is deprecated and will be removed in a future version, " + "use `do_pad` instead.", + ) + do_pad = kwargs.pop("pad_and_return_pixel_mask") + + max_size = None + if "max_size" in kwargs: + logger.warning_once( + "The `max_size` argument is deprecated and will be removed in a future version, use" + " `size['longest_edge']` instead.", + ) + size = kwargs.pop("max_size") + + do_resize = self.do_resize if do_resize is None else do_resize + size = self.size if size is None else size + size = get_size_dict(size=size, max_size=max_size, default_to_square=False) + resample = self.resample if resample is None else resample + do_rescale = self.do_rescale if do_rescale is None else do_rescale + rescale_factor = self.rescale_factor if rescale_factor is None else rescale_factor + do_normalize = self.do_normalize if do_normalize is None else do_normalize + image_mean = self.image_mean if image_mean is None else image_mean + image_std = self.image_std if image_std is None else image_std + do_pad = self.do_pad if do_pad is None else do_pad + format = self.format if format is None else format + + if do_resize is not None and size is None: + raise ValueError("Size and max_size must be specified if do_resize is True.") + + if do_rescale is not None and rescale_factor is None: + raise ValueError("Rescale factor must be specified if do_rescale is True.") + + if do_normalize is not None and (image_mean is None or image_std is None): + raise ValueError("Image mean and std must be specified if do_normalize is True.") + + images = make_list_of_images(images) + if annotations is not None and isinstance(annotations, dict): + annotations = [annotations] + + if annotations is not None and len(images) != len(annotations): + raise ValueError( + f"The number of images ({len(images)}) and annotations ({len(annotations)}) do not match." + ) + + if not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + format = AnnotionFormat(format) + if annotations is not None: + if format == AnnotionFormat.COCO_DETECTION and not valid_coco_detection_annotations(annotations): + raise ValueError( + "Invalid COCO detection annotations. Annotations must a dict (single image) of list of dicts" + "(batch of images) with the following keys: `image_id` and `annotations`, with the latter " + "being a list of annotations in the COCO format." + ) + elif format == AnnotionFormat.COCO_PANOPTIC and not valid_coco_panoptic_annotations(annotations): + raise ValueError( + "Invalid COCO panoptic annotations. Annotations must a dict (single image) of list of dicts " + "(batch of images) with the following keys: `image_id`, `file_name` and `segments_info`, with " + "the latter being a list of annotations in the COCO format." + ) + elif format not in SUPPORTED_ANNOTATION_FORMATS: + raise ValueError( + f"Unsupported annotation format: {format} must be one of {SUPPORTED_ANNOTATION_FORMATS}" + ) + + if ( + masks_path is not None + and format == AnnotionFormat.COCO_PANOPTIC + and not isinstance(masks_path, (pathlib.Path, str)) + ): + raise ValueError( + "The path to the directory containing the mask PNG files should be provided as a" + f" `pathlib.Path` or string object, but is {type(masks_path)} instead." + ) + + # All transformations expect numpy arrays + images = [to_numpy_array(image) for image in images] + + # prepare (COCO annotations as a list of Dict -> DETR target as a single Dict per image) + if annotations is not None: + prepared_images = [] + prepared_annotations = [] + for image, target in zip(images, annotations): + target = self.prepare_annotation( + image, target, format, return_segmentation_masks=return_segmentation_masks, masks_path=masks_path + ) + prepared_images.append(image) + prepared_annotations.append(target) + images = prepared_images + annotations = prepared_annotations + del prepared_images, prepared_annotations + + # transformations + if do_resize: + if annotations is not None: + resized_images, resized_annotations = [], [] + for image, target in zip(images, annotations): + orig_size = get_image_size(image) + resized_image = self.resize(image, size=size, max_size=max_size, resample=resample) + resized_annotation = self.resize_annotation(target, orig_size, get_image_size(resized_image)) + resized_images.append(resized_image) + resized_annotations.append(resized_annotation) + images = resized_images + annotations = resized_annotations + del resized_images, resized_annotations + else: + images = [self.resize(image, size=size, resample=resample) for image in images] + + if do_rescale: + images = [self.rescale(image, rescale_factor) for image in images] + + if do_normalize: + images = [self.normalize(image, image_mean, image_std) for image in images] + if annotations is not None: + annotations = [ + self.normalize_annotation(annotation, get_image_size(image)) + for annotation, image in zip(annotations, images) + ] + + if do_pad: + data = self.pad(images, data_format=data_format) + else: + images = [to_channel_dimension_format(image, data_format) for image in images] + data = {"pixel_values": images} + + encoded_inputs = BatchFeature(data=data, tensor_type=return_tensors) + if annotations is not None: + encoded_inputs["labels"] = [ + BatchFeature(annotation, tensor_type=return_tensors) for annotation in annotations + ] + + return encoded_inputs + + # POSTPROCESSING METHODS - TODO: add support for other frameworks + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.post_process with Detr->Yolos + def post_process(self, outputs, target_sizes): + """ + Converts the raw output of [`YolosForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, + bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`YolosObjectDetectionOutput`]): + Raw outputs of the model. + target_sizes (`torch.Tensor` of shape `(batch_size, 2)`): + Tensor containing the size (height, width) of each image of the batch. For evaluation, this must be the + original image size (before any data augmentation). For visualization, this should be the image size + after data augment, but before padding. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + logger.warning_once( + "`post_process` is deprecated and will be removed in v5 of Transformers, please use" + " `post_process_object_detection`", + ) + + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if len(out_logits) != len(target_sizes): + raise ValueError("Make sure that you pass in as many target sizes as the batch dimension of the logits") + if target_sizes.shape[1] != 2: + raise ValueError("Each element of target_sizes must contain the size (h, w) of each image of the batch") + + prob = nn.functional.softmax(out_logits, -1) + scores, labels = prob[..., :-1].max(-1) + + # convert to [x0, y0, x1, y1] format + boxes = center_to_corners_format(out_bbox) + # and from relative [0, 1] to absolute [0, height] coordinates + img_h, img_w = target_sizes.unbind(1) + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [{"scores": s, "labels": l, "boxes": b} for s, l, b in zip(scores, labels, boxes)] + return results + + # Copied from transformers.models.detr.image_processing_detr.DetrImageProcessor.post_process_object_detection with Detr->Yolos + def post_process_object_detection( + self, outputs, threshold: float = 0.5, target_sizes: Union[TensorType, List[Tuple]] = None + ): + """ + Converts the raw output of [`YolosForObjectDetection`] into final bounding boxes in (top_left_x, top_left_y, + bottom_right_x, bottom_right_y) format. Only supports PyTorch. + + Args: + outputs ([`YolosObjectDetectionOutput`]): + Raw outputs of the model. + threshold (`float`, *optional*): + Score threshold to keep object detection predictions. + target_sizes (`torch.Tensor` or `List[Tuple[int, int]]`, *optional*): + Tensor of shape `(batch_size, 2)` or list of tuples (`Tuple[int, int]`) containing the target size + `(height, width)` of each image in the batch. If unset, predictions will not be resized. + Returns: + `List[Dict]`: A list of dictionaries, each dictionary containing the scores, labels and boxes for an image + in the batch as predicted by the model. + """ + out_logits, out_bbox = outputs.logits, outputs.pred_boxes + + if target_sizes is not None: + if len(out_logits) != len(target_sizes): + raise ValueError( + "Make sure that you pass in as many target sizes as the batch dimension of the logits" + ) + + prob = nn.functional.softmax(out_logits, -1) + scores, labels = prob[..., :-1].max(-1) + + # Convert to [x0, y0, x1, y1] format + boxes = center_to_corners_format(out_bbox) + + # Convert from relative [0, 1] to absolute [0, height] coordinates + if target_sizes is not None: + if isinstance(target_sizes, List): + img_h = torch.Tensor([i[0] for i in target_sizes]) + img_w = torch.Tensor([i[1] for i in target_sizes]) + else: + img_h, img_w = target_sizes.unbind(1) + + scale_fct = torch.stack([img_w, img_h, img_w, img_h], dim=1).to(boxes.device) + boxes = boxes * scale_fct[:, None, :] + + results = [] + for s, l, b in zip(scores, labels, boxes): + score = s[s > threshold] + label = l[s > threshold] + box = b[s > threshold] + results.append({"scores": score, "labels": label, "boxes": box}) + + return results diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/modeling_yolos.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/modeling_yolos.py new file mode 100644 index 0000000000000000000000000000000000000000..e3cb02ceae6ec09621638e2940d70412b4494ceb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yolos/modeling_yolos.py @@ -0,0 +1,1329 @@ +# coding=utf-8 +# Copyright 2022 School of EIC, Huazhong University of Science & Technology and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch YOLOS model.""" + + +import collections.abc +import math +from dataclasses import dataclass +from typing import Dict, List, Optional, Set, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import Tensor, nn + +from ...activations import ACT2FN +from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import ( + ModelOutput, + add_code_sample_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + is_scipy_available, + is_vision_available, + logging, + replace_return_docstrings, + requires_backends, +) +from .configuration_yolos import YolosConfig + + +if is_scipy_available(): + from scipy.optimize import linear_sum_assignment + +if is_vision_available(): + from transformers.image_transforms import center_to_corners_format + + +logger = logging.get_logger(__name__) + +# General docstring +_CONFIG_FOR_DOC = "YolosConfig" + +# Base docstring +_CHECKPOINT_FOR_DOC = "hustvl/yolos-small" +_EXPECTED_OUTPUT_SHAPE = [1, 3401, 384] + + +YOLOS_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "hustvl/yolos-small", + # See all YOLOS models at https://huggingface.co/models?filter=yolos +] + + +@dataclass +class YolosObjectDetectionOutput(ModelOutput): + """ + Output type of [`YolosForObjectDetection`]. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` are provided)): + Total loss as a linear combination of a negative log-likehood (cross-entropy) for class prediction and a + bounding box loss. The latter is defined as a linear combination of the L1 loss and the generalized + scale-invariant IoU loss. + loss_dict (`Dict`, *optional*): + A dictionary containing the individual losses. Useful for logging. + logits (`torch.FloatTensor` of shape `(batch_size, num_queries, num_classes + 1)`): + Classification logits (including no-object) for all queries. + pred_boxes (`torch.FloatTensor` of shape `(batch_size, num_queries, 4)`): + Normalized boxes coordinates for all queries, represented as (center_x, center_y, width, height). These + values are normalized in [0, 1], relative to the size of each individual image in the batch (disregarding + possible padding). You can use [`~YolosImageProcessor.post_process`] to retrieve the unnormalized bounding + boxes. + auxiliary_outputs (`list[Dict]`, *optional*): + Optional, only returned when auxilary losses are activated (i.e. `config.auxiliary_loss` is set to `True`) + and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and + `pred_boxes`) for each decoder layer. + last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Sequence of hidden-states at the output of the last layer of the decoder of the model. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. Hidden-states of + the model at the output of each layer plus the optional initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. Attentions weights after the attention softmax, used to compute the weighted average in + the self-attention heads. + """ + + loss: Optional[torch.FloatTensor] = None + loss_dict: Optional[Dict] = None + logits: torch.FloatTensor = None + pred_boxes: torch.FloatTensor = None + auxiliary_outputs: Optional[List[Dict]] = None + last_hidden_state: Optional[torch.FloatTensor] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + + +class YolosEmbeddings(nn.Module): + """ + Construct the CLS token, detection tokens, position and patch embeddings. + + """ + + def __init__(self, config: YolosConfig) -> None: + super().__init__() + + self.cls_token = nn.Parameter(torch.zeros(1, 1, config.hidden_size)) + self.detection_tokens = nn.Parameter(torch.zeros(1, config.num_detection_tokens, config.hidden_size)) + self.patch_embeddings = YolosPatchEmbeddings(config) + num_patches = self.patch_embeddings.num_patches + self.position_embeddings = nn.Parameter( + torch.zeros(1, num_patches + config.num_detection_tokens + 1, config.hidden_size) + ) + + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.interpolation = InterpolateInitialPositionEmbeddings(config) + self.config = config + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + embeddings = self.patch_embeddings(pixel_values) + + batch_size, seq_len, _ = embeddings.size() + + # add the [CLS] and detection tokens to the embedded patch tokens + cls_tokens = self.cls_token.expand(batch_size, -1, -1) + detection_tokens = self.detection_tokens.expand(batch_size, -1, -1) + embeddings = torch.cat((cls_tokens, embeddings, detection_tokens), dim=1) + + # add positional encoding to each token + # this might require interpolation of the existing position embeddings + position_embeddings = self.interpolation(self.position_embeddings, (height, width)) + + embeddings = embeddings + position_embeddings + + embeddings = self.dropout(embeddings) + + return embeddings + + +class InterpolateInitialPositionEmbeddings(nn.Module): + def __init__(self, config) -> None: + super().__init__() + self.config = config + + def forward(self, pos_embed, img_size=(800, 1344)) -> torch.Tensor: + cls_pos_embed = pos_embed[:, 0, :] + cls_pos_embed = cls_pos_embed[:, None] + det_pos_embed = pos_embed[:, -self.config.num_detection_tokens :, :] + patch_pos_embed = pos_embed[:, 1 : -self.config.num_detection_tokens, :] + patch_pos_embed = patch_pos_embed.transpose(1, 2) + batch_size, hidden_size, seq_len = patch_pos_embed.shape + + patch_height, patch_width = ( + self.config.image_size[0] // self.config.patch_size, + self.config.image_size[1] // self.config.patch_size, + ) + patch_pos_embed = patch_pos_embed.view(batch_size, hidden_size, patch_height, patch_width) + + height, width = img_size + new_patch_heigth, new_patch_width = height // self.config.patch_size, width // self.config.patch_size + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, size=(new_patch_heigth, new_patch_width), mode="bicubic", align_corners=False + ) + patch_pos_embed = patch_pos_embed.flatten(2).transpose(1, 2) + scale_pos_embed = torch.cat((cls_pos_embed, patch_pos_embed, det_pos_embed), dim=1) + return scale_pos_embed + + +class InterpolateMidPositionEmbeddings(nn.Module): + def __init__(self, config) -> None: + super().__init__() + self.config = config + + def forward(self, pos_embed, img_size=(800, 1344)) -> torch.Tensor: + cls_pos_embed = pos_embed[:, :, 0, :] + cls_pos_embed = cls_pos_embed[:, None] + det_pos_embed = pos_embed[:, :, -self.config.num_detection_tokens :, :] + patch_pos_embed = pos_embed[:, :, 1 : -self.config.num_detection_tokens, :] + patch_pos_embed = patch_pos_embed.transpose(2, 3) + depth, batch_size, hidden_size, seq_len = patch_pos_embed.shape + + patch_height, patch_width = ( + self.config.image_size[0] // self.config.patch_size, + self.config.image_size[1] // self.config.patch_size, + ) + patch_pos_embed = patch_pos_embed.view(depth * batch_size, hidden_size, patch_height, patch_width) + height, width = img_size + new_patch_height, new_patch_width = height // self.config.patch_size, width // self.config.patch_size + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, size=(new_patch_height, new_patch_width), mode="bicubic", align_corners=False + ) + patch_pos_embed = ( + patch_pos_embed.flatten(2) + .transpose(1, 2) + .contiguous() + .view(depth, batch_size, new_patch_height * new_patch_width, hidden_size) + ) + scale_pos_embed = torch.cat((cls_pos_embed, patch_pos_embed, det_pos_embed), dim=2) + return scale_pos_embed + + +class YolosPatchEmbeddings(nn.Module): + """ + This class turns `pixel_values` of shape `(batch_size, num_channels, height, width)` into the initial + `hidden_states` (patch embeddings) of shape `(batch_size, seq_length, hidden_size)` to be consumed by a + Transformer. + """ + + def __init__(self, config): + super().__init__() + image_size, patch_size = config.image_size, config.patch_size + num_channels, hidden_size = config.num_channels, config.hidden_size + + image_size = image_size if isinstance(image_size, collections.abc.Iterable) else (image_size, image_size) + patch_size = patch_size if isinstance(patch_size, collections.abc.Iterable) else (patch_size, patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.num_patches = num_patches + + self.projection = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) + + def forward(self, pixel_values: torch.Tensor) -> torch.Tensor: + batch_size, num_channels, height, width = pixel_values.shape + if num_channels != self.num_channels: + raise ValueError( + "Make sure that the channel dimension of the pixel values match with the one set in the configuration." + ) + + embeddings = self.projection(pixel_values).flatten(2).transpose(1, 2) + return embeddings + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfAttention with ViT->Yolos +class YolosSelfAttention(nn.Module): + def __init__(self, config: YolosConfig) -> None: + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size {config.hidden_size,} is not a multiple of the number of attention " + f"heads {config.num_attention_heads}." + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.key = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + self.value = nn.Linear(config.hidden_size, self.all_head_size, bias=config.qkv_bias) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + + def transpose_for_scores(self, x: torch.Tensor) -> torch.Tensor: + new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + x = x.view(new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward( + self, hidden_states, head_mask: Optional[torch.Tensor] = None, output_attentions: bool = False + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + # Take the dot product between "query" and "key" to get the raw attention scores. + attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2)) + + attention_scores = attention_scores / math.sqrt(self.attention_head_size) + + # Normalize the attention scores to probabilities. + attention_probs = nn.functional.softmax(attention_scores, dim=-1) + + # This is actually dropping out entire tokens to attend to, which might + # seem a bit unusual, but is taken from the original Transformer paper. + attention_probs = self.dropout(attention_probs) + + # Mask heads if we want to + if head_mask is not None: + attention_probs = attention_probs * head_mask + + context_layer = torch.matmul(attention_probs, value_layer) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(new_context_layer_shape) + + outputs = (context_layer, attention_probs) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTSelfOutput with ViT->Yolos +class YolosSelfOutput(nn.Module): + """ + The residual connection is defined in YolosLayer instead of here (as is the case with other models), due to the + layernorm applied before each block. + """ + + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTAttention with ViT->Yolos +class YolosAttention(nn.Module): + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.attention = YolosSelfAttention(config) + self.output = YolosSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads: Set[int]) -> None: + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.attention.num_attention_heads, self.attention.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.attention.query = prune_linear_layer(self.attention.query, index) + self.attention.key = prune_linear_layer(self.attention.key, index) + self.attention.value = prune_linear_layer(self.attention.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.attention.num_attention_heads = self.attention.num_attention_heads - len(heads) + self.attention.all_head_size = self.attention.attention_head_size * self.attention.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_outputs = self.attention(hidden_states, head_mask, output_attentions) + + attention_output = self.output(self_outputs[0], hidden_states) + + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.vit.modeling_vit.ViTIntermediate with ViT->Yolos +class YolosIntermediate(nn.Module): + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTOutput with ViT->Yolos +class YolosOutput(nn.Module): + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + + hidden_states = hidden_states + input_tensor + + return hidden_states + + +# Copied from transformers.models.vit.modeling_vit.ViTLayer with ViT->Yolos +class YolosLayer(nn.Module): + """This corresponds to the Block class in the timm implementation.""" + + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = YolosAttention(config) + self.intermediate = YolosIntermediate(config) + self.output = YolosOutput(config) + self.layernorm_before = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.layernorm_after = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward( + self, + hidden_states: torch.Tensor, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + ) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor]]: + self_attention_outputs = self.attention( + self.layernorm_before(hidden_states), # in Yolos, layernorm is applied before self-attention + head_mask, + output_attentions=output_attentions, + ) + attention_output = self_attention_outputs[0] + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + # first residual connection + hidden_states = attention_output + hidden_states + + # in Yolos, layernorm is also applied after self-attention + layer_output = self.layernorm_after(hidden_states) + layer_output = self.intermediate(layer_output) + + # second residual connection is done here + layer_output = self.output(layer_output, hidden_states) + + outputs = (layer_output,) + outputs + + return outputs + + +class YolosEncoder(nn.Module): + def __init__(self, config: YolosConfig) -> None: + super().__init__() + self.config = config + self.layer = nn.ModuleList([YolosLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + seq_length = ( + 1 + (config.image_size[0] * config.image_size[1] // config.patch_size**2) + config.num_detection_tokens + ) + self.mid_position_embeddings = ( + nn.Parameter( + torch.zeros( + config.num_hidden_layers - 1, + 1, + seq_length, + config.hidden_size, + ) + ) + if config.use_mid_position_embeddings + else None + ) + + self.interpolation = InterpolateMidPositionEmbeddings(config) if config.use_mid_position_embeddings else None + + def forward( + self, + hidden_states: torch.Tensor, + height, + width, + head_mask: Optional[torch.Tensor] = None, + output_attentions: bool = False, + output_hidden_states: bool = False, + return_dict: bool = True, + ) -> Union[tuple, BaseModelOutput]: + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + if self.config.use_mid_position_embeddings: + interpolated_mid_position_embeddings = self.interpolation(self.mid_position_embeddings, (height, width)) + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + layer_head_mask = head_mask[i] if head_mask is not None else None + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + layer_head_mask, + ) + else: + layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions) + + hidden_states = layer_outputs[0] + + if self.config.use_mid_position_embeddings: + if i < (self.config.num_hidden_layers - 1): + hidden_states = hidden_states + interpolated_mid_position_embeddings[i] + + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +class YolosPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = YolosConfig + base_model_prefix = "vit" + main_input_name = "pixel_values" + supports_gradient_checkpointing = True + + def _init_weights(self, module: Union[nn.Linear, nn.Conv2d, nn.LayerNorm]) -> None: + """Initialize the weights""" + if isinstance(module, (nn.Linear, nn.Conv2d)): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module: YolosEncoder, value: bool = False) -> None: + if isinstance(module, YolosEncoder): + module.gradient_checkpointing = value + + +YOLOS_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it + as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`YolosConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +YOLOS_INPUTS_DOCSTRING = r""" + Args: + pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`): + Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See + [`YolosImageProcessor.__call__`] for details. + + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare YOLOS Model transformer outputting raw hidden-states without any specific head on top.", + YOLOS_START_DOCSTRING, +) +class YolosModel(YolosPreTrainedModel): + def __init__(self, config: YolosConfig, add_pooling_layer: bool = True): + super().__init__(config) + self.config = config + + self.embeddings = YolosEmbeddings(config) + self.encoder = YolosEncoder(config) + + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.pooler = YolosPooler(config) if add_pooling_layer else None + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> YolosPatchEmbeddings: + return self.embeddings.patch_embeddings + + def _prune_heads(self, heads_to_prune: Dict[int, List[int]]) -> None: + """ + Prunes heads of the model. + + Args: + heads_to_prune (`dict` of {layer_num: list of heads to prune in this layer}): + See base class `PreTrainedModel`. + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(YOLOS_INPUTS_DOCSTRING) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithPooling, + config_class=_CONFIG_FOR_DOC, + modality="vision", + expected_output=_EXPECTED_OUTPUT_SHAPE, + ) + def forward( + self, + pixel_values: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithPooling]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings(pixel_values) + + encoder_outputs = self.encoder( + embedding_output, + height=pixel_values.shape[-2], + width=pixel_values.shape[-1], + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + sequence_output = self.layernorm(sequence_output) + pooled_output = self.pooler(sequence_output) if self.pooler is not None else None + + if not return_dict: + head_outputs = (sequence_output, pooled_output) if pooled_output is not None else (sequence_output,) + return head_outputs + encoder_outputs[1:] + + return BaseModelOutputWithPooling( + last_hidden_state=sequence_output, + pooler_output=pooled_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class YolosPooler(nn.Module): + def __init__(self, config: YolosConfig): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.activation = nn.Tanh() + + def forward(self, hidden_states): + # We "pool" the model by simply taking the hidden state corresponding + # to the first token. + first_token_tensor = hidden_states[:, 0] + pooled_output = self.dense(first_token_tensor) + pooled_output = self.activation(pooled_output) + return pooled_output + + +@add_start_docstrings( + """ + YOLOS Model (consisting of a ViT encoder) with object detection heads on top, for tasks such as COCO detection. + """, + YOLOS_START_DOCSTRING, +) +class YolosForObjectDetection(YolosPreTrainedModel): + def __init__(self, config: YolosConfig): + super().__init__(config) + + # YOLOS (ViT) encoder model + self.vit = YolosModel(config, add_pooling_layer=False) + + # Object detection heads + # We add one for the "no object" class + self.class_labels_classifier = YolosMLPPredictionHead( + input_dim=config.hidden_size, hidden_dim=config.hidden_size, output_dim=config.num_labels + 1, num_layers=3 + ) + self.bbox_predictor = YolosMLPPredictionHead( + input_dim=config.hidden_size, hidden_dim=config.hidden_size, output_dim=4, num_layers=3 + ) + + # Initialize weights and apply final processing + self.post_init() + + # taken from https://github.com/facebookresearch/detr/blob/master/models/detr.py + @torch.jit.unused + def _set_aux_loss(self, outputs_class, outputs_coord): + # this is a workaround to make torchscript happy, as torchscript + # doesn't support dictionary with non-homogeneous values, such + # as a dict having both a Tensor and a list. + return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])] + + @add_start_docstrings_to_model_forward(YOLOS_INPUTS_DOCSTRING) + @replace_return_docstrings(output_type=YolosObjectDetectionOutput, config_class=_CONFIG_FOR_DOC) + def forward( + self, + pixel_values: torch.FloatTensor, + labels: Optional[List[Dict]] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, YolosObjectDetectionOutput]: + r""" + labels (`List[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the + following 2 keys: `'class_labels'` and `'boxes'` (the class labels and bounding boxes of an image in the + batch respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding + boxes in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, + 4)`. + + Returns: + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, AutoModelForObjectDetection + >>> import torch + >>> from PIL import Image + >>> import requests + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> image = Image.open(requests.get(url, stream=True).raw) + + >>> image_processor = AutoImageProcessor.from_pretrained("hustvl/yolos-tiny") + >>> model = AutoModelForObjectDetection.from_pretrained("hustvl/yolos-tiny") + + >>> inputs = image_processor(images=image, return_tensors="pt") + >>> outputs = model(**inputs) + + >>> # convert outputs (bounding boxes and class logits) to COCO API + >>> target_sizes = torch.tensor([image.size[::-1]]) + >>> results = image_processor.post_process_object_detection(outputs, threshold=0.9, target_sizes=target_sizes)[ + ... 0 + ... ] + + >>> for score, label, box in zip(results["scores"], results["labels"], results["boxes"]): + ... box = [round(i, 2) for i in box.tolist()] + ... print( + ... f"Detected {model.config.id2label[label.item()]} with confidence " + ... f"{round(score.item(), 3)} at location {box}" + ... ) + Detected remote with confidence 0.994 at location [46.96, 72.61, 181.02, 119.73] + Detected remote with confidence 0.975 at location [340.66, 79.19, 372.59, 192.65] + Detected cat with confidence 0.984 at location [12.27, 54.25, 319.42, 470.99] + Detected remote with confidence 0.922 at location [41.66, 71.96, 178.7, 120.33] + Detected cat with confidence 0.914 at location [342.34, 21.48, 638.64, 372.46] + ```""" + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + # First, sent images through YOLOS base model to obtain hidden states + outputs = self.vit( + pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + # Take the final hidden states of the detection tokens + sequence_output = sequence_output[:, -self.config.num_detection_tokens :, :] + + # Class logits + predicted bounding boxes + logits = self.class_labels_classifier(sequence_output) + pred_boxes = self.bbox_predictor(sequence_output).sigmoid() + + loss, loss_dict, auxiliary_outputs = None, None, None + if labels is not None: + # First: create the matcher + matcher = YolosHungarianMatcher( + class_cost=self.config.class_cost, bbox_cost=self.config.bbox_cost, giou_cost=self.config.giou_cost + ) + # Second: create the criterion + losses = ["labels", "boxes", "cardinality"] + criterion = YolosLoss( + matcher=matcher, + num_classes=self.config.num_labels, + eos_coef=self.config.eos_coefficient, + losses=losses, + ) + criterion.to(self.device) + # Third: compute the losses, based on outputs and labels + outputs_loss = {} + outputs_loss["logits"] = logits + outputs_loss["pred_boxes"] = pred_boxes + if self.config.auxiliary_loss: + intermediate = outputs.intermediate_hidden_states if return_dict else outputs[4] + outputs_class = self.class_labels_classifier(intermediate) + outputs_coord = self.bbox_predictor(intermediate).sigmoid() + auxiliary_outputs = self._set_aux_loss(outputs_class, outputs_coord) + outputs_loss["auxiliary_outputs"] = auxiliary_outputs + + loss_dict = criterion(outputs_loss, labels) + # Fourth: compute total loss, as a weighted sum of the various losses + weight_dict = {"loss_ce": 1, "loss_bbox": self.config.bbox_loss_coefficient} + weight_dict["loss_giou"] = self.config.giou_loss_coefficient + if self.config.auxiliary_loss: + aux_weight_dict = {} + for i in range(self.config.decoder_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + loss = sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) + + if not return_dict: + if auxiliary_outputs is not None: + output = (logits, pred_boxes) + auxiliary_outputs + outputs + else: + output = (logits, pred_boxes) + outputs + return ((loss, loss_dict) + output) if loss is not None else output + + return YolosObjectDetectionOutput( + loss=loss, + loss_dict=loss_dict, + logits=logits, + pred_boxes=pred_boxes, + auxiliary_outputs=auxiliary_outputs, + last_hidden_state=outputs.last_hidden_state, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +# Copied from transformers.models.detr.modeling_detr.dice_loss +def dice_loss(inputs, targets, num_boxes): + """ + Compute the DICE loss, similar to generalized IOU for masks + + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs (0 for the negative class and 1 for the positive + class). + """ + inputs = inputs.sigmoid() + inputs = inputs.flatten(1) + numerator = 2 * (inputs * targets).sum(1) + denominator = inputs.sum(-1) + targets.sum(-1) + loss = 1 - (numerator + 1) / (denominator + 1) + return loss.sum() / num_boxes + + +# Copied from transformers.models.detr.modeling_detr.sigmoid_focal_loss +def sigmoid_focal_loss(inputs, targets, num_boxes, alpha: float = 0.25, gamma: float = 2): + """ + Loss used in RetinaNet for dense detection: https://arxiv.org/abs/1708.02002. + + Args: + inputs (`torch.FloatTensor` of arbitrary shape): + The predictions for each example. + targets (`torch.FloatTensor` with the same shape as `inputs`) + A tensor storing the binary classification label for each element in the `inputs` (0 for the negative class + and 1 for the positive class). + alpha (`float`, *optional*, defaults to `0.25`): + Optional weighting factor in the range (0,1) to balance positive vs. negative examples. + gamma (`int`, *optional*, defaults to `2`): + Exponent of the modulating factor (1 - p_t) to balance easy vs hard examples. + + Returns: + Loss tensor + """ + prob = inputs.sigmoid() + ce_loss = nn.functional.binary_cross_entropy_with_logits(inputs, targets, reduction="none") + # add modulating factor + p_t = prob * targets + (1 - prob) * (1 - targets) + loss = ce_loss * ((1 - p_t) ** gamma) + + if alpha >= 0: + alpha_t = alpha * targets + (1 - alpha) * (1 - targets) + loss = alpha_t * loss + + return loss.mean(1).sum() / num_boxes + + +# Copied from transformers.models.detr.modeling_detr.DetrLoss with Detr->Yolos +class YolosLoss(nn.Module): + """ + This class computes the losses for YolosForObjectDetection/YolosForSegmentation. The process happens in two steps: + 1) we compute hungarian assignment between ground truth boxes and the outputs of the model 2) we supervise each + pair of matched ground-truth / prediction (supervise class and box). + + A note on the `num_classes` argument (copied from original repo in detr.py): "the naming of the `num_classes` + parameter of the criterion is somewhat misleading. It indeed corresponds to `max_obj_id` + 1, where `max_obj_id` is + the maximum id for a class in your dataset. For example, COCO has a `max_obj_id` of 90, so we pass `num_classes` to + be 91. As another example, for a dataset that has a single class with `id` 1, you should pass `num_classes` to be 2 + (`max_obj_id` + 1). For more details on this, check the following discussion + https://github.com/facebookresearch/detr/issues/108#issuecomment-650269223" + + + Args: + matcher (`YolosHungarianMatcher`): + Module able to compute a matching between targets and proposals. + num_classes (`int`): + Number of object categories, omitting the special no-object category. + eos_coef (`float`): + Relative classification weight applied to the no-object category. + losses (`List[str]`): + List of all the losses to be applied. See `get_loss` for a list of all available losses. + """ + + def __init__(self, matcher, num_classes, eos_coef, losses): + super().__init__() + self.matcher = matcher + self.num_classes = num_classes + self.eos_coef = eos_coef + self.losses = losses + empty_weight = torch.ones(self.num_classes + 1) + empty_weight[-1] = self.eos_coef + self.register_buffer("empty_weight", empty_weight) + + # removed logging parameter, which was part of the original implementation + def loss_labels(self, outputs, targets, indices, num_boxes): + """ + Classification loss (NLL) targets dicts must contain the key "class_labels" containing a tensor of dim + [nb_target_boxes] + """ + if "logits" not in outputs: + raise KeyError("No logits were found in the outputs") + source_logits = outputs["logits"] + + idx = self._get_source_permutation_idx(indices) + target_classes_o = torch.cat([t["class_labels"][J] for t, (_, J) in zip(targets, indices)]) + target_classes = torch.full( + source_logits.shape[:2], self.num_classes, dtype=torch.int64, device=source_logits.device + ) + target_classes[idx] = target_classes_o + + loss_ce = nn.functional.cross_entropy(source_logits.transpose(1, 2), target_classes, self.empty_weight) + losses = {"loss_ce": loss_ce} + + return losses + + @torch.no_grad() + def loss_cardinality(self, outputs, targets, indices, num_boxes): + """ + Compute the cardinality error, i.e. the absolute error in the number of predicted non-empty boxes. + + This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients. + """ + logits = outputs["logits"] + device = logits.device + target_lengths = torch.as_tensor([len(v["class_labels"]) for v in targets], device=device) + # Count the number of predictions that are NOT "no-object" (which is the last class) + card_pred = (logits.argmax(-1) != logits.shape[-1] - 1).sum(1) + card_err = nn.functional.l1_loss(card_pred.float(), target_lengths.float()) + losses = {"cardinality_error": card_err} + return losses + + def loss_boxes(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss. + + Targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]. The target boxes + are expected in format (center_x, center_y, w, h), normalized by the image size. + """ + if "pred_boxes" not in outputs: + raise KeyError("No predicted boxes found in outputs") + idx = self._get_source_permutation_idx(indices) + source_boxes = outputs["pred_boxes"][idx] + target_boxes = torch.cat([t["boxes"][i] for t, (_, i) in zip(targets, indices)], dim=0) + + loss_bbox = nn.functional.l1_loss(source_boxes, target_boxes, reduction="none") + + losses = {} + losses["loss_bbox"] = loss_bbox.sum() / num_boxes + + loss_giou = 1 - torch.diag( + generalized_box_iou(center_to_corners_format(source_boxes), center_to_corners_format(target_boxes)) + ) + losses["loss_giou"] = loss_giou.sum() / num_boxes + return losses + + def loss_masks(self, outputs, targets, indices, num_boxes): + """ + Compute the losses related to the masks: the focal loss and the dice loss. + + Targets dicts must contain the key "masks" containing a tensor of dim [nb_target_boxes, h, w]. + """ + if "pred_masks" not in outputs: + raise KeyError("No predicted masks found in outputs") + + source_idx = self._get_source_permutation_idx(indices) + target_idx = self._get_target_permutation_idx(indices) + source_masks = outputs["pred_masks"] + source_masks = source_masks[source_idx] + masks = [t["masks"] for t in targets] + # TODO use valid to mask invalid areas due to padding in loss + target_masks, valid = nested_tensor_from_tensor_list(masks).decompose() + target_masks = target_masks.to(source_masks) + target_masks = target_masks[target_idx] + + # upsample predictions to the target size + source_masks = nn.functional.interpolate( + source_masks[:, None], size=target_masks.shape[-2:], mode="bilinear", align_corners=False + ) + source_masks = source_masks[:, 0].flatten(1) + + target_masks = target_masks.flatten(1) + target_masks = target_masks.view(source_masks.shape) + losses = { + "loss_mask": sigmoid_focal_loss(source_masks, target_masks, num_boxes), + "loss_dice": dice_loss(source_masks, target_masks, num_boxes), + } + return losses + + def _get_source_permutation_idx(self, indices): + # permute predictions following indices + batch_idx = torch.cat([torch.full_like(source, i) for i, (source, _) in enumerate(indices)]) + source_idx = torch.cat([source for (source, _) in indices]) + return batch_idx, source_idx + + def _get_target_permutation_idx(self, indices): + # permute targets following indices + batch_idx = torch.cat([torch.full_like(target, i) for i, (_, target) in enumerate(indices)]) + target_idx = torch.cat([target for (_, target) in indices]) + return batch_idx, target_idx + + def get_loss(self, loss, outputs, targets, indices, num_boxes): + loss_map = { + "labels": self.loss_labels, + "cardinality": self.loss_cardinality, + "boxes": self.loss_boxes, + "masks": self.loss_masks, + } + if loss not in loss_map: + raise ValueError(f"Loss {loss} not supported") + return loss_map[loss](outputs, targets, indices, num_boxes) + + def forward(self, outputs, targets): + """ + This performs the loss computation. + + Args: + outputs (`dict`, *optional*): + Dictionary of tensors, see the output specification of the model for the format. + targets (`List[dict]`, *optional*): + List of dicts, such that `len(targets) == batch_size`. The expected keys in each dict depends on the + losses applied, see each loss' doc. + """ + outputs_without_aux = {k: v for k, v in outputs.items() if k != "auxiliary_outputs"} + + # Retrieve the matching between the outputs of the last layer and the targets + indices = self.matcher(outputs_without_aux, targets) + + # Compute the average number of target boxes across all nodes, for normalization purposes + num_boxes = sum(len(t["class_labels"]) for t in targets) + num_boxes = torch.as_tensor([num_boxes], dtype=torch.float, device=next(iter(outputs.values())).device) + # (Niels): comment out function below, distributed training to be added + # if is_dist_avail_and_initialized(): + # torch.distributed.all_reduce(num_boxes) + # (Niels) in original implementation, num_boxes is divided by get_world_size() + num_boxes = torch.clamp(num_boxes, min=1).item() + + # Compute all the requested losses + losses = {} + for loss in self.losses: + losses.update(self.get_loss(loss, outputs, targets, indices, num_boxes)) + + # In case of auxiliary losses, we repeat this process with the output of each intermediate layer. + if "auxiliary_outputs" in outputs: + for i, auxiliary_outputs in enumerate(outputs["auxiliary_outputs"]): + indices = self.matcher(auxiliary_outputs, targets) + for loss in self.losses: + if loss == "masks": + # Intermediate masks losses are too costly to compute, we ignore them. + continue + l_dict = self.get_loss(loss, auxiliary_outputs, targets, indices, num_boxes) + l_dict = {k + f"_{i}": v for k, v in l_dict.items()} + losses.update(l_dict) + + return losses + + +# Copied from transformers.models.detr.modeling_detr.DetrMLPPredictionHead with Detr->Yolos +class YolosMLPPredictionHead(nn.Module): + """ + Very simple multi-layer perceptron (MLP, also called FFN), used to predict the normalized center coordinates, + height and width of a bounding box w.r.t. an image. + + Copied from https://github.com/facebookresearch/detr/blob/master/models/detr.py + + """ + + def __init__(self, input_dim, hidden_dim, output_dim, num_layers): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = nn.functional.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x + + +# Copied from transformers.models.detr.modeling_detr.DetrHungarianMatcher with Detr->Yolos +class YolosHungarianMatcher(nn.Module): + """ + This class computes an assignment between the targets and the predictions of the network. + + For efficiency reasons, the targets don't include the no_object. Because of this, in general, there are more + predictions than targets. In this case, we do a 1-to-1 matching of the best predictions, while the others are + un-matched (and thus treated as non-objects). + + Args: + class_cost: + The relative weight of the classification error in the matching cost. + bbox_cost: + The relative weight of the L1 error of the bounding box coordinates in the matching cost. + giou_cost: + The relative weight of the giou loss of the bounding box in the matching cost. + """ + + def __init__(self, class_cost: float = 1, bbox_cost: float = 1, giou_cost: float = 1): + super().__init__() + requires_backends(self, ["scipy"]) + + self.class_cost = class_cost + self.bbox_cost = bbox_cost + self.giou_cost = giou_cost + if class_cost == 0 and bbox_cost == 0 and giou_cost == 0: + raise ValueError("All costs of the Matcher can't be 0") + + @torch.no_grad() + def forward(self, outputs, targets): + """ + Args: + outputs (`dict`): + A dictionary that contains at least these entries: + * "logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits + * "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates. + targets (`List[dict]`): + A list of targets (len(targets) = batch_size), where each target is a dict containing: + * "class_labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of + ground-truth + objects in the target) containing the class labels + * "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates. + + Returns: + `List[Tuple]`: A list of size `batch_size`, containing tuples of (index_i, index_j) where: + - index_i is the indices of the selected predictions (in order) + - index_j is the indices of the corresponding selected targets (in order) + For each batch element, it holds: len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + batch_size, num_queries = outputs["logits"].shape[:2] + + # We flatten to compute the cost matrices in a batch + out_prob = outputs["logits"].flatten(0, 1).softmax(-1) # [batch_size * num_queries, num_classes] + out_bbox = outputs["pred_boxes"].flatten(0, 1) # [batch_size * num_queries, 4] + + # Also concat the target labels and boxes + target_ids = torch.cat([v["class_labels"] for v in targets]) + target_bbox = torch.cat([v["boxes"] for v in targets]) + + # Compute the classification cost. Contrary to the loss, we don't use the NLL, + # but approximate it in 1 - proba[target class]. + # The 1 is a constant that doesn't change the matching, it can be ommitted. + class_cost = -out_prob[:, target_ids] + + # Compute the L1 cost between boxes + bbox_cost = torch.cdist(out_bbox, target_bbox, p=1) + + # Compute the giou cost between boxes + giou_cost = -generalized_box_iou(center_to_corners_format(out_bbox), center_to_corners_format(target_bbox)) + + # Final cost matrix + cost_matrix = self.bbox_cost * bbox_cost + self.class_cost * class_cost + self.giou_cost * giou_cost + cost_matrix = cost_matrix.view(batch_size, num_queries, -1).cpu() + + sizes = [len(v["boxes"]) for v in targets] + indices = [linear_sum_assignment(c[i]) for i, c in enumerate(cost_matrix.split(sizes, -1))] + return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices] + + +# Copied from transformers.models.detr.modeling_detr._upcast +def _upcast(t: Tensor) -> Tensor: + # Protects from numerical overflows in multiplications by upcasting to the equivalent higher type + if t.is_floating_point(): + return t if t.dtype in (torch.float32, torch.float64) else t.float() + else: + return t if t.dtype in (torch.int32, torch.int64) else t.int() + + +# Copied from transformers.models.detr.modeling_detr.box_area +def box_area(boxes: Tensor) -> Tensor: + """ + Computes the area of a set of bounding boxes, which are specified by its (x1, y1, x2, y2) coordinates. + + Args: + boxes (`torch.FloatTensor` of shape `(number_of_boxes, 4)`): + Boxes for which the area will be computed. They are expected to be in (x1, y1, x2, y2) format with `0 <= x1 + < x2` and `0 <= y1 < y2`. + + Returns: + `torch.FloatTensor`: a tensor containing the area for each box. + """ + boxes = _upcast(boxes) + return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) + + +# Copied from transformers.models.detr.modeling_detr.box_iou +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + left_top = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2] + right_bottom = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2] + + width_height = (right_bottom - left_top).clamp(min=0) # [N,M,2] + inter = width_height[:, :, 0] * width_height[:, :, 1] # [N,M] + + union = area1[:, None] + area2 - inter + + iou = inter / union + return iou, union + + +# Copied from transformers.models.detr.modeling_detr.generalized_box_iou +def generalized_box_iou(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/. The boxes should be in [x0, y0, x1, y1] (corner) format. + + Returns: + `torch.FloatTensor`: a [N, M] pairwise matrix, where N = len(boxes1) and M = len(boxes2) + """ + # degenerate boxes gives inf / nan results + # so do an early check + if not (boxes1[:, 2:] >= boxes1[:, :2]).all(): + raise ValueError(f"boxes1 must be in [x0, y0, x1, y1] (corner) format, but got {boxes1}") + if not (boxes2[:, 2:] >= boxes2[:, :2]).all(): + raise ValueError(f"boxes2 must be in [x0, y0, x1, y1] (corner) format, but got {boxes2}") + iou, union = box_iou(boxes1, boxes2) + + top_left = torch.min(boxes1[:, None, :2], boxes2[:, :2]) + bottom_right = torch.max(boxes1[:, None, 2:], boxes2[:, 2:]) + + width_height = (bottom_right - top_left).clamp(min=0) # [N,M,2] + area = width_height[:, :, 0] * width_height[:, :, 1] + + return iou - (area - union) / area + + +# Copied from transformers.models.detr.modeling_detr._max_by_axis +def _max_by_axis(the_list): + # type: (List[List[int]]) -> List[int] + maxes = the_list[0] + for sublist in the_list[1:]: + for index, item in enumerate(sublist): + maxes[index] = max(maxes[index], item) + return maxes + + +# Copied from transformers.models.detr.modeling_detr.NestedTensor +class NestedTensor(object): + def __init__(self, tensors, mask: Optional[Tensor]): + self.tensors = tensors + self.mask = mask + + def to(self, device): + cast_tensor = self.tensors.to(device) + mask = self.mask + if mask is not None: + cast_mask = mask.to(device) + else: + cast_mask = None + return NestedTensor(cast_tensor, cast_mask) + + def decompose(self): + return self.tensors, self.mask + + def __repr__(self): + return str(self.tensors) + + +# Copied from transformers.models.detr.modeling_detr.nested_tensor_from_tensor_list +def nested_tensor_from_tensor_list(tensor_list: List[Tensor]): + if tensor_list[0].ndim == 3: + max_size = _max_by_axis([list(img.shape) for img in tensor_list]) + batch_shape = [len(tensor_list)] + max_size + batch_size, num_channels, height, width = batch_shape + dtype = tensor_list[0].dtype + device = tensor_list[0].device + tensor = torch.zeros(batch_shape, dtype=dtype, device=device) + mask = torch.ones((batch_size, height, width), dtype=torch.bool, device=device) + for img, pad_img, m in zip(tensor_list, tensor, mask): + pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img) + m[: img.shape[1], : img.shape[2]] = False + else: + raise ValueError("Only 3-dimensional tensors are supported") + return NestedTensor(tensor, mask) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e1f89d73ac47c588d20ba9eccc6186af0f01781e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/__init__.py @@ -0,0 +1,65 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tokenizers_available, is_torch_available + + +_import_structure = {"configuration_yoso": ["YOSO_PRETRAINED_CONFIG_ARCHIVE_MAP", "YosoConfig"]} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_yoso"] = [ + "YOSO_PRETRAINED_MODEL_ARCHIVE_LIST", + "YosoForMaskedLM", + "YosoForMultipleChoice", + "YosoForQuestionAnswering", + "YosoForSequenceClassification", + "YosoForTokenClassification", + "YosoLayer", + "YosoModel", + "YosoPreTrainedModel", + ] + + +if TYPE_CHECKING: + from .configuration_yoso import YOSO_PRETRAINED_CONFIG_ARCHIVE_MAP, YosoConfig + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_yoso import ( + YOSO_PRETRAINED_MODEL_ARCHIVE_LIST, + YosoForMaskedLM, + YosoForMultipleChoice, + YosoForQuestionAnswering, + YosoForSequenceClassification, + YosoForTokenClassification, + YosoLayer, + YosoModel, + YosoPreTrainedModel, + ) + + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common.h new file mode 100644 index 0000000000000000000000000000000000000000..e5085c88dd3ea9a12eec264a8c48946bf2b80b23 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common.h @@ -0,0 +1,10 @@ + +#define min(a, b) ((a)<(b)?(a):(b)) +#define max(a, b) ((a)>(b)?(a):(b)) +#define ceil_divide(a, b) ((a)/(b)+((a)%(b)!=0)) +#define select(cond, a, b) ((cond)?(a):(b)) +#define PI 3.141592 +#define EPSILON 1e-8 +#define MAX_VAL 1e12 +#define MIN_VAL -1e12 +#define EMPTY_VALUE -1 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda.h new file mode 100644 index 0000000000000000000000000000000000000000..97030870649a2fdac58cb26cf966e8f5c8cc7909 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda.h @@ -0,0 +1,9 @@ + +#define MAX_THREADS_PER_BLOCK 1024 +#define OPTIMAL_THREADS_PER_BLOCK 256 +#define WARP_SIZE 32 +#define MAX_NUM_BLOCK_X 2147483647 +#define MAX_NUM_BLOCK_Y 65535 +#define MAX_NUM_BLOCK_Z 65535 +#define MAX_SHARED_MEM_PER_BLOCK 48000 +#define FULL_MASK 0xffffffff diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda_device.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda_device.h new file mode 100644 index 0000000000000000000000000000000000000000..6674f93afdc25ab35c5d83881d00028bcf2989fc --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/common_cuda_device.h @@ -0,0 +1,79 @@ + +#include "common.h" + +template +__device__ int set_insert(T *set, int set_size, T value) { + int slot = value % set_size; + int start_slot = slot; + while (true) { + T prev = atomicCAS(&set[slot], EMPTY_VALUE, value); + if (prev == EMPTY_VALUE || prev == value) { + return slot; + } + slot = (slot + 1) % set_size; + if (slot == start_slot) { + return -1; + } + } + return -1; +} + +template +__device__ int set_lookup(T *set, int set_size, T value) { + int slot = value % set_size; + int start_slot = slot; + while (true) { + if (set[slot] == value) { + return slot; + } + slot = (slot + 1) % set_size; + if (slot == start_slot) { + return -1; + } + } + return -1; +} + +template +__device__ void init_buffer(T init_value, T *buffer, int buffer_size, int num_threads, int thread_id) { + __syncthreads(); + for (int i = 0; i < buffer_size; i = i + num_threads) { + int offset_idx = i + thread_id; + if (offset_idx < buffer_size) { + buffer[offset_idx] = init_value; + } + } + __syncthreads(); +} + +template +__device__ void copy_data(T *src_pt, T *dist_pt, int data_length, int num_threads, int thread_id) { + __syncthreads(); + for (int i = 0; i < data_length; i = i + num_threads) { + int offset_idx = i + thread_id; + if (offset_idx < data_length) { + dist_pt[offset_idx] = src_pt[offset_idx]; + } + } + __syncthreads(); +} + +template +__device__ void init_buffer_nonblocking(T init_value, T *buffer, int buffer_size, int num_threads, int thread_id) { + for (int i = 0; i < buffer_size; i = i + num_threads) { + int offset_idx = i + thread_id; + if (offset_idx < buffer_size) { + buffer[offset_idx] = init_value; + } + } +} + +template +__device__ void copy_data_nonblocking(T *src_pt, T *dist_pt, int data_length, int num_threads, int thread_id) { + for (int i = 0; i < data_length; i = i + num_threads) { + int offset_idx = i + thread_id; + if (offset_idx < data_length) { + dist_pt[offset_idx] = src_pt[offset_idx]; + } + } +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/configuration_yoso.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/configuration_yoso.py new file mode 100644 index 0000000000000000000000000000000000000000..c6d2b176ef947d6d73300708ea8a8c2d809be595 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/configuration_yoso.py @@ -0,0 +1,145 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" YOSO model configuration""" + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +YOSO_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "uw-madison/yoso-4096": "https://huggingface.co/uw-madison/yoso-4096/resolve/main/config.json", + # See all YOSO models at https://huggingface.co/models?filter=yoso +} + + +class YosoConfig(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`YosoModel`]. It is used to instantiate an YOSO + model according to the specified arguments, defining the model architecture. Instantiating a configuration with the + defaults will yield a similar configuration to that of the YOSO + [uw-madison/yoso-4096](https://huggingface.co/uw-madison/yoso-4096) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the + documentation from [`PretrainedConfig`] for more information. + + + Args: + vocab_size (`int`, *optional*, defaults to 50265): + Vocabulary size of the YOSO model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`YosoModel`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimension of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimension of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`, + `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`YosoModel`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + position_embedding_type (`str`, *optional*, defaults to `"absolute"`): + Type of position embedding. Choose one of `"absolute"`, `"relative_key"`, `"relative_key_query"`. + use_expectation (`bool`, *optional*, defaults to `True`): + Whether or not to use YOSO Expectation. Overrides any effect of num_hash. + hash_code_len (`int`, *optional*, defaults to 9): + The length of hashes generated by the hash functions. + num_hash (`int`, *optional*, defaults to 64): + Number of hash functions used in [`YosoSelfAttention`]. + conv_window (`int`, *optional*): + Kernel size of depth-wise convolution. + use_fast_hash (`bool`, *optional*, defaults to `False`): + Whether or not to use custom cuda kernels which perform fast random projection via hadamard transform. + lsh_backward (`bool`, *optional*, defaults to `True`): + Whether or not to perform backpropagation using Locality Sensitive Hashing. + + Example: + + ```python + >>> from transformers import YosoConfig, YosoModel + + >>> # Initializing a YOSO uw-madison/yoso-4096 style configuration + >>> configuration = YosoConfig() + + >>> # Initializing a model (with random weights) from the uw-madison/yoso-4096 style configuration + >>> model = YosoModel(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ```""" + model_type = "yoso" + + def __init__( + self, + vocab_size=50265, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=4096, + type_vocab_size=1, + initializer_range=0.02, + layer_norm_eps=1e-12, + position_embedding_type="absolute", + use_expectation=True, + hash_code_len=9, + num_hash=64, + conv_window=None, + use_fast_hash=True, + lsh_backward=True, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + **kwargs, + ): + super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs) + + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.type_vocab_size = type_vocab_size + self.layer_norm_eps = layer_norm_eps + self.position_embedding_type = position_embedding_type + self.use_expectation = use_expectation + self.hash_code_len = hash_code_len + self.num_hash = num_hash + self.conv_window = conv_window + self.use_fast_hash = use_fast_hash + self.lsh_backward = lsh_backward diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/convert_yoso_pytorch_to_pytorch.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/convert_yoso_pytorch_to_pytorch.py new file mode 100644 index 0000000000000000000000000000000000000000..be46a4de81b30cff5c826bd9f298b2ee7a8fecbb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/convert_yoso_pytorch_to_pytorch.py @@ -0,0 +1,108 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Convert YOSO checkpoints from the original repository. URL: https://github.com/mlpen/YOSO""" + +import argparse + +import torch + +from transformers import YosoConfig, YosoForMaskedLM + + +def rename_key(orig_key): + if "model" in orig_key: + orig_key = orig_key.replace("model.", "") + if "norm1" in orig_key: + orig_key = orig_key.replace("norm1", "attention.output.LayerNorm") + if "norm2" in orig_key: + orig_key = orig_key.replace("norm2", "output.LayerNorm") + if "norm" in orig_key: + orig_key = orig_key.replace("norm", "LayerNorm") + if "transformer" in orig_key: + layer_num = orig_key.split(".")[0].split("_")[-1] + orig_key = orig_key.replace(f"transformer_{layer_num}", f"encoder.layer.{layer_num}") + if "mha.attn" in orig_key: + orig_key = orig_key.replace("mha.attn", "attention.self") + if "mha" in orig_key: + orig_key = orig_key.replace("mha", "attention") + if "W_q" in orig_key: + orig_key = orig_key.replace("W_q", "self.query") + if "W_k" in orig_key: + orig_key = orig_key.replace("W_k", "self.key") + if "W_v" in orig_key: + orig_key = orig_key.replace("W_v", "self.value") + if "ff1" in orig_key: + orig_key = orig_key.replace("ff1", "intermediate.dense") + if "ff2" in orig_key: + orig_key = orig_key.replace("ff2", "output.dense") + if "ff" in orig_key: + orig_key = orig_key.replace("ff", "output.dense") + if "mlm_class" in orig_key: + orig_key = orig_key.replace("mlm.mlm_class", "cls.predictions.decoder") + if "mlm" in orig_key: + orig_key = orig_key.replace("mlm", "cls.predictions.transform") + if "cls" not in orig_key: + orig_key = "yoso." + orig_key + + return orig_key + + +def convert_checkpoint_helper(max_position_embeddings, orig_state_dict): + for key in orig_state_dict.copy().keys(): + val = orig_state_dict.pop(key) + + if ("pooler" in key) or ("sen_class" in key): + continue + else: + orig_state_dict[rename_key(key)] = val + + orig_state_dict["cls.predictions.bias"] = orig_state_dict["cls.predictions.decoder.bias"] + orig_state_dict["yoso.embeddings.position_ids"] = torch.arange(max_position_embeddings).expand((1, -1)) + 2 + + return orig_state_dict + + +def convert_yoso_checkpoint(checkpoint_path, yoso_config_file, pytorch_dump_path): + orig_state_dict = torch.load(checkpoint_path, map_location="cpu")["model_state_dict"] + config = YosoConfig.from_json_file(yoso_config_file) + model = YosoForMaskedLM(config) + + new_state_dict = convert_checkpoint_helper(config.max_position_embeddings, orig_state_dict) + + print(model.load_state_dict(new_state_dict)) + model.eval() + model.save_pretrained(pytorch_dump_path) + + print(f"Checkpoint successfuly converted. Model saved at {pytorch_dump_path}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Required parameters + parser.add_argument( + "--pytorch_model_path", default=None, type=str, required=True, help="Path to YOSO pytorch checkpoint." + ) + parser.add_argument( + "--config_file", + default=None, + type=str, + required=True, + help="The json file for YOSO model config.", + ) + parser.add_argument( + "--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model." + ) + args = parser.parse_args() + convert_yoso_checkpoint(args.pytorch_model_path, args.config_file, args.pytorch_dump_path) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.cu b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.cu new file mode 100644 index 0000000000000000000000000000000000000000..c6b13e6cb5f53c9c62e51d2c399a14d14dab7037 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.cu @@ -0,0 +1,588 @@ +// File from https://github.com/mlpen/YOSO/blob/main/encoders/backbones/efficient_attentions/yoso/yoso_v1/cuda/fast_lsh_cumulation.cu + +#include +#include +#include "fast_lsh_cumulation.h" +#include "fast_lsh_cumulation_cuda.h" +#include "common_cuda.h" +#include "common.h" +#include +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector fast_hash_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_vector, + at::Tensor key_mask, + at::Tensor key_vector, + int num_hash_f, + int hash_code_len, + bool use_cuda +) { + + int batch_size = query_vector.size(0); + int num_query = query_vector.size(1); + int num_key = key_vector.size(1); + int vector_dim = query_vector.size(2); + + int num_hash_per_part = vector_dim / hash_code_len; + int num_part = max(1, ceil_divide(num_hash_f, num_hash_per_part)); + + at::Tensor Dmat = 2 * at::randint(0, 2, {batch_size, 3, num_part, vector_dim}, query_mask.options()) - 1; + at::Tensor query_hash_code = at::zeros({batch_size, num_query, num_hash_f}, query_mask.options()); + at::Tensor key_hash_code = at::zeros({batch_size, num_key, num_hash_f}, key_mask.options()); + + int *query_mask_ptr = query_mask.data_ptr(); + float *query_vector_ptr = query_vector.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + float *key_vector_ptr = key_vector.data_ptr(); + + int *Dmat_ptr = Dmat.data_ptr(); + + int *query_hash_code_ptr = query_hash_code.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + + if (use_cuda) { + { + dim3 threads(vector_dim); + dim3 blocks(num_part, num_query, batch_size); + int shared_mem = vector_dim * sizeof(float); + fast_hash_ver1_cuda_kernel<<>>( + query_mask_ptr, + query_vector_ptr, + Dmat_ptr, + query_hash_code_ptr, + batch_size, + num_query, + vector_dim, + num_part, + num_hash_f, + hash_code_len + ); + } + { + dim3 threads(vector_dim); + dim3 blocks(num_part, num_key, batch_size); + int shared_mem = vector_dim * sizeof(float); + fast_hash_ver1_cuda_kernel<<>>( + key_mask_ptr, + key_vector_ptr, + Dmat_ptr, + key_hash_code_ptr, + batch_size, + num_key, + vector_dim, + num_part, + num_hash_f, + hash_code_len + ); + } + } + + return {query_hash_code, key_hash_code}; + +} + +at::Tensor lsh_cumulation_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +) { + + int batch_size = query_hash_code.size(0); + int num_hash_f = query_hash_code.size(2); + + int num_query = query_hash_code.size(1); + int num_key = key_hash_code.size(1); + int value_dim = value.size(2); + + at::Tensor hashtable_value = at::empty({batch_size, num_hash_f, hashtable_capacity, WARP_SIZE}, value.options()); + at::Tensor cumulation_value = at::zeros({batch_size, num_query, value_dim}, value.options()); + + if (use_cuda) { + int threads_x = WARP_SIZE; + int threads_y = OPTIMAL_THREADS_PER_BLOCK / WARP_SIZE; + int block_x_step1 = num_key / threads_y; + int block_x_step2 = num_query / threads_y; + int block_y = batch_size; + + dim3 threads(threads_x, threads_y); + dim3 blocks_step1(block_x_step1, block_y); + dim3 blocks_step2(block_x_step2, block_y); + + int *query_mask_ptr = query_mask.data_ptr(); + int *query_hash_code_ptr = query_hash_code.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + float *value_ptr = value.data_ptr(); + float *hashtable_value_ptr = hashtable_value.data_ptr(); + float *cumulation_value_ptr = cumulation_value.data_ptr(); + + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + + cudaMemset(hashtable_value_ptr, 0, (batch_size * num_hash_f * hashtable_capacity * WARP_SIZE) * sizeof(float)); + + lsh_cumulation_ver1_step1_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + value_ptr, + hashtable_value_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key, + value_dim, + value_offset + ); + + lsh_cumulation_ver1_step2_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + hashtable_value_ptr, + cumulation_value_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query, + value_dim, + value_offset + ); + } + + } + + return cumulation_value; + +} + +at::Tensor lsh_weighted_cumulation_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +) { + + int batch_size = query_hash_code.size(0); + int num_hash_f = query_hash_code.size(2); + + int num_query = query_hash_code.size(1); + int num_key = key_hash_code.size(1); + int value_dim = value.size(2); + int weight_dim = query_weight.size(2); + + at::Tensor hashtable_value = at::zeros({batch_size, num_hash_f, hashtable_capacity, WARP_SIZE}, value.options()); + at::Tensor cumulation_value = at::zeros({batch_size, num_query, value_dim}, value.options()); + + if (use_cuda) { + int threads_x = WARP_SIZE; + int threads_y = OPTIMAL_THREADS_PER_BLOCK / WARP_SIZE; + int block_x_step1 = num_key / threads_y; + int block_x_step2 = num_query / threads_y; + int block_y = batch_size; + + dim3 threads(threads_x, threads_y); + dim3 blocks_step1(block_x_step1, block_y); + dim3 blocks_step2(block_x_step2, block_y); + + int *query_mask_ptr = query_mask.data_ptr(); + int *query_hash_code_ptr = query_hash_code.data_ptr(); + float *query_weight_ptr = query_weight.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + float *key_weight_ptr = key_weight.data_ptr(); + float *value_ptr = value.data_ptr(); + float *hashtable_value_ptr = hashtable_value.data_ptr(); + float *cumulation_value_ptr = cumulation_value.data_ptr(); + + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + for (int weight_idx = 0; weight_idx < weight_dim; weight_idx++) { + + cudaMemset(hashtable_value_ptr, 0, (batch_size * num_hash_f * hashtable_capacity * WARP_SIZE) * sizeof(float)); + + lsh_weighted_cumulation_ver1_step1_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + key_weight_ptr, + value_ptr, + hashtable_value_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key, + value_dim, + weight_dim, + value_offset, + weight_idx + ); + + lsh_weighted_cumulation_ver1_step2_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + query_weight_ptr, + hashtable_value_ptr, + cumulation_value_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query, + value_dim, + weight_dim, + value_offset, + weight_idx + ); + } + } + + } + + return cumulation_value; + +} + +at::Tensor lsh_weighted_cumulation_ver2_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +) { + + int batch_size = query_hash_code.size(0); + int num_hash_f = query_hash_code.size(2); + + int num_query = query_hash_code.size(1); + int num_key = key_hash_code.size(1); + int value_dim = value.size(2); + int weight_dim = query_weight.size(2); + + at::Tensor count_sort_table = at::zeros({batch_size, num_hash_f, hashtable_capacity}, query_hash_code.options()); + at::Tensor key_sorted_idxes = at::zeros({batch_size, num_hash_f, num_key}, query_hash_code.options()); + at::Tensor query_info = at::zeros({batch_size, num_query, 2, num_hash_f}, query_hash_code.options()); + at::Tensor cumulation_value = at::zeros({batch_size, num_query, value_dim}, value.options()); + + if (use_cuda) { + + int *query_mask_ptr = query_mask.data_ptr(); + int *query_hash_code_ptr = query_hash_code.data_ptr(); + float *query_weight_ptr = query_weight.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + float *key_weight_ptr = key_weight.data_ptr(); + float *value_ptr = value.data_ptr(); + + int *count_sort_table_ptr = count_sort_table.data_ptr(); + int *key_sorted_idxes_ptr = key_sorted_idxes.data_ptr(); + int *query_info_ptr = query_info.data_ptr(); + + float *cumulation_value_ptr = cumulation_value.data_ptr(); + + { + dim3 threads_step13(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks_step13(num_key / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + dim3 threads_step2(min(hashtable_capacity, OPTIMAL_THREADS_PER_BLOCK)); + dim3 blocks_step2(num_hash_f, batch_size); + int shared_mem = hashtable_capacity * sizeof(float); + count_sort_step1_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key + ); + count_sort_step2_cuda_kernel<<>>( + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity + ); + count_sort_step3_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + count_sort_table_ptr, + key_sorted_idxes_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key + ); + } + { + dim3 threads(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks(num_query / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + extract_query_info_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + count_sort_table_ptr, + query_info_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query + ); + } + { + dim3 threads(WARP_SIZE, OPTIMAL_THREADS_PER_BLOCK / WARP_SIZE); + dim3 blocks(num_query, num_hash_f, batch_size); + int shared_mem = (weight_dim + WARP_SIZE) * sizeof(float); + lsh_weighted_cumulation_ver2_step2_cuda_kernel<<>>( + query_mask_ptr, + query_info_ptr, + key_sorted_idxes_ptr, + query_weight_ptr, + key_weight_ptr, + value_ptr, + cumulation_value_ptr, + batch_size, + num_hash_f, + num_query, + num_key, + value_dim, + weight_dim + ); + } + } + + return cumulation_value; + +} + +at::Tensor lsh_weighted_cumulation_ver3_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +) { + + int batch_size = query_hash_code.size(0); + int num_hash_f = query_hash_code.size(2); + + int num_query = query_hash_code.size(1); + int num_key = key_hash_code.size(1); + int value_dim = value.size(2); + int weight_dim = query_weight.size(2); + + at::Tensor count_sort_table = at::zeros({batch_size, num_hash_f, hashtable_capacity}, query_hash_code.options()); + at::Tensor query_sorted_idxes = at::zeros({batch_size, num_hash_f, num_query}, query_hash_code.options()); + at::Tensor key_info = at::zeros({batch_size, num_key, 2, num_hash_f}, query_hash_code.options()); + at::Tensor cumulation_value = at::zeros({batch_size, num_query, value_dim}, value.options()); + + if (use_cuda) { + + int *query_mask_ptr = query_mask.data_ptr(); + int *query_hash_code_ptr = query_hash_code.data_ptr(); + float *query_weight_ptr = query_weight.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + float *key_weight_ptr = key_weight.data_ptr(); + float *value_ptr = value.data_ptr(); + + int *count_sort_table_ptr = count_sort_table.data_ptr(); + int *query_sorted_idxes_ptr = query_sorted_idxes.data_ptr(); + int *key_info_ptr = key_info.data_ptr(); + + float *cumulation_value_ptr = cumulation_value.data_ptr(); + + { + dim3 threads_step13(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks_step13(num_query / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + dim3 threads_step2(min(hashtable_capacity, OPTIMAL_THREADS_PER_BLOCK)); + dim3 blocks_step2(num_hash_f, batch_size); + int shared_mem = hashtable_capacity * sizeof(float); + count_sort_step1_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query + ); + count_sort_step2_cuda_kernel<<>>( + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity + ); + count_sort_step3_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + count_sort_table_ptr, + query_sorted_idxes_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query + ); + } + { + dim3 threads(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks(num_key / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + extract_query_info_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + count_sort_table_ptr, + key_info_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key + ); + } + { + dim3 threads(WARP_SIZE, OPTIMAL_THREADS_PER_BLOCK / WARP_SIZE); + dim3 blocks(num_key, num_hash_f, batch_size); + int shared_mem = (weight_dim + value_dim + WARP_SIZE) * sizeof(float); + lsh_weighted_cumulation_ver3_step2_cuda_kernel<<>>( + query_sorted_idxes_ptr, + key_mask_ptr, + key_info_ptr, + query_weight_ptr, + key_weight_ptr, + value_ptr, + cumulation_value_ptr, + batch_size, + num_hash_f, + num_query, + num_key, + value_dim, + weight_dim + ); + } + } + + return cumulation_value; + +} + +at::Tensor lsh_weighted_cumulation_ver4_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +) { + + int batch_size = query_hash_code.size(0); + int num_hash_f = query_hash_code.size(2); + + int num_query = query_hash_code.size(1); + int num_key = key_hash_code.size(1); + int value_dim = value.size(2); + int weight_dim = query_weight.size(2); + + at::Tensor count_sort_table = at::zeros({batch_size, num_hash_f, hashtable_capacity}, query_hash_code.options()); + at::Tensor query_sorted_idxes = at::zeros({batch_size, num_hash_f, num_query}, query_hash_code.options()); + at::Tensor key_info = at::zeros({batch_size, num_key, 2, num_hash_f}, query_hash_code.options()); + at::Tensor cumulation_value = at::zeros({batch_size, num_query, value_dim}, value.options()); + + if (use_cuda) { + + int *query_mask_ptr = query_mask.data_ptr(); + int *query_hash_code_ptr = query_hash_code.data_ptr(); + float *query_weight_ptr = query_weight.data_ptr(); + int *key_mask_ptr = key_mask.data_ptr(); + int *key_hash_code_ptr = key_hash_code.data_ptr(); + float *key_weight_ptr = key_weight.data_ptr(); + float *value_ptr = value.data_ptr(); + + int *count_sort_table_ptr = count_sort_table.data_ptr(); + int *query_sorted_idxes_ptr = query_sorted_idxes.data_ptr(); + int *key_info_ptr = key_info.data_ptr(); + + float *cumulation_value_ptr = cumulation_value.data_ptr(); + + { + dim3 threads_step13(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks_step13(num_query / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + dim3 threads_step2(min(hashtable_capacity, OPTIMAL_THREADS_PER_BLOCK)); + dim3 blocks_step2(num_hash_f, batch_size); + int shared_mem = hashtable_capacity * sizeof(float); + count_sort_step1_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query + ); + count_sort_step2_cuda_kernel<<>>( + count_sort_table_ptr, + batch_size, + num_hash_f, + hashtable_capacity + ); + count_sort_step3_cuda_kernel<<>>( + query_mask_ptr, + query_hash_code_ptr, + count_sort_table_ptr, + query_sorted_idxes_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_query + ); + } + { + dim3 threads(num_hash_f, max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f)); + dim3 blocks(num_key / max(1, OPTIMAL_THREADS_PER_BLOCK / num_hash_f), batch_size); + extract_query_info_cuda_kernel<<>>( + key_mask_ptr, + key_hash_code_ptr, + count_sort_table_ptr, + key_info_ptr, + batch_size, + num_hash_f, + hashtable_capacity, + num_key + ); + } + { + dim3 threads(WARP_SIZE, OPTIMAL_THREADS_PER_BLOCK / WARP_SIZE); + dim3 blocks(num_key, batch_size); + int shared_mem = (weight_dim + value_dim + 2 * num_hash_f) * sizeof(float); + lsh_weighted_cumulation_ver4_step2_cuda_kernel<<>>( + query_sorted_idxes_ptr, + key_mask_ptr, + key_info_ptr, + query_weight_ptr, + key_weight_ptr, + value_ptr, + cumulation_value_ptr, + batch_size, + num_hash_f, + num_query, + num_key, + value_dim, + weight_dim + ); + } + } + + return cumulation_value; + +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.h new file mode 100644 index 0000000000000000000000000000000000000000..dd48de0ed159f49ee3afe93b12aaae719fe87688 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation.h @@ -0,0 +1,71 @@ +#include +#include +#include + +std::vector fast_hash_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_vector, + at::Tensor key_mask, + at::Tensor key_vector, + int num_hash_f, + int hash_code_len, + bool use_cuda +); + +at::Tensor lsh_cumulation_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +); + +at::Tensor lsh_weighted_cumulation_ver1_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +); + +at::Tensor lsh_weighted_cumulation_ver2_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +); + +at::Tensor lsh_weighted_cumulation_ver3_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +); + +at::Tensor lsh_weighted_cumulation_ver4_kernel( + at::Tensor query_mask, + at::Tensor query_hash_code, + at::Tensor query_weight, + at::Tensor key_mask, + at::Tensor key_hash_code, + at::Tensor key_weight, + at::Tensor value, + int hashtable_capacity, + bool use_cuda +); diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.cu b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.cu new file mode 100644 index 0000000000000000000000000000000000000000..ebc6260dd6db3ecaf8cb7b35c3c1a6e1ab3851dc --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.cu @@ -0,0 +1,825 @@ +// File from https://github.com/mlpen/YOSO/blob/main/encoders/backbones/efficient_attentions/yoso/yoso_v1/cuda/fast_lsh_cumulation_cuda.cu + +#include "fast_lsh_cumulation_cuda.h" +#include "common_cuda_device.h" +#include "common_cuda.h" +#include "common.h" +#include +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + +inline __device__ void fast_hadamard_transform(float *vector_buffer, int vector_dim, int dim_idx) { + int stride = vector_dim / 2; + while (stride > (WARP_SIZE / 2)) { + __syncthreads(); + int sign = 1 - ((dim_idx / stride) % 2) * 2; + float val1 = vector_buffer[dim_idx]; + float val2 = vector_buffer[dim_idx + sign * stride]; + __syncthreads(); + vector_buffer[dim_idx] = float(sign) * val1 + val2; + stride = stride / 2; + } + + float val = vector_buffer[dim_idx]; + #pragma unroll + for (stride = (WARP_SIZE / 2); stride > 0; stride = stride / 2) { + int sign = 1 - ((dim_idx / stride) % 2) * 2; + val = float(sign) * val + __shfl_xor_sync(FULL_MASK, val, stride); + } + vector_buffer[dim_idx] = val; +} + +__global__ void fast_hash_ver1_cuda_kernel( + int *mask, // [batch_size, num_vector] + float *vector, // [batch_size, num_vector, vector_dim] + int *Dmat, // [batch_size, 3, num_part, vector_dim] + int *hash_code, // [batch_size, num_vector, num_hash_f] + int batch_size, + int num_vector, + int vector_dim, + int num_part, + int num_hash_f, + int hash_code_len +) { + + int batch_idx = blockIdx.z; + int vector_idx = blockIdx.y; + int part_idx = blockIdx.x; + + int dim_idx = threadIdx.x; + + int batch_idx__vector_idx = batch_idx * num_vector + vector_idx; + if (mask[batch_idx__vector_idx] == 0) { + return; + } + + extern __shared__ float buffer[]; + float *vector_buffer = buffer; + + vector_buffer[dim_idx] = vector[batch_idx__vector_idx * vector_dim + dim_idx]; + + vector_buffer[dim_idx] = vector_buffer[dim_idx] * (float)Dmat[((batch_idx * 3 + 0) * num_part + part_idx) * vector_dim + dim_idx]; + fast_hadamard_transform(vector_buffer, vector_dim, dim_idx); + vector_buffer[dim_idx] = vector_buffer[dim_idx] * (float)Dmat[((batch_idx * 3 + 1) * num_part + part_idx) * vector_dim + dim_idx]; + fast_hadamard_transform(vector_buffer, vector_dim, dim_idx); + vector_buffer[dim_idx] = vector_buffer[dim_idx] * (float)Dmat[((batch_idx * 3 + 2) * num_part + part_idx) * vector_dim + dim_idx]; + fast_hadamard_transform(vector_buffer, vector_dim, dim_idx); + + int num_hash_per_part = vector_dim / hash_code_len; + if (hash_code_len == 8 || hash_code_len == 16) { + int code = select(vector_buffer[dim_idx] > 0, 1 << (dim_idx % hash_code_len), 0); + for (int offset = 1; offset < hash_code_len; offset = offset * 2) { + code += __shfl_xor_sync(FULL_MASK, code, offset); + } + if (dim_idx % hash_code_len == 0) { + int hash_f_idx = part_idx * num_hash_per_part + dim_idx / hash_code_len; + if (hash_f_idx < num_hash_f) { + hash_code[batch_idx__vector_idx * num_hash_f + hash_f_idx] = code; + } + } + } else { + vector_buffer[dim_idx] = select(vector_buffer[dim_idx] > 0, 1 << (dim_idx % hash_code_len), 0); + __syncthreads(); + if (dim_idx < num_hash_per_part) { + int code = 0; + for (int i = 0; i < hash_code_len; i++) { + code += vector_buffer[dim_idx * hash_code_len + i]; + } + int hash_f_idx = part_idx * num_hash_per_part + dim_idx; + if (hash_f_idx < num_hash_f) { + hash_code[batch_idx__vector_idx * num_hash_f + hash_f_idx] = code; + } + } + } +} + +__global__ void lsh_cumulation_ver1_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + float *value, // [batch_size, num_key, value_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key, + int value_dim, + int offset_warp +) { + + int warp_thread_idx = threadIdx.x; + + int batch_idx = blockIdx.y; + int key_idx = blockIdx.x * blockDim.y + threadIdx.y; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + if (num_hash_f > WARP_SIZE) { + float warp_value = value[batch_idx__key_idx * value_dim + offset_warp + warp_thread_idx]; + for (int hash_f_start = 0; hash_f_start < num_hash_f; hash_f_start = hash_f_start + WARP_SIZE) { + int warp_hashcode = key_hash_code[batch_idx__key_idx * num_hash_f + hash_f_start + warp_thread_idx]; + #pragma unroll + for (int hash_f_offset = 0; hash_f_offset < WARP_SIZE; hash_f_offset++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_offset); + int hashtable_idx = (batch_idx * num_hash_f + (hash_f_start + hash_f_offset)) * hashtable_capacity + current_hashcode; + atomicAdd(&hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx], warp_value); + } + } + } else { + float warp_value = value[batch_idx__key_idx * value_dim + offset_warp + warp_thread_idx]; + int warp_hashcode = 0; + if (warp_thread_idx < num_hash_f) { + warp_hashcode = key_hash_code[batch_idx__key_idx * num_hash_f + warp_thread_idx]; + } + for (int hash_f_idx = 0; hash_f_idx < num_hash_f; hash_f_idx++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_idx); + int hashtable_idx = (batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + current_hashcode; + atomicAdd(&hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx], warp_value); + } + } + +} + +__global__ void lsh_cumulation_ver1_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query, + int value_dim, + int offset_warp +) { + + int warp_thread_idx = threadIdx.x; + + int batch_idx = blockIdx.y; + int query_idx = blockIdx.x * blockDim.y + threadIdx.y; + + int batch_idx__query_idx = batch_idx * num_query + query_idx; + if (query_mask[batch_idx__query_idx] == 0) { + return; + } + + if (num_hash_f > WARP_SIZE) { + float warp_value = 0; + for (int hash_f_start = 0; hash_f_start < num_hash_f; hash_f_start = hash_f_start + WARP_SIZE) { + int warp_hashcode = query_hash_code[batch_idx__query_idx * num_hash_f + hash_f_start + warp_thread_idx]; + #pragma unroll + for (int hash_f_offset = 0; hash_f_offset < WARP_SIZE; hash_f_offset++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_offset); + int hashtable_idx = (batch_idx * num_hash_f + (hash_f_start + hash_f_offset)) * hashtable_capacity + current_hashcode; + warp_value = warp_value + hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx]; + } + } + cumulation_value[batch_idx__query_idx * value_dim + offset_warp + warp_thread_idx] = warp_value / float(num_hash_f); + } else { + float warp_value = 0; + int warp_hashcode = 0; + if (warp_thread_idx < num_hash_f) { + warp_hashcode = query_hash_code[batch_idx__query_idx * num_hash_f + warp_thread_idx]; + } + for (int hash_f_idx = 0; hash_f_idx < num_hash_f; hash_f_idx++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_idx); + int hashtable_idx = (batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + current_hashcode; + warp_value = warp_value + hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx]; + } + cumulation_value[batch_idx__query_idx * value_dim + offset_warp + warp_thread_idx] = warp_value / float(num_hash_f); + } + +} + +__global__ void lsh_weighted_cumulation_ver1_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key, + int value_dim, + int weight_dim, + int offset_warp, + int weight_idx +) { + + int warp_thread_idx = threadIdx.x; + + int batch_idx = blockIdx.y; + int key_idx = blockIdx.x * blockDim.y + threadIdx.y; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + if (num_hash_f > WARP_SIZE) { + float warp_value = key_weight[batch_idx__key_idx * weight_dim + weight_idx] * value[batch_idx__key_idx * value_dim + offset_warp + warp_thread_idx]; + for (int hash_f_start = 0; hash_f_start < num_hash_f; hash_f_start = hash_f_start + WARP_SIZE) { + int warp_hashcode = key_hash_code[batch_idx__key_idx * num_hash_f + hash_f_start + warp_thread_idx]; + #pragma unroll + for (int hash_f_offset = 0; hash_f_offset < WARP_SIZE; hash_f_offset++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_offset); + int hashtable_idx = (batch_idx * num_hash_f + (hash_f_start + hash_f_offset)) * hashtable_capacity + current_hashcode; + atomicAdd(&hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx], warp_value); + } + } + } else { + float warp_value = key_weight[batch_idx__key_idx * weight_dim + weight_idx] * value[batch_idx__key_idx * value_dim + offset_warp + warp_thread_idx]; + int warp_hashcode = 0; + if (warp_thread_idx < num_hash_f) { + warp_hashcode = key_hash_code[batch_idx__key_idx * num_hash_f + warp_thread_idx]; + } + for (int hash_f_idx = 0; hash_f_idx < num_hash_f; hash_f_idx++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_idx); + int hashtable_idx = (batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + current_hashcode; + atomicAdd(&hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx], warp_value); + } + } + +} + +__global__ void lsh_weighted_cumulation_ver1_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query, + int value_dim, + int weight_dim, + int offset_warp, + int weight_idx +) { + + int warp_thread_idx = threadIdx.x; + + int batch_idx = blockIdx.y; + int query_idx = blockIdx.x * blockDim.y + threadIdx.y; + + int batch_idx__query_idx = batch_idx * num_query + query_idx; + if (query_mask[batch_idx__query_idx] == 0) { + return; + } + + if (num_hash_f > WARP_SIZE) { + float warp_value = 0; + for (int hash_f_start = 0; hash_f_start < num_hash_f; hash_f_start = hash_f_start + WARP_SIZE) { + int warp_hashcode = query_hash_code[batch_idx__query_idx * num_hash_f + hash_f_start + warp_thread_idx]; + #pragma unroll + for (int hash_f_offset = 0; hash_f_offset < WARP_SIZE; hash_f_offset++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_offset); + int hashtable_idx = (batch_idx * num_hash_f + (hash_f_start + hash_f_offset)) * hashtable_capacity + current_hashcode; + warp_value = warp_value + hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx]; + } + } + float warp_weight = query_weight[batch_idx__query_idx * weight_dim + weight_idx]; + cumulation_value[batch_idx__query_idx * value_dim + offset_warp + warp_thread_idx] += warp_weight * warp_value / float(num_hash_f); + } else { + float warp_value = 0; + int warp_hashcode = 0; + if (warp_thread_idx < num_hash_f) { + warp_hashcode = query_hash_code[batch_idx__query_idx * num_hash_f + warp_thread_idx]; + } + for (int hash_f_idx = 0; hash_f_idx < num_hash_f; hash_f_idx++) { + int current_hashcode = warp_hashcode; + current_hashcode = __shfl_sync(FULL_MASK, current_hashcode, hash_f_idx); + int hashtable_idx = (batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + current_hashcode; + warp_value = warp_value + hashtable_value[hashtable_idx * WARP_SIZE + warp_thread_idx]; + } + float warp_weight = query_weight[batch_idx__query_idx * weight_dim + weight_idx]; + cumulation_value[batch_idx__query_idx * value_dim + offset_warp + warp_thread_idx] += warp_weight * warp_value / float(num_hash_f); + } + +} + +__global__ void count_sort_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key +) { + + int batch_idx = blockIdx.y; + int key_idx = blockIdx.x * blockDim.y + threadIdx.y; + int hash_f_idx = threadIdx.x; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + int hash_code = key_hash_code[batch_idx__key_idx * num_hash_f + hash_f_idx]; + atomicAdd(&count_sort_table[(batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + hash_code], 1); + +} + +__global__ void count_sort_step2_cuda_kernel( + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int batch_size, + int num_hash_f, + int hashtable_capacity +) { + + int batch_idx = blockIdx.y; + int hash_f_idx = blockIdx.x; + + int num_threads = blockDim.x; + int thread_id = threadIdx.x; + + int batch_idx__hash_f_idx = batch_idx * num_hash_f + hash_f_idx; + + extern __shared__ float buffer[]; + int *table_buffer = (int*)buffer; + + if (thread_id == 0) { + table_buffer[0] = 0; + } + copy_data(&count_sort_table[batch_idx__hash_f_idx * hashtable_capacity], &table_buffer[1], hashtable_capacity - 1, num_threads, thread_id); + + for (int table_idx_start = 0; table_idx_start < hashtable_capacity; table_idx_start = table_idx_start + num_threads) { + int thread_value = table_buffer[table_idx_start + thread_id]; + int next_thread_value = 0; + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + next_thread_value = __shfl_up_sync(FULL_MASK, thread_value, offset); + if (thread_id % WARP_SIZE >= offset) { + thread_value = thread_value + next_thread_value; + } + } + table_buffer[table_idx_start + thread_id] = thread_value; + } + __syncthreads(); + + if (hashtable_capacity > WARP_SIZE) { + if (thread_id < WARP_SIZE) { + for (int table_idx_start = WARP_SIZE; table_idx_start < hashtable_capacity; table_idx_start = table_idx_start + WARP_SIZE) { + table_buffer[table_idx_start + thread_id] += table_buffer[table_idx_start - 1]; + } + } + } + + copy_data(table_buffer, &count_sort_table[batch_idx__hash_f_idx * hashtable_capacity], hashtable_capacity, num_threads, thread_id); + +} + + +__global__ void count_sort_step3_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int *key_sorted_idxes, // [batch_size, num_hash_f, num_key] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key +) { + + int batch_idx = blockIdx.y; + int key_idx = blockIdx.x * blockDim.y + threadIdx.y; + int hash_f_idx = threadIdx.x; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + int batch_idx__hash_f_idx = batch_idx * num_hash_f + hash_f_idx; + + int hash_code = key_hash_code[batch_idx__key_idx * num_hash_f + hash_f_idx]; + int sort_idx = atomicAdd(&count_sort_table[batch_idx__hash_f_idx * hashtable_capacity + hash_code], 1); + key_sorted_idxes[batch_idx__hash_f_idx * num_key + sort_idx] = key_idx; + +} + +__global__ void extract_query_info_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int *query_info, // [batch_size, num_query, 2, num_hash_f] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query +) { + + int batch_idx = blockIdx.y; + int query_idx = blockIdx.x * blockDim.y + threadIdx.y; + int hash_f_idx = threadIdx.x; + + int batch_idx__query_idx = batch_idx * num_query + query_idx; + if (query_mask[batch_idx__query_idx] == 0) { + return; + } + + int hash_code = query_hash_code[batch_idx__query_idx * num_hash_f + hash_f_idx]; + int batch_idx__hash_f_idx__hash_code = (batch_idx * num_hash_f + hash_f_idx) * hashtable_capacity + hash_code; + + int key_offset = select(hash_code == 0, 0, count_sort_table[batch_idx__hash_f_idx__hash_code - 1]); + int key_count = count_sort_table[batch_idx__hash_f_idx__hash_code] - key_offset; + + query_info[batch_idx__query_idx * 2 * num_hash_f + hash_f_idx] = key_offset; + query_info[(batch_idx__query_idx * 2 + 1) * num_hash_f + hash_f_idx] = key_count; + +} + +__global__ void lsh_weighted_cumulation_ver2_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_info, // [batch_size, num_query, 2, num_hash_f] + int *key_sorted_idxes, // [batch_size, num_hash_f, num_key] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +) { + + int batch_idx = blockIdx.z; + int hash_f_idx = blockIdx.y; + int query_idx = blockIdx.x; + + int num_threads = blockDim.y * blockDim.x; + int thread_id = threadIdx.y * blockDim.x + threadIdx.x; + + int num_warps = blockDim.y; + int warp_idx = threadIdx.y; + int warp_thread_idx = threadIdx.x; + + int batch_idx__query_idx = batch_idx * num_query + query_idx; + if (query_mask[batch_idx__query_idx] == 0) { + return; + } + + int key_offset = query_info[batch_idx__query_idx * 2 * num_hash_f + hash_f_idx]; + int key_count = query_info[(batch_idx__query_idx * 2 + 1) * num_hash_f + hash_f_idx]; + + if (key_count == 0) { + return; + } + + extern __shared__ float buffer[]; + + if (key_count == 1) { + if (warp_idx == 0) { + int key_idx = key_sorted_idxes[(batch_idx * num_hash_f + hash_f_idx) * num_key + key_offset]; + int batch_idx__key_idx = batch_idx * num_key + key_idx; + float weight = 0; + for (int weight_offset = 0; weight_offset < weight_dim; weight_offset = weight_offset + WARP_SIZE) { + int weight_dim_idx = weight_offset + warp_thread_idx; + float val = query_weight[batch_idx__query_idx * weight_dim + weight_dim_idx] * key_weight[batch_idx__key_idx * weight_dim + weight_dim_idx]; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + val += __shfl_xor_sync(FULL_MASK, val, offset); + } + weight = weight + val; + } + weight = weight / float(num_hash_f); + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + int value_dim_idx = value_offset + warp_thread_idx; + float val = value[batch_idx__key_idx * value_dim + value_dim_idx]; + atomicAdd(&cumulation_value[batch_idx__query_idx * value_dim + value_dim_idx], weight * val); + } + } + } else { + float *weight_buffer = buffer; + int *key_idxes_buffer = (int*)&buffer[weight_dim]; + + copy_data_nonblocking(&query_weight[batch_idx__query_idx * weight_dim], weight_buffer, weight_dim, num_threads, thread_id); + + while (key_count > 0) { + int work_size = min(WARP_SIZE, key_count); + copy_data_nonblocking(&key_sorted_idxes[(batch_idx * num_hash_f + hash_f_idx) * num_key + key_offset], key_idxes_buffer, work_size, num_threads, thread_id); + __syncthreads(); + for (int work_offset = 0; work_offset < WARP_SIZE; work_offset = work_offset + num_warps) { + int work_idx = work_offset + warp_idx; + if (work_idx < key_count) { + int key_idx = key_idxes_buffer[work_idx]; + int batch_idx__key_idx = batch_idx * num_key + key_idx; + float weight = 0; + for (int weight_offset = 0; weight_offset < weight_dim; weight_offset = weight_offset + WARP_SIZE) { + int weight_dim_idx = weight_offset + warp_thread_idx; + float val = weight_buffer[weight_dim_idx] * key_weight[batch_idx__key_idx * weight_dim + weight_dim_idx]; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + val += __shfl_xor_sync(FULL_MASK, val, offset); + } + weight = weight + val; + } + weight = weight / float(num_hash_f); + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + int value_dim_idx = value_offset + warp_thread_idx; + float val = value[batch_idx__key_idx * value_dim + value_dim_idx]; + atomicAdd(&cumulation_value[batch_idx__query_idx * value_dim + value_dim_idx], weight * val); + } + } + } + key_count = key_count - work_size; + key_offset = key_offset + work_size; + } + } + +} + +__global__ void lsh_weighted_cumulation_ver3_step2_cuda_kernel( + int *query_sorted_idxes, // [batch_size, num_hash_f, num_query] + int *key_mask, // [batch_size, num_key] + int *key_info, // [batch_size, num_key, 2, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +) { + + int batch_idx = blockIdx.z; + int hash_f_idx = blockIdx.y; + int key_idx = blockIdx.x; + + int num_threads = blockDim.y * blockDim.x; + int thread_id = threadIdx.y * blockDim.x + threadIdx.x; + + int num_warps = blockDim.y; + int warp_idx = threadIdx.y; + int warp_thread_idx = threadIdx.x; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + int query_offset = key_info[batch_idx__key_idx * 2 * num_hash_f + hash_f_idx]; + int query_count = key_info[(batch_idx__key_idx * 2 + 1) * num_hash_f + hash_f_idx]; + + if (query_count == 0) { + return; + } + + extern __shared__ float buffer[]; + + if (query_count == 1) { + if (warp_idx == 0) { + int query_idx = query_sorted_idxes[(batch_idx * num_hash_f + hash_f_idx) * num_query + query_offset]; + int batch_idx__query_idx = batch_idx * num_query + query_idx; + float weight = 0; + for (int weight_offset = 0; weight_offset < weight_dim; weight_offset = weight_offset + WARP_SIZE) { + int weight_dim_idx = weight_offset + warp_thread_idx; + float val = key_weight[batch_idx__key_idx * weight_dim + weight_dim_idx] * query_weight[batch_idx__query_idx * weight_dim + weight_dim_idx]; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + val += __shfl_xor_sync(FULL_MASK, val, offset); + } + weight = weight + val; + } + weight = weight / float(num_hash_f); + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + int value_dim_idx = value_offset + warp_thread_idx; + float val = value[batch_idx__key_idx * value_dim + value_dim_idx]; + atomicAdd(&cumulation_value[batch_idx__query_idx * value_dim + value_dim_idx], weight * val); + } + } + } else { + float *weight_buffer = buffer; + float *value_buffer = &buffer[weight_dim]; + int *query_idxes_buffer = (int*)&buffer[weight_dim + value_dim]; + + copy_data_nonblocking(&key_weight[batch_idx__key_idx * weight_dim], weight_buffer, weight_dim, num_threads, thread_id); + copy_data_nonblocking(&value[batch_idx__key_idx * value_dim], value_buffer, value_dim, num_threads, thread_id); + + while (query_count > 0) { + int work_size = min(WARP_SIZE, query_count); + copy_data_nonblocking(&query_sorted_idxes[(batch_idx * num_hash_f + hash_f_idx) * num_query + query_offset], query_idxes_buffer, work_size, num_threads, thread_id); + __syncthreads(); + for (int work_offset = 0; work_offset < WARP_SIZE; work_offset = work_offset + num_warps) { + int work_idx = work_offset + warp_idx; + if (work_idx < query_count) { + int query_idx = query_idxes_buffer[work_idx]; + int batch_idx__query_idx = batch_idx * num_query + query_idx; + float weight = 0; + for (int weight_offset = 0; weight_offset < weight_dim; weight_offset = weight_offset + WARP_SIZE) { + int weight_dim_idx = weight_offset + warp_thread_idx; + float val = weight_buffer[weight_dim_idx] * query_weight[batch_idx__query_idx * weight_dim + weight_dim_idx]; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + val += __shfl_xor_sync(FULL_MASK, val, offset); + } + weight = weight + val; + } + weight = weight / float(num_hash_f); + for (int value_offset = 0; value_offset < value_dim; value_offset = value_offset + WARP_SIZE) { + int value_dim_idx = value_offset + warp_thread_idx; + float val = value_buffer[value_dim_idx]; + atomicAdd(&cumulation_value[batch_idx__query_idx * value_dim + value_dim_idx], weight * val); + } + } + } + query_count = query_count - work_size; + query_offset = query_offset + work_size; + } + } + +} + +__global__ void lsh_weighted_cumulation_ver4_step2_cuda_kernel( + int *query_sorted_idxes, // [batch_size, num_hash_f, num_query] + int *key_mask, // [batch_size, num_key] + int *key_info, // [batch_size, num_key, 2, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +) { + + int batch_idx = blockIdx.y; + int key_idx = blockIdx.x; + + int num_threads = blockDim.y * blockDim.x; + int thread_id = threadIdx.y * blockDim.x + threadIdx.x; + + int num_warps = blockDim.y; + int warp_idx = threadIdx.y; + int warp_thread_idx = threadIdx.x; + + int batch_idx__key_idx = batch_idx * num_key + key_idx; + if (key_mask[batch_idx__key_idx] == 0) { + return; + } + + extern __shared__ float buffer[]; + float *weight_buffer = buffer; + float *value_buffer = &buffer[weight_dim]; + int *key_info_buffer = (int*)&buffer[weight_dim + value_dim]; + + copy_data_nonblocking(&key_weight[batch_idx__key_idx * weight_dim], weight_buffer, weight_dim, num_threads, thread_id); + copy_data_nonblocking(&value[batch_idx__key_idx * value_dim], value_buffer, value_dim, num_threads, thread_id); + copy_data_nonblocking(&key_info[batch_idx__key_idx * 2 * num_hash_f], key_info_buffer, 2 * num_hash_f, num_threads, thread_id); + + int *query_offset_buffer = key_info_buffer; + int *query_count_buffer = &key_info_buffer[num_hash_f]; + + const int hashtable_size = 1024 + OPTIMAL_THREADS_PER_BLOCK; + __shared__ int hashtable_query[hashtable_size]; + __shared__ int hashtable_count[hashtable_size]; + __shared__ int inserted_query[hashtable_size]; + __shared__ int query_counter[1]; + + int hash_f_idx_base = 0; + + while (true) { + + init_buffer_nonblocking(EMPTY_VALUE, hashtable_query, hashtable_size, num_threads, thread_id); + init_buffer_nonblocking(0, hashtable_count, hashtable_size, num_threads, thread_id); + init_buffer_nonblocking(EMPTY_VALUE, inserted_query, hashtable_size, num_threads, thread_id); + init_buffer_nonblocking(0, query_counter, 1, num_threads, thread_id); + __syncthreads(); + + while (hash_f_idx_base < num_hash_f) { + + int hash_f_idx = hash_f_idx_base + warp_idx; + int batch_idx__hash_f_idx = batch_idx * num_hash_f + hash_f_idx; + + int stop_flag = 0; + + int query_offset = query_offset_buffer[hash_f_idx]; + int query_count = query_count_buffer[hash_f_idx]; + + while (query_count > 0) { + + int work_size = min(query_count, WARP_SIZE); + + // try inserting query to set and check whether the query is new + int found_new_query = 0; + int query_idx = -1; + if (warp_thread_idx < work_size) { + query_idx = query_sorted_idxes[batch_idx__hash_f_idx * num_query + query_offset + warp_thread_idx]; + int slot = set_insert(hashtable_query, hashtable_size, query_idx); + if (slot >= 0) { + found_new_query = atomicAdd(&hashtable_count[slot], 1) == 0; + } + } + + // compute cumulative offset + int position_offset = found_new_query; + int next_position_offset = 0; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + next_position_offset = __shfl_up_sync(FULL_MASK, position_offset, offset); + if (thread_id % WARP_SIZE >= offset) { + position_offset = position_offset + next_position_offset; + } + } + + // get the inserted query list end index + int inserted_query_base = 0; + if (thread_id % WARP_SIZE == WARP_SIZE - 1) { + inserted_query_base = atomicAdd(query_counter, position_offset); + } + inserted_query_base = __shfl_sync(FULL_MASK, inserted_query_base, WARP_SIZE - 1); + + // insert new queries to list + int insert_idx = inserted_query_base + position_offset - 1; + if (found_new_query) { + inserted_query[insert_idx] = query_idx; + } + + // remove inserted queries from list + query_offset_buffer[hash_f_idx] += work_size; + query_count_buffer[hash_f_idx] -= work_size; + query_offset += work_size; + query_count -= work_size; + + // if list is almost full, stop inserting + if (inserted_query_base + OPTIMAL_THREADS_PER_BLOCK > hashtable_size) { + stop_flag = 1; + break; + } + + } + + if (stop_flag) { + break; + } + + hash_f_idx_base = hash_f_idx_base + num_warps; + + } + + __syncthreads(); + + int num_distint_query = query_counter[0]; + + if (num_distint_query > 0) { + for (int idx_base = 0; idx_base < num_distint_query; idx_base = idx_base + num_warps) { + int idx = idx_base + warp_idx; + if (idx < num_distint_query) { + int query_idx = inserted_query[idx]; + int batch_idx__query_idx = batch_idx * num_query + query_idx; + + int slot = set_lookup(hashtable_query, hashtable_size, query_idx); + int duplicate_count = hashtable_count[slot]; + + float weight = 0; + for (int weight_idx_base = 0; weight_idx_base < weight_dim; weight_idx_base = weight_idx_base + WARP_SIZE) { + int weight_dim_idx = weight_idx_base + warp_thread_idx; + float val = weight_buffer[weight_dim_idx] * query_weight[batch_idx__query_idx * weight_dim + weight_dim_idx]; + #pragma unroll + for (int offset = 1; offset < WARP_SIZE; offset = offset << 1) { + val += __shfl_xor_sync(FULL_MASK, val, offset); + } + weight = weight + val; + } + + weight = (float)duplicate_count * weight / float(num_hash_f); + + for (int value_idx_base = 0; value_idx_base < value_dim; value_idx_base = value_idx_base + WARP_SIZE) { + int value_dim_idx = value_idx_base + warp_thread_idx; + float val = value_buffer[value_dim_idx]; + atomicAdd(&cumulation_value[batch_idx__query_idx * value_dim + value_dim_idx], weight * val); + } + } + } + } else { + + // all computation is completed if num_distint_query == 0 + break; + + } + + __syncthreads(); + + } + +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.h b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.h new file mode 100644 index 0000000000000000000000000000000000000000..b2adc0f735358d0fcb6a056e7d19ba745977e129 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_cuda.h @@ -0,0 +1,157 @@ +__global__ void fast_hash_ver1_cuda_kernel( + int *mask, // [batch_size, num_vector] + float *vector, // [batch_size, num_vector, vector_dim] + int *Dmat, // [3, num_part, vector_dim] + int *hash_code, // [batch_size, num_vector, num_hash_f] + int batch_size, + int num_vector, + int vector_dim, + int num_part, + int num_hash_f, + int hash_code_len +); + +__global__ void lsh_cumulation_ver1_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + float *value, // [batch_size, num_key, value_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, value_dim] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key, + int value_dim, + int offset_warp +); + +__global__ void lsh_cumulation_ver1_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query, + int value_dim, + int offset_warp +); + +__global__ void lsh_weighted_cumulation_ver1_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key, + int value_dim, + int weight_dim, + int offset_warp, + int weight_idx +); + +__global__ void lsh_weighted_cumulation_ver1_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *hashtable_value, // [batch_size, num_hash_f, hashtable_capacity, WARP_SIZE] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query, + int value_dim, + int weight_dim, + int offset_warp, + int weight_idx +); + +__global__ void count_sort_step1_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key +); + +__global__ void count_sort_step2_cuda_kernel( + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int batch_size, + int num_hash_f, + int hashtable_capacity +); + +__global__ void count_sort_step3_cuda_kernel( + int *key_mask, // [batch_size, num_key] + int *key_hash_code, // [batch_size, num_key, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int *key_sorted_idxes, // [batch_size, num_hash_f, num_key] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_key +); + +__global__ void extract_query_info_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_hash_code, // [batch_size, num_query, num_hash_f] + int *count_sort_table, // [batch_size, num_hash_f, hashtable_capacity] + int *query_info, // [batch_size, num_query, 2, num_hash_f] + int batch_size, + int num_hash_f, + int hashtable_capacity, + int num_query +); + +__global__ void lsh_weighted_cumulation_ver2_step2_cuda_kernel( + int *query_mask, // [batch_size, num_query] + int *query_info, // [batch_size, num_query, 2, num_hash_f] + int *key_sorted_idxes, // [batch_size, num_hash_f, num_key] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +); + +__global__ void lsh_weighted_cumulation_ver3_step2_cuda_kernel( + int *query_sorted_idxes, // [batch_size, num_hash_f, num_query] + int *key_mask, // [batch_size, num_key] + int *key_info, // [batch_size, num_key, 2, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +); + +__global__ void lsh_weighted_cumulation_ver4_step2_cuda_kernel( + int *query_sorted_idxes, // [batch_size, num_hash_f, num_query] + int *key_mask, // [batch_size, num_key] + int *key_info, // [batch_size, num_key, 2, num_hash_f] + float *query_weight, // [batch_size, num_query, weight_dim] + float *key_weight, // [batch_size, num_key, weight_dim] + float *value, // [batch_size, num_key, value_dim] + float *cumulation_value, // [batch_size, num_query, value_dim] + int batch_size, + int num_hash_f, + int num_query, + int num_key, + int value_dim, + int weight_dim +); diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_torch.cpp b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_torch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e150a2be604b28f600ab345a8cc9e97819cca416 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/fast_lsh_cumulation_torch.cpp @@ -0,0 +1,128 @@ +#include +#include +#include "fast_lsh_cumulation.h" +#include "common_cuda.h" +#include + +std::vector fast_hash( + at::Tensor query_mask, + at::Tensor query_vector, + at::Tensor key_mask, + at::Tensor key_vector, + int num_hash_f, + int hash_code_len, + bool use_cuda, + int version +) { + return fast_hash_ver1_kernel( + query_mask, + query_vector, + key_mask, + key_vector, + num_hash_f, + hash_code_len, + use_cuda + ); +} + +at::Tensor lsh_cumulation( + at::Tensor query_mask, // [batch_size, num_query] + at::Tensor query_hash_code, // [batch_size, num_query, num_hash_f] + at::Tensor key_mask, // [batch_size, num_key] + at::Tensor key_hash_code, // [batch_size, num_key, num_hash_f] + at::Tensor value, // [batch_size, num_key, value_dim] + int hashtable_capacity, + bool use_cuda, + int version +) { + return lsh_cumulation_ver1_kernel( + query_mask, + query_hash_code, + key_mask, + key_hash_code, + value, + hashtable_capacity, + use_cuda + ); +} + +at::Tensor lsh_weighted_cumulation( + at::Tensor query_mask, // [batch_size, num_query] + at::Tensor query_hash_code, // [batch_size, num_query, num_hash_f] + at::Tensor query_weight, // [batch_size, num_query, weight_dim] + at::Tensor key_mask, // [batch_size, num_key] + at::Tensor key_hash_code, // [batch_size, num_key, num_hash_f] + at::Tensor key_weight, // [batch_size, num_key, weight_dim] + at::Tensor value, // [batch_size, num_key, value_dim] + int hashtable_capacity, + bool use_cuda, + int version +) { + if (version == 1) { + return lsh_weighted_cumulation_ver1_kernel( + query_mask, + query_hash_code, + query_weight, + key_mask, + key_hash_code, + key_weight, + value, + hashtable_capacity, + use_cuda + ); + } else if (version == 2) { + return lsh_weighted_cumulation_ver2_kernel( + query_mask, + query_hash_code, + query_weight, + key_mask, + key_hash_code, + key_weight, + value, + hashtable_capacity, + use_cuda + ); + } else if (version == 3) { + return lsh_weighted_cumulation_ver3_kernel( + query_mask, + query_hash_code, + query_weight, + key_mask, + key_hash_code, + key_weight, + value, + hashtable_capacity, + use_cuda + ); + } else if (version == 4) { + return lsh_weighted_cumulation_ver4_kernel( + query_mask, + query_hash_code, + query_weight, + key_mask, + key_hash_code, + key_weight, + value, + hashtable_capacity, + use_cuda + ); + } else { + return lsh_weighted_cumulation_ver3_kernel( + query_mask, + query_hash_code, + query_weight, + key_mask, + key_hash_code, + key_weight, + value, + hashtable_capacity, + use_cuda + ); + } +} + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def("fast_hash", &fast_hash, "Fast Hash (CUDA)"); + m.def("lsh_cumulation", &lsh_cumulation, "LSH Cumulation (CUDA)"); + m.def("lsh_weighted_cumulation", &lsh_weighted_cumulation, "LSH Weighted Cumulation (CUDA)"); +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/modeling_yoso.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/modeling_yoso.py new file mode 100644 index 0000000000000000000000000000000000000000..cf0c814ff95080788be0712c5b8e47bb0c92dc0c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/models/yoso/modeling_yoso.py @@ -0,0 +1,1316 @@ +# coding=utf-8 +# Copyright 2022 University of Wisconsin-Madison and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" PyTorch YOSO model.""" + + +import math +import os +from typing import Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss + +from ...activations import ACT2FN +from ...modeling_outputs import ( + BaseModelOutputWithCrossAttentions, + MaskedLMOutput, + MultipleChoiceModelOutput, + QuestionAnsweringModelOutput, + SequenceClassifierOutput, + TokenClassifierOutput, +) +from ...modeling_utils import PreTrainedModel +from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer +from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging +from .configuration_yoso import YosoConfig + + +logger = logging.get_logger(__name__) + +_CHECKPOINT_FOR_DOC = "uw-madison/yoso-4096" +_CONFIG_FOR_DOC = "YosoConfig" + +YOSO_PRETRAINED_MODEL_ARCHIVE_LIST = [ + "uw-madison/yoso-4096", + # See all YOSO models at https://huggingface.co/models?filter=yoso +] + + +def load_cuda_kernels(): + global lsh_cumulation + try: + from torch.utils.cpp_extension import load + + def append_root(files): + src_folder = os.path.dirname(os.path.realpath(__file__)) + return [os.path.join(src_folder, file) for file in files] + + src_files = append_root( + ["fast_lsh_cumulation_torch.cpp", "fast_lsh_cumulation.cu", "fast_lsh_cumulation_cuda.cu"] + ) + + load("fast_lsh_cumulation", src_files, verbose=True) + + import fast_lsh_cumulation as lsh_cumulation + + return True + except Exception: + lsh_cumulation = None + return False + + +def to_contiguous(input_tensors): + if isinstance(input_tensors, list): + out = [] + for tensor in input_tensors: + if not tensor.is_contiguous(): + tensor = tensor.contiguous() + out.append(tensor) + return out + else: + if not input_tensors.is_contiguous(): + input_tensors = input_tensors.contiguous() + return input_tensors + + +def normalize(input_tensors): + if type(input_tensors) is list: + out = [] + for tensor in input_tensors: + out.append(nn.functional.normalize(tensor, p=2, dim=-1)) + return out + else: + return nn.functional.normalize(input_tensors, p=2, dim=-1) + + +def hashing(query, key, num_hash, hash_len): + if len(query.size()) != 3: + raise ValueError("Query has incorrect size.") + if len(key.size()) != 3: + raise ValueError("Key has incorrect size.") + + rmat = torch.randn(query.size(0), query.size(2), num_hash * hash_len, device=query.device) + raise_pow = 2 ** torch.arange(hash_len, device=query.device) + + query_projection = torch.matmul(query, rmat).reshape(query.size(0), query.size(1), num_hash, hash_len) + key_projection = torch.matmul(key, rmat).reshape(key.size(0), key.size(1), num_hash, hash_len) + query_binary = (query_projection > 0).int() + key_binary = (key_projection > 0).int() + query_hash = torch.sum(query_binary * raise_pow, dim=-1) + query_hash = torch.sum(key_binary * raise_pow, dim=-1) + + return query_hash.int(), query_hash.int() + + +class YosoCumulation(torch.autograd.Function): + @staticmethod + def forward(ctx, query_mask, key_mask, query, key, value, config): + hash_code_len = config["hash_code_len"] + + expectation = (1 - torch.acos(torch.matmul(query, key.transpose(-1, -2))) / math.pi) ** hash_code_len + expectation = expectation * query_mask[:, :, None] * key_mask[:, None, :] + cumulation_value = torch.matmul(expectation, value) + + ctx.save_for_backward(query_mask, key_mask, expectation, query, key, value) + ctx.config = config + + return cumulation_value + + @staticmethod + def backward(ctx, grad): + grad = to_contiguous(grad) + + query_mask, key_mask, expectation, query, key, value = ctx.saved_tensors + config = ctx.config + + hash_code_len = config["hash_code_len"] + + weighted_exp = torch.matmul(grad, value.transpose(-1, -2)) * expectation + grad_query = torch.matmul(weighted_exp, (hash_code_len / 2) * key) + grad_key = torch.matmul(weighted_exp.transpose(-1, -2), (hash_code_len / 2) * query) + grad_value = torch.matmul(expectation.transpose(-1, -2), grad) + + return None, None, grad_query, grad_key, grad_value, None + + +class YosoLSHCumulation(torch.autograd.Function): + @staticmethod + def forward(ctx, query_mask, key_mask, query, key, value, config): + if query_mask.size(0) != key_mask.size(0): + raise ValueError("Query mask and Key mask differ in sizes in dimension 0") + if query_mask.size(0) != query.size(0): + raise ValueError("Query mask and Query differ in sizes in dimension 0") + if query_mask.size(0) != key.size(0): + raise ValueError("Query mask and Key differ in sizes in dimension 0") + if query_mask.size(0) != value.size(0): + raise ValueError("Query mask and Value mask differ in sizes in dimension 0") + if key.size(1) != value.size(1): + raise ValueError("Key and Value differ in sizes in dimension 1") + if query.size(2) != key.size(2): + raise ValueError("Query and Key differ in sizes in dimension 2") + + query_mask, key_mask, query, key, value = to_contiguous([query_mask, key_mask, query, key, value]) + + use_cuda = query_mask.is_cuda + num_hash = config["num_hash"] + hash_code_len = config["hash_code_len"] + hashtable_capacity = int(2**hash_code_len) + + if config["use_fast_hash"]: + query_hash_code, key_hash_code = lsh_cumulation.fast_hash( + query_mask, query, key_mask, key, num_hash, hash_code_len, use_cuda, 1 + ) + else: + query_hash_code, key_hash_code = hashing(query, key, num_hash, hash_code_len) + + cumulation_value = lsh_cumulation.lsh_cumulation( + query_mask, query_hash_code, key_mask, key_hash_code, value, hashtable_capacity, use_cuda, 1 + ) + + ctx.save_for_backward(query_mask, key_mask, query_hash_code, key_hash_code, query, key, value) + ctx.config = config + + return cumulation_value + + @staticmethod + def backward(ctx, grad): + grad = to_contiguous(grad) + + query_mask, key_mask, query_hash_code, key_hash_code, query, key, value = ctx.saved_tensors + config = ctx.config + + use_cuda = grad.is_cuda + hash_code_len = config["hash_code_len"] + hashtable_capacity = int(2**hash_code_len) + + if config["lsh_backward"]: + grad_value = lsh_cumulation.lsh_cumulation( + key_mask, key_hash_code, query_mask, query_hash_code, grad, hashtable_capacity, use_cuda, 1 + ) + grad_query = lsh_cumulation.lsh_weighted_cumulation( + query_mask, + query_hash_code, + grad, + key_mask, + key_hash_code, + value, + (hash_code_len / 2) * key, + hashtable_capacity, + use_cuda, + 4, + ) + grad_key = lsh_cumulation.lsh_weighted_cumulation( + key_mask, + key_hash_code, + value, + query_mask, + query_hash_code, + grad, + (hash_code_len / 2) * query, + hashtable_capacity, + use_cuda, + 4, + ) + else: + expectation = (1 - torch.acos(torch.matmul(query, key.transpose(-1, -2))) / math.pi) ** hash_code_len + expectation = expectation * query_mask[:, :, None] * key_mask[:, None, :] + weighted_exp = torch.matmul(grad, value.transpose(-1, -2)) * expectation + grad_query = torch.matmul(weighted_exp, (hash_code_len / 2) * key) + grad_key = torch.matmul(weighted_exp.transpose(-1, -2), (hash_code_len / 2) * query) + grad_value = torch.matmul(expectation.transpose(-1, -2), grad) + + return None, None, grad_query, grad_key, grad_value, None + + +# Copied from transformers.models.nystromformer.modeling_nystromformer.NystromformerEmbeddings +class YosoEmbeddings(nn.Module): + """Construct the embeddings from word, position and token_type embeddings.""" + + def __init__(self, config): + super().__init__() + self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id) + self.position_embeddings = nn.Embedding(config.max_position_embeddings + 2, config.hidden_size) + self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size) + + # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load + # any TensorFlow checkpoint file + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + # position_ids (1, len position emb) is contiguous in memory and exported when serialized + self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)) + 2) + self.position_embedding_type = getattr(config, "position_embedding_type", "absolute") + self.register_buffer( + "token_type_ids", + torch.zeros(self.position_ids.size(), dtype=torch.long, device=self.position_ids.device), + persistent=False, + ) + + def forward(self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None): + if input_ids is not None: + input_shape = input_ids.size() + else: + input_shape = inputs_embeds.size()[:-1] + + seq_length = input_shape[1] + + if position_ids is None: + position_ids = self.position_ids[:, :seq_length] + + # Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs + # when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves + # issue #5664 + if token_type_ids is None: + if hasattr(self, "token_type_ids"): + buffered_token_type_ids = self.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device) + + if inputs_embeds is None: + inputs_embeds = self.word_embeddings(input_ids) + token_type_embeddings = self.token_type_embeddings(token_type_ids) + + embeddings = inputs_embeds + token_type_embeddings + if self.position_embedding_type == "absolute": + position_embeddings = self.position_embeddings(position_ids) + embeddings += position_embeddings + embeddings = self.LayerNorm(embeddings) + embeddings = self.dropout(embeddings) + return embeddings + + +class YosoSelfAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"): + raise ValueError( + f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention " + f"heads ({config.num_attention_heads})" + ) + + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.dropout = nn.Dropout(config.attention_probs_dropout_prob) + self.position_embedding_type = ( + position_embedding_type if position_embedding_type is not None else config.position_embedding_type + ) + + self.use_expectation = config.use_expectation + self.hash_code_len = config.hash_code_len + self.use_conv = config.conv_window is not None + self.use_fast_hash = config.use_fast_hash + self.num_hash = config.num_hash + self.lsh_backward = config.lsh_backward + + self.lsh_config = { + "hash_code_len": self.hash_code_len, + "use_fast_hash": self.use_fast_hash, + "num_hash": self.num_hash, + "lsh_backward": self.lsh_backward, + } + + if config.conv_window is not None: + self.conv = nn.Conv2d( + in_channels=config.num_attention_heads, + out_channels=config.num_attention_heads, + kernel_size=(config.conv_window, 1), + padding=(config.conv_window // 2, 0), + bias=False, + groups=config.num_attention_heads, + ) + + def transpose_for_scores(self, layer): + new_layer_shape = layer.size()[:-1] + (self.num_attention_heads, self.attention_head_size) + layer = layer.view(*new_layer_shape) + return layer.permute(0, 2, 1, 3) + + def forward(self, hidden_states, attention_mask=None, output_attentions=False): + mixed_query_layer = self.query(hidden_states) + + key_layer = self.transpose_for_scores(self.key(hidden_states)) + value_layer = self.transpose_for_scores(self.value(hidden_states)) + query_layer = self.transpose_for_scores(mixed_query_layer) + + if self.use_conv: + conv_value_layer = self.conv(value_layer * attention_mask[:, None, :, None]) + + batch_size, num_heads, seq_len, head_dim = query_layer.size() + + query_layer = query_layer.reshape(batch_size * num_heads, seq_len, head_dim) + key_layer = key_layer.reshape(batch_size * num_heads, seq_len, head_dim) + value_layer = value_layer.reshape(batch_size * num_heads, seq_len, head_dim) + + # revert changes made by get_extended_attention_mask + attention_mask = 1.0 + attention_mask / 10000.0 + attention_mask = ( + attention_mask.squeeze().repeat(1, num_heads, 1).reshape(batch_size * num_heads, seq_len).int() + ) + + # The CUDA kernels are most efficient with inputs whose size is a multiple of a GPU's warp size (32). Inputs + # smaller than this are padded with zeros. + gpu_warp_size = 32 + + if (not self.use_expectation) and head_dim < gpu_warp_size: + pad_size = batch_size * num_heads, seq_len, gpu_warp_size - head_dim + + query_layer = torch.cat( + [ + query_layer, + torch.zeros(pad_size, device=query_layer.device), + ], + dim=-1, + ) + key_layer = torch.cat( + [ + key_layer, + torch.zeros(pad_size, device=key_layer.device), + ], + dim=-1, + ) + value_layer = torch.cat( + [ + value_layer, + torch.zeros(pad_size, device=value_layer.device), + ], + dim=-1, + ) + + if self.use_expectation or self.training: + query_layer, key_layer = normalize([query_layer, key_layer]) + + if self.use_expectation: + context_layer = YosoCumulation.apply( + attention_mask, attention_mask, query_layer, key_layer, value_layer, self.lsh_config + ) + else: + context_layer = YosoLSHCumulation.apply( + attention_mask, attention_mask, query_layer, key_layer, value_layer, self.lsh_config + ) + + if (not self.use_expectation) and head_dim < gpu_warp_size: + context_layer = context_layer[:, :, :head_dim] + + context_layer = normalize(context_layer) + + context_layer = context_layer.reshape(batch_size, num_heads, seq_len, head_dim) + + if self.use_conv: + context_layer += conv_value_layer + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,) + context_layer = context_layer.view(*new_context_layer_shape) + + outputs = (context_layer, context_layer) if output_attentions else (context_layer,) + + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertSelfOutput +class YosoSelfOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class YosoAttention(nn.Module): + def __init__(self, config, position_embedding_type=None): + super().__init__() + self.self = YosoSelfAttention(config, position_embedding_type=position_embedding_type) + self.output = YosoSelfOutput(config) + self.pruned_heads = set() + + def prune_heads(self, heads): + if len(heads) == 0: + return + heads, index = find_pruneable_heads_and_indices( + heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads + ) + + # Prune linear layers + self.self.query = prune_linear_layer(self.self.query, index) + self.self.key = prune_linear_layer(self.self.key, index) + self.self.value = prune_linear_layer(self.self.value, index) + self.output.dense = prune_linear_layer(self.output.dense, index, dim=1) + + # Update hyper params and store pruned heads + self.self.num_attention_heads = self.self.num_attention_heads - len(heads) + self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads + self.pruned_heads = self.pruned_heads.union(heads) + + def forward(self, hidden_states, attention_mask=None, output_attentions=False): + self_outputs = self.self(hidden_states, attention_mask, output_attentions) + attention_output = self.output(self_outputs[0], hidden_states) + outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them + return outputs + + +# Copied from transformers.models.bert.modeling_bert.BertIntermediate +class YosoIntermediate(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.intermediate_size) + if isinstance(config.hidden_act, str): + self.intermediate_act_fn = ACT2FN[config.hidden_act] + else: + self.intermediate_act_fn = config.hidden_act + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.intermediate_act_fn(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertOutput +class YosoOutput(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.intermediate_size, config.hidden_size) + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + + def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.dropout(hidden_states) + hidden_states = self.LayerNorm(hidden_states + input_tensor) + return hidden_states + + +class YosoLayer(nn.Module): + def __init__(self, config): + super().__init__() + self.chunk_size_feed_forward = config.chunk_size_feed_forward + self.seq_len_dim = 1 + self.attention = YosoAttention(config) + self.add_cross_attention = config.add_cross_attention + self.intermediate = YosoIntermediate(config) + self.output = YosoOutput(config) + + def forward(self, hidden_states, attention_mask=None, output_attentions=False): + self_attention_outputs = self.attention(hidden_states, attention_mask, output_attentions=output_attentions) + attention_output = self_attention_outputs[0] + + outputs = self_attention_outputs[1:] # add self attentions if we output attention weights + + layer_output = apply_chunking_to_forward( + self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output + ) + outputs = (layer_output,) + outputs + + return outputs + + def feed_forward_chunk(self, attention_output): + intermediate_output = self.intermediate(attention_output) + layer_output = self.output(intermediate_output, attention_output) + return layer_output + + +class YosoEncoder(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.layer = nn.ModuleList([YosoLayer(config) for _ in range(config.num_hidden_layers)]) + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + attention_mask=None, + head_mask=None, + output_attentions=False, + output_hidden_states=False, + return_dict=True, + ): + all_hidden_states = () if output_hidden_states else None + all_self_attentions = () if output_attentions else None + + for i, layer_module in enumerate(self.layer): + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if self.gradient_checkpointing and self.training: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs, output_attentions) + + return custom_forward + + layer_outputs = torch.utils.checkpoint.checkpoint( + create_custom_forward(layer_module), + hidden_states, + attention_mask, + ) + else: + layer_outputs = layer_module(hidden_states, attention_mask, output_attentions) + + hidden_states = layer_outputs[0] + if output_attentions: + all_self_attentions = all_self_attentions + (layer_outputs[1],) + + if output_hidden_states: + all_hidden_states = all_hidden_states + (hidden_states,) + + if not return_dict: + return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None) + return BaseModelOutputWithCrossAttentions( + last_hidden_state=hidden_states, + hidden_states=all_hidden_states, + attentions=all_self_attentions, + ) + + +# Copied from transformers.models.bert.modeling_bert.BertPredictionHeadTransform +class YosoPredictionHeadTransform(nn.Module): + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + if isinstance(config.hidden_act, str): + self.transform_act_fn = ACT2FN[config.hidden_act] + else: + self.transform_act_fn = config.hidden_act + self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.dense(hidden_states) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertLMPredictionHead with Bert->Yoso +class YosoLMPredictionHead(nn.Module): + def __init__(self, config): + super().__init__() + self.transform = YosoPredictionHeadTransform(config) + + # The output weights are the same as the input embeddings, but there is + # an output-only bias for each token. + self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + self.bias = nn.Parameter(torch.zeros(config.vocab_size)) + + # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, hidden_states): + hidden_states = self.transform(hidden_states) + hidden_states = self.decoder(hidden_states) + return hidden_states + + +# Copied from transformers.models.bert.modeling_bert.BertOnlyMLMHead with Bert->Yoso +class YosoOnlyMLMHead(nn.Module): + def __init__(self, config): + super().__init__() + self.predictions = YosoLMPredictionHead(config) + + def forward(self, sequence_output: torch.Tensor) -> torch.Tensor: + prediction_scores = self.predictions(sequence_output) + return prediction_scores + + +class YosoPreTrainedModel(PreTrainedModel): + """ + An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained + models. + """ + + config_class = YosoConfig + base_model_prefix = "yoso" + supports_gradient_checkpointing = True + _keys_to_ignore_on_load_missing = [r"position_ids"] + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + # Slightly different from the TF version which uses truncated_normal for initialization + # cf https://github.com/pytorch/pytorch/pull/5617 + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + module.bias.data.zero_() + elif isinstance(module, nn.Embedding): + module.weight.data.normal_(mean=0.0, std=self.config.initializer_range) + if module.padding_idx is not None: + module.weight.data[module.padding_idx].zero_() + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, YosoEncoder): + module.gradient_checkpointing = value + + +YOSO_START_DOCSTRING = r""" + This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use + it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and + behavior. + + Parameters: + config ([`YosoConfig`]): Model configuration class with all the parameters of the model. + Initializing with a config file does not load the weights associated with the model, only the + configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights. +""" + +YOSO_INPUTS_DOCSTRING = r""" + Args: + input_ids (`torch.LongTensor` of shape `({0})`): + Indices of input sequence tokens in the vocabulary. + + Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and + [`PreTrainedTokenizer.__call__`] for details. + + [What are input IDs?](../glossary#input-ids) + attention_mask (`torch.FloatTensor` of shape `({0})`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + token_type_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0, + 1]`: + + - 0 corresponds to a *sentence A* token, + - 1 corresponds to a *sentence B* token. + + [What are token type IDs?](../glossary#token-type-ids) + position_ids (`torch.LongTensor` of shape `({0})`, *optional*): + Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0, + config.max_position_embeddings - 1]`. + + [What are position IDs?](../glossary#position-ids) + head_mask (`torch.FloatTensor` of shape `(num_heads,)` or `(num_layers, num_heads)`, *optional*): + Mask to nullify selected heads of the self-attention modules. Mask values selected in `[0, 1]`: + + - 1 indicates the head is **not masked**, + - 0 indicates the head is **masked**. + + inputs_embeds (`torch.FloatTensor` of shape `({0}, hidden_size)`, *optional*): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This + is useful if you want more control over how to convert *input_ids* indices into associated vectors than the + model's internal embedding lookup matrix. + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned + tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for + more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. +""" + + +@add_start_docstrings( + "The bare YOSO Model transformer outputting raw hidden-states without any specific head on top.", + YOSO_START_DOCSTRING, +) +class YosoModel(YosoPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.config = config + + self.embeddings = YosoEmbeddings(config) + self.encoder = YosoEncoder(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self): + return self.embeddings.word_embeddings + + def set_input_embeddings(self, value): + self.embeddings.word_embeddings = value + + def _prune_heads(self, heads_to_prune): + """ + Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base + class PreTrainedModel + """ + for layer, heads in heads_to_prune.items(): + self.encoder.layer[layer].attention.prune_heads(heads) + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=BaseModelOutputWithCrossAttentions, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, BaseModelOutputWithCrossAttentions]: + output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions + output_hidden_states = ( + output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states + ) + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + if input_ids is not None and inputs_embeds is not None: + raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") + elif input_ids is not None: + input_shape = input_ids.size() + elif inputs_embeds is not None: + input_shape = inputs_embeds.size()[:-1] + else: + raise ValueError("You have to specify either input_ids or inputs_embeds") + + batch_size, seq_length = input_shape + device = input_ids.device if input_ids is not None else inputs_embeds.device + + if attention_mask is None: + attention_mask = torch.ones(((batch_size, seq_length)), device=device) + + if token_type_ids is None: + if hasattr(self.embeddings, "token_type_ids"): + buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] + buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) + token_type_ids = buffered_token_type_ids_expanded + else: + token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) + + # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] + # ourselves in which case we just need to make it broadcastable to all heads. + extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) + + # Prepare head mask if needed + # 1.0 in head_mask indicate we keep the head + # attention_probs has shape bsz x n_heads x N x N + # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] + # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] + head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) + + embedding_output = self.embeddings( + input_ids=input_ids, + position_ids=position_ids, + token_type_ids=token_type_ids, + inputs_embeds=inputs_embeds, + ) + encoder_outputs = self.encoder( + embedding_output, + attention_mask=extended_attention_mask, + head_mask=head_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + sequence_output = encoder_outputs[0] + + if not return_dict: + return (sequence_output,) + encoder_outputs[1:] + + return BaseModelOutputWithCrossAttentions( + last_hidden_state=sequence_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + cross_attentions=encoder_outputs.cross_attentions, + ) + + +@add_start_docstrings("""YOSO Model with a `language modeling` head on top.""", YOSO_START_DOCSTRING) +class YosoForMaskedLM(YosoPreTrainedModel): + _keys_to_ignore_on_load_missing = [ + "cls.predictions.decoder.bias", + "cls.predictions.decoder.weight", + "embeddings.position_ids", + ] + + def __init__(self, config): + super().__init__(config) + + self.yoso = YosoModel(config) + self.cls = YosoOnlyMLMHead(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_output_embeddings(self): + return self.cls.predictions.decoder + + def set_output_embeddings(self, new_embeddings): + self.cls.predictions.decoder = new_embeddings + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MaskedLMOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MaskedLMOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ..., + config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the + loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.yoso( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + prediction_scores = self.cls(sequence_output) + + masked_lm_loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() # -100 index = padding token + masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)) + + if not return_dict: + output = (prediction_scores,) + outputs[1:] + return ((masked_lm_loss,) + output) if masked_lm_loss is not None else output + + return MaskedLMOutput( + loss=masked_lm_loss, + logits=prediction_scores, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +class YosoClassificationHead(nn.Module): + """Head for sentence-level classification tasks.""" + + def __init__(self, config): + super().__init__() + self.dense = nn.Linear(config.hidden_size, config.hidden_size) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.out_proj = nn.Linear(config.hidden_size, config.num_labels) + + self.config = config + + def forward(self, features, **kwargs): + x = features[:, 0, :] # take token (equiv. to [CLS]) + x = self.dropout(x) + x = self.dense(x) + x = ACT2FN[self.config.hidden_act](x) + x = self.dropout(x) + x = self.out_proj(x) + return x + + +@add_start_docstrings( + """YOSO Model transformer with a sequence classification/regression head on top (a linear layer on top of + the pooled output) e.g. for GLUE tasks.""", + YOSO_START_DOCSTRING, +) +class YosoForSequenceClassification(YosoPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + self.yoso = YosoModel(config) + self.classifier = YosoClassificationHead(config) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=SequenceClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, SequenceClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the sequence classification/regression loss. Indices should be in `[0, ..., + config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If + `config.num_labels > 1` a classification loss is computed (Cross-Entropy). + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.yoso( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + if self.config.problem_type is None: + if self.num_labels == 1: + self.config.problem_type = "regression" + elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int): + self.config.problem_type = "single_label_classification" + else: + self.config.problem_type = "multi_label_classification" + + if self.config.problem_type == "regression": + loss_fct = MSELoss() + if self.num_labels == 1: + loss = loss_fct(logits.squeeze(), labels.squeeze()) + else: + loss = loss_fct(logits, labels) + elif self.config.problem_type == "single_label_classification": + loss_fct = CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + elif self.config.problem_type == "multi_label_classification": + loss_fct = BCEWithLogitsLoss() + loss = loss_fct(logits, labels) + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return SequenceClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """YOSO Model with a multiple choice classification head on top (a linear layer on top of + the pooled output and a softmax) e.g. for RocStories/SWAG tasks.""", + YOSO_START_DOCSTRING, +) +class YosoForMultipleChoice(YosoPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + self.yoso = YosoModel(config) + self.pre_classifier = nn.Linear(config.hidden_size, config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, 1) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, num_choices, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=MultipleChoiceModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, MultipleChoiceModelOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for computing the multiple choice classification loss. Indices should be in `[0, ..., + num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See + `input_ids` above) + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1] + + input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None + attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None + token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None + position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None + inputs_embeds = ( + inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1)) + if inputs_embeds is not None + else None + ) + + outputs = self.yoso( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_state = outputs[0] # (bs * num_choices, seq_len, dim) + pooled_output = hidden_state[:, 0] # (bs * num_choices, dim) + pooled_output = self.pre_classifier(pooled_output) # (bs * num_choices, dim) + pooled_output = nn.ReLU()(pooled_output) # (bs * num_choices, dim) + logits = self.classifier(pooled_output) + + reshaped_logits = logits.view(-1, num_choices) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + loss = loss_fct(reshaped_logits, labels) + + if not return_dict: + output = (reshaped_logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return MultipleChoiceModelOutput( + loss=loss, + logits=reshaped_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """YOSO Model with a token classification head on top (a linear layer on top of + the hidden-states output) e.g. for Named-Entity-Recognition (NER) tasks.""", + YOSO_START_DOCSTRING, +) +class YosoForTokenClassification(YosoPreTrainedModel): + def __init__(self, config): + super().__init__(config) + self.num_labels = config.num_labels + + self.yoso = YosoModel(config) + self.dropout = nn.Dropout(config.hidden_dropout_prob) + self.classifier = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=TokenClassifierOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + labels: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, TokenClassifierOutput]: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.yoso( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + sequence_output = self.dropout(sequence_output) + logits = self.classifier(sequence_output) + + loss = None + if labels is not None: + loss_fct = CrossEntropyLoss() + # Only keep active parts of the loss + if attention_mask is not None: + active_loss = attention_mask.view(-1) == 1 + active_logits = logits.view(-1, self.num_labels) + active_labels = torch.where( + active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels) + ) + loss = loss_fct(active_logits, active_labels) + else: + loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) + + if not return_dict: + output = (logits,) + outputs[1:] + return ((loss,) + output) if loss is not None else output + + return TokenClassifierOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +@add_start_docstrings( + """YOSO Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear + layers on top of the hidden-states output to compute `span start logits` and `span end logits`).""", + YOSO_START_DOCSTRING, +) +class YosoForQuestionAnswering(YosoPreTrainedModel): + def __init__(self, config): + super().__init__(config) + + config.num_labels = 2 + self.num_labels = config.num_labels + + self.yoso = YosoModel(config) + self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels) + + # Initialize weights and apply final processing + self.post_init() + + @add_start_docstrings_to_model_forward(YOSO_INPUTS_DOCSTRING.format("batch_size, sequence_length")) + @add_code_sample_docstrings( + checkpoint=_CHECKPOINT_FOR_DOC, + output_type=QuestionAnsweringModelOutput, + config_class=_CONFIG_FOR_DOC, + ) + def forward( + self, + input_ids: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + token_type_ids: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + head_mask: Optional[torch.Tensor] = None, + inputs_embeds: Optional[torch.Tensor] = None, + start_positions: Optional[torch.Tensor] = None, + end_positions: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ) -> Union[Tuple, QuestionAnsweringModelOutput]: + r""" + start_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the start of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + end_positions (`torch.LongTensor` of shape `(batch_size,)`, *optional*): + Labels for position (index) of the end of the labelled span for computing the token classification loss. + Positions are clamped to the length of the sequence (`sequence_length`). Position outside of the sequence + are not taken into account for computing the loss. + """ + return_dict = return_dict if return_dict is not None else self.config.use_return_dict + + outputs = self.yoso( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + position_ids=position_ids, + head_mask=head_mask, + inputs_embeds=inputs_embeds, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + sequence_output = outputs[0] + + logits = self.qa_outputs(sequence_output) + start_logits, end_logits = logits.split(1, dim=-1) + start_logits = start_logits.squeeze(-1) + end_logits = end_logits.squeeze(-1) + + total_loss = None + if start_positions is not None and end_positions is not None: + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions = start_positions.clamp(0, ignored_index) + end_positions = end_positions.clamp(0, ignored_index) + + loss_fct = CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + + if not return_dict: + output = (start_logits, end_logits) + outputs[1:] + return ((total_loss,) + output) if total_loss is not None else output + + return QuestionAnsweringModelOutput( + loss=total_loss, + start_logits=start_logits, + end_logits=end_logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..33350c83a2c161ee228677e8f6fc4b495e9c05bb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__init__.py @@ -0,0 +1,49 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING + +from ..utils import _LazyModule + + +_import_structure = { + "config": [ + "EXTERNAL_DATA_FORMAT_SIZE_LIMIT", + "OnnxConfig", + "OnnxConfigWithPast", + "OnnxSeq2SeqConfigWithPast", + "PatchingSpec", + ], + "convert": ["export", "validate_model_outputs"], + "features": ["FeaturesManager"], + "utils": ["ParameterFormat", "compute_serialized_parameters_size"], +} + + +if TYPE_CHECKING: + from .config import ( + EXTERNAL_DATA_FORMAT_SIZE_LIMIT, + OnnxConfig, + OnnxConfigWithPast, + OnnxSeq2SeqConfigWithPast, + PatchingSpec, + ) + from .convert import export, validate_model_outputs + from .features import FeaturesManager + from .utils import ParameterFormat, compute_serialized_parameters_size + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__main__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..1a0cdb68b111ef6653ec785f69615d57b3d3d8f0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/__main__.py @@ -0,0 +1,240 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import subprocess +import sys +import warnings +from argparse import ArgumentParser +from pathlib import Path + +from packaging import version + +from .. import AutoFeatureExtractor, AutoProcessor, AutoTokenizer +from ..utils import logging +from ..utils.import_utils import is_optimum_available +from .convert import export, validate_model_outputs +from .features import FeaturesManager +from .utils import get_preprocessor + + +MIN_OPTIMUM_VERSION = "1.5.0" + +ENCODER_DECODER_MODELS = ["vision-encoder-decoder"] + + +def export_with_optimum(args): + if is_optimum_available(): + from optimum.version import __version__ as optimum_version + + parsed_optimum_version = version.parse(optimum_version) + if parsed_optimum_version < version.parse(MIN_OPTIMUM_VERSION): + raise RuntimeError( + f"transformers.onnx requires optimum >= {MIN_OPTIMUM_VERSION} but {optimum_version} is installed. You " + "can upgrade optimum by running: pip install -U optimum[exporters]" + ) + else: + raise RuntimeError( + "transformers.onnx requires optimum to run, you can install the library by running: pip install " + "optimum[exporters]" + ) + cmd_line = [ + sys.executable, + "-m", + "optimum.exporters.onnx", + f"--model {args.model}", + f"--task {args.feature}", + f"--framework {args.framework}" if args.framework is not None else "", + f"{args.output}", + ] + proc = subprocess.Popen(" ".join(cmd_line), stdout=subprocess.PIPE, shell=True) + proc.wait() + + logger.info( + "The export was done by optimum.exporters.onnx. We recommend using to use this package directly in future, as " + "transformers.onnx is deprecated, and will be removed in v5. You can find more information here: " + "https://huggingface.co/docs/optimum/exporters/onnx/usage_guides/export_a_model." + ) + + +def export_with_transformers(args): + args.output = args.output if args.output.is_file() else args.output.joinpath("model.onnx") + if not args.output.parent.exists(): + args.output.parent.mkdir(parents=True) + + # Allocate the model + model = FeaturesManager.get_model_from_feature( + args.feature, args.model, framework=args.framework, cache_dir=args.cache_dir + ) + + model_kind, model_onnx_config = FeaturesManager.check_supported_model_or_raise(model, feature=args.feature) + onnx_config = model_onnx_config(model.config) + + if model_kind in ENCODER_DECODER_MODELS: + encoder_model = model.get_encoder() + decoder_model = model.get_decoder() + + encoder_onnx_config = onnx_config.get_encoder_config(encoder_model.config) + decoder_onnx_config = onnx_config.get_decoder_config( + encoder_model.config, decoder_model.config, feature=args.feature + ) + + if args.opset is None: + args.opset = max(encoder_onnx_config.default_onnx_opset, decoder_onnx_config.default_onnx_opset) + + if args.opset < min(encoder_onnx_config.default_onnx_opset, decoder_onnx_config.default_onnx_opset): + raise ValueError( + f"Opset {args.opset} is not sufficient to export {model_kind}. At least " + f" {min(encoder_onnx_config.default_onnx_opset, decoder_onnx_config.default_onnx_opset)} is required." + ) + + preprocessor = AutoFeatureExtractor.from_pretrained(args.model) + + onnx_inputs, onnx_outputs = export( + preprocessor, + encoder_model, + encoder_onnx_config, + args.opset, + args.output.parent.joinpath("encoder_model.onnx"), + ) + + validate_model_outputs( + encoder_onnx_config, + preprocessor, + encoder_model, + args.output.parent.joinpath("encoder_model.onnx"), + onnx_outputs, + args.atol if args.atol else encoder_onnx_config.atol_for_validation, + ) + + preprocessor = AutoTokenizer.from_pretrained(args.model) + + onnx_inputs, onnx_outputs = export( + preprocessor, + decoder_model, + decoder_onnx_config, + args.opset, + args.output.parent.joinpath("decoder_model.onnx"), + ) + + validate_model_outputs( + decoder_onnx_config, + preprocessor, + decoder_model, + args.output.parent.joinpath("decoder_model.onnx"), + onnx_outputs, + args.atol if args.atol else decoder_onnx_config.atol_for_validation, + ) + logger.info( + f"All good, model saved at: {args.output.parent.joinpath('encoder_model.onnx').as_posix()}," + f" {args.output.parent.joinpath('decoder_model.onnx').as_posix()}" + ) + + else: + # Instantiate the appropriate preprocessor + if args.preprocessor == "auto": + preprocessor = get_preprocessor(args.model) + elif args.preprocessor == "tokenizer": + preprocessor = AutoTokenizer.from_pretrained(args.model) + elif args.preprocessor == "feature_extractor": + preprocessor = AutoFeatureExtractor.from_pretrained(args.model) + elif args.preprocessor == "processor": + preprocessor = AutoProcessor.from_pretrained(args.model) + else: + raise ValueError(f"Unknown preprocessor type '{args.preprocessor}'") + + # Ensure the requested opset is sufficient + if args.opset is None: + args.opset = onnx_config.default_onnx_opset + + if args.opset < onnx_config.default_onnx_opset: + raise ValueError( + f"Opset {args.opset} is not sufficient to export {model_kind}. " + f"At least {onnx_config.default_onnx_opset} is required." + ) + + onnx_inputs, onnx_outputs = export( + preprocessor, + model, + onnx_config, + args.opset, + args.output, + ) + + if args.atol is None: + args.atol = onnx_config.atol_for_validation + + validate_model_outputs(onnx_config, preprocessor, model, args.output, onnx_outputs, args.atol) + logger.info(f"All good, model saved at: {args.output.as_posix()}") + warnings.warn( + "The export was done by transformers.onnx which is deprecated and will be removed in v5. We recommend" + " using optimum.exporters.onnx in future. You can find more information here:" + " https://huggingface.co/docs/optimum/exporters/onnx/usage_guides/export_a_model.", + FutureWarning, + ) + + +def main(): + parser = ArgumentParser("Hugging Face Transformers ONNX exporter") + parser.add_argument( + "-m", "--model", type=str, required=True, help="Model ID on huggingface.co or path on disk to load model from." + ) + parser.add_argument( + "--feature", + default="default", + help="The type of features to export the model with.", + ) + parser.add_argument("--opset", type=int, default=None, help="ONNX opset version to export the model with.") + parser.add_argument( + "--atol", type=float, default=None, help="Absolute difference tolerance when validating the model." + ) + parser.add_argument( + "--framework", + type=str, + choices=["pt", "tf"], + default=None, + help=( + "The framework to use for the ONNX export." + " If not provided, will attempt to use the local checkpoint's original framework" + " or what is available in the environment." + ), + ) + parser.add_argument("output", type=Path, help="Path indicating where to store generated ONNX model.") + parser.add_argument("--cache_dir", type=str, default=None, help="Path indicating where to store cache.") + parser.add_argument( + "--preprocessor", + type=str, + choices=["auto", "tokenizer", "feature_extractor", "processor"], + default="auto", + help="Which type of preprocessor to use. 'auto' tries to automatically detect it.", + ) + parser.add_argument( + "--export_with_transformers", + action="store_true", + help=( + "Whether to use transformers.onnx instead of optimum.exporters.onnx to perform the ONNX export. It can be " + "useful when exporting a model supported in transformers but not in optimum, otherwise it is not " + "recommended." + ), + ) + + args = parser.parse_args() + if args.export_with_transformers or not is_optimum_available(): + export_with_transformers(args) + else: + export_with_optimum(args) + + +if __name__ == "__main__": + logger = logging.get_logger("transformers.onnx") # pylint: disable=invalid-name + logger.setLevel(logging.INFO) + main() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/config.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/config.py new file mode 100644 index 0000000000000000000000000000000000000000..bbf06b07929d97faae9c0fcb3dc64feabfde7c78 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/config.py @@ -0,0 +1,741 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import copy +import dataclasses +import warnings +from abc import ABC, abstractmethod +from collections import OrderedDict +from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple, Union + +import numpy as np +from packaging import version + +from ..utils import TensorType, is_torch_available, is_vision_available, logging +from .utils import ParameterFormat, compute_effective_axis_dimension, compute_serialized_parameters_size + + +if TYPE_CHECKING: + from ..configuration_utils import PretrainedConfig + from ..feature_extraction_utils import FeatureExtractionMixin + from ..image_processing_utils import ImageProcessingMixin + from ..tokenization_utils_base import PreTrainedTokenizerBase + + +if is_vision_available(): + from PIL import Image + +logger = logging.get_logger(__name__) + + +DEFAULT_ONNX_OPSET = 11 + +# 2 Gb +EXTERNAL_DATA_FORMAT_SIZE_LIMIT = 2 * 1024 * 1024 * 1024 + + +@dataclasses.dataclass +class PatchingSpec: + """ + Data class that holds patching specifications. + + Args: + o: Module / object where the op to patch is located + name: Name of the op to monkey patch + custom_op: Custom op that patches the original op + orig_op: Original op that is being patched + op_wrapper: Wrapper (optional) that wraps both the original and custom ops. + It is useful for ops that are class or static methods for instance. + """ + + o: Any + name: str + custom_op: Callable + orig_op: Optional[Callable] = None + op_wrapper: Optional[Callable] = None + + +class OnnxConfig(ABC): + """ + Base class for ONNX exportable model describing metadata on how to export the model through the ONNX format. + """ + + default_fixed_batch = 2 + default_fixed_sequence = 8 + default_fixed_num_choices = 4 + torch_onnx_minimum_version = version.parse("1.8") + _tasks_to_common_outputs = { + "causal-lm": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "default": OrderedDict({"last_hidden_state": {0: "batch", 1: "sequence"}}), + "image-classification": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "image-segmentation": OrderedDict( + { + "logits": {0: "batch", 1: "sequence"}, + "pred_boxes": {0: "batch", 1: "sequence"}, + "pred_masks": {0: "batch", 1: "sequence"}, + } + ), + "masked-im": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "masked-lm": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "multiple-choice": OrderedDict({"logits": {0: "batch"}}), + "object-detection": OrderedDict( + { + "logits": {0: "batch", 1: "sequence"}, + "pred_boxes": {0: "batch", 1: "sequence"}, + } + ), + "question-answering": OrderedDict( + { + "start_logits": {0: "batch", 1: "sequence"}, + "end_logits": {0: "batch", 1: "sequence"}, + } + ), + "semantic-segmentation": OrderedDict({"logits": {0: "batch", 1: "num_labels", 2: "height", 3: "width"}}), + "seq2seq-lm": OrderedDict({"logits": {0: "batch", 1: "decoder_sequence"}}), + "sequence-classification": OrderedDict({"logits": {0: "batch"}}), + "token-classification": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "vision2seq-lm": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + "speech2seq-lm": OrderedDict({"logits": {0: "batch", 1: "sequence"}}), + } + + def __init__(self, config: "PretrainedConfig", task: str = "default", patching_specs: List[PatchingSpec] = None): + self._config = config + + if task not in self._tasks_to_common_outputs: + raise ValueError( + f"{task} is not a supported task, supported tasks: {self._tasks_to_common_outputs.keys()}" + ) + self.task = task + + self._patching_specs = [] + for spec in patching_specs if patching_specs is not None else []: + final_spec = spec + if spec.orig_op is None: + final_spec = dataclasses.replace(spec, orig_op=getattr(spec.o, spec.name)) + self._patching_specs.append(final_spec) + + @classmethod + def from_model_config(cls, config: "PretrainedConfig", task: str = "default") -> "OnnxConfig": + """ + Instantiate a OnnxConfig for a specific model + + Args: + config: The model's configuration to use when exporting to ONNX + + Returns: + OnnxConfig for this model + """ + return cls(config, task=task) + + @property + @abstractmethod + def inputs(self) -> Mapping[str, Mapping[int, str]]: + """ + Mapping containing the axis definition of the input tensors to provide to the model + + Returns: + For each input: its name associated to the axes symbolic name and the axis position within the tensor + """ + raise NotImplementedError() + + @property + def outputs(self) -> Mapping[str, Mapping[int, str]]: + """ + Mapping containing the axis definition of the output tensors to provide to the model + + Returns: + For each output: its name associated to the axes symbolic name and the axis position within the tensor + """ + common_outputs = self._tasks_to_common_outputs[self.task] + return copy.deepcopy(common_outputs) + + @property + def values_override(self) -> Optional[Mapping[str, Any]]: + """ + Dictionary of keys to override in the model's config before exporting + + Returns: + Dictionary with the keys (and their corresponding values) to override + """ + if hasattr(self._config, "use_cache"): + return {"use_cache": False} + + return None + + @property + def default_batch_size(self) -> int: + """ + The default batch size to use if no other indication + + Returns: + Integer > 0 + """ + # Using 2 avoid ONNX making assumption about single sample batch + return OnnxConfig.default_fixed_batch + + @property + def default_sequence_length(self) -> int: + """ + The default sequence length to use if no other indication + + Returns: + Integer > 0 + """ + return OnnxConfig.default_fixed_sequence + + @property + def default_num_choices(self) -> int: + """ + The default number of choices to use if no other indication + + Returns: + Integer > 0 + """ + return OnnxConfig.default_fixed_num_choices + + @property + def default_onnx_opset(self) -> int: + """ + Which onnx opset to use when exporting the model + + Returns: + Integer ONNX Opset version + """ + return DEFAULT_ONNX_OPSET + + @property + def atol_for_validation(self) -> float: + """ + What absolute tolerance value to use during model conversion validation. + + Returns: + Float absolute tolerance value. + """ + return 1e-5 + + @property + def is_torch_support_available(self) -> bool: + """ + The minimum PyTorch version required to export the model. + + Returns: + `bool`: Whether the installed version of PyTorch is compatible with the model. + """ + if is_torch_available(): + from transformers.utils import torch_version + + return torch_version >= self.torch_onnx_minimum_version + else: + return False + + @staticmethod + def use_external_data_format(num_parameters: int) -> bool: + """ + Flag indicating if the model requires using external data format + + Args: + num_parameters: Number of parameter on the model + + Returns: + True if model.num_parameters() * size_of(float32) >= 2Gb False otherwise + """ + + return ( + compute_serialized_parameters_size(num_parameters, ParameterFormat.Float) + >= EXTERNAL_DATA_FORMAT_SIZE_LIMIT + ) + + def _generate_dummy_images( + self, batch_size: int = 2, num_channels: int = 3, image_height: int = 40, image_width: int = 40 + ): + images = [] + for _ in range(batch_size): + data = np.random.rand(image_height, image_width, num_channels) * 255 + images.append(Image.fromarray(data.astype("uint8")).convert("RGB")) + return images + + def _generate_dummy_audio( + self, batch_size: int = 2, sampling_rate: int = 22050, time_duration: float = 5.0, frequency: int = 220 + ): + audio_data = [] + for _ in range(batch_size): + # time variable + t = np.linspace(0, time_duration, int(time_duration * sampling_rate), endpoint=False) + + # generate pure sine wave at `frequency` Hz + audio_data.append(0.5 * np.sin(2 * np.pi * frequency * t)) + + return audio_data + + def generate_dummy_inputs( + self, + preprocessor: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin", "ImageProcessingMixin"], + batch_size: int = -1, + seq_length: int = -1, + num_choices: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + num_channels: int = 3, + image_width: int = 40, + image_height: int = 40, + sampling_rate: int = 22050, + time_duration: float = 5.0, + frequency: int = 220, + tokenizer: "PreTrainedTokenizerBase" = None, + ) -> Mapping[str, Any]: + """ + Generate inputs to provide to the ONNX exporter for the specific framework + + Args: + preprocessor: ([`PreTrainedTokenizerBase`], [`FeatureExtractionMixin`], or [`ImageProcessingMixin`]): + The preprocessor associated with this model configuration. + batch_size (`int`, *optional*, defaults to -1): + The batch size to export the model for (-1 means dynamic axis). + num_choices (`int`, *optional*, defaults to -1): + The number of candidate answers provided for multiple choice task (-1 means dynamic axis). + seq_length (`int`, *optional*, defaults to -1): + The sequence length to export the model for (-1 means dynamic axis). + is_pair (`bool`, *optional*, defaults to `False`): + Indicate if the input is a pair (sentence 1, sentence 2) + framework (`TensorType`, *optional*, defaults to `None`): + The framework (PyTorch or TensorFlow) that the tokenizer will generate tensors for. + num_channels (`int`, *optional*, defaults to 3): + The number of channels of the generated images. + image_width (`int`, *optional*, defaults to 40): + The width of the generated images. + image_height (`int`, *optional*, defaults to 40): + The height of the generated images. + sampling_rate (`int`, *optional* defaults to 22050) + The sampling rate for audio data generation. + time_duration (`float`, *optional* defaults to 5.0) + Total seconds of sampling for audio data generation. + frequency (`int`, *optional* defaults to 220) + The desired natural frequency of generated audio. + + Returns: + Mapping[str, Tensor] holding the kwargs to provide to the model's forward function + """ + from ..feature_extraction_utils import FeatureExtractionMixin + from ..image_processing_utils import ImageProcessingMixin + from ..tokenization_utils_base import PreTrainedTokenizerBase + + if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: + raise ValueError("You cannot provide both a tokenizer and a preprocessor to generate dummy inputs.") + if tokenizer is not None: + warnings.warn( + "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" + " `preprocessor` instead.", + FutureWarning, + ) + logger.warning("Overwriting the `preprocessor` argument with `tokenizer` to generate dummmy inputs.") + preprocessor = tokenizer + if isinstance(preprocessor, PreTrainedTokenizerBase): + # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX + batch_size = compute_effective_axis_dimension( + batch_size, fixed_dimension=OnnxConfig.default_fixed_batch, num_token_to_add=0 + ) + # If dynamic axis (-1) we forward with a fixed dimension of 8 tokens to avoid optimizations made by ONNX + token_to_add = preprocessor.num_special_tokens_to_add(is_pair) + seq_length = compute_effective_axis_dimension( + seq_length, fixed_dimension=OnnxConfig.default_fixed_sequence, num_token_to_add=token_to_add + ) + # Generate dummy inputs according to compute batch and sequence + input_token = ( + preprocessor.unk_token + if (preprocessor.unk_token is not None and len(preprocessor.unk_token) > 0) + else "0" + ) + dummy_input = [" ".join([input_token]) * seq_length] * batch_size + if self.task == "multiple-choice": + # If dynamic axis (-1) we forward with a fixed dimension of 4 candidate answers to avoid optimizations + # made by ONNX + num_choices = compute_effective_axis_dimension( + num_choices, fixed_dimension=OnnxConfig.default_fixed_num_choices, num_token_to_add=0 + ) + dummy_input = dummy_input * num_choices + # The shape of the tokenized inputs values is [batch_size * num_choices, seq_length] + tokenized_input = preprocessor(dummy_input, text_pair=dummy_input) + # Unflatten the tokenized inputs values expanding it to the shape [batch_size, num_choices, seq_length] + for k, v in tokenized_input.items(): + tokenized_input[k] = [v[i : i + num_choices] for i in range(0, len(v), num_choices)] + return dict(tokenized_input.convert_to_tensors(tensor_type=framework)) + return dict(preprocessor(dummy_input, return_tensors=framework)) + elif isinstance(preprocessor, ImageProcessingMixin): + if preprocessor.model_input_names[0] != "pixel_values": + raise ValueError( + f"The `preprocessor` is an image processor ({preprocessor.__class__.__name__}) and expects" + f' `model_input_names[0]` to be "pixel_values", but got {preprocessor.model_input_names[0]}' + ) + # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX + batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) + dummy_input = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) + return dict(preprocessor(images=dummy_input, return_tensors=framework)) + elif isinstance(preprocessor, FeatureExtractionMixin) and preprocessor.model_input_names[0] == "pixel_values": + # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX + batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) + dummy_input = self._generate_dummy_images(batch_size, num_channels, image_height, image_width) + return dict(preprocessor(images=dummy_input, return_tensors=framework)) + elif ( + isinstance(preprocessor, FeatureExtractionMixin) and preprocessor.model_input_names[0] == "input_features" + ): + # If dynamic axis (-1) we forward with a fixed dimension of 2 samples to avoid optimizations made by ONNX + batch_size = compute_effective_axis_dimension(batch_size, fixed_dimension=OnnxConfig.default_fixed_batch) + dummy_input = self._generate_dummy_audio(batch_size, sampling_rate, time_duration, frequency) + return dict(preprocessor(dummy_input, return_tensors=framework)) + else: + raise ValueError( + "Unable to generate dummy inputs for the model. Please provide a tokenizer or a preprocessor." + ) + + def generate_dummy_inputs_onnxruntime(self, reference_model_inputs: Mapping[str, Any]) -> Mapping[str, Any]: + """ + Generate inputs for ONNX Runtime using the reference model inputs. Override this to run inference with seq2seq + models which have the encoder and decoder exported as separate ONNX files. + + Args: + reference_model_inputs ([`Mapping[str, Tensor]`): + Reference inputs for the model. + + Returns: + `Mapping[str, Tensor]`: The mapping holding the kwargs to provide to the model's forward function + """ + return reference_model_inputs + + def patch_ops(self): + for spec in self._patching_specs: + custom_op = spec.custom_op if spec.op_wrapper is None else spec.op_wrapper(spec.custom_op) + setattr(spec.o, spec.name, custom_op) + + def restore_ops(self): + for spec in self._patching_specs: + orig_op = spec.orig_op if spec.op_wrapper is None else spec.op_wrapper(spec.orig_op) + setattr(spec.o, spec.name, orig_op) + + @classmethod + def flatten_output_collection_property(cls, name: str, field: Iterable[Any]) -> Dict[str, Any]: + """ + Flatten any potential nested structure expanding the name of the field with the index of the element within the + structure. + + Args: + name: The name of the nested structure + field: The structure to, potentially, be flattened + + Returns: + (Dict[str, Any]): Outputs with flattened structure and key mapping this new structure. + + """ + from itertools import chain + + return {f"{name}.{idx}": item for idx, item in enumerate(chain.from_iterable(field))} + + +class OnnxConfigWithPast(OnnxConfig, ABC): + def __init__( + self, + config: "PretrainedConfig", + task: str = "default", + patching_specs: List[PatchingSpec] = None, + use_past: bool = False, + ): + super().__init__(config, task=task, patching_specs=patching_specs) + self.use_past = use_past + + @classmethod + def with_past(cls, config: "PretrainedConfig", task: str = "default") -> "OnnxConfigWithPast": + """ + Instantiate a OnnxConfig with `use_past` attribute set to True + + Args: + config: The underlying model's config to use when exporting to ONNX + + Returns: + OnnxConfig with `.use_past = True` + """ + return cls(config, task=task, use_past=True) + + @property + def outputs(self) -> Mapping[str, Mapping[int, str]]: + common_outputs = super().outputs + if self.use_past: + self.fill_with_past_key_values_(common_outputs, direction="outputs") + + return common_outputs + + @property + def values_override(self) -> Optional[Mapping[str, Any]]: + if hasattr(self._config, "use_cache"): + return {"use_cache": self.use_past} + + return None + + @property + def num_layers(self) -> int: + """ + The number of layers attribute retrieved from the model config. Override this for model configs where the + number of layers attribute is not called `num_layers`. + """ + if not hasattr(self._config, "num_layers"): + raise AttributeError( + "could not find the number of layers attribute in the model configuration, override the num_layers" + " property of the model OnnxConfig to solve this" + ) + return self._config.num_layers + + @property + def num_attention_heads(self) -> int: + """ + The number of attention heads attribute retrieved from the model config. Override this for model configs where + the number of attention heads attribute is not called `num_attention_heads`. + """ + if not hasattr(self._config, "num_attention_heads"): + raise AttributeError( + "could not find the number of attention heads attribute in the model configuration, override the" + " num_attention_heads property of the model OnnxConfig to solve this" + ) + return self._config.num_attention_heads + + def generate_dummy_inputs( + self, + tokenizer: "PreTrainedTokenizerBase", + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + # TODO: should we set seq_length = 1 when self.use_past = True? + common_inputs = super().generate_dummy_inputs( + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + ) + + if self.use_past: + if not is_torch_available(): + raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed.") + else: + import torch + + batch, seqlen = common_inputs["input_ids"].shape + # Not using the same length for past_key_values + past_key_values_length = seqlen + 2 + shape = ( + batch, + self.num_attention_heads, + past_key_values_length, + self._config.hidden_size // self.num_attention_heads, + ) + + if "attention_mask" in common_inputs: + mask_dtype = common_inputs["attention_mask"].dtype + common_inputs["attention_mask"] = torch.cat( + [common_inputs["attention_mask"], torch.ones(batch, past_key_values_length, dtype=mask_dtype)], + dim=1, + ) + + common_inputs["past_key_values"] = [] + for _ in range(self.num_layers): + common_inputs["past_key_values"].append((torch.zeros(shape), torch.zeros(shape))) + + return common_inputs + + def fill_with_past_key_values_( + self, inputs_or_outputs: Mapping[str, Mapping[int, str]], direction: str, inverted_values_shape: bool = False + ): + """ + Fill the input_or_outputs mapping with past_key_values dynamic axes considering. + + Args: + inputs_or_outputs: The mapping to fill. + direction: either "inputs" or "outputs", it specifies whether input_or_outputs is the input mapping or the + output mapping, this is important for axes naming. + inverted_values_shape: + If `True`, store values on dynamic axis 1, else on axis 2. + + """ + if direction not in ["inputs", "outputs"]: + raise ValueError(f'direction must either be "inputs" or "outputs", but {direction} was given') + + name = "past_key_values" if direction == "inputs" else "present" + for i in range(self.num_layers): + inputs_or_outputs[f"{name}.{i}.key"] = {0: "batch", 2: "past_sequence + sequence"} + if inverted_values_shape: + inputs_or_outputs[f"{name}.{i}.value"] = {0: "batch", 1: "past_sequence + sequence"} + else: + inputs_or_outputs[f"{name}.{i}.value"] = {0: "batch", 2: "past_sequence + sequence"} + + def _flatten_past_key_values_(self, flattened_output, name, idx, t): + flattened_output[f"{name}.{idx}.key"] = t[0] + flattened_output[f"{name}.{idx}.value"] = t[1] + + def flatten_output_collection_property(self, name: str, field: Iterable[Any]) -> Dict[str, Any]: + flattened_output = {} + if name in ["present", "past_key_values"]: + for idx, t in enumerate(field): + self._flatten_past_key_values_(flattened_output, name, idx, t) + else: + flattened_output = super().flatten_output_collection_property(name, field) + + return flattened_output + + +class OnnxSeq2SeqConfigWithPast(OnnxConfigWithPast): + @property + def outputs(self) -> Mapping[str, Mapping[int, str]]: + common_outputs = super(OnnxConfigWithPast, self).outputs + # Renaming the outputs axes properly. + for name, axes_names in common_outputs.items(): + sequence_name = "encoder_sequence" if "encoder" in name else "decoder_sequence" + for axis_idx, name in axes_names.items(): + if "sequence" in name: + axes_names[axis_idx] = sequence_name + # We reset the value as the order in common_outputs (OrderedDict) is lost otherwise + else: + axes_names[axis_idx] = name + if self.use_past: + self.fill_with_past_key_values_(common_outputs, direction="outputs") + + return common_outputs + + @property + def num_layers(self) -> Tuple[int]: + try: + num_layers = super().num_layers + num_layers = (num_layers, num_layers) + except AttributeError: + if hasattr(self._config, "encoder_layers") and hasattr(self._config, "decoder_layers"): + num_layers = (self._config.encoder_layers, self._config.decoder_layers) + else: + raise AttributeError( + "could not find the number of encoder and decoder layers attributes in the model configuration," + " override the num_layers property of the model OnnxConfig to solve this" + ) + + return num_layers + + @property + def num_attention_heads(self) -> Tuple[int]: + try: + num_attention_heads = super().num_attention_heads + num_attention_heads = (num_attention_heads, num_attention_heads) + except AttributeError: + if hasattr(self._config, "encoder_attention_heads") and hasattr(self._config, "decoder_attention_heads"): + num_attention_heads = (self._config.encoder_attention_heads, self._config.decoder_attention_heads) + else: + raise AttributeError( + "could not find the number of attention heads for the encoder and the decoder attributes in the" + " model configuration, override the num_attention_heads property of the model OnnxConfig to solve" + " this" + ) + return num_attention_heads + + def generate_dummy_inputs( + self, + tokenizer: "PreTrainedTokenizerBase", + batch_size: int = -1, + seq_length: int = -1, + is_pair: bool = False, + framework: Optional[TensorType] = None, + ) -> Mapping[str, Any]: + encoder_inputs = super(OnnxConfigWithPast, self).generate_dummy_inputs( + tokenizer, batch_size=batch_size, seq_length=seq_length, is_pair=is_pair, framework=framework + ) + + # Generate decoder inputs + decoder_seq_length = seq_length if not self.use_past else 1 + decoder_inputs = super(OnnxConfigWithPast, self).generate_dummy_inputs( + tokenizer, batch_size=batch_size, seq_length=decoder_seq_length, is_pair=is_pair, framework=framework + ) + decoder_inputs = {f"decoder_{name}": tensor for name, tensor in decoder_inputs.items()} + common_inputs = dict(**encoder_inputs, **decoder_inputs) + + if self.use_past: + if not is_torch_available(): + raise ValueError("Cannot generate dummy past_keys inputs without PyTorch installed.") + else: + import torch + batch = common_inputs["input_ids"].shape[0] + encoder_seq_length = common_inputs["input_ids"].shape[1] + decoder_seq_length = common_inputs["decoder_input_ids"].shape[1] + num_encoder_attention_heads, num_decoder_attention_heads = self.num_attention_heads + encoder_shape = ( + batch, + num_encoder_attention_heads, + encoder_seq_length, + self._config.hidden_size // num_encoder_attention_heads, + ) + decoder_shape = ( + batch, + num_decoder_attention_heads, + # Not using the same length for past_key_values + decoder_seq_length + 3, + self._config.hidden_size // num_decoder_attention_heads, + ) + + common_inputs["past_key_values"] = [] + # If the number of encoder and decoder layers are present in the model configuration, both are considered + num_encoder_layers, num_decoder_layers = self.num_layers + min_num_layers = min(num_encoder_layers, num_decoder_layers) + max_num_layers = max(num_encoder_layers, num_decoder_layers) - min_num_layers + remaining_side_name = "encoder" if num_encoder_layers > num_decoder_layers else "decoder" + + for _ in range(min_num_layers): + # For encoder-decoder models, past_key_values contains pre-computed values for both the encoder and the + # decoder layers, hence a tuple of 4 tensors instead of 2 + common_inputs["past_key_values"].append( + ( + torch.zeros(decoder_shape), + torch.zeros(decoder_shape), + torch.zeros(encoder_shape), + torch.zeros(encoder_shape), + ) + ) + + # TODO: test this. + shape = encoder_shape if remaining_side_name == "encoder" else decoder_shape + for _ in range(min_num_layers, max_num_layers): + common_inputs["past_key_values"].append((torch.zeros(shape), torch.zeros(shape))) + + return common_inputs + + def fill_with_past_key_values_(self, inputs_or_outputs: Mapping[str, Mapping[int, str]], direction: str): + if direction not in ["inputs", "outputs"]: + raise ValueError(f'direction must either be "inputs" or "outputs", but {direction} was given') + + name = "past_key_values" if direction == "inputs" else "present" + + # If the number of encoder and decoder layers are present in the model configuration, both are considered + num_encoder_layers, num_decoder_layers = self.num_layers + min_num_layers = min(num_encoder_layers, num_decoder_layers) + max_num_layers = max(num_encoder_layers, num_decoder_layers) - min_num_layers + remaining_side_name = "encoder" if num_encoder_layers > num_decoder_layers else "decoder" + + encoder_sequence = "past_encoder_sequence" + decoder_sequence = "past_decoder_sequence" if direction == "inputs" else "past_decoder_sequence + sequence" + + for i in range(min_num_layers): + inputs_or_outputs[f"{name}.{i}.decoder.key"] = {0: "batch", 2: decoder_sequence} + inputs_or_outputs[f"{name}.{i}.decoder.value"] = {0: "batch", 2: decoder_sequence} + inputs_or_outputs[f"{name}.{i}.encoder.key"] = {0: "batch", 2: encoder_sequence} + inputs_or_outputs[f"{name}.{i}.encoder.value"] = {0: "batch", 2: encoder_sequence} + + for i in range(min_num_layers, max_num_layers): + if remaining_side_name == "encoder": + axes_info = {0: "batch", 2: encoder_sequence} + else: + axes_info = {0: "batch", 2: decoder_sequence} + inputs_or_outputs[f"{name}.{i}.{remaining_side_name}.key"] = axes_info + + def _flatten_past_key_values_(self, flattened_output, name, idx, t): + flattened_output[f"{name}.{idx}.decoder.key"] = t[0] + flattened_output[f"{name}.{idx}.decoder.value"] = t[1] + flattened_output[f"{name}.{idx}.encoder.key"] = t[2] + flattened_output[f"{name}.{idx}.encoder.value"] = t[3] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/convert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/convert.py new file mode 100644 index 0000000000000000000000000000000000000000..9e9cc93c064b0b70ea0c6efd866fa51eacbfc9e8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/convert.py @@ -0,0 +1,494 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import warnings +from inspect import signature +from itertools import chain +from pathlib import Path +from typing import TYPE_CHECKING, Iterable, List, Tuple, Union + +import numpy as np +from packaging.version import Version, parse + +from ..tokenization_utils_base import PreTrainedTokenizerBase +from ..utils import ( + TensorType, + is_tf_available, + is_torch_available, + logging, +) +from .config import OnnxConfig + + +if is_torch_available(): + from ..modeling_utils import PreTrainedModel + from ..pytorch_utils import is_torch_less_than_1_11 + +if is_tf_available(): + from ..modeling_tf_utils import TFPreTrainedModel + +if TYPE_CHECKING: + from ..feature_extraction_utils import FeatureExtractionMixin + from ..processing_utils import ProcessorMixin + from ..tokenization_utils import PreTrainedTokenizer + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +# This is the minimal required version to support some ONNX Runtime features +ORT_QUANTIZE_MINIMUM_VERSION = parse("1.4.0") + + +def check_onnxruntime_requirements(minimum_version: Version): + """ + Check onnxruntime is installed and if the installed version match is recent enough + + Raises: + ImportError: If onnxruntime is not installed or too old version is found + """ + try: + import onnxruntime + + # Parse the version of the installed onnxruntime + ort_version = parse(onnxruntime.__version__) + + # We require 1.4.0 minimum + if ort_version < ORT_QUANTIZE_MINIMUM_VERSION: + raise ImportError( + f"We found an older version of onnxruntime ({onnxruntime.__version__}) " + f"but we require onnxruntime to be >= {minimum_version} to enable all the conversions options.\n" + "Please update onnxruntime by running `pip install --upgrade onnxruntime`" + ) + + except ImportError: + raise ImportError( + "onnxruntime doesn't seem to be currently installed. " + "Please install the onnxruntime by running `pip install onnxruntime`" + " and relaunch the conversion." + ) + + +def export_pytorch( + preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin", "ProcessorMixin"], + model: "PreTrainedModel", + config: OnnxConfig, + opset: int, + output: Path, + tokenizer: "PreTrainedTokenizer" = None, + device: str = "cpu", +) -> Tuple[List[str], List[str]]: + """ + Export a PyTorch model to an ONNX Intermediate Representation (IR) + + Args: + preprocessor: ([`PreTrainedTokenizer`], [`FeatureExtractionMixin`] or [`ProcessorMixin`]): + The preprocessor used for encoding the data. + model ([`PreTrainedModel`]): + The model to export. + config ([`~onnx.config.OnnxConfig`]): + The ONNX configuration associated with the exported model. + opset (`int`): + The version of the ONNX operator set to use. + output (`Path`): + Directory to store the exported ONNX model. + device (`str`, *optional*, defaults to `cpu`): + The device on which the ONNX model will be exported. Either `cpu` or `cuda`. + + Returns: + `Tuple[List[str], List[str]]`: A tuple with an ordered list of the model's inputs, and the named inputs from + the ONNX configuration. + """ + + if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: + raise ValueError("You cannot provide both a tokenizer and a preprocessor to export the model.") + if tokenizer is not None: + warnings.warn( + "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" + " `preprocessor` instead.", + FutureWarning, + ) + logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummmy inputs.") + preprocessor = tokenizer + + if issubclass(type(model), PreTrainedModel): + import torch + from torch.onnx import export as onnx_export + + logger.info(f"Using framework PyTorch: {torch.__version__}") + with torch.no_grad(): + model.config.return_dict = True + model.eval() + + # Check if we need to override certain configuration item + if config.values_override is not None: + logger.info(f"Overriding {len(config.values_override)} configuration item(s)") + for override_config_key, override_config_value in config.values_override.items(): + logger.info(f"\t- {override_config_key} -> {override_config_value}") + setattr(model.config, override_config_key, override_config_value) + + # Ensure inputs match + # TODO: Check when exporting QA we provide "is_pair=True" + model_inputs = config.generate_dummy_inputs(preprocessor, framework=TensorType.PYTORCH) + device = torch.device(device) + if device.type == "cuda" and torch.cuda.is_available(): + model.to(device) + model_inputs_device = {} + for k, v in model_inputs.items(): + if isinstance(v, Tuple): + model_inputs_device[k] = tuple( + x.to(device) if isinstance(x, torch.Tensor) else None for x in v + ) + elif isinstance(v, List): + model_inputs_device[k] = [ + tuple(x.to(device) if isinstance(x, torch.Tensor) else None for x in t) for t in v + ] + else: + model_inputs_device[k] = v.to(device) + + model_inputs = model_inputs_device + + inputs_match, matched_inputs = ensure_model_and_config_inputs_match(model, model_inputs.keys()) + onnx_outputs = list(config.outputs.keys()) + + if not inputs_match: + raise ValueError("Model and config inputs doesn't match") + + config.patch_ops() + + # PyTorch deprecated the `enable_onnx_checker` and `use_external_data_format` arguments in v1.11, + # so we check the torch version for backwards compatibility + if is_torch_less_than_1_11: + # export can work with named args but the dict containing named args + # has to be the last element of the args tuple. + try: + onnx_export( + model, + (model_inputs,), + f=output.as_posix(), + input_names=list(config.inputs.keys()), + output_names=onnx_outputs, + dynamic_axes=dict(chain(config.inputs.items(), config.outputs.items())), + do_constant_folding=True, + use_external_data_format=config.use_external_data_format(model.num_parameters()), + enable_onnx_checker=True, + opset_version=opset, + ) + except RuntimeError as err: + message = str(err) + if ( + message + == "Exporting model exceed maximum protobuf size of 2GB. Please call torch.onnx.export without" + " setting use_external_data_format parameter." + ): + message = ( + "Exporting model exceed maximum protobuf size of 2GB. Please call torch.onnx.export" + " without setting use_external_data_format parameter or try with torch 1.10+." + ) + raise RuntimeError(message) + else: + raise err + else: + onnx_export( + model, + (model_inputs,), + f=output.as_posix(), + input_names=list(config.inputs.keys()), + output_names=onnx_outputs, + dynamic_axes=dict(chain(config.inputs.items(), config.outputs.items())), + do_constant_folding=True, + opset_version=opset, + ) + + config.restore_ops() + + return matched_inputs, onnx_outputs + + +def export_tensorflow( + preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin"], + model: "TFPreTrainedModel", + config: OnnxConfig, + opset: int, + output: Path, + tokenizer: "PreTrainedTokenizer" = None, +) -> Tuple[List[str], List[str]]: + """ + Export a TensorFlow model to an ONNX Intermediate Representation (IR) + + Args: + preprocessor: ([`PreTrainedTokenizer`] or [`FeatureExtractionMixin`]): + The preprocessor used for encoding the data. + model ([`TFPreTrainedModel`]): + The model to export. + config ([`~onnx.config.OnnxConfig`]): + The ONNX configuration associated with the exported model. + opset (`int`): + The version of the ONNX operator set to use. + output (`Path`): + Directory to store the exported ONNX model. + + Returns: + `Tuple[List[str], List[str]]`: A tuple with an ordered list of the model's inputs, and the named inputs from + the ONNX configuration. + """ + import onnx + import tensorflow as tf + import tf2onnx + + if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: + raise ValueError("You cannot provide both a tokenizer and preprocessor to export the model.") + if tokenizer is not None: + warnings.warn( + "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" + " `preprocessor` instead.", + FutureWarning, + ) + logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummmy inputs.") + preprocessor = tokenizer + + model.config.return_dict = True + + # Check if we need to override certain configuration item + if config.values_override is not None: + logger.info(f"Overriding {len(config.values_override)} configuration item(s)") + for override_config_key, override_config_value in config.values_override.items(): + logger.info(f"\t- {override_config_key} -> {override_config_value}") + setattr(model.config, override_config_key, override_config_value) + + # Ensure inputs match + model_inputs = config.generate_dummy_inputs(preprocessor, framework=TensorType.TENSORFLOW) + inputs_match, matched_inputs = ensure_model_and_config_inputs_match(model, model_inputs.keys()) + onnx_outputs = list(config.outputs.keys()) + + input_signature = [ + tf.TensorSpec([None] * tensor.ndim, dtype=tensor.dtype, name=key) for key, tensor in model_inputs.items() + ] + onnx_model, _ = tf2onnx.convert.from_keras(model, input_signature, opset=opset) + onnx.save(onnx_model, output.as_posix()) + config.restore_ops() + + return matched_inputs, onnx_outputs + + +def export( + preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin", "ProcessorMixin"], + model: Union["PreTrainedModel", "TFPreTrainedModel"], + config: OnnxConfig, + opset: int, + output: Path, + tokenizer: "PreTrainedTokenizer" = None, + device: str = "cpu", +) -> Tuple[List[str], List[str]]: + """ + Export a Pytorch or TensorFlow model to an ONNX Intermediate Representation (IR) + + Args: + preprocessor: ([`PreTrainedTokenizer`], [`FeatureExtractionMixin`] or [`ProcessorMixin`]): + The preprocessor used for encoding the data. + model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model to export. + config ([`~onnx.config.OnnxConfig`]): + The ONNX configuration associated with the exported model. + opset (`int`): + The version of the ONNX operator set to use. + output (`Path`): + Directory to store the exported ONNX model. + device (`str`, *optional*, defaults to `cpu`): + The device on which the ONNX model will be exported. Either `cpu` or `cuda`. Only PyTorch is supported for + export on CUDA devices. + + Returns: + `Tuple[List[str], List[str]]`: A tuple with an ordered list of the model's inputs, and the named inputs from + the ONNX configuration. + """ + if not (is_torch_available() or is_tf_available()): + raise ImportError( + "Cannot convert because neither PyTorch nor TensorFlow are not installed. " + "Please install torch or tensorflow first." + ) + + if is_tf_available() and isinstance(model, TFPreTrainedModel) and device == "cuda": + raise RuntimeError("`tf2onnx` does not support export on CUDA device.") + + if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: + raise ValueError("You cannot provide both a tokenizer and a preprocessor to export the model.") + if tokenizer is not None: + warnings.warn( + "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" + " `preprocessor` instead.", + FutureWarning, + ) + logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummmy inputs.") + preprocessor = tokenizer + + if is_torch_available(): + from ..utils import torch_version + + if not config.is_torch_support_available: + logger.warning( + f"Unsupported PyTorch version for this model. Minimum required is {config.torch_onnx_minimum_version}," + f" got: {torch_version}" + ) + + if is_torch_available() and issubclass(type(model), PreTrainedModel): + return export_pytorch(preprocessor, model, config, opset, output, tokenizer=tokenizer, device=device) + elif is_tf_available() and issubclass(type(model), TFPreTrainedModel): + return export_tensorflow(preprocessor, model, config, opset, output, tokenizer=tokenizer) + + +def validate_model_outputs( + config: OnnxConfig, + preprocessor: Union["PreTrainedTokenizer", "FeatureExtractionMixin", "ProcessorMixin"], + reference_model: Union["PreTrainedModel", "TFPreTrainedModel"], + onnx_model: Path, + onnx_named_outputs: List[str], + atol: float, + tokenizer: "PreTrainedTokenizer" = None, +): + from onnxruntime import InferenceSession, SessionOptions + + logger.info("Validating ONNX model...") + + if isinstance(preprocessor, PreTrainedTokenizerBase) and tokenizer is not None: + raise ValueError("You cannot provide both a tokenizer and a preprocessor to validate the model outputs.") + if tokenizer is not None: + warnings.warn( + "The `tokenizer` argument is deprecated and will be removed in version 5 of Transformers. Use" + " `preprocessor` instead.", + FutureWarning, + ) + logger.info("Overwriting the `preprocessor` argument with `tokenizer` to generate dummmy inputs.") + preprocessor = tokenizer + + # generate inputs with a different batch_size and seq_len that was used for conversion to properly test + # dynamic input shapes. + if is_torch_available() and issubclass(type(reference_model), PreTrainedModel): + reference_model_inputs = config.generate_dummy_inputs( + preprocessor, + batch_size=config.default_fixed_batch + 1, + seq_length=config.default_fixed_sequence + 1, + framework=TensorType.PYTORCH, + ) + else: + reference_model_inputs = config.generate_dummy_inputs( + preprocessor, + batch_size=config.default_fixed_batch + 1, + seq_length=config.default_fixed_sequence + 1, + framework=TensorType.TENSORFLOW, + ) + + # Create ONNX Runtime session + options = SessionOptions() + session = InferenceSession(onnx_model.as_posix(), options, providers=["CPUExecutionProvider"]) + + # Compute outputs from the reference model + if is_torch_available() and issubclass(type(reference_model), PreTrainedModel): + reference_model.to("cpu") + ref_outputs = reference_model(**reference_model_inputs) + ref_outputs_dict = {} + + # We flatten potential collection of outputs (i.e. past_keys) to a flat structure + for name, value in ref_outputs.items(): + # Overwriting the output name as "present" since it is the name used for the ONNX outputs + # ("past_key_values" being taken for the ONNX inputs) + if name == "past_key_values": + name = "present" + if isinstance(value, (list, tuple)): + value = config.flatten_output_collection_property(name, value) + ref_outputs_dict.update(value) + else: + ref_outputs_dict[name] = value + + # Create onnxruntime inputs from the reference model inputs + reference_model_inputs_onnxruntime = config.generate_dummy_inputs_onnxruntime(reference_model_inputs) + + # We flatten potential collection of inputs (i.e. past_keys) + onnx_inputs = {} + for name, value in reference_model_inputs_onnxruntime.items(): + if isinstance(value, (list, tuple)): + value = config.flatten_output_collection_property(name, value) + onnx_inputs.update({tensor_name: pt_tensor.numpy() for tensor_name, pt_tensor in value.items()}) + else: + onnx_inputs[name] = value.numpy() + + # Compute outputs from the ONNX model + onnx_outputs = session.run(onnx_named_outputs, onnx_inputs) + + # Check we have a subset of the keys into onnx_outputs against ref_outputs + ref_outputs_set, onnx_outputs_set = set(ref_outputs_dict.keys()), set(onnx_named_outputs) + if not onnx_outputs_set.issubset(ref_outputs_set): + logger.info( + f"\t-[x] ONNX model output names {onnx_outputs_set} do not match reference model {ref_outputs_set}" + ) + + raise ValueError( + "Outputs doesn't match between reference model and ONNX exported model: " + f"{onnx_outputs_set.difference(ref_outputs_set)}" + ) + else: + logger.info(f"\t-[✓] ONNX model output names match reference model ({onnx_outputs_set})") + + # Check the shape and values match + for name, ort_value in zip(onnx_named_outputs, onnx_outputs): + if is_torch_available() and issubclass(type(reference_model), PreTrainedModel): + ref_value = ref_outputs_dict[name].detach().numpy() + else: + ref_value = ref_outputs_dict[name].numpy() + logger.info(f'\t- Validating ONNX Model output "{name}":') + + # Shape + if not ort_value.shape == ref_value.shape: + logger.info(f"\t\t-[x] shape {ort_value.shape} doesn't match {ref_value.shape}") + raise ValueError( + "Outputs shape doesn't match between reference model and ONNX exported model: " + f"Got {ref_value.shape} (reference) and {ort_value.shape} (ONNX)" + ) + else: + logger.info(f"\t\t-[✓] {ort_value.shape} matches {ref_value.shape}") + + # Values + if not np.allclose(ref_value, ort_value, atol=atol): + bad_indices = np.logical_not(np.isclose(ref_value, ort_value, atol=atol)) + logger.info(f"\t\t-[x] values not close enough (atol: {atol})") + raise ValueError( + "Outputs values doesn't match between reference model and ONNX exported model: " + f"Got max absolute difference of: {np.amax(np.abs(ref_value - ort_value))} for " + f"{ref_value[bad_indices]} vs {ort_value[bad_indices]}" + ) + else: + logger.info(f"\t\t-[✓] all values close (atol: {atol})") + + +def ensure_model_and_config_inputs_match( + model: Union["PreTrainedModel", "TFPreTrainedModel"], model_inputs: Iterable[str] +) -> Tuple[bool, List[str]]: + """ + + :param model_inputs: :param config_inputs: :return: + """ + if is_torch_available() and issubclass(type(model), PreTrainedModel): + forward_parameters = signature(model.forward).parameters + else: + forward_parameters = signature(model.call).parameters + model_inputs_set = set(model_inputs) + + # We are fine if config_inputs has more keys than model_inputs + forward_inputs_set = set(forward_parameters.keys()) + is_ok = model_inputs_set.issubset(forward_inputs_set) + + # Make sure the input order match (VERY IMPORTANT !!!!) + matching_inputs = forward_inputs_set.intersection(model_inputs_set) + ordered_inputs = [parameter for parameter in forward_parameters.keys() if parameter in matching_inputs] + return is_ok, ordered_inputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/features.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/features.py new file mode 100644 index 0000000000000000000000000000000000000000..1b0bf23d61213cf94a2c1e04650103a70cab4cfb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/features.py @@ -0,0 +1,749 @@ +import os +from functools import partial, reduce +from typing import TYPE_CHECKING, Callable, Dict, Optional, Tuple, Type, Union + +import transformers + +from .. import PretrainedConfig, is_tf_available, is_torch_available +from ..utils import TF2_WEIGHTS_NAME, WEIGHTS_NAME, logging +from .config import OnnxConfig + + +if TYPE_CHECKING: + from transformers import PreTrainedModel, TFPreTrainedModel + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +if is_torch_available(): + from transformers.models.auto import ( + AutoModel, + AutoModelForCausalLM, + AutoModelForImageClassification, + AutoModelForImageSegmentation, + AutoModelForMaskedImageModeling, + AutoModelForMaskedLM, + AutoModelForMultipleChoice, + AutoModelForObjectDetection, + AutoModelForQuestionAnswering, + AutoModelForSemanticSegmentation, + AutoModelForSeq2SeqLM, + AutoModelForSequenceClassification, + AutoModelForSpeechSeq2Seq, + AutoModelForTokenClassification, + AutoModelForVision2Seq, + ) +if is_tf_available(): + from transformers.models.auto import ( + TFAutoModel, + TFAutoModelForCausalLM, + TFAutoModelForMaskedLM, + TFAutoModelForMultipleChoice, + TFAutoModelForQuestionAnswering, + TFAutoModelForSemanticSegmentation, + TFAutoModelForSeq2SeqLM, + TFAutoModelForSequenceClassification, + TFAutoModelForTokenClassification, + ) +if not is_torch_available() and not is_tf_available(): + logger.warning( + "The ONNX export features are only supported for PyTorch or TensorFlow. You will not be able to export models" + " without one of these libraries installed." + ) + + +def supported_features_mapping( + *supported_features: str, onnx_config_cls: str = None +) -> Dict[str, Callable[[PretrainedConfig], OnnxConfig]]: + """ + Generate the mapping between supported the features and their corresponding OnnxConfig for a given model. + + Args: + *supported_features: The names of the supported features. + onnx_config_cls: The OnnxConfig full name corresponding to the model. + + Returns: + The dictionary mapping a feature to an OnnxConfig constructor. + """ + if onnx_config_cls is None: + raise ValueError("A OnnxConfig class must be provided") + + config_cls = transformers + for attr_name in onnx_config_cls.split("."): + config_cls = getattr(config_cls, attr_name) + mapping = {} + for feature in supported_features: + if "-with-past" in feature: + task = feature.replace("-with-past", "") + mapping[feature] = partial(config_cls.with_past, task=task) + else: + mapping[feature] = partial(config_cls.from_model_config, task=feature) + + return mapping + + +class FeaturesManager: + _TASKS_TO_AUTOMODELS = {} + _TASKS_TO_TF_AUTOMODELS = {} + if is_torch_available(): + _TASKS_TO_AUTOMODELS = { + "default": AutoModel, + "masked-lm": AutoModelForMaskedLM, + "causal-lm": AutoModelForCausalLM, + "seq2seq-lm": AutoModelForSeq2SeqLM, + "sequence-classification": AutoModelForSequenceClassification, + "token-classification": AutoModelForTokenClassification, + "multiple-choice": AutoModelForMultipleChoice, + "object-detection": AutoModelForObjectDetection, + "question-answering": AutoModelForQuestionAnswering, + "image-classification": AutoModelForImageClassification, + "image-segmentation": AutoModelForImageSegmentation, + "masked-im": AutoModelForMaskedImageModeling, + "semantic-segmentation": AutoModelForSemanticSegmentation, + "vision2seq-lm": AutoModelForVision2Seq, + "speech2seq-lm": AutoModelForSpeechSeq2Seq, + } + if is_tf_available(): + _TASKS_TO_TF_AUTOMODELS = { + "default": TFAutoModel, + "masked-lm": TFAutoModelForMaskedLM, + "causal-lm": TFAutoModelForCausalLM, + "seq2seq-lm": TFAutoModelForSeq2SeqLM, + "sequence-classification": TFAutoModelForSequenceClassification, + "token-classification": TFAutoModelForTokenClassification, + "multiple-choice": TFAutoModelForMultipleChoice, + "question-answering": TFAutoModelForQuestionAnswering, + "semantic-segmentation": TFAutoModelForSemanticSegmentation, + } + + # Set of model topologies we support associated to the features supported by each topology and the factory + _SUPPORTED_MODEL_TYPE = { + "albert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.albert.AlbertOnnxConfig", + ), + "bart": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + "sequence-classification", + "question-answering", + onnx_config_cls="models.bart.BartOnnxConfig", + ), + # BEiT cannot be used with the masked image modeling autoclass, so this feature is excluded here + "beit": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.beit.BeitOnnxConfig" + ), + "bert": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.bert.BertOnnxConfig", + ), + "big-bird": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.big_bird.BigBirdOnnxConfig", + ), + "bigbird-pegasus": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + "sequence-classification", + "question-answering", + onnx_config_cls="models.bigbird_pegasus.BigBirdPegasusOnnxConfig", + ), + "blenderbot": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.blenderbot.BlenderbotOnnxConfig", + ), + "blenderbot-small": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.blenderbot_small.BlenderbotSmallOnnxConfig", + ), + "bloom": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "sequence-classification", + "token-classification", + onnx_config_cls="models.bloom.BloomOnnxConfig", + ), + "camembert": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.camembert.CamembertOnnxConfig", + ), + "clip": supported_features_mapping( + "default", + onnx_config_cls="models.clip.CLIPOnnxConfig", + ), + "codegen": supported_features_mapping( + "default", + "causal-lm", + onnx_config_cls="models.codegen.CodeGenOnnxConfig", + ), + "convbert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.convbert.ConvBertOnnxConfig", + ), + "convnext": supported_features_mapping( + "default", + "image-classification", + onnx_config_cls="models.convnext.ConvNextOnnxConfig", + ), + "data2vec-text": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.data2vec.Data2VecTextOnnxConfig", + ), + "data2vec-vision": supported_features_mapping( + "default", + "image-classification", + # ONNX doesn't support `adaptive_avg_pool2d` yet + # "semantic-segmentation", + onnx_config_cls="models.data2vec.Data2VecVisionOnnxConfig", + ), + "deberta": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "token-classification", + "question-answering", + onnx_config_cls="models.deberta.DebertaOnnxConfig", + ), + "deberta-v2": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.deberta_v2.DebertaV2OnnxConfig", + ), + "deit": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.deit.DeiTOnnxConfig" + ), + "detr": supported_features_mapping( + "default", + "object-detection", + "image-segmentation", + onnx_config_cls="models.detr.DetrOnnxConfig", + ), + "distilbert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.distilbert.DistilBertOnnxConfig", + ), + "electra": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.electra.ElectraOnnxConfig", + ), + "flaubert": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.flaubert.FlaubertOnnxConfig", + ), + "gpt2": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "sequence-classification", + "token-classification", + onnx_config_cls="models.gpt2.GPT2OnnxConfig", + ), + "gptj": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "question-answering", + "sequence-classification", + onnx_config_cls="models.gptj.GPTJOnnxConfig", + ), + "gpt-neo": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "sequence-classification", + onnx_config_cls="models.gpt_neo.GPTNeoOnnxConfig", + ), + "groupvit": supported_features_mapping( + "default", + onnx_config_cls="models.groupvit.GroupViTOnnxConfig", + ), + "ibert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.ibert.IBertOnnxConfig", + ), + "imagegpt": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.imagegpt.ImageGPTOnnxConfig" + ), + "layoutlm": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "token-classification", + onnx_config_cls="models.layoutlm.LayoutLMOnnxConfig", + ), + "layoutlmv3": supported_features_mapping( + "default", + "question-answering", + "sequence-classification", + "token-classification", + onnx_config_cls="models.layoutlmv3.LayoutLMv3OnnxConfig", + ), + "levit": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.levit.LevitOnnxConfig" + ), + "longt5": supported_features_mapping( + "default", + "default-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.longt5.LongT5OnnxConfig", + ), + "longformer": supported_features_mapping( + "default", + "masked-lm", + "multiple-choice", + "question-answering", + "sequence-classification", + "token-classification", + onnx_config_cls="models.longformer.LongformerOnnxConfig", + ), + "marian": supported_features_mapping( + "default", + "default-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + "causal-lm", + "causal-lm-with-past", + onnx_config_cls="models.marian.MarianOnnxConfig", + ), + "mbart": supported_features_mapping( + "default", + "default-with-past", + "causal-lm", + "causal-lm-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + "sequence-classification", + "question-answering", + onnx_config_cls="models.mbart.MBartOnnxConfig", + ), + "mobilebert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.mobilebert.MobileBertOnnxConfig", + ), + "mobilenet-v1": supported_features_mapping( + "default", + "image-classification", + onnx_config_cls="models.mobilenet_v1.MobileNetV1OnnxConfig", + ), + "mobilenet-v2": supported_features_mapping( + "default", + "image-classification", + onnx_config_cls="models.mobilenet_v2.MobileNetV2OnnxConfig", + ), + "mobilevit": supported_features_mapping( + "default", + "image-classification", + onnx_config_cls="models.mobilevit.MobileViTOnnxConfig", + ), + "mt5": supported_features_mapping( + "default", + "default-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.mt5.MT5OnnxConfig", + ), + "m2m-100": supported_features_mapping( + "default", + "default-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.m2m_100.M2M100OnnxConfig", + ), + "owlvit": supported_features_mapping( + "default", + onnx_config_cls="models.owlvit.OwlViTOnnxConfig", + ), + "perceiver": supported_features_mapping( + "image-classification", + "masked-lm", + "sequence-classification", + onnx_config_cls="models.perceiver.PerceiverOnnxConfig", + ), + "poolformer": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.poolformer.PoolFormerOnnxConfig" + ), + "rembert": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.rembert.RemBertOnnxConfig", + ), + "resnet": supported_features_mapping( + "default", + "image-classification", + onnx_config_cls="models.resnet.ResNetOnnxConfig", + ), + "roberta": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.roberta.RobertaOnnxConfig", + ), + "roformer": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "token-classification", + "multiple-choice", + "question-answering", + "token-classification", + onnx_config_cls="models.roformer.RoFormerOnnxConfig", + ), + "segformer": supported_features_mapping( + "default", + "image-classification", + "semantic-segmentation", + onnx_config_cls="models.segformer.SegformerOnnxConfig", + ), + "squeezebert": supported_features_mapping( + "default", + "masked-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.squeezebert.SqueezeBertOnnxConfig", + ), + "swin": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.swin.SwinOnnxConfig" + ), + "t5": supported_features_mapping( + "default", + "default-with-past", + "seq2seq-lm", + "seq2seq-lm-with-past", + onnx_config_cls="models.t5.T5OnnxConfig", + ), + "vision-encoder-decoder": supported_features_mapping( + "vision2seq-lm", onnx_config_cls="models.vision_encoder_decoder.VisionEncoderDecoderOnnxConfig" + ), + "vit": supported_features_mapping( + "default", "image-classification", onnx_config_cls="models.vit.ViTOnnxConfig" + ), + "whisper": supported_features_mapping( + "default", + "default-with-past", + "speech2seq-lm", + "speech2seq-lm-with-past", + onnx_config_cls="models.whisper.WhisperOnnxConfig", + ), + "xlm": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.xlm.XLMOnnxConfig", + ), + "xlm-roberta": supported_features_mapping( + "default", + "masked-lm", + "causal-lm", + "sequence-classification", + "multiple-choice", + "token-classification", + "question-answering", + onnx_config_cls="models.xlm_roberta.XLMRobertaOnnxConfig", + ), + "yolos": supported_features_mapping( + "default", + "object-detection", + onnx_config_cls="models.yolos.YolosOnnxConfig", + ), + } + + AVAILABLE_FEATURES = sorted(reduce(lambda s1, s2: s1 | s2, (v.keys() for v in _SUPPORTED_MODEL_TYPE.values()))) + + @staticmethod + def get_supported_features_for_model_type( + model_type: str, model_name: Optional[str] = None + ) -> Dict[str, Callable[[PretrainedConfig], OnnxConfig]]: + """ + Tries to retrieve the feature -> OnnxConfig constructor map from the model type. + + Args: + model_type (`str`): + The model type to retrieve the supported features for. + model_name (`str`, *optional*): + The name attribute of the model object, only used for the exception message. + + Returns: + The dictionary mapping each feature to a corresponding OnnxConfig constructor. + """ + model_type = model_type.lower() + if model_type not in FeaturesManager._SUPPORTED_MODEL_TYPE: + model_type_and_model_name = f"{model_type} ({model_name})" if model_name else model_type + raise KeyError( + f"{model_type_and_model_name} is not supported yet. " + f"Only {list(FeaturesManager._SUPPORTED_MODEL_TYPE.keys())} are supported. " + f"If you want to support {model_type} please propose a PR or open up an issue." + ) + return FeaturesManager._SUPPORTED_MODEL_TYPE[model_type] + + @staticmethod + def feature_to_task(feature: str) -> str: + return feature.replace("-with-past", "") + + @staticmethod + def _validate_framework_choice(framework: str): + """ + Validates if the framework requested for the export is both correct and available, otherwise throws an + exception. + """ + if framework not in ["pt", "tf"]: + raise ValueError( + f"Only two frameworks are supported for ONNX export: pt or tf, but {framework} was provided." + ) + elif framework == "pt" and not is_torch_available(): + raise RuntimeError("Cannot export model to ONNX using PyTorch because no PyTorch package was found.") + elif framework == "tf" and not is_tf_available(): + raise RuntimeError("Cannot export model to ONNX using TensorFlow because no TensorFlow package was found.") + + @staticmethod + def get_model_class_for_feature(feature: str, framework: str = "pt") -> Type: + """ + Attempts to retrieve an AutoModel class from a feature name. + + Args: + feature (`str`): + The feature required. + framework (`str`, *optional*, defaults to `"pt"`): + The framework to use for the export. + + Returns: + The AutoModel class corresponding to the feature. + """ + task = FeaturesManager.feature_to_task(feature) + FeaturesManager._validate_framework_choice(framework) + if framework == "pt": + task_to_automodel = FeaturesManager._TASKS_TO_AUTOMODELS + else: + task_to_automodel = FeaturesManager._TASKS_TO_TF_AUTOMODELS + if task not in task_to_automodel: + raise KeyError( + f"Unknown task: {feature}. Possible values are {list(FeaturesManager._TASKS_TO_AUTOMODELS.values())}" + ) + + return task_to_automodel[task] + + @staticmethod + def determine_framework(model: str, framework: str = None) -> str: + """ + Determines the framework to use for the export. + + The priority is in the following order: + 1. User input via `framework`. + 2. If local checkpoint is provided, use the same framework as the checkpoint. + 3. Available framework in environment, with priority given to PyTorch + + Args: + model (`str`): + The name of the model to export. + framework (`str`, *optional*, defaults to `None`): + The framework to use for the export. See above for priority if none provided. + + Returns: + The framework to use for the export. + + """ + if framework is not None: + return framework + + framework_map = {"pt": "PyTorch", "tf": "TensorFlow"} + exporter_map = {"pt": "torch", "tf": "tf2onnx"} + + if os.path.isdir(model): + if os.path.isfile(os.path.join(model, WEIGHTS_NAME)): + framework = "pt" + elif os.path.isfile(os.path.join(model, TF2_WEIGHTS_NAME)): + framework = "tf" + else: + raise FileNotFoundError( + "Cannot determine framework from given checkpoint location." + f" There should be a {WEIGHTS_NAME} for PyTorch" + f" or {TF2_WEIGHTS_NAME} for TensorFlow." + ) + logger.info(f"Local {framework_map[framework]} model found.") + else: + if is_torch_available(): + framework = "pt" + elif is_tf_available(): + framework = "tf" + else: + raise EnvironmentError("Neither PyTorch nor TensorFlow found in environment. Cannot export to ONNX.") + + logger.info(f"Framework not requested. Using {exporter_map[framework]} to export to ONNX.") + + return framework + + @staticmethod + def get_model_from_feature( + feature: str, model: str, framework: str = None, cache_dir: str = None + ) -> Union["PreTrainedModel", "TFPreTrainedModel"]: + """ + Attempts to retrieve a model from a model's name and the feature to be enabled. + + Args: + feature (`str`): + The feature required. + model (`str`): + The name of the model to export. + framework (`str`, *optional*, defaults to `None`): + The framework to use for the export. See `FeaturesManager.determine_framework` for the priority should + none be provided. + + Returns: + The instance of the model. + + """ + framework = FeaturesManager.determine_framework(model, framework) + model_class = FeaturesManager.get_model_class_for_feature(feature, framework) + try: + model = model_class.from_pretrained(model, cache_dir=cache_dir) + except OSError: + if framework == "pt": + logger.info("Loading TensorFlow model in PyTorch before exporting to ONNX.") + model = model_class.from_pretrained(model, from_tf=True, cache_dir=cache_dir) + else: + logger.info("Loading PyTorch model in TensorFlow before exporting to ONNX.") + model = model_class.from_pretrained(model, from_pt=True, cache_dir=cache_dir) + return model + + @staticmethod + def check_supported_model_or_raise( + model: Union["PreTrainedModel", "TFPreTrainedModel"], feature: str = "default" + ) -> Tuple[str, Callable]: + """ + Check whether or not the model has the requested features. + + Args: + model: The model to export. + feature: The name of the feature to check if it is available. + + Returns: + (str) The type of the model (OnnxConfig) The OnnxConfig instance holding the model export properties. + + """ + model_type = model.config.model_type.replace("_", "-") + model_name = getattr(model, "name", "") + model_features = FeaturesManager.get_supported_features_for_model_type(model_type, model_name=model_name) + if feature not in model_features: + raise ValueError( + f"{model.config.model_type} doesn't support feature {feature}. Supported values are: {model_features}" + ) + + return model.config.model_type, FeaturesManager._SUPPORTED_MODEL_TYPE[model_type][feature] + + def get_config(model_type: str, feature: str) -> OnnxConfig: + """ + Gets the OnnxConfig for a model_type and feature combination. + + Args: + model_type (`str`): + The model type to retrieve the config for. + feature (`str`): + The feature to retrieve the config for. + + Returns: + `OnnxConfig`: config for the combination + """ + return FeaturesManager._SUPPORTED_MODEL_TYPE[model_type][feature] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..9672b0a96af88ffa2c7e791d1f4d7c818174247f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/onnx/utils.py @@ -0,0 +1,109 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ctypes import c_float, sizeof +from enum import Enum +from typing import TYPE_CHECKING, Optional, Union + + +if TYPE_CHECKING: + from .. import AutoFeatureExtractor, AutoProcessor, AutoTokenizer # tests_ignore + + +class ParameterFormat(Enum): + Float = c_float + + @property + def size(self) -> int: + """ + Number of byte required for this data type + + Returns: + Integer > 0 + """ + return sizeof(self.value) + + +def compute_effective_axis_dimension(dimension: int, fixed_dimension: int, num_token_to_add: int = 0) -> int: + """ + + Args: + dimension: + fixed_dimension: + num_token_to_add: + + Returns: + + """ + # < 0 is possible if using a dynamic axis + if dimension <= 0: + dimension = fixed_dimension + + dimension -= num_token_to_add + return dimension + + +def compute_serialized_parameters_size(num_parameters: int, dtype: ParameterFormat) -> int: + """ + Compute the size taken by all the parameters in the given the storage format when serializing the model + + Args: + num_parameters: Number of parameters to be saved + dtype: The data format each parameter will be saved + + Returns: + Size (in byte) taken to save all the parameters + """ + return num_parameters * dtype.size + + +def get_preprocessor(model_name: str) -> Optional[Union["AutoTokenizer", "AutoFeatureExtractor", "AutoProcessor"]]: + """ + Gets a preprocessor (tokenizer, feature extractor or processor) that is available for `model_name`. + + Args: + model_name (`str`): Name of the model for which a preprocessor are loaded. + + Returns: + `Optional[Union[AutoTokenizer, AutoFeatureExtractor, AutoProcessor]]`: + If a processor is found, it is returned. Otherwise, if a tokenizer or a feature extractor exists, it is + returned. If both a tokenizer and a feature extractor exist, an error is raised. The function returns + `None` if no preprocessor is found. + """ + # Avoid circular imports by only importing this here. + from .. import AutoFeatureExtractor, AutoProcessor, AutoTokenizer # tests_ignore + + try: + return AutoProcessor.from_pretrained(model_name) + except (ValueError, OSError, KeyError): + tokenizer, feature_extractor = None, None + try: + tokenizer = AutoTokenizer.from_pretrained(model_name) + except (OSError, KeyError): + pass + try: + feature_extractor = AutoFeatureExtractor.from_pretrained(model_name) + except (OSError, KeyError): + pass + + if tokenizer is not None and feature_extractor is not None: + raise ValueError( + f"Couldn't auto-detect preprocessor for {model_name}. Found both a tokenizer and a feature extractor." + ) + elif tokenizer is None and feature_extractor is None: + return None + elif tokenizer is not None: + return tokenizer + else: + return feature_extractor diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..84d461cd1ae7301f79bd774d7601d7b3bb8d2ce6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/__init__.py @@ -0,0 +1,988 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import io +import json +import os +import warnings +from pathlib import Path +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union + +from huggingface_hub import model_info +from numpy import isin + +from ..configuration_utils import PretrainedConfig +from ..dynamic_module_utils import get_class_from_dynamic_module +from ..feature_extraction_utils import PreTrainedFeatureExtractor +from ..image_processing_utils import BaseImageProcessor +from ..models.auto.configuration_auto import AutoConfig +from ..models.auto.feature_extraction_auto import FEATURE_EXTRACTOR_MAPPING, AutoFeatureExtractor +from ..models.auto.image_processing_auto import IMAGE_PROCESSOR_MAPPING, AutoImageProcessor +from ..models.auto.modeling_auto import AutoModelForDepthEstimation +from ..models.auto.tokenization_auto import TOKENIZER_MAPPING, AutoTokenizer +from ..tokenization_utils import PreTrainedTokenizer +from ..utils import ( + HUGGINGFACE_CO_RESOLVE_ENDPOINT, + is_kenlm_available, + is_offline_mode, + is_pyctcdecode_available, + is_tf_available, + is_torch_available, + logging, +) +from .audio_classification import AudioClassificationPipeline +from .automatic_speech_recognition import AutomaticSpeechRecognitionPipeline +from .base import ( + ArgumentHandler, + CsvPipelineDataFormat, + JsonPipelineDataFormat, + PipedPipelineDataFormat, + Pipeline, + PipelineDataFormat, + PipelineException, + PipelineRegistry, + get_default_model_and_revision, + infer_framework_load_model, +) +from .conversational import Conversation, ConversationalPipeline +from .depth_estimation import DepthEstimationPipeline +from .document_question_answering import DocumentQuestionAnsweringPipeline +from .feature_extraction import FeatureExtractionPipeline +from .fill_mask import FillMaskPipeline +from .image_classification import ImageClassificationPipeline +from .image_segmentation import ImageSegmentationPipeline +from .image_to_text import ImageToTextPipeline +from .mask_generation import MaskGenerationPipeline +from .object_detection import ObjectDetectionPipeline +from .question_answering import QuestionAnsweringArgumentHandler, QuestionAnsweringPipeline +from .table_question_answering import TableQuestionAnsweringArgumentHandler, TableQuestionAnsweringPipeline +from .text2text_generation import SummarizationPipeline, Text2TextGenerationPipeline, TranslationPipeline +from .text_classification import TextClassificationPipeline +from .text_generation import TextGenerationPipeline +from .token_classification import ( + AggregationStrategy, + NerPipeline, + TokenClassificationArgumentHandler, + TokenClassificationPipeline, +) +from .video_classification import VideoClassificationPipeline +from .visual_question_answering import VisualQuestionAnsweringPipeline +from .zero_shot_audio_classification import ZeroShotAudioClassificationPipeline +from .zero_shot_classification import ZeroShotClassificationArgumentHandler, ZeroShotClassificationPipeline +from .zero_shot_image_classification import ZeroShotImageClassificationPipeline +from .zero_shot_object_detection import ZeroShotObjectDetectionPipeline + + +if is_tf_available(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import ( + TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + TF_MODEL_WITH_LM_HEAD_MAPPING, + TFAutoModel, + TFAutoModelForCausalLM, + TFAutoModelForImageClassification, + TFAutoModelForMaskedLM, + TFAutoModelForQuestionAnswering, + TFAutoModelForSeq2SeqLM, + TFAutoModelForSequenceClassification, + TFAutoModelForTableQuestionAnswering, + TFAutoModelForTokenClassification, + TFAutoModelForVision2Seq, + TFAutoModelForZeroShotImageClassification, + ) + +if is_torch_available(): + import torch + + from ..models.auto.modeling_auto import ( + MODEL_FOR_MASKED_LM_MAPPING, + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING, + AutoModel, + AutoModelForAudioClassification, + AutoModelForCausalLM, + AutoModelForCTC, + AutoModelForDocumentQuestionAnswering, + AutoModelForImageClassification, + AutoModelForImageSegmentation, + AutoModelForMaskedLM, + AutoModelForMaskGeneration, + AutoModelForObjectDetection, + AutoModelForQuestionAnswering, + AutoModelForSemanticSegmentation, + AutoModelForSeq2SeqLM, + AutoModelForSequenceClassification, + AutoModelForSpeechSeq2Seq, + AutoModelForTableQuestionAnswering, + AutoModelForTokenClassification, + AutoModelForVideoClassification, + AutoModelForVision2Seq, + AutoModelForVisualQuestionAnswering, + AutoModelForZeroShotImageClassification, + AutoModelForZeroShotObjectDetection, + ) + + +if TYPE_CHECKING: + from ..modeling_tf_utils import TFPreTrainedModel + from ..modeling_utils import PreTrainedModel + from ..tokenization_utils_fast import PreTrainedTokenizerFast + + +logger = logging.get_logger(__name__) + + +# Register all the supported tasks here +TASK_ALIASES = { + "sentiment-analysis": "text-classification", + "ner": "token-classification", + "vqa": "visual-question-answering", +} +SUPPORTED_TASKS = { + "audio-classification": { + "impl": AudioClassificationPipeline, + "tf": (), + "pt": (AutoModelForAudioClassification,) if is_torch_available() else (), + "default": {"model": {"pt": ("superb/wav2vec2-base-superb-ks", "372e048")}}, + "type": "audio", + }, + "automatic-speech-recognition": { + "impl": AutomaticSpeechRecognitionPipeline, + "tf": (), + "pt": (AutoModelForCTC, AutoModelForSpeechSeq2Seq) if is_torch_available() else (), + "default": {"model": {"pt": ("facebook/wav2vec2-base-960h", "55bb623")}}, + "type": "multimodal", + }, + "feature-extraction": { + "impl": FeatureExtractionPipeline, + "tf": (TFAutoModel,) if is_tf_available() else (), + "pt": (AutoModel,) if is_torch_available() else (), + "default": {"model": {"pt": ("distilbert-base-cased", "935ac13"), "tf": ("distilbert-base-cased", "935ac13")}}, + "type": "multimodal", + }, + "text-classification": { + "impl": TextClassificationPipeline, + "tf": (TFAutoModelForSequenceClassification,) if is_tf_available() else (), + "pt": (AutoModelForSequenceClassification,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("distilbert-base-uncased-finetuned-sst-2-english", "af0f99b"), + "tf": ("distilbert-base-uncased-finetuned-sst-2-english", "af0f99b"), + }, + }, + "type": "text", + }, + "token-classification": { + "impl": TokenClassificationPipeline, + "tf": (TFAutoModelForTokenClassification,) if is_tf_available() else (), + "pt": (AutoModelForTokenClassification,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("dbmdz/bert-large-cased-finetuned-conll03-english", "f2482bf"), + "tf": ("dbmdz/bert-large-cased-finetuned-conll03-english", "f2482bf"), + }, + }, + "type": "text", + }, + "question-answering": { + "impl": QuestionAnsweringPipeline, + "tf": (TFAutoModelForQuestionAnswering,) if is_tf_available() else (), + "pt": (AutoModelForQuestionAnswering,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("distilbert-base-cased-distilled-squad", "626af31"), + "tf": ("distilbert-base-cased-distilled-squad", "626af31"), + }, + }, + "type": "text", + }, + "table-question-answering": { + "impl": TableQuestionAnsweringPipeline, + "pt": (AutoModelForTableQuestionAnswering,) if is_torch_available() else (), + "tf": (TFAutoModelForTableQuestionAnswering,) if is_tf_available() else (), + "default": { + "model": { + "pt": ("google/tapas-base-finetuned-wtq", "69ceee2"), + "tf": ("google/tapas-base-finetuned-wtq", "69ceee2"), + }, + }, + "type": "text", + }, + "visual-question-answering": { + "impl": VisualQuestionAnsweringPipeline, + "pt": (AutoModelForVisualQuestionAnswering,) if is_torch_available() else (), + "tf": (), + "default": { + "model": {"pt": ("dandelin/vilt-b32-finetuned-vqa", "4355f59")}, + }, + "type": "multimodal", + }, + "document-question-answering": { + "impl": DocumentQuestionAnsweringPipeline, + "pt": (AutoModelForDocumentQuestionAnswering,) if is_torch_available() else (), + "tf": (), + "default": { + "model": {"pt": ("impira/layoutlm-document-qa", "52e01b3")}, + }, + "type": "multimodal", + }, + "fill-mask": { + "impl": FillMaskPipeline, + "tf": (TFAutoModelForMaskedLM,) if is_tf_available() else (), + "pt": (AutoModelForMaskedLM,) if is_torch_available() else (), + "default": {"model": {"pt": ("distilroberta-base", "ec58a5b"), "tf": ("distilroberta-base", "ec58a5b")}}, + "type": "text", + }, + "summarization": { + "impl": SummarizationPipeline, + "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), + "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), + "default": {"model": {"pt": ("sshleifer/distilbart-cnn-12-6", "a4f8f3e"), "tf": ("t5-small", "d769bba")}}, + "type": "text", + }, + # This task is a special case as it's parametrized by SRC, TGT languages. + "translation": { + "impl": TranslationPipeline, + "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), + "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), + "default": { + ("en", "fr"): {"model": {"pt": ("t5-base", "686f1db"), "tf": ("t5-base", "686f1db")}}, + ("en", "de"): {"model": {"pt": ("t5-base", "686f1db"), "tf": ("t5-base", "686f1db")}}, + ("en", "ro"): {"model": {"pt": ("t5-base", "686f1db"), "tf": ("t5-base", "686f1db")}}, + }, + "type": "text", + }, + "text2text-generation": { + "impl": Text2TextGenerationPipeline, + "tf": (TFAutoModelForSeq2SeqLM,) if is_tf_available() else (), + "pt": (AutoModelForSeq2SeqLM,) if is_torch_available() else (), + "default": {"model": {"pt": ("t5-base", "686f1db"), "tf": ("t5-base", "686f1db")}}, + "type": "text", + }, + "text-generation": { + "impl": TextGenerationPipeline, + "tf": (TFAutoModelForCausalLM,) if is_tf_available() else (), + "pt": (AutoModelForCausalLM,) if is_torch_available() else (), + "default": {"model": {"pt": ("gpt2", "6c0e608"), "tf": ("gpt2", "6c0e608")}}, + "type": "text", + }, + "zero-shot-classification": { + "impl": ZeroShotClassificationPipeline, + "tf": (TFAutoModelForSequenceClassification,) if is_tf_available() else (), + "pt": (AutoModelForSequenceClassification,) if is_torch_available() else (), + "default": { + "model": {"pt": ("facebook/bart-large-mnli", "c626438"), "tf": ("roberta-large-mnli", "130fb28")}, + "config": {"pt": ("facebook/bart-large-mnli", "c626438"), "tf": ("roberta-large-mnli", "130fb28")}, + }, + "type": "text", + }, + "zero-shot-image-classification": { + "impl": ZeroShotImageClassificationPipeline, + "tf": (TFAutoModelForZeroShotImageClassification,) if is_tf_available() else (), + "pt": (AutoModelForZeroShotImageClassification,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("openai/clip-vit-base-patch32", "f4881ba"), + "tf": ("openai/clip-vit-base-patch32", "f4881ba"), + } + }, + "type": "multimodal", + }, + "zero-shot-audio-classification": { + "impl": ZeroShotAudioClassificationPipeline, + "tf": (), + "pt": (AutoModel,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("laion/clap-htsat-fused", "973b6e5"), + } + }, + "type": "multimodal", + }, + "conversational": { + "impl": ConversationalPipeline, + "tf": (TFAutoModelForSeq2SeqLM, TFAutoModelForCausalLM) if is_tf_available() else (), + "pt": (AutoModelForSeq2SeqLM, AutoModelForCausalLM) if is_torch_available() else (), + "default": { + "model": {"pt": ("microsoft/DialoGPT-medium", "8bada3b"), "tf": ("microsoft/DialoGPT-medium", "8bada3b")} + }, + "type": "text", + }, + "image-classification": { + "impl": ImageClassificationPipeline, + "tf": (TFAutoModelForImageClassification,) if is_tf_available() else (), + "pt": (AutoModelForImageClassification,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("google/vit-base-patch16-224", "5dca96d"), + "tf": ("google/vit-base-patch16-224", "5dca96d"), + } + }, + "type": "image", + }, + "image-segmentation": { + "impl": ImageSegmentationPipeline, + "tf": (), + "pt": (AutoModelForImageSegmentation, AutoModelForSemanticSegmentation) if is_torch_available() else (), + "default": {"model": {"pt": ("facebook/detr-resnet-50-panoptic", "fc15262")}}, + "type": "multimodal", + }, + "image-to-text": { + "impl": ImageToTextPipeline, + "tf": (TFAutoModelForVision2Seq,) if is_tf_available() else (), + "pt": (AutoModelForVision2Seq,) if is_torch_available() else (), + "default": { + "model": { + "pt": ("ydshieh/vit-gpt2-coco-en", "65636df"), + "tf": ("ydshieh/vit-gpt2-coco-en", "65636df"), + } + }, + "type": "multimodal", + }, + "object-detection": { + "impl": ObjectDetectionPipeline, + "tf": (), + "pt": (AutoModelForObjectDetection,) if is_torch_available() else (), + "default": {"model": {"pt": ("facebook/detr-resnet-50", "2729413")}}, + "type": "multimodal", + }, + "zero-shot-object-detection": { + "impl": ZeroShotObjectDetectionPipeline, + "tf": (), + "pt": (AutoModelForZeroShotObjectDetection,) if is_torch_available() else (), + "default": {"model": {"pt": ("google/owlvit-base-patch32", "17740e1")}}, + "type": "multimodal", + }, + "depth-estimation": { + "impl": DepthEstimationPipeline, + "tf": (), + "pt": (AutoModelForDepthEstimation,) if is_torch_available() else (), + "default": {"model": {"pt": ("Intel/dpt-large", "e93beec")}}, + "type": "image", + }, + "video-classification": { + "impl": VideoClassificationPipeline, + "tf": (), + "pt": (AutoModelForVideoClassification,) if is_torch_available() else (), + "default": {"model": {"pt": ("MCG-NJU/videomae-base-finetuned-kinetics", "4800870")}}, + "type": "video", + }, + "mask-generation": { + "impl": MaskGenerationPipeline, + "tf": (), + "pt": (AutoModelForMaskGeneration,) if is_torch_available() else (), + "default": {"model": {"pt": ("facebook/sam-vit-huge", "997b15")}}, + "type": "multimodal", + }, +} + +NO_FEATURE_EXTRACTOR_TASKS = set() +NO_IMAGE_PROCESSOR_TASKS = set() +NO_TOKENIZER_TASKS = set() +# Those model configs are special, they are generic over their task, meaning +# any tokenizer/feature_extractor might be use for a given model so we cannot +# use the statically defined TOKENIZER_MAPPING and FEATURE_EXTRACTOR_MAPPING to +# see if the model defines such objects or not. +MULTI_MODEL_CONFIGS = {"SpeechEncoderDecoderConfig", "VisionEncoderDecoderConfig", "VisionTextDualEncoderConfig"} +for task, values in SUPPORTED_TASKS.items(): + if values["type"] == "text": + NO_FEATURE_EXTRACTOR_TASKS.add(task) + NO_IMAGE_PROCESSOR_TASKS.add(task) + elif values["type"] in {"image", "video"}: + NO_TOKENIZER_TASKS.add(task) + elif values["type"] in {"audio"}: + NO_TOKENIZER_TASKS.add(task) + NO_IMAGE_PROCESSOR_TASKS.add(task) + elif values["type"] != "multimodal": + raise ValueError(f"SUPPORTED_TASK {task} contains invalid type {values['type']}") + +PIPELINE_REGISTRY = PipelineRegistry(supported_tasks=SUPPORTED_TASKS, task_aliases=TASK_ALIASES) + + +def get_supported_tasks() -> List[str]: + """ + Returns a list of supported task strings. + """ + return PIPELINE_REGISTRY.get_supported_tasks() + + +def get_task(model: str, use_auth_token: Optional[str] = None) -> str: + if is_offline_mode(): + raise RuntimeError("You cannot infer task automatically within `pipeline` when using offline mode") + try: + info = model_info(model, token=use_auth_token) + except Exception as e: + raise RuntimeError(f"Instantiating a pipeline without a task set raised an error: {e}") + if not info.pipeline_tag: + raise RuntimeError( + f"The model {model} does not seem to have a correct `pipeline_tag` set to infer the task automatically" + ) + if getattr(info, "library_name", "transformers") != "transformers": + raise RuntimeError(f"This model is meant to be used with {info.library_name} not with transformers") + task = info.pipeline_tag + return task + + +def check_task(task: str) -> Tuple[str, Dict, Any]: + """ + Checks an incoming task string, to validate it's correct and return the default Pipeline and Model classes, and + default models if they exist. + + Args: + task (`str`): + The task defining which pipeline will be returned. Currently accepted tasks are: + + - `"audio-classification"` + - `"automatic-speech-recognition"` + - `"conversational"` + - `"depth-estimation"` + - `"document-question-answering"` + - `"feature-extraction"` + - `"fill-mask"` + - `"image-classification"` + - `"image-segmentation"` + - `"image-to-text"` + - `"object-detection"` + - `"question-answering"` + - `"summarization"` + - `"table-question-answering"` + - `"text2text-generation"` + - `"text-classification"` (alias `"sentiment-analysis"` available) + - `"text-generation"` + - `"token-classification"` (alias `"ner"` available) + - `"translation"` + - `"translation_xx_to_yy"` + - `"video-classification"` + - `"visual-question-answering"` + - `"zero-shot-classification"` + - `"zero-shot-image-classification"` + - `"zero-shot-object-detection"` + + Returns: + (normalized_task: `str`, task_defaults: `dict`, task_options: (`tuple`, None)) The normalized task name + (removed alias and options). The actual dictionary required to initialize the pipeline and some extra task + options for parametrized tasks like "translation_XX_to_YY" + + + """ + return PIPELINE_REGISTRY.check_task(task) + + +def clean_custom_task(task_info): + import transformers + + if "impl" not in task_info: + raise RuntimeError("This model introduces a custom pipeline without specifying its implementation.") + pt_class_names = task_info.get("pt", ()) + if isinstance(pt_class_names, str): + pt_class_names = [pt_class_names] + task_info["pt"] = tuple(getattr(transformers, c) for c in pt_class_names) + tf_class_names = task_info.get("tf", ()) + if isinstance(tf_class_names, str): + tf_class_names = [tf_class_names] + task_info["tf"] = tuple(getattr(transformers, c) for c in tf_class_names) + return task_info, None + + +def pipeline( + task: str = None, + model: Optional = None, + config: Optional[Union[str, PretrainedConfig]] = None, + tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None, + feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None, + image_processor: Optional[Union[str, BaseImageProcessor]] = None, + framework: Optional[str] = None, + revision: Optional[str] = None, + use_fast: bool = True, + use_auth_token: Optional[Union[str, bool]] = None, + device: Optional[Union[int, str, "torch.device"]] = None, + device_map=None, + torch_dtype=None, + trust_remote_code: Optional[bool] = None, + model_kwargs: Dict[str, Any] = None, + pipeline_class: Optional[Any] = None, + **kwargs, +) -> Pipeline: + """ + Utility factory method to build a [`Pipeline`]. + + Pipelines are made of: + + - A [tokenizer](tokenizer) in charge of mapping raw textual input to token. + - A [model](model) to make predictions from the inputs. + - Some (optional) post processing for enhancing model's output. + + Args: + task (`str`): + The task defining which pipeline will be returned. Currently accepted tasks are: + + - `"audio-classification"`: will return a [`AudioClassificationPipeline`]. + - `"automatic-speech-recognition"`: will return a [`AutomaticSpeechRecognitionPipeline`]. + - `"conversational"`: will return a [`ConversationalPipeline`]. + - `"depth-estimation"`: will return a [`DepthEstimationPipeline`]. + - `"document-question-answering"`: will return a [`DocumentQuestionAnsweringPipeline`]. + - `"feature-extraction"`: will return a [`FeatureExtractionPipeline`]. + - `"fill-mask"`: will return a [`FillMaskPipeline`]:. + - `"image-classification"`: will return a [`ImageClassificationPipeline`]. + - `"image-segmentation"`: will return a [`ImageSegmentationPipeline`]. + - `"image-to-text"`: will return a [`ImageToTextPipeline`]. + - `"mask-generation"`: will return a [`MaskGenerationPipeline`]. + - `"object-detection"`: will return a [`ObjectDetectionPipeline`]. + - `"question-answering"`: will return a [`QuestionAnsweringPipeline`]. + - `"summarization"`: will return a [`SummarizationPipeline`]. + - `"table-question-answering"`: will return a [`TableQuestionAnsweringPipeline`]. + - `"text2text-generation"`: will return a [`Text2TextGenerationPipeline`]. + - `"text-classification"` (alias `"sentiment-analysis"` available): will return a + [`TextClassificationPipeline`]. + - `"text-generation"`: will return a [`TextGenerationPipeline`]:. + - `"token-classification"` (alias `"ner"` available): will return a [`TokenClassificationPipeline`]. + - `"translation"`: will return a [`TranslationPipeline`]. + - `"translation_xx_to_yy"`: will return a [`TranslationPipeline`]. + - `"video-classification"`: will return a [`VideoClassificationPipeline`]. + - `"visual-question-answering"`: will return a [`VisualQuestionAnsweringPipeline`]. + - `"zero-shot-classification"`: will return a [`ZeroShotClassificationPipeline`]. + - `"zero-shot-image-classification"`: will return a [`ZeroShotImageClassificationPipeline`]. + - `"zero-shot-audio-classification"`: will return a [`ZeroShotAudioClassificationPipeline`]. + - `"zero-shot-object-detection"`: will return a [`ZeroShotObjectDetectionPipeline`]. + + model (`str` or [`PreTrainedModel`] or [`TFPreTrainedModel`], *optional*): + The model that will be used by the pipeline to make predictions. This can be a model identifier or an + actual instance of a pretrained model inheriting from [`PreTrainedModel`] (for PyTorch) or + [`TFPreTrainedModel`] (for TensorFlow). + + If not provided, the default for the `task` will be loaded. + config (`str` or [`PretrainedConfig`], *optional*): + The configuration that will be used by the pipeline to instantiate the model. This can be a model + identifier or an actual pretrained model configuration inheriting from [`PretrainedConfig`]. + + If not provided, the default configuration file for the requested model will be used. That means that if + `model` is given, its default configuration will be used. However, if `model` is not supplied, this + `task`'s default model's config is used instead. + tokenizer (`str` or [`PreTrainedTokenizer`], *optional*): + The tokenizer that will be used by the pipeline to encode data for the model. This can be a model + identifier or an actual pretrained tokenizer inheriting from [`PreTrainedTokenizer`]. + + If not provided, the default tokenizer for the given `model` will be loaded (if it is a string). If `model` + is not specified or not a string, then the default tokenizer for `config` is loaded (if it is a string). + However, if `config` is also not given or not a string, then the default tokenizer for the given `task` + will be loaded. + feature_extractor (`str` or [`PreTrainedFeatureExtractor`], *optional*): + The feature extractor that will be used by the pipeline to encode data for the model. This can be a model + identifier or an actual pretrained feature extractor inheriting from [`PreTrainedFeatureExtractor`]. + + Feature extractors are used for non-NLP models, such as Speech or Vision models as well as multi-modal + models. Multi-modal models will also require a tokenizer to be passed. + + If not provided, the default feature extractor for the given `model` will be loaded (if it is a string). If + `model` is not specified or not a string, then the default feature extractor for `config` is loaded (if it + is a string). However, if `config` is also not given or not a string, then the default feature extractor + for the given `task` will be loaded. + framework (`str`, *optional*): + The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be + installed. + + If no framework is specified, will default to the one currently installed. If no framework is specified and + both frameworks are installed, will default to the framework of the `model`, or to PyTorch if no model is + provided. + revision (`str`, *optional*, defaults to `"main"`): + When passing a task name or a string model identifier: The specific model version to use. It can be a + branch name, a tag name, or a commit id, since we use a git-based system for storing models and other + artifacts on huggingface.co, so `revision` can be any identifier allowed by git. + use_fast (`bool`, *optional*, defaults to `True`): + Whether or not to use a Fast tokenizer if possible (a [`PreTrainedTokenizerFast`]). + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + device (`int` or `str` or `torch.device`): + Defines the device (*e.g.*, `"cpu"`, `"cuda:1"`, `"mps"`, or a GPU ordinal rank like `1`) on which this + pipeline will be allocated. + device_map (`str` or `Dict[str, Union[int, str, torch.device]`, *optional*): + Sent directly as `model_kwargs` (just a simpler shortcut). When `accelerate` library is present, set + `device_map="auto"` to compute the most optimized `device_map` automatically (see + [here](https://huggingface.co/docs/accelerate/main/en/package_reference/big_modeling#accelerate.cpu_offload) + for more information). + + + + Do not use `device_map` AND `device` at the same time as they will conflict + + + + torch_dtype (`str` or `torch.dtype`, *optional*): + Sent directly as `model_kwargs` (just a simpler shortcut) to use the available precision for this model + (`torch.float16`, `torch.bfloat16`, ... or `"auto"`). + trust_remote_code (`bool`, *optional*, defaults to `False`): + Whether or not to allow for custom code defined on the Hub in their own modeling, configuration, + tokenization or even pipeline files. This option should only be set to `True` for repositories you trust + and in which you have read the code, as it will execute code present on the Hub on your local machine. + model_kwargs: + Additional dictionary of keyword arguments passed along to the model's `from_pretrained(..., + **model_kwargs)` function. + kwargs: + Additional keyword arguments passed along to the specific pipeline init (see the documentation for the + corresponding pipeline class for possible values). + + Returns: + [`Pipeline`]: A suitable pipeline for the task. + + Examples: + + ```python + >>> from transformers import pipeline, AutoModelForTokenClassification, AutoTokenizer + + >>> # Sentiment analysis pipeline + >>> analyzer = pipeline("sentiment-analysis") + + >>> # Question answering pipeline, specifying the checkpoint identifier + >>> oracle = pipeline( + ... "question-answering", model="distilbert-base-cased-distilled-squad", tokenizer="bert-base-cased" + ... ) + + >>> # Named entity recognition pipeline, passing in a specific model and tokenizer + >>> model = AutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english") + >>> tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") + >>> recognizer = pipeline("ner", model=model, tokenizer=tokenizer) + ```""" + if model_kwargs is None: + model_kwargs = {} + # Make sure we only pass use_auth_token once as a kwarg (it used to be possible to pass it in model_kwargs, + # this is to keep BC). + use_auth_token = model_kwargs.pop("use_auth_token", use_auth_token) + hub_kwargs = { + "revision": revision, + "use_auth_token": use_auth_token, + "trust_remote_code": trust_remote_code, + "_commit_hash": None, + } + + if task is None and model is None: + raise RuntimeError( + "Impossible to instantiate a pipeline without either a task or a model " + "being specified. " + "Please provide a task class or a model" + ) + + if model is None and tokenizer is not None: + raise RuntimeError( + "Impossible to instantiate a pipeline with tokenizer specified but not the model as the provided tokenizer" + " may not be compatible with the default model. Please provide a PreTrainedModel class or a" + " path/identifier to a pretrained model when providing tokenizer." + ) + if model is None and feature_extractor is not None: + raise RuntimeError( + "Impossible to instantiate a pipeline with feature_extractor specified but not the model as the provided" + " feature_extractor may not be compatible with the default model. Please provide a PreTrainedModel class" + " or a path/identifier to a pretrained model when providing feature_extractor." + ) + if isinstance(model, Path): + model = str(model) + + # Config is the primordial information item. + # Instantiate config if needed + if isinstance(config, str): + config = AutoConfig.from_pretrained(config, _from_pipeline=task, **hub_kwargs, **model_kwargs) + hub_kwargs["_commit_hash"] = config._commit_hash + elif config is None and isinstance(model, str): + config = AutoConfig.from_pretrained(model, _from_pipeline=task, **hub_kwargs, **model_kwargs) + hub_kwargs["_commit_hash"] = config._commit_hash + + custom_tasks = {} + if config is not None and len(getattr(config, "custom_pipelines", {})) > 0: + custom_tasks = config.custom_pipelines + if task is None and trust_remote_code is not False: + if len(custom_tasks) == 1: + task = list(custom_tasks.keys())[0] + else: + raise RuntimeError( + "We can't infer the task automatically for this model as there are multiple tasks available. Pick " + f"one in {', '.join(custom_tasks.keys())}" + ) + + if task is None and model is not None: + if not isinstance(model, str): + raise RuntimeError( + "Inferring the task automatically requires to check the hub with a model_id defined as a `str`." + f"{model} is not a valid model_id." + ) + task = get_task(model, use_auth_token) + + # Retrieve the task + if task in custom_tasks: + normalized_task = task + targeted_task, task_options = clean_custom_task(custom_tasks[task]) + if pipeline_class is None: + if not trust_remote_code: + raise ValueError( + "Loading this pipeline requires you to execute the code in the pipeline file in that" + " repo on your local machine. Make sure you have read the code there to avoid malicious use, then" + " set the option `trust_remote_code=True` to remove this error." + ) + class_ref = targeted_task["impl"] + pipeline_class = get_class_from_dynamic_module( + class_ref, model, revision=revision, use_auth_token=use_auth_token + ) + else: + normalized_task, targeted_task, task_options = check_task(task) + if pipeline_class is None: + pipeline_class = targeted_task["impl"] + + # Use default model/config/tokenizer for the task if no model is provided + if model is None: + # At that point framework might still be undetermined + model, default_revision = get_default_model_and_revision(targeted_task, framework, task_options) + revision = revision if revision is not None else default_revision + logger.warning( + f"No model was supplied, defaulted to {model} and revision" + f" {revision} ({HUGGINGFACE_CO_RESOLVE_ENDPOINT}/{model}).\n" + "Using a pipeline without specifying a model name and revision in production is not recommended." + ) + if config is None and isinstance(model, str): + config = AutoConfig.from_pretrained(model, _from_pipeline=task, **hub_kwargs, **model_kwargs) + hub_kwargs["_commit_hash"] = config._commit_hash + + if device_map is not None: + if "device_map" in model_kwargs: + raise ValueError( + 'You cannot use both `pipeline(... device_map=..., model_kwargs={"device_map":...})` as those' + " arguments might conflict, use only one.)" + ) + if device is not None: + logger.warning( + "Both `device` and `device_map` are specified. `device` will override `device_map`. You" + " will most likely encounter unexpected behavior. Please remove `device` and keep `device_map`." + ) + model_kwargs["device_map"] = device_map + if torch_dtype is not None: + if "torch_dtype" in model_kwargs: + raise ValueError( + 'You cannot use both `pipeline(... torch_dtype=..., model_kwargs={"torch_dtype":...})` as those' + " arguments might conflict, use only one.)" + ) + model_kwargs["torch_dtype"] = torch_dtype + + model_name = model if isinstance(model, str) else None + + # Infer the framework from the model + # Forced if framework already defined, inferred if it's None + # Will load the correct model if possible + model_classes = {"tf": targeted_task["tf"], "pt": targeted_task["pt"]} + framework, model = infer_framework_load_model( + model, + model_classes=model_classes, + config=config, + framework=framework, + task=task, + **hub_kwargs, + **model_kwargs, + ) + + model_config = model.config + hub_kwargs["_commit_hash"] = model.config._commit_hash + load_tokenizer = type(model_config) in TOKENIZER_MAPPING or model_config.tokenizer_class is not None + load_feature_extractor = type(model_config) in FEATURE_EXTRACTOR_MAPPING or feature_extractor is not None + load_image_processor = type(model_config) in IMAGE_PROCESSOR_MAPPING or image_processor is not None + + # If `model` (instance of `PretrainedModel` instead of `str`) is passed (and/or same for config), while + # `image_processor` or `feature_extractor` is `None`, the loading will fail. This happens particularly for some + # vision tasks when calling `pipeline()` with `model` and only one of the `image_processor` and `feature_extractor`. + # TODO: we need to make `NO_IMAGE_PROCESSOR_TASKS` and `NO_FEATURE_EXTRACTOR_TASKS` more robust to avoid such issue. + # This block is only temporarily to make CI green. + if load_image_processor and load_feature_extractor: + load_feature_extractor = False + + if ( + tokenizer is None + and not load_tokenizer + and normalized_task not in NO_TOKENIZER_TASKS + # Using class name to avoid importing the real class. + and model_config.__class__.__name__ in MULTI_MODEL_CONFIGS + ): + # This is a special category of models, that are fusions of multiple models + # so the model_config might not define a tokenizer, but it seems to be + # necessary for the task, so we're force-trying to load it. + load_tokenizer = True + if ( + image_processor is None + and not load_image_processor + and normalized_task not in NO_IMAGE_PROCESSOR_TASKS + # Using class name to avoid importing the real class. + and model_config.__class__.__name__ in MULTI_MODEL_CONFIGS + and normalized_task != "automatic-speech-recognition" + ): + # This is a special category of models, that are fusions of multiple models + # so the model_config might not define a tokenizer, but it seems to be + # necessary for the task, so we're force-trying to load it. + load_image_processor = True + if ( + feature_extractor is None + and not load_feature_extractor + and normalized_task not in NO_FEATURE_EXTRACTOR_TASKS + # Using class name to avoid importing the real class. + and model_config.__class__.__name__ in MULTI_MODEL_CONFIGS + ): + # This is a special category of models, that are fusions of multiple models + # so the model_config might not define a tokenizer, but it seems to be + # necessary for the task, so we're force-trying to load it. + load_feature_extractor = True + + if task in NO_TOKENIZER_TASKS: + # These will never require a tokenizer. + # the model on the other hand might have a tokenizer, but + # the files could be missing from the hub, instead of failing + # on such repos, we just force to not load it. + load_tokenizer = False + + if task in NO_FEATURE_EXTRACTOR_TASKS: + load_feature_extractor = False + if task in NO_IMAGE_PROCESSOR_TASKS: + load_image_processor = False + + if load_tokenizer: + # Try to infer tokenizer from model or config name (if provided as str) + if tokenizer is None: + if isinstance(model_name, str): + tokenizer = model_name + elif isinstance(config, str): + tokenizer = config + else: + # Impossible to guess what is the right tokenizer here + raise Exception( + "Impossible to guess which tokenizer to use. " + "Please provide a PreTrainedTokenizer class or a path/identifier to a pretrained tokenizer." + ) + + # Instantiate tokenizer if needed + if isinstance(tokenizer, (str, tuple)): + if isinstance(tokenizer, tuple): + # For tuple we have (tokenizer name, {kwargs}) + use_fast = tokenizer[1].pop("use_fast", use_fast) + tokenizer_identifier = tokenizer[0] + tokenizer_kwargs = tokenizer[1] + else: + tokenizer_identifier = tokenizer + tokenizer_kwargs = model_kwargs.copy() + tokenizer_kwargs.pop("torch_dtype", None) + + tokenizer = AutoTokenizer.from_pretrained( + tokenizer_identifier, use_fast=use_fast, _from_pipeline=task, **hub_kwargs, **tokenizer_kwargs + ) + + if load_image_processor: + # Try to infer image processor from model or config name (if provided as str) + if image_processor is None: + if isinstance(model_name, str): + image_processor = model_name + elif isinstance(config, str): + image_processor = config + # Backward compatibility, as `feature_extractor` used to be the name + # for `ImageProcessor`. + elif feature_extractor is not None and isinstance(feature_extractor, BaseImageProcessor): + image_processor = feature_extractor + else: + # Impossible to guess what is the right image_processor here + raise Exception( + "Impossible to guess which image processor to use. " + "Please provide a PreTrainedImageProcessor class or a path/identifier " + "to a pretrained image processor." + ) + + # Instantiate image_processor if needed + if isinstance(image_processor, (str, tuple)): + image_processor = AutoImageProcessor.from_pretrained( + image_processor, _from_pipeline=task, **hub_kwargs, **model_kwargs + ) + + if load_feature_extractor: + # Try to infer feature extractor from model or config name (if provided as str) + if feature_extractor is None: + if isinstance(model_name, str): + feature_extractor = model_name + elif isinstance(config, str): + feature_extractor = config + else: + # Impossible to guess what is the right feature_extractor here + raise Exception( + "Impossible to guess which feature extractor to use. " + "Please provide a PreTrainedFeatureExtractor class or a path/identifier " + "to a pretrained feature extractor." + ) + + # Instantiate feature_extractor if needed + if isinstance(feature_extractor, (str, tuple)): + feature_extractor = AutoFeatureExtractor.from_pretrained( + feature_extractor, _from_pipeline=task, **hub_kwargs, **model_kwargs + ) + + if ( + feature_extractor._processor_class + and feature_extractor._processor_class.endswith("WithLM") + and isinstance(model_name, str) + ): + try: + import kenlm # to trigger `ImportError` if not installed + from pyctcdecode import BeamSearchDecoderCTC + + if os.path.isdir(model_name) or os.path.isfile(model_name): + decoder = BeamSearchDecoderCTC.load_from_dir(model_name) + else: + language_model_glob = os.path.join( + BeamSearchDecoderCTC._LANGUAGE_MODEL_SERIALIZED_DIRECTORY, "*" + ) + alphabet_filename = BeamSearchDecoderCTC._ALPHABET_SERIALIZED_FILENAME + allow_patterns = [language_model_glob, alphabet_filename] + decoder = BeamSearchDecoderCTC.load_from_hf_hub(model_name, allow_patterns=allow_patterns) + + kwargs["decoder"] = decoder + except ImportError as e: + logger.warning(f"Could not load the `decoder` for {model_name}. Defaulting to raw CTC. Error: {e}") + if not is_kenlm_available(): + logger.warning("Try to install `kenlm`: `pip install kenlm") + + if not is_pyctcdecode_available(): + logger.warning("Try to install `pyctcdecode`: `pip install pyctcdecode") + + if task == "translation" and model.config.task_specific_params: + for key in model.config.task_specific_params: + if key.startswith("translation"): + task = key + warnings.warn( + f'"translation" task was used, instead of "translation_XX_to_YY", defaulting to "{task}"', + UserWarning, + ) + break + + if tokenizer is not None: + kwargs["tokenizer"] = tokenizer + + if feature_extractor is not None: + kwargs["feature_extractor"] = feature_extractor + + if torch_dtype is not None: + kwargs["torch_dtype"] = torch_dtype + + if image_processor is not None: + kwargs["image_processor"] = image_processor + + if device is not None: + kwargs["device"] = device + + return pipeline_class(model=model, framework=framework, task=task, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..7f104e74e12824fd790d44cdac9cf1e5018acc7d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_classification.py @@ -0,0 +1,177 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import subprocess +from typing import Union + +import numpy as np +import requests + +from ..utils import add_end_docstrings, is_torch_available, logging +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING + +logger = logging.get_logger(__name__) + + +def ffmpeg_read(bpayload: bytes, sampling_rate: int) -> np.array: + """ + Helper function to read an audio file through ffmpeg. + """ + ar = f"{sampling_rate}" + ac = "1" + format_for_conversion = "f32le" + ffmpeg_command = [ + "ffmpeg", + "-i", + "pipe:0", + "-ac", + ac, + "-ar", + ar, + "-f", + format_for_conversion, + "-hide_banner", + "-loglevel", + "quiet", + "pipe:1", + ] + + try: + ffmpeg_process = subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + except FileNotFoundError: + raise ValueError("ffmpeg was not found but is required to load audio files from filename") + output_stream = ffmpeg_process.communicate(bpayload) + out_bytes = output_stream[0] + + audio = np.frombuffer(out_bytes, np.float32) + if audio.shape[0] == 0: + raise ValueError("Malformed soundfile") + return audio + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class AudioClassificationPipeline(Pipeline): + """ + Audio classification pipeline using any `AutoModelForAudioClassification`. This pipeline predicts the class of a + raw waveform or an audio file. In case of an audio file, ffmpeg should be installed to support multiple audio + formats. + + Example: + + ```python + >>> from transformers import pipeline + + >>> classifier = pipeline(model="superb/wav2vec2-base-superb-ks") + >>> classifier("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/1.flac") + [{'score': 0.997, 'label': '_unknown_'}, {'score': 0.002, 'label': 'left'}, {'score': 0.0, 'label': 'yes'}, {'score': 0.0, 'label': 'down'}, {'score': 0.0, 'label': 'stop'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + + This pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"audio-classification"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=audio-classification). + """ + + def __init__(self, *args, **kwargs): + # Default, might be overriden by the model.config. + kwargs["top_k"] = 5 + super().__init__(*args, **kwargs) + + if self.framework != "pt": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + + self.check_model_type(MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING) + + def __call__( + self, + inputs: Union[np.ndarray, bytes, str], + **kwargs, + ): + """ + Classify the sequence(s) given as inputs. See the [`AutomaticSpeechRecognitionPipeline`] documentation for more + information. + + Args: + inputs (`np.ndarray` or `bytes` or `str`): + The inputs is either a raw waveform (`np.ndarray` of shape (n, ) of type `np.float32` or `np.float64`) + at the correct sampling rate (no further check will be done) or a `str` that is the filename of the + audio file, the file will be read at the correct sampling rate to get the waveform using *ffmpeg*. This + requires *ffmpeg* to be installed on the system. If *inputs* is `bytes` it is supposed to be the + content of an audio file and is interpreted by *ffmpeg* in the same way. + top_k (`int`, *optional*, defaults to None): + The number of top labels that will be returned by the pipeline. If the provided number is `None` or + higher than the number of labels available in the model configuration, it will default to the number of + labels. + + Return: + A list of `dict` with the following keys: + + - **label** (`str`) -- The label predicted. + - **score** (`float`) -- The corresponding probability. + """ + return super().__call__(inputs, **kwargs) + + def _sanitize_parameters(self, top_k=None, **kwargs): + # No parameters on this pipeline right now + postprocess_params = {} + if top_k is not None: + if top_k > self.model.config.num_labels: + top_k = self.model.config.num_labels + postprocess_params["top_k"] = top_k + return {}, {}, postprocess_params + + def preprocess(self, inputs): + if isinstance(inputs, str): + if inputs.startswith("http://") or inputs.startswith("https://"): + # We need to actually check for a real protocol, otherwise it's impossible to use a local file + # like http_huggingface_co.png + inputs = requests.get(inputs).content + else: + with open(inputs, "rb") as f: + inputs = f.read() + + if isinstance(inputs, bytes): + inputs = ffmpeg_read(inputs, self.feature_extractor.sampling_rate) + + if not isinstance(inputs, np.ndarray): + raise ValueError("We expect a numpy ndarray as input") + if len(inputs.shape) != 1: + raise ValueError("We expect a single channel audio input for AutomaticSpeechRecognitionPipeline") + + processed = self.feature_extractor( + inputs, sampling_rate=self.feature_extractor.sampling_rate, return_tensors="pt" + ) + return processed + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs, top_k=5): + probs = model_outputs.logits[0].softmax(-1) + scores, ids = probs.topk(top_k) + + scores = scores.tolist() + ids = ids.tolist() + + labels = [{"score": score, "label": self.model.config.id2label[_id]} for score, _id in zip(scores, ids)] + + return labels diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..62c2b00c467ab324a6f95665af7025266e8b3c74 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/audio_utils.py @@ -0,0 +1,224 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +import datetime +import platform +import subprocess +from typing import Optional, Tuple, Union + +import numpy as np + + +def ffmpeg_read(bpayload: bytes, sampling_rate: int) -> np.array: + """ + Helper function to read an audio file through ffmpeg. + """ + ar = f"{sampling_rate}" + ac = "1" + format_for_conversion = "f32le" + ffmpeg_command = [ + "ffmpeg", + "-i", + "pipe:0", + "-ac", + ac, + "-ar", + ar, + "-f", + format_for_conversion, + "-hide_banner", + "-loglevel", + "quiet", + "pipe:1", + ] + + try: + with subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) as ffmpeg_process: + output_stream = ffmpeg_process.communicate(bpayload) + except FileNotFoundError as error: + raise ValueError("ffmpeg was not found but is required to load audio files from filename") from error + out_bytes = output_stream[0] + audio = np.frombuffer(out_bytes, np.float32) + if audio.shape[0] == 0: + raise ValueError("Malformed soundfile") + return audio + + +def ffmpeg_microphone( + sampling_rate: int, + chunk_length_s: float, + format_for_conversion: str = "f32le", +): + """ + Helper function ro read raw microphone data. + """ + ar = f"{sampling_rate}" + ac = "1" + if format_for_conversion == "s16le": + size_of_sample = 2 + elif format_for_conversion == "f32le": + size_of_sample = 4 + else: + raise ValueError(f"Unhandled format `{format_for_conversion}`. Please use `s16le` or `f32le`") + + system = platform.system() + if system == "Linux": + format_ = "alsa" + input_ = "default" + elif system == "Darwin": + format_ = "avfoundation" + input_ = ":0" + elif system == "Windows": + format_ = "dshow" + input_ = "default" + + ffmpeg_command = [ + "ffmpeg", + "-f", + format_, + "-i", + input_, + "-ac", + ac, + "-ar", + ar, + "-f", + format_for_conversion, + "-fflags", + "nobuffer", + "-hide_banner", + "-loglevel", + "quiet", + "pipe:1", + ] + chunk_len = int(round(sampling_rate * chunk_length_s)) * size_of_sample + iterator = _ffmpeg_stream(ffmpeg_command, chunk_len) + for item in iterator: + yield item + + +def ffmpeg_microphone_live( + sampling_rate: int, + chunk_length_s: float, + stream_chunk_s: Optional[int] = None, + stride_length_s: Optional[Union[Tuple[float, float], float]] = None, + format_for_conversion: str = "f32le", +): + """ + Helper function to read audio from the microphone file through ffmpeg. This will output `partial` overlapping + chunks starting from `stream_chunk_s` (if it is defined) until `chunk_length_s` is reached. It will make use of + striding to avoid errors on the "sides" of the various chunks. + + Arguments: + sampling_rate (`int`): + The sampling_rate to use when reading the data from the microphone. Try using the model's sampling_rate to + avoid resampling later. + chunk_length_s (`float` or `int`): + The length of the maximum chunk of audio to be sent returned. This includes the eventual striding. + stream_chunk_s (`float` or `int`) + The length of the minimal temporary audio to be returned. + stride_length_s (`float` or `int` or `(float, float)`, *optional*, defaults to `None`) + The length of the striding to be used. Stride is used to provide context to a model on the (left, right) of + an audio sample but without using that part to actually make the prediction. Setting this does not change + the length of the chunk. + format_for_conversion: (`str`, defalts to `f32le`) + The name of the format of the audio samples to be returned by ffmpeg. The standard is `f32le`, `s16le` + could also be used. + Return: + A generator yielding dictionaries of the following form + + `{"sampling_rate": int, "raw": np.array(), "partial" bool}` With optionnally a `"stride" (int, int)` key if + `stride_length_s` is defined. + + `stride` and `raw` are all expressed in `samples`, and `partial` is a boolean saying if the current yield item + is a whole chunk, or a partial temporary result to be later replaced by another larger chunk. + + + """ + if stream_chunk_s is not None: + chunk_s = stream_chunk_s + else: + chunk_s = chunk_length_s + + microphone = ffmpeg_microphone(sampling_rate, chunk_s, format_for_conversion=format_for_conversion) + if format_for_conversion == "s16le": + dtype = np.int16 + size_of_sample = 2 + elif format_for_conversion == "f32le": + dtype = np.float32 + size_of_sample = 4 + else: + raise ValueError(f"Unhandled format `{format_for_conversion}`. Please use `s16le` or `f32le`") + + if stride_length_s is None: + stride_length_s = chunk_length_s / 6 + chunk_len = int(round(sampling_rate * chunk_length_s)) * size_of_sample + if isinstance(stride_length_s, (int, float)): + stride_length_s = [stride_length_s, stride_length_s] + + stride_left = int(round(sampling_rate * stride_length_s[0])) * size_of_sample + stride_right = int(round(sampling_rate * stride_length_s[1])) * size_of_sample + audio_time = datetime.datetime.now() + delta = datetime.timedelta(seconds=chunk_s) + for item in chunk_bytes_iter(microphone, chunk_len, stride=(stride_left, stride_right), stream=True): + # Put everything back in numpy scale + item["raw"] = np.frombuffer(item["raw"], dtype=dtype) + item["stride"] = ( + item["stride"][0] // size_of_sample, + item["stride"][1] // size_of_sample, + ) + item["sampling_rate"] = sampling_rate + audio_time += delta + if datetime.datetime.now() > audio_time + 10 * delta: + # We're late !! SKIP + continue + yield item + + +def chunk_bytes_iter(iterator, chunk_len: int, stride: Tuple[int, int], stream: bool = False): + """ + Reads raw bytes from an iterator and does chunks of length `chunk_len`. Optionally adds `stride` to each chunks to + get overlaps. `stream` is used to return partial results even if a full `chunk_len` is not yet available. + """ + acc = b"" + stride_left, stride_right = stride + if stride_left + stride_right >= chunk_len: + raise ValueError( + f"Stride needs to be strictly smaller than chunk_len: ({stride_left}, {stride_right}) vs {chunk_len}" + ) + _stride_left = 0 + for raw in iterator: + acc += raw + if stream and len(acc) < chunk_len: + stride = (_stride_left, 0) + yield {"raw": acc[:chunk_len], "stride": stride, "partial": True} + else: + while len(acc) >= chunk_len: + # We are flushing the accumulator + stride = (_stride_left, stride_right) + item = {"raw": acc[:chunk_len], "stride": stride} + if stream: + item["partial"] = False + yield item + _stride_left = stride_left + acc = acc[chunk_len - stride_left - stride_right :] + # Last chunk + if len(acc) > stride_left: + item = {"raw": acc, "stride": (_stride_left, 0)} + if stream: + item["partial"] = False + yield item + + +def _ffmpeg_stream(ffmpeg_command, buflen: int): + """ + Internal function to create the generator of data through ffmpeg + """ + bufsize = 2**24 # 16Mo + try: + with subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, bufsize=bufsize) as ffmpeg_process: + while True: + raw = ffmpeg_process.stdout.read(buflen) + if raw == b"": + break + yield raw + except FileNotFoundError as error: + raise ValueError("ffmpeg was not found but is required to stream audio files from filename") from error diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/automatic_speech_recognition.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/automatic_speech_recognition.py new file mode 100644 index 0000000000000000000000000000000000000000..b96363232fb515f95be1086a498624c0c745adac --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/automatic_speech_recognition.py @@ -0,0 +1,685 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from collections import defaultdict +from typing import TYPE_CHECKING, Dict, Optional, Union + +import numpy as np +import requests + +from ..utils import is_torch_available, logging +from .audio_utils import ffmpeg_read +from .base import ChunkPipeline + + +if TYPE_CHECKING: + from pyctcdecode import BeamSearchDecoderCTC + + from ..feature_extraction_sequence_utils import SequenceFeatureExtractor + +logger = logging.get_logger(__name__) + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_CTC_MAPPING, MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING + + +def rescale_stride(stride, ratio): + """ + Rescales the stride values from audio space to tokens/logits space. + + (160_000, 16_000, 16_000) -> (2000, 200, 200) for instance. + """ + # Shape is [B, SEQ] for tokens + # [B, SEQ, V] for logits + + new_strides = [] + for input_n, left, right in stride: + token_n = int(round(input_n * ratio)) + left = int(round(left / input_n * token_n)) + right = int(round(right / input_n * token_n)) + new_stride = (token_n, left, right) + new_strides.append(new_stride) + + return new_strides + + +def chunk_iter(inputs, feature_extractor, chunk_len, stride_left, stride_right, rescale=True, dtype=None): + inputs_len = inputs.shape[0] + step = chunk_len - stride_left - stride_right + for chunk_start_idx in range(0, inputs_len, step): + chunk_end_idx = chunk_start_idx + chunk_len + chunk = inputs[chunk_start_idx:chunk_end_idx] + processed = feature_extractor(chunk, sampling_rate=feature_extractor.sampling_rate, return_tensors="pt") + if dtype is not None: + processed = processed.to(dtype=dtype) + _stride_left = 0 if chunk_start_idx == 0 else stride_left + # all right strides must be full, otherwise it is the last item + is_last = chunk_end_idx > inputs_len if stride_right > 0 else chunk_end_idx >= inputs_len + _stride_right = 0 if is_last else stride_right + + chunk_len = chunk.shape[0] + stride = (chunk_len, _stride_left, _stride_right) + if "input_features" in processed: + processed_len = processed["input_features"].shape[-1] + elif "input_values" in processed: + processed_len = processed["input_values"].shape[-1] + if processed_len != chunk.shape[-1] and rescale: + ratio = processed_len / chunk_len + stride = rescale_stride([stride], ratio)[0] + if chunk.shape[0] > _stride_left: + yield {"is_last": is_last, "stride": stride, **processed} + if is_last: + break + + +def _fast_find_longest_common_sequence(sequence_left, sequence_right): + seq_len_left = len(sequence_left) + seq_len_right = len(sequence_right) + counter = [[0] * (seq_len_right + 1) for _ in range(seq_len_left + 1)] + longest = 0 + for i in range(seq_len_left): + for j in range(seq_len_right): + if sequence_left[i] == sequence_right[j]: + previous_counter = counter[i][j] + 1 + counter[i + 1][j + 1] = previous_counter + if previous_counter > longest: + longest = previous_counter + + counter = np.array(counter) + # we return the idx of the first element of the longest common sequence in the left sequence + index_left = np.argwhere(counter == longest)[-1][0] - longest if longest != 0 else -1 + index_right = np.argwhere(counter == longest)[-1][1] - longest if longest != 0 else -1 + return index_left, index_right, longest + + +def _find_longest_common_sequence(sequences, tokenizer): + # TODO Use a faster algorithm this can probably be done in O(n) + # using suffix array. + # It might be tedious to do because of fault tolerance. + # We actually have a really good property which is that the total sequence + # MUST be those subsequences in order. + # Also the algorithm should be more tolerant to errors. + sequence = [tok_id for tok_id in sequences[0][0].tolist() if tok_id not in tokenizer.all_special_ids] + for new_seq in sequences[1:]: + new_sequence = [tok_id for tok_id in new_seq[0].tolist() if tok_id not in tokenizer.all_special_ids] + + index = 0 + max_ = 0.0 + for i in range(1, len(new_sequence) + 1): + # epsilon to favor long perfect matches + eps = i / 10000.0 + matches = np.sum(np.array(sequence[-i:]) == np.array(new_sequence[:i])) + matching = matches / i + eps + if matches > 1 and matching > max_: + index = i + max_ = matching + sequence.extend(new_sequence[index:]) + return np.array(sequence) + + +class AutomaticSpeechRecognitionPipeline(ChunkPipeline): + """ + Pipeline that aims at extracting spoken text contained within some audio. + + The input can be either a raw waveform or a audio file. In case of the audio file, ffmpeg should be installed for + to support multiple audio formats + + Example: + + ```python + >>> from transformers import pipeline + + >>> transcriber = pipeline(model="openai/whisper-base") + >>> transcriber("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/1.flac") + {'text': ' He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered flour-fatten sauce.'} + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + Arguments: + model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from + [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow. + tokenizer ([`PreTrainedTokenizer`]): + The tokenizer that will be used by the pipeline to encode data for the model. This object inherits from + [`PreTrainedTokenizer`]. + feature_extractor ([`SequenceFeatureExtractor`]): + The feature extractor that will be used by the pipeline to encode waveform for the model. + chunk_length_s (`float`, *optional*, defaults to 0): + The input length for in each chunk. If `chunk_length_s = 0` then chunking is disabled (default). Only + available for CTC models, e.g. [`Wav2Vec2ForCTC`]. + + + + For more information on how to effectively use `chunk_length_s`, please have a look at the [ASR chunking + blog post](https://huggingface.co/blog/asr-chunking). + + + + stride_length_s (`float`, *optional*, defaults to `chunk_length_s / 6`): + The length of stride on the left and right of each chunk. Used only with `chunk_length_s > 0`. This enables + the model to *see* more context and infer letters better than without this context but the pipeline + discards the stride bits at the end to make the final reconstitution as perfect as possible. + + + + For more information on how to effectively use `stride_length_s`, please have a look at the [ASR chunking + blog post](https://huggingface.co/blog/asr-chunking). + + + + framework (`str`, *optional*): + The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be + installed. If no framework is specified, will default to the one currently installed. If no framework is + specified and both frameworks are installed, will default to the framework of the `model`, or to PyTorch if + no model is provided. + device (Union[`int`, `torch.device`], *optional*): + Device ordinal for CPU/GPU supports. Setting this to `None` will leverage CPU, a positive will run the + model on the associated CUDA device id. + decoder (`pyctcdecode.BeamSearchDecoderCTC`, *optional*): + [PyCTCDecode's + BeamSearchDecoderCTC](https://github.com/kensho-technologies/pyctcdecode/blob/2fd33dc37c4111417e08d89ccd23d28e9b308d19/pyctcdecode/decoder.py#L180) + can be passed for language model boosted decoding. See [`Wav2Vec2ProcessorWithLM`] for more information. + + """ + + def __init__( + self, + feature_extractor: Union["SequenceFeatureExtractor", str], + *, + decoder: Optional[Union["BeamSearchDecoderCTC", str]] = None, + **kwargs, + ): + super().__init__(**kwargs) + self.feature_extractor = feature_extractor + + if self.model.config.model_type == "whisper": + self.type = "seq2seq_whisper" + elif self.model.__class__ in MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING.values(): + self.type = "seq2seq" + elif ( + feature_extractor._processor_class + and feature_extractor._processor_class.endswith("WithLM") + and decoder is not None + ): + self.decoder = decoder + self.type = "ctc_with_lm" + else: + self.type = "ctc" + + if self.framework == "tf": + raise ValueError("The AutomaticSpeechRecognitionPipeline is only available in PyTorch.") + + self.check_model_type(dict(MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING.items() + MODEL_FOR_CTC_MAPPING.items())) + + def __call__( + self, + inputs: Union[np.ndarray, bytes, str], + **kwargs, + ): + """ + Transcribe the audio sequence(s) given as inputs to text. See the [`AutomaticSpeechRecognitionPipeline`] + documentation for more information. + + Args: + inputs (`np.ndarray` or `bytes` or `str` or `dict`): + The inputs is either : + - `str` that is the filename of the audio file, the file will be read at the correct sampling rate + to get the waveform using *ffmpeg*. This requires *ffmpeg* to be installed on the system. + - `bytes` it is supposed to be the content of an audio file and is interpreted by *ffmpeg* in the + same way. + - (`np.ndarray` of shape (n, ) of type `np.float32` or `np.float64`) + Raw audio at the correct sampling rate (no further check will be done) + - `dict` form can be used to pass raw audio sampled at arbitrary `sampling_rate` and let this + pipeline do the resampling. The dict must be in the format `{"sampling_rate": int, "raw": + np.array}` with optionally a `"stride": (left: int, right: int)` than can ask the pipeline to + treat the first `left` samples and last `right` samples to be ignored in decoding (but used at + inference to provide more context to the model). Only use `stride` with CTC models. + return_timestamps (*optional*, `str`): + Only available for pure CTC models. If set to `"char"`, the pipeline will return `timestamps` along the + text for every character in the text. For instance if you get `[{"text": "h", "timestamps": (0.5,0.6), + {"text": "i", "timestamps": (0.7, .9)}]`, then it means the model predicts that the letter "h" was + pronounced after `0.5` and before `0.6` seconds. If set to `"word"`, the pipeline will return + `timestamps` along the text for every word in the text. For instance if you get `[{"text": "hi ", + "timestamps": (0.5,0.9), {"text": "there", "timestamps": (1.0, .1.5)}]`, then it means the model + predicts that the word "hi" was pronounced after `0.5` and before `0.9` seconds. + generate_kwargs (`dict`, *optional*): + The dictionary of ad-hoc parametrization of `generate_config` to be used for the generation call. For a + complete overview of generate, check the [following + guide](https://huggingface.co/docs/transformers/en/main_classes/text_generation). + max_new_tokens (`int`, *optional*): + The maximum numbers of tokens to generate, ignoring the number of tokens in the prompt. + + Return: + `Dict`: A dictionary with the following keys: + - **text** (`str` ) -- The recognized text. + - **chunks** (*optional(, `List[Dict]`) + When using `return_timestamps`, the `chunks` will become a list containing all the various text + chunks identified by the model, *e.g.* `[{"text": "hi ", "timestamps": (0.5,0.9), {"text": + "there", "timestamps": (1.0, 1.5)}]`. The original full text can roughly be recovered by doing + `"".join(chunk["text"] for chunk in output["chunks"])`. + """ + return super().__call__(inputs, **kwargs) + + def _sanitize_parameters( + self, + chunk_length_s=None, + stride_length_s=None, + ignore_warning=None, + decoder_kwargs=None, + return_timestamps=None, + return_language=None, + generate_kwargs=None, + max_new_tokens=None, + ): + # No parameters on this pipeline right now + preprocess_params = {} + if chunk_length_s is not None: + preprocess_params["chunk_length_s"] = chunk_length_s + if stride_length_s is not None: + preprocess_params["stride_length_s"] = stride_length_s + if ignore_warning is not None: + preprocess_params["ignore_warning"] = ignore_warning + + forward_params = defaultdict(dict) + if max_new_tokens is not None: + forward_params["generate_kwargs"]["max_new_tokens"] = max_new_tokens + if generate_kwargs is not None: + if max_new_tokens is not None and "max_new_tokens" in generate_kwargs: + raise ValueError( + "`max_new_tokens` is defined both as an argument and inside `generate_kwargs` argument, please use" + " only 1 version" + ) + forward_params["generate_kwargs"].update(generate_kwargs) + + postprocess_params = {} + if decoder_kwargs is not None: + postprocess_params["decoder_kwargs"] = decoder_kwargs + if return_timestamps is not None: + forward_params["return_timestamps"] = return_timestamps + postprocess_params["return_timestamps"] = return_timestamps + if return_language is not None: + postprocess_params["return_language"] = return_language + + return preprocess_params, forward_params, postprocess_params + + def preprocess(self, inputs, chunk_length_s=0, stride_length_s=None, ignore_warning=False): + if isinstance(inputs, str): + if inputs.startswith("http://") or inputs.startswith("https://"): + # We need to actually check for a real protocol, otherwise it's impossible to use a local file + # like http_huggingface_co.png + inputs = requests.get(inputs).content + else: + with open(inputs, "rb") as f: + inputs = f.read() + + if isinstance(inputs, bytes): + inputs = ffmpeg_read(inputs, self.feature_extractor.sampling_rate) + + stride = None + extra = {} + if isinstance(inputs, dict): + stride = inputs.pop("stride", None) + # Accepting `"array"` which is the key defined in `datasets` for + # better integration + if not ("sampling_rate" in inputs and ("raw" in inputs or "array" in inputs)): + raise ValueError( + "When passing a dictionary to AutomaticSpeechRecognitionPipeline, the dict needs to contain a " + '"raw" key containing the numpy array representing the audio and a "sampling_rate" key, ' + "containing the sampling_rate associated with that array" + ) + + _inputs = inputs.pop("raw", None) + if _inputs is None: + # Remove path which will not be used from `datasets`. + inputs.pop("path", None) + _inputs = inputs.pop("array", None) + in_sampling_rate = inputs.pop("sampling_rate") + extra = inputs + inputs = _inputs + if in_sampling_rate != self.feature_extractor.sampling_rate: + import torch + from torchaudio import functional as F + + inputs = F.resample( + torch.from_numpy(inputs), in_sampling_rate, self.feature_extractor.sampling_rate + ).numpy() + ratio = self.feature_extractor.sampling_rate / in_sampling_rate + else: + ratio = 1 + if stride is not None: + if stride[0] + stride[1] > inputs.shape[0]: + raise ValueError("Stride is too large for input") + + # Stride needs to get the chunk length here, it's going to get + # swallowed by the `feature_extractor` later, and then batching + # can add extra data in the inputs, so we need to keep track + # of the original length in the stride so we can cut properly. + stride = (inputs.shape[0], int(round(stride[0] * ratio)), int(round(stride[1] * ratio))) + if not isinstance(inputs, np.ndarray): + raise ValueError(f"We expect a numpy ndarray as input, got `{type(inputs)}`") + if len(inputs.shape) != 1: + raise ValueError("We expect a single channel audio input for AutomaticSpeechRecognitionPipeline") + + if chunk_length_s: + if self.type == "seq2seq" and not ignore_warning: + logger.warning( + "Using `chunk_length_s` is very experimental with seq2seq models. The results will not necessarily" + " be entirely accurate and will have caveats. More information:" + " https://github.com/huggingface/transformers/pull/20104. Ignore this warning with pipeline(...," + " ignore_warning=True)" + ) + self._preprocess_params["ignore_warning"] = True + if stride_length_s is None: + stride_length_s = chunk_length_s / 6 + + if isinstance(stride_length_s, (int, float)): + stride_length_s = [stride_length_s, stride_length_s] + + # XXX: Carefuly, this variable will not exist in `seq2seq` setting. + # Currently chunking is not possible at this level for `seq2seq` so + # it's ok. + align_to = getattr(self.model.config, "inputs_to_logits_ratio", 1) + chunk_len = int(round(chunk_length_s * self.feature_extractor.sampling_rate / align_to) * align_to) + stride_left = int(round(stride_length_s[0] * self.feature_extractor.sampling_rate / align_to) * align_to) + stride_right = int(round(stride_length_s[1] * self.feature_extractor.sampling_rate / align_to) * align_to) + + if chunk_len < stride_left + stride_right: + raise ValueError("Chunk length must be superior to stride length") + + rescale = self.type != "seq2seq_whisper" + # make sure that + for item in chunk_iter( + inputs, self.feature_extractor, chunk_len, stride_left, stride_right, rescale, self.torch_dtype + ): + yield item + else: + processed = self.feature_extractor( + inputs, sampling_rate=self.feature_extractor.sampling_rate, return_tensors="pt" + ) + if self.torch_dtype is not None: + processed = processed.to(dtype=self.torch_dtype) + if stride is not None: + if self.type == "seq2seq": + raise ValueError("Stride is only usable with CTC models, try removing it !") + + processed["stride"] = stride + yield {"is_last": True, **processed, **extra} + + def _forward(self, model_inputs, return_timestamps=False, generate_kwargs=None): + if generate_kwargs is None: + generate_kwargs = {} + if return_timestamps and self.type == "seq2seq_whisper": + generate_kwargs["return_timestamps"] = return_timestamps + is_last = model_inputs.pop("is_last") + + if self.type in {"seq2seq", "seq2seq_whisper"}: + encoder = self.model.get_encoder() + # Consume values so we can let extra information flow freely through + # the pipeline (important for `partial` in microphone) + if "input_features" in model_inputs: + inputs = model_inputs.pop("input_features") + elif "input_values" in model_inputs: + inputs = model_inputs.pop("input_values") + else: + raise ValueError( + "Seq2Seq speech recognition model requires either a " + f"`input_features` or `input_values` key, but only has {model_inputs.keys()}" + ) + + # we need to pass `processed.get("attention_mask")` here since audio encoder + # attention mask length is different from expected text decoder `encoder_attention_mask` length + # `generate` magic to create the mask automatically won't work, we basically need to help + # it here. + attention_mask = model_inputs.pop("attention_mask", None) + tokens = self.model.generate( + encoder_outputs=encoder(inputs, attention_mask=attention_mask), + attention_mask=attention_mask, + **generate_kwargs, + ) + out = {"tokens": tokens} + if self.type == "seq2seq_whisper": + stride = model_inputs.pop("stride", None) + if stride is not None: + out["stride"] = stride + + else: + stride = model_inputs.pop("stride", None) + input_values = model_inputs.pop("input_values") + attention_mask = model_inputs.pop("attention_mask", None) + outputs = self.model(input_values=input_values, attention_mask=attention_mask) + logits = outputs.logits + + if self.type == "ctc_with_lm": + out = {"logits": logits} + else: + out = {"tokens": logits.argmax(dim=-1)} + if stride is not None: + # Send stride to `postprocess`. + # it needs to be handled there where + # the pieces are to be concatenated. + ratio = 1 / self.model.config.inputs_to_logits_ratio + if isinstance(stride, tuple): + out["stride"] = rescale_stride([stride], ratio)[0] + else: + out["stride"] = rescale_stride(stride, ratio) + # Leftover + extra = model_inputs + return {"is_last": is_last, **out, **extra} + + def postprocess( + self, model_outputs, decoder_kwargs: Optional[Dict] = None, return_timestamps=None, return_language=None + ): + # Optional return types + optional = {} + + if return_timestamps and self.type == "seq2seq": + raise ValueError("We cannot return_timestamps yet on non-ctc models apart from Whisper !") + if return_timestamps == "char" and self.type == "ctc_with_lm": + raise ValueError("CTC with LM cannot return `char` timestamps, only `words`") + if return_timestamps in {"char", "words"} and self.type == "seq2seq_whisper": + raise ValueError("Whisper cannot return `char` nor `words` timestamps, use `True` instead.") + + if return_language is not None and self.type != "seq2seq_whisper": + raise ValueError("Only whisper can return language for now.") + + final_items = [] + key = "logits" if self.type == "ctc_with_lm" else "tokens" + stride = None + for outputs in model_outputs: + items = outputs[key].numpy() + stride = outputs.get("stride", None) + if stride is not None and self.type in {"ctc", "ctc_with_lm"}: + total_n, left, right = stride + # Total_n might be < logits.shape[1] + # because of padding, that's why + # we need to reconstruct this information + # This won't work with left padding (which doesn't exist right now) + right_n = total_n - right + items = items[:, left:right_n] + final_items.append(items) + + if stride and self.type == "seq2seq": + items = _find_longest_common_sequence(final_items, self.tokenizer) + elif self.type == "seq2seq_whisper": + time_precision = self.feature_extractor.chunk_length / self.model.config.max_source_positions + # Send the chunking back to seconds, it's easier to handle in whisper + sampling_rate = self.feature_extractor.sampling_rate + for output in model_outputs: + if "stride" in output: + chunk_len, stride_left, stride_right = output["stride"] + # Go back in seconds + chunk_len /= sampling_rate + stride_left /= sampling_rate + stride_right /= sampling_rate + output["stride"] = chunk_len, stride_left, stride_right + + text, optional = self.tokenizer._decode_asr( + model_outputs, + return_timestamps=return_timestamps, + return_language=return_language, + time_precision=time_precision, + ) + else: + items = np.concatenate(final_items, axis=1) + items = items.squeeze(0) + + if self.type == "ctc_with_lm": + if decoder_kwargs is None: + decoder_kwargs = {} + beams = self.decoder.decode_beams(items, **decoder_kwargs) + text = beams[0][0] + if return_timestamps: + # Simply cast from pyctcdecode format to wav2vec2 format to leverage + # pre-existing code later + chunk_offset = beams[0][2] + offsets = [] + for word, (start_offset, end_offset) in chunk_offset: + offsets.append({"word": word, "start_offset": start_offset, "end_offset": end_offset}) + elif self.type != "seq2seq_whisper": + skip_special_tokens = self.type != "ctc" + text = self.tokenizer.decode(items, skip_special_tokens=skip_special_tokens) + if return_timestamps: + offsets = self.tokenizer.decode( + items, skip_special_tokens=skip_special_tokens, output_char_offsets=True + )["char_offsets"] + if return_timestamps == "word": + offsets = self.tokenizer._get_word_offsets(offsets, self.tokenizer.replace_word_delimiter_char) + + if return_timestamps and self.type not in {"seq2seq", "seq2seq_whisper"}: + chunks = [] + for item in offsets: + start = item["start_offset"] * self.model.config.inputs_to_logits_ratio + start /= self.feature_extractor.sampling_rate + + stop = item["end_offset"] * self.model.config.inputs_to_logits_ratio + stop /= self.feature_extractor.sampling_rate + + chunks.append({"text": item[return_timestamps], "timestamp": (start, stop)}) + optional["chunks"] = chunks + + extra = defaultdict(list) + for output in model_outputs: + output.pop("tokens", None) + output.pop("logits", None) + output.pop("is_last", None) + output.pop("stride", None) + for k, v in output.items(): + extra[k].append(v) + return {"text": text, **optional, **extra} + + +def _find_timestamp_sequence(sequences, tokenizer, feature_extractor, max_source_positions): + """ + Computes the final sequences by merging the end of the nth sequence with the beginning of the n+1th sequence. Since + `WhisperForConditionalGeneration` produces the timestamps pairwise, we filter the consecutive timestamps and only + iterate over them. We keep track of the `time` which indicates the actual starting time of the chunk that is + processed. We need to make sure to offset the timestamps tokens by the `time` in order for the tokenizer to + properly compute the final `offset`. + """ + # index of the first timestamp token + timestamp_begin = tokenizer.convert_tokens_to_ids("<|notimestamps|>") + 1 + items = [] + # approximation of the token to time ratio : ~0.2seconds + time_precision = feature_extractor.chunk_length / max_source_positions + time = 0 + for seq_idx, item in enumerate(sequences): + sequence, stride = item + if isinstance(sequence, list): + sequence = np.array(sequence) + chunk_len, stride_left, stride_right = stride + sequence = sequence.squeeze(0) + # get rid of the `forced_decoder_idx` that are use to parametrize the generation + begin_idx = np.where(sequence == timestamp_begin)[0][0] if timestamp_begin in sequence else 0 + sequence = sequence[begin_idx:] + + timestamp_tokens = sequence >= timestamp_begin + if seq_idx != 0 and sum(timestamp_tokens) > 0: + consecutive = np.where(timestamp_tokens[:-1] & timestamp_tokens[1:])[0] + 1 + last_timestamp = np.where(timestamp_tokens)[0][-1] + consecutive = np.append(consecutive, last_timestamp) if last_timestamp not in consecutive else consecutive + time -= stride_left + stride_right + offset = int((time / feature_extractor.sampling_rate) / time_precision) + overlap_time = int((stride_left / feature_extractor.sampling_rate) / time_precision) + # relevant timestamps are in the overlapping part + relevant_timestamp = np.where(sequence[consecutive] >= timestamp_begin + overlap_time)[0] + if relevant_timestamp.shape[0] > 0: + relevant_timestamp = ( + consecutive[relevant_timestamp[0] - 1] if relevant_timestamp[0] > 0 else consecutive[0] + ) + # if a big stride is used, we need to check some of the previous items for the best overlap + best_match = 0 + sliced_sequence = [] + for idx, previous_sequence in enumerate(reversed(items)): + previous_tokens = previous_sequence[1:-1] + if previous_sequence[0] < (timestamp_begin + offset - overlap_time) and idx != 0: + break # the previous sequence is too far in the past + if len(previous_tokens) > 0: + # find the longest common sequence between the overlapping parts + index_left, index_right, match_length = _fast_find_longest_common_sequence( + sequence[1:relevant_timestamp], previous_tokens + ) + # don't do anything if only 1 token was matched + if match_length > 1 and match_length > best_match: + best_match = match_length + best_idx = idx + end_of_curr_sequence_idx = ( + np.where(sequence[index_left + 1 :] >= timestamp_begin)[0][0] + 1 + ) + end_of_curr_sequence_idx = end_of_curr_sequence_idx + 1 + index_left + # if all the tokens are matched, suffix + if index_left == 0 and match_length == len(previous_tokens): + sliced_sequence = np.insert( + sequence[index_left + 1 : end_of_curr_sequence_idx], 0, previous_sequence[0] + ) + sliced_sequence[-1] = previous_sequence[-1] + # if part of the previous sequence is not taken + elif index_left >= 0: + sliced_sequence = sequence[index_left + 1 : end_of_curr_sequence_idx] + # let's insert the missing part of the previous sequence + previous_slice = ( + previous_sequence[: index_right + 1] if index_right > 0 else [previous_sequence[0]] + ) + sliced_sequence = np.insert(sliced_sequence, 0, previous_slice) + sliced_sequence[-1] += offset + + if len(sliced_sequence) > 0: + items[len(items) - best_idx - 1] = sliced_sequence + items = items[: len(items) - best_idx] + sequence = sequence[end_of_curr_sequence_idx:] + + # sequence might have changed + timestamp_tokens = sequence >= timestamp_begin + consecutive = np.where(timestamp_tokens[:-1] & timestamp_tokens[1:])[0] + 1 + if sum(timestamp_tokens) > 0: + last_timestamp = np.where(timestamp_tokens)[0][-1] + consecutive = ( + np.append(consecutive, last_timestamp + 1) if last_timestamp not in consecutive else consecutive + ) + + if len(consecutive) > 0: + last_slice = 0 + for current_slice in consecutive: + actual_offset = items[-1][-1] if seq_idx != 0 or last_slice != 0 else sequence[0] + sliced_tokens = sequence[last_slice:current_slice] + duration = sliced_tokens[-1] - sliced_tokens[0] + sliced_tokens[0] = actual_offset + sliced_tokens[-1] = actual_offset + duration + items.append(sliced_tokens) + last_slice = current_slice + + time += chunk_len + result = [] + for i in range(len(items)): + result += items[i].tolist() + return result diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/base.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/base.py new file mode 100644 index 0000000000000000000000000000000000000000..de6c9a8ec4d945c9da66d0b007abd32f43974ed0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/base.py @@ -0,0 +1,1234 @@ +# coding=utf-8 +# Copyright 2018 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import collections +import csv +import importlib +import inspect +import json +import os +import pickle +import sys +import types +import warnings +from abc import ABC, abstractmethod +from collections import UserDict +from contextlib import contextmanager +from os.path import abspath, exists +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union + +from packaging import version + +from ..dynamic_module_utils import custom_object_save +from ..feature_extraction_utils import PreTrainedFeatureExtractor +from ..image_processing_utils import BaseImageProcessor +from ..modelcard import ModelCard +from ..models.auto.configuration_auto import AutoConfig +from ..tokenization_utils import PreTrainedTokenizer +from ..utils import ModelOutput, add_end_docstrings, is_tf_available, is_torch_available, logging + + +GenericTensor = Union[List["GenericTensor"], "torch.Tensor", "tf.Tensor"] + +if is_tf_available(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import TFAutoModel + +if is_torch_available(): + import torch + from torch.utils.data import DataLoader, Dataset + + from ..models.auto.modeling_auto import AutoModel + + # Re-export for backward compatibility + from .pt_utils import KeyDataset +else: + Dataset = None + KeyDataset = None + +if TYPE_CHECKING: + from ..modeling_tf_utils import TFPreTrainedModel + from ..modeling_utils import PreTrainedModel + + +logger = logging.get_logger(__name__) + + +def no_collate_fn(items): + if len(items) != 1: + raise ValueError("This collate_fn is meant to be used with batch_size=1") + return items[0] + + +def _pad(items, key, padding_value, padding_side): + batch_size = len(items) + if isinstance(items[0][key], torch.Tensor): + # Others include `attention_mask` etc... + shape = items[0][key].shape + dim = len(shape) + if key in ["pixel_values", "image"]: + # This is probable image so padding shouldn't be necessary + # B, C, H, W + return torch.cat([item[key] for item in items], dim=0) + elif dim == 4 and key == "input_features": + # this is probably a mel spectrogram batched + return torch.cat([item[key] for item in items], dim=0) + max_length = max(item[key].shape[1] for item in items) + min_length = min(item[key].shape[1] for item in items) + dtype = items[0][key].dtype + + if dim == 2: + if max_length == min_length: + # Bypass for `ImageGPT` which doesn't provide a padding value, yet + # we can consistently pad since the size should be matching + return torch.cat([item[key] for item in items], dim=0) + tensor = torch.zeros((batch_size, max_length), dtype=dtype) + padding_value + elif dim == 3: + tensor = torch.zeros((batch_size, max_length, shape[-1]), dtype=dtype) + padding_value + elif dim == 4: + tensor = torch.zeros((batch_size, max_length, shape[-2], shape[-1]), dtype=dtype) + padding_value + + for i, item in enumerate(items): + if dim == 2: + if padding_side == "left": + tensor[i, -len(item[key][0]) :] = item[key][0].clone() + else: + tensor[i, : len(item[key][0])] = item[key][0].clone() + elif dim == 3: + if padding_side == "left": + tensor[i, -len(item[key][0]) :, :] = item[key][0].clone() + else: + tensor[i, : len(item[key][0]), :] = item[key][0].clone() + elif dim == 4: + if padding_side == "left": + tensor[i, -len(item[key][0]) :, :, :] = item[key][0].clone() + else: + tensor[i, : len(item[key][0]), :, :] = item[key][0].clone() + + return tensor + else: + return [item[key] for item in items] + + +def pad_collate_fn(tokenizer, feature_extractor): + # Tokenizer + t_padding_side = None + # Feature extractor + f_padding_side = None + if tokenizer is None and feature_extractor is None: + raise ValueError("Pipeline without tokenizer or feature_extractor cannot do batching") + if tokenizer is not None: + if tokenizer.pad_token_id is None: + raise ValueError( + "Pipeline with tokenizer without pad_token cannot do batching. You can try to set it with " + "`pipe.tokenizer.pad_token_id = model.config.eos_token_id`." + ) + else: + t_padding_value = tokenizer.pad_token_id + t_padding_side = tokenizer.padding_side + if feature_extractor is not None: + # Feature extractor can be images, where no padding is expected + f_padding_value = getattr(feature_extractor, "padding_value", None) + f_padding_side = getattr(feature_extractor, "padding_side", None) + + if t_padding_side is not None and f_padding_side is not None and t_padding_side != f_padding_side: + raise ValueError( + f"The feature extractor, and tokenizer don't agree on padding side {t_padding_side} != {f_padding_side}" + ) + padding_side = "right" + if t_padding_side is not None: + padding_side = t_padding_side + if f_padding_side is not None: + padding_side = f_padding_side + + def inner(items): + keys = set(items[0].keys()) + for item in items: + if set(item.keys()) != keys: + raise ValueError( + f"The elements of the batch contain different keys. Cannot batch them ({set(item.keys())} !=" + f" {keys})" + ) + # input_values, input_pixels, input_ids, ... + padded = {} + for key in keys: + if key in {"input_ids"}: + # ImageGPT uses a feature extractor + if tokenizer is None and feature_extractor is not None: + _padding_value = f_padding_value + else: + _padding_value = t_padding_value + elif key in {"input_values", "pixel_values", "input_features"}: + _padding_value = f_padding_value + elif key in {"p_mask", "special_tokens_mask"}: + _padding_value = 1 + elif key in {"attention_mask", "token_type_ids"}: + _padding_value = 0 + else: + # This is likely another random key maybe even user provided + _padding_value = 0 + padded[key] = _pad(items, key, _padding_value, padding_side) + return padded + + return inner + + +def infer_framework_load_model( + model, + config: AutoConfig, + model_classes: Optional[Dict[str, Tuple[type]]] = None, + task: Optional[str] = None, + framework: Optional[str] = None, + **model_kwargs, +): + """ + Select framework (TensorFlow or PyTorch) to use from the `model` passed. Returns a tuple (framework, model). + + If `model` is instantiated, this function will just infer the framework from the model class. Otherwise `model` is + actually a checkpoint name and this method will try to instantiate it using `model_classes`. Since we don't want to + instantiate the model twice, this model is returned for use by the pipeline. + + If both frameworks are installed and available for `model`, PyTorch is selected. + + Args: + model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model to infer the framework from. If `str`, a checkpoint name. The model to infer the framewrok from. + config ([`AutoConfig`]): + The config associated with the model to help using the correct class + model_classes (dictionary `str` to `type`, *optional*): + A mapping framework to class. + task (`str`): + The task defining which pipeline will be returned. + model_kwargs: + Additional dictionary of keyword arguments passed along to the model's `from_pretrained(..., + **model_kwargs)` function. + + Returns: + `Tuple`: A tuple framework, model. + """ + if not is_tf_available() and not is_torch_available(): + raise RuntimeError( + "At least one of TensorFlow 2.0 or PyTorch should be installed. " + "To install TensorFlow 2.0, read the instructions at https://www.tensorflow.org/install/ " + "To install PyTorch, read the instructions at https://pytorch.org/." + ) + if isinstance(model, str): + model_kwargs["_from_pipeline"] = task + class_tuple = () + look_pt = is_torch_available() and framework in {"pt", None} + look_tf = is_tf_available() and framework in {"tf", None} + if model_classes: + if look_pt: + class_tuple = class_tuple + model_classes.get("pt", (AutoModel,)) + if look_tf: + class_tuple = class_tuple + model_classes.get("tf", (TFAutoModel,)) + if config.architectures: + classes = [] + for architecture in config.architectures: + transformers_module = importlib.import_module("transformers") + if look_pt: + _class = getattr(transformers_module, architecture, None) + if _class is not None: + classes.append(_class) + if look_tf: + _class = getattr(transformers_module, f"TF{architecture}", None) + if _class is not None: + classes.append(_class) + class_tuple = class_tuple + tuple(classes) + + if len(class_tuple) == 0: + raise ValueError(f"Pipeline cannot infer suitable model classes from {model}") + + for model_class in class_tuple: + kwargs = model_kwargs.copy() + if framework == "pt" and model.endswith(".h5"): + kwargs["from_tf"] = True + logger.warning( + "Model might be a TensorFlow model (ending with `.h5`) but TensorFlow is not available. " + "Trying to load the model with PyTorch." + ) + elif framework == "tf" and model.endswith(".bin"): + kwargs["from_pt"] = True + logger.warning( + "Model might be a PyTorch model (ending with `.bin`) but PyTorch is not available. " + "Trying to load the model with Tensorflow." + ) + + try: + model = model_class.from_pretrained(model, **kwargs) + if hasattr(model, "eval"): + model = model.eval() + # Stop loading on the first successful load. + break + except (OSError, ValueError): + continue + + if isinstance(model, str): + raise ValueError(f"Could not load model {model} with any of the following classes: {class_tuple}.") + + framework = "tf" if "keras.engine.training.Model" in str(inspect.getmro(model.__class__)) else "pt" + return framework, model + + +def infer_framework_from_model( + model, + model_classes: Optional[Dict[str, Tuple[type]]] = None, + task: Optional[str] = None, + framework: Optional[str] = None, + **model_kwargs, +): + """ + Select framework (TensorFlow or PyTorch) to use from the `model` passed. Returns a tuple (framework, model). + + If `model` is instantiated, this function will just infer the framework from the model class. Otherwise `model` is + actually a checkpoint name and this method will try to instantiate it using `model_classes`. Since we don't want to + instantiate the model twice, this model is returned for use by the pipeline. + + If both frameworks are installed and available for `model`, PyTorch is selected. + + Args: + model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model to infer the framework from. If `str`, a checkpoint name. The model to infer the framewrok from. + model_classes (dictionary `str` to `type`, *optional*): + A mapping framework to class. + task (`str`): + The task defining which pipeline will be returned. + model_kwargs: + Additional dictionary of keyword arguments passed along to the model's `from_pretrained(..., + **model_kwargs)` function. + + Returns: + `Tuple`: A tuple framework, model. + """ + if isinstance(model, str): + config = AutoConfig.from_pretrained(model, _from_pipeline=task, **model_kwargs) + else: + config = model.config + return infer_framework_load_model( + model, config, model_classes=model_classes, _from_pipeline=task, task=task, framework=framework, **model_kwargs + ) + + +def get_framework(model, revision: Optional[str] = None): + """ + Select framework (TensorFlow or PyTorch) to use. + + Args: + model (`str`, [`PreTrainedModel`] or [`TFPreTrainedModel`]): + If both frameworks are installed, picks the one corresponding to the model passed (either a model class or + the model name). If no specific model is provided, defaults to using PyTorch. + """ + warnings.warn( + "`get_framework` is deprecated and will be removed in v5, use `infer_framework_from_model` instead.", + FutureWarning, + ) + if not is_tf_available() and not is_torch_available(): + raise RuntimeError( + "At least one of TensorFlow 2.0 or PyTorch should be installed. " + "To install TensorFlow 2.0, read the instructions at https://www.tensorflow.org/install/ " + "To install PyTorch, read the instructions at https://pytorch.org/." + ) + if isinstance(model, str): + if is_torch_available() and not is_tf_available(): + model = AutoModel.from_pretrained(model, revision=revision) + elif is_tf_available() and not is_torch_available(): + model = TFAutoModel.from_pretrained(model, revision=revision) + else: + try: + model = AutoModel.from_pretrained(model, revision=revision) + except OSError: + model = TFAutoModel.from_pretrained(model, revision=revision) + + framework = "tf" if "keras.engine.training.Model" in str(inspect.getmro(model.__class__)) else "pt" + return framework + + +def get_default_model_and_revision( + targeted_task: Dict, framework: Optional[str], task_options: Optional[Any] +) -> Union[str, Tuple[str, str]]: + """ + Select a default model to use for a given task. Defaults to pytorch if ambiguous. + + Args: + targeted_task (`Dict` ): + Dictionary representing the given task, that should contain default models + + framework (`str`, None) + "pt", "tf" or None, representing a specific framework if it was specified, or None if we don't know yet. + + task_options (`Any`, None) + Any further value required by the task to get fully specified, for instance (SRC, TGT) languages for + translation task. + + Returns + + `str` The model string representing the default model for this pipeline + """ + if is_torch_available() and not is_tf_available(): + framework = "pt" + elif is_tf_available() and not is_torch_available(): + framework = "tf" + + defaults = targeted_task["default"] + if task_options: + if task_options not in defaults: + raise ValueError(f"The task does not provide any default models for options {task_options}") + default_models = defaults[task_options]["model"] + elif "model" in defaults: + default_models = targeted_task["default"]["model"] + else: + # XXX This error message needs to be updated to be more generic if more tasks are going to become + # parametrized + raise ValueError('The task defaults can\'t be correctly selected. You probably meant "translation_XX_to_YY"') + + if framework is None: + framework = "pt" + + return default_models[framework] + + +class PipelineException(Exception): + """ + Raised by a [`Pipeline`] when handling __call__. + + Args: + task (`str`): The task of the pipeline. + model (`str`): The model used by the pipeline. + reason (`str`): The error message to display. + """ + + def __init__(self, task: str, model: str, reason: str): + super().__init__(reason) + + self.task = task + self.model = model + + +class ArgumentHandler(ABC): + """ + Base interface for handling arguments for each [`~pipelines.Pipeline`]. + """ + + @abstractmethod + def __call__(self, *args, **kwargs): + raise NotImplementedError() + + +class PipelineDataFormat: + """ + Base class for all the pipeline supported data format both for reading and writing. Supported data formats + currently includes: + + - JSON + - CSV + - stdin/stdout (pipe) + + `PipelineDataFormat` also includes some utilities to work with multi-columns like mapping from datasets columns to + pipelines keyword arguments through the `dataset_kwarg_1=dataset_column_1` format. + + Args: + output_path (`str`, *optional*): Where to save the outgoing data. + input_path (`str`, *optional*): Where to look for the input data. + column (`str`, *optional*): The column to read. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not to overwrite the `output_path`. + """ + + SUPPORTED_FORMATS = ["json", "csv", "pipe"] + + def __init__( + self, + output_path: Optional[str], + input_path: Optional[str], + column: Optional[str], + overwrite: bool = False, + ): + self.output_path = output_path + self.input_path = input_path + self.column = column.split(",") if column is not None else [""] + self.is_multi_columns = len(self.column) > 1 + + if self.is_multi_columns: + self.column = [tuple(c.split("=")) if "=" in c else (c, c) for c in self.column] + + if output_path is not None and not overwrite: + if exists(abspath(self.output_path)): + raise OSError(f"{self.output_path} already exists on disk") + + if input_path is not None: + if not exists(abspath(self.input_path)): + raise OSError(f"{self.input_path} doesnt exist on disk") + + @abstractmethod + def __iter__(self): + raise NotImplementedError() + + @abstractmethod + def save(self, data: Union[dict, List[dict]]): + """ + Save the provided data object with the representation for the current [`~pipelines.PipelineDataFormat`]. + + Args: + data (`dict` or list of `dict`): The data to store. + """ + raise NotImplementedError() + + def save_binary(self, data: Union[dict, List[dict]]) -> str: + """ + Save the provided data object as a pickle-formatted binary data on the disk. + + Args: + data (`dict` or list of `dict`): The data to store. + + Returns: + `str`: Path where the data has been saved. + """ + path, _ = os.path.splitext(self.output_path) + binary_path = os.path.extsep.join((path, "pickle")) + + with open(binary_path, "wb+") as f_output: + pickle.dump(data, f_output) + + return binary_path + + @staticmethod + def from_str( + format: str, + output_path: Optional[str], + input_path: Optional[str], + column: Optional[str], + overwrite=False, + ) -> "PipelineDataFormat": + """ + Creates an instance of the right subclass of [`~pipelines.PipelineDataFormat`] depending on `format`. + + Args: + format: (`str`): + The format of the desired pipeline. Acceptable values are `"json"`, `"csv"` or `"pipe"`. + output_path (`str`, *optional*): + Where to save the outgoing data. + input_path (`str`, *optional*): + Where to look for the input data. + column (`str`, *optional*): + The column to read. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not to overwrite the `output_path`. + + Returns: + [`~pipelines.PipelineDataFormat`]: The proper data format. + """ + if format == "json": + return JsonPipelineDataFormat(output_path, input_path, column, overwrite=overwrite) + elif format == "csv": + return CsvPipelineDataFormat(output_path, input_path, column, overwrite=overwrite) + elif format == "pipe": + return PipedPipelineDataFormat(output_path, input_path, column, overwrite=overwrite) + else: + raise KeyError(f"Unknown reader {format} (Available reader are json/csv/pipe)") + + +class CsvPipelineDataFormat(PipelineDataFormat): + """ + Support for pipelines using CSV data format. + + Args: + output_path (`str`, *optional*): Where to save the outgoing data. + input_path (`str`, *optional*): Where to look for the input data. + column (`str`, *optional*): The column to read. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not to overwrite the `output_path`. + """ + + def __init__( + self, + output_path: Optional[str], + input_path: Optional[str], + column: Optional[str], + overwrite=False, + ): + super().__init__(output_path, input_path, column, overwrite=overwrite) + + def __iter__(self): + with open(self.input_path, "r") as f: + reader = csv.DictReader(f) + for row in reader: + if self.is_multi_columns: + yield {k: row[c] for k, c in self.column} + else: + yield row[self.column[0]] + + def save(self, data: List[dict]): + """ + Save the provided data object with the representation for the current [`~pipelines.PipelineDataFormat`]. + + Args: + data (`List[dict]`): The data to store. + """ + with open(self.output_path, "w") as f: + if len(data) > 0: + writer = csv.DictWriter(f, list(data[0].keys())) + writer.writeheader() + writer.writerows(data) + + +class JsonPipelineDataFormat(PipelineDataFormat): + """ + Support for pipelines using JSON file format. + + Args: + output_path (`str`, *optional*): Where to save the outgoing data. + input_path (`str`, *optional*): Where to look for the input data. + column (`str`, *optional*): The column to read. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not to overwrite the `output_path`. + """ + + def __init__( + self, + output_path: Optional[str], + input_path: Optional[str], + column: Optional[str], + overwrite=False, + ): + super().__init__(output_path, input_path, column, overwrite=overwrite) + + with open(input_path, "r") as f: + self._entries = json.load(f) + + def __iter__(self): + for entry in self._entries: + if self.is_multi_columns: + yield {k: entry[c] for k, c in self.column} + else: + yield entry[self.column[0]] + + def save(self, data: dict): + """ + Save the provided data object in a json file. + + Args: + data (`dict`): The data to store. + """ + with open(self.output_path, "w") as f: + json.dump(data, f) + + +class PipedPipelineDataFormat(PipelineDataFormat): + """ + Read data from piped input to the python process. For multi columns data, columns should separated by \t + + If columns are provided, then the output will be a dictionary with {column_x: value_x} + + Args: + output_path (`str`, *optional*): Where to save the outgoing data. + input_path (`str`, *optional*): Where to look for the input data. + column (`str`, *optional*): The column to read. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not to overwrite the `output_path`. + """ + + def __iter__(self): + for line in sys.stdin: + # Split for multi-columns + if "\t" in line: + line = line.split("\t") + if self.column: + # Dictionary to map arguments + yield {kwargs: l for (kwargs, _), l in zip(self.column, line)} + else: + yield tuple(line) + + # No dictionary to map arguments + else: + yield line + + def save(self, data: dict): + """ + Print the data. + + Args: + data (`dict`): The data to store. + """ + print(data) + + def save_binary(self, data: Union[dict, List[dict]]) -> str: + if self.output_path is None: + raise KeyError( + "When using piped input on pipeline outputting large object requires an output file path. " + "Please provide such output path through --output argument." + ) + + return super().save_binary(data) + + +class _ScikitCompat(ABC): + """ + Interface layer for the Scikit and Keras compatibility. + """ + + @abstractmethod + def transform(self, X): + raise NotImplementedError() + + @abstractmethod + def predict(self, X): + raise NotImplementedError() + + +PIPELINE_INIT_ARGS = r""" + Arguments: + model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from + [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow. + tokenizer ([`PreTrainedTokenizer`]): + The tokenizer that will be used by the pipeline to encode data for the model. This object inherits from + [`PreTrainedTokenizer`]. + modelcard (`str` or [`ModelCard`], *optional*): + Model card attributed to the model for this pipeline. + framework (`str`, *optional*): + The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be + installed. + + If no framework is specified, will default to the one currently installed. If no framework is specified and + both frameworks are installed, will default to the framework of the `model`, or to PyTorch if no model is + provided. + task (`str`, defaults to `""`): + A task-identifier for the pipeline. + num_workers (`int`, *optional*, defaults to 8): + When the pipeline will use *DataLoader* (when passing a dataset, on GPU for a Pytorch model), the number of + workers to be used. + batch_size (`int`, *optional*, defaults to 1): + When the pipeline will use *DataLoader* (when passing a dataset, on GPU for a Pytorch model), the size of + the batch to use, for inference this is not always beneficial, please read [Batching with + pipelines](https://huggingface.co/transformers/main_classes/pipelines.html#pipeline-batching) . + args_parser ([`~pipelines.ArgumentHandler`], *optional*): + Reference to the object in charge of parsing supplied pipeline parameters. + device (`int`, *optional*, defaults to -1): + Device ordinal for CPU/GPU supports. Setting this to -1 will leverage CPU, a positive will run the model on + the associated CUDA device id. You can pass native `torch.device` or a `str` too. + binary_output (`bool`, *optional*, defaults to `False`): + Flag indicating if the output the pipeline should happen in a binary format (i.e., pickle) or as raw text. +""" + +if is_torch_available(): + from transformers.pipelines.pt_utils import ( + PipelineChunkIterator, + PipelineDataset, + PipelineIterator, + PipelinePackIterator, + ) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class Pipeline(_ScikitCompat): + """ + The Pipeline class is the class from which all pipelines inherit. Refer to this class for methods shared across + different pipelines. + + Base class implementing pipelined operations. Pipeline workflow is defined as a sequence of the following + operations: + + Input -> Tokenization -> Model Inference -> Post-Processing (task dependent) -> Output + + Pipeline supports running on CPU or GPU through the device argument (see below). + + Some pipeline, like for instance [`FeatureExtractionPipeline`] (`'feature-extraction'`) output large tensor object + as nested-lists. In order to avoid dumping such large structure as textual data we provide the `binary_output` + constructor argument. If set to `True`, the output will be stored in the pickle format. + """ + + default_input_names = None + + def __init__( + self, + model: Union["PreTrainedModel", "TFPreTrainedModel"], + tokenizer: Optional[PreTrainedTokenizer] = None, + feature_extractor: Optional[PreTrainedFeatureExtractor] = None, + image_processor: Optional[BaseImageProcessor] = None, + modelcard: Optional[ModelCard] = None, + framework: Optional[str] = None, + task: str = "", + args_parser: ArgumentHandler = None, + device: Union[int, str, "torch.device"] = None, + torch_dtype: Optional[Union[str, "torch.dtype"]] = None, + binary_output: bool = False, + **kwargs, + ): + if framework is None: + framework, model = infer_framework_load_model(model, config=model.config) + + self.task = task + self.model = model + self.tokenizer = tokenizer + self.feature_extractor = feature_extractor + self.image_processor = image_processor + self.modelcard = modelcard + self.framework = framework + + if self.framework == "pt" and device is not None and not (isinstance(device, int) and device < 0): + self.model.to(device) + + if device is None: + # `accelerate` device map + hf_device_map = getattr(self.model, "hf_device_map", None) + if hf_device_map is not None: + # Take the first device used by `accelerate`. + device = next(iter(hf_device_map.values())) + else: + device = -1 + + if is_torch_available() and self.framework == "pt": + if isinstance(device, torch.device): + self.device = device + elif isinstance(device, str): + self.device = torch.device(device) + elif device < 0: + self.device = torch.device("cpu") + else: + self.device = torch.device(f"cuda:{device}") + else: + self.device = device if device is not None else -1 + self.torch_dtype = torch_dtype + self.binary_output = binary_output + + # Update config and generation_config with task specific parameters + task_specific_params = self.model.config.task_specific_params + if task_specific_params is not None and task in task_specific_params: + self.model.config.update(task_specific_params.get(task)) + if self.model.can_generate(): + self.model.generation_config.update(**task_specific_params.get(task)) + + self.call_count = 0 + self._batch_size = kwargs.pop("batch_size", None) + self._num_workers = kwargs.pop("num_workers", None) + self._preprocess_params, self._forward_params, self._postprocess_params = self._sanitize_parameters(**kwargs) + + if self.image_processor is None and self.feature_extractor is not None: + if isinstance(self.feature_extractor, BaseImageProcessor): + # Backward compatible change, if users called + # ImageSegmentationPipeline(.., feature_extractor=MyFeatureExtractor()) + # then we should keep working + self.image_processor = self.feature_extractor + + def save_pretrained(self, save_directory: str): + """ + Save the pipeline's model and tokenizer. + + Args: + save_directory (`str`): + A path to the directory where to saved. It will be created if it doesn't exist. + """ + if os.path.isfile(save_directory): + logger.error(f"Provided path ({save_directory}) should be a directory, not a file") + return + os.makedirs(save_directory, exist_ok=True) + + if hasattr(self, "_registered_impl"): + # Add info to the config + pipeline_info = self._registered_impl.copy() + custom_pipelines = {} + for task, info in pipeline_info.items(): + if info["impl"] != self.__class__: + continue + + info = info.copy() + module_name = info["impl"].__module__ + last_module = module_name.split(".")[-1] + # Change classes into their names/full names + info["impl"] = f"{last_module}.{info['impl'].__name__}" + info["pt"] = tuple(c.__name__ for c in info["pt"]) + info["tf"] = tuple(c.__name__ for c in info["tf"]) + + custom_pipelines[task] = info + self.model.config.custom_pipelines = custom_pipelines + # Save the pipeline custom code + custom_object_save(self, save_directory) + + self.model.save_pretrained(save_directory) + + if self.tokenizer is not None: + self.tokenizer.save_pretrained(save_directory) + + if self.feature_extractor is not None: + self.feature_extractor.save_pretrained(save_directory) + + if self.modelcard is not None: + self.modelcard.save_pretrained(save_directory) + + def transform(self, X): + """ + Scikit / Keras interface to transformers' pipelines. This method will forward to __call__(). + """ + return self(X) + + def predict(self, X): + """ + Scikit / Keras interface to transformers' pipelines. This method will forward to __call__(). + """ + return self(X) + + @contextmanager + def device_placement(self): + """ + Context Manager allowing tensor allocation on the user-specified device in framework agnostic way. + + Returns: + Context manager + + Examples: + + ```python + # Explicitly ask for tensor allocation on CUDA device :0 + pipe = pipeline(..., device=0) + with pipe.device_placement(): + # Every framework specific tensor allocation will be done on the request device + output = pipe(...) + ```""" + if self.framework == "tf": + with tf.device("/CPU:0" if self.device == -1 else f"/device:GPU:{self.device}"): + yield + else: + if self.device.type == "cuda": + torch.cuda.set_device(self.device) + + yield + + def ensure_tensor_on_device(self, **inputs): + """ + Ensure PyTorch tensors are on the specified device. + + Args: + inputs (keyword arguments that should be `torch.Tensor`, the rest is ignored): + The tensors to place on `self.device`. + Recursive on lists **only**. + + Return: + `Dict[str, torch.Tensor]`: The same as `inputs` but on the proper device. + """ + return self._ensure_tensor_on_device(inputs, self.device) + + def _ensure_tensor_on_device(self, inputs, device): + if isinstance(inputs, ModelOutput): + return ModelOutput( + {name: self._ensure_tensor_on_device(tensor, device) for name, tensor in inputs.items()} + ) + elif isinstance(inputs, dict): + return {name: self._ensure_tensor_on_device(tensor, device) for name, tensor in inputs.items()} + elif isinstance(inputs, UserDict): + return UserDict({name: self._ensure_tensor_on_device(tensor, device) for name, tensor in inputs.items()}) + elif isinstance(inputs, list): + return [self._ensure_tensor_on_device(item, device) for item in inputs] + elif isinstance(inputs, tuple): + return tuple([self._ensure_tensor_on_device(item, device) for item in inputs]) + elif isinstance(inputs, torch.Tensor): + if device == torch.device("cpu") and inputs.dtype in {torch.float16, torch.bfloat16}: + inputs = inputs.float() + return inputs.to(device) + else: + return inputs + + def check_model_type(self, supported_models: Union[List[str], dict]): + """ + Check if the model class is in supported by the pipeline. + + Args: + supported_models (`List[str]` or `dict`): + The list of models supported by the pipeline, or a dictionary with model class values. + """ + if not isinstance(supported_models, list): # Create from a model mapping + supported_models_names = [] + for config, model in supported_models.items(): + # Mapping can now contain tuples of models for the same configuration. + if isinstance(model, tuple): + supported_models_names.extend([_model.__name__ for _model in model]) + else: + supported_models_names.append(model.__name__) + supported_models = supported_models_names + if self.model.__class__.__name__ not in supported_models: + logger.error( + f"The model '{self.model.__class__.__name__}' is not supported for {self.task}. Supported models are" + f" {supported_models}." + ) + + @abstractmethod + def _sanitize_parameters(self, **pipeline_parameters): + """ + _sanitize_parameters will be called with any excessive named arguments from either `__init__` or `__call__` + methods. It should return 3 dictionnaries of the resolved parameters used by the various `preprocess`, + `forward` and `postprocess` methods. Do not fill dictionnaries if the caller didn't specify a kwargs. This + let's you keep defaults in function signatures, which is more "natural". + + It is not meant to be called directly, it will be automatically called and the final parameters resolved by + `__init__` and `__call__` + """ + raise NotImplementedError("_sanitize_parameters not implemented") + + @abstractmethod + def preprocess(self, input_: Any, **preprocess_parameters: Dict) -> Dict[str, GenericTensor]: + """ + Preprocess will take the `input_` of a specific pipeline and return a dictionary of everything necessary for + `_forward` to run properly. It should contain at least one tensor, but might have arbitrary other items. + """ + raise NotImplementedError("preprocess not implemented") + + @abstractmethod + def _forward(self, input_tensors: Dict[str, GenericTensor], **forward_parameters: Dict) -> ModelOutput: + """ + _forward will receive the prepared dictionary from `preprocess` and run it on the model. This method might + involve the GPU or the CPU and should be agnostic to it. Isolating this function is the reason for `preprocess` + and `postprocess` to exist, so that the hot path, this method generally can run as fast as possible. + + It is not meant to be called directly, `forward` is preferred. It is basically the same but contains additional + code surrounding `_forward` making sure tensors and models are on the same device, disabling the training part + of the code (leading to faster inference). + """ + raise NotImplementedError("_forward not implemented") + + @abstractmethod + def postprocess(self, model_outputs: ModelOutput, **postprocess_parameters: Dict) -> Any: + """ + Postprocess will receive the raw outputs of the `_forward` method, generally tensors, and reformat them into + something more friendly. Generally it will output a list or a dict or results (containing just strings and + numbers). + """ + raise NotImplementedError("postprocess not implemented") + + def get_inference_context(self): + inference_context = ( + torch.inference_mode + if version.parse(version.parse(torch.__version__).base_version) >= version.parse("1.9.0") + else torch.no_grad + ) + return inference_context + + def forward(self, model_inputs, **forward_params): + with self.device_placement(): + if self.framework == "tf": + model_inputs["training"] = False + model_outputs = self._forward(model_inputs, **forward_params) + elif self.framework == "pt": + inference_context = self.get_inference_context() + with inference_context(): + model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) + model_outputs = self._forward(model_inputs, **forward_params) + model_outputs = self._ensure_tensor_on_device(model_outputs, device=torch.device("cpu")) + else: + raise ValueError(f"Framework {self.framework} is not supported") + return model_outputs + + def get_iterator( + self, inputs, num_workers: int, batch_size: int, preprocess_params, forward_params, postprocess_params + ): + if isinstance(inputs, collections.abc.Sized): + dataset = PipelineDataset(inputs, self.preprocess, preprocess_params) + else: + if num_workers > 1: + logger.warning( + "For iterable dataset using num_workers>1 is likely to result" + " in errors since everything is iterable, setting `num_workers=1`" + " to guarantee correctness." + ) + num_workers = 1 + dataset = PipelineIterator(inputs, self.preprocess, preprocess_params) + if "TOKENIZERS_PARALLELISM" not in os.environ: + logger.info("Disabling tokenizer parallelism, we're using DataLoader multithreading already") + os.environ["TOKENIZERS_PARALLELISM"] = "false" + # TODO hack by collating feature_extractor and image_processor + feature_extractor = self.feature_extractor if self.feature_extractor is not None else self.image_processor + collate_fn = no_collate_fn if batch_size == 1 else pad_collate_fn(self.tokenizer, feature_extractor) + dataloader = DataLoader(dataset, num_workers=num_workers, batch_size=batch_size, collate_fn=collate_fn) + model_iterator = PipelineIterator(dataloader, self.forward, forward_params, loader_batch_size=batch_size) + final_iterator = PipelineIterator(model_iterator, self.postprocess, postprocess_params) + return final_iterator + + def __call__(self, inputs, *args, num_workers=None, batch_size=None, **kwargs): + if args: + logger.warning(f"Ignoring args : {args}") + + if num_workers is None: + if self._num_workers is None: + num_workers = 0 + else: + num_workers = self._num_workers + if batch_size is None: + if self._batch_size is None: + batch_size = 1 + else: + batch_size = self._batch_size + + preprocess_params, forward_params, postprocess_params = self._sanitize_parameters(**kwargs) + + # Fuse __init__ params and __call__ params without modifying the __init__ ones. + preprocess_params = {**self._preprocess_params, **preprocess_params} + forward_params = {**self._forward_params, **forward_params} + postprocess_params = {**self._postprocess_params, **postprocess_params} + + self.call_count += 1 + if self.call_count > 10 and self.framework == "pt" and self.device.type == "cuda": + warnings.warn( + "You seem to be using the pipelines sequentially on GPU. In order to maximize efficiency please use a" + " dataset", + UserWarning, + ) + + is_dataset = Dataset is not None and isinstance(inputs, Dataset) + is_generator = isinstance(inputs, types.GeneratorType) + is_list = isinstance(inputs, list) + + is_iterable = is_dataset or is_generator or is_list + + # TODO make the get_iterator work also for `tf` (and `flax`). + can_use_iterator = self.framework == "pt" and (is_dataset or is_generator or is_list) + + if is_list: + if can_use_iterator: + final_iterator = self.get_iterator( + inputs, num_workers, batch_size, preprocess_params, forward_params, postprocess_params + ) + outputs = list(final_iterator) + return outputs + else: + return self.run_multi(inputs, preprocess_params, forward_params, postprocess_params) + elif can_use_iterator: + return self.get_iterator( + inputs, num_workers, batch_size, preprocess_params, forward_params, postprocess_params + ) + elif is_iterable: + return self.iterate(inputs, preprocess_params, forward_params, postprocess_params) + elif self.framework == "pt" and isinstance(self, ChunkPipeline): + return next( + iter( + self.get_iterator( + [inputs], num_workers, batch_size, preprocess_params, forward_params, postprocess_params + ) + ) + ) + else: + return self.run_single(inputs, preprocess_params, forward_params, postprocess_params) + + def run_multi(self, inputs, preprocess_params, forward_params, postprocess_params): + return [self.run_single(item, preprocess_params, forward_params, postprocess_params) for item in inputs] + + def run_single(self, inputs, preprocess_params, forward_params, postprocess_params): + model_inputs = self.preprocess(inputs, **preprocess_params) + model_outputs = self.forward(model_inputs, **forward_params) + outputs = self.postprocess(model_outputs, **postprocess_params) + return outputs + + def iterate(self, inputs, preprocess_params, forward_params, postprocess_params): + # This function should become `get_iterator` again, this is a temporary + # easy solution. + for input_ in inputs: + yield self.run_single(input_, preprocess_params, forward_params, postprocess_params) + + +class ChunkPipeline(Pipeline): + def run_single(self, inputs, preprocess_params, forward_params, postprocess_params): + all_outputs = [] + for model_inputs in self.preprocess(inputs, **preprocess_params): + model_outputs = self.forward(model_inputs, **forward_params) + all_outputs.append(model_outputs) + outputs = self.postprocess(all_outputs, **postprocess_params) + return outputs + + def get_iterator( + self, inputs, num_workers: int, batch_size: int, preprocess_params, forward_params, postprocess_params + ): + if "TOKENIZERS_PARALLELISM" not in os.environ: + logger.info("Disabling tokenizer parallelism, we're using DataLoader multithreading already") + os.environ["TOKENIZERS_PARALLELISM"] = "false" + if num_workers > 1: + logger.warning( + "For ChunkPipeline using num_workers>0 is likely to result in errors since everything is iterable," + " setting `num_workers=1` to guarantee correctness." + ) + num_workers = 1 + dataset = PipelineChunkIterator(inputs, self.preprocess, preprocess_params) + + # TODO hack by collating feature_extractor and image_processor + feature_extractor = self.feature_extractor if self.feature_extractor is not None else self.image_processor + collate_fn = no_collate_fn if batch_size == 1 else pad_collate_fn(self.tokenizer, feature_extractor) + dataloader = DataLoader(dataset, num_workers=num_workers, batch_size=batch_size, collate_fn=collate_fn) + model_iterator = PipelinePackIterator(dataloader, self.forward, forward_params, loader_batch_size=batch_size) + final_iterator = PipelineIterator(model_iterator, self.postprocess, postprocess_params) + return final_iterator + + +class PipelineRegistry: + def __init__(self, supported_tasks: Dict[str, Any], task_aliases: Dict[str, str]) -> None: + self.supported_tasks = supported_tasks + self.task_aliases = task_aliases + + def get_supported_tasks(self) -> List[str]: + supported_task = list(self.supported_tasks.keys()) + list(self.task_aliases.keys()) + supported_task.sort() + return supported_task + + def check_task(self, task: str) -> Tuple[str, Dict, Any]: + if task in self.task_aliases: + task = self.task_aliases[task] + if task in self.supported_tasks: + targeted_task = self.supported_tasks[task] + return task, targeted_task, None + + if task.startswith("translation"): + tokens = task.split("_") + if len(tokens) == 4 and tokens[0] == "translation" and tokens[2] == "to": + targeted_task = self.supported_tasks["translation"] + task = "translation" + return task, targeted_task, (tokens[1], tokens[3]) + raise KeyError(f"Invalid translation task {task}, use 'translation_XX_to_YY' format") + + raise KeyError( + f"Unknown task {task}, available tasks are {self.get_supported_tasks() + ['translation_XX_to_YY']}" + ) + + def register_pipeline( + self, + task: str, + pipeline_class: type, + pt_model: Optional[Union[type, Tuple[type]]] = None, + tf_model: Optional[Union[type, Tuple[type]]] = None, + default: Optional[Dict] = None, + type: Optional[str] = None, + ) -> None: + if task in self.supported_tasks: + logger.warning(f"{task} is already registered. Overwriting pipeline for task {task}...") + + if pt_model is None: + pt_model = () + elif not isinstance(pt_model, tuple): + pt_model = (pt_model,) + + if tf_model is None: + tf_model = () + elif not isinstance(tf_model, tuple): + tf_model = (tf_model,) + + task_impl = {"impl": pipeline_class, "pt": pt_model, "tf": tf_model} + + if default is not None: + if "model" not in default and ("pt" in default or "tf" in default): + default = {"model": default} + task_impl["default"] = default + + if type is not None: + task_impl["type"] = type + + self.supported_tasks[task] = task_impl + pipeline_class._registered_impl = {task: task_impl} + + def to_dict(self): + return self.supported_tasks diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/conversational.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/conversational.py new file mode 100644 index 0000000000000000000000000000000000000000..93d056c88d44ef560d9e050480eefce48550b6d5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/conversational.py @@ -0,0 +1,310 @@ +import uuid +from typing import Any, Dict, List, Optional, Union + +from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_tf_available(): + import tensorflow as tf + +if is_torch_available(): + import torch + + +logger = logging.get_logger(__name__) + + +class Conversation: + """ + Utility class containing a conversation and its history. This class is meant to be used as an input to the + [`ConversationalPipeline`]. The conversation contains several utility functions to manage the addition of new user + inputs and generated model responses. A conversation needs to contain an unprocessed user input before being passed + to the [`ConversationalPipeline`]. This user input is either created when the class is instantiated, or by calling + `conversational_pipeline.append_response("input")` after a conversation turn. + + Arguments: + text (`str`, *optional*): + The initial user input to start the conversation. If not provided, a user input needs to be provided + manually using the [`~Conversation.add_user_input`] method before the conversation can begin. + conversation_id (`uuid.UUID`, *optional*): + Unique identifier for the conversation. If not provided, a random UUID4 id will be assigned to the + conversation. + past_user_inputs (`List[str]`, *optional*): + Eventual past history of the conversation of the user. You don't need to pass it manually if you use the + pipeline interactively but if you want to recreate history you need to set both `past_user_inputs` and + `generated_responses` with equal length lists of strings + generated_responses (`List[str]`, *optional*): + Eventual past history of the conversation of the model. You don't need to pass it manually if you use the + pipeline interactively but if you want to recreate history you need to set both `past_user_inputs` and + `generated_responses` with equal length lists of strings + + Usage: + + ```python + conversation = Conversation("Going to the movies tonight - any suggestions?") + + # Steps usually performed by the model when generating a response: + # 1. Mark the user input as processed (moved to the history) + conversation.mark_processed() + # 2. Append a mode response + conversation.append_response("The Big lebowski.") + + conversation.add_user_input("Is it good?") + ```""" + + def __init__( + self, text: str = None, conversation_id: uuid.UUID = None, past_user_inputs=None, generated_responses=None + ): + if not conversation_id: + conversation_id = uuid.uuid4() + if past_user_inputs is None: + past_user_inputs = [] + if generated_responses is None: + generated_responses = [] + + self.uuid: uuid.UUID = conversation_id + self.past_user_inputs: List[str] = past_user_inputs + self.generated_responses: List[str] = generated_responses + self.new_user_input: Optional[str] = text + + def __eq__(self, other): + if not isinstance(other, Conversation): + return False + if self.uuid == other.uuid: + return True + return ( + self.new_user_input == other.new_user_input + and self.past_user_inputs == other.past_user_inputs + and self.generated_responses == other.generated_responses + ) + + def add_user_input(self, text: str, overwrite: bool = False): + """ + Add a user input to the conversation for the next round. This populates the internal `new_user_input` field. + + Args: + text (`str`): The user input for the next conversation round. + overwrite (`bool`, *optional*, defaults to `False`): + Whether or not existing and unprocessed user input should be overwritten when this function is called. + """ + if self.new_user_input: + if overwrite: + logger.warning( + f'User input added while unprocessed input was existing: "{self.new_user_input}" was overwritten ' + f'with: "{text}".' + ) + self.new_user_input = text + else: + logger.warning( + f'User input added while unprocessed input was existing: "{self.new_user_input}" new input ' + f'ignored: "{text}". Set `overwrite` to True to overwrite unprocessed user input' + ) + else: + self.new_user_input = text + + def mark_processed(self): + """ + Mark the conversation as processed (moves the content of `new_user_input` to `past_user_inputs`) and empties + the `new_user_input` field. + """ + if self.new_user_input: + self.past_user_inputs.append(self.new_user_input) + self.new_user_input = None + + def append_response(self, response: str): + """ + Append a response to the list of generated responses. + + Args: + response (`str`): The model generated response. + """ + self.generated_responses.append(response) + + def iter_texts(self): + """ + Iterates over all blobs of the conversation. + + Returns: Iterator of (is_user, text_chunk) in chronological order of the conversation. `is_user` is a `bool`, + `text_chunks` is a `str`. + """ + for user_input, generated_response in zip(self.past_user_inputs, self.generated_responses): + yield True, user_input + yield False, generated_response + if self.new_user_input: + yield True, self.new_user_input + + def __repr__(self): + """ + Generates a string representation of the conversation. + + Return: + `str`: + + Example: Conversation id: 7d15686b-dc94-49f2-9c4b-c9eac6a1f114 user >> Going to the movies tonight - any + suggestions? bot >> The Big Lebowski + """ + output = f"Conversation id: {self.uuid} \n" + for is_user, text in self.iter_texts(): + name = "user" if is_user else "bot" + output += f"{name} >> {text} \n" + return output + + +@add_end_docstrings( + PIPELINE_INIT_ARGS, + r""" + min_length_for_response (`int`, *optional*, defaults to 32): + The minimum length (in number of tokens) for a response. + minimum_tokens (`int`, *optional*, defaults to 10): + The minimum length of tokens to leave for a response. + """, +) +class ConversationalPipeline(Pipeline): + """ + Multi-turn conversational pipeline. + + Example: + + ```python + >>> from transformers import pipeline, Conversation + + >>> chatbot = pipeline(model="microsoft/DialoGPT-medium") + >>> conversation = Conversation("Going to the movies tonight - any suggestions?") + >>> conversation = chatbot(conversation) + >>> conversation.generated_responses[-1] + 'The Big Lebowski' + + >>> conversation.add_user_input("Is it an action movie?") + >>> conversation = chatbot(conversation) + >>> conversation.generated_responses[-1] + "It's a comedy." + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This conversational pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"conversational"`. + + The models that this pipeline can use are models that have been fine-tuned on a multi-turn conversational task, + currently: *'microsoft/DialoGPT-small'*, *'microsoft/DialoGPT-medium'*, *'microsoft/DialoGPT-large'*. See the + up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=conversational). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.tokenizer.pad_token_id is None: + self.tokenizer.pad_token = self.tokenizer.eos_token + + def _sanitize_parameters( + self, min_length_for_response=None, minimum_tokens=None, clean_up_tokenization_spaces=None, **generate_kwargs + ): + preprocess_params = {} + forward_params = {} + postprocess_params = {} + + if min_length_for_response is not None: + preprocess_params["min_length_for_response"] = min_length_for_response + if minimum_tokens is not None: + forward_params["minimum_tokens"] = minimum_tokens + + if "max_length" in generate_kwargs: + forward_params["max_length"] = generate_kwargs["max_length"] + # self.max_length = generate_kwargs.get("max_length", self.model.config.max_length) + if clean_up_tokenization_spaces is not None: + postprocess_params["clean_up_tokenization_spaces"] = clean_up_tokenization_spaces + + if generate_kwargs: + forward_params.update(generate_kwargs) + return preprocess_params, forward_params, postprocess_params + + def __call__(self, conversations: Union[Conversation, List[Conversation]], num_workers=0, **kwargs): + r""" + Generate responses for the conversation(s) given as inputs. + + Args: + conversations (a [`Conversation`] or a list of [`Conversation`]): + Conversations to generate responses for. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the potential extra spaces in the text output. + generate_kwargs: + Additional keyword arguments to pass along to the generate method of the model (see the generate method + corresponding to your framework [here](./model#generative-models)). + + Returns: + [`Conversation`] or a list of [`Conversation`]: Conversation(s) with updated generated responses for those + containing a new user input. + """ + # XXX: num_workers==0 is required to be backward compatible + # Otherwise the threads will require a Conversation copy. + # This will definitely hinder performance on GPU, but has to be opted + # in because of this BC change. + outputs = super().__call__(conversations, num_workers=num_workers, **kwargs) + if isinstance(outputs, list) and len(outputs) == 1: + return outputs[0] + return outputs + + def preprocess(self, conversation: Conversation, min_length_for_response=32) -> Dict[str, Any]: + if not isinstance(conversation, Conversation): + raise ValueError("ConversationalPipeline, expects Conversation as inputs") + if conversation.new_user_input is None: + raise ValueError( + f"Conversation with UUID {type(conversation.uuid)} does not contain new user input to process. " + "Add user inputs with the conversation's `add_user_input` method" + ) + if hasattr(self.tokenizer, "_build_conversation_input_ids"): + input_ids = self.tokenizer._build_conversation_input_ids(conversation) + else: + # If the tokenizer cannot handle conversations, we default to only the old version + input_ids = self._legacy_parse_and_tokenize(conversation) + + if self.framework == "pt": + input_ids = torch.LongTensor([input_ids]) + elif self.framework == "tf": + input_ids = tf.constant([input_ids]) + return {"input_ids": input_ids, "conversation": conversation} + + def _forward(self, model_inputs, minimum_tokens=10, **generate_kwargs): + max_length = generate_kwargs.get("max_length", self.model.config.max_length) + + n = model_inputs["input_ids"].shape[1] + if max_length - minimum_tokens < n: + logger.warning(f"Conversation input is to long ({n}), trimming it to ({max_length} - {minimum_tokens})") + trim = max_length - minimum_tokens + model_inputs["input_ids"] = model_inputs["input_ids"][:, -trim:] + if "attention_mask" in model_inputs: + model_inputs["attention_mask"] = model_inputs["attention_mask"][:, -trim:] + conversation = model_inputs.pop("conversation") + generate_kwargs["max_length"] = max_length + output_ids = self.model.generate(**model_inputs, **generate_kwargs) + if self.model.config.is_encoder_decoder: + start_position = 1 + else: + start_position = n + return {"output_ids": output_ids[:, start_position:], "conversation": conversation} + + def postprocess(self, model_outputs, clean_up_tokenization_spaces=True): + output_ids = model_outputs["output_ids"] + answer = self.tokenizer.decode( + output_ids[0], + skip_special_tokens=True, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + ) + conversation = model_outputs["conversation"] + conversation.mark_processed() + conversation.append_response(answer) + return conversation + + def _legacy_parse_and_tokenize(self, conversation: Conversation) -> Dict: + eos_token_id = self.tokenizer.eos_token_id + input_ids = [] + for is_user, text in conversation.iter_texts(): + if eos_token_id is not None: + input_ids.extend(self.tokenizer.encode(text, add_special_tokens=False) + [eos_token_id]) + else: + input_ids.extend(self.tokenizer.encode(text, add_special_tokens=False)) + + if len(input_ids) > self.tokenizer.model_max_length: + input_ids = input_ids[-self.tokenizer.model_max_length :] + return input_ids diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/depth_estimation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/depth_estimation.py new file mode 100644 index 0000000000000000000000000000000000000000..7d0490f635d0952319fe85b49bc3aefc241d8b7d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/depth_estimation.py @@ -0,0 +1,108 @@ +from typing import List, Union + +import numpy as np + +from ..utils import add_end_docstrings, 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_torch_available(): + import torch + + from ..models.auto.modeling_auto import MODEL_FOR_DEPTH_ESTIMATION_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class DepthEstimationPipeline(Pipeline): + """ + Depth estimation pipeline using any `AutoModelForDepthEstimation`. This pipeline predicts the depth of an image. + + Example: + + ```python + >>> from transformers import pipeline + + >>> depth_estimator = pipeline(task="depth-estimation", model="Intel/dpt-large") + >>> output = depth_estimator("http://images.cocodataset.org/val2017/000000039769.jpg") + >>> # This is a tensor with the values being the depth expressed in meters for each pixel + >>> output["predicted_depth"].shape + torch.Size([1, 384, 384]) + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + + This depth estimation pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"depth-estimation"`. + + See the list of available models on [huggingface.co/models](https://huggingface.co/models?filter=depth-estimation). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + requires_backends(self, "vision") + self.check_model_type(MODEL_FOR_DEPTH_ESTIMATION_MAPPING) + + def __call__(self, images: Union[str, List[str], "Image.Image", List["Image.Image"]], **kwargs): + """ + Assign labels to the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing a http link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images, which must then be passed as a string. + Images in a batch must all be in the same format: all as http links, all as local paths, or all as PIL + images. + top_k (`int`, *optional*, defaults to 5): + The number of top labels that will be returned by the pipeline. If the provided number is higher than + the number of labels available in the model configuration, it will default to the number of labels. + + Return: + A dictionary or a list of dictionaries containing result. If the input is a single image, will return a + dictionary, if the input is a list of several images, will return a list of dictionaries corresponding to + the images. + + The dictionaries contain the following keys: + + - **label** (`str`) -- The label identified by the model. + - **score** (`int`) -- The score attributed by the model for that label. + """ + return super().__call__(images, **kwargs) + + def _sanitize_parameters(self, **kwargs): + return {}, {}, {} + + def preprocess(self, image): + image = load_image(image) + self.image_size = image.size + model_inputs = self.image_processor(images=image, return_tensors=self.framework) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs): + predicted_depth = model_outputs.predicted_depth + prediction = torch.nn.functional.interpolate( + predicted_depth.unsqueeze(1), size=self.image_size[::-1], mode="bicubic", align_corners=False + ) + output = prediction.squeeze().cpu().numpy() + formatted = (output * 255 / np.max(output)).astype("uint8") + depth = Image.fromarray(formatted) + output_dict = {} + output_dict["predicted_depth"] = predicted_depth + output_dict["depth"] = depth + return output_dict diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/document_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/document_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..936d728b5983938b9aa7c3dc02662c9a5dee0502 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/document_question_answering.py @@ -0,0 +1,495 @@ +# Copyright 2022 The Impira Team and the HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +from typing import List, Optional, Tuple, Union + +import numpy as np + +from ..utils import ( + ExplicitEnum, + add_end_docstrings, + is_pytesseract_available, + is_torch_available, + is_vision_available, + logging, +) +from .base import PIPELINE_INIT_ARGS, ChunkPipeline +from .question_answering import select_starts_ends + + +if is_vision_available(): + from PIL import Image + + from ..image_utils import load_image + +if is_torch_available(): + import torch + + from ..models.auto.modeling_auto import MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING + +TESSERACT_LOADED = False +if is_pytesseract_available(): + TESSERACT_LOADED = True + import pytesseract + +logger = logging.get_logger(__name__) + + +# normalize_bbox() and apply_tesseract() are derived from apply_tesseract in models/layoutlmv3/feature_extraction_layoutlmv3.py. +# However, because the pipeline may evolve from what layoutlmv3 currently does, it's copied (vs. imported) to avoid creating an +# unnecessary dependency. +def normalize_box(box, width, height): + return [ + int(1000 * (box[0] / width)), + int(1000 * (box[1] / height)), + int(1000 * (box[2] / width)), + int(1000 * (box[3] / height)), + ] + + +def apply_tesseract(image: "Image.Image", lang: Optional[str], tesseract_config: Optional[str]): + """Applies Tesseract OCR on a document image, and returns recognized words + normalized bounding boxes.""" + # apply OCR + data = pytesseract.image_to_data(image, lang=lang, output_type="dict", config=tesseract_config) + words, left, top, width, height = data["text"], data["left"], data["top"], data["width"], data["height"] + + # filter empty words and corresponding coordinates + irrelevant_indices = [idx for idx, word in enumerate(words) if not word.strip()] + words = [word for idx, word in enumerate(words) if idx not in irrelevant_indices] + left = [coord for idx, coord in enumerate(left) if idx not in irrelevant_indices] + top = [coord for idx, coord in enumerate(top) if idx not in irrelevant_indices] + width = [coord for idx, coord in enumerate(width) if idx not in irrelevant_indices] + height = [coord for idx, coord in enumerate(height) if idx not in irrelevant_indices] + + # turn coordinates into (left, top, left+width, top+height) format + actual_boxes = [] + for x, y, w, h in zip(left, top, width, height): + actual_box = [x, y, x + w, y + h] + actual_boxes.append(actual_box) + + image_width, image_height = image.size + + # finally, normalize the bounding boxes + normalized_boxes = [] + for box in actual_boxes: + normalized_boxes.append(normalize_box(box, image_width, image_height)) + + if len(words) != len(normalized_boxes): + raise ValueError("Not as many words as there are bounding boxes") + + return words, normalized_boxes + + +class ModelType(ExplicitEnum): + LayoutLM = "layoutlm" + LayoutLMv2andv3 = "layoutlmv2andv3" + VisionEncoderDecoder = "vision_encoder_decoder" + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class DocumentQuestionAnsweringPipeline(ChunkPipeline): + # TODO: Update task_summary docs to include an example with document QA and then update the first sentence + """ + Document Question Answering pipeline using any `AutoModelForDocumentQuestionAnswering`. The inputs/outputs are + similar to the (extractive) question answering pipeline; however, the pipeline takes an image (and optional OCR'd + words/boxes) as input instead of text context. + + Example: + + ```python + >>> from transformers import pipeline + + >>> document_qa = pipeline(model="impira/layoutlm-document-qa") + >>> document_qa( + ... image="https://huggingface.co/spaces/impira/docquery/resolve/2359223c1837a7587402bda0f2643382a6eefeab/invoice.png", + ... question="What is the invoice number?", + ... ) + [{'score': 0.425, 'answer': 'us-001', 'start': 16, 'end': 16}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This document question answering pipeline can currently be loaded from [`pipeline`] using the following task + identifier: `"document-question-answering"`. + + The models that this pipeline can use are models that have been fine-tuned on a document question answering task. + See the up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=document-question-answering). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.tokenizer is not None and not self.tokenizer.__class__.__name__.endswith("Fast"): + raise ValueError( + "`DocumentQuestionAnsweringPipeline` requires a fast tokenizer, but a slow tokenizer " + f"(`{self.tokenizer.__class__.__name__}`) is provided." + ) + + if self.model.config.__class__.__name__ == "VisionEncoderDecoderConfig": + self.model_type = ModelType.VisionEncoderDecoder + if self.model.config.encoder.model_type != "donut-swin": + raise ValueError("Currently, the only supported VisionEncoderDecoder model is Donut") + else: + self.check_model_type(MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING) + if self.model.config.__class__.__name__ == "LayoutLMConfig": + self.model_type = ModelType.LayoutLM + else: + self.model_type = ModelType.LayoutLMv2andv3 + + def _sanitize_parameters( + self, + padding=None, + doc_stride=None, + max_question_len=None, + lang: Optional[str] = None, + tesseract_config: Optional[str] = None, + max_answer_len=None, + max_seq_len=None, + top_k=None, + handle_impossible_answer=None, + **kwargs, + ): + preprocess_params, postprocess_params = {}, {} + if padding is not None: + preprocess_params["padding"] = padding + if doc_stride is not None: + preprocess_params["doc_stride"] = doc_stride + if max_question_len is not None: + preprocess_params["max_question_len"] = max_question_len + if max_seq_len is not None: + preprocess_params["max_seq_len"] = max_seq_len + if lang is not None: + preprocess_params["lang"] = lang + if tesseract_config is not None: + preprocess_params["tesseract_config"] = tesseract_config + + if top_k is not None: + if top_k < 1: + raise ValueError(f"top_k parameter should be >= 1 (got {top_k})") + postprocess_params["top_k"] = top_k + if max_answer_len is not None: + if max_answer_len < 1: + raise ValueError(f"max_answer_len parameter should be >= 1 (got {max_answer_len}") + postprocess_params["max_answer_len"] = max_answer_len + if handle_impossible_answer is not None: + postprocess_params["handle_impossible_answer"] = handle_impossible_answer + + return preprocess_params, {}, postprocess_params + + def __call__( + self, + image: Union["Image.Image", str], + question: Optional[str] = None, + word_boxes: Tuple[str, List[float]] = None, + **kwargs, + ): + """ + Answer the question(s) given as inputs by using the document(s). A document is defined as an image and an + optional list of (word, box) tuples which represent the text in the document. If the `word_boxes` are not + provided, it will use the Tesseract OCR engine (if available) to extract the words and boxes automatically for + LayoutLM-like models which require them as input. For Donut, no OCR is run. + + You can invoke the pipeline several ways: + + - `pipeline(image=image, question=question)` + - `pipeline(image=image, question=question, word_boxes=word_boxes)` + - `pipeline([{"image": image, "question": question}])` + - `pipeline([{"image": image, "question": question, "word_boxes": word_boxes}])` + + Args: + image (`str` or `PIL.Image`): + The pipeline handles three types of images: + + - A string containing a http link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images. If given a single image, it can be + broadcasted to multiple questions. + question (`str`): + A question to ask of the document. + word_boxes (`List[str, Tuple[float, float, float, float]]`, *optional*): + A list of words and bounding boxes (normalized 0->1000). If you provide this optional input, then the + pipeline will use these words and boxes instead of running OCR on the image to derive them for models + that need them (e.g. LayoutLM). This allows you to reuse OCR'd results across many invocations of the + pipeline without having to re-run it each time. + top_k (`int`, *optional*, defaults to 1): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + top_k answers if there are not enough options available within the context. + doc_stride (`int`, *optional*, defaults to 128): + If the words in the document are too long to fit with the question for the model, it will be split in + several chunks with some overlap. This argument controls the size of that overlap. + max_answer_len (`int`, *optional*, defaults to 15): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_seq_len (`int`, *optional*, defaults to 384): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using `doc_stride` as overlap) if needed. + max_question_len (`int`, *optional*, defaults to 64): + The maximum length of the question after tokenization. It will be truncated if needed. + handle_impossible_answer (`bool`, *optional*, defaults to `False`): + Whether or not we accept impossible as an answer. + lang (`str`, *optional*): + Language to use while running OCR. Defaults to english. + tesseract_config (`str`, *optional*): + Additional flags to pass to tesseract while running OCR. + + Return: + A `dict` or a list of `dict`: Each result comes as a dictionary with the following keys: + + - **score** (`float`) -- The probability associated to the answer. + - **start** (`int`) -- The start word index of the answer (in the OCR'd version of the input or provided + `word_boxes`). + - **end** (`int`) -- The end word index of the answer (in the OCR'd version of the input or provided + `word_boxes`). + - **answer** (`str`) -- The answer to the question. + - **words** (`list[int]`) -- The index of each word/box pair that is in the answer + """ + if isinstance(question, str): + inputs = {"question": question, "image": image} + if word_boxes is not None: + inputs["word_boxes"] = word_boxes + else: + inputs = image + return super().__call__(inputs, **kwargs) + + def preprocess( + self, + input, + padding="do_not_pad", + doc_stride=None, + max_seq_len=None, + word_boxes: Tuple[str, List[float]] = None, + lang=None, + tesseract_config="", + ): + # NOTE: This code mirrors the code in question answering and will be implemented in a follow up PR + # to support documents with enough tokens that overflow the model's window + if max_seq_len is None: + max_seq_len = self.tokenizer.model_max_length + + if doc_stride is None: + doc_stride = min(max_seq_len // 2, 256) + + image = None + image_features = {} + if input.get("image", None) is not None: + image = load_image(input["image"]) + if self.image_processor is not None: + image_features.update(self.image_processor(images=image, return_tensors=self.framework)) + elif self.feature_extractor is not None: + image_features.update(self.feature_extractor(images=image, return_tensors=self.framework)) + elif self.model_type == ModelType.VisionEncoderDecoder: + raise ValueError("If you are using a VisionEncoderDecoderModel, you must provide a feature extractor") + + words, boxes = None, None + if not self.model_type == ModelType.VisionEncoderDecoder: + if "word_boxes" in input: + words = [x[0] for x in input["word_boxes"]] + boxes = [x[1] for x in input["word_boxes"]] + elif "words" in image_features and "boxes" in image_features: + words = image_features.pop("words")[0] + boxes = image_features.pop("boxes")[0] + elif image is not None: + if not TESSERACT_LOADED: + raise ValueError( + "If you provide an image without word_boxes, then the pipeline will run OCR using Tesseract," + " but pytesseract is not available" + ) + if TESSERACT_LOADED: + words, boxes = apply_tesseract(image, lang=lang, tesseract_config=tesseract_config) + else: + raise ValueError( + "You must provide an image or word_boxes. If you provide an image, the pipeline will automatically" + " run OCR to derive words and boxes" + ) + + if self.tokenizer.padding_side != "right": + raise ValueError( + "Document question answering only supports tokenizers whose padding side is 'right', not" + f" {self.tokenizer.padding_side}" + ) + + if self.model_type == ModelType.VisionEncoderDecoder: + task_prompt = f'{input["question"]}' + # Adapted from https://huggingface.co/spaces/nielsr/donut-docvqa/blob/main/app.py + encoding = { + "inputs": image_features["pixel_values"], + "decoder_input_ids": self.tokenizer( + task_prompt, add_special_tokens=False, return_tensors=self.framework + ).input_ids, + "return_dict_in_generate": True, + } + yield { + **encoding, + "p_mask": None, + "word_ids": None, + "words": None, + "output_attentions": True, + "is_last": True, + } + else: + tokenizer_kwargs = {} + if self.model_type == ModelType.LayoutLM: + tokenizer_kwargs["text"] = input["question"].split() + tokenizer_kwargs["text_pair"] = words + tokenizer_kwargs["is_split_into_words"] = True + else: + tokenizer_kwargs["text"] = [input["question"]] + tokenizer_kwargs["text_pair"] = [words] + tokenizer_kwargs["boxes"] = [boxes] + + encoding = self.tokenizer( + padding=padding, + max_length=max_seq_len, + stride=doc_stride, + return_token_type_ids=True, + truncation="only_second", + return_overflowing_tokens=True, + **tokenizer_kwargs, + ) + # TODO: check why slower `LayoutLMTokenizer` and `LayoutLMv2Tokenizer` don't have this key in outputs + # FIXME: ydshieh and/or Narsil + encoding.pop("overflow_to_sample_mapping", None) # We do not use this + + num_spans = len(encoding["input_ids"]) + + # p_mask: mask with 1 for token than cannot be in the answer (0 for token which can be in an answer) + # We put 0 on the tokens from the context and 1 everywhere else (question and special tokens) + # This logic mirrors the logic in the question_answering pipeline + p_mask = [[tok != 1 for tok in encoding.sequence_ids(span_id)] for span_id in range(num_spans)] + for span_idx in range(num_spans): + if self.framework == "pt": + span_encoding = {k: torch.tensor(v[span_idx : span_idx + 1]) for (k, v) in encoding.items()} + if "pixel_values" in image_features: + span_encoding["image"] = image_features["pixel_values"] + else: + raise ValueError("Unsupported: Tensorflow preprocessing for DocumentQuestionAnsweringPipeline") + + input_ids_span_idx = encoding["input_ids"][span_idx] + # keep the cls_token unmasked (some models use it to indicate unanswerable questions) + if self.tokenizer.cls_token_id is not None: + cls_indices = np.nonzero(np.array(input_ids_span_idx) == self.tokenizer.cls_token_id)[0] + for cls_index in cls_indices: + p_mask[span_idx][cls_index] = 0 + + # For each span, place a bounding box [0,0,0,0] for question and CLS tokens, [1000,1000,1000,1000] + # for SEP tokens, and the word's bounding box for words in the original document. + if "boxes" not in tokenizer_kwargs: + bbox = [] + for input_id, sequence_id, word_id in zip( + encoding.input_ids[span_idx], + encoding.sequence_ids(span_idx), + encoding.word_ids(span_idx), + ): + if sequence_id == 1: + bbox.append(boxes[word_id]) + elif input_id == self.tokenizer.sep_token_id: + bbox.append([1000] * 4) + else: + bbox.append([0] * 4) + + if self.framework == "pt": + span_encoding["bbox"] = torch.tensor(bbox).unsqueeze(0) + elif self.framework == "tf": + raise ValueError("Unsupported: Tensorflow preprocessing for DocumentQuestionAnsweringPipeline") + yield { + **span_encoding, + "p_mask": p_mask[span_idx], + "word_ids": encoding.word_ids(span_idx), + "words": words, + "is_last": span_idx == num_spans - 1, + } + + def _forward(self, model_inputs): + p_mask = model_inputs.pop("p_mask", None) + word_ids = model_inputs.pop("word_ids", None) + words = model_inputs.pop("words", None) + is_last = model_inputs.pop("is_last", False) + + if self.model_type == ModelType.VisionEncoderDecoder: + model_outputs = self.model.generate(**model_inputs) + else: + model_outputs = self.model(**model_inputs) + + model_outputs = dict(model_outputs.items()) + model_outputs["p_mask"] = p_mask + model_outputs["word_ids"] = word_ids + model_outputs["words"] = words + model_outputs["attention_mask"] = model_inputs.get("attention_mask", None) + model_outputs["is_last"] = is_last + return model_outputs + + def postprocess(self, model_outputs, top_k=1, **kwargs): + if self.model_type == ModelType.VisionEncoderDecoder: + answers = [self.postprocess_encoder_decoder_single(o) for o in model_outputs] + else: + answers = self.postprocess_extractive_qa(model_outputs, top_k=top_k, **kwargs) + + answers = sorted(answers, key=lambda x: x.get("score", 0), reverse=True)[:top_k] + return answers + + def postprocess_encoder_decoder_single(self, model_outputs, **kwargs): + sequence = self.tokenizer.batch_decode(model_outputs["sequences"])[0] + + # TODO: A lot of this logic is specific to Donut and should probably be handled in the tokenizer + # (see https://github.com/huggingface/transformers/pull/18414/files#r961747408 for more context). + sequence = sequence.replace(self.tokenizer.eos_token, "").replace(self.tokenizer.pad_token, "") + sequence = re.sub(r"<.*?>", "", sequence, count=1).strip() # remove first task start token + ret = { + "answer": None, + } + + answer = re.search(r"(.*)", sequence) + if answer is not None: + ret["answer"] = answer.group(1).strip() + return ret + + def postprocess_extractive_qa( + self, model_outputs, top_k=1, handle_impossible_answer=False, max_answer_len=15, **kwargs + ): + min_null_score = 1000000 # large and positive + answers = [] + for output in model_outputs: + words = output["words"] + + starts, ends, scores, min_null_score = select_starts_ends( + start=output["start_logits"], + end=output["end_logits"], + p_mask=output["p_mask"], + attention_mask=output["attention_mask"].numpy() + if output.get("attention_mask", None) is not None + else None, + min_null_score=min_null_score, + top_k=top_k, + handle_impossible_answer=handle_impossible_answer, + max_answer_len=max_answer_len, + ) + word_ids = output["word_ids"] + for start, end, score in zip(starts, ends, scores): + word_start, word_end = word_ids[start], word_ids[end] + if word_start is not None and word_end is not None: + answers.append( + { + "score": float(score), + "answer": " ".join(words[word_start : word_end + 1]), + "start": word_start, + "end": word_end, + } + ) + + if handle_impossible_answer: + answers.append({"score": min_null_score, "answer": "", "start": 0, "end": 0}) + + return answers diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/feature_extraction.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/feature_extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..b8b5eafeb760676f4992b731486b3d2cccaf8dc9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/feature_extraction.py @@ -0,0 +1,107 @@ +from typing import Dict + +from .base import GenericTensor, Pipeline + + +# Can't use @add_end_docstrings(PIPELINE_INIT_ARGS) here because this one does not accept `binary_output` +class FeatureExtractionPipeline(Pipeline): + """ + Feature extraction pipeline using no model head. This pipeline extracts the hidden states from the base + transformer, which can be used as features in downstream tasks. + + Example: + + ```python + >>> from transformers import pipeline + + >>> extractor = pipeline(model="bert-base-uncased", task="feature-extraction") + >>> result = extractor("This is a simple test.", return_tensors=True) + >>> result.shape # This is a tensor of shape [1, sequence_lenth, hidden_dimension] representing the input string. + torch.Size([1, 8, 768]) + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This feature extraction pipeline can currently be loaded from [`pipeline`] using the task identifier: + `"feature-extraction"`. + + All models may be used for this pipeline. See a list of all models, including community-contributed models on + [huggingface.co/models](https://huggingface.co/models). + + Arguments: + model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from + [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow. + tokenizer ([`PreTrainedTokenizer`]): + The tokenizer that will be used by the pipeline to encode data for the model. This object inherits from + [`PreTrainedTokenizer`]. + modelcard (`str` or [`ModelCard`], *optional*): + Model card attributed to the model for this pipeline. + framework (`str`, *optional*): + The framework to use, either `"pt"` for PyTorch or `"tf"` for TensorFlow. The specified framework must be + installed. + + If no framework is specified, will default to the one currently installed. If no framework is specified and + both frameworks are installed, will default to the framework of the `model`, or to PyTorch if no model is + provided. + return_tensors (`bool`, *optional*): + If `True`, returns a tensor according to the specified framework, otherwise returns a list. + task (`str`, defaults to `""`): + A task-identifier for the pipeline. + args_parser ([`~pipelines.ArgumentHandler`], *optional*): + Reference to the object in charge of parsing supplied pipeline parameters. + device (`int`, *optional*, defaults to -1): + Device ordinal for CPU/GPU supports. Setting this to -1 will leverage CPU, a positive will run the model on + the associated CUDA device id. + tokenize_kwargs (`dict`, *optional*): + Additional dictionary of keyword arguments passed along to the tokenizer. + """ + + def _sanitize_parameters(self, truncation=None, tokenize_kwargs=None, return_tensors=None, **kwargs): + if tokenize_kwargs is None: + tokenize_kwargs = {} + + if truncation is not None: + if "truncation" in tokenize_kwargs: + raise ValueError( + "truncation parameter defined twice (given as keyword argument as well as in tokenize_kwargs)" + ) + tokenize_kwargs["truncation"] = truncation + + preprocess_params = tokenize_kwargs + + postprocess_params = {} + if return_tensors is not None: + postprocess_params["return_tensors"] = return_tensors + + return preprocess_params, {}, postprocess_params + + def preprocess(self, inputs, **tokenize_kwargs) -> Dict[str, GenericTensor]: + return_tensors = self.framework + model_inputs = self.tokenizer(inputs, return_tensors=return_tensors, **tokenize_kwargs) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs, return_tensors=False): + # [0] is the first available tensor, logits or last_hidden_state. + if return_tensors: + return model_outputs[0] + if self.framework == "pt": + return model_outputs[0].tolist() + elif self.framework == "tf": + return model_outputs[0].numpy().tolist() + + def __call__(self, *args, **kwargs): + """ + Extract the features of the input(s). + + Args: + args (`str` or `List[str]`): One or several texts (or one list of texts) to get the features of. + + Return: + A nested list of `float`: The features computed by the model. + """ + return super().__call__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/fill_mask.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/fill_mask.py new file mode 100644 index 0000000000000000000000000000000000000000..74992485d36912e33a3dc2b9de13521fa7db4a97 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/fill_mask.py @@ -0,0 +1,242 @@ +from typing import Dict + +import numpy as np + +from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging +from .base import PIPELINE_INIT_ARGS, GenericTensor, Pipeline, PipelineException + + +if is_tf_available(): + import tensorflow as tf + + from ..tf_utils import stable_softmax + + +if is_torch_available(): + import torch + + +logger = logging.get_logger(__name__) + + +@add_end_docstrings( + PIPELINE_INIT_ARGS, + r""" + top_k (`int`, defaults to 5): + The number of predictions to return. + targets (`str` or `List[str]`, *optional*): + When passed, the model will limit the scores to the passed targets instead of looking up in the whole + vocab. If the provided targets are not in the model vocab, they will be tokenized and the first resulting + token will be used (with a warning, and that might be slower). + + """, +) +class FillMaskPipeline(Pipeline): + """ + Masked language modeling prediction pipeline using any `ModelWithLMHead`. See the [masked language modeling + examples](../task_summary#masked-language-modeling) for more information. + + Example: + + ```python + >>> from transformers import pipeline + + >>> fill_masker = pipeline(model="bert-base-uncased") + >>> fill_masker("This is a simple [MASK].") + [{'score': 0.042, 'token': 3291, 'token_str': 'problem', 'sequence': 'this is a simple problem.'}, {'score': 0.031, 'token': 3160, 'token_str': 'question', 'sequence': 'this is a simple question.'}, {'score': 0.03, 'token': 8522, 'token_str': 'equation', 'sequence': 'this is a simple equation.'}, {'score': 0.027, 'token': 2028, 'token_str': 'one', 'sequence': 'this is a simple one.'}, {'score': 0.024, 'token': 3627, 'token_str': 'rule', 'sequence': 'this is a simple rule.'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This mask filling pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"fill-mask"`. + + The models that this pipeline can use are models that have been trained with a masked language modeling objective, + which includes the bi-directional models in the library. See the up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=fill-mask). + + + + This pipeline only works for inputs with exactly one token masked. Experimental: We added support for multiple + masks. The returned values are raw model output, and correspond to disjoint probabilities where one might expect + joint probabilities (See [discussion](https://github.com/huggingface/transformers/pull/10222)). + + """ + + def get_masked_index(self, input_ids: GenericTensor) -> np.ndarray: + if self.framework == "tf": + masked_index = tf.where(input_ids == self.tokenizer.mask_token_id).numpy() + elif self.framework == "pt": + masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False) + else: + raise ValueError("Unsupported framework") + return masked_index + + def _ensure_exactly_one_mask_token(self, input_ids: GenericTensor) -> np.ndarray: + masked_index = self.get_masked_index(input_ids) + numel = np.prod(masked_index.shape) + if numel < 1: + raise PipelineException( + "fill-mask", + self.model.base_model_prefix, + f"No mask_token ({self.tokenizer.mask_token}) found on the input", + ) + + def ensure_exactly_one_mask_token(self, model_inputs: GenericTensor): + if isinstance(model_inputs, list): + for model_input in model_inputs: + self._ensure_exactly_one_mask_token(model_input["input_ids"][0]) + else: + for input_ids in model_inputs["input_ids"]: + self._ensure_exactly_one_mask_token(input_ids) + + def preprocess(self, inputs, return_tensors=None, **preprocess_parameters) -> Dict[str, GenericTensor]: + if return_tensors is None: + return_tensors = self.framework + model_inputs = self.tokenizer(inputs, return_tensors=return_tensors) + self.ensure_exactly_one_mask_token(model_inputs) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + model_outputs["input_ids"] = model_inputs["input_ids"] + return model_outputs + + def postprocess(self, model_outputs, top_k=5, target_ids=None): + # Cap top_k if there are targets + if target_ids is not None and target_ids.shape[0] < top_k: + top_k = target_ids.shape[0] + input_ids = model_outputs["input_ids"][0] + outputs = model_outputs["logits"] + + if self.framework == "tf": + masked_index = tf.where(input_ids == self.tokenizer.mask_token_id).numpy()[:, 0] + + outputs = outputs.numpy() + + logits = outputs[0, masked_index, :] + probs = stable_softmax(logits, axis=-1) + if target_ids is not None: + probs = tf.gather_nd(tf.squeeze(probs, 0), target_ids.reshape(-1, 1)) + probs = tf.expand_dims(probs, 0) + + topk = tf.math.top_k(probs, k=top_k) + values, predictions = topk.values.numpy(), topk.indices.numpy() + else: + masked_index = torch.nonzero(input_ids == self.tokenizer.mask_token_id, as_tuple=False).squeeze(-1) + # Fill mask pipeline supports only one ${mask_token} per sample + + logits = outputs[0, masked_index, :] + probs = logits.softmax(dim=-1) + if target_ids is not None: + probs = probs[..., target_ids] + + values, predictions = probs.topk(top_k) + + result = [] + single_mask = values.shape[0] == 1 + for i, (_values, _predictions) in enumerate(zip(values.tolist(), predictions.tolist())): + row = [] + for v, p in zip(_values, _predictions): + # Copy is important since we're going to modify this array in place + tokens = input_ids.numpy().copy() + if target_ids is not None: + p = target_ids[p].tolist() + + tokens[masked_index[i]] = p + # Filter padding out: + tokens = tokens[np.where(tokens != self.tokenizer.pad_token_id)] + # Originally we skip special tokens to give readable output. + # For multi masks though, the other [MASK] would be removed otherwise + # making the output look odd, so we add them back + sequence = self.tokenizer.decode(tokens, skip_special_tokens=single_mask) + proposition = {"score": v, "token": p, "token_str": self.tokenizer.decode([p]), "sequence": sequence} + row.append(proposition) + result.append(row) + if single_mask: + return result[0] + return result + + def get_target_ids(self, targets, top_k=None): + if isinstance(targets, str): + targets = [targets] + try: + vocab = self.tokenizer.get_vocab() + except Exception: + vocab = {} + target_ids = [] + for target in targets: + id_ = vocab.get(target, None) + if id_ is None: + input_ids = self.tokenizer( + target, + add_special_tokens=False, + return_attention_mask=False, + return_token_type_ids=False, + max_length=1, + truncation=True, + )["input_ids"] + if len(input_ids) == 0: + logger.warning( + f"The specified target token `{target}` does not exist in the model vocabulary. " + "We cannot replace it with anything meaningful, ignoring it" + ) + continue + id_ = input_ids[0] + # XXX: If users encounter this pass + # it becomes pretty slow, so let's make sure + # The warning enables them to fix the input to + # get faster performance. + logger.warning( + f"The specified target token `{target}` does not exist in the model vocabulary. " + f"Replacing with `{self.tokenizer.convert_ids_to_tokens(id_)}`." + ) + target_ids.append(id_) + target_ids = list(set(target_ids)) + if len(target_ids) == 0: + raise ValueError("At least one target must be provided when passed.") + target_ids = np.array(target_ids) + return target_ids + + def _sanitize_parameters(self, top_k=None, targets=None): + postprocess_params = {} + + if targets is not None: + target_ids = self.get_target_ids(targets, top_k) + postprocess_params["target_ids"] = target_ids + + if top_k is not None: + postprocess_params["top_k"] = top_k + + if self.tokenizer.mask_token_id is None: + raise PipelineException( + "fill-mask", self.model.base_model_prefix, "The tokenizer does not define a `mask_token`." + ) + return {}, {}, postprocess_params + + def __call__(self, inputs, *args, **kwargs): + """ + Fill the masked token in the text(s) given as inputs. + + Args: + args (`str` or `List[str]`): + One or several texts (or one list of prompts) with masked tokens. + targets (`str` or `List[str]`, *optional*): + When passed, the model will limit the scores to the passed targets instead of looking up in the whole + vocab. If the provided targets are not in the model vocab, they will be tokenized and the first + resulting token will be used (with a warning, and that might be slower). + top_k (`int`, *optional*): + When passed, overrides the number of predictions to return. + + Return: + A list or a list of list of `dict`: Each result comes as list of dictionaries with the following keys: + + - **sequence** (`str`) -- The corresponding input with the mask token prediction. + - **score** (`float`) -- The corresponding probability. + - **token** (`int`) -- The predicted token id (to replace the masked one). + - **token_str** (`str`) -- The predicted token (to replace the masked one). + """ + outputs = super().__call__(inputs, **kwargs) + if isinstance(inputs, list) and len(inputs) == 1: + return outputs[0] + return outputs diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..93dc4cff2144af32a7284452ae06024ed5d5b913 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_classification.py @@ -0,0 +1,127 @@ +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(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + from ..tf_utils import stable_softmax + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ImageClassificationPipeline(Pipeline): + """ + Image classification pipeline using any `AutoModelForImageClassification`. This pipeline predicts the class of an + image. + + Example: + + ```python + >>> from transformers import pipeline + + >>> classifier = pipeline(model="microsoft/beit-base-patch16-224-pt22k-ft22k") + >>> classifier("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png") + [{'score': 0.442, 'label': 'macaw'}, {'score': 0.088, 'label': 'popinjay'}, {'score': 0.075, 'label': 'parrot'}, {'score': 0.073, 'label': 'parodist, lampooner'}, {'score': 0.046, 'label': 'poll, poll_parrot'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This image classification pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"image-classification"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=image-classification). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + requires_backends(self, "vision") + self.check_model_type( + TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + if self.framework == "tf" + else MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING + ) + + def _sanitize_parameters(self, top_k=None): + postprocess_params = {} + if top_k is not None: + postprocess_params["top_k"] = top_k + return {}, {}, postprocess_params + + def __call__(self, images: Union[str, List[str], "Image.Image", List["Image.Image"]], **kwargs): + """ + Assign labels to the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing a http link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images, which must then be passed as a string. + Images in a batch must all be in the same format: all as http links, all as local paths, or all as PIL + images. + top_k (`int`, *optional*, defaults to 5): + The number of top labels that will be returned by the pipeline. If the provided number is higher than + the number of labels available in the model configuration, it will default to the number of labels. + + Return: + A dictionary or a list of dictionaries containing result. If the input is a single image, will return a + dictionary, if the input is a list of several images, will return a list of dictionaries corresponding to + the images. + + The dictionaries contain the following keys: + + - **label** (`str`) -- The label identified by the model. + - **score** (`int`) -- The score attributed by the model for that label. + """ + return super().__call__(images, **kwargs) + + def preprocess(self, image): + image = load_image(image) + model_inputs = self.image_processor(images=image, return_tensors=self.framework) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs, top_k=5): + if top_k > self.model.config.num_labels: + top_k = self.model.config.num_labels + + if self.framework == "pt": + probs = model_outputs.logits.softmax(-1)[0] + scores, ids = probs.topk(top_k) + elif self.framework == "tf": + probs = stable_softmax(model_outputs.logits, axis=-1)[0] + topk = tf.math.top_k(probs, k=top_k) + scores, ids = topk.values.numpy(), topk.indices.numpy() + else: + raise ValueError(f"Unsupported framework: {self.framework}") + + scores = scores.tolist() + ids = ids.tolist() + return [{"score": score, "label": self.model.config.id2label[_id]} for score, _id in zip(scores, ids)] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_segmentation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_segmentation.py new file mode 100644 index 0000000000000000000000000000000000000000..00f52af28725669464c3ed8f746dac5b9ed49e05 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_segmentation.py @@ -0,0 +1,209 @@ +from typing import Any, Dict, List, Union + +import numpy as np + +from ..utils import add_end_docstrings, 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_torch_available(): + from ..models.auto.modeling_auto import ( + MODEL_FOR_IMAGE_SEGMENTATION_MAPPING, + MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING, + MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING, + MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING, + ) + + +logger = logging.get_logger(__name__) + + +Prediction = Dict[str, Any] +Predictions = List[Prediction] + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ImageSegmentationPipeline(Pipeline): + """ + Image segmentation pipeline using any `AutoModelForXXXSegmentation`. This pipeline predicts masks of objects and + their classes. + + Example: + + ```python + >>> from transformers import pipeline + + >>> segmenter = pipeline(model="facebook/detr-resnet-50-panoptic") + >>> segments = segmenter("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png") + >>> len(segments) + 2 + + >>> segments[0]["label"] + 'bird' + + >>> segments[1]["label"] + 'bird' + + >>> type(segments[0]["mask"]) # This is a black and white mask showing where is the bird on the original image. + + + >>> segments[0]["mask"].size + (768, 512) + ``` + + + This image segmentation pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"image-segmentation"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=image-segmentation). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if self.framework == "tf": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + + requires_backends(self, "vision") + self.check_model_type( + dict( + MODEL_FOR_IMAGE_SEGMENTATION_MAPPING.items() + + MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING.items() + + MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING.items() + + MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING.items() + ) + ) + + def _sanitize_parameters(self, **kwargs): + preprocess_kwargs = {} + postprocess_kwargs = {} + if "subtask" in kwargs: + postprocess_kwargs["subtask"] = kwargs["subtask"] + preprocess_kwargs["subtask"] = kwargs["subtask"] + if "threshold" in kwargs: + postprocess_kwargs["threshold"] = kwargs["threshold"] + if "mask_threshold" in kwargs: + postprocess_kwargs["mask_threshold"] = kwargs["mask_threshold"] + if "overlap_mask_area_threshold" in kwargs: + postprocess_kwargs["overlap_mask_area_threshold"] = kwargs["overlap_mask_area_threshold"] + + return preprocess_kwargs, {}, postprocess_kwargs + + def __call__(self, images, **kwargs) -> Union[Predictions, List[Prediction]]: + """ + Perform segmentation (detect masks & classes) in the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing an HTTP(S) link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images. Images in a batch must all be in the + same format: all as HTTP(S) links, all as local paths, or all as PIL images. + subtask (`str`, *optional*): + Segmentation task to be performed, choose [`semantic`, `instance` and `panoptic`] depending on model + capabilities. If not set, the pipeline will attempt tp resolve in the following order: + `panoptic`, `instance`, `semantic`. + threshold (`float`, *optional*, defaults to 0.9): + Probability threshold to filter out predicted masks. + mask_threshold (`float`, *optional*, defaults to 0.5): + Threshold to use when turning the predicted masks into binary values. + overlap_mask_area_threshold (`float`, *optional*, defaults to 0.5): + Mask overlap threshold to eliminate small, disconnected segments. + + Return: + A dictionary or a list of dictionaries containing the result. If the input is a single image, will return a + list of dictionaries, if the input is a list of several images, will return a list of list of dictionaries + corresponding to each image. + + The dictionaries contain the mask, label and score (where applicable) of each detected object and contains + the following keys: + + - **label** (`str`) -- The class label identified by the model. + - **mask** (`PIL.Image`) -- A binary mask of the detected object as a Pil Image of shape (width, height) of + the original image. Returns a mask filled with zeros if no object is found. + - **score** (*optional* `float`) -- Optionally, when the model is capable of estimating a confidence of the + "object" described by the label and the mask. + """ + return super().__call__(images, **kwargs) + + def preprocess(self, image, subtask=None): + image = load_image(image) + target_size = [(image.height, image.width)] + if self.model.config.__class__.__name__ == "OneFormerConfig": + if subtask is None: + kwargs = {} + else: + kwargs = {"task_inputs": [subtask]} + inputs = self.image_processor(images=[image], return_tensors="pt", **kwargs) + inputs["task_inputs"] = self.tokenizer( + inputs["task_inputs"], + padding="max_length", + max_length=self.model.config.task_seq_len, + return_tensors=self.framework, + )["input_ids"] + else: + inputs = self.image_processor(images=[image], return_tensors="pt") + inputs["target_size"] = target_size + return inputs + + def _forward(self, model_inputs): + target_size = model_inputs.pop("target_size") + model_outputs = self.model(**model_inputs) + model_outputs["target_size"] = target_size + return model_outputs + + def postprocess( + self, model_outputs, subtask=None, threshold=0.9, mask_threshold=0.5, overlap_mask_area_threshold=0.5 + ): + fn = None + if subtask in {"panoptic", None} and hasattr(self.image_processor, "post_process_panoptic_segmentation"): + fn = self.image_processor.post_process_panoptic_segmentation + elif subtask in {"instance", None} and hasattr(self.image_processor, "post_process_instance_segmentation"): + fn = self.image_processor.post_process_instance_segmentation + + if fn is not None: + outputs = fn( + model_outputs, + threshold=threshold, + mask_threshold=mask_threshold, + overlap_mask_area_threshold=overlap_mask_area_threshold, + target_sizes=model_outputs["target_size"], + )[0] + + annotation = [] + segmentation = outputs["segmentation"] + + for segment in outputs["segments_info"]: + mask = (segmentation == segment["id"]) * 255 + mask = Image.fromarray(mask.numpy().astype(np.uint8), mode="L") + label = self.model.config.id2label[segment["label_id"]] + score = segment["score"] + annotation.append({"score": score, "label": label, "mask": mask}) + + elif subtask in {"semantic", None} and hasattr(self.image_processor, "post_process_semantic_segmentation"): + outputs = self.image_processor.post_process_semantic_segmentation( + model_outputs, target_sizes=model_outputs["target_size"] + )[0] + + annotation = [] + segmentation = outputs.numpy() + labels = np.unique(segmentation) + + for label in labels: + mask = (segmentation == label) * 255 + mask = Image.fromarray(mask.astype(np.uint8), mode="L") + label = self.model.config.id2label[label] + annotation.append({"score": None, "label": label, "mask": mask}) + else: + raise ValueError(f"Subtask {subtask} is not supported for model {type(self.model)}") + return annotation diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..f34dad3cef81428e97b7574692833024defc140a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/image_to_text.py @@ -0,0 +1,127 @@ +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(): + from ..models.auto.modeling_auto import MODEL_FOR_VISION_2_SEQ_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ImageToTextPipeline(Pipeline): + """ + Image To Text pipeline using a `AutoModelForVision2Seq`. This pipeline predicts a caption for a given image. + + Example: + + ```python + >>> from transformers import pipeline + + >>> captioner = pipeline(model="ydshieh/vit-gpt2-coco-en") + >>> captioner("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png") + [{'generated_text': 'two birds are standing next to each other '}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This image to text pipeline can currently be loaded from pipeline() using the following task identifier: + "image-to-text". + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?pipeline_tag=image-to-text). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + 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 _sanitize_parameters(self, max_new_tokens=None, generate_kwargs=None): + forward_kwargs = {} + if generate_kwargs is not None: + forward_kwargs["generate_kwargs"] = generate_kwargs + if max_new_tokens is not None: + if "generate_kwargs" not in forward_kwargs: + forward_kwargs["generate_kwargs"] = {} + 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" + ) + forward_kwargs["generate_kwargs"]["max_new_tokens"] = max_new_tokens + return {}, forward_kwargs, {} + + def __call__(self, images: Union[str, List[str], "Image.Image", List["Image.Image"]], **kwargs): + """ + Assign labels to the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing a HTTP(s) link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images. + + max_new_tokens (`int`, *optional*): + The amount of maximum tokens to generate. By default it will use `generate` default. + + generate_kwargs (`Dict`, *optional*): + Pass it to send all of these arguments directly to `generate` allowing full control of this function. + + Return: + A list or a list of list of `dict`: Each result comes as a dictionary with the following key: + + - **generated_text** (`str`) -- The generated text. + """ + return super().__call__(images, **kwargs) + + def preprocess(self, image): + image = load_image(image) + model_inputs = self.image_processor(images=image, return_tensors=self.framework) + return model_inputs + + def _forward(self, model_inputs, generate_kwargs=None): + if generate_kwargs is None: + generate_kwargs = {} + # 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. + inputs = model_inputs.pop(self.model.main_input_name) + model_outputs = self.model.generate(inputs, **model_inputs, **generate_kwargs) + return model_outputs + + def postprocess(self, model_outputs): + records = [] + for output_ids in model_outputs: + record = { + "generated_text": self.tokenizer.decode( + output_ids, + skip_special_tokens=True, + ) + } + records.append(record) + return records diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/mask_generation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/mask_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..bfcd9e800a87e8a3be3091f3875e8b9086da55f0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/mask_generation.py @@ -0,0 +1,286 @@ +from collections import defaultdict +from typing import Optional + +from ..image_utils import load_image +from ..utils import ( + add_end_docstrings, + is_torch_available, + logging, + requires_backends, +) +from .base import PIPELINE_INIT_ARGS, ChunkPipeline + + +if is_torch_available(): + import torch + + from ..models.auto.modeling_auto import MODEL_FOR_MASK_GENERATION_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class MaskGenerationPipeline(ChunkPipeline): + """ + Automatic mask generation for images using `SamForMaskGeneration`. This pipeline predicts binary masks for an + image, given an image. It is a `ChunkPipeline` because you can seperate the points in a mini-batch in order to + avoid OOM issues. Use the `points_per_batch` argument to control the number of points that will be processed at the + same time. Default is `64`. + + The pipeline works in 3 steps: + 1. `preprocess`: A grid of 1024 points evenly separated is generated along with bounding boxes and point + labels. + For more details on how the points and bounding boxes are created, check the `_generate_crop_boxes` + function. The image is also preprocessed using the `image_processor`. This function `yields` a minibatch of + `points_per_batch`. + + 2. `forward`: feeds the outputs of `preprocess` to the model. The image embedding is computed only once. + Calls both `self.model.get_image_embeddings` and makes sure that the gradients are not computed, and the + tensors and models are on the same device. + + 3. `postprocess`: The most important part of the automatic mask generation happens here. Three steps + are induced: + - image_processor.postprocess_masks (run on each minibatch loop): takes in the raw output masks, + resizes them according + to the image size, and transforms there to binary masks. + - image_processor.filter_masks (on each minibatch loop): uses both `pred_iou_thresh` and + `stability_scores`. Also + applies a variety of filters based on non maximum suppression to remove bad masks. + - image_processor.postprocess_masks_for_amg applies the NSM on the mask to only keep relevant ones. + + Arguments: + model ([`PreTrainedModel`] or [`TFPreTrainedModel`]): + The model that will be used by the pipeline to make predictions. This needs to be a model inheriting from + [`PreTrainedModel`] for PyTorch and [`TFPreTrainedModel`] for TensorFlow. + tokenizer ([`PreTrainedTokenizer`]): + The tokenizer that will be used by the pipeline to encode data for the model. This object inherits from + [`PreTrainedTokenizer`]. + feature_extractor ([`SequenceFeatureExtractor`]): + The feature extractor that will be used by the pipeline to encode the input. + points_per_batch (*optional*, int, default to 64): + Sets the number of points run simultaneously by the model. Higher numbers may be faster but use more GPU + memory. + output_bboxes_mask (`bool`, *optional*, default to `False`): + Whether or not to output the bounding box predictions. + output_rle_masks (`bool`, *optional*, default to `False`): + Whether or not to output the masks in `RLE` format + + Example: + + ```python + >>> from transformers import pipeline + + >>> generator = pipeline(model="facebook/sam-vit-base", task="mask-generation") + >>> outputs = generator( + ... "http://images.cocodataset.org/val2017/000000039769.jpg", + ... ) + + >>> outputs = generator( + ... "https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png", points_per_batch=128 + ... ) + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This segmentation pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"mask-generation"`. + + See the list of available models on [huggingface.co/models](https://huggingface.co/models?filter=mask-generation). + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + requires_backends(self, "vision") + requires_backends(self, "torch") + + if self.framework != "pt": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + + self.check_model_type(MODEL_FOR_MASK_GENERATION_MAPPING) + + def _sanitize_parameters(self, **kwargs): + preprocess_kwargs = {} + postprocess_kwargs = {} + forward_params = {} + # preprocess args + if "points_per_batch" in kwargs: + preprocess_kwargs["points_per_batch"] = kwargs["points_per_batch"] + if "points_per_crop" in kwargs: + preprocess_kwargs["points_per_crop"] = kwargs["points_per_crop"] + if "crops_n_layers" in kwargs: + preprocess_kwargs["crops_n_layers"] = kwargs["crops_n_layers"] + if "crop_overlap_ratio" in kwargs: + preprocess_kwargs["crop_overlap_ratio"] = kwargs["crop_overlap_ratio"] + if "crop_n_points_downscale_factor" in kwargs: + preprocess_kwargs["crop_n_points_downscale_factor"] = kwargs["crop_n_points_downscale_factor"] + # postprocess args + if "pred_iou_thresh" in kwargs: + forward_params["pred_iou_thresh"] = kwargs["pred_iou_thresh"] + if "stability_score_offset" in kwargs: + forward_params["stability_score_offset"] = kwargs["stability_score_offset"] + if "mask_threshold" in kwargs: + forward_params["mask_threshold"] = kwargs["mask_threshold"] + if "stability_score_thresh" in kwargs: + forward_params["stability_score_thresh"] = kwargs["stability_score_thresh"] + if "crops_nms_thresh" in kwargs: + postprocess_kwargs["crops_nms_thresh"] = kwargs["crops_nms_thresh"] + if "output_rle_mask" in kwargs: + postprocess_kwargs["output_rle_mask"] = kwargs["output_rle_mask"] + if "output_bboxes_mask" in kwargs: + postprocess_kwargs["output_bboxes_mask"] = kwargs["output_bboxes_mask"] + return preprocess_kwargs, forward_params, postprocess_kwargs + + def __call__(self, image, *args, num_workers=None, batch_size=None, **kwargs): + """ + Generates binary segmentation masks + + Args: + inputs (`np.ndarray` or `bytes` or `str` or `dict`): + Image or list of images. + mask_threshold (`float`, *optional*, defaults to 0.0): + Threshold to use when turning the predicted masks into binary values. + pred_iou_thresh (`float`, *optional*, defaults to 0.88): + A filtering threshold in `[0,1]` applied on the model's predicted mask quality. + stability_score_thresh (`float`, *optional*, defaults to 0.95): + A filtering threshold in `[0,1]`, using the stability of the mask under changes to the cutoff used to + binarize the model's mask predictions. + stability_score_offset (`int`, *optional*, defaults to 1): + The amount to shift the cutoff when calculated the stability score. + crops_nms_thresh (`float`, *optional*, defaults to 0.7): + The box IoU cutoff used by non-maximal suppression to filter duplicate masks. + crops_n_layers (`int`, *optional*, defaults to 0): + If `crops_n_layers>0`, mask prediction will be run again on crops of the image. Sets the number of + layers to run, where each layer has 2**i_layer number of image crops. + crop_overlap_ratio (`float`, *optional*, defaults to `512 / 1500`): + Sets the degree to which crops overlap. In the first crop layer, crops will overlap by this fraction of + the image length. Later layers with more crops scale down this overlap. + crop_n_points_downscale_factor (`int`, *optional*, defaults to `1`): + The number of points-per-side sampled in layer n is scaled down by crop_n_points_downscale_factor**n. + + Return: + `Dict`: A dictionary with the following keys: + - **mask** (`PIL.Image`) -- A binary mask of the detected object as a PIL Image of shape `(width, + height)` of the original image. Returns a mask filled with zeros if no object is found. + - **score** (*optional* `float`) -- Optionally, when the model is capable of estimating a confidence of + the "object" described by the label and the mask. + + """ + return super().__call__(image, *args, num_workers=num_workers, batch_size=batch_size, **kwargs) + + def preprocess( + self, + image, + points_per_batch=64, + crops_n_layers: int = 0, + crop_overlap_ratio: float = 512 / 1500, + points_per_crop: Optional[int] = 32, + crop_n_points_downscale_factor: Optional[int] = 1, + ): + image = load_image(image) + target_size = self.image_processor.size["longest_edge"] + crop_boxes, grid_points, cropped_images, input_labels = self.image_processor.generate_crop_boxes( + image, target_size, crops_n_layers, crop_overlap_ratio, points_per_crop, crop_n_points_downscale_factor + ) + model_inputs = self.image_processor(images=cropped_images, return_tensors="pt") + + with self.device_placement(): + if self.framework == "pt": + inference_context = self.get_inference_context() + with inference_context(): + model_inputs = self._ensure_tensor_on_device(model_inputs, device=self.device) + image_embeddings = self.model.get_image_embeddings(model_inputs.pop("pixel_values")) + model_inputs["image_embeddings"] = image_embeddings + + n_points = grid_points.shape[1] + points_per_batch = points_per_batch if points_per_batch is not None else n_points + + if points_per_batch <= 0: + raise ValueError( + "Cannot have points_per_batch<=0. Must be >=1 to returned batched outputs. " + "To return all points at once, set points_per_batch to None" + ) + + for i in range(0, n_points, points_per_batch): + batched_points = grid_points[:, i : i + points_per_batch, :, :] + labels = input_labels[:, i : i + points_per_batch] + is_last = i == n_points - points_per_batch + yield { + "input_points": batched_points, + "input_labels": labels, + "input_boxes": crop_boxes, + "is_last": is_last, + **model_inputs, + } + + def _forward( + self, + model_inputs, + pred_iou_thresh=0.88, + stability_score_thresh=0.95, + mask_threshold=0, + stability_score_offset=1, + ): + input_boxes = model_inputs.pop("input_boxes") + is_last = model_inputs.pop("is_last") + original_sizes = model_inputs.pop("original_sizes").tolist() + reshaped_input_sizes = model_inputs.pop("reshaped_input_sizes").tolist() + + model_outputs = self.model(**model_inputs) + + # post processing happens here in order to avoid CPU GPU copies of ALL the masks + low_resolution_masks = model_outputs["pred_masks"] + masks = self.image_processor.post_process_masks( + low_resolution_masks, original_sizes, reshaped_input_sizes, mask_threshold, binarize=False + ) + iou_scores = model_outputs["iou_scores"] + masks, iou_scores, boxes = self.image_processor.filter_masks( + masks[0], + iou_scores[0], + original_sizes[0], + input_boxes[0], + pred_iou_thresh, + stability_score_thresh, + mask_threshold, + stability_score_offset, + ) + return { + "masks": masks, + "is_last": is_last, + "boxes": boxes, + "iou_scores": iou_scores, + } + + def postprocess( + self, + model_outputs, + output_rle_mask=False, + output_bboxes_mask=False, + crops_nms_thresh=0.7, + ): + all_scores = [] + all_masks = [] + all_boxes = [] + for model_output in model_outputs: + all_scores.append(model_output.pop("iou_scores")) + all_masks.extend(model_output.pop("masks")) + all_boxes.append(model_output.pop("boxes")) + + all_scores = torch.cat(all_scores) + all_boxes = torch.cat(all_boxes) + output_masks, iou_scores, rle_mask, bounding_boxes = self.image_processor.post_process_for_mask_generation( + all_masks, all_scores, all_boxes, crops_nms_thresh + ) + + extra = defaultdict(list) + for output in model_outputs: + for k, v in output.items(): + extra[k].append(v) + + optional = {} + if output_rle_mask: + optional["rle_mask"] = rle_mask + + if output_bboxes_mask: + optional["bounding_boxes"] = bounding_boxes + + return {"masks": output_masks, "scores": iou_scores, **optional, **extra} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/object_detection.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/object_detection.py new file mode 100644 index 0000000000000000000000000000000000000000..0b9c5f0763dc00b97788ebc93b6746e14d71bf7f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/object_detection.py @@ -0,0 +1,178 @@ +from typing import Any, Dict, List, Union + +from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging, requires_backends +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_vision_available(): + from ..image_utils import load_image + + +if is_torch_available(): + import torch + + from ..models.auto.modeling_auto import MODEL_FOR_OBJECT_DETECTION_MAPPING, MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + +logger = logging.get_logger(__name__) + + +Prediction = Dict[str, Any] +Predictions = List[Prediction] + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ObjectDetectionPipeline(Pipeline): + """ + Object detection pipeline using any `AutoModelForObjectDetection`. This pipeline predicts bounding boxes of objects + and their classes. + + Example: + + ```python + >>> from transformers import pipeline + + >>> detector = pipeline(model="facebook/detr-resnet-50") + >>> detector("https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png") + [{'score': 0.997, 'label': 'bird', 'box': {'xmin': 69, 'ymin': 171, 'xmax': 396, 'ymax': 507}}, {'score': 0.999, 'label': 'bird', 'box': {'xmin': 398, 'ymin': 105, 'xmax': 767, 'ymax': 507}}] + + >>> # x, y are expressed relative to the top left hand corner. + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This object detection pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"object-detection"`. + + See the list of available models on [huggingface.co/models](https://huggingface.co/models?filter=object-detection). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if self.framework == "tf": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + + requires_backends(self, "vision") + self.check_model_type( + dict(MODEL_FOR_OBJECT_DETECTION_MAPPING.items() + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING.items()) + ) + + def _sanitize_parameters(self, **kwargs): + postprocess_kwargs = {} + if "threshold" in kwargs: + postprocess_kwargs["threshold"] = kwargs["threshold"] + return {}, {}, postprocess_kwargs + + def __call__(self, *args, **kwargs) -> Union[Predictions, List[Prediction]]: + """ + Detect objects (bounding boxes & classes) in the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing an HTTP(S) link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images. Images in a batch must all be in the + same format: all as HTTP(S) links, all as local paths, or all as PIL images. + threshold (`float`, *optional*, defaults to 0.9): + The probability necessary to make a prediction. + + Return: + A list of dictionaries or a list of list of dictionaries containing the result. If the input is a single + image, will return a list of dictionaries, if the input is a list of several images, will return a list of + list of dictionaries corresponding to each image. + + The dictionaries contain the following keys: + + - **label** (`str`) -- The class label identified by the model. + - **score** (`float`) -- The score attributed by the model for that label. + - **box** (`List[Dict[str, int]]`) -- The bounding box of detected object in image's original size. + """ + + return super().__call__(*args, **kwargs) + + def preprocess(self, image): + image = load_image(image) + target_size = torch.IntTensor([[image.height, image.width]]) + inputs = self.image_processor(images=[image], return_tensors="pt") + if self.tokenizer is not None: + inputs = self.tokenizer(text=inputs["words"], boxes=inputs["boxes"], return_tensors="pt") + inputs["target_size"] = target_size + return inputs + + def _forward(self, model_inputs): + target_size = model_inputs.pop("target_size") + outputs = self.model(**model_inputs) + model_outputs = outputs.__class__({"target_size": target_size, **outputs}) + if self.tokenizer is not None: + model_outputs["bbox"] = model_inputs["bbox"] + return model_outputs + + def postprocess(self, model_outputs, threshold=0.9): + target_size = model_outputs["target_size"] + if self.tokenizer is not None: + # This is a LayoutLMForTokenClassification variant. + # The OCR got the boxes and the model classified the words. + height, width = target_size[0].tolist() + + def unnormalize(bbox): + return self._get_bounding_box( + torch.Tensor( + [ + (width * bbox[0] / 1000), + (height * bbox[1] / 1000), + (width * bbox[2] / 1000), + (height * bbox[3] / 1000), + ] + ) + ) + + scores, classes = model_outputs["logits"].squeeze(0).softmax(dim=-1).max(dim=-1) + labels = [self.model.config.id2label[prediction] for prediction in classes.tolist()] + boxes = [unnormalize(bbox) for bbox in model_outputs["bbox"].squeeze(0)] + keys = ["score", "label", "box"] + annotation = [dict(zip(keys, vals)) for vals in zip(scores.tolist(), labels, boxes) if vals[0] > threshold] + else: + # This is a regular ForObjectDetectionModel + raw_annotations = self.image_processor.post_process_object_detection(model_outputs, threshold, target_size) + raw_annotation = raw_annotations[0] + scores = raw_annotation["scores"] + labels = raw_annotation["labels"] + boxes = raw_annotation["boxes"] + + raw_annotation["scores"] = scores.tolist() + raw_annotation["labels"] = [self.model.config.id2label[label.item()] for label in labels] + raw_annotation["boxes"] = [self._get_bounding_box(box) for box in boxes] + + # {"scores": [...], ...} --> [{"score":x, ...}, ...] + keys = ["score", "label", "box"] + annotation = [ + dict(zip(keys, vals)) + for vals in zip(raw_annotation["scores"], raw_annotation["labels"], raw_annotation["boxes"]) + ] + + return annotation + + def _get_bounding_box(self, box: "torch.Tensor") -> Dict[str, int]: + """ + Turns list [xmin, xmax, ymin, ymax] into dict { "xmin": xmin, ... } + + Args: + box (`torch.Tensor`): Tensor containing the coordinates in corners format. + + Returns: + bbox (`Dict[str, int]`): Dict containing the coordinates in corners format. + """ + if self.framework != "pt": + raise ValueError("The ObjectDetectionPipeline is only available in PyTorch.") + xmin, ymin, xmax, ymax = box.int().tolist() + bbox = { + "xmin": xmin, + "ymin": ymin, + "xmax": xmax, + "ymax": ymax, + } + return bbox diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/pt_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/pt_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..4a95d050ec8c3c70c01f1be34c816db707344637 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/pt_utils.py @@ -0,0 +1,318 @@ +import numpy as np +import torch +from torch.utils.data import Dataset, IterableDataset + +from ..utils.generic import ModelOutput + + +class PipelineDataset(Dataset): + def __init__(self, dataset, process, params): + self.dataset = dataset + self.process = process + self.params = params + + def __len__(self): + return len(self.dataset) + + def __getitem__(self, i): + item = self.dataset[i] + processed = self.process(item, **self.params) + return processed + + +class PipelineIterator(IterableDataset): + def __init__(self, loader, infer, params, loader_batch_size=None): + """ + Roughly equivalent to + + ``` + for item in loader: + yield infer(item, **params) + ``` + + Arguments: + loader (`torch.utils.data.DataLoader` or any iterator): + The iterator that will be used to apply `infer` on. + infer (any function): + The function to apply of each element of `loader`. + params (`dict`): + The parameters passed to `infer` along with every item + loader_batch_size (`int`, *optional*): + If specified, the items of `loader` are supposed to come as batch, and are loader_batched here + making it roughly behave as + + + ``` + for items in loader: + for i in loader_batch_size: + item = items[i] + yield infer(item, **params) + ```""" + self.loader = loader + self.infer = infer + self.params = params + if loader_batch_size == 1: + # Let's spare some time by deactivating altogether + loader_batch_size = None + self.loader_batch_size = loader_batch_size + + # Internal bookkeeping + self._loader_batch_index = None + self._loader_batch_data = None + + def __len__(self): + return len(self.loader) + + def __iter__(self): + self.iterator = iter(self.loader) + return self + + def loader_batch_item(self): + """ + Return item located at `loader_batch_index` within the current `loader_batch_data`. + """ + if isinstance(self._loader_batch_data, torch.Tensor): + # Batch data is simple tensor, just fetch the slice + result = self._loader_batch_data[self._loader_batch_index] + else: + # Batch data is assumed to be BaseModelOutput (or dict) + loader_batched = {} + for k, element in self._loader_batch_data.items(): + if isinstance(element, ModelOutput): + # Convert ModelOutput to tuple first + element = element.to_tuple() + if isinstance(element[0], torch.Tensor): + loader_batched[k] = tuple(el[self._loader_batch_index].unsqueeze(0) for el in element) + elif isinstance(element[0], np.ndarray): + loader_batched[k] = 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(element, tuple): + # Those are stored as lists of tensors so need specific unbatching. + if isinstance(element[0], torch.Tensor): + loader_batched[k] = tuple(el[self._loader_batch_index].unsqueeze(0) for el in element) + elif isinstance(element[0], np.ndarray): + loader_batched[k] = 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 + loader_batched[k] = 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 + + loader_batched[k] = 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 + loader_batched[k] = np.expand_dims(element[self._loader_batch_index], 0) + else: + # This is typically a list, so no need to `unsqueeze`. + loader_batched[k] = element[self._loader_batch_index] + # Recreate the element by reusing the original class to make it look + # batch_size=1 + result = self._loader_batch_data.__class__(loader_batched) + self._loader_batch_index += 1 + return result + + def __next__(self): + 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 + item = next(self.iterator) + processed = self.infer(item, **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(processed, torch.Tensor): + first_tensor = processed + else: + key = list(processed.keys())[0] + first_tensor = processed[key] + if isinstance(first_tensor, list): + observed_batch_size = len(first_tensor) + else: + observed_batch_size = 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. + self.loader_batch_size = observed_batch_size + # Setting internal index to unwrap the batch + self._loader_batch_data = processed + self._loader_batch_index = 0 + return self.loader_batch_item() + else: + # We're not unrolling batches + return processed + + +class PipelineChunkIterator(PipelineIterator): + def __init__(self, loader, infer, params, loader_batch_size=None): + """ + Roughly equivalent to + + ``` + for iterator in loader: + for item in iterator: + yield infer(item, **params) + ``` + + Arguments: + loader (`torch.utils.data.DataLoader` or any iterator): + The iterator that will be used to apply `infer` on. + infer (any function): + The function to apply of each element of `loader`. + params (`dict`): + The parameters passed to `infer` along with every item + """ + super().__init__(loader, infer, params) + + def __iter__(self): + self.iterator = iter(self.loader) + self.subiterator = None + return self + + def __next__(self): + if self.subiterator is None: + "Subiterator None means we haven't started a `preprocess` iterator. so start it" + self.subiterator = self.infer(next(self.iterator), **self.params) + try: + # Try to return next item + processed = 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 + self.subiterator = self.infer(next(self.iterator), **self.params) + processed = next(self.subiterator) + return processed + + +class PipelinePackIterator(PipelineIterator): + """ + Roughly equivalent to + + ``` + packed = [] + for item in loader: + packed.append(item) + if item["is_last"]: + yield packed + packed = [] + ``` + + but it also handles cases where `item` are batched (meaning it's a dict of Tensor with first dimension > 1. In + that case it does + + ``` + packed = [] + for batch in loader: + # item is batched + for item in batch: + packed.append(item) + if item["is_last"]: + yield packed + packed = [] + ``` + + Arguments: + loader (`torch.utils.data.DataLoader` or any iterator): + The iterator that will be used to apply `infer` on. + infer (any function): + The function to apply of each element of `loader`. + params (`dict`): + The parameters passed to `infer` along with every item + loader_batch_size (`int`, *optional*): + If specified, the items of `loader` are supposed to come as batch, and are loader_batched here making + it roughly behave as + + + ``` + for items in loader: + for i in loader_batch_size: + item = items[i] + yield infer(item, **params) + ```""" + + def __iter__(self): + self.iterator = iter(self.loader) + return self + + def __next__(self): + # Extremely similar to PipelineIterator in its unpacking mechanism + # BUT, we have an extra required item which is the presence of `is_last` + # That is because everything is flattened by `PipelineChunkIterator` we + # need to keep track of how to regroup here in the original `process` + # boundaries so that `process` and `postprocess` see the same data. + + # This iterator accumulates items (possibly while unbatching) until it + # its a `is_last` and then just passes it on to the caller. + is_last = False + accumulator = [] + 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: + item = self.loader_batch_item() + is_last = item.pop("is_last") + accumulator.append(item) + if is_last: + return accumulator + + while not is_last: + processed = self.infer(next(self.iterator), **self.params) + if self.loader_batch_size is not None: + if isinstance(processed, torch.Tensor): + first_tensor = processed + else: + key = list(processed.keys())[0] + first_tensor = processed[key] + if isinstance(first_tensor, list): + observed_batch_size = len(first_tensor) + else: + observed_batch_size = 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. + self.loader_batch_size = observed_batch_size + self._loader_batch_data = processed + self._loader_batch_index = 0 + while self._loader_batch_index < self.loader_batch_size: + item = self.loader_batch_item() + is_last = item.pop("is_last") + accumulator.append(item) + if is_last: + return accumulator + else: + item = processed + is_last = item.pop("is_last") + accumulator.append(item) + return accumulator + + +class KeyDataset(Dataset): + def __init__(self, dataset: Dataset, key: str): + self.dataset = dataset + self.key = key + + def __len__(self): + return len(self.dataset) + + def __getitem__(self, i): + return self.dataset[i][self.key] + + +class KeyPairDataset(Dataset): + def __init__(self, dataset: Dataset, key1: str, key2: str): + self.dataset = dataset + self.key1 = key1 + self.key2 = key2 + + def __len__(self): + return len(self.dataset) + + def __getitem__(self, i): + return {"text": self.dataset[i][self.key1], "text_pair": self.dataset[i][self.key2]} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..884cee78ca5f2c4ac71682a243abbf7732196776 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/question_answering.py @@ -0,0 +1,664 @@ +import types +import warnings +from collections.abc import Iterable +from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union + +import numpy as np + +from ..data import SquadExample, SquadFeatures, squad_convert_examples_to_features +from ..modelcard import ModelCard +from ..tokenization_utils import PreTrainedTokenizer +from ..utils import ( + PaddingStrategy, + add_end_docstrings, + is_tf_available, + is_tokenizers_available, + is_torch_available, + logging, +) +from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline + + +logger = logging.get_logger(__name__) + +if TYPE_CHECKING: + from ..modeling_tf_utils import TFPreTrainedModel + from ..modeling_utils import PreTrainedModel + + if is_tokenizers_available(): + import tokenizers + +if is_tf_available(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING + + Dataset = None + +if is_torch_available(): + import torch + from torch.utils.data import Dataset + + from ..models.auto.modeling_auto import MODEL_FOR_QUESTION_ANSWERING_MAPPING + + +def decode_spans( + start: np.ndarray, end: np.ndarray, topk: int, max_answer_len: int, undesired_tokens: np.ndarray +) -> Tuple: + """ + Take the output of any `ModelForQuestionAnswering` and will generate probabilities for each span to be the actual + answer. + + In addition, it filters out some unwanted/impossible cases like answer len being greater than max_answer_len or + answer end position being before the starting position. The method supports output the k-best answer through the + topk argument. + + Args: + start (`np.ndarray`): Individual start probabilities for each token. + end (`np.ndarray`): Individual end probabilities for each token. + topk (`int`): Indicates how many possible answer span(s) to extract from the model output. + max_answer_len (`int`): Maximum size of the answer to extract from the model's output. + undesired_tokens (`np.ndarray`): Mask determining tokens that can be part of the answer + """ + # Ensure we have batch axis + if start.ndim == 1: + start = start[None] + + if end.ndim == 1: + end = end[None] + + # Compute the score of each tuple(start, end) to be the real answer + outer = np.matmul(np.expand_dims(start, -1), np.expand_dims(end, 1)) + + # Remove candidate with end < start and end - start > max_answer_len + candidates = np.tril(np.triu(outer), max_answer_len - 1) + + # Inspired by Chen & al. (https://github.com/facebookresearch/DrQA) + scores_flat = candidates.flatten() + if topk == 1: + idx_sort = [np.argmax(scores_flat)] + elif len(scores_flat) < topk: + idx_sort = np.argsort(-scores_flat) + else: + idx = np.argpartition(-scores_flat, topk)[0:topk] + idx_sort = idx[np.argsort(-scores_flat[idx])] + + starts, ends = np.unravel_index(idx_sort, candidates.shape)[1:] + desired_spans = np.isin(starts, undesired_tokens.nonzero()) & np.isin(ends, undesired_tokens.nonzero()) + starts = starts[desired_spans] + ends = ends[desired_spans] + scores = candidates[0, starts, ends] + + return starts, ends, scores + + +def select_starts_ends( + start, + end, + p_mask, + attention_mask, + min_null_score=1000000, + top_k=1, + handle_impossible_answer=False, + max_answer_len=15, +): + """ + Takes the raw output of any `ModelForQuestionAnswering` and first normalizes its outputs and then uses + `decode_spans()` to generate probabilities for each span to be the actual answer. + + Args: + start (`np.ndarray`): Individual start logits for each token. + end (`np.ndarray`): Individual end logits for each token. + p_mask (`np.ndarray`): A mask with 1 for values that cannot be in the answer + attention_mask (`np.ndarray`): The attention mask generated by the tokenizer + min_null_score(`float`): The minimum null (empty) answer score seen so far. + topk (`int`): Indicates how many possible answer span(s) to extract from the model output. + handle_impossible_answer(`bool`): Whether to allow null (empty) answers + max_answer_len (`int`): Maximum size of the answer to extract from the model's output. + """ + # Ensure padded tokens & question tokens cannot belong to the set of candidate answers. + undesired_tokens = np.abs(np.array(p_mask) - 1) + + if attention_mask is not None: + undesired_tokens = undesired_tokens & attention_mask + + # Generate mask + undesired_tokens_mask = undesired_tokens == 0.0 + + # Make sure non-context indexes in the tensor cannot contribute to the softmax + start = np.where(undesired_tokens_mask, -10000.0, start) + end = np.where(undesired_tokens_mask, -10000.0, end) + + # Normalize logits and spans to retrieve the answer + start = np.exp(start - start.max(axis=-1, keepdims=True)) + start = start / start.sum() + + end = np.exp(end - end.max(axis=-1, keepdims=True)) + end = end / end.sum() + + if handle_impossible_answer: + min_null_score = min(min_null_score, (start[0, 0] * end[0, 0]).item()) + + # Mask CLS + start[0, 0] = end[0, 0] = 0.0 + + starts, ends, scores = decode_spans(start, end, top_k, max_answer_len, undesired_tokens) + return starts, ends, scores, min_null_score + + +class QuestionAnsweringArgumentHandler(ArgumentHandler): + """ + QuestionAnsweringPipeline requires the user to provide multiple arguments (i.e. question & context) to be mapped to + internal [`SquadExample`]. + + QuestionAnsweringArgumentHandler manages all the possible to create a [`SquadExample`] from the command-line + supplied arguments. + """ + + def normalize(self, item): + if isinstance(item, SquadExample): + return item + elif isinstance(item, dict): + for k in ["question", "context"]: + if k not in item: + raise KeyError("You need to provide a dictionary with keys {question:..., context:...}") + elif item[k] is None: + raise ValueError(f"`{k}` cannot be None") + elif isinstance(item[k], str) and len(item[k]) == 0: + raise ValueError(f"`{k}` cannot be empty") + + return QuestionAnsweringPipeline.create_sample(**item) + raise ValueError(f"{item} argument needs to be of type (SquadExample, dict)") + + def __call__(self, *args, **kwargs): + # Detect where the actual inputs are + if args is not None and len(args) > 0: + if len(args) == 1: + inputs = args[0] + elif len(args) == 2 and {type(el) for el in args} == {str}: + inputs = [{"question": args[0], "context": args[1]}] + else: + inputs = list(args) + # Generic compatibility with sklearn and Keras + # Batched data + elif "X" in kwargs: + inputs = kwargs["X"] + elif "data" in kwargs: + inputs = kwargs["data"] + elif "question" in kwargs and "context" in kwargs: + if isinstance(kwargs["question"], list) and isinstance(kwargs["context"], str): + inputs = [{"question": Q, "context": kwargs["context"]} for Q in kwargs["question"]] + elif isinstance(kwargs["question"], list) and isinstance(kwargs["context"], list): + if len(kwargs["question"]) != len(kwargs["context"]): + raise ValueError("Questions and contexts don't have the same lengths") + + inputs = [{"question": Q, "context": C} for Q, C in zip(kwargs["question"], kwargs["context"])] + elif isinstance(kwargs["question"], str) and isinstance(kwargs["context"], str): + inputs = [{"question": kwargs["question"], "context": kwargs["context"]}] + else: + raise ValueError("Arguments can't be understood") + else: + raise ValueError(f"Unknown arguments {kwargs}") + + # When user is sending a generator we need to trust it's a valid example + generator_types = (types.GeneratorType, Dataset) if Dataset is not None else (types.GeneratorType,) + if isinstance(inputs, generator_types): + return inputs + + # Normalize inputs + if isinstance(inputs, dict): + inputs = [inputs] + elif isinstance(inputs, Iterable): + # Copy to avoid overriding arguments + inputs = list(inputs) + else: + raise ValueError(f"Invalid arguments {kwargs}") + + for i, item in enumerate(inputs): + inputs[i] = self.normalize(item) + + return inputs + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class QuestionAnsweringPipeline(ChunkPipeline): + """ + Question Answering pipeline using any `ModelForQuestionAnswering`. See the [question answering + examples](../task_summary#question-answering) for more information. + + Example: + + ```python + >>> from transformers import pipeline + + >>> oracle = pipeline(model="deepset/roberta-base-squad2") + >>> oracle(question="Where do I live?", context="My name is Wolfgang and I live in Berlin") + {'score': 0.9191, 'start': 34, 'end': 40, 'answer': 'Berlin'} + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This question answering pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"question-answering"`. + + The models that this pipeline can use are models that have been fine-tuned on a question answering task. See the + up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=question-answering). + """ + + default_input_names = "question,context" + handle_impossible_answer = False + + def __init__( + self, + model: Union["PreTrainedModel", "TFPreTrainedModel"], + tokenizer: PreTrainedTokenizer, + modelcard: Optional[ModelCard] = None, + framework: Optional[str] = None, + task: str = "", + **kwargs, + ): + super().__init__( + model=model, + tokenizer=tokenizer, + modelcard=modelcard, + framework=framework, + task=task, + **kwargs, + ) + + self._args_parser = QuestionAnsweringArgumentHandler() + self.check_model_type( + TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING if self.framework == "tf" else MODEL_FOR_QUESTION_ANSWERING_MAPPING + ) + + @staticmethod + def create_sample( + question: Union[str, List[str]], context: Union[str, List[str]] + ) -> Union[SquadExample, List[SquadExample]]: + """ + QuestionAnsweringPipeline leverages the [`SquadExample`] internally. This helper method encapsulate all the + logic for converting question(s) and context(s) to [`SquadExample`]. + + We currently support extractive question answering. + + Arguments: + question (`str` or `List[str]`): The question(s) asked. + context (`str` or `List[str]`): The context(s) in which we will look for the answer. + + Returns: + One or a list of [`SquadExample`]: The corresponding [`SquadExample`] grouping question and context. + """ + if isinstance(question, list): + return [SquadExample(None, q, c, None, None, None) for q, c in zip(question, context)] + else: + return SquadExample(None, question, context, None, None, None) + + def _sanitize_parameters( + self, + padding=None, + topk=None, + top_k=None, + doc_stride=None, + max_answer_len=None, + max_seq_len=None, + max_question_len=None, + handle_impossible_answer=None, + align_to_words=None, + **kwargs, + ): + # Set defaults values + preprocess_params = {} + if padding is not None: + preprocess_params["padding"] = padding + if doc_stride is not None: + preprocess_params["doc_stride"] = doc_stride + if max_question_len is not None: + preprocess_params["max_question_len"] = max_question_len + if max_seq_len is not None: + preprocess_params["max_seq_len"] = max_seq_len + + postprocess_params = {} + if topk is not None and top_k is None: + warnings.warn("topk parameter is deprecated, use top_k instead", UserWarning) + top_k = topk + if top_k is not None: + if top_k < 1: + raise ValueError(f"top_k parameter should be >= 1 (got {top_k})") + postprocess_params["top_k"] = top_k + if max_answer_len is not None: + if max_answer_len < 1: + raise ValueError(f"max_answer_len parameter should be >= 1 (got {max_answer_len}") + if max_answer_len is not None: + postprocess_params["max_answer_len"] = max_answer_len + if handle_impossible_answer is not None: + postprocess_params["handle_impossible_answer"] = handle_impossible_answer + if align_to_words is not None: + postprocess_params["align_to_words"] = align_to_words + return preprocess_params, {}, postprocess_params + + def __call__(self, *args, **kwargs): + """ + Answer the question(s) given as inputs by using the context(s). + + Args: + args ([`SquadExample`] or a list of [`SquadExample`]): + One or several [`SquadExample`] containing the question and context. + X ([`SquadExample`] or a list of [`SquadExample`], *optional*): + One or several [`SquadExample`] containing the question and context (will be treated the same way as if + passed as the first positional argument). + data ([`SquadExample`] or a list of [`SquadExample`], *optional*): + One or several [`SquadExample`] containing the question and context (will be treated the same way as if + passed as the first positional argument). + question (`str` or `List[str]`): + One or several question(s) (must be used in conjunction with the `context` argument). + context (`str` or `List[str]`): + One or several context(s) associated with the question(s) (must be used in conjunction with the + `question` argument). + topk (`int`, *optional*, defaults to 1): + The number of answers to return (will be chosen by order of likelihood). Note that we return less than + topk answers if there are not enough options available within the context. + doc_stride (`int`, *optional*, defaults to 128): + If the context is too long to fit with the question for the model, it will be split in several chunks + with some overlap. This argument controls the size of that overlap. + max_answer_len (`int`, *optional*, defaults to 15): + The maximum length of predicted answers (e.g., only answers with a shorter length are considered). + max_seq_len (`int`, *optional*, defaults to 384): + The maximum length of the total sentence (context + question) in tokens of each chunk passed to the + model. The context will be split in several chunks (using `doc_stride` as overlap) if needed. + max_question_len (`int`, *optional*, defaults to 64): + The maximum length of the question after tokenization. It will be truncated if needed. + handle_impossible_answer (`bool`, *optional*, defaults to `False`): + Whether or not we accept impossible as an answer. + align_to_words (`bool`, *optional*, defaults to `True`): + Attempts to align the answer to real words. Improves quality on space separated langages. Might hurt on + non-space-separated languages (like Japanese or Chinese) + + Return: + A `dict` or a list of `dict`: Each result comes as a dictionary with the following keys: + + - **score** (`float`) -- The probability associated to the answer. + - **start** (`int`) -- The character start index of the answer (in the tokenized version of the input). + - **end** (`int`) -- The character end index of the answer (in the tokenized version of the input). + - **answer** (`str`) -- The answer to the question. + """ + + # Convert inputs to features + + examples = self._args_parser(*args, **kwargs) + if isinstance(examples, (list, tuple)) and len(examples) == 1: + return super().__call__(examples[0], **kwargs) + return super().__call__(examples, **kwargs) + + def preprocess(self, example, padding="do_not_pad", doc_stride=None, max_question_len=64, max_seq_len=None): + # XXX: This is specal, args_parser will not handle anything generator or dataset like + # For those we expect user to send a simple valid example either directly as a SquadExample or simple dict. + # So we still need a little sanitation here. + if isinstance(example, dict): + example = SquadExample(None, example["question"], example["context"], None, None, None) + + if max_seq_len is None: + max_seq_len = min(self.tokenizer.model_max_length, 384) + if doc_stride is None: + doc_stride = min(max_seq_len // 2, 128) + + if doc_stride > max_seq_len: + raise ValueError(f"`doc_stride` ({doc_stride}) is larger than `max_seq_len` ({max_seq_len})") + + if not self.tokenizer.is_fast: + features = squad_convert_examples_to_features( + examples=[example], + tokenizer=self.tokenizer, + max_seq_length=max_seq_len, + doc_stride=doc_stride, + max_query_length=max_question_len, + padding_strategy=PaddingStrategy.MAX_LENGTH, + is_training=False, + tqdm_enabled=False, + ) + else: + # Define the side we want to truncate / pad and the text/pair sorting + question_first = self.tokenizer.padding_side == "right" + + encoded_inputs = self.tokenizer( + text=example.question_text if question_first else example.context_text, + text_pair=example.context_text if question_first else example.question_text, + padding=padding, + truncation="only_second" if question_first else "only_first", + max_length=max_seq_len, + stride=doc_stride, + return_token_type_ids=True, + return_overflowing_tokens=True, + return_offsets_mapping=True, + return_special_tokens_mask=True, + ) + # When the input is too long, it's converted in a batch of inputs with overflowing tokens + # and a stride of overlap between the inputs. If a batch of inputs is given, a special output + # "overflow_to_sample_mapping" indicate which member of the encoded batch belong to which original batch sample. + # Here we tokenize examples one-by-one so we don't need to use "overflow_to_sample_mapping". + # "num_span" is the number of output samples generated from the overflowing tokens. + num_spans = len(encoded_inputs["input_ids"]) + + # p_mask: mask with 1 for token than cannot be in the answer (0 for token which can be in an answer) + # We put 0 on the tokens from the context and 1 everywhere else (question and special tokens) + p_mask = [ + [tok != 1 if question_first else 0 for tok in encoded_inputs.sequence_ids(span_id)] + for span_id in range(num_spans) + ] + + features = [] + for span_idx in range(num_spans): + input_ids_span_idx = encoded_inputs["input_ids"][span_idx] + attention_mask_span_idx = ( + encoded_inputs["attention_mask"][span_idx] if "attention_mask" in encoded_inputs else None + ) + token_type_ids_span_idx = ( + encoded_inputs["token_type_ids"][span_idx] if "token_type_ids" in encoded_inputs else None + ) + # keep the cls_token unmasked (some models use it to indicate unanswerable questions) + if self.tokenizer.cls_token_id is not None: + cls_indices = np.nonzero(np.array(input_ids_span_idx) == self.tokenizer.cls_token_id)[0] + for cls_index in cls_indices: + p_mask[span_idx][cls_index] = 0 + submask = p_mask[span_idx] + features.append( + SquadFeatures( + input_ids=input_ids_span_idx, + attention_mask=attention_mask_span_idx, + token_type_ids=token_type_ids_span_idx, + p_mask=submask, + encoding=encoded_inputs[span_idx], + # We don't use the rest of the values - and actually + # for Fast tokenizer we could totally avoid using SquadFeatures and SquadExample + cls_index=None, + token_to_orig_map={}, + example_index=0, + unique_id=0, + paragraph_len=0, + token_is_max_context=0, + tokens=[], + start_position=0, + end_position=0, + is_impossible=False, + qas_id=None, + ) + ) + + for i, feature in enumerate(features): + fw_args = {} + others = {} + model_input_names = self.tokenizer.model_input_names + ["p_mask", "token_type_ids"] + + for k, v in feature.__dict__.items(): + if k in model_input_names: + if self.framework == "tf": + tensor = tf.constant(v) + if tensor.dtype == tf.int64: + tensor = tf.cast(tensor, tf.int32) + fw_args[k] = tf.expand_dims(tensor, 0) + elif self.framework == "pt": + tensor = torch.tensor(v) + if tensor.dtype == torch.int32: + tensor = tensor.long() + fw_args[k] = tensor.unsqueeze(0) + else: + others[k] = v + + is_last = i == len(features) - 1 + yield {"example": example, "is_last": is_last, **fw_args, **others} + + def _forward(self, inputs): + example = inputs["example"] + model_inputs = {k: inputs[k] for k in self.tokenizer.model_input_names} + output = self.model(**model_inputs) + if isinstance(output, dict): + return {"start": output["start_logits"], "end": output["end_logits"], "example": example, **inputs} + else: + start, end = output[:2] + return {"start": start, "end": end, "example": example, **inputs} + + def postprocess( + self, + model_outputs, + top_k=1, + handle_impossible_answer=False, + max_answer_len=15, + align_to_words=True, + ): + min_null_score = 1000000 # large and positive + answers = [] + for output in model_outputs: + start_ = output["start"] + end_ = output["end"] + example = output["example"] + p_mask = output["p_mask"] + attention_mask = ( + output["attention_mask"].numpy() if output.get("attention_mask", None) is not None else None + ) + + starts, ends, scores, min_null_score = select_starts_ends( + start_, end_, p_mask, attention_mask, min_null_score, top_k, handle_impossible_answer, max_answer_len + ) + + if not self.tokenizer.is_fast: + char_to_word = np.array(example.char_to_word_offset) + + # Convert the answer (tokens) back to the original text + # Score: score from the model + # Start: Index of the first character of the answer in the context string + # End: Index of the character following the last character of the answer in the context string + # Answer: Plain text of the answer + for s, e, score in zip(starts, ends, scores): + token_to_orig_map = output["token_to_orig_map"] + answers.append( + { + "score": score.item(), + "start": np.where(char_to_word == token_to_orig_map[s])[0][0].item(), + "end": np.where(char_to_word == token_to_orig_map[e])[0][-1].item(), + "answer": " ".join(example.doc_tokens[token_to_orig_map[s] : token_to_orig_map[e] + 1]), + } + ) + else: + # Convert the answer (tokens) back to the original text + # Score: score from the model + # Start: Index of the first character of the answer in the context string + # End: Index of the character following the last character of the answer in the context string + # Answer: Plain text of the answer + question_first = bool(self.tokenizer.padding_side == "right") + enc = output["encoding"] + + # Encoding was *not* padded, input_ids *might*. + # It doesn't make a difference unless we're padding on + # the left hand side, since now we have different offsets + # everywhere. + if self.tokenizer.padding_side == "left": + offset = (output["input_ids"] == self.tokenizer.pad_token_id).numpy().sum() + else: + offset = 0 + + # Sometimes the max probability token is in the middle of a word so: + # - we start by finding the right word containing the token with `token_to_word` + # - then we convert this word in a character span with `word_to_chars` + sequence_index = 1 if question_first else 0 + for s, e, score in zip(starts, ends, scores): + s = s - offset + e = e - offset + + start_index, end_index = self.get_indices(enc, s, e, sequence_index, align_to_words) + + answers.append( + { + "score": score.item(), + "start": start_index, + "end": end_index, + "answer": example.context_text[start_index:end_index], + } + ) + + if handle_impossible_answer: + answers.append({"score": min_null_score, "start": 0, "end": 0, "answer": ""}) + answers = sorted(answers, key=lambda x: x["score"], reverse=True)[:top_k] + if len(answers) == 1: + return answers[0] + return answers + + def get_indices( + self, enc: "tokenizers.Encoding", s: int, e: int, sequence_index: int, align_to_words: bool + ) -> Tuple[int, int]: + if align_to_words: + try: + start_word = enc.token_to_word(s) + end_word = enc.token_to_word(e) + start_index = enc.word_to_chars(start_word, sequence_index=sequence_index)[0] + end_index = enc.word_to_chars(end_word, sequence_index=sequence_index)[1] + except Exception: + # Some tokenizers don't really handle words. Keep to offsets then. + start_index = enc.offsets[s][0] + end_index = enc.offsets[e][1] + else: + start_index = enc.offsets[s][0] + end_index = enc.offsets[e][1] + return start_index, end_index + + def span_to_answer(self, text: str, start: int, end: int) -> Dict[str, Union[str, int]]: + """ + When decoding from token probabilities, this method maps token indexes to actual word in the initial context. + + Args: + text (`str`): The actual context to extract the answer from. + start (`int`): The answer starting token index. + end (`int`): The answer end token index. + + Returns: + Dictionary like `{'answer': str, 'start': int, 'end': int}` + """ + words = [] + token_idx = char_start_idx = char_end_idx = chars_idx = 0 + + for i, word in enumerate(text.split(" ")): + token = self.tokenizer.tokenize(word) + + # Append words if they are in the span + if start <= token_idx <= end: + if token_idx == start: + char_start_idx = chars_idx + + if token_idx == end: + char_end_idx = chars_idx + len(word) + + words += [word] + + # Stop if we went over the end of the answer + if token_idx > end: + break + + # Append the subtokenization length to the running index + token_idx += len(token) + chars_idx += len(word) + 1 + + # Join text with spaces + return { + "answer": " ".join(words), + "start": max(0, char_start_idx), + "end": min(len(text), char_end_idx), + } diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/table_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/table_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..c01d7e49053a91e4a2e2129c86f3a6a9fbe61729 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/table_question_answering.py @@ -0,0 +1,436 @@ +import collections +import types + +import numpy as np + +from ..utils import ( + add_end_docstrings, + is_tensorflow_probability_available, + is_tf_available, + is_torch_available, + requires_backends, +) +from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException + + +if is_torch_available(): + import torch + + from ..models.auto.modeling_auto import ( + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING, + ) + +if is_tf_available() and is_tensorflow_probability_available(): + import tensorflow as tf + import tensorflow_probability as tfp + + from ..models.auto.modeling_tf_auto import ( + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING, + ) + + +class TableQuestionAnsweringArgumentHandler(ArgumentHandler): + """ + Handles arguments for the TableQuestionAnsweringPipeline + """ + + def __call__(self, table=None, query=None, **kwargs): + # Returns tqa_pipeline_inputs of shape: + # [ + # {"table": pd.DataFrame, "query": List[str]}, + # ..., + # {"table": pd.DataFrame, "query" : List[str]} + # ] + requires_backends(self, "pandas") + import pandas as pd + + if table is None: + raise ValueError("Keyword argument `table` cannot be None.") + elif query is None: + if isinstance(table, dict) and table.get("query") is not None and table.get("table") is not None: + tqa_pipeline_inputs = [table] + elif isinstance(table, list) and len(table) > 0: + if not all(isinstance(d, dict) for d in table): + raise ValueError( + f"Keyword argument `table` should be a list of dict, but is {(type(d) for d in table)}" + ) + + if table[0].get("query") is not None and table[0].get("table") is not None: + tqa_pipeline_inputs = table + else: + raise ValueError( + "If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`" + f" and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys." + ) + elif Dataset is not None and isinstance(table, Dataset) or isinstance(table, types.GeneratorType): + return table + else: + raise ValueError( + "Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but " + f"is {type(table)})" + ) + else: + tqa_pipeline_inputs = [{"table": table, "query": query}] + + for tqa_pipeline_input in tqa_pipeline_inputs: + if not isinstance(tqa_pipeline_input["table"], pd.DataFrame): + if tqa_pipeline_input["table"] is None: + raise ValueError("Table cannot be None.") + + tqa_pipeline_input["table"] = pd.DataFrame(tqa_pipeline_input["table"]) + + return tqa_pipeline_inputs + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class TableQuestionAnsweringPipeline(Pipeline): + """ + Table Question Answering pipeline using a `ModelForTableQuestionAnswering`. This pipeline is only available in + PyTorch. + + Example: + + ```python + >>> from transformers import pipeline + + >>> oracle = pipeline(model="google/tapas-base-finetuned-wtq") + >>> table = { + ... "Repository": ["Transformers", "Datasets", "Tokenizers"], + ... "Stars": ["36542", "4512", "3934"], + ... "Contributors": ["651", "77", "34"], + ... "Programming language": ["Python", "Python", "Rust, Python and NodeJS"], + ... } + >>> oracle(query="How many stars does the transformers repository have?", table=table) + {'answer': 'AVERAGE > 36542', 'coordinates': [(0, 1)], 'cells': ['36542'], 'aggregator': 'AVERAGE'} + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This tabular question answering pipeline can currently be loaded from [`pipeline`] using the following task + identifier: `"table-question-answering"`. + + The models that this pipeline can use are models that have been fine-tuned on a tabular question answering task. + See the up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=table-question-answering). + """ + + default_input_names = "table,query" + + def __init__(self, args_parser=TableQuestionAnsweringArgumentHandler(), *args, **kwargs): + super().__init__(*args, **kwargs) + self._args_parser = args_parser + + self.check_model_type( + dict( + TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items() + ) + if self.framework == "tf" + else dict( + MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items() + ) + ) + + self.aggregate = bool(getattr(self.model.config, "aggregation_labels", None)) and bool( + getattr(self.model.config, "num_aggregation_labels", None) + ) + self.type = "tapas" if hasattr(self.model.config, "aggregation_labels") else None + + def batch_inference(self, **inputs): + return self.model(**inputs) + + def sequential_inference(self, **inputs): + """ + Inference used for models that need to process sequences in a sequential fashion, like the SQA models which + handle conversational query related to a table. + """ + if self.framework == "pt": + all_logits = [] + all_aggregations = [] + prev_answers = None + batch_size = inputs["input_ids"].shape[0] + + input_ids = inputs["input_ids"].to(self.device) + attention_mask = inputs["attention_mask"].to(self.device) + token_type_ids = inputs["token_type_ids"].to(self.device) + token_type_ids_example = None + + for index in range(batch_size): + # If sequences have already been processed, the token type IDs will be created according to the previous + # answer. + if prev_answers is not None: + prev_labels_example = token_type_ids_example[:, 3] # shape (seq_len,) + model_labels = np.zeros_like(prev_labels_example.cpu().numpy()) # shape (seq_len,) + + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + for i in range(model_labels.shape[0]): + segment_id = token_type_ids_example[:, 0].tolist()[i] + col_id = token_type_ids_example[:, 1].tolist()[i] - 1 + row_id = token_type_ids_example[:, 2].tolist()[i] - 1 + + if row_id >= 0 and col_id >= 0 and segment_id == 1: + model_labels[i] = int(prev_answers[(col_id, row_id)]) + + token_type_ids_example[:, 3] = torch.from_numpy(model_labels).type(torch.long).to(self.device) + + input_ids_example = input_ids[index] + attention_mask_example = attention_mask[index] # shape (seq_len,) + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + outputs = self.model( + input_ids=input_ids_example.unsqueeze(0), + attention_mask=attention_mask_example.unsqueeze(0), + token_type_ids=token_type_ids_example.unsqueeze(0), + ) + logits = outputs.logits + + if self.aggregate: + all_aggregations.append(outputs.logits_aggregation) + + all_logits.append(logits) + + dist_per_token = torch.distributions.Bernoulli(logits=logits) + probabilities = dist_per_token.probs * attention_mask_example.type(torch.float32).to( + dist_per_token.probs.device + ) + + coords_to_probs = collections.defaultdict(list) + for i, p in enumerate(probabilities.squeeze().tolist()): + segment_id = token_type_ids_example[:, 0].tolist()[i] + col = token_type_ids_example[:, 1].tolist()[i] - 1 + row = token_type_ids_example[:, 2].tolist()[i] - 1 + if col >= 0 and row >= 0 and segment_id == 1: + coords_to_probs[(col, row)].append(p) + + prev_answers = {key: np.array(coords_to_probs[key]).mean() > 0.5 for key in coords_to_probs} + + logits_batch = torch.cat(tuple(all_logits), 0) + + return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(all_aggregations), 0)) + else: + all_logits = [] + all_aggregations = [] + prev_answers = None + batch_size = inputs["input_ids"].shape[0] + + input_ids = inputs["input_ids"] + attention_mask = inputs["attention_mask"] + token_type_ids = inputs["token_type_ids"].numpy() + token_type_ids_example = None + + for index in range(batch_size): + # If sequences have already been processed, the token type IDs will be created according to the previous + # answer. + if prev_answers is not None: + prev_labels_example = token_type_ids_example[:, 3] # shape (seq_len,) + model_labels = np.zeros_like(prev_labels_example, dtype=np.int32) # shape (seq_len,) + + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + for i in range(model_labels.shape[0]): + segment_id = token_type_ids_example[:, 0].tolist()[i] + col_id = token_type_ids_example[:, 1].tolist()[i] - 1 + row_id = token_type_ids_example[:, 2].tolist()[i] - 1 + + if row_id >= 0 and col_id >= 0 and segment_id == 1: + model_labels[i] = int(prev_answers[(col_id, row_id)]) + + token_type_ids_example[:, 3] = model_labels + + input_ids_example = input_ids[index] + attention_mask_example = attention_mask[index] # shape (seq_len,) + token_type_ids_example = token_type_ids[index] # shape (seq_len, 7) + outputs = self.model( + input_ids=np.expand_dims(input_ids_example, axis=0), + attention_mask=np.expand_dims(attention_mask_example, axis=0), + token_type_ids=np.expand_dims(token_type_ids_example, axis=0), + ) + logits = outputs.logits + + if self.aggregate: + all_aggregations.append(outputs.logits_aggregation) + + all_logits.append(logits) + + dist_per_token = tfp.distributions.Bernoulli(logits=logits) + probabilities = dist_per_token.probs_parameter() * tf.cast(attention_mask_example, tf.float32) + + coords_to_probs = collections.defaultdict(list) + token_type_ids_example = token_type_ids_example + for i, p in enumerate(tf.squeeze(probabilities).numpy().tolist()): + segment_id = token_type_ids_example[:, 0].tolist()[i] + col = token_type_ids_example[:, 1].tolist()[i] - 1 + row = token_type_ids_example[:, 2].tolist()[i] - 1 + if col >= 0 and row >= 0 and segment_id == 1: + coords_to_probs[(col, row)].append(p) + + prev_answers = {key: np.array(coords_to_probs[key]).mean() > 0.5 for key in coords_to_probs} + + logits_batch = tf.concat(tuple(all_logits), 0) + + return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(all_aggregations), 0)) + + def __call__(self, *args, **kwargs): + r""" + Answers queries according to a table. The pipeline accepts several types of inputs which are detailed below: + + - `pipeline(table, query)` + - `pipeline(table, [query])` + - `pipeline(table=table, query=query)` + - `pipeline(table=table, query=[query])` + - `pipeline({"table": table, "query": query})` + - `pipeline({"table": table, "query": [query]})` + - `pipeline([{"table": table, "query": query}, {"table": table, "query": query}])` + + The `table` argument should be a dict or a DataFrame built from that dict, containing the whole table: + + Example: + + ```python + data = { + "actors": ["brad pitt", "leonardo di caprio", "george clooney"], + "age": ["56", "45", "59"], + "number of movies": ["87", "53", "69"], + "date of birth": ["7 february 1967", "10 june 1996", "28 november 1967"], + } + ``` + + This dictionary can be passed in as such, or can be converted to a pandas DataFrame: + + Example: + + ```python + import pandas as pd + + table = pd.DataFrame.from_dict(data) + ``` + + Args: + table (`pd.DataFrame` or `Dict`): + Pandas DataFrame or dictionary that will be converted to a DataFrame containing all the table values. + See above for an example of dictionary. + query (`str` or `List[str]`): + Query or list of queries that will be sent to the model alongside the table. + sequential (`bool`, *optional*, defaults to `False`): + Whether to do inference sequentially or as a batch. Batching is faster, but models like SQA require the + inference to be done sequentially to extract relations within sequences, given their conversational + nature. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + + truncation (`bool`, `str` or [`TapasTruncationStrategy`], *optional*, defaults to `False`): + Activates and controls truncation. Accepts the following values: + + - `True` or `'drop_rows_to_fit'`: Truncate to a maximum length specified with the argument `max_length` + or to the maximum acceptable input length for the model if that argument is not provided. This will + truncate row by row, removing rows from the table. + - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths + greater than the model maximum admissible input size). + + + Return: + A dictionary or a list of dictionaries containing results: Each result is a dictionary with the following + keys: + + - **answer** (`str`) -- The answer of the query given the table. If there is an aggregator, the answer will + be preceded by `AGGREGATOR >`. + - **coordinates** (`List[Tuple[int, int]]`) -- Coordinates of the cells of the answers. + - **cells** (`List[str]`) -- List of strings made up of the answer cell values. + - **aggregator** (`str`) -- If the model has an aggregator, this returns the aggregator. + """ + pipeline_inputs = self._args_parser(*args, **kwargs) + + results = super().__call__(pipeline_inputs, **kwargs) + if len(results) == 1: + return results[0] + return results + + def _sanitize_parameters(self, sequential=None, padding=None, truncation=None, **kwargs): + preprocess_params = {} + if padding is not None: + preprocess_params["padding"] = padding + if truncation is not None: + preprocess_params["truncation"] = truncation + + forward_params = {} + if sequential is not None: + forward_params["sequential"] = sequential + return preprocess_params, forward_params, {} + + def preprocess(self, pipeline_input, sequential=None, padding=True, truncation=None): + if truncation is None: + if self.type == "tapas": + truncation = "drop_rows_to_fit" + else: + truncation = "do_not_truncate" + + table, query = pipeline_input["table"], pipeline_input["query"] + if table.empty: + raise ValueError("table is empty") + if query is None or query == "": + raise ValueError("query is empty") + inputs = self.tokenizer(table, query, return_tensors=self.framework, truncation=truncation, padding=padding) + inputs["table"] = table + return inputs + + def _forward(self, model_inputs, sequential=False): + table = model_inputs.pop("table") + + if self.type == "tapas": + if sequential: + outputs = self.sequential_inference(**model_inputs) + else: + outputs = self.batch_inference(**model_inputs) + else: + outputs = self.model.generate(**model_inputs) + model_outputs = {"model_inputs": model_inputs, "table": table, "outputs": outputs} + return model_outputs + + def postprocess(self, model_outputs): + inputs = model_outputs["model_inputs"] + table = model_outputs["table"] + outputs = model_outputs["outputs"] + if self.type == "tapas": + if self.aggregate: + logits, logits_agg = outputs[:2] + predictions = self.tokenizer.convert_logits_to_predictions(inputs, logits, logits_agg) + answer_coordinates_batch, agg_predictions = predictions + aggregators = {i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(agg_predictions)} + + no_agg_label_index = self.model.config.no_aggregation_label_index + aggregators_prefix = { + i: aggregators[i] + " > " for i, pred in enumerate(agg_predictions) if pred != no_agg_label_index + } + else: + logits = outputs[0] + predictions = self.tokenizer.convert_logits_to_predictions(inputs, logits) + answer_coordinates_batch = predictions[0] + aggregators = {} + aggregators_prefix = {} + answers = [] + for index, coordinates in enumerate(answer_coordinates_batch): + cells = [table.iat[coordinate] for coordinate in coordinates] + aggregator = aggregators.get(index, "") + aggregator_prefix = aggregators_prefix.get(index, "") + answer = { + "answer": aggregator_prefix + ", ".join(cells), + "coordinates": coordinates, + "cells": [table.iat[coordinate] for coordinate in coordinates], + } + if aggregator: + answer["aggregator"] = aggregator + + answers.append(answer) + if len(answer) == 0: + raise PipelineException("Empty answer") + else: + answers = [{"answer": answer} for answer in self.tokenizer.batch_decode(outputs, skip_special_tokens=True)] + + return answers if len(answers) > 1 else answers[0] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text2text_generation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text2text_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..48df10336a655f2c7fbeb8d2ebfb3be83ae8f5c6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text2text_generation.py @@ -0,0 +1,367 @@ +import enum +import warnings + +from ..tokenization_utils import TruncationStrategy +from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_tf_available(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + +logger = logging.get_logger(__name__) + + +class ReturnType(enum.Enum): + TENSORS = 0 + TEXT = 1 + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class Text2TextGenerationPipeline(Pipeline): + """ + Pipeline for text to text generation using seq2seq models. + + Example: + + ```python + >>> from transformers import pipeline + + >>> generator = pipeline(model="mrm8488/t5-base-finetuned-question-generation-ap") + >>> generator( + ... "answer: Manuel context: Manuel has created RuPERTa-base with the support of HF-Transformers and Google" + ... ) + [{'generated_text': 'question: Who created the RuPERTa-base?'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + + This Text2TextGenerationPipeline pipeline can currently be loaded from [`pipeline`] using the following task + identifier: `"text2text-generation"`. + + The models that this pipeline can use are models that have been fine-tuned on a translation task. See the + up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=text2text-generation). For a list of available + parameters, see the [following + documentation](https://huggingface.co/docs/transformers/en/main_classes/text_generation#transformers.generation.GenerationMixin.generate) + + Usage: + + ```python + text2text_generator = pipeline("text2text-generation") + text2text_generator("question: What is 42 ? context: 42 is the answer to life, the universe and everything") + ```""" + + # Used in the return key of the pipeline. + return_name = "generated" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.check_model_type( + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + if self.framework == "tf" + else MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING + ) + + def _sanitize_parameters( + self, + return_tensors=None, + return_text=None, + return_type=None, + clean_up_tokenization_spaces=None, + truncation=None, + stop_sequence=None, + **generate_kwargs, + ): + preprocess_params = {} + if truncation is not None: + preprocess_params["truncation"] = truncation + + forward_params = generate_kwargs + + postprocess_params = {} + if return_tensors is not None and return_type is None: + return_type = ReturnType.TENSORS if return_tensors else ReturnType.TEXT + if return_type is not None: + postprocess_params["return_type"] = return_type + + if clean_up_tokenization_spaces is not None: + postprocess_params["clean_up_tokenization_spaces"] = clean_up_tokenization_spaces + + if stop_sequence is not None: + stop_sequence_ids = self.tokenizer.encode(stop_sequence, add_special_tokens=False) + if len(stop_sequence_ids) > 1: + warnings.warn( + "Stopping on a multiple token sequence is not yet supported on transformers. The first token of" + " the stop sequence will be used as the stop sequence string in the interim." + ) + generate_kwargs["eos_token_id"] = stop_sequence_ids[0] + + return preprocess_params, forward_params, postprocess_params + + def check_inputs(self, input_length: int, min_length: int, max_length: int): + """ + Checks whether there might be something wrong with given input with regard to the model. + """ + return True + + def _parse_and_tokenize(self, *args, truncation): + prefix = self.model.config.prefix if self.model.config.prefix is not None else "" + if isinstance(args[0], list): + if self.tokenizer.pad_token_id is None: + raise ValueError("Please make sure that the tokenizer has a pad_token_id when using a batch input") + args = ([prefix + arg for arg in args[0]],) + padding = True + + elif isinstance(args[0], str): + args = (prefix + args[0],) + padding = False + else: + raise ValueError( + f" `args[0]`: {args[0]} have the wrong format. The should be either of type `str` or type `list`" + ) + inputs = self.tokenizer(*args, padding=padding, truncation=truncation, return_tensors=self.framework) + # This is produced by tokenizers but is an invalid generate kwargs + if "token_type_ids" in inputs: + del inputs["token_type_ids"] + return inputs + + def __call__(self, *args, **kwargs): + r""" + Generate the output text(s) using text(s) given as inputs. + + Args: + args (`str` or `List[str]`): + Input text for the encoder. + return_tensors (`bool`, *optional*, defaults to `False`): + Whether or not to include the tensors of predictions (as token indices) in the outputs. + return_text (`bool`, *optional*, defaults to `True`): + Whether or not to include the decoded texts in the outputs. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the potential extra spaces in the text output. + truncation (`TruncationStrategy`, *optional*, defaults to `TruncationStrategy.DO_NOT_TRUNCATE`): + The truncation strategy for the tokenization within the pipeline. `TruncationStrategy.DO_NOT_TRUNCATE` + (default) will never truncate, but it is sometimes desirable to truncate the input to fit the model's + max_length instead of throwing an error down the line. + generate_kwargs: + Additional keyword arguments to pass along to the generate method of the model (see the generate method + corresponding to your framework [here](./model#generative-models)). + + Return: + A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: + + - **generated_text** (`str`, present when `return_text=True`) -- The generated text. + - **generated_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + ids of the generated text. + """ + + result = super().__call__(*args, **kwargs) + if ( + isinstance(args[0], list) + and all(isinstance(el, str) for el in args[0]) + and all(len(res) == 1 for res in result) + ): + return [res[0] for res in result] + return result + + def preprocess(self, inputs, truncation=TruncationStrategy.DO_NOT_TRUNCATE, **kwargs): + inputs = self._parse_and_tokenize(inputs, truncation=truncation, **kwargs) + return inputs + + def _forward(self, model_inputs, **generate_kwargs): + if self.framework == "pt": + in_b, input_length = model_inputs["input_ids"].shape + elif self.framework == "tf": + in_b, input_length = tf.shape(model_inputs["input_ids"]).numpy() + + generate_kwargs["min_length"] = generate_kwargs.get("min_length", self.model.config.min_length) + generate_kwargs["max_length"] = generate_kwargs.get("max_length", self.model.config.max_length) + self.check_inputs(input_length, generate_kwargs["min_length"], generate_kwargs["max_length"]) + output_ids = self.model.generate(**model_inputs, **generate_kwargs) + out_b = output_ids.shape[0] + if self.framework == "pt": + output_ids = output_ids.reshape(in_b, out_b // in_b, *output_ids.shape[1:]) + elif self.framework == "tf": + output_ids = tf.reshape(output_ids, (in_b, out_b // in_b, *output_ids.shape[1:])) + return {"output_ids": output_ids} + + def postprocess(self, model_outputs, return_type=ReturnType.TEXT, clean_up_tokenization_spaces=False): + records = [] + for output_ids in model_outputs["output_ids"][0]: + if return_type == ReturnType.TENSORS: + record = {f"{self.return_name}_token_ids": output_ids} + elif return_type == ReturnType.TEXT: + record = { + f"{self.return_name}_text": self.tokenizer.decode( + output_ids, + skip_special_tokens=True, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + ) + } + records.append(record) + return records + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class SummarizationPipeline(Text2TextGenerationPipeline): + """ + Summarize news articles and other documents. + + This summarizing pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"summarization"`. + + The models that this pipeline can use are models that have been fine-tuned on a summarization task, which is + currently, '*bart-large-cnn*', '*t5-small*', '*t5-base*', '*t5-large*', '*t5-3b*', '*t5-11b*'. See the up-to-date + list of available models on [huggingface.co/models](https://huggingface.co/models?filter=summarization). For a list + of available parameters, see the [following + documentation](https://huggingface.co/docs/transformers/en/main_classes/text_generation#transformers.generation.GenerationMixin.generate) + + Usage: + + ```python + # use bart in pytorch + summarizer = pipeline("summarization") + summarizer("An apple a day, keeps the doctor away", min_length=5, max_length=20) + + # use t5 in tf + summarizer = pipeline("summarization", model="t5-base", tokenizer="t5-base", framework="tf") + summarizer("An apple a day, keeps the doctor away", min_length=5, max_length=20) + ```""" + + # Used in the return key of the pipeline. + return_name = "summary" + + def __call__(self, *args, **kwargs): + r""" + Summarize the text(s) given as inputs. + + Args: + documents (*str* or `List[str]`): + One or several articles (or one list of articles) to summarize. + return_text (`bool`, *optional*, defaults to `True`): + Whether or not to include the decoded texts in the outputs + return_tensors (`bool`, *optional*, defaults to `False`): + Whether or not to include the tensors of predictions (as token indices) in the outputs. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the potential extra spaces in the text output. + generate_kwargs: + Additional keyword arguments to pass along to the generate method of the model (see the generate method + corresponding to your framework [here](./model#generative-models)). + + Return: + A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: + + - **summary_text** (`str`, present when `return_text=True`) -- The summary of the corresponding input. + - **summary_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + ids of the summary. + """ + return super().__call__(*args, **kwargs) + + def check_inputs(self, input_length: int, min_length: int, max_length: int) -> bool: + """ + Checks whether there might be something wrong with given input with regard to the model. + """ + if max_length < min_length: + logger.warning(f"Your min_length={min_length} must be inferior than your max_length={max_length}.") + + if input_length < max_length: + logger.warning( + f"Your max_length is set to {max_length}, but your input_length is only {input_length}. Since this is " + "a summarization task, where outputs shorter than the input are typically wanted, you might " + f"consider decreasing max_length manually, e.g. summarizer('...', max_length={input_length//2})" + ) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class TranslationPipeline(Text2TextGenerationPipeline): + """ + Translates from one language to another. + + This translation pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"translation_xx_to_yy"`. + + The models that this pipeline can use are models that have been fine-tuned on a translation task. See the + up-to-date list of available models on [huggingface.co/models](https://huggingface.co/models?filter=translation). + For a list of available parameters, see the [following + documentation](https://huggingface.co/docs/transformers/en/main_classes/text_generation#transformers.generation.GenerationMixin.generate) + + Usage: + + ```python + en_fr_translator = pipeline("translation_en_to_fr") + en_fr_translator("How old are you?") + ```""" + + # Used in the return key of the pipeline. + return_name = "translation" + + def check_inputs(self, input_length: int, min_length: int, max_length: int): + if input_length > 0.9 * max_length: + logger.warning( + f"Your input_length: {input_length} is bigger than 0.9 * max_length: {max_length}. You might consider " + "increasing your max_length manually, e.g. translator('...', max_length=400)" + ) + return True + + def preprocess(self, *args, truncation=TruncationStrategy.DO_NOT_TRUNCATE, src_lang=None, tgt_lang=None): + if getattr(self.tokenizer, "_build_translation_inputs", None): + return self.tokenizer._build_translation_inputs( + *args, return_tensors=self.framework, truncation=truncation, src_lang=src_lang, tgt_lang=tgt_lang + ) + else: + return super()._parse_and_tokenize(*args, truncation=truncation) + + def _sanitize_parameters(self, src_lang=None, tgt_lang=None, **kwargs): + preprocess_params, forward_params, postprocess_params = super()._sanitize_parameters(**kwargs) + if src_lang is not None: + preprocess_params["src_lang"] = src_lang + if tgt_lang is not None: + preprocess_params["tgt_lang"] = tgt_lang + if src_lang is None and tgt_lang is None: + # Backward compatibility, direct arguments use is preferred. + task = kwargs.get("task", self.task) + items = task.split("_") + if task and len(items) == 4: + # translation, XX, to YY + preprocess_params["src_lang"] = items[1] + preprocess_params["tgt_lang"] = items[3] + return preprocess_params, forward_params, postprocess_params + + def __call__(self, *args, **kwargs): + r""" + Translate the text(s) given as inputs. + + Args: + args (`str` or `List[str]`): + Texts to be translated. + return_tensors (`bool`, *optional*, defaults to `False`): + Whether or not to include the tensors of predictions (as token indices) in the outputs. + return_text (`bool`, *optional*, defaults to `True`): + Whether or not to include the decoded texts in the outputs. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the potential extra spaces in the text output. + src_lang (`str`, *optional*): + The language of the input. Might be required for multilingual models. Will not have any effect for + single pair translation models + tgt_lang (`str`, *optional*): + The language of the desired output. Might be required for multilingual models. Will not have any effect + for single pair translation models + generate_kwargs: + Additional keyword arguments to pass along to the generate method of the model (see the generate method + corresponding to your framework [here](./model#generative-models)). + + Return: + A list or a list of list of `dict`: Each result comes as a dictionary with the following keys: + + - **translation_text** (`str`, present when `return_text=True`) -- The translation. + - **translation_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The + token ids of the translation. + """ + return super().__call__(*args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..1c1c7249f49d78eb87ac22849af13d00ed26e99f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_classification.py @@ -0,0 +1,221 @@ +import warnings +from typing import Dict + +import numpy as np + +from ..utils import ExplicitEnum, add_end_docstrings, is_tf_available, is_torch_available +from .base import PIPELINE_INIT_ARGS, GenericTensor, Pipeline + + +if is_tf_available(): + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + + +def sigmoid(_outputs): + return 1.0 / (1.0 + np.exp(-_outputs)) + + +def softmax(_outputs): + maxes = np.max(_outputs, axis=-1, keepdims=True) + shifted_exp = np.exp(_outputs - maxes) + return shifted_exp / shifted_exp.sum(axis=-1, keepdims=True) + + +class ClassificationFunction(ExplicitEnum): + SIGMOID = "sigmoid" + SOFTMAX = "softmax" + NONE = "none" + + +@add_end_docstrings( + PIPELINE_INIT_ARGS, + r""" + return_all_scores (`bool`, *optional*, defaults to `False`): + Whether to return all prediction scores or just the one of the predicted class. + function_to_apply (`str`, *optional*, defaults to `"default"`): + The function to apply to the model outputs in order to retrieve the scores. Accepts four different values: + + - `"default"`: if the model has a single label, will apply the sigmoid function on the output. If the model + has several labels, will apply the softmax function on the output. + - `"sigmoid"`: Applies the sigmoid function on the output. + - `"softmax"`: Applies the softmax function on the output. + - `"none"`: Does not apply any function on the output. + """, +) +class TextClassificationPipeline(Pipeline): + """ + Text classification pipeline using any `ModelForSequenceClassification`. See the [sequence classification + examples](../task_summary#sequence-classification) for more information. + + Example: + + ```python + >>> from transformers import pipeline + + >>> classifier = pipeline(model="distilbert-base-uncased-finetuned-sst-2-english") + >>> classifier("This movie is disgustingly good !") + [{'label': 'POSITIVE', 'score': 1.0}] + + >>> classifier("Director tried too much.") + [{'label': 'NEGATIVE', 'score': 0.996}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This text classification pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"sentiment-analysis"` (for classifying sequences according to positive or negative sentiments). + + If multiple classification labels are available (`model.config.num_labels >= 2`), the pipeline will run a softmax + over the results. If there is a single label, the pipeline will run a sigmoid over the result. + + The models that this pipeline can use are models that have been fine-tuned on a sequence classification task. See + the up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=text-classification). + """ + + return_all_scores = False + function_to_apply = ClassificationFunction.NONE + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.check_model_type( + TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + if self.framework == "tf" + else MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING + ) + + def _sanitize_parameters(self, return_all_scores=None, function_to_apply=None, top_k="", **tokenizer_kwargs): + # Using "" as default argument because we're going to use `top_k=None` in user code to declare + # "No top_k" + preprocess_params = tokenizer_kwargs + + postprocess_params = {} + if hasattr(self.model.config, "return_all_scores") and return_all_scores is None: + return_all_scores = self.model.config.return_all_scores + + if isinstance(top_k, int) or top_k is None: + postprocess_params["top_k"] = top_k + postprocess_params["_legacy"] = False + elif return_all_scores is not None: + warnings.warn( + "`return_all_scores` is now deprecated, if want a similar funcionality use `top_k=None` instead of" + " `return_all_scores=True` or `top_k=1` instead of `return_all_scores=False`.", + UserWarning, + ) + if return_all_scores: + postprocess_params["top_k"] = None + else: + postprocess_params["top_k"] = 1 + + if isinstance(function_to_apply, str): + function_to_apply = ClassificationFunction[function_to_apply.upper()] + + if function_to_apply is not None: + postprocess_params["function_to_apply"] = function_to_apply + return preprocess_params, {}, postprocess_params + + def __call__(self, *args, **kwargs): + """ + Classify the text(s) given as inputs. + + Args: + args (`str` or `List[str]` or `Dict[str]`, or `List[Dict[str]]`): + One or several texts to classify. In order to use text pairs for your classification, you can send a + dictionary containing `{"text", "text_pair"}` keys, or a list of those. + top_k (`int`, *optional*, defaults to `1`): + How many results to return. + function_to_apply (`str`, *optional*, defaults to `"default"`): + The function to apply to the model outputs in order to retrieve the scores. Accepts four different + values: + + If this argument is not specified, then it will apply the following functions according to the number + of labels: + + - If the model has a single label, will apply the sigmoid function on the output. + - If the model has several labels, will apply the softmax function on the output. + + Possible values are: + + - `"sigmoid"`: Applies the sigmoid function on the output. + - `"softmax"`: Applies the softmax function on the output. + - `"none"`: Does not apply any function on the output. + + Return: + A list or a list of list of `dict`: Each result comes as list of dictionaries with the following keys: + + - **label** (`str`) -- The label predicted. + - **score** (`float`) -- The corresponding probability. + + If `top_k` is used, one such dictionary is returned per label. + """ + result = super().__call__(*args, **kwargs) + # TODO try and retrieve it in a nicer way from _sanitize_parameters. + _legacy = "top_k" not in kwargs + if isinstance(args[0], str) and _legacy: + # This pipeline is odd, and return a list when single item is run + return [result] + else: + return result + + def preprocess(self, inputs, **tokenizer_kwargs) -> Dict[str, GenericTensor]: + return_tensors = self.framework + if isinstance(inputs, dict): + return self.tokenizer(**inputs, return_tensors=return_tensors, **tokenizer_kwargs) + elif isinstance(inputs, list) and len(inputs) == 1 and isinstance(inputs[0], list) and len(inputs[0]) == 2: + # It used to be valid to use a list of list of list for text pairs, keeping this path for BC + return self.tokenizer( + text=inputs[0][0], text_pair=inputs[0][1], return_tensors=return_tensors, **tokenizer_kwargs + ) + elif isinstance(inputs, list): + # This is likely an invalid usage of the pipeline attempting to pass text pairs. + raise ValueError( + "The pipeline received invalid inputs, if you are trying to send text pairs, you can try to send a" + ' dictionary `{"text": "My text", "text_pair": "My pair"}` in order to send a text pair.' + ) + return self.tokenizer(inputs, return_tensors=return_tensors, **tokenizer_kwargs) + + def _forward(self, model_inputs): + return self.model(**model_inputs) + + def postprocess(self, model_outputs, function_to_apply=None, top_k=1, _legacy=True): + # `_legacy` is used to determine if we're running the naked pipeline and in backward + # compatibility mode, or if running the pipeline with `pipeline(..., top_k=1)` we're running + # the more natural result containing the list. + # Default value before `set_parameters` + if function_to_apply is None: + if self.model.config.problem_type == "multi_label_classification" or self.model.config.num_labels == 1: + function_to_apply = ClassificationFunction.SIGMOID + elif self.model.config.problem_type == "single_label_classification" or self.model.config.num_labels > 1: + function_to_apply = ClassificationFunction.SOFTMAX + elif hasattr(self.model.config, "function_to_apply") and function_to_apply is None: + function_to_apply = self.model.config.function_to_apply + else: + function_to_apply = ClassificationFunction.NONE + + outputs = model_outputs["logits"][0] + outputs = outputs.numpy() + + if function_to_apply == ClassificationFunction.SIGMOID: + scores = sigmoid(outputs) + elif function_to_apply == ClassificationFunction.SOFTMAX: + scores = softmax(outputs) + elif function_to_apply == ClassificationFunction.NONE: + scores = outputs + else: + raise ValueError(f"Unrecognized `function_to_apply` argument: {function_to_apply}") + + if top_k == 1 and _legacy: + return {"label": self.model.config.id2label[scores.argmax().item()], "score": scores.max().item()} + + dict_scores = [ + {"label": self.model.config.id2label[i], "score": score.item()} for i, score in enumerate(scores) + ] + if not _legacy: + dict_scores.sort(key=lambda x: x["score"], reverse=True) + if top_k is not None: + dict_scores = dict_scores[:top_k] + return dict_scores diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_generation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..60037339072db971185325dc7a0b5668d84f933f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/text_generation.py @@ -0,0 +1,308 @@ +import copy +import enum +import warnings + +from .. import MODEL_FOR_CAUSAL_LM_MAPPING, TF_MODEL_FOR_CAUSAL_LM_MAPPING +from ..utils import add_end_docstrings, is_tf_available +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_tf_available(): + import tensorflow as tf + + +class ReturnType(enum.Enum): + TENSORS = 0 + NEW_TEXT = 1 + FULL_TEXT = 2 + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class TextGenerationPipeline(Pipeline): + """ + Language generation pipeline using any `ModelWithLMHead`. This pipeline predicts the words that will follow a + specified text prompt. + + Example: + + ```python + >>> from transformers import pipeline + + >>> generator = pipeline(model="gpt2") + >>> generator("I can't believe you did such a ", do_sample=False) + [{'generated_text': "I can't believe you did such a icky thing to me. I'm so sorry. I'm so sorry. I'm so sorry. I'm so sorry. I'm so sorry. I'm so sorry. I'm so sorry. I"}] + + >>> # These parameters will return suggestions, and only the newly created text making it easier for prompting suggestions. + >>> outputs = generator("My tart needs some", num_return_sequences=4, return_full_text=False) + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This language generation pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"text-generation"`. + + The models that this pipeline can use are models that have been trained with an autoregressive language modeling + objective, which includes the uni-directional models in the library (e.g. gpt2). See the list of available models + on [huggingface.co/models](https://huggingface.co/models?filter=text-generation). + """ + + # Prefix text to help Transformer-XL and XLNet with short prompts as proposed by Aman Rusia + # in https://github.com/rusiaaman/XLNet-gen#methodology + # and https://medium.com/@amanrusia/xlnet-speaks-comparison-to-gpt-2-ea1a4e9ba39e + + XL_PREFIX = """ + In 1991, the remains of Russian Tsar Nicholas II and his family (except for Alexei and Maria) are discovered. The + voice of Nicholas's young son, Tsarevich Alexei Nikolaevich, narrates the remainder of the story. 1883 Western + Siberia, a young Grigori Rasputin is asked by his father and a group of men to perform magic. Rasputin has a vision + and denounces one of the men as a horse thief. Although his father initially slaps him for making such an + accusation, Rasputin watches as the man is chased outside and beaten. Twenty years later, Rasputin sees a vision of + the Virgin Mary, prompting him to become a priest. Rasputin quickly becomes famous, with people, even a bishop, + begging for his blessing. + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.check_model_type( + TF_MODEL_FOR_CAUSAL_LM_MAPPING if self.framework == "tf" else MODEL_FOR_CAUSAL_LM_MAPPING + ) + if "prefix" not in self._preprocess_params: + # This is very specific. The logic is quite complex and needs to be done + # as a "default". + # It also defines both some preprocess_kwargs and generate_kwargs + # which is why we cannot put them in their respective methods. + prefix = None + if self.model.config.prefix is not None: + prefix = self.model.config.prefix + if prefix is None and self.model.__class__.__name__ in [ + "XLNetLMHeadModel", + "TransfoXLLMHeadModel", + "TFXLNetLMHeadModel", + "TFTransfoXLLMHeadModel", + ]: + # For XLNet and TransformerXL we add an article to the prompt to give more state to the model. + prefix = self.XL_PREFIX + if prefix is not None: + # Recalculate some generate_kwargs linked to prefix. + preprocess_params, forward_params, _ = self._sanitize_parameters(prefix=prefix, **self._forward_params) + self._preprocess_params = {**self._preprocess_params, **preprocess_params} + self._forward_params = {**self._forward_params, **forward_params} + + def _sanitize_parameters( + self, + return_full_text=None, + return_tensors=None, + return_text=None, + return_type=None, + clean_up_tokenization_spaces=None, + prefix=None, + handle_long_generation=None, + stop_sequence=None, + **generate_kwargs, + ): + preprocess_params = {} + if prefix is not None: + preprocess_params["prefix"] = prefix + if prefix: + prefix_inputs = self.tokenizer( + prefix, padding=False, add_special_tokens=False, return_tensors=self.framework + ) + generate_kwargs["prefix_length"] = prefix_inputs["input_ids"].shape[-1] + + if handle_long_generation is not None: + if handle_long_generation not in {"hole"}: + raise ValueError( + f"{handle_long_generation} is not a valid value for `handle_long_generation` parameter expected" + " [None, 'hole']" + ) + preprocess_params["handle_long_generation"] = handle_long_generation + + preprocess_params.update(generate_kwargs) + forward_params = generate_kwargs + + postprocess_params = {} + if return_full_text is not None and return_type is None: + if return_text is not None: + raise ValueError("`return_text` is mutually exclusive with `return_full_text`") + if return_tensors is not None: + raise ValueError("`return_full_text` is mutually exclusive with `return_tensors`") + return_type = ReturnType.FULL_TEXT if return_full_text else ReturnType.NEW_TEXT + if return_tensors is not None and return_type is None: + if return_text is not None: + raise ValueError("`return_text` is mutually exclusive with `return_tensors`") + return_type = ReturnType.TENSORS + if return_type is not None: + postprocess_params["return_type"] = return_type + if clean_up_tokenization_spaces is not None: + postprocess_params["clean_up_tokenization_spaces"] = clean_up_tokenization_spaces + + if stop_sequence is not None: + stop_sequence_ids = self.tokenizer.encode(stop_sequence, add_special_tokens=False) + if len(stop_sequence_ids) > 1: + warnings.warn( + "Stopping on a multiple token sequence is not yet supported on transformers. The first token of" + " the stop sequence will be used as the stop sequence string in the interim." + ) + generate_kwargs["eos_token_id"] = stop_sequence_ids[0] + + return preprocess_params, forward_params, postprocess_params + + # overriding _parse_and_tokenize to allow for unusual language-modeling tokenizer arguments + def _parse_and_tokenize(self, *args, **kwargs): + """ + Parse arguments and tokenize + """ + # Parse arguments + if self.model.__class__.__name__ in ["TransfoXLLMHeadModel"]: + kwargs.update({"add_space_before_punct_symbol": True}) + + return super()._parse_and_tokenize(*args, **kwargs) + + def __call__(self, text_inputs, **kwargs): + """ + Complete the prompt(s) given as inputs. + + Args: + args (`str` or `List[str]`): + One or several prompts (or one list of prompts) to complete. + return_tensors (`bool`, *optional*, defaults to `False`): + Whether or not to return the tensors of predictions (as token indices) in the outputs. If set to + `True`, the decoded text is not returned. + return_text (`bool`, *optional*, defaults to `True`): + Whether or not to return the decoded texts in the outputs. + return_full_text (`bool`, *optional*, defaults to `True`): + If set to `False` only added text is returned, otherwise the full text is returned. Only meaningful if + *return_text* is set to True. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the potential extra spaces in the text output. + prefix (`str`, *optional*): + Prefix added to prompt. + handle_long_generation (`str`, *optional*): + By default, this pipelines does not handle long generation (ones that exceed in one form or the other + the model maximum length). There is no perfect way to adress this (more info + :https://github.com/huggingface/transformers/issues/14033#issuecomment-948385227). This provides common + strategies to work around that problem depending on your use case. + + - `None` : default strategy where nothing in particular happens + - `"hole"`: Truncates left of input, and leaves a gap wide enough to let generation happen (might + truncate a lot of the prompt and not suitable when generation exceed the model capacity) + + generate_kwargs: + Additional keyword arguments to pass along to the generate method of the model (see the generate method + corresponding to your framework [here](./model#generative-models)). + + Return: + A list or a list of list of `dict`: Returns one of the following dictionaries (cannot return a combination + of both `generated_text` and `generated_token_ids`): + + - **generated_text** (`str`, present when `return_text=True`) -- The generated text. + - **generated_token_ids** (`torch.Tensor` or `tf.Tensor`, present when `return_tensors=True`) -- The token + ids of the generated text. + """ + return super().__call__(text_inputs, **kwargs) + + def preprocess(self, prompt_text, prefix="", handle_long_generation=None, **generate_kwargs): + inputs = self.tokenizer( + prefix + prompt_text, padding=False, add_special_tokens=False, return_tensors=self.framework + ) + inputs["prompt_text"] = prompt_text + + if handle_long_generation == "hole": + cur_len = inputs["input_ids"].shape[-1] + if "max_new_tokens" in generate_kwargs: + new_tokens = generate_kwargs["max_new_tokens"] + else: + new_tokens = generate_kwargs.get("max_length", self.model.config.max_length) - cur_len + if new_tokens < 0: + raise ValueError("We cannot infer how many new tokens are expected") + if cur_len + new_tokens > self.tokenizer.model_max_length: + keep_length = self.tokenizer.model_max_length - new_tokens + if keep_length <= 0: + raise ValueError( + "We cannot use `hole` to handle this generation the number of desired tokens exceeds the" + " models max length" + ) + + inputs["input_ids"] = inputs["input_ids"][:, -keep_length:] + if "attention_mask" in inputs: + inputs["attention_mask"] = inputs["attention_mask"][:, -keep_length:] + + return inputs + + def _forward(self, model_inputs, **generate_kwargs): + input_ids = model_inputs["input_ids"] + attention_mask = model_inputs.get("attention_mask", None) + # Allow empty prompts + if input_ids.shape[1] == 0: + input_ids = None + attention_mask = None + in_b = 1 + else: + in_b = input_ids.shape[0] + prompt_text = model_inputs.pop("prompt_text") + + # If there is a prefix, we may need to adjust the generation length. Do so without permanently modifying + # generate_kwargs, as some of the parameterization may come from the initialization of the pipeline. + generate_kwargs = copy.deepcopy(generate_kwargs) + prefix_length = generate_kwargs.pop("prefix_length", 0) + if prefix_length > 0: + has_max_new_tokens = "max_new_tokens" in generate_kwargs or ( + "generation_config" in generate_kwargs + and generate_kwargs["generation_config"].max_new_tokens is not None + ) + if not has_max_new_tokens: + generate_kwargs["max_length"] = generate_kwargs.get("max_length") or self.model.config.max_length + generate_kwargs["max_length"] += prefix_length + has_min_new_tokens = "min_new_tokens" in generate_kwargs or ( + "generation_config" in generate_kwargs + and generate_kwargs["generation_config"].min_new_tokens is not None + ) + if not has_min_new_tokens and "min_length" in generate_kwargs: + generate_kwargs["min_length"] += prefix_length + + # BS x SL + generated_sequence = self.model.generate(input_ids=input_ids, attention_mask=attention_mask, **generate_kwargs) + out_b = generated_sequence.shape[0] + if self.framework == "pt": + generated_sequence = generated_sequence.reshape(in_b, out_b // in_b, *generated_sequence.shape[1:]) + elif self.framework == "tf": + generated_sequence = tf.reshape(generated_sequence, (in_b, out_b // in_b, *generated_sequence.shape[1:])) + return {"generated_sequence": generated_sequence, "input_ids": input_ids, "prompt_text": prompt_text} + + def postprocess(self, model_outputs, return_type=ReturnType.FULL_TEXT, clean_up_tokenization_spaces=True): + generated_sequence = model_outputs["generated_sequence"][0] + input_ids = model_outputs["input_ids"] + prompt_text = model_outputs["prompt_text"] + generated_sequence = generated_sequence.numpy().tolist() + records = [] + for sequence in generated_sequence: + if return_type == ReturnType.TENSORS: + record = {"generated_token_ids": sequence} + elif return_type in {ReturnType.NEW_TEXT, ReturnType.FULL_TEXT}: + # Decode text + text = self.tokenizer.decode( + sequence, + skip_special_tokens=True, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + ) + + # Remove PADDING prompt of the sequence if XLNet or Transfo-XL model is used + if input_ids is None: + prompt_length = 0 + else: + prompt_length = len( + self.tokenizer.decode( + input_ids[0], + skip_special_tokens=True, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + ) + ) + + if return_type == ReturnType.FULL_TEXT: + all_text = prompt_text + text[prompt_length:] + else: + all_text = text[prompt_length:] + + record = {"generated_text": all_text} + records.append(record) + + return records diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/token_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/token_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..7698b37f31df8de1a6a765e1507d53d23d569f4b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/token_classification.py @@ -0,0 +1,570 @@ +import types +import warnings +from typing import List, Optional, Tuple, Union + +import numpy as np + +from ..models.bert.tokenization_bert import BasicTokenizer +from ..utils import ( + ExplicitEnum, + add_end_docstrings, + is_tf_available, + is_torch_available, +) +from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline, Dataset + + +if is_tf_available(): + import tensorflow as tf + + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + + +class TokenClassificationArgumentHandler(ArgumentHandler): + """ + Handles arguments for token classification. + """ + + def __call__(self, inputs: Union[str, List[str]], **kwargs): + if inputs is not None and isinstance(inputs, (list, tuple)) and len(inputs) > 0: + inputs = list(inputs) + batch_size = len(inputs) + elif isinstance(inputs, str): + inputs = [inputs] + batch_size = 1 + elif Dataset is not None and isinstance(inputs, Dataset) or isinstance(inputs, types.GeneratorType): + return inputs, None + else: + raise ValueError("At least one input is required.") + + offset_mapping = kwargs.get("offset_mapping") + if offset_mapping: + if isinstance(offset_mapping, list) and isinstance(offset_mapping[0], tuple): + offset_mapping = [offset_mapping] + if len(offset_mapping) != batch_size: + raise ValueError("offset_mapping should have the same batch size as the input") + return inputs, offset_mapping + + +class AggregationStrategy(ExplicitEnum): + """All the valid aggregation strategies for TokenClassificationPipeline""" + + NONE = "none" + SIMPLE = "simple" + FIRST = "first" + AVERAGE = "average" + MAX = "max" + + +@add_end_docstrings( + PIPELINE_INIT_ARGS, + r""" + ignore_labels (`List[str]`, defaults to `["O"]`): + A list of labels to ignore. + grouped_entities (`bool`, *optional*, defaults to `False`): + DEPRECATED, use `aggregation_strategy` instead. Whether or not to group the tokens corresponding to the + same entity together in the predictions or not. + stride (`int`, *optional*): + If stride is provided, the pipeline is applied on all the text. The text is split into chunks of size + model_max_length. Works only with fast tokenizers and `aggregation_strategy` different from `NONE`. The + value of this argument defines the number of overlapping tokens between chunks. In other words, the model + will shift forward by `tokenizer.model_max_length - stride` tokens each step. + aggregation_strategy (`str`, *optional*, defaults to `"none"`): + The strategy to fuse (or not) tokens based on the model prediction. + + - "none" : Will simply not do any aggregation and simply return raw results from the model + - "simple" : Will attempt to group entities following the default schema. (A, B-TAG), (B, I-TAG), (C, + I-TAG), (D, B-TAG2) (E, B-TAG2) will end up being [{"word": ABC, "entity": "TAG"}, {"word": "D", + "entity": "TAG2"}, {"word": "E", "entity": "TAG2"}] Notice that two consecutive B tags will end up as + different entities. On word based languages, we might end up splitting words undesirably : Imagine + Microsoft being tagged as [{"word": "Micro", "entity": "ENTERPRISE"}, {"word": "soft", "entity": + "NAME"}]. Look for FIRST, MAX, AVERAGE for ways to mitigate that and disambiguate words (on languages + that support that meaning, which is basically tokens separated by a space). These mitigations will + only work on real words, "New york" might still be tagged with two different entities. + - "first" : (works only on word based models) Will use the `SIMPLE` strategy except that words, cannot + end up with different tags. Words will simply use the tag of the first token of the word when there + is ambiguity. + - "average" : (works only on word based models) Will use the `SIMPLE` strategy except that words, + cannot end up with different tags. scores will be averaged first across tokens, and then the maximum + label is applied. + - "max" : (works only on word based models) Will use the `SIMPLE` strategy except that words, cannot + end up with different tags. Word entity will simply be the token with the maximum score. + """, +) +class TokenClassificationPipeline(ChunkPipeline): + """ + Named Entity Recognition pipeline using any `ModelForTokenClassification`. See the [named entity recognition + examples](../task_summary#named-entity-recognition) for more information. + + Example: + + ```python + >>> from transformers import pipeline + + >>> token_classifier = pipeline(model="Jean-Baptiste/camembert-ner", aggregation_strategy="simple") + >>> sentence = "Je m'appelle jean-baptiste et je vis à montréal" + >>> tokens = token_classifier(sentence) + >>> tokens + [{'entity_group': 'PER', 'score': 0.9931, 'word': 'jean-baptiste', 'start': 12, 'end': 26}, {'entity_group': 'LOC', 'score': 0.998, 'word': 'montréal', 'start': 38, 'end': 47}] + + >>> token = tokens[0] + >>> # Start and end provide an easy way to highlight words in the original text. + >>> sentence[token["start"] : token["end"]] + ' jean-baptiste' + + >>> # Some models use the same idea to do part of speech. + >>> syntaxer = pipeline(model="vblagoje/bert-english-uncased-finetuned-pos", aggregation_strategy="simple") + >>> syntaxer("My name is Sarah and I live in London") + [{'entity_group': 'PRON', 'score': 0.999, 'word': 'my', 'start': 0, 'end': 2}, {'entity_group': 'NOUN', 'score': 0.997, 'word': 'name', 'start': 3, 'end': 7}, {'entity_group': 'AUX', 'score': 0.994, 'word': 'is', 'start': 8, 'end': 10}, {'entity_group': 'PROPN', 'score': 0.999, 'word': 'sarah', 'start': 11, 'end': 16}, {'entity_group': 'CCONJ', 'score': 0.999, 'word': 'and', 'start': 17, 'end': 20}, {'entity_group': 'PRON', 'score': 0.999, 'word': 'i', 'start': 21, 'end': 22}, {'entity_group': 'VERB', 'score': 0.998, 'word': 'live', 'start': 23, 'end': 27}, {'entity_group': 'ADP', 'score': 0.999, 'word': 'in', 'start': 28, 'end': 30}, {'entity_group': 'PROPN', 'score': 0.999, 'word': 'london', 'start': 31, 'end': 37}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This token recognition pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"ner"` (for predicting the classes of tokens in a sequence: person, organisation, location or miscellaneous). + + The models that this pipeline can use are models that have been fine-tuned on a token classification task. See the + up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=token-classification). + """ + + default_input_names = "sequences" + + def __init__(self, args_parser=TokenClassificationArgumentHandler(), *args, **kwargs): + super().__init__(*args, **kwargs) + self.check_model_type( + TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + if self.framework == "tf" + else MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING + ) + + self._basic_tokenizer = BasicTokenizer(do_lower_case=False) + self._args_parser = args_parser + + def _sanitize_parameters( + self, + ignore_labels=None, + grouped_entities: Optional[bool] = None, + ignore_subwords: Optional[bool] = None, + aggregation_strategy: Optional[AggregationStrategy] = None, + offset_mapping: Optional[List[Tuple[int, int]]] = None, + stride: Optional[int] = None, + ): + preprocess_params = {} + if offset_mapping is not None: + preprocess_params["offset_mapping"] = offset_mapping + + postprocess_params = {} + if grouped_entities is not None or ignore_subwords is not None: + if grouped_entities and ignore_subwords: + aggregation_strategy = AggregationStrategy.FIRST + elif grouped_entities and not ignore_subwords: + aggregation_strategy = AggregationStrategy.SIMPLE + else: + aggregation_strategy = AggregationStrategy.NONE + + if grouped_entities is not None: + warnings.warn( + "`grouped_entities` is deprecated and will be removed in version v5.0.0, defaulted to" + f' `aggregation_strategy="{aggregation_strategy}"` instead.' + ) + if ignore_subwords is not None: + warnings.warn( + "`ignore_subwords` is deprecated and will be removed in version v5.0.0, defaulted to" + f' `aggregation_strategy="{aggregation_strategy}"` instead.' + ) + + if aggregation_strategy is not None: + if isinstance(aggregation_strategy, str): + aggregation_strategy = AggregationStrategy[aggregation_strategy.upper()] + if ( + aggregation_strategy + in {AggregationStrategy.FIRST, AggregationStrategy.MAX, AggregationStrategy.AVERAGE} + and not self.tokenizer.is_fast + ): + raise ValueError( + "Slow tokenizers cannot handle subwords. Please set the `aggregation_strategy` option" + ' to `"simple"` or use a fast tokenizer.' + ) + postprocess_params["aggregation_strategy"] = aggregation_strategy + if ignore_labels is not None: + postprocess_params["ignore_labels"] = ignore_labels + if stride is not None: + if stride >= self.tokenizer.model_max_length: + raise ValueError( + "`stride` must be less than `tokenizer.model_max_length` (or even lower if the tokenizer adds special tokens)" + ) + if aggregation_strategy == AggregationStrategy.NONE: + raise ValueError( + "`stride` was provided to process all the text but `aggregation_strategy=" + f'"{aggregation_strategy}"`, please select another one instead.' + ) + else: + if self.tokenizer.is_fast: + tokenizer_params = { + "return_overflowing_tokens": True, + "padding": True, + "stride": stride, + } + preprocess_params["tokenizer_params"] = tokenizer_params + else: + raise ValueError( + "`stride` was provided to process all the text but you're using a slow tokenizer." + " Please use a fast tokenizer." + ) + return preprocess_params, {}, postprocess_params + + def __call__(self, inputs: Union[str, List[str]], **kwargs): + """ + Classify each token of the text(s) given as inputs. + + Args: + inputs (`str` or `List[str]`): + One or several texts (or one list of texts) for token classification. + + Return: + A list or a list of list of `dict`: Each result comes as a list of dictionaries (one for each token in the + corresponding input, or each entity if this pipeline was instantiated with an aggregation_strategy) with + the following keys: + + - **word** (`str`) -- The token/word classified. This is obtained by decoding the selected tokens. If you + want to have the exact string in the original sentence, use `start` and `end`. + - **score** (`float`) -- The corresponding probability for `entity`. + - **entity** (`str`) -- The entity predicted for that token/word (it is named *entity_group* when + *aggregation_strategy* is not `"none"`. + - **index** (`int`, only present when `aggregation_strategy="none"`) -- The index of the corresponding + token in the sentence. + - **start** (`int`, *optional*) -- The index of the start of the corresponding entity in the sentence. Only + exists if the offsets are available within the tokenizer + - **end** (`int`, *optional*) -- The index of the end of the corresponding entity in the sentence. Only + exists if the offsets are available within the tokenizer + """ + + _inputs, offset_mapping = self._args_parser(inputs, **kwargs) + if offset_mapping: + kwargs["offset_mapping"] = offset_mapping + + return super().__call__(inputs, **kwargs) + + def preprocess(self, sentence, offset_mapping=None, **preprocess_params): + tokenizer_params = preprocess_params.pop("tokenizer_params", {}) + truncation = True if self.tokenizer.model_max_length and self.tokenizer.model_max_length > 0 else False + inputs = self.tokenizer( + sentence, + return_tensors=self.framework, + truncation=truncation, + return_special_tokens_mask=True, + return_offsets_mapping=self.tokenizer.is_fast, + **tokenizer_params, + ) + inputs.pop("overflow_to_sample_mapping", None) + num_chunks = len(inputs["input_ids"]) + + for i in range(num_chunks): + if self.framework == "tf": + model_inputs = {k: tf.expand_dims(v[i], 0) for k, v in inputs.items()} + else: + model_inputs = {k: v[i].unsqueeze(0) for k, v in inputs.items()} + if offset_mapping is not None: + model_inputs["offset_mapping"] = offset_mapping + model_inputs["sentence"] = sentence if i == 0 else None + model_inputs["is_last"] = i == num_chunks - 1 + + yield model_inputs + + def _forward(self, model_inputs): + # Forward + special_tokens_mask = model_inputs.pop("special_tokens_mask") + offset_mapping = model_inputs.pop("offset_mapping", None) + sentence = model_inputs.pop("sentence") + is_last = model_inputs.pop("is_last") + if self.framework == "tf": + logits = self.model(**model_inputs)[0] + else: + output = self.model(**model_inputs) + logits = output["logits"] if isinstance(output, dict) else output[0] + + return { + "logits": logits, + "special_tokens_mask": special_tokens_mask, + "offset_mapping": offset_mapping, + "sentence": sentence, + "is_last": is_last, + **model_inputs, + } + + def postprocess(self, all_outputs, aggregation_strategy=AggregationStrategy.NONE, ignore_labels=None): + if ignore_labels is None: + ignore_labels = ["O"] + all_entities = [] + for model_outputs in all_outputs: + logits = model_outputs["logits"][0].numpy() + sentence = all_outputs[0]["sentence"] + input_ids = model_outputs["input_ids"][0] + offset_mapping = ( + model_outputs["offset_mapping"][0] if model_outputs["offset_mapping"] is not None else None + ) + special_tokens_mask = model_outputs["special_tokens_mask"][0].numpy() + + maxes = np.max(logits, axis=-1, keepdims=True) + shifted_exp = np.exp(logits - maxes) + scores = shifted_exp / shifted_exp.sum(axis=-1, keepdims=True) + + if self.framework == "tf": + input_ids = input_ids.numpy() + offset_mapping = offset_mapping.numpy() if offset_mapping is not None else None + + pre_entities = self.gather_pre_entities( + sentence, input_ids, scores, offset_mapping, special_tokens_mask, aggregation_strategy + ) + grouped_entities = self.aggregate(pre_entities, aggregation_strategy) + # Filter anything that is in self.ignore_labels + entities = [ + entity + for entity in grouped_entities + if entity.get("entity", None) not in ignore_labels + and entity.get("entity_group", None) not in ignore_labels + ] + all_entities.extend(entities) + num_chunks = len(all_outputs) + if num_chunks > 1: + all_entities = self.aggregate_overlapping_entities(all_entities) + return all_entities + + def aggregate_overlapping_entities(self, entities): + if len(entities) == 0: + return entities + entities = sorted(entities, key=lambda x: x["start"]) + aggregated_entities = [] + previous_entity = entities[0] + for entity in entities: + if previous_entity["start"] <= entity["start"] < previous_entity["end"]: + current_length = entity["end"] - entity["start"] + previous_length = previous_entity["end"] - previous_entity["start"] + if current_length > previous_length: + previous_entity = entity + elif current_length == previous_length and entity["score"] > previous_entity["score"]: + previous_entity = entity + else: + aggregated_entities.append(previous_entity) + previous_entity = entity + aggregated_entities.append(previous_entity) + return aggregated_entities + + def gather_pre_entities( + self, + sentence: str, + input_ids: np.ndarray, + scores: np.ndarray, + offset_mapping: Optional[List[Tuple[int, int]]], + special_tokens_mask: np.ndarray, + aggregation_strategy: AggregationStrategy, + ) -> List[dict]: + """Fuse various numpy arrays into dicts with all the information needed for aggregation""" + pre_entities = [] + for idx, token_scores in enumerate(scores): + # Filter special_tokens + if special_tokens_mask[idx]: + continue + + word = self.tokenizer.convert_ids_to_tokens(int(input_ids[idx])) + if offset_mapping is not None: + start_ind, end_ind = offset_mapping[idx] + if not isinstance(start_ind, int): + if self.framework == "pt": + start_ind = start_ind.item() + end_ind = end_ind.item() + word_ref = sentence[start_ind:end_ind] + if getattr(self.tokenizer, "_tokenizer", None) and getattr( + self.tokenizer._tokenizer.model, "continuing_subword_prefix", None + ): + # This is a BPE, word aware tokenizer, there is a correct way + # to fuse tokens + is_subword = len(word) != len(word_ref) + else: + # This is a fallback heuristic. This will fail most likely on any kind of text + punctuation mixtures that will be considered "words". Non word aware models cannot do better than this unfortunately. + if aggregation_strategy in { + AggregationStrategy.FIRST, + AggregationStrategy.AVERAGE, + AggregationStrategy.MAX, + }: + warnings.warn( + "Tokenizer does not support real words, using fallback heuristic", + UserWarning, + ) + is_subword = start_ind > 0 and " " not in sentence[start_ind - 1 : start_ind + 1] + + if int(input_ids[idx]) == self.tokenizer.unk_token_id: + word = word_ref + is_subword = False + else: + start_ind = None + end_ind = None + is_subword = False + + pre_entity = { + "word": word, + "scores": token_scores, + "start": start_ind, + "end": end_ind, + "index": idx, + "is_subword": is_subword, + } + pre_entities.append(pre_entity) + return pre_entities + + def aggregate(self, pre_entities: List[dict], aggregation_strategy: AggregationStrategy) -> List[dict]: + if aggregation_strategy in {AggregationStrategy.NONE, AggregationStrategy.SIMPLE}: + entities = [] + for pre_entity in pre_entities: + entity_idx = pre_entity["scores"].argmax() + score = pre_entity["scores"][entity_idx] + entity = { + "entity": self.model.config.id2label[entity_idx], + "score": score, + "index": pre_entity["index"], + "word": pre_entity["word"], + "start": pre_entity["start"], + "end": pre_entity["end"], + } + entities.append(entity) + else: + entities = self.aggregate_words(pre_entities, aggregation_strategy) + + if aggregation_strategy == AggregationStrategy.NONE: + return entities + return self.group_entities(entities) + + def aggregate_word(self, entities: List[dict], aggregation_strategy: AggregationStrategy) -> dict: + word = self.tokenizer.convert_tokens_to_string([entity["word"] for entity in entities]) + if aggregation_strategy == AggregationStrategy.FIRST: + scores = entities[0]["scores"] + idx = scores.argmax() + score = scores[idx] + entity = self.model.config.id2label[idx] + elif aggregation_strategy == AggregationStrategy.MAX: + max_entity = max(entities, key=lambda entity: entity["scores"].max()) + scores = max_entity["scores"] + idx = scores.argmax() + score = scores[idx] + entity = self.model.config.id2label[idx] + elif aggregation_strategy == AggregationStrategy.AVERAGE: + scores = np.stack([entity["scores"] for entity in entities]) + average_scores = np.nanmean(scores, axis=0) + entity_idx = average_scores.argmax() + entity = self.model.config.id2label[entity_idx] + score = average_scores[entity_idx] + else: + raise ValueError("Invalid aggregation_strategy") + new_entity = { + "entity": entity, + "score": score, + "word": word, + "start": entities[0]["start"], + "end": entities[-1]["end"], + } + return new_entity + + def aggregate_words(self, entities: List[dict], aggregation_strategy: AggregationStrategy) -> List[dict]: + """ + Override tokens from a given word that disagree to force agreement on word boundaries. + + Example: micro|soft| com|pany| B-ENT I-NAME I-ENT I-ENT will be rewritten with first strategy as microsoft| + company| B-ENT I-ENT + """ + if aggregation_strategy in { + AggregationStrategy.NONE, + AggregationStrategy.SIMPLE, + }: + raise ValueError("NONE and SIMPLE strategies are invalid for word aggregation") + + word_entities = [] + word_group = None + for entity in entities: + if word_group is None: + word_group = [entity] + elif entity["is_subword"]: + word_group.append(entity) + else: + word_entities.append(self.aggregate_word(word_group, aggregation_strategy)) + word_group = [entity] + # Last item + word_entities.append(self.aggregate_word(word_group, aggregation_strategy)) + return word_entities + + def group_sub_entities(self, entities: List[dict]) -> dict: + """ + Group together the adjacent tokens with the same entity predicted. + + Args: + entities (`dict`): The entities predicted by the pipeline. + """ + # Get the first entity in the entity group + entity = entities[0]["entity"].split("-")[-1] + scores = np.nanmean([entity["score"] for entity in entities]) + tokens = [entity["word"] for entity in entities] + + entity_group = { + "entity_group": entity, + "score": np.mean(scores), + "word": self.tokenizer.convert_tokens_to_string(tokens), + "start": entities[0]["start"], + "end": entities[-1]["end"], + } + return entity_group + + def get_tag(self, entity_name: str) -> Tuple[str, str]: + if entity_name.startswith("B-"): + bi = "B" + tag = entity_name[2:] + elif entity_name.startswith("I-"): + bi = "I" + tag = entity_name[2:] + else: + # It's not in B-, I- format + # Default to I- for continuation. + bi = "I" + tag = entity_name + return bi, tag + + def group_entities(self, entities: List[dict]) -> List[dict]: + """ + Find and group together the adjacent tokens with the same entity predicted. + + Args: + entities (`dict`): The entities predicted by the pipeline. + """ + + entity_groups = [] + entity_group_disagg = [] + + for entity in entities: + if not entity_group_disagg: + entity_group_disagg.append(entity) + continue + + # If the current entity is similar and adjacent to the previous entity, + # append it to the disaggregated entity group + # The split is meant to account for the "B" and "I" prefixes + # Shouldn't merge if both entities are B-type + bi, tag = self.get_tag(entity["entity"]) + last_bi, last_tag = self.get_tag(entity_group_disagg[-1]["entity"]) + + if tag == last_tag and bi != "B": + # Modify subword type to be previous_type + entity_group_disagg.append(entity) + else: + # If the current entity is different from the previous entity + # aggregate the disaggregated entity group + entity_groups.append(self.group_sub_entities(entity_group_disagg)) + entity_group_disagg = [entity] + if entity_group_disagg: + # it's the last entity, add it to the entity groups + entity_groups.append(self.group_sub_entities(entity_group_disagg)) + + return entity_groups + + +NerPipeline = TokenClassificationPipeline diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/video_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/video_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..41a1699a7e82cfea768005ebecada1e0fe744d1f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/video_classification.py @@ -0,0 +1,122 @@ +from io import BytesIO +from typing import List, Union + +import requests + +from ..utils import add_end_docstrings, is_decord_available, is_torch_available, logging, requires_backends +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_decord_available(): + import numpy as np + from decord import VideoReader + + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class VideoClassificationPipeline(Pipeline): + """ + Video classification pipeline using any `AutoModelForVideoClassification`. This pipeline predicts the class of a + video. + + This video classification pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"video-classification"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=video-classification). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + requires_backends(self, "decord") + self.check_model_type(MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING) + + def _sanitize_parameters(self, top_k=None, num_frames=None, frame_sampling_rate=None): + preprocess_params = {} + if frame_sampling_rate is not None: + preprocess_params["frame_sampling_rate"] = frame_sampling_rate + if num_frames is not None: + preprocess_params["num_frames"] = num_frames + + postprocess_params = {} + if top_k is not None: + postprocess_params["top_k"] = top_k + return preprocess_params, {}, postprocess_params + + def __call__(self, videos: Union[str, List[str]], **kwargs): + """ + Assign labels to the video(s) passed as inputs. + + Args: + videos (`str`, `List[str]`): + The pipeline handles three types of videos: + + - A string containing a http link pointing to a video + - A string containing a local path to a video + + The pipeline accepts either a single video or a batch of videos, which must then be passed as a string. + Videos in a batch must all be in the same format: all as http links or all as local paths. + top_k (`int`, *optional*, defaults to 5): + The number of top labels that will be returned by the pipeline. If the provided number is higher than + the number of labels available in the model configuration, it will default to the number of labels. + num_frames (`int`, *optional*, defaults to `self.model.config.num_frames`): + The number of frames sampled from the video to run the classification on. If not provided, will default + to the number of frames specified in the model configuration. + frame_sampling_rate (`int`, *optional*, defaults to 1): + The sampling rate used to select frames from the video. If not provided, will default to 1, i.e. every + frame will be used. + + Return: + A dictionary or a list of dictionaries containing result. If the input is a single video, will return a + dictionary, if the input is a list of several videos, will return a list of dictionaries corresponding to + the videos. + + The dictionaries contain the following keys: + + - **label** (`str`) -- The label identified by the model. + - **score** (`int`) -- The score attributed by the model for that label. + """ + return super().__call__(videos, **kwargs) + + def preprocess(self, video, num_frames=None, frame_sampling_rate=1): + if num_frames is None: + num_frames = self.model.config.num_frames + + if video.startswith("http://") or video.startswith("https://"): + video = BytesIO(requests.get(video).content) + + videoreader = VideoReader(video) + videoreader.seek(0) + + start_idx = 0 + end_idx = num_frames * frame_sampling_rate - 1 + indices = np.linspace(start_idx, end_idx, num=num_frames, dtype=np.int64) + + video = videoreader.get_batch(indices).asnumpy() + video = list(video) + + model_inputs = self.image_processor(video, return_tensors=self.framework) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs, top_k=5): + if top_k > self.model.config.num_labels: + top_k = self.model.config.num_labels + + if self.framework == "pt": + probs = model_outputs.logits.softmax(-1)[0] + scores, ids = probs.topk(top_k) + else: + raise ValueError(f"Unsupported framework: {self.framework}") + + scores = scores.tolist() + ids = ids.tolist() + return [{"score": score, "label": self.model.config.id2label[_id]} for score, _id in zip(scores, ids)] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/visual_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/visual_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..6d9e1cb3e7d1c99a507a103b3d81d5d21ea6b3a1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/visual_question_answering.py @@ -0,0 +1,137 @@ +from typing import Union + +from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging +from .base import PIPELINE_INIT_ARGS, Pipeline + + +if is_vision_available(): + from PIL import Image + + from ..image_utils import load_image + +if is_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class VisualQuestionAnsweringPipeline(Pipeline): + """ + Visual Question Answering pipeline using a `AutoModelForVisualQuestionAnswering`. This pipeline is currently only + available in PyTorch. + + Example: + + ```python + >>> from transformers import pipeline + + >>> oracle = pipeline(model="dandelin/vilt-b32-finetuned-vqa") + >>> image_url = "https://huggingface.co/datasets/Narsil/image_dummy/raw/main/lena.png" + >>> oracle(question="What is she wearing ?", image=image_url) + [{'score': 0.948, 'answer': 'hat'}, {'score': 0.009, 'answer': 'fedora'}, {'score': 0.003, 'answer': 'clothes'}, {'score': 0.003, 'answer': 'sun hat'}, {'score': 0.002, 'answer': 'nothing'}] + + >>> oracle(question="What is she wearing ?", image=image_url, top_k=1) + [{'score': 0.948, 'answer': 'hat'}] + + >>> oracle(question="Is this a person ?", image=image_url, top_k=1) + [{'score': 0.993, 'answer': 'yes'}] + + >>> oracle(question="Is this a man ?", image=image_url, top_k=1) + [{'score': 0.996, 'answer': 'no'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This visual question answering pipeline can currently be loaded from [`pipeline`] using the following task + identifiers: `"visual-question-answering", "vqa"`. + + The models that this pipeline can use are models that have been fine-tuned on a visual question answering task. See + the up-to-date list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=visual-question-answering). + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.check_model_type(MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING) + + def _sanitize_parameters(self, top_k=None, padding=None, truncation=None, **kwargs): + preprocess_params, postprocess_params = {}, {} + if padding is not None: + preprocess_params["padding"] = padding + if truncation is not None: + preprocess_params["truncation"] = truncation + if top_k is not None: + postprocess_params["top_k"] = top_k + return preprocess_params, {}, postprocess_params + + def __call__(self, image: Union["Image.Image", str], question: str = None, **kwargs): + r""" + Answers open-ended questions about images. The pipeline accepts several types of inputs which are detailed + below: + + - `pipeline(image=image, question=question)` + - `pipeline({"image": image, "question": question})` + - `pipeline([{"image": image, "question": question}])` + - `pipeline([{"image": image, "question": question}, {"image": image, "question": question}])` + + Args: + image (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing a http link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + The pipeline accepts either a single image or a batch of images. If given a single image, it can be + broadcasted to multiple questions. + question (`str`, `List[str]`): + The question(s) asked. If given a single question, it can be broadcasted to multiple images. + top_k (`int`, *optional*, defaults to 5): + The number of top labels that will be returned by the pipeline. If the provided number is higher than + the number of labels available in the model configuration, it will default to the number of labels. + Return: + A dictionary or a list of dictionaries containing the result. The dictionaries contain the following keys: + + - **label** (`str`) -- The label identified by the model. + - **score** (`int`) -- The score attributed by the model for that label. + """ + if isinstance(image, (Image.Image, str)) and isinstance(question, str): + inputs = {"image": image, "question": question} + else: + """ + Supports the following format + - {"image": image, "question": question} + - [{"image": image, "question": question}] + - Generator and datasets + """ + inputs = image + results = super().__call__(inputs, **kwargs) + return results + + def preprocess(self, inputs, padding=False, truncation=False): + image = load_image(inputs["image"]) + model_inputs = self.tokenizer( + inputs["question"], return_tensors=self.framework, padding=padding, truncation=truncation + ) + image_features = self.image_processor(images=image, return_tensors=self.framework) + model_inputs.update(image_features) + return model_inputs + + def _forward(self, model_inputs): + model_outputs = self.model(**model_inputs) + return model_outputs + + def postprocess(self, model_outputs, top_k=5): + if top_k > self.model.config.num_labels: + top_k = self.model.config.num_labels + + if self.framework == "pt": + probs = model_outputs.logits.sigmoid()[0] + scores, ids = probs.topk(top_k) + else: + raise ValueError(f"Unsupported framework: {self.framework}") + + scores = scores.tolist() + ids = ids.tolist() + return [{"score": score, "answer": self.model.config.id2label[_id]} for score, _id in zip(scores, ids)] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_audio_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_audio_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..e6b1da7df70a3373a9595424405bb397832d26cb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_audio_classification.py @@ -0,0 +1,155 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from collections import UserDict +from typing import Union + +import numpy as np +import requests + +from ..utils import ( + add_end_docstrings, + logging, +) +from .audio_classification import ffmpeg_read +from .base import PIPELINE_INIT_ARGS, Pipeline + + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ZeroShotAudioClassificationPipeline(Pipeline): + """ + Zero shot audio classification pipeline using `ClapModel`. This pipeline predicts the class of an audio when you + provide an audio and a set of `candidate_labels`. + + Example: + ```python + >>> from transformers import pipeline + >>> from datasets import load_dataset + + >>> dataset = load_dataset("ashraq/esc50") + >>> audio = next(iter(dataset["train"]["audio"]))["array"] + >>> classifier = pipeline(task="zero-shot-audio-classification", model="laion/clap-htsat-unfused") + >>> classifier(audio, candidate_labels=["Sound of a dog", "Sound of vaccum cleaner"]) + [{'score': 0.9996, 'label': 'Sound of a dog'}, {'score': 0.0004, 'label': 'Sound of vaccum cleaner'}] + ``` + + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) This audio + classification pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"zero-shot-audio-classification"`. See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=zero-shot-audio-classification). + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + if self.framework != "pt": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + # No specific FOR_XXX available yet + + def __call__(self, audios: Union[np.ndarray, bytes, str], **kwargs): + """ + Assign labels to the audio(s) passed as inputs. + + Args: + audios (`str`, `List[str]`, `np.array` or `List[np.array]`): + The pipeline handles three types of inputs: + - A string containing a http link pointing to an audio + - A string containing a local path to an audio + - An audio loaded in numpy + candidate_labels (`List[str]`): + The candidate labels for this audio + hypothesis_template (`str`, *optional*, defaults to `"This is a sound of {}"`): + The sentence used in cunjunction with *candidate_labels* to attempt the audio classification by + replacing the placeholder with the candidate_labels. Then likelihood is estimated by using + logits_per_audio + Return: + A list of dictionaries containing result, one dictionary per proposed label. The dictionaries contain the + following keys: + - **label** (`str`) -- The label identified by the model. It is one of the suggested `candidate_label`. + - **score** (`float`) -- The score attributed by the model for that label (between 0 and 1). + """ + return super().__call__(audios, **kwargs) + + def _sanitize_parameters(self, **kwargs): + preprocess_params = {} + if "candidate_labels" in kwargs: + preprocess_params["candidate_labels"] = kwargs["candidate_labels"] + if "hypothesis_template" in kwargs: + preprocess_params["hypothesis_template"] = kwargs["hypothesis_template"] + + return preprocess_params, {}, {} + + def preprocess(self, audio, candidate_labels=None, hypothesis_template="This is a sound of {}."): + if isinstance(audio, str): + if audio.startswith("http://") or audio.startswith("https://"): + # We need to actually check for a real protocol, otherwise it's impossible to use a local file + # like http_huggingface_co.png + audio = requests.get(audio).content + else: + with open(audio, "rb") as f: + audio = f.read() + + if isinstance(audio, bytes): + audio = ffmpeg_read(audio, self.feature_extractor.sampling_rate) + + if not isinstance(audio, np.ndarray): + raise ValueError("We expect a numpy ndarray as input") + if len(audio.shape) != 1: + raise ValueError("We expect a single channel audio input for ZeroShotAudioClassificationPipeline") + + inputs = self.feature_extractor( + [audio], sampling_rate=self.feature_extractor.sampling_rate, return_tensors="pt" + ) + inputs["candidate_labels"] = candidate_labels + sequences = [hypothesis_template.format(x) for x in candidate_labels] + text_inputs = self.tokenizer(sequences, return_tensors=self.framework, padding=True) + inputs["text_inputs"] = [text_inputs] + return inputs + + def _forward(self, model_inputs): + candidate_labels = model_inputs.pop("candidate_labels") + text_inputs = model_inputs.pop("text_inputs") + if isinstance(text_inputs[0], UserDict): + text_inputs = text_inputs[0] + else: + # Batching case. + text_inputs = text_inputs[0][0] + + outputs = self.model(**text_inputs, **model_inputs) + + model_outputs = { + "candidate_labels": candidate_labels, + "logits": outputs.logits_per_audio, + } + return model_outputs + + def postprocess(self, model_outputs): + candidate_labels = model_outputs.pop("candidate_labels") + logits = model_outputs["logits"][0] + + if self.framework == "pt": + probs = logits.softmax(dim=0) + scores = probs.tolist() + else: + raise ValueError("`tf` framework not supported.") + + result = [ + {"score": score, "label": candidate_label} + for score, candidate_label in sorted(zip(scores, candidate_labels), key=lambda x: -x[0]) + ] + return result diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..413591cf9050e525edabe5ae96926733b0c78a85 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_classification.py @@ -0,0 +1,260 @@ +from typing import List, Union + +import numpy as np + +from ..tokenization_utils import TruncationStrategy +from ..utils import add_end_docstrings, logging +from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline + + +logger = logging.get_logger(__name__) + + +class ZeroShotClassificationArgumentHandler(ArgumentHandler): + """ + Handles arguments for zero-shot for text classification by turning each possible label into an NLI + premise/hypothesis pair. + """ + + def _parse_labels(self, labels): + if isinstance(labels, str): + labels = [label.strip() for label in labels.split(",") if label.strip()] + return labels + + def __call__(self, sequences, labels, hypothesis_template): + if len(labels) == 0 or len(sequences) == 0: + raise ValueError("You must include at least one label and at least one sequence.") + if hypothesis_template.format(labels[0]) == hypothesis_template: + raise ValueError( + ( + 'The provided hypothesis_template "{}" was not able to be formatted with the target labels. ' + "Make sure the passed template includes formatting syntax such as {{}} where the label should go." + ).format(hypothesis_template) + ) + + if isinstance(sequences, str): + sequences = [sequences] + + sequence_pairs = [] + for sequence in sequences: + sequence_pairs.extend([[sequence, hypothesis_template.format(label)] for label in labels]) + + return sequence_pairs, sequences + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ZeroShotClassificationPipeline(ChunkPipeline): + """ + NLI-based zero-shot classification pipeline using a `ModelForSequenceClassification` trained on NLI (natural + language inference) tasks. Equivalent of `text-classification` pipelines, but these models don't require a + hardcoded number of potential classes, they can be chosen at runtime. It usually means it's slower but it is + **much** more flexible. + + Any combination of sequences and labels can be passed and each combination will be posed as a premise/hypothesis + pair and passed to the pretrained model. Then, the logit for *entailment* is taken as the logit for the candidate + label being valid. Any NLI model can be used, but the id of the *entailment* label must be included in the model + config's :attr:*~transformers.PretrainedConfig.label2id*. + + Example: + + ```python + >>> from transformers import pipeline + + >>> oracle = pipeline(model="facebook/bart-large-mnli") + >>> oracle( + ... "I have a problem with my iphone that needs to be resolved asap!!", + ... candidate_labels=["urgent", "not urgent", "phone", "tablet", "computer"], + ... ) + {'sequence': 'I have a problem with my iphone that needs to be resolved asap!!', 'labels': ['urgent', 'phone', 'computer', 'not urgent', 'tablet'], 'scores': [0.504, 0.479, 0.013, 0.003, 0.002]} + + >>> oracle( + ... "I have a problem with my iphone that needs to be resolved asap!!", + ... candidate_labels=["english", "german"], + ... ) + {'sequence': 'I have a problem with my iphone that needs to be resolved asap!!', 'labels': ['english', 'german'], 'scores': [0.814, 0.186]} + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This NLI pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"zero-shot-classification"`. + + The models that this pipeline can use are models that have been fine-tuned on an NLI task. See the up-to-date list + of available models on [huggingface.co/models](https://huggingface.co/models?search=nli). + """ + + def __init__(self, args_parser=ZeroShotClassificationArgumentHandler(), *args, **kwargs): + self._args_parser = args_parser + super().__init__(*args, **kwargs) + if self.entailment_id == -1: + logger.warning( + "Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to " + "-1. Define a descriptive label2id mapping in the model config to ensure correct outputs." + ) + + @property + def entailment_id(self): + for label, ind in self.model.config.label2id.items(): + if label.lower().startswith("entail"): + return ind + return -1 + + def _parse_and_tokenize( + self, sequence_pairs, padding=True, add_special_tokens=True, truncation=TruncationStrategy.ONLY_FIRST, **kwargs + ): + """ + Parse arguments and tokenize only_first so that hypothesis (label) is not truncated + """ + return_tensors = self.framework + if self.tokenizer.pad_token is None: + # Override for tokenizers not supporting padding + logger.error( + "Tokenizer was not supporting padding necessary for zero-shot, attempting to use " + " `pad_token=eos_token`" + ) + self.tokenizer.pad_token = self.tokenizer.eos_token + try: + inputs = self.tokenizer( + sequence_pairs, + add_special_tokens=add_special_tokens, + return_tensors=return_tensors, + padding=padding, + truncation=truncation, + ) + except Exception as e: + if "too short" in str(e): + # tokenizers might yell that we want to truncate + # to a value that is not even reached by the input. + # In that case we don't want to truncate. + # It seems there's not a really better way to catch that + # exception. + + inputs = self.tokenizer( + sequence_pairs, + add_special_tokens=add_special_tokens, + return_tensors=return_tensors, + padding=padding, + truncation=TruncationStrategy.DO_NOT_TRUNCATE, + ) + else: + raise e + + return inputs + + def _sanitize_parameters(self, **kwargs): + if kwargs.get("multi_class", None) is not None: + kwargs["multi_label"] = kwargs["multi_class"] + logger.warning( + "The `multi_class` argument has been deprecated and renamed to `multi_label`. " + "`multi_class` will be removed in a future version of Transformers." + ) + preprocess_params = {} + if "candidate_labels" in kwargs: + preprocess_params["candidate_labels"] = self._args_parser._parse_labels(kwargs["candidate_labels"]) + if "hypothesis_template" in kwargs: + preprocess_params["hypothesis_template"] = kwargs["hypothesis_template"] + + postprocess_params = {} + if "multi_label" in kwargs: + postprocess_params["multi_label"] = kwargs["multi_label"] + return preprocess_params, {}, postprocess_params + + def __call__( + self, + sequences: Union[str, List[str]], + *args, + **kwargs, + ): + """ + Classify the sequence(s) given as inputs. See the [`ZeroShotClassificationPipeline`] documentation for more + information. + + Args: + sequences (`str` or `List[str]`): + The sequence(s) to classify, will be truncated if the model input is too large. + candidate_labels (`str` or `List[str]`): + The set of possible class labels to classify each sequence into. Can be a single label, a string of + comma-separated labels, or a list of labels. + hypothesis_template (`str`, *optional*, defaults to `"This example is {}."`): + The template used to turn each label into an NLI-style hypothesis. This template must include a {} or + similar syntax for the candidate label to be inserted into the template. For example, the default + template is `"This example is {}."` With the candidate label `"sports"`, this would be fed into the + model like `" sequence to classify This example is sports . "`. The default template + works well in many cases, but it may be worthwhile to experiment with different templates depending on + the task setting. + multi_label (`bool`, *optional*, defaults to `False`): + Whether or not multiple candidate labels can be true. If `False`, the scores are normalized such that + the sum of the label likelihoods for each sequence is 1. If `True`, the labels are considered + independent and probabilities are normalized for each candidate by doing a softmax of the entailment + score vs. the contradiction score. + + Return: + A `dict` or a list of `dict`: Each result comes as a dictionary with the following keys: + + - **sequence** (`str`) -- The sequence for which this is the output. + - **labels** (`List[str]`) -- The labels sorted by order of likelihood. + - **scores** (`List[float]`) -- The probabilities for each of the labels. + """ + if len(args) == 0: + pass + elif len(args) == 1 and "candidate_labels" not in kwargs: + kwargs["candidate_labels"] = args[0] + else: + raise ValueError(f"Unable to understand extra arguments {args}") + + return super().__call__(sequences, **kwargs) + + def preprocess(self, inputs, candidate_labels=None, hypothesis_template="This example is {}."): + sequence_pairs, sequences = self._args_parser(inputs, candidate_labels, hypothesis_template) + + for i, (candidate_label, sequence_pair) in enumerate(zip(candidate_labels, sequence_pairs)): + model_input = self._parse_and_tokenize([sequence_pair]) + + yield { + "candidate_label": candidate_label, + "sequence": sequences[0], + "is_last": i == len(candidate_labels) - 1, + **model_input, + } + + def _forward(self, inputs): + candidate_label = inputs["candidate_label"] + sequence = inputs["sequence"] + model_inputs = {k: inputs[k] for k in self.tokenizer.model_input_names} + outputs = self.model(**model_inputs) + + model_outputs = { + "candidate_label": candidate_label, + "sequence": sequence, + "is_last": inputs["is_last"], + **outputs, + } + return model_outputs + + def postprocess(self, model_outputs, multi_label=False): + candidate_labels = [outputs["candidate_label"] for outputs in model_outputs] + sequences = [outputs["sequence"] for outputs in model_outputs] + logits = np.concatenate([output["logits"].numpy() for output in model_outputs]) + N = logits.shape[0] + n = len(candidate_labels) + num_sequences = N // n + reshaped_outputs = logits.reshape((num_sequences, n, -1)) + + if multi_label or len(candidate_labels) == 1: + # softmax over the entailment vs. contradiction dim for each label independently + entailment_id = self.entailment_id + contradiction_id = -1 if entailment_id == 0 else 0 + entail_contr_logits = reshaped_outputs[..., [contradiction_id, entailment_id]] + scores = np.exp(entail_contr_logits) / np.exp(entail_contr_logits).sum(-1, keepdims=True) + scores = scores[..., 1] + else: + # softmax the "entailment" logits over all candidate labels + entail_logits = reshaped_outputs[..., self.entailment_id] + scores = np.exp(entail_logits) / np.exp(entail_logits).sum(-1, keepdims=True) + + top_inds = list(reversed(scores[0].argsort())) + return { + "sequence": sequences[0], + "labels": [candidate_labels[i] for i in top_inds], + "scores": scores[0, top_inds].tolist(), + } diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_image_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_image_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..8ba07eb018cba8d9ee209996a2a69b0017432b0c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_image_classification.py @@ -0,0 +1,154 @@ +from collections import UserDict +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_torch_available(): + from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + +if is_tf_available(): + from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + from ..tf_utils import stable_softmax + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ZeroShotImageClassificationPipeline(Pipeline): + """ + Zero shot image classification pipeline using `CLIPModel`. This pipeline predicts the class of an image when you + provide an image and a set of `candidate_labels`. + + Example: + + ```python + >>> from transformers import pipeline + + >>> classifier = pipeline(model="openai/clip-vit-large-patch14") + >>> classifier( + ... "https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png", + ... candidate_labels=["animals", "humans", "landscape"], + ... ) + [{'score': 0.965, 'label': 'animals'}, {'score': 0.03, 'label': 'humans'}, {'score': 0.005, 'label': 'landscape'}] + + >>> classifier( + ... "https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png", + ... candidate_labels=["black and white", "photorealist", "painting"], + ... ) + [{'score': 0.996, 'label': 'black and white'}, {'score': 0.003, 'label': 'photorealist'}, {'score': 0.0, 'label': 'painting'}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This image classification pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"zero-shot-image-classification"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=zero-shot-image-classification). + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + requires_backends(self, "vision") + self.check_model_type( + TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + if self.framework == "tf" + else MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING + ) + + def __call__(self, images: Union[str, List[str], "Image", List["Image"]], **kwargs): + """ + Assign labels to the image(s) passed as inputs. + + Args: + images (`str`, `List[str]`, `PIL.Image` or `List[PIL.Image]`): + The pipeline handles three types of images: + + - A string containing a http link pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + candidate_labels (`List[str]`): + The candidate labels for this image + + hypothesis_template (`str`, *optional*, defaults to `"This is a photo of {}"`): + The sentence used in cunjunction with *candidate_labels* to attempt the image classification by + replacing the placeholder with the candidate_labels. Then likelihood is estimated by using + logits_per_image + + Return: + A list of dictionaries containing result, one dictionary per proposed label. The dictionaries contain the + following keys: + + - **label** (`str`) -- The label identified by the model. It is one of the suggested `candidate_label`. + - **score** (`float`) -- The score attributed by the model for that label (between 0 and 1). + """ + return super().__call__(images, **kwargs) + + def _sanitize_parameters(self, **kwargs): + preprocess_params = {} + if "candidate_labels" in kwargs: + preprocess_params["candidate_labels"] = kwargs["candidate_labels"] + if "hypothesis_template" in kwargs: + preprocess_params["hypothesis_template"] = kwargs["hypothesis_template"] + + return preprocess_params, {}, {} + + def preprocess(self, image, candidate_labels=None, hypothesis_template="This is a photo of {}."): + image = load_image(image) + inputs = self.image_processor(images=[image], return_tensors=self.framework) + inputs["candidate_labels"] = candidate_labels + sequences = [hypothesis_template.format(x) for x in candidate_labels] + text_inputs = self.tokenizer(sequences, return_tensors=self.framework, padding=True) + inputs["text_inputs"] = [text_inputs] + return inputs + + def _forward(self, model_inputs): + candidate_labels = model_inputs.pop("candidate_labels") + text_inputs = model_inputs.pop("text_inputs") + if isinstance(text_inputs[0], UserDict): + text_inputs = text_inputs[0] + else: + # Batching case. + text_inputs = text_inputs[0][0] + + outputs = self.model(**text_inputs, **model_inputs) + + model_outputs = { + "candidate_labels": candidate_labels, + "logits": outputs.logits_per_image, + } + return model_outputs + + def postprocess(self, model_outputs): + candidate_labels = model_outputs.pop("candidate_labels") + logits = model_outputs["logits"][0] + if self.framework == "pt": + probs = logits.softmax(dim=-1).squeeze(-1) + scores = probs.tolist() + elif self.framework == "tf": + probs = stable_softmax(logits, axis=-1) + scores = probs.numpy().tolist() + else: + raise ValueError(f"Unsupported framework: {self.framework}") + + result = [ + {"score": score, "label": candidate_label} + for score, candidate_label in sorted(zip(scores, candidate_labels), key=lambda x: -x[0]) + ] + return result diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_object_detection.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_object_detection.py new file mode 100644 index 0000000000000000000000000000000000000000..cf05999861c05fbcb4c12311b2e9024b4a196c3e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/pipelines/zero_shot_object_detection.py @@ -0,0 +1,211 @@ +from typing import Any, Dict, List, Union + +from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging, requires_backends +from .base import PIPELINE_INIT_ARGS, ChunkPipeline + + +if is_vision_available(): + from PIL import Image + + from ..image_utils import load_image + +if is_torch_available(): + import torch + + from transformers.modeling_outputs import BaseModelOutput + + from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING + +logger = logging.get_logger(__name__) + + +@add_end_docstrings(PIPELINE_INIT_ARGS) +class ZeroShotObjectDetectionPipeline(ChunkPipeline): + """ + Zero shot object detection pipeline using `OwlViTForObjectDetection`. This pipeline predicts bounding boxes of + objects when you provide an image and a set of `candidate_labels`. + + Example: + + ```python + >>> from transformers import pipeline + + >>> detector = pipeline(model="google/owlvit-base-patch32", task="zero-shot-object-detection") + >>> detector( + ... "http://images.cocodataset.org/val2017/000000039769.jpg", + ... candidate_labels=["cat", "couch"], + ... ) + [{'score': 0.287, 'label': 'cat', 'box': {'xmin': 324, 'ymin': 20, 'xmax': 640, 'ymax': 373}}, {'score': 0.254, 'label': 'cat', 'box': {'xmin': 1, 'ymin': 55, 'xmax': 315, 'ymax': 472}}, {'score': 0.121, 'label': 'couch', 'box': {'xmin': 4, 'ymin': 0, 'xmax': 642, 'ymax': 476}}] + + >>> detector( + ... "https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png", + ... candidate_labels=["head", "bird"], + ... ) + [{'score': 0.119, 'label': 'bird', 'box': {'xmin': 71, 'ymin': 170, 'xmax': 410, 'ymax': 508}}] + ``` + + Learn more about the basics of using a pipeline in the [pipeline tutorial](../pipeline_tutorial) + + This object detection pipeline can currently be loaded from [`pipeline`] using the following task identifier: + `"zero-shot-object-detection"`. + + See the list of available models on + [huggingface.co/models](https://huggingface.co/models?filter=zero-shot-object-detection). + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + if self.framework == "tf": + raise ValueError(f"The {self.__class__} is only available in PyTorch.") + + requires_backends(self, "vision") + self.check_model_type(MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING) + + def __call__( + self, + image: Union[str, "Image.Image", List[Dict[str, Any]]], + candidate_labels: Union[str, List[str]] = None, + **kwargs, + ): + """ + Detect objects (bounding boxes & classes) in the image(s) passed as inputs. + + Args: + image (`str`, `PIL.Image` or `List[Dict[str, Any]]`): + The pipeline handles three types of images: + + - A string containing an http url pointing to an image + - A string containing a local path to an image + - An image loaded in PIL directly + + You can use this parameter to send directly a list of images, or a dataset or a generator like so: + + ```python + >>> from transformers import pipeline + + >>> detector = pipeline(model="google/owlvit-base-patch32", task="zero-shot-object-detection") + >>> detector( + ... [ + ... { + ... "image": "http://images.cocodataset.org/val2017/000000039769.jpg", + ... "candidate_labels": ["cat", "couch"], + ... }, + ... { + ... "image": "http://images.cocodataset.org/val2017/000000039769.jpg", + ... "candidate_labels": ["cat", "couch"], + ... }, + ... ] + ... ) + [[{'score': 0.287, 'label': 'cat', 'box': {'xmin': 324, 'ymin': 20, 'xmax': 640, 'ymax': 373}}, {'score': 0.25, 'label': 'cat', 'box': {'xmin': 1, 'ymin': 55, 'xmax': 315, 'ymax': 472}}, {'score': 0.121, 'label': 'couch', 'box': {'xmin': 4, 'ymin': 0, 'xmax': 642, 'ymax': 476}}], [{'score': 0.287, 'label': 'cat', 'box': {'xmin': 324, 'ymin': 20, 'xmax': 640, 'ymax': 373}}, {'score': 0.254, 'label': 'cat', 'box': {'xmin': 1, 'ymin': 55, 'xmax': 315, 'ymax': 472}}, {'score': 0.121, 'label': 'couch', 'box': {'xmin': 4, 'ymin': 0, 'xmax': 642, 'ymax': 476}}]] + ``` + + + candidate_labels (`str` or `List[str]` or `List[List[str]]`): + What the model should recognize in the image. + + threshold (`float`, *optional*, defaults to 0.1): + The probability necessary to make a prediction. + + top_k (`int`, *optional*, defaults to None): + The number of top predictions that will be returned by the pipeline. If the provided number is `None` + or higher than the number of predictions available, it will default to the number of predictions. + + + Return: + A list of lists containing prediction results, one list per input image. Each list contains dictionaries + with the following keys: + + - **label** (`str`) -- Text query corresponding to the found object. + - **score** (`float`) -- Score corresponding to the object (between 0 and 1). + - **box** (`Dict[str,int]`) -- Bounding box of the detected object in image's original size. It is a + dictionary with `x_min`, `x_max`, `y_min`, `y_max` keys. + """ + if "text_queries" in kwargs: + candidate_labels = kwargs.pop("text_queries") + + if isinstance(image, (str, Image.Image)): + inputs = {"image": image, "candidate_labels": candidate_labels} + else: + inputs = image + results = super().__call__(inputs, **kwargs) + return results + + def _sanitize_parameters(self, **kwargs): + postprocess_params = {} + if "threshold" in kwargs: + postprocess_params["threshold"] = kwargs["threshold"] + if "top_k" in kwargs: + postprocess_params["top_k"] = kwargs["top_k"] + return {}, {}, postprocess_params + + def preprocess(self, inputs): + image = load_image(inputs["image"]) + candidate_labels = inputs["candidate_labels"] + if isinstance(candidate_labels, str): + candidate_labels = candidate_labels.split(",") + + target_size = torch.tensor([[image.height, image.width]], dtype=torch.int32) + for i, candidate_label in enumerate(candidate_labels): + text_inputs = self.tokenizer(candidate_label, return_tensors=self.framework) + image_features = self.image_processor(image, return_tensors=self.framework) + yield { + "is_last": i == len(candidate_labels) - 1, + "target_size": target_size, + "candidate_label": candidate_label, + **text_inputs, + **image_features, + } + + def _forward(self, model_inputs): + target_size = model_inputs.pop("target_size") + candidate_label = model_inputs.pop("candidate_label") + is_last = model_inputs.pop("is_last") + + outputs = self.model(**model_inputs) + + model_outputs = {"target_size": target_size, "candidate_label": candidate_label, "is_last": is_last, **outputs} + return model_outputs + + def postprocess(self, model_outputs, threshold=0.1, top_k=None): + results = [] + for model_output in model_outputs: + label = model_output["candidate_label"] + model_output = BaseModelOutput(model_output) + outputs = self.image_processor.post_process_object_detection( + outputs=model_output, threshold=threshold, target_sizes=model_output["target_size"] + )[0] + + for index in outputs["scores"].nonzero(): + score = outputs["scores"][index].item() + box = self._get_bounding_box(outputs["boxes"][index][0]) + + result = {"score": score, "label": label, "box": box} + results.append(result) + + results = sorted(results, key=lambda x: x["score"], reverse=True) + if top_k: + results = results[:top_k] + + return results + + def _get_bounding_box(self, box: "torch.Tensor") -> Dict[str, int]: + """ + Turns list [xmin, xmax, ymin, ymax] into dict { "xmin": xmin, ... } + + Args: + box (`torch.Tensor`): Tensor containing the coordinates in corners format. + + Returns: + bbox (`Dict[str, int]`): Dict containing the coordinates in corners format. + """ + if self.framework != "pt": + raise ValueError("The ZeroShotObjectDetectionPipeline is only available in PyTorch.") + xmin, ymin, xmax, ymax = box.int().tolist() + bbox = { + "xmin": xmin, + "ymin": ymin, + "xmax": xmax, + "ymax": ymax, + } + return bbox diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..98fe38de89cd025911d03669f9e22b03ab0768bd --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .trainer_sm import SageMakerTrainer +from .training_args_sm import SageMakerTrainingArguments, is_sagemaker_dp_enabled diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/trainer_sm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/trainer_sm.py new file mode 100644 index 0000000000000000000000000000000000000000..6ab4e01acdbcd3ade1afc2339a75850bc538bd7a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/trainer_sm.py @@ -0,0 +1,30 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import warnings + +from ..trainer import Trainer +from ..utils import logging + + +logger = logging.get_logger(__name__) + + +class SageMakerTrainer(Trainer): + def __init__(self, args=None, **kwargs): + warnings.warn( + "`SageMakerTrainer` is deprecated and will be removed in v5 of Transformers. You can use `Trainer` " + "instead.", + FutureWarning, + ) + super().__init__(args=args, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/training_args_sm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/training_args_sm.py new file mode 100644 index 0000000000000000000000000000000000000000..3daac7859b550de31f211a5e7c9938d8d557fc4c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/sagemaker/training_args_sm.py @@ -0,0 +1,136 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib.util +import json +import os +import warnings +from dataclasses import dataclass, field + +import torch + +from ..training_args import TrainingArguments +from ..utils import cached_property, is_sagemaker_dp_enabled, logging + + +logger = logging.get_logger(__name__) + +# TODO: should be moved to `utils` after refactoring of SageMakerTrainer + + +def is_sagemaker_model_parallel_available(): + # Get the sagemaker specific mp parameters from smp_options variable. + smp_options = os.getenv("SM_HP_MP_PARAMETERS", "{}") + try: + # Parse it and check the field "partitions" is included, it is required for model parallel. + smp_options = json.loads(smp_options) + if "partitions" not in smp_options: + return False + except json.JSONDecodeError: + return False + + # Get the sagemaker specific framework parameters from mpi_options variable. + mpi_options = os.getenv("SM_FRAMEWORK_PARAMS", "{}") + try: + # Parse it and check the field "sagemaker_distributed_dataparallel_enabled". + mpi_options = json.loads(mpi_options) + if not mpi_options.get("sagemaker_mpi_enabled", False): + return False + except json.JSONDecodeError: + return False + # Lastly, check if the `smdistributed` module is present. + return importlib.util.find_spec("smdistributed") is not None + + +if is_sagemaker_model_parallel_available(): + import smdistributed.modelparallel.torch as smp + + smp.init() + + +@dataclass +class SageMakerTrainingArguments(TrainingArguments): + mp_parameters: str = field( + default="", + metadata={"help": "Used by the SageMaker launcher to send mp-specific args. Ignored in SageMakerTrainer"}, + ) + + def __post_init__(self): + super().__post_init__() + warnings.warn( + "`SageMakerTrainingArguments` is deprecated and will be removed in v5 of Transformers. You can use " + "`TrainingArguments` instead.", + FutureWarning, + ) + + @cached_property + def _setup_devices(self) -> "torch.device": + logger.info("PyTorch: setting up devices") + if torch.distributed.is_available() and torch.distributed.is_initialized() and self.local_rank == -1: + logger.warning( + "torch.distributed process group is initialized, but local_rank == -1. " + "In order to use Torch DDP, launch your script with `python -m torch.distributed.launch" + ) + if self.no_cuda: + device = torch.device("cpu") + self._n_gpu = 0 + elif is_sagemaker_model_parallel_available(): + local_rank = smp.local_rank() + device = torch.device("cuda", local_rank) + self._n_gpu = 1 + elif is_sagemaker_dp_enabled(): + import smdistributed.dataparallel.torch.torch_smddp # noqa: F401 + + torch.distributed.init_process_group(backend="smddp", timeout=self.ddp_timeout_delta) + self.local_rank = int(os.getenv("SMDATAPARALLEL_LOCAL_RANK")) + device = torch.device("cuda", self.local_rank) + self._n_gpu = 1 + elif self.local_rank == -1: + # if n_gpu is > 1 we'll use nn.DataParallel. + # If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0` + # Explicitly set CUDA to the first (index 0) CUDA device, otherwise `set_device` will + # trigger an error that a device index is missing. Index 0 takes into account the + # GPUs available in the environment, so `CUDA_VISIBLE_DEVICES=1,2` with `cuda:0` + # will use the first GPU in that env, i.e. GPU#1 + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + # Sometimes the line in the postinit has not been run before we end up here, so just checking we're not at + # the default value. + self._n_gpu = torch.cuda.device_count() + else: + # Here, we'll use torch.distributed. + # Initializes the distributed backend which will take care of synchronizing nodes/GPUs + if not torch.distributed.is_initialized(): + torch.distributed.init_process_group(backend="nccl", timeout=self.ddp_timeout_delta) + device = torch.device("cuda", self.local_rank) + self._n_gpu = 1 + + if device.type == "cuda": + torch.cuda.set_device(device) + + return device + + @property + def world_size(self): + if is_sagemaker_model_parallel_available(): + return smp.dp_size() + + return super().world_size + + @property + def place_model_on_device(self): + return not is_sagemaker_model_parallel_available() + + @property + def _no_sync_in_gradient_accumulation(self): + return False diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/testing_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/testing_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..e9e9c7e2c1c6a83c3d80214ccad322fe50243826 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/testing_utils.py @@ -0,0 +1,1814 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import contextlib +import functools +import inspect +import logging +import multiprocessing +import os +import re +import shlex +import shutil +import subprocess +import sys +import tempfile +import time +import unittest +from collections.abc import Mapping +from io import StringIO +from pathlib import Path +from typing import Iterator, List, Optional, Union +from unittest import mock + +import huggingface_hub +import requests + +from transformers import logging as transformers_logging + +from .deepspeed import is_deepspeed_available +from .integrations import ( + is_clearml_available, + is_fairscale_available, + is_optuna_available, + is_ray_available, + is_sigopt_available, + is_wandb_available, +) +from .utils import ( + is_accelerate_available, + is_apex_available, + is_bitsandbytes_available, + is_bs4_available, + is_cython_available, + is_decord_available, + is_detectron2_available, + is_faiss_available, + is_flax_available, + is_ftfy_available, + is_ipex_available, + is_jieba_available, + is_jumanpp_available, + is_keras_nlp_available, + is_librosa_available, + is_natten_available, + is_onnx_available, + is_optimum_available, + is_pandas_available, + is_phonemizer_available, + is_pyctcdecode_available, + is_pytesseract_available, + is_pytorch_quantization_available, + is_rjieba_available, + is_safetensors_available, + is_scipy_available, + is_sentencepiece_available, + is_soundfile_availble, + is_spacy_available, + is_sudachi_available, + is_tensorflow_probability_available, + is_tensorflow_text_available, + is_tf2onnx_available, + is_tf_available, + is_timm_available, + is_tokenizers_available, + is_torch_available, + is_torch_bf16_cpu_available, + is_torch_bf16_gpu_available, + is_torch_neuroncore_available, + is_torch_tensorrt_fx_available, + is_torch_tf32_available, + is_torch_tpu_available, + is_torchaudio_available, + is_torchdynamo_available, + is_torchvision_available, + is_vision_available, + strtobool, +) + + +SMALL_MODEL_IDENTIFIER = "julien-c/bert-xsmall-dummy" +DUMMY_UNKNOWN_IDENTIFIER = "julien-c/dummy-unknown" +DUMMY_DIFF_TOKENIZER_IDENTIFIER = "julien-c/dummy-diff-tokenizer" +# Used to test Auto{Config, Model, Tokenizer} model_type detection. + +# Used to test the hub +USER = "__DUMMY_TRANSFORMERS_USER__" +ENDPOINT_STAGING = "https://hub-ci.huggingface.co" + +# Not critical, only usable on the sandboxed CI instance. +TOKEN = "hf_94wBhPGp6KrrTH3KDchhKpRxZwd6dmHWLL" + + +def parse_flag_from_env(key, default=False): + try: + value = os.environ[key] + except KeyError: + # KEY isn't set, default to `default`. + _value = default + else: + # KEY is set, convert it to True or False. + try: + _value = strtobool(value) + except ValueError: + # More values are supported, but let's keep the message simple. + raise ValueError(f"If set, {key} must be yes or no.") + return _value + + +def parse_int_from_env(key, default=None): + try: + value = os.environ[key] + except KeyError: + _value = default + else: + try: + _value = int(value) + except ValueError: + raise ValueError(f"If set, {key} must be a int.") + return _value + + +_run_slow_tests = parse_flag_from_env("RUN_SLOW", default=False) +_run_pt_tf_cross_tests = parse_flag_from_env("RUN_PT_TF_CROSS_TESTS", default=True) +_run_pt_flax_cross_tests = parse_flag_from_env("RUN_PT_FLAX_CROSS_TESTS", default=True) +_run_custom_tokenizers = parse_flag_from_env("RUN_CUSTOM_TOKENIZERS", default=False) +_run_staging = parse_flag_from_env("HUGGINGFACE_CO_STAGING", default=False) +_tf_gpu_memory_limit = parse_int_from_env("TF_GPU_MEMORY_LIMIT", default=None) +_run_pipeline_tests = parse_flag_from_env("RUN_PIPELINE_TESTS", default=True) +_run_tool_tests = parse_flag_from_env("RUN_TOOL_TESTS", default=False) + + +def is_pt_tf_cross_test(test_case): + """ + Decorator marking a test as a test that control interactions between PyTorch and TensorFlow. + + PT+TF tests are skipped by default and we can run only them by setting RUN_PT_TF_CROSS_TESTS environment variable + to a truthy value and selecting the is_pt_tf_cross_test pytest mark. + + """ + if not _run_pt_tf_cross_tests or not is_torch_available() or not is_tf_available(): + return unittest.skip("test is PT+TF test")(test_case) + else: + try: + import pytest # We don't need a hard dependency on pytest in the main library + except ImportError: + return test_case + else: + return pytest.mark.is_pt_tf_cross_test()(test_case) + + +def is_pt_flax_cross_test(test_case): + """ + Decorator marking a test as a test that control interactions between PyTorch and Flax + + PT+FLAX tests are skipped by default and we can run only them by setting RUN_PT_FLAX_CROSS_TESTS environment + variable to a truthy value and selecting the is_pt_flax_cross_test pytest mark. + + """ + if not _run_pt_flax_cross_tests or not is_torch_available() or not is_flax_available(): + return unittest.skip("test is PT+FLAX test")(test_case) + else: + try: + import pytest # We don't need a hard dependency on pytest in the main library + except ImportError: + return test_case + else: + return pytest.mark.is_pt_flax_cross_test()(test_case) + + +def is_staging_test(test_case): + """ + Decorator marking a test as a staging test. + + Those tests will run using the staging environment of huggingface.co instead of the real model hub. + """ + if not _run_staging: + return unittest.skip("test is staging test")(test_case) + else: + try: + import pytest # We don't need a hard dependency on pytest in the main library + except ImportError: + return test_case + else: + return pytest.mark.is_staging_test()(test_case) + + +def is_pipeline_test(test_case): + """ + Decorator marking a test as a pipeline test. If RUN_PIPELINE_TESTS is set to a falsy value, those tests will be + skipped. + """ + if not _run_pipeline_tests: + return unittest.skip("test is pipeline test")(test_case) + else: + try: + import pytest # We don't need a hard dependency on pytest in the main library + except ImportError: + return test_case + else: + return pytest.mark.is_pipeline_test()(test_case) + + +def is_tool_test(test_case): + """ + Decorator marking a test as a tool test. If RUN_TOOL_TESTS is set to a falsy value, those tests will be skipped. + """ + if not _run_tool_tests: + return unittest.skip("test is a tool test")(test_case) + else: + try: + import pytest # We don't need a hard dependency on pytest in the main library + except ImportError: + return test_case + else: + return pytest.mark.is_tool_test()(test_case) + + +def slow(test_case): + """ + Decorator marking a test as slow. + + Slow tests are skipped by default. Set the RUN_SLOW environment variable to a truthy value to run them. + + """ + return unittest.skipUnless(_run_slow_tests, "test is slow")(test_case) + + +def tooslow(test_case): + """ + Decorator marking a test as too slow. + + Slow tests are skipped while they're in the process of being fixed. No test should stay tagged as "tooslow" as + these will not be tested by the CI. + + """ + return unittest.skip("test is too slow")(test_case) + + +def custom_tokenizers(test_case): + """ + Decorator marking a test for a custom tokenizer. + + Custom tokenizers require additional dependencies, and are skipped by default. Set the RUN_CUSTOM_TOKENIZERS + environment variable to a truthy value to run them. + """ + return unittest.skipUnless(_run_custom_tokenizers, "test of custom tokenizers")(test_case) + + +def require_bs4(test_case): + """ + Decorator marking a test that requires BeautifulSoup4. These tests are skipped when BeautifulSoup4 isn't installed. + """ + return unittest.skipUnless(is_bs4_available(), "test requires BeautifulSoup4")(test_case) + + +def require_accelerate(test_case): + """ + Decorator marking a test that requires accelerate. These tests are skipped when accelerate isn't installed. + """ + return unittest.skipUnless(is_accelerate_available(), "test requires accelerate")(test_case) + + +def require_safetensors(test_case): + """ + Decorator marking a test that requires safetensors. These tests are skipped when safetensors isn't installed. + """ + return unittest.skipUnless(is_safetensors_available(), "test requires safetensors")(test_case) + + +def require_rjieba(test_case): + """ + Decorator marking a test that requires rjieba. These tests are skipped when rjieba isn't installed. + """ + return unittest.skipUnless(is_rjieba_available(), "test requires rjieba")(test_case) + + +def require_jieba(test_case): + """ + Decorator marking a test that requires jieba. These tests are skipped when jieba isn't installed. + """ + return unittest.skipUnless(is_jieba_available(), "test requires jieba")(test_case) + + +def require_tf2onnx(test_case): + return unittest.skipUnless(is_tf2onnx_available(), "test requires tf2onnx")(test_case) + + +def require_onnx(test_case): + return unittest.skipUnless(is_onnx_available(), "test requires ONNX")(test_case) + + +def require_timm(test_case): + """ + Decorator marking a test that requires Timm. + + These tests are skipped when Timm isn't installed. + + """ + return unittest.skipUnless(is_timm_available(), "test requires Timm")(test_case) + + +def require_natten(test_case): + """ + Decorator marking a test that requires NATTEN. + + These tests are skipped when NATTEN isn't installed. + + """ + return unittest.skipUnless(is_natten_available(), "test requires natten")(test_case) + + +def require_torch(test_case): + """ + Decorator marking a test that requires PyTorch. + + These tests are skipped when PyTorch isn't installed. + + """ + return unittest.skipUnless(is_torch_available(), "test requires PyTorch")(test_case) + + +def require_torchvision(test_case): + """ + Decorator marking a test that requires Torchvision. + + These tests are skipped when Torchvision isn't installed. + + """ + return unittest.skipUnless(is_torchvision_available(), "test requires Torchvision")(test_case) + + +def require_torch_or_tf(test_case): + """ + Decorator marking a test that requires PyTorch or TensorFlow. + + These tests are skipped when neither PyTorch not TensorFlow is installed. + + """ + return unittest.skipUnless(is_torch_available() or is_tf_available(), "test requires PyTorch or TensorFlow")( + test_case + ) + + +def require_intel_extension_for_pytorch(test_case): + """ + Decorator marking a test that requires Intel Extension for PyTorch. + + These tests are skipped when Intel Extension for PyTorch isn't installed or it does not match current PyTorch + version. + + """ + return unittest.skipUnless( + is_ipex_available(), + "test requires Intel Extension for PyTorch to be installed and match current PyTorch version, see" + " https://github.com/intel/intel-extension-for-pytorch", + )(test_case) + + +def require_tensorflow_probability(test_case): + """ + Decorator marking a test that requires TensorFlow probability. + + These tests are skipped when TensorFlow probability isn't installed. + + """ + return unittest.skipUnless(is_tensorflow_probability_available(), "test requires TensorFlow probability")( + test_case + ) + + +def require_torchaudio(test_case): + """ + Decorator marking a test that requires torchaudio. These tests are skipped when torchaudio isn't installed. + """ + return unittest.skipUnless(is_torchaudio_available(), "test requires torchaudio")(test_case) + + +def require_tf(test_case): + """ + Decorator marking a test that requires TensorFlow. These tests are skipped when TensorFlow isn't installed. + """ + return unittest.skipUnless(is_tf_available(), "test requires TensorFlow")(test_case) + + +def require_flax(test_case): + """ + Decorator marking a test that requires JAX & Flax. These tests are skipped when one / both are not installed + """ + return unittest.skipUnless(is_flax_available(), "test requires JAX & Flax")(test_case) + + +def require_sentencepiece(test_case): + """ + Decorator marking a test that requires SentencePiece. These tests are skipped when SentencePiece isn't installed. + """ + return unittest.skipUnless(is_sentencepiece_available(), "test requires SentencePiece")(test_case) + + +def require_scipy(test_case): + """ + Decorator marking a test that requires Scipy. These tests are skipped when SentencePiece isn't installed. + """ + return unittest.skipUnless(is_scipy_available(), "test requires Scipy")(test_case) + + +def require_tokenizers(test_case): + """ + Decorator marking a test that requires 🤗 Tokenizers. These tests are skipped when 🤗 Tokenizers isn't installed. + """ + return unittest.skipUnless(is_tokenizers_available(), "test requires tokenizers")(test_case) + + +def require_tensorflow_text(test_case): + """ + Decorator marking a test that requires tensorflow_text. These tests are skipped when tensroflow_text isn't + installed. + """ + return unittest.skipUnless(is_tensorflow_text_available(), "test requires tensorflow_text")(test_case) + + +def require_keras_nlp(test_case): + """ + Decorator marking a test that requires keras_nlp. These tests are skipped when keras_nlp isn't installed. + """ + return unittest.skipUnless(is_keras_nlp_available(), "test requires keras_nlp")(test_case) + + +def require_pandas(test_case): + """ + Decorator marking a test that requires pandas. These tests are skipped when pandas isn't installed. + """ + return unittest.skipUnless(is_pandas_available(), "test requires pandas")(test_case) + + +def require_pytesseract(test_case): + """ + Decorator marking a test that requires PyTesseract. These tests are skipped when PyTesseract isn't installed. + """ + return unittest.skipUnless(is_pytesseract_available(), "test requires PyTesseract")(test_case) + + +def require_pytorch_quantization(test_case): + """ + Decorator marking a test that requires PyTorch Quantization Toolkit. These tests are skipped when PyTorch + Quantization Toolkit isn't installed. + """ + return unittest.skipUnless(is_pytorch_quantization_available(), "test requires PyTorch Quantization Toolkit")( + test_case + ) + + +def require_vision(test_case): + """ + Decorator marking a test that requires the vision dependencies. These tests are skipped when torchaudio isn't + installed. + """ + return unittest.skipUnless(is_vision_available(), "test requires vision")(test_case) + + +def require_ftfy(test_case): + """ + Decorator marking a test that requires ftfy. These tests are skipped when ftfy isn't installed. + """ + return unittest.skipUnless(is_ftfy_available(), "test requires ftfy")(test_case) + + +def require_spacy(test_case): + """ + Decorator marking a test that requires SpaCy. These tests are skipped when SpaCy isn't installed. + """ + return unittest.skipUnless(is_spacy_available(), "test requires spacy")(test_case) + + +def require_decord(test_case): + """ + Decorator marking a test that requires decord. These tests are skipped when decord isn't installed. + """ + return unittest.skipUnless(is_decord_available(), "test requires decord")(test_case) + + +def require_torch_multi_gpu(test_case): + """ + Decorator marking a test that requires a multi-GPU setup (in PyTorch). These tests are skipped on a machine without + multiple GPUs. + + To run *only* the multi_gpu tests, assuming all test names contain multi_gpu: $ pytest -sv ./tests -k "multi_gpu" + """ + if not is_torch_available(): + return unittest.skip("test requires PyTorch")(test_case) + + import torch + + return unittest.skipUnless(torch.cuda.device_count() > 1, "test requires multiple GPUs")(test_case) + + +def require_torch_non_multi_gpu(test_case): + """ + Decorator marking a test that requires 0 or 1 GPU setup (in PyTorch). + """ + if not is_torch_available(): + return unittest.skip("test requires PyTorch")(test_case) + + import torch + + return unittest.skipUnless(torch.cuda.device_count() < 2, "test requires 0 or 1 GPU")(test_case) + + +def require_torch_up_to_2_gpus(test_case): + """ + Decorator marking a test that requires 0 or 1 or 2 GPU setup (in PyTorch). + """ + if not is_torch_available(): + return unittest.skip("test requires PyTorch")(test_case) + + import torch + + return unittest.skipUnless(torch.cuda.device_count() < 3, "test requires 0 or 1 or 2 GPUs")(test_case) + + +def require_torch_tpu(test_case): + """ + Decorator marking a test that requires a TPU (in PyTorch). + """ + return unittest.skipUnless(is_torch_tpu_available(check_device=False), "test requires PyTorch TPU")(test_case) + + +def require_torch_neuroncore(test_case): + """ + Decorator marking a test that requires NeuronCore (in PyTorch). + """ + return unittest.skipUnless(is_torch_neuroncore_available(check_device=False), "test requires PyTorch NeuronCore")( + test_case + ) + + +if is_torch_available(): + # Set env var CUDA_VISIBLE_DEVICES="" to force cpu-mode + import torch + + torch_device = "cuda" if torch.cuda.is_available() else "cpu" +else: + torch_device = None + +if is_tf_available(): + import tensorflow as tf + +if is_flax_available(): + import jax + + jax_device = jax.default_backend() +else: + jax_device = None + + +def require_torchdynamo(test_case): + """Decorator marking a test that requires TorchDynamo""" + return unittest.skipUnless(is_torchdynamo_available(), "test requires TorchDynamo")(test_case) + + +def require_torch_tensorrt_fx(test_case): + """Decorator marking a test that requires Torch-TensorRT FX""" + return unittest.skipUnless(is_torch_tensorrt_fx_available(), "test requires Torch-TensorRT FX")(test_case) + + +def require_torch_gpu(test_case): + """Decorator marking a test that requires CUDA and PyTorch.""" + return unittest.skipUnless(torch_device == "cuda", "test requires CUDA")(test_case) + + +def require_torch_bf16_gpu(test_case): + """Decorator marking a test that requires torch>=1.10, using Ampere GPU or newer arch with cuda>=11.0""" + return unittest.skipUnless( + is_torch_bf16_gpu_available(), + "test requires torch>=1.10, using Ampere GPU or newer arch with cuda>=11.0", + )(test_case) + + +def require_torch_bf16_cpu(test_case): + """Decorator marking a test that requires torch>=1.10, using CPU.""" + return unittest.skipUnless( + is_torch_bf16_cpu_available(), + "test requires torch>=1.10, using CPU", + )(test_case) + + +def require_torch_tf32(test_case): + """Decorator marking a test that requires Ampere or a newer GPU arch, cuda>=11 and torch>=1.7.""" + return unittest.skipUnless( + is_torch_tf32_available(), "test requires Ampere or a newer GPU arch, cuda>=11 and torch>=1.7" + )(test_case) + + +def require_detectron2(test_case): + """Decorator marking a test that requires detectron2.""" + return unittest.skipUnless(is_detectron2_available(), "test requires `detectron2`")(test_case) + + +def require_faiss(test_case): + """Decorator marking a test that requires faiss.""" + return unittest.skipUnless(is_faiss_available(), "test requires `faiss`")(test_case) + + +def require_optuna(test_case): + """ + Decorator marking a test that requires optuna. + + These tests are skipped when optuna isn't installed. + + """ + return unittest.skipUnless(is_optuna_available(), "test requires optuna")(test_case) + + +def require_ray(test_case): + """ + Decorator marking a test that requires Ray/tune. + + These tests are skipped when Ray/tune isn't installed. + + """ + return unittest.skipUnless(is_ray_available(), "test requires Ray/tune")(test_case) + + +def require_sigopt(test_case): + """ + Decorator marking a test that requires SigOpt. + + These tests are skipped when SigOpt isn't installed. + + """ + return unittest.skipUnless(is_sigopt_available(), "test requires SigOpt")(test_case) + + +def require_wandb(test_case): + """ + Decorator marking a test that requires wandb. + + These tests are skipped when wandb isn't installed. + + """ + return unittest.skipUnless(is_wandb_available(), "test requires wandb")(test_case) + + +def require_clearml(test_case): + """ + Decorator marking a test requires clearml. + + These tests are skipped when clearml isn't installed. + + """ + return unittest.skipUnless(is_clearml_available(), "test requires clearml")(test_case) + + +def require_soundfile(test_case): + """ + Decorator marking a test that requires soundfile + + These tests are skipped when soundfile isn't installed. + + """ + return unittest.skipUnless(is_soundfile_availble(), "test requires soundfile")(test_case) + + +def require_deepspeed(test_case): + """ + Decorator marking a test that requires deepspeed + """ + return unittest.skipUnless(is_deepspeed_available(), "test requires deepspeed")(test_case) + + +def require_fairscale(test_case): + """ + Decorator marking a test that requires fairscale + """ + return unittest.skipUnless(is_fairscale_available(), "test requires fairscale")(test_case) + + +def require_apex(test_case): + """ + Decorator marking a test that requires apex + """ + return unittest.skipUnless(is_apex_available(), "test requires apex")(test_case) + + +def require_bitsandbytes(test_case): + """ + Decorator for bits and bytes (bnb) dependency + """ + return unittest.skipUnless(is_bitsandbytes_available(), "test requires bnb")(test_case) + + +def require_optimum(test_case): + """ + Decorator for optimum dependency + """ + return unittest.skipUnless(is_optimum_available(), "test requires optimum")(test_case) + + +def require_phonemizer(test_case): + """ + Decorator marking a test that requires phonemizer + """ + return unittest.skipUnless(is_phonemizer_available(), "test requires phonemizer")(test_case) + + +def require_pyctcdecode(test_case): + """ + Decorator marking a test that requires pyctcdecode + """ + return unittest.skipUnless(is_pyctcdecode_available(), "test requires pyctcdecode")(test_case) + + +def require_librosa(test_case): + """ + Decorator marking a test that requires librosa + """ + return unittest.skipUnless(is_librosa_available(), "test requires librosa")(test_case) + + +def cmd_exists(cmd): + return shutil.which(cmd) is not None + + +def require_usr_bin_time(test_case): + """ + Decorator marking a test that requires `/usr/bin/time` + """ + return unittest.skipUnless(cmd_exists("/usr/bin/time"), "test requires /usr/bin/time")(test_case) + + +def require_sudachi(test_case): + """ + Decorator marking a test that requires sudachi + """ + return unittest.skipUnless(is_sudachi_available(), "test requires sudachi")(test_case) + + +def require_jumanpp(test_case): + """ + Decorator marking a test that requires jumanpp + """ + return unittest.skipUnless(is_jumanpp_available(), "test requires jumanpp")(test_case) + + +def require_cython(test_case): + """ + Decorator marking a test that requires jumanpp + """ + return unittest.skipUnless(is_cython_available(), "test requires cython")(test_case) + + +def get_gpu_count(): + """ + Return the number of available gpus (regardless of whether torch, tf or jax is used) + """ + if is_torch_available(): + import torch + + return torch.cuda.device_count() + elif is_tf_available(): + import tensorflow as tf + + return len(tf.config.list_physical_devices("GPU")) + elif is_flax_available(): + import jax + + return jax.device_count() + else: + return 0 + + +def get_tests_dir(append_path=None): + """ + Args: + append_path: optional path to append to the tests dir path + + Return: + The full path to the `tests` dir, so that the tests can be invoked from anywhere. Optionally `append_path` is + joined after the `tests` dir the former is provided. + + """ + # this function caller's __file__ + caller__file__ = inspect.stack()[1][1] + tests_dir = os.path.abspath(os.path.dirname(caller__file__)) + + while not tests_dir.endswith("tests"): + tests_dir = os.path.dirname(tests_dir) + + if append_path: + return os.path.join(tests_dir, append_path) + else: + return tests_dir + + +# +# Helper functions for dealing with testing text outputs +# The original code came from: +# https://github.com/fastai/fastai/blob/master/tests/utils/text.py + + +# When any function contains print() calls that get overwritten, like progress bars, +# a special care needs to be applied, since under pytest -s captured output (capsys +# or contextlib.redirect_stdout) contains any temporary printed strings, followed by +# \r's. This helper function ensures that the buffer will contain the same output +# with and without -s in pytest, by turning: +# foo bar\r tar mar\r final message +# into: +# final message +# it can handle a single string or a multiline buffer +def apply_print_resets(buf): + return re.sub(r"^.*\r", "", buf, 0, re.M) + + +def assert_screenout(out, what): + out_pr = apply_print_resets(out).lower() + match_str = out_pr.find(what.lower()) + assert match_str != -1, f"expecting to find {what} in output: f{out_pr}" + + +class CaptureStd: + """ + Context manager to capture: + + - stdout: replay it, clean it up and make it available via `obj.out` + - stderr: replay it and make it available via `obj.err` + + Args: + out (`bool`, *optional*, defaults to `True`): Whether to capture stdout or not. + err (`bool`, *optional*, defaults to `True`): Whether to capture stderr or not. + replay (`bool`, *optional*, defaults to `True`): Whether to replay or not. + By default each captured stream gets replayed back on context's exit, so that one can see what the test was + doing. If this is a not wanted behavior and the captured data shouldn't be replayed, pass `replay=False` to + disable this feature. + + Examples: + + ```python + # to capture stdout only with auto-replay + with CaptureStdout() as cs: + print("Secret message") + assert "message" in cs.out + + # to capture stderr only with auto-replay + import sys + + with CaptureStderr() as cs: + print("Warning: ", file=sys.stderr) + assert "Warning" in cs.err + + # to capture both streams with auto-replay + with CaptureStd() as cs: + print("Secret message") + print("Warning: ", file=sys.stderr) + assert "message" in cs.out + assert "Warning" in cs.err + + # to capture just one of the streams, and not the other, with auto-replay + with CaptureStd(err=False) as cs: + print("Secret message") + assert "message" in cs.out + # but best use the stream-specific subclasses + + # to capture without auto-replay + with CaptureStd(replay=False) as cs: + print("Secret message") + assert "message" in cs.out + ```""" + + def __init__(self, out=True, err=True, replay=True): + self.replay = replay + + if out: + self.out_buf = StringIO() + self.out = "error: CaptureStd context is unfinished yet, called too early" + else: + self.out_buf = None + self.out = "not capturing stdout" + + if err: + self.err_buf = StringIO() + self.err = "error: CaptureStd context is unfinished yet, called too early" + else: + self.err_buf = None + self.err = "not capturing stderr" + + def __enter__(self): + if self.out_buf: + self.out_old = sys.stdout + sys.stdout = self.out_buf + + if self.err_buf: + self.err_old = sys.stderr + sys.stderr = self.err_buf + + return self + + def __exit__(self, *exc): + if self.out_buf: + sys.stdout = self.out_old + captured = self.out_buf.getvalue() + if self.replay: + sys.stdout.write(captured) + self.out = apply_print_resets(captured) + + if self.err_buf: + sys.stderr = self.err_old + captured = self.err_buf.getvalue() + if self.replay: + sys.stderr.write(captured) + self.err = captured + + def __repr__(self): + msg = "" + if self.out_buf: + msg += f"stdout: {self.out}\n" + if self.err_buf: + msg += f"stderr: {self.err}\n" + return msg + + +# in tests it's the best to capture only the stream that's wanted, otherwise +# it's easy to miss things, so unless you need to capture both streams, use the +# subclasses below (less typing). Or alternatively, configure `CaptureStd` to +# disable the stream you don't need to test. + + +class CaptureStdout(CaptureStd): + """Same as CaptureStd but captures only stdout""" + + def __init__(self, replay=True): + super().__init__(err=False, replay=replay) + + +class CaptureStderr(CaptureStd): + """Same as CaptureStd but captures only stderr""" + + def __init__(self, replay=True): + super().__init__(out=False, replay=replay) + + +class CaptureLogger: + """ + Context manager to capture `logging` streams + + Args: + logger: 'logging` logger object + + Returns: + The captured output is available via `self.out` + + Example: + + ```python + >>> from transformers import logging + >>> from transformers.testing_utils import CaptureLogger + + >>> msg = "Testing 1, 2, 3" + >>> logging.set_verbosity_info() + >>> logger = logging.get_logger("transformers.models.bart.tokenization_bart") + >>> with CaptureLogger(logger) as cl: + ... logger.info(msg) + >>> assert cl.out, msg + "\n" + ``` + """ + + def __init__(self, logger): + self.logger = logger + self.io = StringIO() + self.sh = logging.StreamHandler(self.io) + self.out = "" + + def __enter__(self): + self.logger.addHandler(self.sh) + return self + + def __exit__(self, *exc): + self.logger.removeHandler(self.sh) + self.out = self.io.getvalue() + + def __repr__(self): + return f"captured: {self.out}\n" + + +@contextlib.contextmanager +def LoggingLevel(level): + """ + This is a context manager to temporarily change transformers modules logging level to the desired value and have it + restored to the original setting at the end of the scope. + + Example: + + ```python + with LoggingLevel(logging.INFO): + AutoModel.from_pretrained("gpt2") # calls logger.info() several times + ``` + """ + orig_level = transformers_logging.get_verbosity() + try: + transformers_logging.set_verbosity(level) + yield + finally: + transformers_logging.set_verbosity(orig_level) + + +@contextlib.contextmanager +# adapted from https://stackoverflow.com/a/64789046/9201239 +def ExtendSysPath(path: Union[str, os.PathLike]) -> Iterator[None]: + """ + Temporary add given path to `sys.path`. + + Usage : + + ```python + with ExtendSysPath("/path/to/dir"): + mymodule = importlib.import_module("mymodule") + ``` + """ + + path = os.fspath(path) + try: + sys.path.insert(0, path) + yield + finally: + sys.path.remove(path) + + +class TestCasePlus(unittest.TestCase): + """ + This class extends *unittest.TestCase* with additional features. + + Feature 1: A set of fully resolved important file and dir path accessors. + + In tests often we need to know where things are relative to the current test file, and it's not trivial since the + test could be invoked from more than one directory or could reside in sub-directories with different depths. This + class solves this problem by sorting out all the basic paths and provides easy accessors to them: + + - `pathlib` objects (all fully resolved): + + - `test_file_path` - the current test file path (=`__file__`) + - `test_file_dir` - the directory containing the current test file + - `tests_dir` - the directory of the `tests` test suite + - `examples_dir` - the directory of the `examples` test suite + - `repo_root_dir` - the directory of the repository + - `src_dir` - the directory of `src` (i.e. where the `transformers` sub-dir resides) + + - stringified paths---same as above but these return paths as strings, rather than `pathlib` objects: + + - `test_file_path_str` + - `test_file_dir_str` + - `tests_dir_str` + - `examples_dir_str` + - `repo_root_dir_str` + - `src_dir_str` + + Feature 2: Flexible auto-removable temporary dirs which are guaranteed to get removed at the end of test. + + 1. Create a unique temporary dir: + + ```python + def test_whatever(self): + tmp_dir = self.get_auto_remove_tmp_dir() + ``` + + `tmp_dir` will contain the path to the created temporary dir. It will be automatically removed at the end of the + test. + + + 2. Create a temporary dir of my choice, ensure it's empty before the test starts and don't + empty it after the test. + + ```python + def test_whatever(self): + tmp_dir = self.get_auto_remove_tmp_dir("./xxx") + ``` + + This is useful for debug when you want to monitor a specific directory and want to make sure the previous tests + didn't leave any data in there. + + 3. You can override the first two options by directly overriding the `before` and `after` args, leading to the + following behavior: + + `before=True`: the temporary dir will always be cleared at the beginning of the test. + + `before=False`: if the temporary dir already existed, any existing files will remain there. + + `after=True`: the temporary dir will always be deleted at the end of the test. + + `after=False`: the temporary dir will always be left intact at the end of the test. + + Note 1: In order to run the equivalent of `rm -r` safely, only subdirs of the project repository checkout are + allowed if an explicit `tmp_dir` is used, so that by mistake no `/tmp` or similar important part of the filesystem + will get nuked. i.e. please always pass paths that start with `./` + + Note 2: Each test can register multiple temporary dirs and they all will get auto-removed, unless requested + otherwise. + + Feature 3: Get a copy of the `os.environ` object that sets up `PYTHONPATH` specific to the current test suite. This + is useful for invoking external programs from the test suite - e.g. distributed training. + + + ```python + def test_whatever(self): + env = self.get_env() + ```""" + + def setUp(self): + # get_auto_remove_tmp_dir feature: + self.teardown_tmp_dirs = [] + + # figure out the resolved paths for repo_root, tests, examples, etc. + self._test_file_path = inspect.getfile(self.__class__) + path = Path(self._test_file_path).resolve() + self._test_file_dir = path.parents[0] + for up in [1, 2, 3]: + tmp_dir = path.parents[up] + if (tmp_dir / "src").is_dir() and (tmp_dir / "tests").is_dir(): + break + if tmp_dir: + self._repo_root_dir = tmp_dir + else: + raise ValueError(f"can't figure out the root of the repo from {self._test_file_path}") + self._tests_dir = self._repo_root_dir / "tests" + self._examples_dir = self._repo_root_dir / "examples" + self._src_dir = self._repo_root_dir / "src" + + @property + def test_file_path(self): + return self._test_file_path + + @property + def test_file_path_str(self): + return str(self._test_file_path) + + @property + def test_file_dir(self): + return self._test_file_dir + + @property + def test_file_dir_str(self): + return str(self._test_file_dir) + + @property + def tests_dir(self): + return self._tests_dir + + @property + def tests_dir_str(self): + return str(self._tests_dir) + + @property + def examples_dir(self): + return self._examples_dir + + @property + def examples_dir_str(self): + return str(self._examples_dir) + + @property + def repo_root_dir(self): + return self._repo_root_dir + + @property + def repo_root_dir_str(self): + return str(self._repo_root_dir) + + @property + def src_dir(self): + return self._src_dir + + @property + def src_dir_str(self): + return str(self._src_dir) + + def get_env(self): + """ + Return a copy of the `os.environ` object that sets up `PYTHONPATH` correctly, depending on the test suite it's + invoked from. This is useful for invoking external programs from the test suite - e.g. distributed training. + + It always inserts `./src` first, then `./tests` or `./examples` depending on the test suite type and finally + the preset `PYTHONPATH` if any (all full resolved paths). + + """ + env = os.environ.copy() + paths = [self.src_dir_str] + if "/examples" in self.test_file_dir_str: + paths.append(self.examples_dir_str) + else: + paths.append(self.tests_dir_str) + paths.append(env.get("PYTHONPATH", "")) + + env["PYTHONPATH"] = ":".join(paths) + return env + + def get_auto_remove_tmp_dir(self, tmp_dir=None, before=None, after=None): + """ + Args: + tmp_dir (`string`, *optional*): + if `None`: + + - a unique temporary path will be created + - sets `before=True` if `before` is `None` + - sets `after=True` if `after` is `None` + else: + + - `tmp_dir` will be created + - sets `before=True` if `before` is `None` + - sets `after=False` if `after` is `None` + before (`bool`, *optional*): + If `True` and the `tmp_dir` already exists, make sure to empty it right away if `False` and the + `tmp_dir` already exists, any existing files will remain there. + after (`bool`, *optional*): + If `True`, delete the `tmp_dir` at the end of the test if `False`, leave the `tmp_dir` and its contents + intact at the end of the test. + + Returns: + tmp_dir(`string`): either the same value as passed via *tmp_dir* or the path to the auto-selected tmp dir + """ + if tmp_dir is not None: + # defining the most likely desired behavior for when a custom path is provided. + # this most likely indicates the debug mode where we want an easily locatable dir that: + # 1. gets cleared out before the test (if it already exists) + # 2. is left intact after the test + if before is None: + before = True + if after is None: + after = False + + # using provided path + path = Path(tmp_dir).resolve() + + # to avoid nuking parts of the filesystem, only relative paths are allowed + if not tmp_dir.startswith("./"): + raise ValueError( + f"`tmp_dir` can only be a relative path, i.e. `./some/path`, but received `{tmp_dir}`" + ) + + # ensure the dir is empty to start with + if before is True and path.exists(): + shutil.rmtree(tmp_dir, ignore_errors=True) + + path.mkdir(parents=True, exist_ok=True) + + else: + # defining the most likely desired behavior for when a unique tmp path is auto generated + # (not a debug mode), here we require a unique tmp dir that: + # 1. is empty before the test (it will be empty in this situation anyway) + # 2. gets fully removed after the test + if before is None: + before = True + if after is None: + after = True + + # using unique tmp dir (always empty, regardless of `before`) + tmp_dir = tempfile.mkdtemp() + + if after is True: + # register for deletion + self.teardown_tmp_dirs.append(tmp_dir) + + return tmp_dir + + def python_one_liner_max_rss(self, one_liner_str): + """ + Runs the passed python one liner (just the code) and returns how much max cpu memory was used to run the + program. + + Args: + one_liner_str (`string`): + a python one liner code that gets passed to `python -c` + + Returns: + max cpu memory bytes used to run the program. This value is likely to vary slightly from run to run. + + Requirements: + this helper needs `/usr/bin/time` to be installed (`apt install time`) + + Example: + + ``` + one_liner_str = 'from transformers import AutoModel; AutoModel.from_pretrained("t5-large")' + max_rss = self.python_one_liner_max_rss(one_liner_str) + ``` + """ + + if not cmd_exists("/usr/bin/time"): + raise ValueError("/usr/bin/time is required, install with `apt install time`") + + cmd = shlex.split(f"/usr/bin/time -f %M python -c '{one_liner_str}'") + with CaptureStd() as cs: + execute_subprocess_async(cmd, env=self.get_env()) + # returned data is in KB so convert to bytes + max_rss = int(cs.err.split("\n")[-2].replace("stderr: ", "")) * 1024 + return max_rss + + def tearDown(self): + # get_auto_remove_tmp_dir feature: remove registered temp dirs + for path in self.teardown_tmp_dirs: + shutil.rmtree(path, ignore_errors=True) + self.teardown_tmp_dirs = [] + + +def mockenv(**kwargs): + """ + this is a convenience wrapper, that allows this :: + + @mockenv(RUN_SLOW=True, USE_TF=False) def test_something(): + run_slow = os.getenv("RUN_SLOW", False) use_tf = os.getenv("USE_TF", False) + + """ + return mock.patch.dict(os.environ, kwargs) + + +# from https://stackoverflow.com/a/34333710/9201239 +@contextlib.contextmanager +def mockenv_context(*remove, **update): + """ + Temporarily updates the `os.environ` dictionary in-place. Similar to mockenv + + The `os.environ` dictionary is updated in-place so that the modification is sure to work in all situations. + + Args: + remove: Environment variables to remove. + update: Dictionary of environment variables and values to add/update. + """ + env = os.environ + update = update or {} + remove = remove or [] + + # List of environment variables being updated or removed. + stomped = (set(update.keys()) | set(remove)) & set(env.keys()) + # Environment variables and values to restore on exit. + update_after = {k: env[k] for k in stomped} + # Environment variables and values to remove on exit. + remove_after = frozenset(k for k in update if k not in env) + + try: + env.update(update) + [env.pop(k, None) for k in remove] + yield + finally: + env.update(update_after) + [env.pop(k) for k in remove_after] + + +# --- pytest conf functions --- # + +# to avoid multiple invocation from tests/conftest.py and examples/conftest.py - make sure it's called only once +pytest_opt_registered = {} + + +def pytest_addoption_shared(parser): + """ + This function is to be called from `conftest.py` via `pytest_addoption` wrapper that has to be defined there. + + It allows loading both `conftest.py` files at once without causing a failure due to adding the same `pytest` + option. + + """ + option = "--make-reports" + if option not in pytest_opt_registered: + parser.addoption( + option, + action="store", + default=False, + help="generate report files. The value of this option is used as a prefix to report names", + ) + pytest_opt_registered[option] = 1 + + +def pytest_terminal_summary_main(tr, id): + """ + Generate multiple reports at the end of test suite run - each report goes into a dedicated file in the current + directory. The report files are prefixed with the test suite name. + + This function emulates --duration and -rA pytest arguments. + + This function is to be called from `conftest.py` via `pytest_terminal_summary` wrapper that has to be defined + there. + + Args: + - tr: `terminalreporter` passed from `conftest.py` + - id: unique id like `tests` or `examples` that will be incorporated into the final reports filenames - this is + needed as some jobs have multiple runs of pytest, so we can't have them overwrite each other. + + NB: this functions taps into a private _pytest API and while unlikely, it could break should pytest do internal + changes - also it calls default internal methods of terminalreporter which can be hijacked by various `pytest-` + plugins and interfere. + + """ + from _pytest.config import create_terminal_writer + + if not len(id): + id = "tests" + + config = tr.config + orig_writer = config.get_terminal_writer() + orig_tbstyle = config.option.tbstyle + orig_reportchars = tr.reportchars + + dir = f"reports/{id}" + Path(dir).mkdir(parents=True, exist_ok=True) + report_files = { + k: f"{dir}/{k}.txt" + for k in [ + "durations", + "errors", + "failures_long", + "failures_short", + "failures_line", + "passes", + "stats", + "summary_short", + "warnings", + ] + } + + # custom durations report + # note: there is no need to call pytest --durations=XX to get this separate report + # adapted from https://github.com/pytest-dev/pytest/blob/897f151e/src/_pytest/runner.py#L66 + dlist = [] + for replist in tr.stats.values(): + for rep in replist: + if hasattr(rep, "duration"): + dlist.append(rep) + if dlist: + dlist.sort(key=lambda x: x.duration, reverse=True) + with open(report_files["durations"], "w") as f: + durations_min = 0.05 # sec + f.write("slowest durations\n") + for i, rep in enumerate(dlist): + if rep.duration < durations_min: + f.write(f"{len(dlist)-i} durations < {durations_min} secs were omitted") + break + f.write(f"{rep.duration:02.2f}s {rep.when:<8} {rep.nodeid}\n") + + def summary_failures_short(tr): + # expecting that the reports were --tb=long (default) so we chop them off here to the last frame + reports = tr.getreports("failed") + if not reports: + return + tr.write_sep("=", "FAILURES SHORT STACK") + for rep in reports: + msg = tr._getfailureheadline(rep) + tr.write_sep("_", msg, red=True, bold=True) + # chop off the optional leading extra frames, leaving only the last one + longrepr = re.sub(r".*_ _ _ (_ ){10,}_ _ ", "", rep.longreprtext, 0, re.M | re.S) + tr._tw.line(longrepr) + # note: not printing out any rep.sections to keep the report short + + # use ready-made report funcs, we are just hijacking the filehandle to log to a dedicated file each + # adapted from https://github.com/pytest-dev/pytest/blob/897f151e/src/_pytest/terminal.py#L814 + # note: some pytest plugins may interfere by hijacking the default `terminalreporter` (e.g. + # pytest-instafail does that) + + # report failures with line/short/long styles + config.option.tbstyle = "auto" # full tb + with open(report_files["failures_long"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.summary_failures() + + # config.option.tbstyle = "short" # short tb + with open(report_files["failures_short"], "w") as f: + tr._tw = create_terminal_writer(config, f) + summary_failures_short(tr) + + config.option.tbstyle = "line" # one line per error + with open(report_files["failures_line"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.summary_failures() + + with open(report_files["errors"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.summary_errors() + + with open(report_files["warnings"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.summary_warnings() # normal warnings + tr.summary_warnings() # final warnings + + tr.reportchars = "wPpsxXEf" # emulate -rA (used in summary_passes() and short_test_summary()) + + # Skip the `passes` report, as it starts to take more than 5 minutes, and sometimes it timeouts on CircleCI if it + # takes > 10 minutes (as this part doesn't generate any output on the terminal). + # (also, it seems there is no useful information in this report, and we rarely need to read it) + # with open(report_files["passes"], "w") as f: + # tr._tw = create_terminal_writer(config, f) + # tr.summary_passes() + + with open(report_files["summary_short"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.short_test_summary() + + with open(report_files["stats"], "w") as f: + tr._tw = create_terminal_writer(config, f) + tr.summary_stats() + + # restore: + tr._tw = orig_writer + tr.reportchars = orig_reportchars + config.option.tbstyle = orig_tbstyle + + +# --- distributed testing functions --- # + +# adapted from https://stackoverflow.com/a/59041913/9201239 +import asyncio # noqa + + +class _RunOutput: + def __init__(self, returncode, stdout, stderr): + self.returncode = returncode + self.stdout = stdout + self.stderr = stderr + + +async def _read_stream(stream, callback): + while True: + line = await stream.readline() + if line: + callback(line) + else: + break + + +async def _stream_subprocess(cmd, env=None, stdin=None, timeout=None, quiet=False, echo=False) -> _RunOutput: + if echo: + print("\nRunning: ", " ".join(cmd)) + + p = await asyncio.create_subprocess_exec( + cmd[0], + *cmd[1:], + stdin=stdin, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + env=env, + ) + + # note: there is a warning for a possible deadlock when using `wait` with huge amounts of data in the pipe + # https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.asyncio.subprocess.Process.wait + # + # If it starts hanging, will need to switch to the following code. The problem is that no data + # will be seen until it's done and if it hangs for example there will be no debug info. + # out, err = await p.communicate() + # return _RunOutput(p.returncode, out, err) + + out = [] + err = [] + + def tee(line, sink, pipe, label=""): + line = line.decode("utf-8").rstrip() + sink.append(line) + if not quiet: + print(label, line, file=pipe) + + # XXX: the timeout doesn't seem to make any difference here + await asyncio.wait( + [ + _read_stream(p.stdout, lambda l: tee(l, out, sys.stdout, label="stdout:")), + _read_stream(p.stderr, lambda l: tee(l, err, sys.stderr, label="stderr:")), + ], + timeout=timeout, + ) + return _RunOutput(await p.wait(), out, err) + + +def execute_subprocess_async(cmd, env=None, stdin=None, timeout=180, quiet=False, echo=True) -> _RunOutput: + loop = asyncio.get_event_loop() + result = loop.run_until_complete( + _stream_subprocess(cmd, env=env, stdin=stdin, timeout=timeout, quiet=quiet, echo=echo) + ) + + cmd_str = " ".join(cmd) + if result.returncode > 0: + stderr = "\n".join(result.stderr) + raise RuntimeError( + f"'{cmd_str}' failed with returncode {result.returncode}\n\n" + f"The combined stderr from workers follows:\n{stderr}" + ) + + # check that the subprocess actually did run and produced some output, should the test rely on + # the remote side to do the testing + if not result.stdout and not result.stderr: + raise RuntimeError(f"'{cmd_str}' produced no output.") + + return result + + +def pytest_xdist_worker_id(): + """ + Returns an int value of worker's numerical id under `pytest-xdist`'s concurrent workers `pytest -n N` regime, or 0 + if `-n 1` or `pytest-xdist` isn't being used. + """ + worker = os.environ.get("PYTEST_XDIST_WORKER", "gw0") + worker = re.sub(r"^gw", "", worker, 0, re.M) + return int(worker) + + +def get_torch_dist_unique_port(): + """ + Returns a port number that can be fed to `torch.distributed.launch`'s `--master_port` argument. + + Under `pytest-xdist` it adds a delta number based on a worker id so that concurrent tests don't try to use the same + port at once. + """ + port = 29500 + uniq_delta = pytest_xdist_worker_id() + return port + uniq_delta + + +def nested_simplify(obj, decimals=3): + """ + Simplifies an object by rounding float numbers, and downcasting tensors/numpy arrays to get simple equality test + within tests. + """ + import numpy as np + + if isinstance(obj, list): + return [nested_simplify(item, decimals) for item in obj] + if isinstance(obj, tuple): + return tuple([nested_simplify(item, decimals) for item in obj]) + elif isinstance(obj, np.ndarray): + return nested_simplify(obj.tolist()) + elif isinstance(obj, Mapping): + return {nested_simplify(k, decimals): nested_simplify(v, decimals) for k, v in obj.items()} + elif isinstance(obj, (str, int, np.int64)): + return obj + elif obj is None: + return obj + elif is_torch_available() and isinstance(obj, torch.Tensor): + return nested_simplify(obj.tolist(), decimals) + elif is_tf_available() and tf.is_tensor(obj): + return nested_simplify(obj.numpy().tolist()) + elif isinstance(obj, float): + return round(obj, decimals) + elif isinstance(obj, (np.int32, np.float32)): + return nested_simplify(obj.item(), decimals) + else: + raise Exception(f"Not supported: {type(obj)}") + + +def check_json_file_has_correct_format(file_path): + with open(file_path, "r") as f: + lines = f.readlines() + if len(lines) == 1: + # length can only be 1 if dict is empty + assert lines[0] == "{}" + else: + # otherwise make sure json has correct format (at least 3 lines) + assert len(lines) >= 3 + # each key one line, ident should be 2, min length is 3 + assert lines[0].strip() == "{" + for line in lines[1:-1]: + left_indent = len(lines[1]) - len(lines[1].lstrip()) + assert left_indent == 2 + assert lines[-1].strip() == "}" + + +def to_2tuple(x): + if isinstance(x, collections.abc.Iterable): + return x + return (x, x) + + +# These utils relate to ensuring the right error message is received when running scripts +class SubprocessCallException(Exception): + pass + + +def run_command(command: List[str], return_stdout=False): + """ + Runs `command` with `subprocess.check_output` and will potentially return the `stdout`. Will also properly capture + if an error occured while running `command` + """ + try: + output = subprocess.check_output(command, stderr=subprocess.STDOUT) + if return_stdout: + if hasattr(output, "decode"): + output = output.decode("utf-8") + return output + except subprocess.CalledProcessError as e: + raise SubprocessCallException( + f"Command `{' '.join(command)}` failed with the following error:\n\n{e.output.decode()}" + ) from e + + +class RequestCounter: + """ + Helper class that will count all requests made online. + """ + + def __enter__(self): + self.head_request_count = 0 + self.get_request_count = 0 + self.other_request_count = 0 + + # Mock `get_session` to count HTTP calls. + self.old_get_session = huggingface_hub.utils._http.get_session + self.session = requests.Session() + self.session.request = self.new_request + huggingface_hub.utils._http.get_session = lambda: self.session + return self + + def __exit__(self, *args, **kwargs): + huggingface_hub.utils._http.get_session = self.old_get_session + + def new_request(self, method, **kwargs): + if method == "GET": + self.get_request_count += 1 + elif method == "HEAD": + self.head_request_count += 1 + else: + self.other_request_count += 1 + + return requests.request(method=method, **kwargs) + + +def is_flaky(max_attempts: int = 5, wait_before_retry: Optional[float] = None, description: Optional[str] = None): + """ + To decorate flaky tests. They will be retried on failures. + + Args: + max_attempts (`int`, *optional*, defaults to 5): + The maximum number of attempts to retry the flaky test. + wait_before_retry (`float`, *optional*): + If provided, will wait that number of seconds before retrying the test. + description (`str`, *optional*): + A string to describe the situation (what / where / why is flaky, link to GH issue/PR comments, errors, + etc.) + """ + + def decorator(test_func_ref): + @functools.wraps(test_func_ref) + def wrapper(*args, **kwargs): + retry_count = 1 + + while retry_count < max_attempts: + try: + return test_func_ref(*args, **kwargs) + + except Exception as err: + print(f"Test failed with {err} at try {retry_count}/{max_attempts}.", file=sys.stderr) + if wait_before_retry is not None: + time.sleep(wait_before_retry) + retry_count += 1 + + return test_func_ref(*args, **kwargs) + + return wrapper + + return decorator + + +def run_test_in_subprocess(test_case, target_func, inputs=None, timeout=None): + """ + To run a test in a subprocess. In particular, this can avoid (GPU) memory issue. + + Args: + test_case (`unittest.TestCase`): + The test that will run `target_func`. + target_func (`Callable`): + The function implementing the actual testing logic. + inputs (`dict`, *optional*, defaults to `None`): + The inputs that will be passed to `target_func` through an (input) queue. + timeout (`int`, *optional*, defaults to `None`): + The timeout (in seconds) that will be passed to the input and output queues. If not specified, the env. + variable `PYTEST_TIMEOUT` will be checked. If still `None`, its value will be set to `600`. + """ + if timeout is None: + timeout = int(os.environ.get("PYTEST_TIMEOUT", 600)) + + start_methohd = "spawn" + ctx = multiprocessing.get_context(start_methohd) + + input_queue = ctx.Queue(1) + output_queue = ctx.JoinableQueue(1) + + # We can't send `unittest.TestCase` to the child, otherwise we get issues regarding pickle. + input_queue.put(inputs, timeout=timeout) + + process = ctx.Process(target=target_func, args=(input_queue, output_queue, timeout)) + process.start() + # Kill the child process if we can't get outputs from it in time: otherwise, the hanging subprocess prevents + # the test to exit properly. + try: + results = output_queue.get(timeout=timeout) + output_queue.task_done() + except Exception as e: + process.terminate() + test_case.fail(e) + process.join(timeout=timeout) + + if results["error"] is not None: + test_case.fail(f'{results["error"]}') diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/time_series_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/time_series_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b07451253e87d800b5e2974ce1afaeb882e3b809 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/time_series_utils.py @@ -0,0 +1,225 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Time series distributional output classes and utilities. +""" +from typing import Callable, Dict, Optional, Tuple + +import torch +from torch import nn +from torch.distributions import ( + AffineTransform, + Distribution, + Independent, + NegativeBinomial, + Normal, + StudentT, + TransformedDistribution, +) + + +class AffineTransformed(TransformedDistribution): + def __init__(self, base_distribution: Distribution, loc=None, scale=None, event_dim=0): + self.scale = 1.0 if scale is None else scale + self.loc = 0.0 if loc is None else loc + + super().__init__(base_distribution, [AffineTransform(loc=self.loc, scale=self.scale, event_dim=event_dim)]) + + @property + def mean(self): + """ + Returns the mean of the distribution. + """ + return self.base_dist.mean * self.scale + self.loc + + @property + def variance(self): + """ + Returns the variance of the distribution. + """ + return self.base_dist.variance * self.scale**2 + + @property + def stddev(self): + """ + Returns the standard deviation of the distribution. + """ + return self.variance.sqrt() + + +class ParameterProjection(nn.Module): + def __init__( + self, in_features: int, args_dim: Dict[str, int], domain_map: Callable[..., Tuple[torch.Tensor]], **kwargs + ) -> None: + super().__init__(**kwargs) + self.args_dim = args_dim + self.proj = nn.ModuleList([nn.Linear(in_features, dim) for dim in args_dim.values()]) + self.domain_map = domain_map + + def forward(self, x: torch.Tensor) -> Tuple[torch.Tensor]: + params_unbounded = [proj(x) for proj in self.proj] + + return self.domain_map(*params_unbounded) + + +class LambdaLayer(nn.Module): + def __init__(self, function): + super().__init__() + self.function = function + + def forward(self, x, *args): + return self.function(x, *args) + + +class DistributionOutput: + distribution_class: type + in_features: int + args_dim: Dict[str, int] + + def __init__(self, dim: int = 1) -> None: + self.dim = dim + self.args_dim = {k: dim * self.args_dim[k] for k in self.args_dim} + + def _base_distribution(self, distr_args): + if self.dim == 1: + return self.distribution_class(*distr_args) + else: + return Independent(self.distribution_class(*distr_args), 1) + + def distribution( + self, + distr_args, + loc: Optional[torch.Tensor] = None, + scale: Optional[torch.Tensor] = None, + ) -> Distribution: + distr = self._base_distribution(distr_args) + if loc is None and scale is None: + return distr + else: + return AffineTransformed(distr, loc=loc, scale=scale, event_dim=self.event_dim) + + @property + def event_shape(self) -> Tuple: + r""" + Shape of each individual event contemplated by the distributions that this object constructs. + """ + return () if self.dim == 1 else (self.dim,) + + @property + def event_dim(self) -> int: + r""" + Number of event dimensions, i.e., length of the `event_shape` tuple, of the distributions that this object + constructs. + """ + return len(self.event_shape) + + @property + def value_in_support(self) -> float: + r""" + A float that will have a valid numeric value when computing the log-loss of the corresponding distribution. By + default 0.0. This value will be used when padding data series. + """ + return 0.0 + + def get_parameter_projection(self, in_features: int) -> nn.Module: + r""" + Return the parameter projection layer that maps the input to the appropriate parameters of the distribution. + """ + return ParameterProjection( + in_features=in_features, + args_dim=self.args_dim, + domain_map=LambdaLayer(self.domain_map), + ) + + def domain_map(self, *args: torch.Tensor): + r""" + Converts arguments to the right shape and domain. The domain depends on the type of distribution, while the + correct shape is obtained by reshaping the trailing axis in such a way that the returned tensors define a + distribution of the right event_shape. + """ + raise NotImplementedError() + + @staticmethod + def squareplus(x: torch.Tensor) -> torch.Tensor: + r""" + Helper to map inputs to the positive orthant by applying the square-plus operation. Reference: + https://twitter.com/jon_barron/status/1387167648669048833 + """ + return (x + torch.sqrt(torch.square(x) + 4.0)) / 2.0 + + +class StudentTOutput(DistributionOutput): + """ + Student-T distribution output class. + """ + + args_dim: Dict[str, int] = {"df": 1, "loc": 1, "scale": 1} + distribution_class: type = StudentT + + @classmethod + def domain_map(cls, df: torch.Tensor, loc: torch.Tensor, scale: torch.Tensor): + scale = cls.squareplus(scale) + df = 2.0 + cls.squareplus(df) + return df.squeeze(-1), loc.squeeze(-1), scale.squeeze(-1) + + +class NormalOutput(DistributionOutput): + """ + Normal distribution output class. + """ + + args_dim: Dict[str, int] = {"loc": 1, "scale": 1} + distribution_class: type = Normal + + @classmethod + def domain_map(cls, loc: torch.Tensor, scale: torch.Tensor): + scale = cls.squareplus(scale) + return loc.squeeze(-1), scale.squeeze(-1) + + +class NegativeBinomialOutput(DistributionOutput): + """ + Negative Binomial distribution output class. + """ + + args_dim: Dict[str, int] = {"total_count": 1, "logits": 1} + distribution_class: type = NegativeBinomial + + @classmethod + def domain_map(cls, total_count: torch.Tensor, logits: torch.Tensor): + total_count = cls.squareplus(total_count) + return total_count.squeeze(-1), logits.squeeze(-1) + + def _base_distribution(self, distr_args) -> Distribution: + total_count, logits = distr_args + if self.dim == 1: + return self.distribution_class(total_count=total_count, logits=logits) + else: + return Independent(self.distribution_class(total_count=total_count, logits=logits), 1) + + # Overwrites the parent class method. We cannot scale using the affine + # transformation since negative binomial should return integers. Instead + # we scale the parameters. + def distribution( + self, distr_args, loc: Optional[torch.Tensor] = None, scale: Optional[torch.Tensor] = None + ) -> Distribution: + total_count, logits = distr_args + + if scale is not None: + # See scaling property of Gamma. + logits += scale.log() + + return self._base_distribution((total_count, logits)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_base.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_base.py new file mode 100644 index 0000000000000000000000000000000000000000..a186c8338badcced31f899d683ba446468291dd8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_base.py @@ -0,0 +1,3802 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Base classes common to both the slow and the fast tokenization classes: PreTrainedTokenizerBase (host all the user +fronting encoding methods) Special token mixing (host the special tokens logic) and BatchEncoding (wrap the dictionary +of output with special method for the Fast tokenizers) +""" + +import copy +import json +import os +import re +import warnings +from collections import OrderedDict, UserDict +from collections.abc import Mapping, Sized +from contextlib import contextmanager +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Union + +import numpy as np +from packaging import version + +from . import __version__ +from .dynamic_module_utils import custom_object_save +from .utils import ( + ExplicitEnum, + PaddingStrategy, + PushToHubMixin, + TensorType, + add_end_docstrings, + add_model_info_to_auto_map, + cached_file, + copy_func, + download_url, + extract_commit_hash, + is_flax_available, + is_jax_tensor, + is_numpy_array, + is_offline_mode, + is_remote_url, + is_tf_available, + is_tf_tensor, + is_tokenizers_available, + is_torch_available, + is_torch_device, + is_torch_tensor, + logging, + requires_backends, + to_py_obj, +) + + +if TYPE_CHECKING: + if is_torch_available(): + import torch + if is_tf_available(): + import tensorflow as tf + if is_flax_available(): + import jax.numpy as jnp # noqa: F401 + + +if is_tokenizers_available(): + from tokenizers import AddedToken + from tokenizers import Encoding as EncodingFast +else: + + @dataclass(frozen=True, eq=True) + class AddedToken: + """ + AddedToken represents a token to be added to a Tokenizer An AddedToken can have special options defining the + way it should behave. + """ + + content: str = field(default_factory=str) + single_word: bool = False + lstrip: bool = False + rstrip: bool = False + normalized: bool = True + + def __getstate__(self): + return self.__dict__ + + @dataclass + class EncodingFast: + """This is dummy class because without the `tokenizers` library we don't have these objects anyway""" + + pass + + +logger = logging.get_logger(__name__) + +VERY_LARGE_INTEGER = int(1e30) # This is used to set the max input length for a model with infinite size input +LARGE_INTEGER = int(1e20) # This is used when we need something big but slightly smaller than VERY_LARGE_INTEGER + +# Define type aliases and NamedTuples +TextInput = str +PreTokenizedInput = List[str] +EncodedInput = List[int] +TextInputPair = Tuple[str, str] +PreTokenizedInputPair = Tuple[List[str], List[str]] +EncodedInputPair = Tuple[List[int], List[int]] + + +# Slow tokenizers used to be saved in three separated files +SPECIAL_TOKENS_MAP_FILE = "special_tokens_map.json" +ADDED_TOKENS_FILE = "added_tokens.json" +TOKENIZER_CONFIG_FILE = "tokenizer_config.json" + +# Fast tokenizers (provided by HuggingFace tokenizer's library) can be saved in a single file +FULL_TOKENIZER_FILE = "tokenizer.json" +_re_tokenizer_file = re.compile(r"tokenizer\.(.*)\.json") + + +class TruncationStrategy(ExplicitEnum): + """ + Possible values for the `truncation` argument in [`PreTrainedTokenizerBase.__call__`]. Useful for tab-completion in + an IDE. + """ + + ONLY_FIRST = "only_first" + ONLY_SECOND = "only_second" + LONGEST_FIRST = "longest_first" + DO_NOT_TRUNCATE = "do_not_truncate" + + +class CharSpan(NamedTuple): + """ + Character span in the original string. + + Args: + start (`int`): Index of the first character in the original string. + end (`int`): Index of the character following the last character in the original string. + """ + + start: int + end: int + + +class TokenSpan(NamedTuple): + """ + Token span in an encoded string (list of tokens). + + Args: + start (`int`): Index of the first token in the span. + end (`int`): Index of the token following the last token in the span. + """ + + start: int + end: int + + +class BatchEncoding(UserDict): + """ + Holds the output of the [`~tokenization_utils_base.PreTrainedTokenizerBase.__call__`], + [`~tokenization_utils_base.PreTrainedTokenizerBase.encode_plus`] and + [`~tokenization_utils_base.PreTrainedTokenizerBase.batch_encode_plus`] methods (tokens, attention_masks, etc). + + This class is derived from a python dictionary and can be used as a dictionary. In addition, this class exposes + utility methods to map from word/character space to token space. + + Args: + data (`dict`): + Dictionary of lists/arrays/tensors returned by the `__call__`/`encode_plus`/`batch_encode_plus` methods + ('input_ids', 'attention_mask', etc.). + encoding (`tokenizers.Encoding` or `Sequence[tokenizers.Encoding]`, *optional*): + If the tokenizer is a fast tokenizer which outputs additional information like mapping from word/character + space to token space the `tokenizers.Encoding` instance or list of instance (for batches) hold this + information. + tensor_type (`Union[None, str, TensorType]`, *optional*): + You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + initialization. + prepend_batch_axis (`bool`, *optional*, defaults to `False`): + Whether or not to add a batch axis when converting to tensors (see `tensor_type` above). + n_sequences (`Optional[int]`, *optional*): + You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at + initialization. + """ + + def __init__( + self, + data: Optional[Dict[str, Any]] = None, + encoding: Optional[Union[EncodingFast, Sequence[EncodingFast]]] = None, + tensor_type: Union[None, str, TensorType] = None, + prepend_batch_axis: bool = False, + n_sequences: Optional[int] = None, + ): + super().__init__(data) + + if isinstance(encoding, EncodingFast): + encoding = [encoding] + + self._encodings = encoding + + if n_sequences is None and encoding is not None and len(encoding): + n_sequences = encoding[0].n_sequences + + self._n_sequences = n_sequences + + self.convert_to_tensors(tensor_type=tensor_type, prepend_batch_axis=prepend_batch_axis) + + @property + def n_sequences(self) -> Optional[int]: + """ + `Optional[int]`: The number of sequences used to generate each sample from the batch encoded in this + [`BatchEncoding`]. Currently can be one of `None` (unknown), `1` (a single sentence) or `2` (a pair of + sentences) + """ + return self._n_sequences + + @property + def is_fast(self) -> bool: + """ + `bool`: Indicate whether this [`BatchEncoding`] was generated from the result of a [`PreTrainedTokenizerFast`] + or not. + """ + return self._encodings is not None + + def __getitem__(self, item: Union[int, str]) -> Union[Any, EncodingFast]: + """ + If the key is a string, returns the value of the dict associated to `key` ('input_ids', 'attention_mask', + etc.). + + If the key is an integer, get the `tokenizers.Encoding` for batch item with index `key`. + """ + if isinstance(item, str): + return self.data[item] + elif self._encodings is not None: + return self._encodings[item] + else: + raise KeyError( + "Indexing with integers (to access backend Encoding for a given batch index) " + "is not available when using Python based tokenizers" + ) + + def __getattr__(self, item: str): + try: + return self.data[item] + except KeyError: + raise AttributeError + + def __getstate__(self): + return {"data": self.data, "encodings": self._encodings} + + def __setstate__(self, state): + if "data" in state: + self.data = state["data"] + + if "encodings" in state: + self._encodings = state["encodings"] + + def keys(self): + return self.data.keys() + + def values(self): + return self.data.values() + + def items(self): + return self.data.items() + + # After this point: + # Extended properties and methods only available for fast (Rust-based) tokenizers + # provided by HuggingFace tokenizers library. + + @property + def encodings(self) -> Optional[List[EncodingFast]]: + """ + `Optional[List[tokenizers.Encoding]]`: The list all encodings from the tokenization process. Returns `None` if + the input was tokenized through Python (i.e., not a fast) tokenizer. + """ + return self._encodings + + def tokens(self, batch_index: int = 0) -> List[str]: + """ + Return the list of tokens (sub-parts of the input strings after word/subword splitting and before conversion to + integer indices) at a given batch index (only works for the output of a fast tokenizer). + + Args: + batch_index (`int`, *optional*, defaults to 0): The index to access in the batch. + + Returns: + `List[str]`: The list of tokens at that index. + """ + if not self._encodings: + raise ValueError( + "tokens() is not available when using non-fast tokenizers (e.g. instance of a `XxxTokenizerFast`" + " class)." + ) + return self._encodings[batch_index].tokens + + def sequence_ids(self, batch_index: int = 0) -> List[Optional[int]]: + """ + Return a list mapping the tokens to the id of their original sentences: + + - `None` for special tokens added around or between sequences, + - `0` for tokens corresponding to words in the first sequence, + - `1` for tokens corresponding to words in the second sequence when a pair of sequences was jointly + encoded. + + Args: + batch_index (`int`, *optional*, defaults to 0): The index to access in the batch. + + Returns: + `List[Optional[int]]`: A list indicating the sequence id corresponding to each token. Special tokens added + by the tokenizer are mapped to `None` and other tokens are mapped to the index of their corresponding + sequence. + """ + if not self._encodings: + raise ValueError( + "sequence_ids() is not available when using non-fast tokenizers (e.g. instance of a `XxxTokenizerFast`" + " class)." + ) + return self._encodings[batch_index].sequence_ids + + def words(self, batch_index: int = 0) -> List[Optional[int]]: + """ + Return a list mapping the tokens to their actual word in the initial sentence for a fast tokenizer. + + Args: + batch_index (`int`, *optional*, defaults to 0): The index to access in the batch. + + Returns: + `List[Optional[int]]`: A list indicating the word corresponding to each token. Special tokens added by the + tokenizer are mapped to `None` and other tokens are mapped to the index of their corresponding word + (several tokens will be mapped to the same word index if they are parts of that word). + """ + if not self._encodings: + raise ValueError( + "words() is not available when using non-fast tokenizers (e.g. instance of a `XxxTokenizerFast`" + " class)." + ) + warnings.warn( + "`BatchEncoding.words()` property is deprecated and should be replaced with the identical, " + "but more self-explanatory `BatchEncoding.word_ids()` property.", + FutureWarning, + ) + return self.word_ids(batch_index) + + def word_ids(self, batch_index: int = 0) -> List[Optional[int]]: + """ + Return a list mapping the tokens to their actual word in the initial sentence for a fast tokenizer. + + Args: + batch_index (`int`, *optional*, defaults to 0): The index to access in the batch. + + Returns: + `List[Optional[int]]`: A list indicating the word corresponding to each token. Special tokens added by the + tokenizer are mapped to `None` and other tokens are mapped to the index of their corresponding word + (several tokens will be mapped to the same word index if they are parts of that word). + """ + if not self._encodings: + raise ValueError( + "word_ids() is not available when using non-fast tokenizers (e.g. instance of a `XxxTokenizerFast`" + " class)." + ) + return self._encodings[batch_index].word_ids + + def token_to_sequence(self, batch_or_token_index: int, token_index: Optional[int] = None) -> int: + """ + Get the index of the sequence represented by the given token. In the general use case, this method returns `0` + for a single sequence or the first sequence of a pair, and `1` for the second sequence of a pair + + Can be called as: + + - `self.token_to_sequence(token_index)` if batch size is 1 + - `self.token_to_sequence(batch_index, token_index)` if batch size is greater than 1 + + This method is particularly suited when the input sequences are provided as pre-tokenized sequences (i.e., + words are defined by the user). In this case it allows to easily associate encoded tokens with provided + tokenized words. + + Args: + batch_or_token_index (`int`): + Index of the sequence in the batch. If the batch only comprises one sequence, this can be the index of + the token in the sequence. + token_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the token in the + sequence. + + Returns: + `int`: Index of the word in the input sequence. + """ + + if not self._encodings: + raise ValueError("token_to_sequence() is not available when using Python based tokenizers") + if token_index is not None: + batch_index = batch_or_token_index + else: + batch_index = 0 + token_index = batch_or_token_index + if batch_index < 0: + batch_index = self._batch_size + batch_index + if token_index < 0: + token_index = self._seq_len + token_index + return self._encodings[batch_index].token_to_sequence(token_index) + + def token_to_word(self, batch_or_token_index: int, token_index: Optional[int] = None) -> int: + """ + Get the index of the word corresponding (i.e. comprising) to an encoded token in a sequence of the batch. + + Can be called as: + + - `self.token_to_word(token_index)` if batch size is 1 + - `self.token_to_word(batch_index, token_index)` if batch size is greater than 1 + + This method is particularly suited when the input sequences are provided as pre-tokenized sequences (i.e., + words are defined by the user). In this case it allows to easily associate encoded tokens with provided + tokenized words. + + Args: + batch_or_token_index (`int`): + Index of the sequence in the batch. If the batch only comprise one sequence, this can be the index of + the token in the sequence. + token_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the token in the + sequence. + + Returns: + `int`: Index of the word in the input sequence. + """ + + if not self._encodings: + raise ValueError("token_to_word() is not available when using Python based tokenizers") + if token_index is not None: + batch_index = batch_or_token_index + else: + batch_index = 0 + token_index = batch_or_token_index + if batch_index < 0: + batch_index = self._batch_size + batch_index + if token_index < 0: + token_index = self._seq_len + token_index + return self._encodings[batch_index].token_to_word(token_index) + + def word_to_tokens( + self, batch_or_word_index: int, word_index: Optional[int] = None, sequence_index: int = 0 + ) -> Optional[TokenSpan]: + """ + Get the encoded token span corresponding to a word in a sequence of the batch. + + Token spans are returned as a [`~tokenization_utils_base.TokenSpan`] with: + + - **start** -- Index of the first token. + - **end** -- Index of the token following the last token. + + Can be called as: + + - `self.word_to_tokens(word_index, sequence_index: int = 0)` if batch size is 1 + - `self.word_to_tokens(batch_index, word_index, sequence_index: int = 0)` if batch size is greater or equal to + 1 + + This method is particularly suited when the input sequences are provided as pre-tokenized sequences (i.e. words + are defined by the user). In this case it allows to easily associate encoded tokens with provided tokenized + words. + + Args: + batch_or_word_index (`int`): + Index of the sequence in the batch. If the batch only comprises one sequence, this can be the index of + the word in the sequence. + word_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the word in the + sequence. + sequence_index (`int`, *optional*, defaults to 0): + If pair of sequences are encoded in the batch this can be used to specify which sequence in the pair (0 + or 1) the provided word index belongs to. + + Returns: + ([`~tokenization_utils_base.TokenSpan`], *optional*): Span of tokens in the encoded sequence. Returns + `None` if no tokens correspond to the word. This can happen especially when the token is a special token + that has been used to format the tokenization. For example when we add a class token at the very beginning + of the tokenization. + """ + + if not self._encodings: + raise ValueError("word_to_tokens() is not available when using Python based tokenizers") + if word_index is not None: + batch_index = batch_or_word_index + else: + batch_index = 0 + word_index = batch_or_word_index + if batch_index < 0: + batch_index = self._batch_size + batch_index + if word_index < 0: + word_index = self._seq_len + word_index + span = self._encodings[batch_index].word_to_tokens(word_index, sequence_index) + return TokenSpan(*span) if span is not None else None + + def token_to_chars(self, batch_or_token_index: int, token_index: Optional[int] = None) -> CharSpan: + """ + Get the character span corresponding to an encoded token in a sequence of the batch. + + Character spans are returned as a [`~tokenization_utils_base.CharSpan`] with: + + - **start** -- Index of the first character in the original string associated to the token. + - **end** -- Index of the character following the last character in the original string associated to the + token. + + Can be called as: + + - `self.token_to_chars(token_index)` if batch size is 1 + - `self.token_to_chars(batch_index, token_index)` if batch size is greater or equal to 1 + + Args: + batch_or_token_index (`int`): + Index of the sequence in the batch. If the batch only comprise one sequence, this can be the index of + the token in the sequence. + token_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the token or tokens in + the sequence. + + Returns: + [`~tokenization_utils_base.CharSpan`]: Span of characters in the original string, or None, if the token + (e.g. , ) doesn't correspond to any chars in the origin string. + """ + + if not self._encodings: + raise ValueError("token_to_chars() is not available when using Python based tokenizers") + if token_index is not None: + batch_index = batch_or_token_index + else: + batch_index = 0 + token_index = batch_or_token_index + span_indices = self._encodings[batch_index].token_to_chars(token_index) + + return CharSpan(*span_indices) if span_indices is not None else None + + def char_to_token( + self, batch_or_char_index: int, char_index: Optional[int] = None, sequence_index: int = 0 + ) -> int: + """ + Get the index of the token in the encoded output comprising a character in the original string for a sequence + of the batch. + + Can be called as: + + - `self.char_to_token(char_index)` if batch size is 1 + - `self.char_to_token(batch_index, char_index)` if batch size is greater or equal to 1 + + This method is particularly suited when the input sequences are provided as pre-tokenized sequences (i.e. words + are defined by the user). In this case it allows to easily associate encoded tokens with provided tokenized + words. + + Args: + batch_or_char_index (`int`): + Index of the sequence in the batch. If the batch only comprise one sequence, this can be the index of + the word in the sequence + char_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the word in the + sequence. + sequence_index (`int`, *optional*, defaults to 0): + If pair of sequences are encoded in the batch this can be used to specify which sequence in the pair (0 + or 1) the provided character index belongs to. + + + Returns: + `int`: Index of the token. + """ + + if not self._encodings: + raise ValueError("char_to_token() is not available when using Python based tokenizers") + if char_index is not None: + batch_index = batch_or_char_index + else: + batch_index = 0 + char_index = batch_or_char_index + return self._encodings[batch_index].char_to_token(char_index, sequence_index) + + def word_to_chars( + self, batch_or_word_index: int, word_index: Optional[int] = None, sequence_index: int = 0 + ) -> CharSpan: + """ + Get the character span in the original string corresponding to given word in a sequence of the batch. + + Character spans are returned as a CharSpan NamedTuple with: + + - start: index of the first character in the original string + - end: index of the character following the last character in the original string + + Can be called as: + + - `self.word_to_chars(word_index)` if batch size is 1 + - `self.word_to_chars(batch_index, word_index)` if batch size is greater or equal to 1 + + Args: + batch_or_word_index (`int`): + Index of the sequence in the batch. If the batch only comprise one sequence, this can be the index of + the word in the sequence + word_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the word in the + sequence. + sequence_index (`int`, *optional*, defaults to 0): + If pair of sequences are encoded in the batch this can be used to specify which sequence in the pair (0 + or 1) the provided word index belongs to. + + Returns: + `CharSpan` or `List[CharSpan]`: Span(s) of the associated character or characters in the string. CharSpan + are NamedTuple with: + + - start: index of the first character associated to the token in the original string + - end: index of the character following the last character associated to the token in the original + string + """ + + if not self._encodings: + raise ValueError("word_to_chars() is not available when using Python based tokenizers") + if word_index is not None: + batch_index = batch_or_word_index + else: + batch_index = 0 + word_index = batch_or_word_index + return CharSpan(*(self._encodings[batch_index].word_to_chars(word_index, sequence_index))) + + def char_to_word(self, batch_or_char_index: int, char_index: Optional[int] = None, sequence_index: int = 0) -> int: + """ + Get the word in the original string corresponding to a character in the original string of a sequence of the + batch. + + Can be called as: + + - `self.char_to_word(char_index)` if batch size is 1 + - `self.char_to_word(batch_index, char_index)` if batch size is greater than 1 + + This method is particularly suited when the input sequences are provided as pre-tokenized sequences (i.e. words + are defined by the user). In this case it allows to easily associate encoded tokens with provided tokenized + words. + + Args: + batch_or_char_index (`int`): + Index of the sequence in the batch. If the batch only comprise one sequence, this can be the index of + the character in the original string. + char_index (`int`, *optional*): + If a batch index is provided in *batch_or_token_index*, this can be the index of the character in the + original string. + sequence_index (`int`, *optional*, defaults to 0): + If pair of sequences are encoded in the batch this can be used to specify which sequence in the pair (0 + or 1) the provided character index belongs to. + + + Returns: + `int` or `List[int]`: Index or indices of the associated encoded token(s). + """ + + if not self._encodings: + raise ValueError("char_to_word() is not available when using Python based tokenizers") + if char_index is not None: + batch_index = batch_or_char_index + else: + batch_index = 0 + char_index = batch_or_char_index + return self._encodings[batch_index].char_to_word(char_index, sequence_index) + + def convert_to_tensors( + self, tensor_type: Optional[Union[str, TensorType]] = None, prepend_batch_axis: bool = False + ): + """ + Convert the inner content to tensors. + + Args: + tensor_type (`str` or [`~utils.TensorType`], *optional*): + The type of tensors to use. If `str`, should be one of the values of the enum [`~utils.TensorType`]. If + `None`, no modification is done. + prepend_batch_axis (`int`, *optional*, defaults to `False`): + Whether or not to add the batch dimension during the conversion. + """ + if tensor_type is None: + return self + + # Convert to TensorType + if not isinstance(tensor_type, TensorType): + tensor_type = TensorType(tensor_type) + + # Get a function reference for the correct framework + if tensor_type == TensorType.TENSORFLOW: + if not is_tf_available(): + raise ImportError( + "Unable to convert output to TensorFlow tensors format, TensorFlow is not installed." + ) + import tensorflow as tf + + as_tensor = tf.constant + is_tensor = tf.is_tensor + elif tensor_type == TensorType.PYTORCH: + if not is_torch_available(): + raise ImportError("Unable to convert output to PyTorch tensors format, PyTorch is not installed.") + import torch + + as_tensor = torch.tensor + is_tensor = torch.is_tensor + elif tensor_type == TensorType.JAX: + if not is_flax_available(): + raise ImportError("Unable to convert output to JAX tensors format, JAX is not installed.") + import jax.numpy as jnp # noqa: F811 + + as_tensor = jnp.array + is_tensor = is_jax_tensor + else: + as_tensor = np.asarray + is_tensor = is_numpy_array + + # Do the tensor conversion in batch + for key, value in self.items(): + try: + if prepend_batch_axis: + value = [value] + + if not is_tensor(value): + tensor = as_tensor(value) + + # Removing this for now in favor of controlling the shape with `prepend_batch_axis` + # # at-least2d + # if tensor.ndim > 2: + # tensor = tensor.squeeze(0) + # elif tensor.ndim < 2: + # tensor = tensor[None, :] + + self[key] = tensor + except Exception as e: + if key == "overflowing_tokens": + raise ValueError( + "Unable to create tensor returning overflowing tokens of different lengths. " + "Please see if a fast version of this tokenizer is available to have this feature available." + ) from e + raise ValueError( + "Unable to create tensor, you should probably activate truncation and/or padding with" + " 'padding=True' 'truncation=True' to have batched tensors with the same length. Perhaps your" + f" features (`{key}` in this case) have excessive nesting (inputs type `list` where type `int` is" + " expected)." + ) from e + + return self + + def to(self, device: Union[str, "torch.device"]) -> "BatchEncoding": + """ + Send all values to device by calling `v.to(device)` (PyTorch only). + + Args: + device (`str` or `torch.device`): The device to put the tensors on. + + Returns: + [`BatchEncoding`]: The same instance after modification. + """ + requires_backends(self, ["torch"]) + + # This check catches things like APEX blindly calling "to" on all inputs to a module + # Otherwise it passes the casts down and casts the LongTensor containing the token idxs + # into a HalfTensor + if isinstance(device, str) or is_torch_device(device) or isinstance(device, int): + self.data = {k: v.to(device=device) for k, v in self.data.items()} + else: + logger.warning(f"Attempting to cast a BatchEncoding to type {str(device)}. This is not supported.") + return self + + +class SpecialTokensMixin: + """ + A mixin derived by [`PreTrainedTokenizer`] and [`PreTrainedTokenizerFast`] to handle specific behaviors related to + special tokens. In particular, this class hold the attributes which can be used to directly access these special + tokens in a model-independent manner and allow to set and update the special tokens. + + Args: + bos_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the beginning of a sentence. + eos_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the end of a sentence. + unk_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing an out-of-vocabulary token. + sep_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token separating two different sentences in the same input (used by BERT for instance). + pad_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token used to make arrays of tokens the same size for batching purpose. Will then be ignored by + attention mechanisms or loss computation. + cls_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the class of the input (used by BERT for instance). + mask_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing a masked token (used by masked-language modeling pretraining objectives, like + BERT). + additional_special_tokens (tuple or list of `str` or `tokenizers.AddedToken`, *optional*): + A tuple or a list of additional special tokens. + """ + + SPECIAL_TOKENS_ATTRIBUTES = [ + "bos_token", + "eos_token", + "unk_token", + "sep_token", + "pad_token", + "cls_token", + "mask_token", + "additional_special_tokens", + ] + + def __init__(self, verbose=True, **kwargs): + self._bos_token = None + self._eos_token = None + self._unk_token = None + self._sep_token = None + self._pad_token = None + self._cls_token = None + self._mask_token = None + self._pad_token_type_id = 0 + self._additional_special_tokens = [] + self.verbose = verbose + + # We directly set the hidden value to allow initialization with special tokens + # which are not yet in the vocabulary. Necessary for serialization/de-serialization + # TODO clean this up at some point (probably by switching to fast tokenizers) + for key, value in kwargs.items(): + if value is None: + continue + if key in self.SPECIAL_TOKENS_ATTRIBUTES: + if key == "additional_special_tokens": + assert isinstance(value, (list, tuple)), f"Value {value} is not a list or tuple" + assert all( + isinstance(t, (str, AddedToken)) for t in value + ), "One of the tokens is not a string or an AddedToken" + setattr(self, key, value) + elif isinstance(value, (str, AddedToken)): + setattr(self, key, value) + else: + raise TypeError(f"special token {key} has to be either str or AddedToken but got: {type(value)}") + + def sanitize_special_tokens(self) -> int: + """ + Make sure that all the special tokens attributes of the tokenizer (`tokenizer.mask_token`, + `tokenizer.cls_token`, etc.) are in the vocabulary. + + Add the missing ones to the vocabulary if needed. + + Return: + `int`: The number of tokens added in the vocabulary during the operation. + """ + return self.add_tokens(self.all_special_tokens_extended, special_tokens=True) + + def add_special_tokens( + self, special_tokens_dict: Dict[str, Union[str, AddedToken]], replace_additional_special_tokens=True + ) -> int: + """ + Add a dictionary of special tokens (eos, pad, cls, etc.) to the encoder and link them to class attributes. If + special tokens are NOT in the vocabulary, they are added to it (indexed starting from the last index of the + current vocabulary). + + Note,None When adding new tokens to the vocabulary, you should make sure to also resize the token embedding + matrix of the model so that its embedding matrix matches the tokenizer. + + In order to do that, please use the [`~PreTrainedModel.resize_token_embeddings`] method. + + Using `add_special_tokens` will ensure your special tokens can be used in several ways: + + - Special tokens are carefully handled by the tokenizer (they are never split). + - You can easily refer to special tokens using tokenizer class attributes like `tokenizer.cls_token`. This + makes it easy to develop model-agnostic training and fine-tuning scripts. + + When possible, special tokens are already registered for provided pretrained models (for instance + [`BertTokenizer`] `cls_token` is already registered to be :obj*'[CLS]'* and XLM's one is also registered to be + `''`). + + Args: + special_tokens_dict (dictionary *str* to *str* or `tokenizers.AddedToken`): + Keys should be in the list of predefined special attributes: [`bos_token`, `eos_token`, `unk_token`, + `sep_token`, `pad_token`, `cls_token`, `mask_token`, `additional_special_tokens`]. + + Tokens are only added if they are not already in the vocabulary (tested by checking if the tokenizer + assign the index of the `unk_token` to them). + replace_additional_special_tokens (`bool`, *optional*,, defaults to `True`): + If `True`, the existing list of additional special tokens will be replaced by the one specified in + `special_tokens_dict`. Otherwise, `self._additional_special_tokens` is updated. In the former case, the + tokens will NOT be removed from the tokenizer's full vocabulary - they are only being flagged as + non-special tokens. + + Returns: + `int`: Number of tokens added to the vocabulary. + + Examples: + + ```python + # Let's see how to add a new classification token to GPT-2 + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + model = GPT2Model.from_pretrained("gpt2") + + special_tokens_dict = {"cls_token": ""} + + num_added_toks = tokenizer.add_special_tokens(special_tokens_dict) + print("We have added", num_added_toks, "tokens") + # Notice: resize_token_embeddings expect to receive the full size of the new vocabulary, i.e., the length of the tokenizer. + model.resize_token_embeddings(len(tokenizer)) + + assert tokenizer.cls_token == "" + ```""" + if not special_tokens_dict: + return 0 + + added_tokens = 0 + for key, value in special_tokens_dict.items(): + assert key in self.SPECIAL_TOKENS_ATTRIBUTES, f"Key {key} is not a special token" + + if self.verbose: + logger.info(f"Assigning {value} to the {key} key of the tokenizer") + + if key == "additional_special_tokens": + assert isinstance(value, (list, tuple)) and all( + isinstance(t, (str, AddedToken)) for t in value + ), f"Tokens {value} for key {key} should all be str or AddedToken instances" + + if replace_additional_special_tokens: + setattr(self, key, value) + else: + # This is a copy of `self._additional_special_tokens` + additional_special_tokens = getattr(self, key) + additional_special_tokens_set = set(additional_special_tokens) + to_add = [] + for token in value: + if str(token) not in additional_special_tokens_set and str(token) not in to_add: + to_add.append(token) + # update the property + additional_special_tokens.extend(to_add) + self.additional_special_tokens = additional_special_tokens + + added_tokens += self.add_tokens(value, special_tokens=True) + else: + assert isinstance( + value, (str, AddedToken) + ), f"Token {value} for key {key} should be a str or an AddedToken instance" + setattr(self, key, value) + added_tokens += self.add_tokens([value], special_tokens=True) + + return added_tokens + + def add_tokens( + self, new_tokens: Union[str, AddedToken, List[Union[str, AddedToken]]], special_tokens: bool = False + ) -> int: + """ + Add a list of new tokens to the tokenizer class. If the new tokens are not in the vocabulary, they are added to + it with indices starting from length of the current vocabulary and and will be isolated before the tokenization + algorithm is applied. Added tokens and tokens from the vocabulary of the tokenization algorithm are therefore + not treated in the same way. + + Note, when adding new tokens to the vocabulary, you should make sure to also resize the token embedding matrix + of the model so that its embedding matrix matches the tokenizer. + + In order to do that, please use the [`~PreTrainedModel.resize_token_embeddings`] method. + + Args: + new_tokens (`str`, `tokenizers.AddedToken` or a list of *str* or `tokenizers.AddedToken`): + Tokens are only added if they are not already in the vocabulary. `tokenizers.AddedToken` wraps a string + token to let you personalize its behavior: whether this token should only match against a single word, + whether this token should strip all potential whitespaces on the left side, whether this token should + strip all potential whitespaces on the right side, etc. + special_tokens (`bool`, *optional*, defaults to `False`): + Can be used to specify if the token is a special token. This mostly change the normalization behavior + (special tokens like CLS or [MASK] are usually not lower-cased for instance). + + See details for `tokenizers.AddedToken` in HuggingFace tokenizers library. + + Returns: + `int`: Number of tokens added to the vocabulary. + + Examples: + + ```python + # Let's see how to increase the vocabulary of Bert model and tokenizer + tokenizer = BertTokenizerFast.from_pretrained("bert-base-uncased") + model = BertModel.from_pretrained("bert-base-uncased") + + num_added_toks = tokenizer.add_tokens(["new_tok1", "my_new-tok2"]) + print("We have added", num_added_toks, "tokens") + # Notice: resize_token_embeddings expect to receive the full size of the new vocabulary, i.e., the length of the tokenizer. + model.resize_token_embeddings(len(tokenizer)) + ```""" + if not new_tokens: + return 0 + + if not isinstance(new_tokens, (list, tuple)): + new_tokens = [new_tokens] + + return self._add_tokens(new_tokens, special_tokens=special_tokens) + + def _add_tokens(self, new_tokens: Union[List[str], List[AddedToken]], special_tokens: bool = False) -> int: + raise NotImplementedError + + @property + def bos_token(self) -> str: + """ + `str`: Beginning of sentence token. Log an error if used while not having been set. + """ + if self._bos_token is None: + if self.verbose: + logger.error("Using bos_token, but it is not set yet.") + return None + return str(self._bos_token) + + @property + def eos_token(self) -> str: + """ + `str`: End of sentence token. Log an error if used while not having been set. + """ + if self._eos_token is None: + if self.verbose: + logger.error("Using eos_token, but it is not set yet.") + return None + return str(self._eos_token) + + @property + def unk_token(self) -> str: + """ + `str`: Unknown token. Log an error if used while not having been set. + """ + if self._unk_token is None: + if self.verbose: + logger.error("Using unk_token, but it is not set yet.") + return None + return str(self._unk_token) + + @property + def sep_token(self) -> str: + """ + `str`: Separation token, to separate context and query in an input sequence. Log an error if used while not + having been set. + """ + if self._sep_token is None: + if self.verbose: + logger.error("Using sep_token, but it is not set yet.") + return None + return str(self._sep_token) + + @property + def pad_token(self) -> str: + """ + `str`: Padding token. Log an error if used while not having been set. + """ + if self._pad_token is None: + if self.verbose: + logger.error("Using pad_token, but it is not set yet.") + return None + return str(self._pad_token) + + @property + def cls_token(self) -> str: + """ + `str`: Classification token, to extract a summary of an input sequence leveraging self-attention along the full + depth of the model. Log an error if used while not having been set. + """ + if self._cls_token is None: + if self.verbose: + logger.error("Using cls_token, but it is not set yet.") + return None + return str(self._cls_token) + + @property + def mask_token(self) -> str: + """ + `str`: Mask token, to use when training a model with masked-language modeling. Log an error if used while not + having been set. + """ + if self._mask_token is None: + if self.verbose: + logger.error("Using mask_token, but it is not set yet.") + return None + return str(self._mask_token) + + @property + def additional_special_tokens(self) -> List[str]: + """ + `List[str]`: All the additional special tokens you may want to use. Log an error if used while not having been + set. + """ + if self._additional_special_tokens is None: + if self.verbose: + logger.error("Using additional_special_tokens, but it is not set yet.") + return None + return [str(tok) for tok in self._additional_special_tokens] + + @bos_token.setter + def bos_token(self, value): + self._bos_token = value + + @eos_token.setter + def eos_token(self, value): + self._eos_token = value + + @unk_token.setter + def unk_token(self, value): + self._unk_token = value + + @sep_token.setter + def sep_token(self, value): + self._sep_token = value + + @pad_token.setter + def pad_token(self, value): + self._pad_token = value + + @cls_token.setter + def cls_token(self, value): + self._cls_token = value + + @mask_token.setter + def mask_token(self, value): + self._mask_token = value + + @additional_special_tokens.setter + def additional_special_tokens(self, value): + self._additional_special_tokens = value + + @property + def bos_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the beginning of sentence token in the vocabulary. Returns `None` if the token has not + been set. + """ + if self._bos_token is None: + return None + return self.convert_tokens_to_ids(self.bos_token) + + @property + def eos_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the end of sentence token in the vocabulary. Returns `None` if the token has not been + set. + """ + if self._eos_token is None: + return None + return self.convert_tokens_to_ids(self.eos_token) + + @property + def unk_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the unknown token in the vocabulary. Returns `None` if the token has not been set. + """ + if self._unk_token is None: + return None + return self.convert_tokens_to_ids(self.unk_token) + + @property + def sep_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the separation token in the vocabulary, to separate context and query in an input + sequence. Returns `None` if the token has not been set. + """ + if self._sep_token is None: + return None + return self.convert_tokens_to_ids(self.sep_token) + + @property + def pad_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the padding token in the vocabulary. Returns `None` if the token has not been set. + """ + if self._pad_token is None: + return None + return self.convert_tokens_to_ids(self.pad_token) + + @property + def pad_token_type_id(self) -> int: + """ + `int`: Id of the padding token type in the vocabulary. + """ + return self._pad_token_type_id + + @property + def cls_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the classification token in the vocabulary, to extract a summary of an input sequence + leveraging self-attention along the full depth of the model. + + Returns `None` if the token has not been set. + """ + if self._cls_token is None: + return None + return self.convert_tokens_to_ids(self.cls_token) + + @property + def mask_token_id(self) -> Optional[int]: + """ + `Optional[int]`: Id of the mask token in the vocabulary, used when training a model with masked-language + modeling. Returns `None` if the token has not been set. + """ + if self._mask_token is None: + return None + return self.convert_tokens_to_ids(self.mask_token) + + @property + def additional_special_tokens_ids(self) -> List[int]: + """ + `List[int]`: Ids of all the additional special tokens in the vocabulary. Log an error if used while not having + been set. + """ + return self.convert_tokens_to_ids(self.additional_special_tokens) + + @bos_token_id.setter + def bos_token_id(self, value): + self._bos_token = self.convert_ids_to_tokens(value) if value is not None else None + + @eos_token_id.setter + def eos_token_id(self, value): + self._eos_token = self.convert_ids_to_tokens(value) if value is not None else None + + @unk_token_id.setter + def unk_token_id(self, value): + self._unk_token = self.convert_ids_to_tokens(value) if value is not None else None + + @sep_token_id.setter + def sep_token_id(self, value): + self._sep_token = self.convert_ids_to_tokens(value) if value is not None else None + + @pad_token_id.setter + def pad_token_id(self, value): + self._pad_token = self.convert_ids_to_tokens(value) if value is not None else None + + @cls_token_id.setter + def cls_token_id(self, value): + self._cls_token = self.convert_ids_to_tokens(value) if value is not None else None + + @mask_token_id.setter + def mask_token_id(self, value): + self._mask_token = self.convert_ids_to_tokens(value) if value is not None else None + + @additional_special_tokens_ids.setter + def additional_special_tokens_ids(self, values): + self._additional_special_tokens = [self.convert_ids_to_tokens(value) for value in values] + + @property + def special_tokens_map(self) -> Dict[str, Union[str, List[str]]]: + """ + `Dict[str, Union[str, List[str]]]`: A dictionary mapping special token class attributes (`cls_token`, + `unk_token`, etc.) to their values (`''`, `''`, etc.). + + Convert potential tokens of `tokenizers.AddedToken` type to string. + """ + set_attr = {} + for attr in self.SPECIAL_TOKENS_ATTRIBUTES: + attr_value = getattr(self, "_" + attr) + if attr_value: + set_attr[attr] = ( + type(attr_value)(str(attr_value_sub) for attr_value_sub in attr_value) + if isinstance(attr_value, (list, tuple)) + else str(attr_value) + ) + return set_attr + + @property + def special_tokens_map_extended(self) -> Dict[str, Union[str, AddedToken, List[Union[str, AddedToken]]]]: + """ + `Dict[str, Union[str, tokenizers.AddedToken, List[Union[str, tokenizers.AddedToken]]]]`: A dictionary mapping + special token class attributes (`cls_token`, `unk_token`, etc.) to their values (`''`, `''`, etc.). + + Don't convert tokens of `tokenizers.AddedToken` type to string so they can be used to control more finely how + special tokens are tokenized. + """ + set_attr = {} + for attr in self.SPECIAL_TOKENS_ATTRIBUTES: + attr_value = getattr(self, "_" + attr) + if attr_value: + set_attr[attr] = attr_value + return set_attr + + @property + def all_special_tokens(self) -> List[str]: + """ + `List[str]`: All the special tokens (`''`, `''`, etc.) mapped to class attributes. + + Convert tokens of `tokenizers.AddedToken` type to string. + """ + all_toks = [str(s) for s in self.all_special_tokens_extended] + return all_toks + + @property + def all_special_tokens_extended(self) -> List[Union[str, AddedToken]]: + """ + `List[Union[str, tokenizers.AddedToken]]`: All the special tokens (`''`, `''`, etc.) mapped to class + attributes. + + Don't convert tokens of `tokenizers.AddedToken` type to string so they can be used to control more finely how + special tokens are tokenized. + """ + all_toks = [] + set_attr = self.special_tokens_map_extended + for attr_value in set_attr.values(): + all_toks = all_toks + (list(attr_value) if isinstance(attr_value, (list, tuple)) else [attr_value]) + all_toks = list(OrderedDict.fromkeys(all_toks)) + return all_toks + + @property + def all_special_ids(self) -> List[int]: + """ + `List[int]`: List the ids of the special tokens(`''`, `''`, etc.) mapped to class attributes. + """ + all_toks = self.all_special_tokens + all_ids = self.convert_tokens_to_ids(all_toks) + return all_ids + + +ENCODE_KWARGS_DOCSTRING = r""" + add_special_tokens (`bool`, *optional*, defaults to `True`): + Whether or not to encode the sequences with the special tokens relative to their model. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`): + Activates and controls truncation. Accepts the following values: + + - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or + to the maximum acceptable input length for the model if that argument is not provided. This will + truncate token by token, removing a token from the longest sequence in the pair if a pair of + sequences (or a batch of pairs) is provided. + - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the first sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the second sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths + greater than the model maximum admissible input size). + max_length (`int`, *optional*): + Controls the maximum length to use by one of the truncation/padding parameters. + + If left unset or set to `None`, this will use the predefined model maximum length if a maximum length + is required by one of the truncation/padding parameters. If the model has no specific maximum input + length (like XLNet) truncation/padding to a maximum length will be deactivated. + stride (`int`, *optional*, defaults to 0): + If set to a number along with `max_length`, the overflowing tokens returned when + `return_overflowing_tokens=True` will contain some tokens from the end of the truncated sequence + returned to provide some overlap between truncated and overflowing sequences. The value of this + argument defines the number of overlapping tokens. + is_split_into_words (`bool`, *optional*, defaults to `False`): + Whether or not the input is already pre-tokenized (e.g., split into words). If set to `True`, the + tokenizer assumes the input is already split into words (for instance, by splitting it on whitespace) + which it will tokenize. This is useful for NER or token classification. + pad_to_multiple_of (`int`, *optional*): + If set will pad the sequence to a multiple of the provided value. Requires `padding` to be activated. + This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability + `>= 7.5` (Volta). + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. +""" + +ENCODE_PLUS_ADDITIONAL_KWARGS_DOCSTRING = r""" + return_token_type_ids (`bool`, *optional*): + Whether to return token type IDs. If left to the default, will return the token type IDs according to + the specific tokenizer's default, defined by the `return_outputs` attribute. + + [What are token type IDs?](../glossary#token-type-ids) + return_attention_mask (`bool`, *optional*): + Whether to return the attention mask. If left to the default, will return the attention mask according + to the specific tokenizer's default, defined by the `return_outputs` attribute. + + [What are attention masks?](../glossary#attention-mask) + return_overflowing_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to return overflowing token sequences. If a pair of sequences of input ids (or a batch + of pairs) is provided with `truncation_strategy = longest_first` or `True`, an error is raised instead + of returning overflowing tokens. + return_special_tokens_mask (`bool`, *optional*, defaults to `False`): + Whether or not to return special tokens mask information. + return_offsets_mapping (`bool`, *optional*, defaults to `False`): + Whether or not to return `(char_start, char_end)` for each token. + + This is only available on fast tokenizers inheriting from [`PreTrainedTokenizerFast`], if using + Python's tokenizer, this method will raise `NotImplementedError`. + return_length (`bool`, *optional*, defaults to `False`): + Whether or not to return the lengths of the encoded inputs. + verbose (`bool`, *optional*, defaults to `True`): + Whether or not to print more information and warnings. + **kwargs: passed to the `self.tokenize()` method + + Return: + [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. + + [What are input IDs?](../glossary#input-ids) + + - **token_type_ids** -- List of token type ids to be fed to a model (when `return_token_type_ids=True` or + if *"token_type_ids"* is in `self.model_input_names`). + + [What are token type IDs?](../glossary#token-type-ids) + + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names`). + + [What are attention masks?](../glossary#attention-mask) + + - **overflowing_tokens** -- List of overflowing tokens sequences (when a `max_length` is specified and + `return_overflowing_tokens=True`). + - **num_truncated_tokens** -- Number of tokens truncated (when a `max_length` is specified and + `return_overflowing_tokens=True`). + - **special_tokens_mask** -- List of 0s and 1s, with 1 specifying added special tokens and 0 specifying + regular sequence tokens (when `add_special_tokens=True` and `return_special_tokens_mask=True`). + - **length** -- The length of the inputs (when `return_length=True`) +""" + +INIT_TOKENIZER_DOCSTRING = r""" + Class attributes (overridden by derived classes) + + - **vocab_files_names** (`Dict[str, str]`) -- A dictionary with, as keys, the `__init__` keyword name of each + vocabulary file required by the model, and as associated values, the filename for saving the associated file + (string). + - **pretrained_vocab_files_map** (`Dict[str, Dict[str, str]]`) -- A dictionary of dictionaries, with the + high-level keys being the `__init__` keyword name of each vocabulary file required by the model, the + low-level being the `short-cut-names` of the pretrained models with, as associated values, the `url` to the + associated pretrained vocabulary file. + - **max_model_input_sizes** (`Dict[str, Optional[int]]`) -- A dictionary with, as keys, the `short-cut-names` + of the pretrained models, and as associated values, the maximum length of the sequence inputs of this model, + or `None` if the model has no maximum input size. + - **pretrained_init_configuration** (`Dict[str, Dict[str, Any]]`) -- A dictionary with, as keys, the + `short-cut-names` of the pretrained models, and as associated values, a dictionary of specific arguments to + pass to the `__init__` method of the tokenizer class for this pretrained model when loading the tokenizer + with the [`~tokenization_utils_base.PreTrainedTokenizerBase.from_pretrained`] method. + - **model_input_names** (`List[str]`) -- A list of inputs expected in the forward pass of the model. + - **padding_side** (`str`) -- The default value for the side on which the model should have padding applied. + Should be `'right'` or `'left'`. + - **truncation_side** (`str`) -- The default value for the side on which the model should have truncation + applied. Should be `'right'` or `'left'`. + + Args: + model_max_length (`int`, *optional*): + The maximum length (in number of tokens) for the inputs to the transformer model. When the tokenizer is + loaded with [`~tokenization_utils_base.PreTrainedTokenizerBase.from_pretrained`], this will be set to the + value stored for the associated model in `max_model_input_sizes` (see above). If no value is provided, will + default to VERY_LARGE_INTEGER (`int(1e30)`). + padding_side (`str`, *optional*): + The side on which the model should have padding applied. Should be selected between ['right', 'left']. + Default value is picked from the class attribute of the same name. + truncation_side (`str`, *optional*): + The side on which the model should have truncation applied. Should be selected between ['right', 'left']. + Default value is picked from the class attribute of the same name. + model_input_names (`List[string]`, *optional*): + The list of inputs accepted by the forward pass of the model (like `"token_type_ids"` or + `"attention_mask"`). Default value is picked from the class attribute of the same name. + bos_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the beginning of a sentence. Will be associated to `self.bos_token` and + `self.bos_token_id`. + eos_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the end of a sentence. Will be associated to `self.eos_token` and + `self.eos_token_id`. + unk_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing an out-of-vocabulary token. Will be associated to `self.unk_token` and + `self.unk_token_id`. + sep_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token separating two different sentences in the same input (used by BERT for instance). Will be + associated to `self.sep_token` and `self.sep_token_id`. + pad_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token used to make arrays of tokens the same size for batching purpose. Will then be ignored by + attention mechanisms or loss computation. Will be associated to `self.pad_token` and `self.pad_token_id`. + cls_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing the class of the input (used by BERT for instance). Will be associated to + `self.cls_token` and `self.cls_token_id`. + mask_token (`str` or `tokenizers.AddedToken`, *optional*): + A special token representing a masked token (used by masked-language modeling pretraining objectives, like + BERT). Will be associated to `self.mask_token` and `self.mask_token_id`. + additional_special_tokens (tuple or list of `str` or `tokenizers.AddedToken`, *optional*): + A tuple or a list of additional special tokens. Add them here to ensure they won't be split by the + tokenization process. Will be associated to `self.additional_special_tokens` and + `self.additional_special_tokens_ids`. + clean_up_tokenization_spaces (`bool`, *optional*, defaults to `True`): + Whether or not the model should cleanup the spaces that were added when splitting the input text during the + tokenization process. +""" + + +@add_end_docstrings(INIT_TOKENIZER_DOCSTRING) +class PreTrainedTokenizerBase(SpecialTokensMixin, PushToHubMixin): + """ + Base class for [`PreTrainedTokenizer`] and [`PreTrainedTokenizerFast`]. + + Handles shared (mostly boiler plate) methods for those two classes. + """ + + vocab_files_names: Dict[str, str] = {} + pretrained_vocab_files_map: Dict[str, Dict[str, str]] = {} + pretrained_init_configuration: Dict[str, Dict[str, Any]] = {} + max_model_input_sizes: Dict[str, Optional[int]] = {} + _auto_class: Optional[str] = None + + # first name has to correspond to main model input name + # to make sure `tokenizer.pad(...)` works correctly + model_input_names: List[str] = ["input_ids", "token_type_ids", "attention_mask"] + padding_side: str = "right" + truncation_side: str = "right" + slow_tokenizer_class = None + + def __init__(self, **kwargs): + # inputs and kwargs for saving and re-loading (see ``from_pretrained`` and ``save_pretrained``) + self.init_inputs = () + self.init_kwargs = copy.deepcopy(kwargs) + self.name_or_path = kwargs.pop("name_or_path", "") + self._processor_class = kwargs.pop("processor_class", None) + + # For backward compatibility we fallback to set model_max_length from max_len if provided + model_max_length = kwargs.pop("model_max_length", kwargs.pop("max_len", None)) + self.model_max_length = model_max_length if model_max_length is not None else VERY_LARGE_INTEGER + + # Padding and truncation side are right by default and overridden in subclasses. If specified in the kwargs, it + # is changed. + self.padding_side = kwargs.pop("padding_side", self.padding_side) + if self.padding_side not in ["right", "left"]: + raise ValueError( + f"Padding side should be selected between 'right' and 'left', current value: {self.padding_side}" + ) + + self.truncation_side = kwargs.pop("truncation_side", self.truncation_side) + if self.truncation_side not in ["right", "left"]: + raise ValueError( + f"Padding side should be selected between 'right' and 'left', current value: {self.truncation_side}" + ) + + self.model_input_names = kwargs.pop("model_input_names", self.model_input_names) + + # By default, cleaning tokenization spaces for both fast and slow tokenizers + self.clean_up_tokenization_spaces = kwargs.pop("clean_up_tokenization_spaces", True) + + self.deprecation_warnings = ( + {} + ) # Use to store when we have already noticed a deprecation warning (avoid overlogging). + self._in_target_context_manager = False + super().__init__(**kwargs) + + @property + def max_len_single_sentence(self) -> int: + """ + `int`: The maximum length of a sentence that can be fed to the model. + """ + return self.model_max_length - self.num_special_tokens_to_add(pair=False) + + @property + def max_len_sentences_pair(self) -> int: + """ + `int`: The maximum combined length of a pair of sentences that can be fed to the model. + """ + return self.model_max_length - self.num_special_tokens_to_add(pair=True) + + @max_len_single_sentence.setter + def max_len_single_sentence(self, value) -> int: + # For backward compatibility, allow to try to setup 'max_len_single_sentence'. + if value == self.model_max_length - self.num_special_tokens_to_add(pair=False) and self.verbose: + if not self.deprecation_warnings.get("max_len_single_sentence", False): + logger.warning( + "Setting 'max_len_single_sentence' is now deprecated. This value is automatically set up." + ) + self.deprecation_warnings["max_len_single_sentence"] = True + else: + raise ValueError( + "Setting 'max_len_single_sentence' is now deprecated. This value is automatically set up." + ) + + @max_len_sentences_pair.setter + def max_len_sentences_pair(self, value) -> int: + # For backward compatibility, allow to try to setup 'max_len_sentences_pair'. + if value == self.model_max_length - self.num_special_tokens_to_add(pair=True) and self.verbose: + if not self.deprecation_warnings.get("max_len_sentences_pair", False): + logger.warning( + "Setting 'max_len_sentences_pair' is now deprecated. This value is automatically set up." + ) + self.deprecation_warnings["max_len_sentences_pair"] = True + else: + raise ValueError("Setting 'max_len_sentences_pair' is now deprecated. This value is automatically set up.") + + def _set_processor_class(self, processor_class: str): + """Sets processor class as an attribute.""" + self._processor_class = processor_class + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}(name_or_path='{self.name_or_path}'," + f" vocab_size={self.vocab_size}, model_max_length={self.model_max_length}, is_fast={self.is_fast}," + f" padding_side='{self.padding_side}', truncation_side='{self.truncation_side}'," + f" special_tokens={self.special_tokens_map_extended}, clean_up_tokenization_spaces={self.clean_up_tokenization_spaces})" + ) + + def __len__(self) -> int: + raise NotImplementedError() + + def get_vocab(self) -> Dict[str, int]: + """ + Returns the vocabulary as a dictionary of token to index. + + `tokenizer.get_vocab()[token]` is equivalent to `tokenizer.convert_tokens_to_ids(token)` when `token` is in the + vocab. + + Returns: + `Dict[str, int]`: The vocabulary. + """ + raise NotImplementedError() + + @classmethod + def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], *init_inputs, **kwargs): + r""" + Instantiate a [`~tokenization_utils_base.PreTrainedTokenizerBase`] (or a derived class) from a predefined + tokenizer. + + Args: + pretrained_model_name_or_path (`str` or `os.PathLike`): + Can be either: + + - A string, the *model id* of a predefined tokenizer hosted inside a model repo on huggingface.co. + Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a + user or organization name, like `dbmdz/bert-base-german-cased`. + - A path to a *directory* containing vocabulary files required by the tokenizer, for instance saved + using the [`~tokenization_utils_base.PreTrainedTokenizerBase.save_pretrained`] method, e.g., + `./my_model_directory/`. + - (**Deprecated**, not applicable to all derived classes) A path or url to a single saved vocabulary + file (if and only if the tokenizer only requires a single vocabulary file like Bert or XLNet), e.g., + `./my_model_directory/vocab.txt`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded predefined tokenizer vocabulary files should be cached if the + standard cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force the (re-)download the vocabulary files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received files. Attempt to resume the download if such a file + exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + local_files_only (`bool`, *optional*, defaults to `False`): + Whether or not to only rely on local files and not to attempt to download any files. + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + subfolder (`str`, *optional*): + In case the relevant files are located inside a subfolder of the model repo on huggingface.co (e.g. for + facebook/rag-token-base), specify it here. + inputs (additional positional arguments, *optional*): + Will be passed along to the Tokenizer `__init__` method. + kwargs (additional keyword arguments, *optional*): + Will be passed to the Tokenizer `__init__` method. Can be used to set special tokens like `bos_token`, + `eos_token`, `unk_token`, `sep_token`, `pad_token`, `cls_token`, `mask_token`, + `additional_special_tokens`. See parameters in the `__init__` for more details. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Examples: + + ```python + # We can't instantiate directly the base class *PreTrainedTokenizerBase* so let's show our examples on a derived class: BertTokenizer + # Download vocabulary from huggingface.co and cache. + tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") + + # Download vocabulary from huggingface.co (user-uploaded) and cache. + tokenizer = BertTokenizer.from_pretrained("dbmdz/bert-base-german-cased") + + # If vocabulary files are in a directory (e.g. tokenizer was saved using *save_pretrained('./test/saved_model/')*) + tokenizer = BertTokenizer.from_pretrained("./test/saved_model/") + + # If the tokenizer uses a single vocabulary file, you can point directly to this file + tokenizer = BertTokenizer.from_pretrained("./test/saved_model/my_vocab.txt") + + # You can link tokens to special vocabulary when instantiating + tokenizer = BertTokenizer.from_pretrained("bert-base-uncased", unk_token="") + # You should be sure '' is in the vocabulary when doing that. + # Otherwise use tokenizer.add_special_tokens({'unk_token': ''}) instead) + assert tokenizer.unk_token == "" + ```""" + cache_dir = kwargs.pop("cache_dir", None) + force_download = kwargs.pop("force_download", False) + resume_download = kwargs.pop("resume_download", False) + proxies = kwargs.pop("proxies", None) + local_files_only = kwargs.pop("local_files_only", False) + use_auth_token = kwargs.pop("use_auth_token", None) + revision = kwargs.pop("revision", None) + subfolder = kwargs.pop("subfolder", None) + from_pipeline = kwargs.pop("_from_pipeline", None) + from_auto_class = kwargs.pop("_from_auto", False) + commit_hash = kwargs.pop("_commit_hash", None) + + user_agent = {"file_type": "tokenizer", "from_auto_class": from_auto_class, "is_fast": "Fast" in cls.__name__} + if from_pipeline is not None: + user_agent["using_pipeline"] = from_pipeline + + if is_offline_mode() and not local_files_only: + logger.info("Offline mode: forcing local_files_only=True") + local_files_only = True + + pretrained_model_name_or_path = str(pretrained_model_name_or_path) + vocab_files = {} + init_configuration = {} + + is_local = os.path.isdir(pretrained_model_name_or_path) + single_file_id = None + if os.path.isfile(pretrained_model_name_or_path) or is_remote_url(pretrained_model_name_or_path): + if len(cls.vocab_files_names) > 1: + raise ValueError( + f"Calling {cls.__name__}.from_pretrained() with the path to a single file or url is not " + "supported for this tokenizer. Use a model identifier or the path to a directory instead." + ) + warnings.warn( + f"Calling {cls.__name__}.from_pretrained() with the path to a single file or url is deprecated and " + "won't be possible anymore in v5. Use a model identifier or the path to a directory instead.", + FutureWarning, + ) + file_id = list(cls.vocab_files_names.keys())[0] + + vocab_files[file_id] = pretrained_model_name_or_path + single_file_id = file_id + else: + # At this point pretrained_model_name_or_path is either a directory or a model identifier name + additional_files_names = { + "added_tokens_file": ADDED_TOKENS_FILE, + "special_tokens_map_file": SPECIAL_TOKENS_MAP_FILE, + "tokenizer_config_file": TOKENIZER_CONFIG_FILE, + } + vocab_files = {**cls.vocab_files_names, **additional_files_names} + + if "tokenizer_file" in vocab_files: + # Try to get the tokenizer config to see if there are versioned tokenizer files. + fast_tokenizer_file = FULL_TOKENIZER_FILE + resolved_config_file = cached_file( + pretrained_model_name_or_path, + TOKENIZER_CONFIG_FILE, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + use_auth_token=use_auth_token, + revision=revision, + local_files_only=local_files_only, + subfolder=subfolder, + user_agent=user_agent, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + _commit_hash=commit_hash, + ) + commit_hash = extract_commit_hash(resolved_config_file, commit_hash) + if resolved_config_file is not None: + with open(resolved_config_file, encoding="utf-8") as reader: + tokenizer_config = json.load(reader) + if "fast_tokenizer_files" in tokenizer_config: + fast_tokenizer_file = get_fast_tokenizer_file(tokenizer_config["fast_tokenizer_files"]) + vocab_files["tokenizer_file"] = fast_tokenizer_file + + # Get files from url, cache, or disk depending on the case + resolved_vocab_files = {} + unresolved_files = [] + for file_id, file_path in vocab_files.items(): + if file_path is None: + resolved_vocab_files[file_id] = None + elif single_file_id == file_id: + if os.path.isfile(file_path): + resolved_vocab_files[file_id] = file_path + elif is_remote_url(file_path): + resolved_vocab_files[file_id] = download_url(file_path, proxies=proxies) + else: + resolved_vocab_files[file_id] = cached_file( + pretrained_model_name_or_path, + file_path, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + use_auth_token=use_auth_token, + user_agent=user_agent, + revision=revision, + subfolder=subfolder, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + _commit_hash=commit_hash, + ) + commit_hash = extract_commit_hash(resolved_vocab_files[file_id], commit_hash) + + if len(unresolved_files) > 0: + logger.info( + f"Can't load following files from cache: {unresolved_files} and cannot check if these " + "files are necessary for the tokenizer to operate." + ) + + if all(full_file_name is None for full_file_name in resolved_vocab_files.values()): + raise EnvironmentError( + f"Can't load tokenizer for '{pretrained_model_name_or_path}'. If you were trying to load it from " + "'https://huggingface.co/models', make sure you don't have a local directory with the same name. " + f"Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a directory " + f"containing all relevant files for a {cls.__name__} tokenizer." + ) + + for file_id, file_path in vocab_files.items(): + if file_id not in resolved_vocab_files: + continue + + if is_local: + logger.info(f"loading file {file_path}") + else: + logger.info(f"loading file {file_path} from cache at {resolved_vocab_files[file_id]}") + + return cls._from_pretrained( + resolved_vocab_files, + pretrained_model_name_or_path, + init_configuration, + *init_inputs, + use_auth_token=use_auth_token, + cache_dir=cache_dir, + local_files_only=local_files_only, + _commit_hash=commit_hash, + _is_local=is_local, + **kwargs, + ) + + @classmethod + def _from_pretrained( + cls, + resolved_vocab_files, + pretrained_model_name_or_path, + init_configuration, + *init_inputs, + use_auth_token=None, + cache_dir=None, + local_files_only=False, + _commit_hash=None, + _is_local=False, + **kwargs, + ): + # We instantiate fast tokenizers based on a slow tokenizer if we don't have access to the tokenizer.json + # file or if `from_slow` is set to True. + from_slow = kwargs.get("from_slow", False) + has_tokenizer_file = resolved_vocab_files.get("tokenizer_file", None) is not None + if (from_slow or not has_tokenizer_file) and cls.slow_tokenizer_class is not None: + slow_tokenizer = (cls.slow_tokenizer_class)._from_pretrained( + copy.deepcopy(resolved_vocab_files), + pretrained_model_name_or_path, + copy.deepcopy(init_configuration), + *init_inputs, + use_auth_token=use_auth_token, + cache_dir=cache_dir, + local_files_only=local_files_only, + _commit_hash=_commit_hash, + **(copy.deepcopy(kwargs)), + ) + else: + slow_tokenizer = None + + # Prepare tokenizer initialization kwargs + # Did we saved some inputs and kwargs to reload ? + tokenizer_config_file = resolved_vocab_files.pop("tokenizer_config_file", None) + if tokenizer_config_file is not None: + with open(tokenizer_config_file, encoding="utf-8") as tokenizer_config_handle: + init_kwargs = json.load(tokenizer_config_handle) + # First attempt. We get tokenizer_class from tokenizer_config to check mismatch between tokenizers. + config_tokenizer_class = init_kwargs.get("tokenizer_class") + init_kwargs.pop("tokenizer_class", None) + saved_init_inputs = init_kwargs.pop("init_inputs", ()) + if not init_inputs: + init_inputs = saved_init_inputs + else: + config_tokenizer_class = None + init_kwargs = init_configuration + + if "auto_map" in init_kwargs and not _is_local: + # For backward compatibility with odl format. + if isinstance(init_kwargs["auto_map"], (tuple, list)): + init_kwargs["auto_map"] = {"AutoTokenizer": init_kwargs["auto_map"]} + init_kwargs["auto_map"] = add_model_info_to_auto_map( + init_kwargs["auto_map"], pretrained_model_name_or_path + ) + + if config_tokenizer_class is None: + from .models.auto.configuration_auto import AutoConfig # tests_ignore + + # Second attempt. If we have not yet found tokenizer_class, let's try to use the config. + try: + config = AutoConfig.from_pretrained( + pretrained_model_name_or_path, + use_auth_token=use_auth_token, + cache_dir=cache_dir, + local_files_only=local_files_only, + _commit_hash=_commit_hash, + ) + config_tokenizer_class = config.tokenizer_class + except (OSError, ValueError, KeyError): + # skip if an error occurred. + config = None + if config_tokenizer_class is None: + # Third attempt. If we have not yet found the original type of the tokenizer, + # we are loading we see if we can infer it from the type of the configuration file + from .models.auto.tokenization_auto import TOKENIZER_MAPPING_NAMES # tests_ignore + + if hasattr(config, "model_type"): + model_type = config.model_type + else: + # Fallback: use pattern matching on the string. + model_type = None + for pattern in TOKENIZER_MAPPING_NAMES.keys(): + if pattern in str(pretrained_model_name_or_path): + model_type = pattern + break + + if model_type is not None: + config_tokenizer_class, config_tokenizer_class_fast = TOKENIZER_MAPPING_NAMES.get( + model_type, (None, None) + ) + if config_tokenizer_class is None: + config_tokenizer_class = config_tokenizer_class_fast + + if config_tokenizer_class is not None: + if cls.__name__.replace("Fast", "") != config_tokenizer_class.replace("Fast", ""): + logger.warning( + "The tokenizer class you load from this checkpoint is not the same type as the class this" + " function is called from. It may result in unexpected tokenization. \nThe tokenizer class you" + f" load from this checkpoint is '{config_tokenizer_class}'. \nThe class this function is called" + f" from is '{cls.__name__}'." + ) + + # Update with newly provided kwargs + init_kwargs.update(kwargs) + + # Convert AddedTokens serialized as dict to class instances + def convert_added_tokens(obj: Union[AddedToken, Any]): + if isinstance(obj, dict) and "__type" in obj and obj["__type"] == "AddedToken": + obj.pop("__type") + return AddedToken(**obj) + elif isinstance(obj, (list, tuple)): + return [convert_added_tokens(o) for o in obj] + elif isinstance(obj, dict): + return {k: convert_added_tokens(v) for k, v in obj.items()} + return obj + + init_kwargs = convert_added_tokens(init_kwargs) + + # Set max length if needed + if pretrained_model_name_or_path in cls.max_model_input_sizes: + # if we're using a pretrained model, ensure the tokenizer + # wont index sequences longer than the number of positional embeddings + + model_max_length = cls.max_model_input_sizes[pretrained_model_name_or_path] + if model_max_length is not None and isinstance(model_max_length, (int, float)): + model_max_length = min(init_kwargs.get("model_max_length", int(1e30)), model_max_length) + # TODO(PVP) - uncomment following line in Transformers v5 + # init_kwargs["model_max_length"] = model_max_length + # TODO(PVP) - remove in Transformers v5 + # --- + init_kwargs["model_max_length"] = cls._eventually_correct_t5_max_length( + pretrained_model_name_or_path, model_max_length, init_kwargs.get("model_max_length") + ) + # --- + + # Merge resolved_vocab_files arguments in init_kwargs. + added_tokens_file = resolved_vocab_files.pop("added_tokens_file", None) + for args_name, file_path in resolved_vocab_files.items(): + if args_name not in init_kwargs: + init_kwargs[args_name] = file_path + + if slow_tokenizer is not None: + init_kwargs["__slow_tokenizer"] = slow_tokenizer + + init_kwargs["name_or_path"] = pretrained_model_name_or_path + + # Instantiate tokenizer. + try: + tokenizer = cls(*init_inputs, **init_kwargs) + except OSError: + raise OSError( + "Unable to load vocabulary from file. " + "Please check that the provided vocabulary is accessible and not corrupted." + ) + + # Save inputs and kwargs for saving and re-loading with ``save_pretrained`` + # Removed: Now done at the base class level + # tokenizer.init_inputs = init_inputs + # tokenizer.init_kwargs = init_kwargs + + # If there is a complementary special token map, load it + special_tokens_map_file = resolved_vocab_files.pop("special_tokens_map_file", None) + if special_tokens_map_file is not None: + with open(special_tokens_map_file, encoding="utf-8") as special_tokens_map_handle: + special_tokens_map = json.load(special_tokens_map_handle) + for key, value in special_tokens_map.items(): + if key in kwargs and kwargs[key]: + # This value has already been redefined by the kwargs + # We keep this new value and ignore the one stored in the special_tokens_map_file + + continue + + if isinstance(value, dict): + value = AddedToken(**value) + elif isinstance(value, list): + value = [AddedToken(**token) if isinstance(token, dict) else token for token in value] + setattr(tokenizer, key, value) + + # Add supplementary tokens. + special_tokens = tokenizer.all_special_tokens + if added_tokens_file is not None: + with open(added_tokens_file, encoding="utf-8") as added_tokens_handle: + added_tok_encoder = json.load(added_tokens_handle) + + # Sort added tokens by index + added_tok_encoder_sorted = sorted(added_tok_encoder.items(), key=lambda x: x[1]) + + # Accumulate added tokens into batches of special/non-special tokens, because calling add_tokens() for + # individual tokens would repeatedly rebuild a trie, which can be slow. + is_last_special = None + tokens = [] + + for token, index in added_tok_encoder_sorted: + current_index = len(tokenizer) + len(tokens) + if has_tokenizer_file and index != current_index and tokenizer.convert_tokens_to_ids(token) != index: + # Tokenizer fast: added token needs to either be in the vocabulary with the proper index or the + # index is the current length of the tokenizer (not in vocabulary) + raise ValueError( + f"Wrong index found for {token}: should be {tokenizer.convert_tokens_to_ids(token)} but found " + f"{index}." + ) + elif not has_tokenizer_file and index != current_index: + # Tokenizer slow: added token cannot already be in the vocabulary so its index needs to be the + # current length of the tokenizer. + raise ValueError( + f"Non-consecutive added token '{token}' found. " + f"Should have index {current_index} but has index {index} in saved vocabulary." + ) + + is_special = bool(token in special_tokens) + if is_last_special is None or is_last_special == is_special: + tokens.append(token) + else: + tokenizer.add_tokens(tokens, special_tokens=is_last_special) + tokens = [token] + is_last_special = is_special + + if tokens: + tokenizer.add_tokens(tokens, special_tokens=is_last_special) + + # Check all our special tokens are registered as "no split" token (we don't cut them) and are in the vocab + added_tokens = tokenizer.sanitize_special_tokens() + if added_tokens: + logger.warning_advice( + "Special tokens have been added in the vocabulary, make sure the associated word embeddings are" + " fine-tuned or trained." + ) + + return tokenizer + + @staticmethod + def _eventually_correct_t5_max_length(pretrained_model_name_or_path, max_model_length, init_max_model_length): + # This method should be deleted in Transformers v5 + # Its only purpose is to potentially throw a warning + # that incorrectly defined max lengths of T5's tokenizer are used + # which we will correct in Transformers v5. + return max_model_length + + def save_pretrained( + self, + save_directory: Union[str, os.PathLike], + legacy_format: Optional[bool] = None, + filename_prefix: Optional[str] = None, + push_to_hub: bool = False, + **kwargs, + ) -> Tuple[str]: + """ + Save the full tokenizer state. + + + This method make sure the full tokenizer can then be re-loaded using the + [`~tokenization_utils_base.PreTrainedTokenizer.from_pretrained`] class method.. + + Warning,None This won't save modifications you may have applied to the tokenizer after the instantiation (for + instance, modifying `tokenizer.do_lower_case` after creation). + + Args: + save_directory (`str` or `os.PathLike`): The path to a directory where the tokenizer will be saved. + legacy_format (`bool`, *optional*): + Only applicable for a fast tokenizer. If unset (default), will save the tokenizer in the unified JSON + format as well as in legacy format if it exists, i.e. with tokenizer specific vocabulary and a separate + added_tokens files. + + If `False`, will only save the tokenizer in the unified JSON format. This format is incompatible with + "slow" tokenizers (not powered by the *tokenizers* library), so the tokenizer will not be able to be + loaded in the corresponding "slow" tokenizer. + + If `True`, will save the tokenizer in legacy format. If the "slow" tokenizer doesn't exits, a value + error is raised. + filename_prefix: (`str`, *optional*): + A prefix to add to the names of the files saved by the tokenizer. + push_to_hub (`bool`, *optional*, defaults to `False`): + Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the + repository you want to push to with `repo_id` (will default to the name of `save_directory` in your + namespace). + kwargs: + Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method. + + Returns: + A tuple of `str`: The files saved. + """ + if os.path.isfile(save_directory): + logger.error(f"Provided path ({save_directory}) should be a directory, not a file") + return + + os.makedirs(save_directory, exist_ok=True) + + if push_to_hub: + commit_message = kwargs.pop("commit_message", None) + repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1]) + repo_id = self._create_repo(repo_id, **kwargs) + files_timestamps = self._get_files_timestamps(save_directory) + + special_tokens_map_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + SPECIAL_TOKENS_MAP_FILE + ) + tokenizer_config_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + TOKENIZER_CONFIG_FILE + ) + + tokenizer_config = copy.deepcopy(self.init_kwargs) + + # TODO: Ensure the modified attributes (those are also in the __init__ kwargs) will give identical tokenizers + # target_keys = self.init_kwargs.keys() + target_keys = ["model_max_length", "clean_up_tokenization_spaces"] + for k in target_keys: + if hasattr(self, k): + tokenizer_config[k] = getattr(self, k) + + if len(self.init_inputs) > 0: + tokenizer_config["init_inputs"] = copy.deepcopy(self.init_inputs) + for file_id in self.vocab_files_names.keys(): + tokenizer_config.pop(file_id, None) + + # Sanitize AddedTokens + def convert_added_tokens(obj: Union[AddedToken, Any], add_type_field=True): + if isinstance(obj, AddedToken): + out = obj.__getstate__() + if add_type_field: + out["__type"] = "AddedToken" + return out + elif isinstance(obj, (list, tuple)): + return [convert_added_tokens(o, add_type_field=add_type_field) for o in obj] + elif isinstance(obj, dict): + return {k: convert_added_tokens(v, add_type_field=add_type_field) for k, v in obj.items()} + return obj + + # add_type_field=True to allow dicts in the kwargs / differentiate from AddedToken serialization + tokenizer_config = convert_added_tokens(tokenizer_config, add_type_field=True) + + # Add tokenizer class to the tokenizer config to be able to reload it with from_pretrained + tokenizer_class = self.__class__.__name__ + # Remove the Fast at the end unless we have a special `PreTrainedTokenizerFast` + if tokenizer_class.endswith("Fast") and tokenizer_class != "PreTrainedTokenizerFast": + tokenizer_class = tokenizer_class[:-4] + tokenizer_config["tokenizer_class"] = tokenizer_class + if getattr(self, "_auto_map", None) is not None: + tokenizer_config["auto_map"] = self._auto_map + if getattr(self, "_processor_class", None) is not None: + tokenizer_config["processor_class"] = self._processor_class + + # If we have a custom model, we copy the file defining it in the folder and set the attributes so it can be + # loaded from the Hub. + if self._auto_class is not None: + custom_object_save(self, save_directory, config=tokenizer_config) + + # remove private information + if "name_or_path" in tokenizer_config: + tokenizer_config.pop("name_or_path") + tokenizer_config.pop("special_tokens_map_file", None) + + with open(tokenizer_config_file, "w", encoding="utf-8") as f: + out_str = json.dumps(tokenizer_config, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + f.write(out_str) + logger.info(f"tokenizer config file saved in {tokenizer_config_file}") + + # Sanitize AddedTokens in special_tokens_map + write_dict = convert_added_tokens(self.special_tokens_map_extended, add_type_field=False) + with open(special_tokens_map_file, "w", encoding="utf-8") as f: + out_str = json.dumps(write_dict, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + f.write(out_str) + logger.info(f"Special tokens file saved in {special_tokens_map_file}") + + file_names = (tokenizer_config_file, special_tokens_map_file) + + save_files = self._save_pretrained( + save_directory=save_directory, + file_names=file_names, + legacy_format=legacy_format, + filename_prefix=filename_prefix, + ) + + if push_to_hub: + self._upload_modified_files( + save_directory, + repo_id, + files_timestamps, + commit_message=commit_message, + token=kwargs.get("use_auth_token"), + ) + + return save_files + + def _save_pretrained( + self, + save_directory: Union[str, os.PathLike], + file_names: Tuple[str], + legacy_format: Optional[bool] = None, + filename_prefix: Optional[str] = None, + ) -> Tuple[str]: + """ + Save a tokenizer using the slow-tokenizer/legacy format: vocabulary + added tokens. + + Fast tokenizers can also be saved in a unique JSON file containing {config + vocab + added-tokens} using the + specific [`~tokenization_utils_fast.PreTrainedTokenizerFast._save_pretrained`] + """ + if legacy_format is False: + raise ValueError( + "Only fast tokenizers (instances of PreTrainedTokenizerFast) can be saved in non legacy format." + ) + + save_directory = str(save_directory) + + added_tokens_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + ADDED_TOKENS_FILE + ) + added_vocab = self.get_added_vocab() + if added_vocab: + with open(added_tokens_file, "w", encoding="utf-8") as f: + out_str = json.dumps(added_vocab, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + f.write(out_str) + logger.info(f"added tokens file saved in {added_tokens_file}") + + vocab_files = self.save_vocabulary(save_directory, filename_prefix=filename_prefix) + + return file_names + vocab_files + (added_tokens_file,) + + def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]: + """ + Save only the vocabulary of the tokenizer (vocabulary + added tokens). + + This method won't save the configuration and special token mappings of the tokenizer. Use + [`~PreTrainedTokenizerFast._save_pretrained`] to save the whole state of the tokenizer. + + Args: + save_directory (`str`): + The directory in which to save the vocabulary. + filename_prefix (`str`, *optional*): + An optional prefix to add to the named of the saved files. + + Returns: + `Tuple(str)`: Paths to the files saved. + """ + raise NotImplementedError + + def tokenize(self, text: str, pair: Optional[str] = None, add_special_tokens: bool = False, **kwargs) -> List[str]: + """ + Converts a string in a sequence of tokens, replacing unknown tokens with the `unk_token`. + + Args: + text (`str`): + The sequence to be encoded. + pair (`str`, *optional*): + A second sequence to be encoded with the first. + add_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to add the special tokens associated with the corresponding model. + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific encode method. See details in + [`~PreTrainedTokenizerBase.__call__`] + + Returns: + `List[str]`: The list of tokens. + """ + raise NotImplementedError + + @add_end_docstrings( + ENCODE_KWARGS_DOCSTRING, + """ + **kwargs: Passed along to the `.tokenize()` method. + """, + """ + Returns: + `List[int]`, `torch.Tensor`, `tf.Tensor` or `np.ndarray`: The tokenized ids of the text. + """, + ) + def encode( + self, + text: Union[TextInput, PreTokenizedInput, EncodedInput], + text_pair: Optional[Union[TextInput, PreTokenizedInput, EncodedInput]] = None, + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + return_tensors: Optional[Union[str, TensorType]] = None, + **kwargs, + ) -> List[int]: + """ + Converts a string to a sequence of ids (integer), using the tokenizer and vocabulary. + + Same as doing `self.convert_tokens_to_ids(self.tokenize(text))`. + + Args: + text (`str`, `List[str]` or `List[int]`): + The first sequence to be encoded. This can be a string, a list of strings (tokenized string using the + `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids` + method). + text_pair (`str`, `List[str]` or `List[int]`, *optional*): + Optional second sequence to be encoded. This can be a string, a list of strings (tokenized string using + the `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids` + method). + """ + encoded_inputs = self.encode_plus( + text, + text_pair=text_pair, + add_special_tokens=add_special_tokens, + padding=padding, + truncation=truncation, + max_length=max_length, + stride=stride, + return_tensors=return_tensors, + **kwargs, + ) + + return encoded_inputs["input_ids"] + + def num_special_tokens_to_add(self, pair: bool = False) -> int: + raise NotImplementedError + + def _get_padding_truncation_strategies( + self, padding=False, truncation=None, max_length=None, pad_to_multiple_of=None, verbose=True, **kwargs + ): + """ + Find the correct padding/truncation strategy with backward compatibility for old arguments (truncation_strategy + and pad_to_max_length) and behaviors. + """ + old_truncation_strategy = kwargs.pop("truncation_strategy", "do_not_truncate") + old_pad_to_max_length = kwargs.pop("pad_to_max_length", False) + + # Backward compatibility for previous behavior, maybe we should deprecate it: + # If you only set max_length, it activates truncation for max_length + if max_length is not None and padding is False and truncation is None: + if verbose: + if not self.deprecation_warnings.get("Truncation-not-explicitly-activated", False): + logger.warning( + "Truncation was not explicitly activated but `max_length` is provided a specific value, please" + " use `truncation=True` to explicitly truncate examples to max length. Defaulting to" + " 'longest_first' truncation strategy. If you encode pairs of sequences (GLUE-style) with the" + " tokenizer you can select this strategy more precisely by providing a specific strategy to" + " `truncation`." + ) + self.deprecation_warnings["Truncation-not-explicitly-activated"] = True + truncation = "longest_first" + + # Get padding strategy + if padding is False and old_pad_to_max_length: + if verbose: + warnings.warn( + "The `pad_to_max_length` argument is deprecated and will be removed in a future version, " + "use `padding=True` or `padding='longest'` to pad to the longest sequence in the batch, or " + "use `padding='max_length'` to pad to a max length. In this case, you can give a specific " + "length with `max_length` (e.g. `max_length=45`) or leave max_length to None to pad to the " + "maximal input size of the model (e.g. 512 for Bert).", + FutureWarning, + ) + if max_length is None: + padding_strategy = PaddingStrategy.LONGEST + else: + padding_strategy = PaddingStrategy.MAX_LENGTH + elif padding is not False: + if padding is True: + if verbose: + if max_length is not None and ( + truncation is None or truncation is False or truncation == "do_not_truncate" + ): + warnings.warn( + "`max_length` is ignored when `padding`=`True` and there is no truncation strategy. " + "To pad to max length, use `padding='max_length'`." + ) + if old_pad_to_max_length is not False: + warnings.warn("Though `pad_to_max_length` = `True`, it is ignored because `padding`=`True`.") + padding_strategy = PaddingStrategy.LONGEST # Default to pad to the longest sequence in the batch + elif not isinstance(padding, PaddingStrategy): + padding_strategy = PaddingStrategy(padding) + elif isinstance(padding, PaddingStrategy): + padding_strategy = padding + else: + padding_strategy = PaddingStrategy.DO_NOT_PAD + + # Get truncation strategy + if truncation is None and old_truncation_strategy != "do_not_truncate": + if verbose: + warnings.warn( + "The `truncation_strategy` argument is deprecated and will be removed in a future version, use" + " `truncation=True` to truncate examples to a max length. You can give a specific length with" + " `max_length` (e.g. `max_length=45`) or leave max_length to None to truncate to the maximal input" + " size of the model (e.g. 512 for Bert). If you have pairs of inputs, you can give a specific" + " truncation strategy selected among `truncation='only_first'` (will only truncate the first" + " sentence in the pairs) `truncation='only_second'` (will only truncate the second sentence in the" + " pairs) or `truncation='longest_first'` (will iteratively remove tokens from the longest sentence" + " in the pairs).", + FutureWarning, + ) + truncation_strategy = TruncationStrategy(old_truncation_strategy) + elif truncation is not False and truncation is not None: + if truncation is True: + truncation_strategy = ( + TruncationStrategy.LONGEST_FIRST + ) # Default to truncate the longest sequences in pairs of inputs + elif not isinstance(truncation, TruncationStrategy): + truncation_strategy = TruncationStrategy(truncation) + elif isinstance(truncation, TruncationStrategy): + truncation_strategy = truncation + else: + truncation_strategy = TruncationStrategy.DO_NOT_TRUNCATE + + # Set max length if needed + if max_length is None: + if padding_strategy == PaddingStrategy.MAX_LENGTH: + if self.model_max_length > LARGE_INTEGER: + if verbose: + if not self.deprecation_warnings.get("Asking-to-pad-to-max_length", False): + logger.warning( + "Asking to pad to max_length but no maximum length is provided and the model has no" + " predefined maximum length. Default to no padding." + ) + self.deprecation_warnings["Asking-to-pad-to-max_length"] = True + padding_strategy = PaddingStrategy.DO_NOT_PAD + else: + max_length = self.model_max_length + + if truncation_strategy != TruncationStrategy.DO_NOT_TRUNCATE: + if self.model_max_length > LARGE_INTEGER: + if verbose: + if not self.deprecation_warnings.get("Asking-to-truncate-to-max_length", False): + logger.warning( + "Asking to truncate to max_length but no maximum length is provided and the model has" + " no predefined maximum length. Default to no truncation." + ) + self.deprecation_warnings["Asking-to-truncate-to-max_length"] = True + truncation_strategy = TruncationStrategy.DO_NOT_TRUNCATE + else: + max_length = self.model_max_length + + # Test if we have a padding token + if padding_strategy != PaddingStrategy.DO_NOT_PAD and (not self.pad_token or self.pad_token_id < 0): + raise ValueError( + "Asking to pad but the tokenizer does not have a padding token. " + "Please select a token to use as `pad_token` `(tokenizer.pad_token = tokenizer.eos_token e.g.)` " + "or add a new pad token via `tokenizer.add_special_tokens({'pad_token': '[PAD]'})`." + ) + + # Check that we will truncate to a multiple of pad_to_multiple_of if both are provided + if ( + truncation_strategy != TruncationStrategy.DO_NOT_TRUNCATE + and padding_strategy != PaddingStrategy.DO_NOT_PAD + and pad_to_multiple_of is not None + and max_length is not None + and (max_length % pad_to_multiple_of != 0) + ): + raise ValueError( + "Truncation and padding are both activated but " + f"truncation length ({max_length}) is not a multiple of pad_to_multiple_of ({pad_to_multiple_of})." + ) + + return padding_strategy, truncation_strategy, max_length, kwargs + + @add_end_docstrings(ENCODE_KWARGS_DOCSTRING, ENCODE_PLUS_ADDITIONAL_KWARGS_DOCSTRING) + def __call__( + self, + text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None, + text_pair: Optional[Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]]] = None, + text_target: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None, + text_pair_target: Optional[ + Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] + ] = None, + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + """ + Main method to tokenize and prepare for the model one or several sequence(s) or one or several pair(s) of + sequences. + + Args: + text (`str`, `List[str]`, `List[List[str]]`, *optional*): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + text_pair (`str`, `List[str]`, `List[List[str]]`, *optional*): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + text_target (`str`, `List[str]`, `List[List[str]]`, *optional*): + The sequence or batch of sequences to be encoded as target texts. Each sequence can be a string or a + list of strings (pretokenized string). If the sequences are provided as list of strings (pretokenized), + you must set `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + text_pair_target (`str`, `List[str]`, `List[List[str]]`, *optional*): + The sequence or batch of sequences to be encoded as target texts. Each sequence can be a string or a + list of strings (pretokenized string). If the sequences are provided as list of strings (pretokenized), + you must set `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + """ + # To avoid duplicating + all_kwargs = { + "add_special_tokens": add_special_tokens, + "padding": padding, + "truncation": truncation, + "max_length": max_length, + "stride": stride, + "is_split_into_words": is_split_into_words, + "pad_to_multiple_of": pad_to_multiple_of, + "return_tensors": return_tensors, + "return_token_type_ids": return_token_type_ids, + "return_attention_mask": return_attention_mask, + "return_overflowing_tokens": return_overflowing_tokens, + "return_special_tokens_mask": return_special_tokens_mask, + "return_offsets_mapping": return_offsets_mapping, + "return_length": return_length, + "verbose": verbose, + } + all_kwargs.update(kwargs) + if text is None and text_target is None: + raise ValueError("You need to specify either `text` or `text_target`.") + if text is not None: + # The context manager will send the inputs as normal texts and not text_target, but we shouldn't change the + # input mode in this case. + if not self._in_target_context_manager: + self._switch_to_input_mode() + encodings = self._call_one(text=text, text_pair=text_pair, **all_kwargs) + if text_target is not None: + self._switch_to_target_mode() + target_encodings = self._call_one(text=text_target, text_pair=text_pair_target, **all_kwargs) + # Leave back tokenizer in input mode + self._switch_to_input_mode() + + if text_target is None: + return encodings + elif text is None: + return target_encodings + else: + encodings["labels"] = target_encodings["input_ids"] + return encodings + + def _call_one( + self, + text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]], + text_pair: Optional[Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]]] = None, + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + # Input type checking for clearer error + def _is_valid_text_input(t): + if isinstance(t, str): + # Strings are fine + return True + elif isinstance(t, (list, tuple)): + # List are fine as long as they are... + if len(t) == 0: + # ... empty + return True + elif isinstance(t[0], str): + # ... list of strings + return True + elif isinstance(t[0], (list, tuple)): + # ... list with an empty list or with a list of strings + return len(t[0]) == 0 or isinstance(t[0][0], str) + else: + return False + else: + return False + + if not _is_valid_text_input(text): + raise ValueError( + "text input must of type `str` (single example), `List[str]` (batch or single pretokenized example) " + "or `List[List[str]]` (batch of pretokenized examples)." + ) + + if text_pair is not None and not _is_valid_text_input(text_pair): + raise ValueError( + "text input must of type `str` (single example), `List[str]` (batch or single pretokenized example) " + "or `List[List[str]]` (batch of pretokenized examples)." + ) + + if is_split_into_words: + is_batched = isinstance(text, (list, tuple)) and text and isinstance(text[0], (list, tuple)) + else: + is_batched = isinstance(text, (list, tuple)) + + if is_batched: + if isinstance(text_pair, str): + raise TypeError( + "when tokenizing batches of text, `text_pair` must be a list or tuple with the same length as" + " `text`." + ) + if text_pair is not None and len(text) != len(text_pair): + raise ValueError( + f"batch length of `text`: {len(text)} does not match batch length of `text_pair`:" + f" {len(text_pair)}." + ) + batch_text_or_text_pairs = list(zip(text, text_pair)) if text_pair is not None else text + return self.batch_encode_plus( + batch_text_or_text_pairs=batch_text_or_text_pairs, + add_special_tokens=add_special_tokens, + padding=padding, + truncation=truncation, + max_length=max_length, + stride=stride, + is_split_into_words=is_split_into_words, + pad_to_multiple_of=pad_to_multiple_of, + return_tensors=return_tensors, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + **kwargs, + ) + else: + return self.encode_plus( + text=text, + text_pair=text_pair, + add_special_tokens=add_special_tokens, + padding=padding, + truncation=truncation, + max_length=max_length, + stride=stride, + is_split_into_words=is_split_into_words, + pad_to_multiple_of=pad_to_multiple_of, + return_tensors=return_tensors, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + **kwargs, + ) + + @add_end_docstrings(ENCODE_KWARGS_DOCSTRING, ENCODE_PLUS_ADDITIONAL_KWARGS_DOCSTRING) + def encode_plus( + self, + text: Union[TextInput, PreTokenizedInput, EncodedInput], + text_pair: Optional[Union[TextInput, PreTokenizedInput, EncodedInput]] = None, + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + """ + Tokenize and prepare for the model a sequence or a pair of sequences. + + + + This method is deprecated, `__call__` should be used instead. + + + + Args: + text (`str`, `List[str]` or `List[int]` (the latter only for not-fast tokenizers)): + The first sequence to be encoded. This can be a string, a list of strings (tokenized string using the + `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids` + method). + text_pair (`str`, `List[str]` or `List[int]`, *optional*): + Optional second sequence to be encoded. This can be a string, a list of strings (tokenized string using + the `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids` + method). + """ + + # Backward compatibility for 'truncation_strategy', 'pad_to_max_length' + padding_strategy, truncation_strategy, max_length, kwargs = self._get_padding_truncation_strategies( + padding=padding, + truncation=truncation, + max_length=max_length, + pad_to_multiple_of=pad_to_multiple_of, + verbose=verbose, + **kwargs, + ) + + return self._encode_plus( + text=text, + text_pair=text_pair, + add_special_tokens=add_special_tokens, + padding_strategy=padding_strategy, + truncation_strategy=truncation_strategy, + max_length=max_length, + stride=stride, + is_split_into_words=is_split_into_words, + pad_to_multiple_of=pad_to_multiple_of, + return_tensors=return_tensors, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + **kwargs, + ) + + def _encode_plus( + self, + text: Union[TextInput, PreTokenizedInput, EncodedInput], + text_pair: Optional[Union[TextInput, PreTokenizedInput, EncodedInput]] = None, + add_special_tokens: bool = True, + padding_strategy: PaddingStrategy = PaddingStrategy.DO_NOT_PAD, + truncation_strategy: TruncationStrategy = TruncationStrategy.DO_NOT_TRUNCATE, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + raise NotImplementedError + + @add_end_docstrings(ENCODE_KWARGS_DOCSTRING, ENCODE_PLUS_ADDITIONAL_KWARGS_DOCSTRING) + def batch_encode_plus( + self, + batch_text_or_text_pairs: Union[ + List[TextInput], + List[TextInputPair], + List[PreTokenizedInput], + List[PreTokenizedInputPair], + List[EncodedInput], + List[EncodedInputPair], + ], + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + """ + Tokenize and prepare for the model a list of sequences or a list of pairs of sequences. + + + + This method is deprecated, `__call__` should be used instead. + + + + Args: + batch_text_or_text_pairs (`List[str]`, `List[Tuple[str, str]]`, `List[List[str]]`, `List[Tuple[List[str], List[str]]]`, and for not-fast tokenizers, also `List[List[int]]`, `List[Tuple[List[int], List[int]]]`): + Batch of sequences or pair of sequences to be encoded. This can be a list of + string/string-sequences/int-sequences or a list of pair of string/string-sequences/int-sequence (see + details in `encode_plus`). + """ + + # Backward compatibility for 'truncation_strategy', 'pad_to_max_length' + padding_strategy, truncation_strategy, max_length, kwargs = self._get_padding_truncation_strategies( + padding=padding, + truncation=truncation, + max_length=max_length, + pad_to_multiple_of=pad_to_multiple_of, + verbose=verbose, + **kwargs, + ) + + return self._batch_encode_plus( + batch_text_or_text_pairs=batch_text_or_text_pairs, + add_special_tokens=add_special_tokens, + padding_strategy=padding_strategy, + truncation_strategy=truncation_strategy, + max_length=max_length, + stride=stride, + is_split_into_words=is_split_into_words, + pad_to_multiple_of=pad_to_multiple_of, + return_tensors=return_tensors, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + **kwargs, + ) + + def _batch_encode_plus( + self, + batch_text_or_text_pairs: Union[ + List[TextInput], + List[TextInputPair], + List[PreTokenizedInput], + List[PreTokenizedInputPair], + List[EncodedInput], + List[EncodedInputPair], + ], + add_special_tokens: bool = True, + padding_strategy: PaddingStrategy = PaddingStrategy.DO_NOT_PAD, + truncation_strategy: TruncationStrategy = TruncationStrategy.DO_NOT_TRUNCATE, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + raise NotImplementedError + + def pad( + self, + encoded_inputs: Union[ + BatchEncoding, + List[BatchEncoding], + Dict[str, EncodedInput], + Dict[str, List[EncodedInput]], + List[Dict[str, EncodedInput]], + ], + padding: Union[bool, str, PaddingStrategy] = True, + max_length: Optional[int] = None, + pad_to_multiple_of: Optional[int] = None, + return_attention_mask: Optional[bool] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + verbose: bool = True, + ) -> BatchEncoding: + """ + Pad a single encoded input or a batch of encoded inputs up to predefined length or to the max sequence length + in the batch. + + Padding side (left/right) padding token ids are defined at the tokenizer level (with `self.padding_side`, + `self.pad_token_id` and `self.pad_token_type_id`). + + Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the + text followed by a call to the `pad` method to get a padded encoding. + + + + If the `encoded_inputs` passed are dictionary of numpy arrays, PyTorch tensors or TensorFlow tensors, the + result will use the same type unless you provide a different tensor type with `return_tensors`. In the case of + PyTorch tensors, you will lose the specific device of your tensors however. + + + + Args: + encoded_inputs ([`BatchEncoding`], list of [`BatchEncoding`], `Dict[str, List[int]]`, `Dict[str, List[List[int]]` or `List[Dict[str, List[int]]]`): + Tokenized inputs. Can represent one input ([`BatchEncoding`] or `Dict[str, List[int]]`) or a batch of + tokenized inputs (list of [`BatchEncoding`], *Dict[str, List[List[int]]]* or *List[Dict[str, + List[int]]]*) so you can use this method during preprocessing as well as in a PyTorch Dataloader + collate function. + + Instead of `List[int]` you can have tensors (numpy arrays, PyTorch tensors or TensorFlow tensors), see + the note above for the return type. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `True`): + Select a strategy to pad the returned sequences (according to the model's padding side and padding + index) among: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + max_length (`int`, *optional*): + Maximum length of the returned list and optionally padding length (see above). + pad_to_multiple_of (`int`, *optional*): + If set will pad the sequence to a multiple of the provided value. + + This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability + `>= 7.5` (Volta). + return_attention_mask (`bool`, *optional*): + Whether to return the attention mask. If left to the default, will return the attention mask according + to the specific tokenizer's default, defined by the `return_outputs` attribute. + + [What are attention masks?](../glossary#attention-mask) + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + verbose (`bool`, *optional*, defaults to `True`): + Whether or not to print more information and warnings. + """ + if self.__class__.__name__.endswith("Fast"): + if not self.deprecation_warnings.get("Asking-to-pad-a-fast-tokenizer", False): + logger.warning_advice( + f"You're using a {self.__class__.__name__} tokenizer. Please note that with a fast tokenizer," + " using the `__call__` method is faster than using a method to encode the text followed by a call" + " to the `pad` method to get a padded encoding." + ) + self.deprecation_warnings["Asking-to-pad-a-fast-tokenizer"] = True + + # If we have a list of dicts, let's convert it in a dict of lists + # We do this to allow using this method as a collate_fn function in PyTorch Dataloader + if isinstance(encoded_inputs, (list, tuple)) and isinstance(encoded_inputs[0], Mapping): + encoded_inputs = {key: [example[key] for example in encoded_inputs] for key in encoded_inputs[0].keys()} + + # The model's main input name, usually `input_ids`, has be passed for padding + if self.model_input_names[0] not in encoded_inputs: + raise ValueError( + "You should supply an encoding or a list of encodings to this method " + f"that includes {self.model_input_names[0]}, but you provided {list(encoded_inputs.keys())}" + ) + + required_input = encoded_inputs[self.model_input_names[0]] + + if required_input is None or (isinstance(required_input, Sized) and len(required_input) == 0): + if return_attention_mask: + encoded_inputs["attention_mask"] = [] + return encoded_inputs + + # If we have PyTorch/TF/NumPy tensors/arrays as inputs, we cast them as python objects + # and rebuild them afterwards if no return_tensors is specified + # Note that we lose the specific device the tensor may be on for PyTorch + + first_element = required_input[0] + if isinstance(first_element, (list, tuple)): + # first_element might be an empty list/tuple in some edge cases so we grab the first non empty element. + for item in required_input: + if len(item) != 0: + first_element = item[0] + break + # At this state, if `first_element` is still a list/tuple, it's an empty one so there is nothing to do. + if not isinstance(first_element, (int, list, tuple)): + if is_tf_tensor(first_element): + return_tensors = "tf" if return_tensors is None else return_tensors + elif is_torch_tensor(first_element): + return_tensors = "pt" if return_tensors is None else return_tensors + elif isinstance(first_element, np.ndarray): + return_tensors = "np" if return_tensors is None else return_tensors + else: + raise ValueError( + f"type of {first_element} unknown: {type(first_element)}. " + "Should be one of a python, numpy, pytorch or tensorflow object." + ) + + for key, value in encoded_inputs.items(): + encoded_inputs[key] = to_py_obj(value) + + # Convert padding_strategy in PaddingStrategy + padding_strategy, _, max_length, _ = self._get_padding_truncation_strategies( + padding=padding, max_length=max_length, verbose=verbose + ) + + required_input = encoded_inputs[self.model_input_names[0]] + if required_input and not isinstance(required_input[0], (list, tuple)): + encoded_inputs = self._pad( + encoded_inputs, + max_length=max_length, + padding_strategy=padding_strategy, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=return_attention_mask, + ) + return BatchEncoding(encoded_inputs, tensor_type=return_tensors) + + batch_size = len(required_input) + assert all( + len(v) == batch_size for v in encoded_inputs.values() + ), "Some items in the output dictionary have a different batch size than others." + + if padding_strategy == PaddingStrategy.LONGEST: + max_length = max(len(inputs) for inputs in required_input) + padding_strategy = PaddingStrategy.MAX_LENGTH + + batch_outputs = {} + for i in range(batch_size): + inputs = {k: v[i] for k, v in encoded_inputs.items()} + outputs = self._pad( + inputs, + max_length=max_length, + padding_strategy=padding_strategy, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=return_attention_mask, + ) + + for key, value in outputs.items(): + if key not in batch_outputs: + batch_outputs[key] = [] + batch_outputs[key].append(value) + + return BatchEncoding(batch_outputs, tensor_type=return_tensors) + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create the token type IDs corresponding to the sequences passed. [What are token type + IDs?](../glossary#token-type-ids) + + Should be overridden in a subclass if the model has a special way of building those. + + Args: + token_ids_0 (`List[int]`): The first tokenized sequence. + token_ids_1 (`List[int]`, *optional*): The second tokenized sequence. + + Returns: + `List[int]`: The token type ids. + """ + if token_ids_1 is None: + return len(token_ids_0) * [0] + return [0] * len(token_ids_0) + [1] * len(token_ids_1) + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and + adding special tokens. + + This implementation does not add special tokens and this method should be overridden in a subclass. + + Args: + token_ids_0 (`List[int]`): The first tokenized sequence. + token_ids_1 (`List[int]`, *optional*): The second tokenized sequence. + + Returns: + `List[int]`: The model input with special tokens. + """ + if token_ids_1 is None: + return token_ids_0 + return token_ids_0 + token_ids_1 + + @add_end_docstrings(ENCODE_KWARGS_DOCSTRING, ENCODE_PLUS_ADDITIONAL_KWARGS_DOCSTRING) + def prepare_for_model( + self, + ids: List[int], + pair_ids: Optional[List[int]] = None, + add_special_tokens: bool = True, + padding: Union[bool, str, PaddingStrategy] = False, + truncation: Union[bool, str, TruncationStrategy] = None, + max_length: Optional[int] = None, + stride: int = 0, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[Union[str, TensorType]] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + prepend_batch_axis: bool = False, + **kwargs, + ) -> BatchEncoding: + """ + Prepares a sequence of input id, or a pair of sequences of inputs ids so that it can be used by the model. It + adds special tokens, truncates sequences if overflowing while taking into account the special tokens and + manages a moving window (with user defined stride) for overflowing tokens. Please Note, for *pair_ids* + different than `None` and *truncation_strategy = longest_first* or `True`, it is not possible to return + overflowing tokens. Such a combination of arguments will raise an error. + + Args: + ids (`List[int]`): + Tokenized input ids of the first sequence. Can be obtained from a string by chaining the `tokenize` and + `convert_tokens_to_ids` methods. + pair_ids (`List[int]`, *optional*): + Tokenized input ids of the second sequence. Can be obtained from a string by chaining the `tokenize` + and `convert_tokens_to_ids` methods. + """ + + # Backward compatibility for 'truncation_strategy', 'pad_to_max_length' + padding_strategy, truncation_strategy, max_length, kwargs = self._get_padding_truncation_strategies( + padding=padding, + truncation=truncation, + max_length=max_length, + pad_to_multiple_of=pad_to_multiple_of, + verbose=verbose, + **kwargs, + ) + + pair = bool(pair_ids is not None) + len_ids = len(ids) + len_pair_ids = len(pair_ids) if pair else 0 + + if return_token_type_ids and not add_special_tokens: + raise ValueError( + "Asking to return token_type_ids while setting add_special_tokens to False " + "results in an undefined behavior. Please set add_special_tokens to True or " + "set return_token_type_ids to None." + ) + + if ( + return_overflowing_tokens + and truncation_strategy == TruncationStrategy.LONGEST_FIRST + and pair_ids is not None + ): + raise ValueError( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + + # Load from model defaults + if return_token_type_ids is None: + return_token_type_ids = "token_type_ids" in self.model_input_names + if return_attention_mask is None: + return_attention_mask = "attention_mask" in self.model_input_names + + encoded_inputs = {} + + # Compute the total size of the returned encodings + total_len = len_ids + len_pair_ids + (self.num_special_tokens_to_add(pair=pair) if add_special_tokens else 0) + + # Truncation: Handle max sequence length + overflowing_tokens = [] + if truncation_strategy != TruncationStrategy.DO_NOT_TRUNCATE and max_length and total_len > max_length: + ids, pair_ids, overflowing_tokens = self.truncate_sequences( + ids, + pair_ids=pair_ids, + num_tokens_to_remove=total_len - max_length, + truncation_strategy=truncation_strategy, + stride=stride, + ) + + if return_overflowing_tokens: + encoded_inputs["overflowing_tokens"] = overflowing_tokens + encoded_inputs["num_truncated_tokens"] = total_len - max_length + + # Add special tokens + if add_special_tokens: + sequence = self.build_inputs_with_special_tokens(ids, pair_ids) + token_type_ids = self.create_token_type_ids_from_sequences(ids, pair_ids) + else: + sequence = ids + pair_ids if pair else ids + token_type_ids = [0] * len(ids) + ([0] * len(pair_ids) if pair else []) + + # Build output dictionary + encoded_inputs["input_ids"] = sequence + if return_token_type_ids: + encoded_inputs["token_type_ids"] = token_type_ids + if return_special_tokens_mask: + if add_special_tokens: + encoded_inputs["special_tokens_mask"] = self.get_special_tokens_mask(ids, pair_ids) + else: + encoded_inputs["special_tokens_mask"] = [0] * len(sequence) + + # Check lengths + self._eventual_warn_about_too_long_sequence(encoded_inputs["input_ids"], max_length, verbose) + + # Padding + if padding_strategy != PaddingStrategy.DO_NOT_PAD or return_attention_mask: + encoded_inputs = self.pad( + encoded_inputs, + max_length=max_length, + padding=padding_strategy.value, + pad_to_multiple_of=pad_to_multiple_of, + return_attention_mask=return_attention_mask, + ) + + if return_length: + encoded_inputs["length"] = len(encoded_inputs["input_ids"]) + + batch_outputs = BatchEncoding( + encoded_inputs, tensor_type=return_tensors, prepend_batch_axis=prepend_batch_axis + ) + + return batch_outputs + + def truncate_sequences( + self, + ids: List[int], + pair_ids: Optional[List[int]] = None, + num_tokens_to_remove: int = 0, + truncation_strategy: Union[str, TruncationStrategy] = "longest_first", + stride: int = 0, + ) -> Tuple[List[int], List[int], List[int]]: + """ + Truncates a sequence pair in-place following the strategy. + + Args: + ids (`List[int]`): + Tokenized input ids of the first sequence. Can be obtained from a string by chaining the `tokenize` and + `convert_tokens_to_ids` methods. + pair_ids (`List[int]`, *optional*): + Tokenized input ids of the second sequence. Can be obtained from a string by chaining the `tokenize` + and `convert_tokens_to_ids` methods. + num_tokens_to_remove (`int`, *optional*, defaults to 0): + Number of tokens to remove using the truncation strategy. + truncation_strategy (`str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `False`): + The strategy to follow for truncation. Can be: + + - `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will truncate + token by token, removing a token from the longest sequence in the pair if a pair of sequences (or a + batch of pairs) is provided. + - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the first sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the second sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths greater + than the model maximum admissible input size). + stride (`int`, *optional*, defaults to 0): + If set to a positive number, the overflowing tokens returned will contain some tokens from the main + sequence returned. The value of this argument defines the number of additional tokens. + + Returns: + `Tuple[List[int], List[int], List[int]]`: The truncated `ids`, the truncated `pair_ids` and the list of + overflowing tokens. Note: The *longest_first* strategy returns empty list of overflowing tokens if a pair + of sequences (or a batch of pairs) is provided. + """ + if num_tokens_to_remove <= 0: + return ids, pair_ids, [] + + if not isinstance(truncation_strategy, TruncationStrategy): + truncation_strategy = TruncationStrategy(truncation_strategy) + + overflowing_tokens = [] + if truncation_strategy == TruncationStrategy.ONLY_FIRST or ( + truncation_strategy == TruncationStrategy.LONGEST_FIRST and pair_ids is None + ): + if len(ids) > num_tokens_to_remove: + window_len = min(len(ids), stride + num_tokens_to_remove) + if self.truncation_side == "left": + overflowing_tokens = ids[:window_len] + ids = ids[num_tokens_to_remove:] + elif self.truncation_side == "right": + overflowing_tokens = ids[-window_len:] + ids = ids[:-num_tokens_to_remove] + else: + raise ValueError(f"invalid truncation strategy: {self.truncation_side}, use 'left' or 'right'.") + + else: + error_msg = ( + f"We need to remove {num_tokens_to_remove} to truncate the input " + f"but the first sequence has a length {len(ids)}. " + ) + if truncation_strategy == TruncationStrategy.ONLY_FIRST: + error_msg = ( + error_msg + "Please select another truncation strategy than " + f"{truncation_strategy}, for instance 'longest_first' or 'only_second'." + ) + logger.error(error_msg) + elif truncation_strategy == TruncationStrategy.LONGEST_FIRST: + logger.warning( + "Be aware, overflowing tokens are not returned for the setting you have chosen," + f" i.e. sequence pairs with the '{TruncationStrategy.LONGEST_FIRST.value}' " + "truncation strategy. So the returned list will always be empty even if some " + "tokens have been removed." + ) + for _ in range(num_tokens_to_remove): + if pair_ids is None or len(ids) > len(pair_ids): + if self.truncation_side == "right": + ids = ids[:-1] + elif self.truncation_side == "left": + ids = ids[1:] + else: + raise ValueError("invalid truncation strategy:" + str(self.truncation_side)) + else: + if self.truncation_side == "right": + pair_ids = pair_ids[:-1] + elif self.truncation_side == "left": + pair_ids = pair_ids[1:] + else: + raise ValueError("invalid truncation strategy:" + str(self.truncation_side)) + elif truncation_strategy == TruncationStrategy.ONLY_SECOND and pair_ids is not None: + if len(pair_ids) > num_tokens_to_remove: + window_len = min(len(pair_ids), stride + num_tokens_to_remove) + if self.truncation_side == "right": + overflowing_tokens = pair_ids[-window_len:] + pair_ids = pair_ids[:-num_tokens_to_remove] + elif self.truncation_side == "left": + overflowing_tokens = pair_ids[:window_len] + pair_ids = pair_ids[num_tokens_to_remove:] + else: + raise ValueError("invalid truncation strategy:" + str(self.truncation_side)) + else: + logger.error( + f"We need to remove {num_tokens_to_remove} to truncate the input " + f"but the second sequence has a length {len(pair_ids)}. " + f"Please select another truncation strategy than {truncation_strategy}, " + "for instance 'longest_first' or 'only_first'." + ) + + return (ids, pair_ids, overflowing_tokens) + + def _pad( + self, + encoded_inputs: Union[Dict[str, EncodedInput], BatchEncoding], + max_length: Optional[int] = None, + padding_strategy: PaddingStrategy = PaddingStrategy.DO_NOT_PAD, + pad_to_multiple_of: Optional[int] = None, + return_attention_mask: Optional[bool] = None, + ) -> dict: + """ + Pad encoded inputs (on left/right and up to predefined length or max length in the batch) + + Args: + encoded_inputs: + Dictionary of tokenized inputs (`List[int]`) or batch of tokenized inputs (`List[List[int]]`). + max_length: maximum length of the returned list and optionally padding length (see below). + Will truncate by taking into account the special tokens. + padding_strategy: PaddingStrategy to use for padding. + + - PaddingStrategy.LONGEST Pad to the longest sequence in the batch + - PaddingStrategy.MAX_LENGTH: Pad to the max length (default) + - PaddingStrategy.DO_NOT_PAD: Do not pad + The tokenizer padding sides are defined in self.padding_side: + + - 'left': pads on the left of the sequences + - 'right': pads on the right of the sequences + pad_to_multiple_of: (optional) Integer if set will pad the sequence to a multiple of the provided value. + This is especially useful to enable the use of Tensor Core on NVIDIA hardware with compute capability + `>= 7.5` (Volta). + return_attention_mask: + (optional) Set to False to avoid returning attention mask (default: set to model specifics) + """ + # Load from model defaults + if return_attention_mask is None: + return_attention_mask = "attention_mask" in self.model_input_names + + required_input = encoded_inputs[self.model_input_names[0]] + + if padding_strategy == PaddingStrategy.LONGEST: + max_length = len(required_input) + + if max_length is not None and pad_to_multiple_of is not None and (max_length % pad_to_multiple_of != 0): + max_length = ((max_length // pad_to_multiple_of) + 1) * pad_to_multiple_of + + needs_to_be_padded = padding_strategy != PaddingStrategy.DO_NOT_PAD and len(required_input) != max_length + + # Initialize attention mask if not present. + if return_attention_mask and "attention_mask" not in encoded_inputs: + encoded_inputs["attention_mask"] = [1] * len(required_input) + + if needs_to_be_padded: + difference = max_length - len(required_input) + + if self.padding_side == "right": + if return_attention_mask: + encoded_inputs["attention_mask"] = encoded_inputs["attention_mask"] + [0] * difference + if "token_type_ids" in encoded_inputs: + encoded_inputs["token_type_ids"] = ( + encoded_inputs["token_type_ids"] + [self.pad_token_type_id] * difference + ) + if "special_tokens_mask" in encoded_inputs: + encoded_inputs["special_tokens_mask"] = encoded_inputs["special_tokens_mask"] + [1] * difference + encoded_inputs[self.model_input_names[0]] = required_input + [self.pad_token_id] * difference + elif self.padding_side == "left": + if return_attention_mask: + encoded_inputs["attention_mask"] = [0] * difference + encoded_inputs["attention_mask"] + if "token_type_ids" in encoded_inputs: + encoded_inputs["token_type_ids"] = [self.pad_token_type_id] * difference + encoded_inputs[ + "token_type_ids" + ] + if "special_tokens_mask" in encoded_inputs: + encoded_inputs["special_tokens_mask"] = [1] * difference + encoded_inputs["special_tokens_mask"] + encoded_inputs[self.model_input_names[0]] = [self.pad_token_id] * difference + required_input + else: + raise ValueError("Invalid padding strategy:" + str(self.padding_side)) + + return encoded_inputs + + def convert_tokens_to_string(self, tokens: List[str]) -> str: + """ + Converts a sequence of tokens in a single string. The most simple way to do it is `" ".join(tokens)` but we + often want to remove sub-word tokenization artifacts at the same time. + + Args: + tokens (`List[str]`): The token to join in a string. + + Returns: + `str`: The joined tokens. + """ + raise NotImplementedError + + def batch_decode( + self, + sequences: Union[List[int], List[List[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + **kwargs, + ) -> List[str]: + """ + Convert a list of lists of token ids into a list of strings by calling decode. + + Args: + sequences (`Union[List[int], List[List[int]], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. If `None`, will default to + `self.clean_up_tokenization_spaces`. + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `List[str]`: The list of decoded sentences. + """ + return [ + self.decode( + seq, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + for seq in sequences + ] + + def decode( + self, + token_ids: Union[int, List[int], "np.ndarray", "torch.Tensor", "tf.Tensor"], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + **kwargs, + ) -> str: + """ + Converts a sequence of ids in a string, using the tokenizer and vocabulary with options to remove special + tokens and clean up tokenization spaces. + + Similar to doing `self.convert_tokens_to_string(self.convert_ids_to_tokens(token_ids))`. + + Args: + token_ids (`Union[int, List[int], np.ndarray, torch.Tensor, tf.Tensor]`): + List of tokenized input ids. Can be obtained using the `__call__` method. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + clean_up_tokenization_spaces (`bool`, *optional*): + Whether or not to clean up the tokenization spaces. If `None`, will default to + `self.clean_up_tokenization_spaces`. + kwargs (additional keyword arguments, *optional*): + Will be passed to the underlying model specific decode method. + + Returns: + `str`: The decoded sentence. + """ + # Convert inputs to python lists + token_ids = to_py_obj(token_ids) + + return self._decode( + token_ids=token_ids, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + + def _decode( + self, + token_ids: Union[int, List[int]], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + **kwargs, + ) -> str: + raise NotImplementedError + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieves sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` or `encode_plus` methods. + + Args: + token_ids_0 (`List[int]`): + List of ids of the first sequence. + token_ids_1 (`List[int]`, *optional*): + List of ids of the second sequence. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + assert already_has_special_tokens and token_ids_1 is None, ( + "You cannot use ``already_has_special_tokens=False`` with this tokenizer. " + "Please use a slow (full python) tokenizer to activate this argument. " + "Or set `return_special_tokens_mask=True` when calling the encoding method " + "to get the special tokens mask in any tokenizer. " + ) + + all_special_ids = self.all_special_ids # cache the property + + special_tokens_mask = [1 if token in all_special_ids else 0 for token in token_ids_0] + + return special_tokens_mask + + @staticmethod + def clean_up_tokenization(out_string: str) -> str: + """ + Clean up a list of simple English tokenization artifacts like spaces before punctuations and abbreviated forms. + + Args: + out_string (`str`): The text to clean up. + + Returns: + `str`: The cleaned-up string. + """ + out_string = ( + out_string.replace(" .", ".") + .replace(" ?", "?") + .replace(" !", "!") + .replace(" ,", ",") + .replace(" ' ", "'") + .replace(" n't", "n't") + .replace(" 'm", "'m") + .replace(" 's", "'s") + .replace(" 've", "'ve") + .replace(" 're", "'re") + ) + return out_string + + def _eventual_warn_about_too_long_sequence(self, ids: List[int], max_length: Optional[int], verbose: bool): + """ + Depending on the input and internal state we might trigger a warning about a sequence that is too long for its + corresponding model + + Args: + ids (`List[str]`): The ids produced by the tokenization + max_length (`int`, *optional*): The max_length desired (does not trigger a warning if it is set) + verbose (`bool`): Whether or not to print more information and warnings. + + """ + if max_length is None and len(ids) > self.model_max_length and verbose: + if not self.deprecation_warnings.get("sequence-length-is-longer-than-the-specified-maximum", False): + logger.warning( + "Token indices sequence length is longer than the specified maximum sequence length " + f"for this model ({len(ids)} > {self.model_max_length}). Running this sequence through the model " + "will result in indexing errors" + ) + self.deprecation_warnings["sequence-length-is-longer-than-the-specified-maximum"] = True + + def _switch_to_input_mode(self): + """ + Private method to put the tokenizer in input mode (when it has different modes for input/outputs) + """ + pass + + def _switch_to_target_mode(self): + """ + Private method to put the tokenizer in target mode (when it has different modes for input/outputs) + """ + pass + + @contextmanager + def as_target_tokenizer(self): + """ + Temporarily sets the tokenizer for encoding the targets. Useful for tokenizer associated to + sequence-to-sequence models that need a slightly different processing for the labels. + """ + warnings.warn( + "`as_target_tokenizer` is deprecated and will be removed in v5 of Transformers. You can tokenize your " + "labels by using the argument `text_target` of the regular `__call__` method (either in the same call as " + "your input texts if you use the same keyword arguments, or in a separate call." + ) + self._switch_to_target_mode() + self._in_target_context_manager = True + yield + self._in_target_context_manager = False + self._switch_to_input_mode() + + @classmethod + def register_for_auto_class(cls, auto_class="AutoTokenizer"): + """ + Register this class with a given auto class. This should only be used for custom tokenizers as the ones in the + library are already mapped with `AutoTokenizer`. + + + + This API is experimental and may have some slight breaking changes in the next releases. + + + + Args: + auto_class (`str` or `type`, *optional*, defaults to `"AutoTokenizer"`): + The auto class to register this new tokenizer with. + """ + if not isinstance(auto_class, str): + auto_class = auto_class.__name__ + + import transformers.models.auto as auto_module + + if not hasattr(auto_module, auto_class): + raise ValueError(f"{auto_class} is not a valid auto class.") + + cls._auto_class = auto_class + + def prepare_seq2seq_batch( + self, + src_texts: List[str], + tgt_texts: Optional[List[str]] = None, + max_length: Optional[int] = None, + max_target_length: Optional[int] = None, + padding: str = "longest", + return_tensors: str = None, + truncation: bool = True, + **kwargs, + ) -> BatchEncoding: + """ + Prepare model inputs for translation. For best performance, translate one sentence at a time. + + Arguments: + src_texts (`List[str]`): + List of documents to summarize or source language texts. + tgt_texts (`list`, *optional*): + List of summaries or target language texts. + max_length (`int`, *optional*): + Controls the maximum length for encoder inputs (documents to summarize or source language texts) If + left unset or set to `None`, this will use the predefined model maximum length if a maximum length is + required by one of the truncation/padding parameters. If the model has no specific maximum input length + (like XLNet) truncation/padding to a maximum length will be deactivated. + max_target_length (`int`, *optional*): + Controls the maximum length of decoder inputs (target language texts or summaries) If left unset or set + to `None`, this will use the max_length value. + padding (`bool`, `str` or [`~utils.PaddingStrategy`], *optional*, defaults to `False`): + Activates and controls padding. Accepts the following values: + + - `True` or `'longest'`: Pad to the longest sequence in the batch (or no padding if only a single + sequence if provided). + - `'max_length'`: Pad to a maximum length specified with the argument `max_length` or to the maximum + acceptable input length for the model if that argument is not provided. + - `False` or `'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of different + lengths). + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors instead of list of python integers. Acceptable values are: + + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return Numpy `np.ndarray` objects. + truncation (`bool`, `str` or [`~tokenization_utils_base.TruncationStrategy`], *optional*, defaults to `True`): + Activates and controls truncation. Accepts the following values: + + - `True` or `'longest_first'`: Truncate to a maximum length specified with the argument `max_length` or + to the maximum acceptable input length for the model if that argument is not provided. This will + truncate token by token, removing a token from the longest sequence in the pair if a pair of + sequences (or a batch of pairs) is provided. + - `'only_first'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the first sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `'only_second'`: Truncate to a maximum length specified with the argument `max_length` or to the + maximum acceptable input length for the model if that argument is not provided. This will only + truncate the second sequence of a pair if a pair of sequences (or a batch of pairs) is provided. + - `False` or `'do_not_truncate'` (default): No truncation (i.e., can output batch with sequence lengths + greater than the model maximum admissible input size). + **kwargs: + Additional keyword arguments passed along to `self.__call__`. + + Return: + [`BatchEncoding`]: A [`BatchEncoding`] with the following fields: + + - **input_ids** -- List of token ids to be fed to the encoder. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model. + - **labels** -- List of token ids for tgt_texts. + + The full set of keys `[input_ids, attention_mask, labels]`, will only be returned if tgt_texts is passed. + Otherwise, input_ids, attention_mask will be the only keys. + """ + # docstyle-ignore + formatted_warning = """ +`prepare_seq2seq_batch` is deprecated and will be removed in version 5 of HuggingFace Transformers. Use the regular +`__call__` method to prepare your inputs and targets. + +Here is a short example: + +model_inputs = tokenizer(src_texts, text_target=tgt_texts, ...) + +If you either need to use different keyword arguments for the source and target texts, you should do two calls like +this: + +model_inputs = tokenizer(src_texts, ...) +labels = tokenizer(text_target=tgt_texts, ...) +model_inputs["labels"] = labels["input_ids"] + +See the documentation of your specific tokenizer for more details on the specific arguments to the tokenizer of choice. +For a more complete example, see the implementation of `prepare_seq2seq_batch`. +""" + warnings.warn(formatted_warning, FutureWarning) + # mBART-specific kwargs that should be ignored by other models. + kwargs.pop("src_lang", None) + kwargs.pop("tgt_lang", None) + if max_length is None: + max_length = self.model_max_length + model_inputs = self( + src_texts, + add_special_tokens=True, + return_tensors=return_tensors, + max_length=max_length, + padding=padding, + truncation=truncation, + **kwargs, + ) + if tgt_texts is None: + return model_inputs + # Process tgt_texts + if max_target_length is None: + max_target_length = max_length + with self.as_target_tokenizer(): + labels = self( + tgt_texts, + add_special_tokens=True, + return_tensors=return_tensors, + padding=padding, + max_length=max_target_length, + truncation=truncation, + **kwargs, + ) + model_inputs["labels"] = labels["input_ids"] + return model_inputs + + +def get_fast_tokenizer_file(tokenization_files: List[str]) -> str: + """ + Get the tokenization file to use for this version of transformers. + + Args: + tokenization_files (`List[str]`): The list of available configuration files. + + Returns: + `str`: The tokenization file to use. + """ + tokenizer_files_map = {} + for file_name in tokenization_files: + search = _re_tokenizer_file.search(file_name) + if search is not None: + v = search.groups()[0] + tokenizer_files_map[v] = file_name + available_versions = sorted(tokenizer_files_map.keys()) + + # Defaults to FULL_TOKENIZER_FILE and then try to look at some newer versions. + tokenizer_file = FULL_TOKENIZER_FILE + transformers_version = version.parse(__version__) + for v in available_versions: + if version.parse(v) <= transformers_version: + tokenizer_file = tokenizer_files_map[v] + else: + # No point going further since the versions are sorted. + break + + return tokenizer_file + + +# To update the docstring, we need to copy the method, otherwise we change the original docstring. +PreTrainedTokenizerBase.push_to_hub = copy_func(PreTrainedTokenizerBase.push_to_hub) +if PreTrainedTokenizerBase.push_to_hub.__doc__ is not None: + PreTrainedTokenizerBase.push_to_hub.__doc__ = PreTrainedTokenizerBase.push_to_hub.__doc__.format( + object="tokenizer", object_class="AutoTokenizer", object_files="tokenizer files" + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_fast.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_fast.py new file mode 100644 index 0000000000000000000000000000000000000000..51b5acebbf271f0ee5270cef7273ad306d25297e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tokenization_utils_fast.py @@ -0,0 +1,768 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + Tokenization classes for fast tokenizers (provided by HuggingFace's tokenizers library). For slow (python) tokenizers + see tokenization_utils.py +""" +import copy +import json +import os +from collections import defaultdict +from typing import Any, Dict, List, Optional, Tuple, Union + +import tokenizers.pre_tokenizers as pre_tokenizers_fast +from tokenizers import Encoding as EncodingFast +from tokenizers import Tokenizer as TokenizerFast +from tokenizers.decoders import Decoder as DecoderFast +from tokenizers.trainers import BpeTrainer, UnigramTrainer, WordLevelTrainer, WordPieceTrainer + +from .convert_slow_tokenizer import convert_slow_tokenizer +from .tokenization_utils import PreTrainedTokenizer +from .tokenization_utils_base import ( + INIT_TOKENIZER_DOCSTRING, + AddedToken, + BatchEncoding, + PreTokenizedInput, + PreTokenizedInputPair, + PreTrainedTokenizerBase, + SpecialTokensMixin, + TextInput, + TextInputPair, + TruncationStrategy, +) +from .utils import PaddingStrategy, add_end_docstrings, logging + + +logger = logging.get_logger(__name__) + +# Fast tokenizers (provided by HuggingFace tokenizer's library) can be saved in a single file +TOKENIZER_FILE = "tokenizer.json" +SPECIAL_TOKENS_MAP_FILE = "special_tokens_map.json" +TOKENIZER_CONFIG_FILE = "tokenizer_config.json" + +# Slow tokenizers have an additional added tokens files +ADDED_TOKENS_FILE = "added_tokens.json" + +INIT_TOKENIZER_DOCSTRING += """ + tokenizer_object ([`tokenizers.Tokenizer`]): + A [`tokenizers.Tokenizer`] object from 🤗 tokenizers to instantiate from. See [Using tokenizers from 🤗 + tokenizers](../fast_tokenizers) for more information. + tokenizer_file ([`str`]): + A path to a local JSON file representing a previously serialized [`tokenizers.Tokenizer`] object from 🤗 + tokenizers. +""" + +MODEL_TO_TRAINER_MAPPING = { + "BPE": BpeTrainer, + "Unigram": UnigramTrainer, + "WordLevel": WordLevelTrainer, + "WordPiece": WordPieceTrainer, +} + +VOCAB_FILES_NAMES = {"tokenizer_file": TOKENIZER_FILE} + + +@add_end_docstrings(INIT_TOKENIZER_DOCSTRING) +class PreTrainedTokenizerFast(PreTrainedTokenizerBase): + """ + Base class for all fast tokenizers (wrapping HuggingFace tokenizers library). + + Inherits from [`~tokenization_utils_base.PreTrainedTokenizerBase`]. + + Handles all the shared methods for tokenization and special tokens, as well as methods for + downloading/caching/loading pretrained tokenizers, as well as adding tokens to the vocabulary. + + This class also contains the added tokens in a unified way on top of all tokenizers so we don't have to handle the + specific vocabulary augmentation methods of the various underlying dictionary structures (BPE, sentencepiece...). + """ + + vocab_files_names = VOCAB_FILES_NAMES + slow_tokenizer_class: PreTrainedTokenizer = None + can_save_slow_tokenizer: bool = True + + def __init__(self, *args, **kwargs): + tokenizer_object = kwargs.pop("tokenizer_object", None) + slow_tokenizer = kwargs.pop("__slow_tokenizer", None) + fast_tokenizer_file = kwargs.pop("tokenizer_file", None) + from_slow = kwargs.pop("from_slow", False) + + if from_slow and slow_tokenizer is None and self.slow_tokenizer_class is None: + raise ValueError( + "Cannot instantiate this tokenizer from a slow version. If it's based on sentencepiece, make sure you " + "have sentencepiece installed." + ) + + if tokenizer_object is not None: + fast_tokenizer = copy.deepcopy(tokenizer_object) + elif fast_tokenizer_file is not None and not from_slow: + # We have a serialization from tokenizers which let us directly build the backend + fast_tokenizer = TokenizerFast.from_file(fast_tokenizer_file) + elif slow_tokenizer is not None: + # We need to convert a slow tokenizer to build the backend + fast_tokenizer = convert_slow_tokenizer(slow_tokenizer) + elif self.slow_tokenizer_class is not None: + # We need to create and convert a slow tokenizer to build the backend + slow_tokenizer = self.slow_tokenizer_class(*args, **kwargs) + fast_tokenizer = convert_slow_tokenizer(slow_tokenizer) + else: + raise ValueError( + "Couldn't instantiate the backend tokenizer from one of: \n" + "(1) a `tokenizers` library serialization file, \n" + "(2) a slow tokenizer instance to convert or \n" + "(3) an equivalent slow tokenizer class to instantiate and convert. \n" + "You need to have sentencepiece installed to convert a slow tokenizer to a fast one." + ) + + self._tokenizer = fast_tokenizer + + if slow_tokenizer is not None: + kwargs.update(slow_tokenizer.init_kwargs) + + self._decode_use_source_tokenizer = False + + # We call this after having initialized the backend tokenizer because we update it. + super().__init__(**kwargs) + + @property + def is_fast(self) -> bool: + return True + + @property + def vocab_size(self) -> int: + """ + `int`: Size of the base vocabulary (without the added tokens). + """ + return self._tokenizer.get_vocab_size(with_added_tokens=False) + + def get_vocab(self) -> Dict[str, int]: + return self._tokenizer.get_vocab(with_added_tokens=True) + + @property + def vocab(self) -> Dict[str, int]: + return self.get_vocab() + + def get_added_vocab(self) -> Dict[str, int]: + """ + Returns the added tokens in the vocabulary as a dictionary of token to index. + + Returns: + `Dict[str, int]`: The added tokens. + """ + base_vocab = self._tokenizer.get_vocab(with_added_tokens=False) + full_vocab = self._tokenizer.get_vocab(with_added_tokens=True) + added_vocab = {tok: index for tok, index in full_vocab.items() if tok not in base_vocab} + return added_vocab + + def __len__(self) -> int: + """ + Size of the full vocabulary with the added tokens. + """ + return self._tokenizer.get_vocab_size(with_added_tokens=True) + + @property + def backend_tokenizer(self) -> TokenizerFast: + """ + `tokenizers.implementations.BaseTokenizer`: The Rust tokenizer used as a backend. + """ + return self._tokenizer + + @property + def decoder(self) -> DecoderFast: + """ + `tokenizers.decoders.Decoder`: The Rust decoder for this tokenizer. + """ + return self._tokenizer.decoder + + def _convert_encoding( + self, + encoding: EncodingFast, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + ) -> Tuple[Dict[str, Any], List[EncodingFast]]: + """ + Convert the encoding representation (from low-level HuggingFace tokenizer output) to a python Dict and a list + of encodings, take care of building a batch from overflowing tokens. + + Overflowing tokens are converted to additional examples (like batches) so the output values of the dict are + lists (overflows) of lists (tokens). + + Output shape: (overflows, sequence length) + """ + if return_token_type_ids is None: + return_token_type_ids = "token_type_ids" in self.model_input_names + if return_attention_mask is None: + return_attention_mask = "attention_mask" in self.model_input_names + + if return_overflowing_tokens and encoding.overflowing is not None: + encodings = [encoding] + encoding.overflowing + else: + encodings = [encoding] + + encoding_dict = defaultdict(list) + for e in encodings: + encoding_dict["input_ids"].append(e.ids) + + if return_token_type_ids: + encoding_dict["token_type_ids"].append(e.type_ids) + if return_attention_mask: + encoding_dict["attention_mask"].append(e.attention_mask) + if return_special_tokens_mask: + encoding_dict["special_tokens_mask"].append(e.special_tokens_mask) + if return_offsets_mapping: + encoding_dict["offset_mapping"].append(e.offsets) + if return_length: + encoding_dict["length"].append(len(e.ids)) + + return encoding_dict, encodings + + def convert_tokens_to_ids(self, tokens: Union[str, List[str]]) -> Union[int, List[int]]: + """ + Converts a token string (or a sequence of tokens) in a single integer id (or a sequence of ids), using the + vocabulary. + + Args: + tokens (`str` or `List[str]`): One or several token(s) to convert to token id(s). + + Returns: + `int` or `List[int]`: The token id or list of token ids. + """ + if tokens is None: + return None + + if isinstance(tokens, str): + return self._convert_token_to_id_with_added_voc(tokens) + + ids = [] + for token in tokens: + ids.append(self._convert_token_to_id_with_added_voc(token)) + return ids + + def _convert_token_to_id_with_added_voc(self, token: str) -> int: + index = self._tokenizer.token_to_id(token) + if index is None: + return self.unk_token_id + return index + + def _convert_id_to_token(self, index: int) -> Optional[str]: + return self._tokenizer.id_to_token(int(index)) + + def _add_tokens(self, new_tokens: List[Union[str, AddedToken]], special_tokens=False) -> int: + if special_tokens: + return self._tokenizer.add_special_tokens(new_tokens) + + return self._tokenizer.add_tokens(new_tokens) + + def num_special_tokens_to_add(self, pair: bool = False) -> int: + """ + Returns the number of added tokens when encoding a sequence with special tokens. + + + + This encodes a dummy input and checks the number of added tokens, and is therefore not efficient. Do not put + this inside your training loop. + + + + Args: + pair (`bool`, *optional*, defaults to `False`): + Whether the number of added tokens should be computed in the case of a sequence pair or a single + sequence. + + Returns: + `int`: Number of special tokens added to sequences. + """ + return self._tokenizer.num_special_tokens_to_add(pair) + + def convert_ids_to_tokens( + self, ids: Union[int, List[int]], skip_special_tokens: bool = False + ) -> Union[str, List[str]]: + """ + Converts a single index or a sequence of indices in a token or a sequence of tokens, using the vocabulary and + added tokens. + + Args: + ids (`int` or `List[int]`): + The token id (or token ids) to convert to tokens. + skip_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not to remove special tokens in the decoding. + + Returns: + `str` or `List[str]`: The decoded token(s). + """ + if isinstance(ids, int): + return self._tokenizer.id_to_token(ids) + tokens = [] + for index in ids: + index = int(index) + if skip_special_tokens and index in self.all_special_ids: + continue + tokens.append(self._tokenizer.id_to_token(index)) + return tokens + + def tokenize(self, text: str, pair: Optional[str] = None, add_special_tokens: bool = False, **kwargs) -> List[str]: + return self.encode_plus(text=text, text_pair=pair, add_special_tokens=add_special_tokens, **kwargs).tokens() + + def set_truncation_and_padding( + self, + padding_strategy: PaddingStrategy, + truncation_strategy: TruncationStrategy, + max_length: int, + stride: int, + pad_to_multiple_of: Optional[int], + ): + """ + Define the truncation and the padding strategies for fast tokenizers (provided by HuggingFace tokenizers + library) and restore the tokenizer settings afterwards. + + The provided tokenizer has no padding / truncation strategy before the managed section. If your tokenizer set a + padding / truncation strategy before, then it will be reset to no padding / truncation when exiting the managed + section. + + Args: + padding_strategy ([`~utils.PaddingStrategy`]): + The kind of padding that will be applied to the input + truncation_strategy ([`~tokenization_utils_base.TruncationStrategy`]): + The kind of truncation that will be applied to the input + max_length (`int`): + The maximum size of a sequence. + stride (`int`): + The stride to use when handling overflow. + pad_to_multiple_of (`int`, *optional*): + If set will pad the sequence to a multiple of the provided value. This is especially useful to enable + the use of Tensor Cores on NVIDIA hardware with compute capability `>= 7.5` (Volta). + """ + _truncation = self._tokenizer.truncation + _padding = self._tokenizer.padding + # Set truncation and padding on the backend tokenizer + if truncation_strategy == TruncationStrategy.DO_NOT_TRUNCATE: + if _truncation is not None: + self._tokenizer.no_truncation() + else: + target = { + "max_length": max_length, + "stride": stride, + "strategy": truncation_strategy.value, + "direction": self.truncation_side, + } + + # _truncation might contain more keys that the target `transformers` + # supports. Use only the target keys to trigger `enable_truncation`. + # This should enable this code to works on various `tokenizers` + # targets. + if _truncation is None: + current = None + else: + current = {k: _truncation.get(k, None) for k in target} + + if current != target: + self._tokenizer.enable_truncation(**target) + + if padding_strategy == PaddingStrategy.DO_NOT_PAD: + if _padding is not None: + self._tokenizer.no_padding() + else: + length = max_length if padding_strategy == PaddingStrategy.MAX_LENGTH else None + target = { + "length": length, + "direction": self.padding_side, + "pad_id": self.pad_token_id, + "pad_token": self.pad_token, + "pad_type_id": self.pad_token_type_id, + "pad_to_multiple_of": pad_to_multiple_of, + } + if _padding != target: + self._tokenizer.enable_padding(**target) + + def _batch_encode_plus( + self, + batch_text_or_text_pairs: Union[ + List[TextInput], List[TextInputPair], List[PreTokenizedInput], List[PreTokenizedInputPair] + ], + add_special_tokens: bool = True, + padding_strategy: PaddingStrategy = PaddingStrategy.DO_NOT_PAD, + truncation_strategy: TruncationStrategy = TruncationStrategy.DO_NOT_TRUNCATE, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[str] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + ) -> BatchEncoding: + if not isinstance(batch_text_or_text_pairs, (tuple, list)): + raise TypeError( + f"batch_text_or_text_pairs has to be a list or a tuple (got {type(batch_text_or_text_pairs)})" + ) + + # Set the truncation and padding strategy and restore the initial configuration + self.set_truncation_and_padding( + padding_strategy=padding_strategy, + truncation_strategy=truncation_strategy, + max_length=max_length, + stride=stride, + pad_to_multiple_of=pad_to_multiple_of, + ) + + encodings = self._tokenizer.encode_batch( + batch_text_or_text_pairs, + add_special_tokens=add_special_tokens, + is_pretokenized=is_split_into_words, + ) + + # Convert encoding to dict + # `Tokens` has type: Tuple[ + # List[Dict[str, List[List[int]]]] or List[Dict[str, 2D-Tensor]], + # List[EncodingFast] + # ] + # with nested dimensions corresponding to batch, overflows, sequence length + tokens_and_encodings = [ + self._convert_encoding( + encoding=encoding, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + ) + for encoding in encodings + ] + + # Convert the output to have dict[list] from list[dict] and remove the additional overflows dimension + # From (variable) shape (batch, overflows, sequence length) to ~ (batch * overflows, sequence length) + # (we say ~ because the number of overflow varies with the example in the batch) + # + # To match each overflowing sample with the original sample in the batch + # we add an overflow_to_sample_mapping array (see below) + sanitized_tokens = {} + for key in tokens_and_encodings[0][0].keys(): + stack = [e for item, _ in tokens_and_encodings for e in item[key]] + sanitized_tokens[key] = stack + sanitized_encodings = [e for _, item in tokens_and_encodings for e in item] + + # If returning overflowing tokens, we need to return a mapping + # from the batch idx to the original sample + if return_overflowing_tokens: + overflow_to_sample_mapping = [] + for i, (toks, _) in enumerate(tokens_and_encodings): + overflow_to_sample_mapping += [i] * len(toks["input_ids"]) + sanitized_tokens["overflow_to_sample_mapping"] = overflow_to_sample_mapping + + for input_ids in sanitized_tokens["input_ids"]: + self._eventual_warn_about_too_long_sequence(input_ids, max_length, verbose) + return BatchEncoding(sanitized_tokens, sanitized_encodings, tensor_type=return_tensors) + + def _encode_plus( + self, + text: Union[TextInput, PreTokenizedInput], + text_pair: Optional[Union[TextInput, PreTokenizedInput]] = None, + add_special_tokens: bool = True, + padding_strategy: PaddingStrategy = PaddingStrategy.DO_NOT_PAD, + truncation_strategy: TruncationStrategy = TruncationStrategy.DO_NOT_TRUNCATE, + max_length: Optional[int] = None, + stride: int = 0, + is_split_into_words: bool = False, + pad_to_multiple_of: Optional[int] = None, + return_tensors: Optional[bool] = None, + return_token_type_ids: Optional[bool] = None, + return_attention_mask: Optional[bool] = None, + return_overflowing_tokens: bool = False, + return_special_tokens_mask: bool = False, + return_offsets_mapping: bool = False, + return_length: bool = False, + verbose: bool = True, + **kwargs, + ) -> BatchEncoding: + batched_input = [(text, text_pair)] if text_pair else [text] + batched_output = self._batch_encode_plus( + batched_input, + is_split_into_words=is_split_into_words, + add_special_tokens=add_special_tokens, + padding_strategy=padding_strategy, + truncation_strategy=truncation_strategy, + max_length=max_length, + stride=stride, + pad_to_multiple_of=pad_to_multiple_of, + return_tensors=return_tensors, + return_token_type_ids=return_token_type_ids, + return_attention_mask=return_attention_mask, + return_overflowing_tokens=return_overflowing_tokens, + return_special_tokens_mask=return_special_tokens_mask, + return_offsets_mapping=return_offsets_mapping, + return_length=return_length, + verbose=verbose, + **kwargs, + ) + + # Return tensor is None, then we can remove the leading batch axis + # Overflowing tokens are returned as a batch of output so we keep them in this case + if return_tensors is None and not return_overflowing_tokens: + batched_output = BatchEncoding( + { + key: value[0] if len(value) > 0 and isinstance(value[0], list) else value + for key, value in batched_output.items() + }, + batched_output.encodings, + ) + + self._eventual_warn_about_too_long_sequence(batched_output["input_ids"], max_length, verbose) + + return batched_output + + def convert_tokens_to_string(self, tokens: List[str]) -> str: + return self.backend_tokenizer.decoder.decode(tokens) + + def _decode( + self, + token_ids: Union[int, List[int]], + skip_special_tokens: bool = False, + clean_up_tokenization_spaces: bool = None, + **kwargs, + ) -> str: + self._decode_use_source_tokenizer = kwargs.pop("use_source_tokenizer", False) + + if isinstance(token_ids, int): + token_ids = [token_ids] + text = self._tokenizer.decode(token_ids, skip_special_tokens=skip_special_tokens) + + clean_up_tokenization_spaces = ( + clean_up_tokenization_spaces + if clean_up_tokenization_spaces is not None + else self.clean_up_tokenization_spaces + ) + if clean_up_tokenization_spaces: + clean_text = self.clean_up_tokenization(text) + return clean_text + else: + return text + + def _save_pretrained( + self, + save_directory: Union[str, os.PathLike], + file_names: Tuple[str], + legacy_format: Optional[bool] = None, + filename_prefix: Optional[str] = None, + ) -> Tuple[str]: + """ + Save a tokenizer using the slow-tokenizer/legacy format: vocabulary + added tokens as well as in a unique JSON + file containing {config + vocab + added-tokens}. + """ + save_directory = str(save_directory) + + if self.slow_tokenizer_class is None and legacy_format is True: + raise ValueError( + "Your tokenizer does not have a legacy version defined and therefore cannot register this version. You" + " might consider leaving the legacy_format at `None` or setting it to `False`." + ) + + save_slow = ( + (legacy_format is None or legacy_format is True) + and self.slow_tokenizer_class is not None + and self.can_save_slow_tokenizer + ) + save_fast = legacy_format is None or legacy_format is False + + if save_slow: + added_tokens_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + ADDED_TOKENS_FILE + ) + added_vocab = self.get_added_vocab() + if added_vocab: + with open(added_tokens_file, "w", encoding="utf-8") as f: + out_str = json.dumps(added_vocab, indent=2, sort_keys=True, ensure_ascii=False) + "\n" + f.write(out_str) + + vocab_files = self.save_vocabulary(save_directory, filename_prefix=filename_prefix) + file_names = file_names + vocab_files + (added_tokens_file,) + + if save_fast: + tokenizer_file = os.path.join( + save_directory, (filename_prefix + "-" if filename_prefix else "") + TOKENIZER_FILE + ) + self.backend_tokenizer.save(tokenizer_file) + file_names = file_names + (tokenizer_file,) + + return file_names + + def train_new_from_iterator( + self, + text_iterator, + vocab_size, + length=None, + new_special_tokens=None, + special_tokens_map=None, + **kwargs, + ): + """ + Trains a tokenizer on a new corpus with the same defaults (in terms of special tokens or tokenization pipeline) + as the current one. + + Args: + text_iterator (generator of `List[str]`): + The training corpus. Should be a generator of batches of texts, for instance a list of lists of texts + if you have everything in memory. + vocab_size (`int`): + The size of the vocabulary you want for your tokenizer. + length (`int`, *optional*): + The total number of sequences in the iterator. This is used to provide meaningful progress tracking + new_special_tokens (list of `str` or `AddedToken`, *optional*): + A list of new special tokens to add to the tokenizer you are training. + special_tokens_map (`Dict[str, str]`, *optional*): + If you want to rename some of the special tokens this tokenizer uses, pass along a mapping old special + token name to new special token name in this argument. + kwargs: + Additional keyword arguments passed along to the trainer from the 🤗 Tokenizers library. + + Returns: + [`PreTrainedTokenizerFast`]: A new tokenizer of the same type as the original one, trained on + `text_iterator`. + + """ + tokenizer_json = json.loads(self._tokenizer.to_str()) + # Remove added tokens for now (uses IDs of tokens) + added_tokens = tokenizer_json.pop("added_tokens") + # Remove post processor for now (uses IDs of tokens) + post_processor = tokenizer_json.pop("post_processor") + + unk_token = None + # Remove vocab + if tokenizer_json["model"]["type"] == "BPE": + tokenizer_json["model"]["vocab"] = {} + tokenizer_json["model"]["merges"] = [] + elif tokenizer_json["model"]["type"] == "Unigram": + if tokenizer_json["model"]["unk_id"] is not None: + unk_id = tokenizer_json["model"]["unk_id"] + unk_token = tokenizer_json["model"]["vocab"][unk_id][0] + if special_tokens_map is not None and unk_token in special_tokens_map: + unk_token = special_tokens_map[unk_token] + tokenizer_json["model"]["unk_id"] = 0 + tokenizer_json["model"]["vocab"] = [[unk_token, 0.0]] + elif tokenizer_json["model"]["type"] in ["WordLevel", "WordPiece"]: + tokenizer_json["model"]["vocab"] = {} + else: + raise ValueError( + f"This method does not support this type of tokenizer (found {tokenizer_json['model']['type']}) " + "only BPE, Unigram, WordLevel and WordPiece." + ) + + if ( + special_tokens_map is not None + and "unk_token" in tokenizer_json["model"] + and tokenizer_json["model"]["unk_token"] in special_tokens_map + ): + tokenizer_json["model"]["unk_token"] = special_tokens_map[tokenizer_json["model"]["unk_token"]] + + tokenizer = TokenizerFast.from_str(json.dumps(tokenizer_json)) + + # Get the special tokens from the current tokenizer if none are specified. + special_tokens = [] + for added_token in added_tokens: + special = added_token.pop("special", None) + _ = added_token.pop("id", None) + if tokenizer_json["model"]["type"] != "Unigram" and not special: + continue + if special_tokens_map is not None and added_token["content"] in special_tokens_map: + added_token["content"] = special_tokens_map[added_token["content"]] + special_tokens.append(AddedToken(**added_token)) + + if new_special_tokens is not None: + special_tokens.extend(new_special_tokens) + + # Trainer needs to know the end of word / continuing subword thingies in BPE + if ( + tokenizer_json["model"]["type"] == "BPE" + and "continuing_subword_prefix" not in kwargs + and tokenizer_json["model"]["continuing_subword_prefix"] is not None + ): + kwargs["continuing_subword_prefix"] = tokenizer_json["model"]["continuing_subword_prefix"] + if ( + tokenizer_json["model"]["type"] == "BPE" + and "end_of_word_suffix" not in kwargs + and tokenizer_json["model"]["end_of_word_suffix"] is not None + ): + kwargs["end_of_word_suffix"] = tokenizer_json["model"]["end_of_word_suffix"] + if tokenizer_json["model"]["type"] == "Unigram" and unk_token is not None: + kwargs["unk_token"] = unk_token + if tokenizer_json["pre_tokenizer"] is not None and tokenizer_json["pre_tokenizer"]["type"] == "ByteLevel": + kwargs["initial_alphabet"] = pre_tokenizers_fast.ByteLevel.alphabet() + + trainer_class = MODEL_TO_TRAINER_MAPPING[tokenizer_json["model"]["type"]] + trainer = trainer_class(vocab_size=vocab_size, special_tokens=special_tokens, **kwargs) + tokenizer.train_from_iterator(text_iterator, length=length, trainer=trainer) + + if post_processor is not None: + trained_tokenizer_json = json.loads(tokenizer.to_str()) + # Almost done, we just have to adjust the token IDs in the post processor + if "special_tokens" in post_processor: + for key in post_processor["special_tokens"]: + tokens = post_processor["special_tokens"][key]["tokens"] + if special_tokens_map is not None: + tokens = [special_tokens_map.get(token, token) for token in tokens] + post_processor["special_tokens"][key]["tokens"] = tokens + post_processor["special_tokens"][key]["ids"] = [tokenizer.token_to_id(token) for token in tokens] + + for special_token in ["cls", "sep"]: + if special_token in post_processor: + token, _ = post_processor[special_token] + if special_tokens_map is not None and token in special_tokens_map: + token = special_tokens_map[token] + token_id = tokenizer.token_to_id(token) + post_processor[special_token] = [token, token_id] + + trained_tokenizer_json["post_processor"] = post_processor + tokenizer = TokenizerFast.from_str(json.dumps(trained_tokenizer_json)) + + kwargs = self.init_kwargs.copy() + # Map pad/cls/mask token at the Transformers level + special_tokens_list = SpecialTokensMixin.SPECIAL_TOKENS_ATTRIBUTES.copy() + special_tokens_list.remove("additional_special_tokens") + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(self, f"_{token}") is not None: + special_token = getattr(self, token) + if special_tokens_map is not None and special_token in special_tokens_map: + special_token = special_tokens_map[special_token] + + special_token_full = getattr(self, f"_{token}") + if isinstance(special_token_full, AddedToken): + # Create an added token with the same parameters except the content + kwargs[token] = AddedToken( + special_token, + single_word=special_token_full.single_word, + lstrip=special_token_full.lstrip, + rstrip=special_token_full.rstrip, + normalized=special_token_full.normalized, + ) + else: + kwargs[token] = special_token + + additional_special_tokens = self.additional_special_tokens + if new_special_tokens is not None: + additional_special_tokens.extend(new_special_tokens) + if len(additional_special_tokens) > 0: + kwargs["additional_special_tokens"] = additional_special_tokens + + return self.__class__(tokenizer_object=tokenizer, **kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d064f35a5e66b15d0739d0b208d2d0f254b09110 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/__init__.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ..utils import ( + OptionalDependencyNotAvailable, + _LazyModule, + is_torch_available, +) + + +_import_structure = { + "agents": ["Agent", "HfAgent", "OpenAiAgent"], + "base": ["PipelineTool", "RemoteTool", "Tool", "launch_gradio_demo", "load_tool"], +} + +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["document_question_answering"] = ["DocumentQuestionAnsweringTool"] + _import_structure["image_captioning"] = ["ImageCaptioningTool"] + _import_structure["image_question_answering"] = ["ImageQuestionAnsweringTool"] + _import_structure["image_segmentation"] = ["ImageSegmentationTool"] + _import_structure["language_identifier"] = ["LanguageIdentificationTool"] + _import_structure["speech_to_text"] = ["SpeechToTextTool"] + _import_structure["text_classification"] = ["TextClassificationTool"] + _import_structure["text_question_answering"] = ["TextQuestionAnsweringTool"] + _import_structure["text_summarization"] = ["TextSummarizationTool"] + _import_structure["text_to_speech"] = ["TextToSpeechTool"] + _import_structure["translation"] = ["TranslationTool"] + +if TYPE_CHECKING: + from .agents import Agent, HfAgent, OpenAiAgent + from .base import PipelineTool, RemoteTool, Tool, launch_gradio_demo, load_tool + + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .document_question_answering import DocumentQuestionAnsweringTool + from .image_captioning import ImageCaptioningTool + from .image_question_answering import ImageQuestionAnsweringTool + from .image_segmentation import ImageSegmentationTool + from .language_identifier import LanguageIdentificationTool + from .speech_to_text import SpeechToTextTool + from .text_classification import TextClassificationTool + from .text_question_answering import TextQuestionAnsweringTool + from .text_summarization import TextSummarizationTool + from .text_to_speech import TextToSpeechTool + from .translation import TranslationTool +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/agents.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/agents.py new file mode 100644 index 0000000000000000000000000000000000000000..a7b07a4932cfb3c2681ceca28cf9fa4584ca12c0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/agents.py @@ -0,0 +1,495 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import importlib.util +import json +import os +import time +from dataclasses import dataclass +from typing import Dict + +import requests +from huggingface_hub import HfFolder, hf_hub_download, list_spaces + +from ..utils import is_openai_available, logging +from .base import TASK_MAPPING, TOOL_CONFIG_FILE, Tool, load_tool, supports_remote +from .prompts import CHAT_MESSAGE_PROMPT, CHAT_PROMPT_TEMPLATE, RUN_PROMPT_TEMPLATE +from .python_interpreter import evaluate + + +logger = logging.get_logger(__name__) + + +if is_openai_available(): + import openai + +_tools_are_initialized = False + + +BASE_PYTHON_TOOLS = { + "print": print, + "float": float, + "int": int, + "bool": bool, + "str": str, +} + + +@dataclass +class PreTool: + task: str + description: str + repo_id: str + + +HUGGINGFACE_DEFAULT_TOOLS = {} + + +HUGGINGFACE_DEFAULT_TOOLS_FROM_HUB = [ + "image-transformation", + "text-download", + "text-to-image", + "text-to-video", +] + + +def get_remote_tools(organization="huggingface-tools"): + spaces = list_spaces(author=organization) + tools = {} + for space_info in spaces: + repo_id = space_info.id + resolved_config_file = hf_hub_download(repo_id, TOOL_CONFIG_FILE, repo_type="space") + with open(resolved_config_file, encoding="utf-8") as reader: + config = json.load(reader) + + task = repo_id.split("/")[-1] + tools[config["name"]] = PreTool(task=task, description=config["description"], repo_id=repo_id) + + return tools + + +def _setup_default_tools(): + global HUGGINGFACE_DEFAULT_TOOLS + global _tools_are_initialized + + if _tools_are_initialized: + return + + main_module = importlib.import_module("transformers") + tools_module = main_module.tools + + remote_tools = get_remote_tools() + for task_name in TASK_MAPPING: + tool_class_name = TASK_MAPPING.get(task_name) + tool_class = getattr(tools_module, tool_class_name) + description = tool_class.description + HUGGINGFACE_DEFAULT_TOOLS[tool_class.name] = PreTool(task=task_name, description=description, repo_id=None) + + for task_name in HUGGINGFACE_DEFAULT_TOOLS_FROM_HUB: + found = False + for tool_name, tool in remote_tools.items(): + if tool.task == task_name: + HUGGINGFACE_DEFAULT_TOOLS[tool_name] = tool + found = True + break + + if not found: + raise ValueError(f"{task_name} is not implemented on the Hub.") + + _tools_are_initialized = True + + +def resolve_tools(code, toolbox, remote=False, cached_tools=None): + if cached_tools is None: + resolved_tools = BASE_PYTHON_TOOLS.copy() + else: + resolved_tools = cached_tools + for name, tool in toolbox.items(): + if name not in code or name in resolved_tools: + continue + + if isinstance(tool, Tool): + resolved_tools[name] = tool + else: + task_or_repo_id = tool.task if tool.repo_id is None else tool.repo_id + _remote = remote and supports_remote(task_or_repo_id) + resolved_tools[name] = load_tool(task_or_repo_id, remote=_remote) + + return resolved_tools + + +def get_tool_creation_code(code, toolbox, remote=False): + code_lines = ["from transformers import load_tool", ""] + for name, tool in toolbox.items(): + if name not in code or isinstance(tool, Tool): + continue + + task_or_repo_id = tool.task if tool.repo_id is None else tool.repo_id + line = f'{name} = load_tool("{task_or_repo_id}"' + if remote: + line += ", remote=True" + line += ")" + code_lines.append(line) + + return "\n".join(code_lines) + "\n" + + +def clean_code_for_chat(result): + lines = result.split("\n") + idx = 0 + while idx < len(lines) and not lines[idx].lstrip().startswith("```"): + idx += 1 + explanation = "\n".join(lines[:idx]).strip() + if idx == len(lines): + return explanation, None + + idx += 1 + start_idx = idx + while not lines[idx].lstrip().startswith("```"): + idx += 1 + code = "\n".join(lines[start_idx:idx]).strip() + + return explanation, code + + +def clean_code_for_run(result): + result = f"I will use the following {result}" + explanation, code = result.split("Answer:") + explanation = explanation.strip() + code = code.strip() + + code_lines = code.split("\n") + if code_lines[0] in ["```", "```py", "```python"]: + code_lines = code_lines[1:] + if code_lines[-1] == "```": + code_lines = code_lines[:-1] + code = "\n".join(code_lines) + + return explanation, code + + +class Agent: + """ + Base class for all agents which contains the main API methods. + + Args: + chat_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `chat` method. + run_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `run` method. + additional_tools ([`Tool`], list of tools or dictionary with tool values, *optional*): + Any additional tools to include on top of the default ones. If you pass along a tool with the same name as + one of the default tools, that default tool will be overridden. + """ + + def __init__(self, chat_prompt_template=None, run_prompt_template=None, additional_tools=None): + _setup_default_tools() + + self.chat_prompt_template = CHAT_MESSAGE_PROMPT if chat_prompt_template is None else chat_prompt_template + self.run_prompt_template = RUN_PROMPT_TEMPLATE if run_prompt_template is None else run_prompt_template + self._toolbox = HUGGINGFACE_DEFAULT_TOOLS.copy() + if additional_tools is not None: + if isinstance(additional_tools, (list, tuple)): + additional_tools = {t.name: t for t in additional_tools} + elif not isinstance(additional_tools, dict): + additional_tools = {additional_tools.name: additional_tools} + + replacements = {name: tool for name, tool in additional_tools.items() if name in HUGGINGFACE_DEFAULT_TOOLS} + self._toolbox.update(additional_tools) + if len(replacements) > 1: + names = "\n".join([f"- {n}: {t}" for n, t in replacements.items()]) + logger.warn( + f"The following tools have been replaced by the ones provided in `additional_tools`:\n{names}." + ) + elif len(replacements) == 1: + name = list(replacements.keys())[0] + logger.warn(f"{name} has been replaced by {replacements[name]} as provided in `additional_tools`.") + + self.prepare_for_new_chat() + + @property + def toolbox(self) -> Dict[str, Tool]: + """Get all tool currently available to the agent""" + return self._toolbox + + def format_prompt(self, task, chat_mode=False): + description = "\n".join([f"- {name}: {tool.description}" for name, tool in self.toolbox.items()]) + if chat_mode: + if self.chat_history is None: + prompt = CHAT_PROMPT_TEMPLATE.replace("<>", description) + else: + prompt = self.chat_history + prompt += CHAT_MESSAGE_PROMPT.replace("<>", task) + else: + prompt = self.run_prompt_template.replace("<>", description) + prompt = prompt.replace("<>", task) + return prompt + + def chat(self, task, *, return_code=False, remote=False, **kwargs): + """ + Sends a new request to the agent in a chat. Will use the previous ones in its history. + + Args: + task (`str`): The task to perform + return_code (`bool`, *optional*, defaults to `False`): + Whether to just return code and not evaluate it. + remote (`bool`, *optional*, defaults to `False`): + Whether or not to use remote tools (inference endpoints) instead of local ones. + kwargs: + Any keyword argument to send to the agent when evaluating the code. + + Example: + + ```py + from transformers import HfAgent + + agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder") + agent.chat("Draw me a picture of rivers and lakes") + + agent.chat("Transform the picture so that there is a rock in there") + ``` + """ + prompt = self.format_prompt(task, chat_mode=True) + result = self.generate_one(prompt, stop=["Human:", "====="]) + self.chat_history = prompt + result.strip() + "\n" + explanation, code = clean_code_for_chat(result) + + print(f"==Explanation from the agent==\n{explanation}") + + if code is not None: + print(f"\n\n==Code generated by the agent==\n{code}") + if not return_code: + print("\n\n==Result==") + self.cached_tools = resolve_tools(code, self.toolbox, remote=remote, cached_tools=self.cached_tools) + self.chat_state.update(kwargs) + return evaluate(code, self.cached_tools, self.chat_state, chat_mode=True) + else: + tool_code = get_tool_creation_code(code, self.toolbox, remote=remote) + return f"{tool_code}\n{code}" + + def prepare_for_new_chat(self): + """ + Clears the history of prior calls to [`~Agent.chat`]. + """ + self.chat_history = None + self.chat_state = {} + self.cached_tools = None + + def run(self, task, *, return_code=False, remote=False, **kwargs): + """ + Sends a request to the agent. + + Args: + task (`str`): The task to perform + return_code (`bool`, *optional*, defaults to `False`): + Whether to just return code and not evaluate it. + remote (`bool`, *optional*, defaults to `False`): + Whether or not to use remote tools (inference endpoints) instead of local ones. + kwargs: + Any keyword argument to send to the agent when evaluating the code. + + Example: + + ```py + from transformers import HfAgent + + agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder") + agent.run("Draw me a picture of rivers and lakes") + ``` + """ + prompt = self.format_prompt(task) + result = self.generate_one(prompt, stop=["Task:"]) + explanation, code = clean_code_for_run(result) + + print(f"==Explanation from the agent==\n{explanation}") + + print(f"\n\n==Code generated by the agent==\n{code}") + if not return_code: + print("\n\n==Result==") + self.cached_tools = resolve_tools(code, self.toolbox, remote=remote, cached_tools=self.cached_tools) + return evaluate(code, self.cached_tools, state=kwargs.copy()) + else: + tool_code = get_tool_creation_code(code, self.toolbox, remote=remote) + return f"{tool_code}\n{code}" + + def generate_one(self, prompt, stop): + # This is the method to implement in your custom agent. + raise NotImplementedError + + def generate_many(self, prompts, stop): + # Override if you have a way to do batch generation faster than one by one + return [self.generate_one(prompt, stop) for prompt in prompts] + + +class OpenAiAgent(Agent): + """ + Agent that uses the openai API to generate code. + + + + The openAI models are used in generation mode, so even for the `chat()` API, it's better to use models like + `"text-davinci-003"` over the chat-GPT variant. Proper support for chat-GPT models will come in a next version. + + + + Args: + model (`str`, *optional*, defaults to `"text-davinci-003"`): + The name of the OpenAI model to use. + api_key (`str`, *optional*): + The API key to use. If unset, will look for the environment variable `"OPENAI_API_KEY"`. + chat_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `chat` method. + run_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `run` method. + additional_tools ([`Tool`], list of tools or dictionary with tool values, *optional*): + Any additional tools to include on top of the default ones. If you pass along a tool with the same name as + one of the default tools, that default tool will be overridden. + + Example: + + ```py + from transformers import OpenAiAgent + + agent = OpenAiAgent(model="text-davinci-003", api_key=xxx) + agent.run("Is the following `text` (in Spanish) positive or negative?", text="¡Este es un API muy agradable!") + ``` + """ + + def __init__( + self, + model="text-davinci-003", + api_key=None, + chat_prompt_template=None, + run_prompt_template=None, + additional_tools=None, + ): + if not is_openai_available(): + raise ImportError("Using `OpenAiAgent` requires `openai`: `pip install openai`.") + + if api_key is None: + api_key = os.environ.get("OPENAI_API_KEY", None) + if api_key is None: + raise ValueError( + "You need an openai key to use `OpenAIAgent`. You can get one here: Get one here " + "https://openai.com/api/`. If you have one, set it in your env with `os.environ['OPENAI_API_KEY'] = " + "xxx." + ) + else: + openai.api_key = api_key + self.model = model + super().__init__( + chat_prompt_template=chat_prompt_template, + run_prompt_template=run_prompt_template, + additional_tools=additional_tools, + ) + + def generate_many(self, prompts, stop): + if "gpt" in self.model: + return [self._chat_generate(prompt, stop) for prompt in prompts] + else: + return self._completion_generate(prompts, stop) + + def generate_one(self, prompt, stop): + if "gpt" in self.model: + return self._chat_generate(prompt, stop) + else: + return self._completion_generate([prompt], stop)[0] + + def _chat_generate(self, prompt, stop): + result = openai.ChatCompletion.create( + model=self.model, + messages=[{"role": "user", "content": prompt}], + temperature=0, + stop=stop, + ) + return result["choices"][0]["message"]["content"] + + def _completion_generate(self, prompts, stop): + result = openai.Completion.create( + model=self.model, + prompt=prompts, + temperature=0, + stop=stop, + max_tokens=200, + ) + return [answer["text"] for answer in result["choices"]] + + +class HfAgent(Agent): + """ + Agent that uses and inference endpoint to generate code. + + Args: + url_endpoint (`str`): + The name of the url endpoint to use. + token (`str`, *optional*): + The token to use as HTTP bearer authorization for remote files. If unset, will use the token generated when + running `huggingface-cli login` (stored in `~/.huggingface`). + chat_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `chat` method. + run_prompt_template (`str`, *optional*): + Pass along your own prompt if you want to override the default template for the `run` method. + additional_tools ([`Tool`], list of tools or dictionary with tool values, *optional*): + Any additional tools to include on top of the default ones. If you pass along a tool with the same name as + one of the default tools, that default tool will be overridden. + + Example: + + ```py + from transformers import HfAgent + + agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder") + agent.run("Is the following `text` (in Spanish) positive or negative?", text="¡Este es un API muy agradable!") + ``` + """ + + def __init__( + self, url_endpoint, token=None, chat_prompt_template=None, run_prompt_template=None, additional_tools=None + ): + self.url_endpoint = url_endpoint + if token is None: + self.token = f"Bearer {HfFolder().get_token()}" + elif token.startswith("Bearer") or token.startswith("Basic"): + self.token = token + else: + self.token = f"Bearer {token}" + super().__init__( + chat_prompt_template=chat_prompt_template, + run_prompt_template=run_prompt_template, + additional_tools=additional_tools, + ) + + def generate_one(self, prompt, stop): + headers = {"Authorization": self.token} + inputs = { + "inputs": prompt, + "parameters": {"max_new_tokens": 200, "return_full_text": False, "stop": stop}, + } + + response = requests.post(self.url_endpoint, json=inputs, headers=headers) + if response.status_code == 429: + print("Getting rate-limited, waiting a tiny bit before trying again.") + time.sleep(1) + return self._generate_one(prompt) + elif response.status_code != 200: + raise ValueError(f"Error {response.status_code}: {response.json()}") + + result = response.json()[0]["generated_text"] + # Inference API returns the stop sequence + for stop_seq in stop: + if result.endswith(stop_seq): + result = result[: -len(stop_seq)] + return result diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/base.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/base.py new file mode 100644 index 0000000000000000000000000000000000000000..b51868e7c60bf91c32268bbac5c26cfebd712c3d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/base.py @@ -0,0 +1,723 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import base64 +import importlib +import inspect +import io +import json +import os +import tempfile +from typing import Any, Dict, List, Optional, Union + +from huggingface_hub import CommitOperationAdd, HfFolder, create_commit, create_repo, hf_hub_download, metadata_update +from huggingface_hub.utils import RepositoryNotFoundError, get_session + +from ..dynamic_module_utils import custom_object_save, get_class_from_dynamic_module, get_imports +from ..image_utils import is_pil_image +from ..models.auto import AutoProcessor +from ..utils import ( + CONFIG_NAME, + cached_file, + is_accelerate_available, + is_torch_available, + is_vision_available, + logging, +) + + +logger = logging.get_logger(__name__) + +if is_torch_available(): + import torch + +if is_accelerate_available(): + from accelerate.utils import send_to_device + + +TOOL_CONFIG_FILE = "tool_config.json" + + +def get_repo_type(repo_id, repo_type=None, **hub_kwargs): + if repo_type is not None: + return repo_type + try: + hf_hub_download(repo_id, TOOL_CONFIG_FILE, repo_type="space", **hub_kwargs) + return "space" + except RepositoryNotFoundError: + try: + hf_hub_download(repo_id, TOOL_CONFIG_FILE, repo_type="model", **hub_kwargs) + return "model" + except RepositoryNotFoundError: + raise EnvironmentError(f"`{repo_id}` does not seem to be a valid repo identifier on the Hub.") + except Exception: + return "model" + except Exception: + return "space" + + +# docstyle-ignore +APP_FILE_TEMPLATE = """from transformers import launch_gradio_demo +from {module_name} import {class_name} + +launch_gradio_demo({class_name}) +""" + + +class Tool: + """ + A base class for the functions used by the agent. Subclass this and implement the `__call__` method as well as the + following class attributes: + + - **description** (`str`) -- A short description of what your tool does, the inputs it expects and the output(s) it + will return. For instance 'This is a tool that downloads a file from a `url`. It takes the `url` as input, and + returns the text contained in the file'. + - **name** (`str`) -- A performative name that will be used for your tool in the prompt to the agent. For instance + `"text-classifier"` or `"image_generator"`. + - **inputs** (`List[str]`) -- The list of modalities expected for the inputs (in the same order as in the call). + Modalitiies should be `"text"`, `"image"` or `"audio"`. This is only used by `launch_gradio_demo` or to make a + nice space from your tool. + - **outputs** (`List[str]`) -- The list of modalities returned but the tool (in the same order as the return of the + call method). Modalitiies should be `"text"`, `"image"` or `"audio"`. This is only used by `launch_gradio_demo` + or to make a nice space from your tool. + + You can also override the method [`~Tool.setup`] if your tool as an expensive operation to perform before being + usable (such as loading a model). [`~Tool.setup`] will be called the first time you use your tool, but not at + instantiation. + """ + + description: str = "This is a tool that ..." + name: str = "" + + inputs: List[str] + outputs: List[str] + + def __init__(self, *args, **kwargs): + self.is_initialized = False + + def __call__(self, *args, **kwargs): + return NotImplemented("Write this method in your subclass of `Tool`.") + + def setup(self): + """ + Overwrite this method here for any operation that is expensive and needs to be executed before you start using + your tool. Such as loading a big model. + """ + self.is_initialized = True + + def save(self, output_dir): + """ + Saves the relevant code files for your tool so it can be pushed to the Hub. This will copy the code of your + tool in `output_dir` as well as autogenerate: + + - a config file named `tool_config.json` + - an `app.py` file so that your tool can be converted to a space + - a `requirements.txt` containing the names of the module used by your tool (as detected when inspecting its + code) + + You should only use this method to save tools that are defined in a separate module (not `__main__`). + + Args: + output_dir (`str`): The folder in which you want to save your tool. + """ + os.makedirs(output_dir, exist_ok=True) + # Save module file + if self.__module__ == "__main__": + raise ValueError( + f"We can't save the code defining {self} in {output_dir} as it's been defined in __main__. You " + "have to put this code in a separate module so we can include it in the saved folder." + ) + module_files = custom_object_save(self, output_dir) + + module_name = self.__class__.__module__ + last_module = module_name.split(".")[-1] + full_name = f"{last_module}.{self.__class__.__name__}" + + # Save config file + config_file = os.path.join(output_dir, "tool_config.json") + if os.path.isfile(config_file): + with open(config_file, "r", encoding="utf-8") as f: + tool_config = json.load(f) + else: + tool_config = {} + + tool_config = {"tool_class": full_name, "description": self.description, "name": self.name} + with open(config_file, "w", encoding="utf-8") as f: + f.write(json.dumps(tool_config, indent=2, sort_keys=True) + "\n") + + # Save app file + app_file = os.path.join(output_dir, "app.py") + with open(app_file, "w", encoding="utf-8") as f: + f.write(APP_FILE_TEMPLATE.format(module_name=last_module, class_name=self.__class__.__name__)) + + # Save requirements file + requirements_file = os.path.join(output_dir, "requirements.txt") + imports = [] + for module in module_files: + imports.extend(get_imports(module)) + imports = list(set(imports)) + with open(requirements_file, "w", encoding="utf-8") as f: + f.write("\n".join(imports) + "\n") + + @classmethod + def from_hub(cls, repo_id, model_repo_id=None, token=None, remote=False, **kwargs): + """ + Loads a tool defined on the Hub. + + Args: + repo_id (`str`): + The name of the repo on the Hub where your tool is defined. + model_repo_id (`str`, *optional*): + If your tool uses a model and you want to use a different model than the default, you can pass a second + repo ID or an endpoint url to this argument. + token (`str`, *optional*): + The token to identify you on hf.co. If unset, will use the token generated when running + `huggingface-cli login` (stored in `~/.huggingface`). + remote (`bool`, *optional*, defaults to `False`): + Whether to use your tool by downloading the model or (if it is available) with an inference endpoint. + kwargs: + Additional keyword arguments that will be split in two: all arguments relevant to the Hub (such as + `cache_dir`, `revision`, `subfolder`) will be used when downloading the files for your tool, and the + others will be passed along to its init. + """ + if remote and model_repo_id is None: + endpoints = get_default_endpoints() + if repo_id not in endpoints: + raise ValueError( + f"Could not infer a default endpoint for {repo_id}, you need to pass one using the " + "`model_repo_id` argument." + ) + model_repo_id = endpoints[repo_id] + hub_kwargs_names = [ + "cache_dir", + "force_download", + "resume_download", + "proxies", + "revision", + "repo_type", + "subfolder", + "local_files_only", + ] + hub_kwargs = {k: v for k, v in kwargs.items() if k in hub_kwargs_names} + + # Try to get the tool config first. + hub_kwargs["repo_type"] = get_repo_type(repo_id, **hub_kwargs) + resolved_config_file = cached_file( + repo_id, + TOOL_CONFIG_FILE, + use_auth_token=token, + **hub_kwargs, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + ) + is_tool_config = resolved_config_file is not None + if resolved_config_file is None: + resolved_config_file = cached_file( + repo_id, + CONFIG_NAME, + use_auth_token=token, + **hub_kwargs, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + ) + if resolved_config_file is None: + raise EnvironmentError( + f"{repo_id} does not appear to provide a valid configuration in `tool_config.json` or `config.json`." + ) + + with open(resolved_config_file, encoding="utf-8") as reader: + config = json.load(reader) + + if not is_tool_config: + if "custom_tool" not in config: + raise EnvironmentError( + f"{repo_id} does not provide a mapping to custom tools in its configuration `config.json`." + ) + custom_tool = config["custom_tool"] + else: + custom_tool = config + + tool_class = custom_tool["tool_class"] + tool_class = get_class_from_dynamic_module(tool_class, repo_id, use_auth_token=token, **hub_kwargs) + + if remote: + return RemoteTool(model_repo_id, token=token, tool_class=tool_class) + return tool_class(model_repo_id, token=token, **kwargs) + + def push_to_hub( + self, + repo_id: str, + commit_message: str = "Upload tool", + private: Optional[bool] = None, + token: Optional[Union[bool, str]] = None, + create_pr: bool = False, + ) -> str: + """ + Upload the tool to the Hub. + + Parameters: + repo_id (`str`): + The name of the repository you want to push your tool to. It should contain your organization name when + pushing to a given organization. + commit_message (`str`, *optional*, defaults to `"Upload tool"`): + Message to commit while pushing. + private (`bool`, *optional*): + Whether or not the repository created should be private. + token (`bool` or `str`, *optional*): + The token to use as HTTP bearer authorization for remote files. If unset, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + create_pr (`bool`, *optional*, defaults to `False`): + Whether or not to create a PR with the uploaded files or directly commit. + """ + repo_url = create_repo( + repo_id=repo_id, token=token, private=private, exist_ok=True, repo_type="space", space_sdk="gradio" + ) + metadata_update(repo_id, {"tags": ["tool"]}, repo_type="space") + repo_id = repo_url.repo_id + + with tempfile.TemporaryDirectory() as work_dir: + # Save all files. + self.save(work_dir) + os.listdir(work_dir) + operations = [ + CommitOperationAdd(path_or_fileobj=os.path.join(work_dir, f), path_in_repo=f) + for f in os.listdir(work_dir) + ] + logger.info(f"Uploading the following files to {repo_id}: {','.join(os.listdir(work_dir))}") + return create_commit( + repo_id=repo_id, + operations=operations, + commit_message=commit_message, + token=token, + create_pr=create_pr, + repo_type="space", + ) + + @staticmethod + def from_gradio(gradio_tool): + """ + Creates a [`Tool`] from a gradio tool. + """ + + class GradioToolWrapper(Tool): + def __init__(self, _gradio_tool): + super().__init__() + self.name = _gradio_tool.name + self.description = _gradio_tool.description + + GradioToolWrapper.__call__ = gradio_tool.run + return GradioToolWrapper(gradio_tool) + + +class RemoteTool(Tool): + """ + A [`Tool`] that will make requests to an inference endpoint. + + Args: + endpoint_url (`str`): + The url of the endpoint to use. + token (`str`, *optional*): + The token to use as HTTP bearer authorization for remote files. If unset, will use the token generated when + running `huggingface-cli login` (stored in `~/.huggingface`). + tool_class (`type`, *optional*): + The corresponding `tool_class` if this is a remote version of an existing tool. Will help determine when + the output should be converted to another type (like images). + """ + + def __init__(self, endpoint_url=None, token=None, tool_class=None): + self.endpoint_url = endpoint_url + self.client = EndpointClient(endpoint_url, token=token) + self.tool_class = tool_class + + def prepare_inputs(self, *args, **kwargs): + """ + Prepare the inputs received for the HTTP client sending data to the endpoint. Positional arguments will be + matched with the signature of the `tool_class` if it was provided at instantation. Images will be encoded into + bytes. + + You can override this method in your custom class of [`RemoteTool`]. + """ + inputs = kwargs.copy() + if len(args) > 0: + if self.tool_class is not None: + # Match args with the signature + if issubclass(self.tool_class, PipelineTool): + call_method = self.tool_class.encode + else: + call_method = self.tool_class.__call__ + signature = inspect.signature(call_method).parameters + parameters = [ + k + for k, p in signature.items() + if p.kind not in [inspect._ParameterKind.VAR_POSITIONAL, inspect._ParameterKind.VAR_KEYWORD] + ] + if parameters[0] == "self": + parameters = parameters[1:] + if len(args) > len(parameters): + raise ValueError( + f"{self.tool_class} only accepts {len(parameters)} arguments but {len(args)} were given." + ) + for arg, name in zip(args, parameters): + inputs[name] = arg + elif len(args) > 1: + raise ValueError("A `RemoteTool` can only accept one positional input.") + elif len(args) == 1: + if is_pil_image(args[0]): + return {"inputs": self.client.encode_image(args[0])} + return {"inputs": args[0]} + + for key, value in inputs.items(): + if is_pil_image(value): + inputs[key] = self.client.encode_image(value) + + return {"inputs": inputs} + + def extract_outputs(self, outputs): + """ + You can override this method in your custom class of [`RemoteTool`] to apply some custom post-processing of the + outputs of the endpoint. + """ + return outputs + + def __call__(self, *args, **kwargs): + output_image = self.tool_class is not None and self.tool_class.outputs == ["image"] + inputs = self.prepare_inputs(*args, **kwargs) + if isinstance(inputs, dict): + outputs = self.client(**inputs, output_image=output_image) + else: + outputs = self.client(inputs, output_image=output_image) + if isinstance(outputs, list) and len(outputs) == 1 and isinstance(outputs[0], list): + outputs = outputs[0] + return self.extract_outputs(outputs) + + +class PipelineTool(Tool): + """ + A [`Tool`] tailored towards Transformer models. On top of the class attributes of the base class [`Tool`], you will + need to specify: + + - **model_class** (`type`) -- The class to use to load the model in this tool. + - **default_checkpoint** (`str`) -- The default checkpoint that should be used when the user doesn't specify one. + - **pre_processor_class** (`type`, *optional*, defaults to [`AutoProcessor`]) -- The class to use to load the + pre-processor + - **post_processor_class** (`type`, *optional*, defaults to [`AutoProcessor`]) -- The class to use to load the + post-processor (when different from the pre-processor). + + Args: + model (`str` or [`PreTrainedModel`], *optional*): + The name of the checkpoint to use for the model, or the instantiated model. If unset, will default to the + value of the class attribute `default_checkpoint`. + pre_processor (`str` or `Any`, *optional*): + The name of the checkpoint to use for the pre-processor, or the instantiated pre-processor (can be a + tokenizer, an image processor, a feature extractor or a processor). Will default to the value of `model` if + unset. + post_processor (`str` or `Any`, *optional*): + The name of the checkpoint to use for the post-processor, or the instantiated pre-processor (can be a + tokenizer, an image processor, a feature extractor or a processor). Will default to the `pre_processor` if + unset. + device (`int`, `str` or `torch.device`, *optional*): + The device on which to execute the model. Will default to any accelerator available (GPU, MPS etc...), the + CPU otherwise. + device_map (`str` or `dict`, *optional*): + If passed along, will be used to instantiate the model. + model_kwargs (`dict`, *optional*): + Any keyword argument to send to the model instantiation. + token (`str`, *optional*): + The token to use as HTTP bearer authorization for remote files. If unset, will use the token generated when + running `huggingface-cli login` (stored in `~/.huggingface`). + hub_kwargs: + Any additional keyword argument to send to the methods that will load the data from the Hub. + """ + + pre_processor_class = AutoProcessor + model_class = None + post_processor_class = AutoProcessor + default_checkpoint = None + + def __init__( + self, + model=None, + pre_processor=None, + post_processor=None, + device=None, + device_map=None, + model_kwargs=None, + token=None, + **hub_kwargs, + ): + if not is_torch_available(): + raise ImportError("Please install torch in order to use this tool.") + + if not is_accelerate_available(): + raise ImportError("Please install accelerate in order to use this tool.") + + if model is None: + if self.default_checkpoint is None: + raise ValueError("This tool does not implement a default checkpoint, you need to pass one.") + model = self.default_checkpoint + if pre_processor is None: + pre_processor = model + + self.model = model + self.pre_processor = pre_processor + self.post_processor = post_processor + self.device = device + self.device_map = device_map + self.model_kwargs = {} if model_kwargs is None else model_kwargs + if device_map is not None: + self.model_kwargs["device_map"] = device_map + self.hub_kwargs = hub_kwargs + self.hub_kwargs["use_auth_token"] = token + + self.is_initialized = False + + def setup(self): + """ + Instantiates the `pre_processor`, `model` and `post_processor` if necessary. + """ + if isinstance(self.pre_processor, str): + self.pre_processor = self.pre_processor_class.from_pretrained(self.pre_processor, **self.hub_kwargs) + + if isinstance(self.model, str): + self.model = self.model_class.from_pretrained(self.model, **self.model_kwargs, **self.hub_kwargs) + + if self.post_processor is None: + self.post_processor = self.pre_processor + elif isinstance(self.post_processor, str): + self.post_processor = self.post_processor_class.from_pretrained(self.post_processor, **self.hub_kwargs) + + if self.device is None: + if self.device_map is not None: + self.device = list(self.model.hf_device_map.values())[0] + else: + self.device = get_default_device() + + if self.device_map is None: + self.model.to(self.device) + + def encode(self, raw_inputs): + """ + Uses the `pre_processor` to prepare the inputs for the `model`. + """ + return self.pre_processor(raw_inputs) + + def forward(self, inputs): + """ + Sends the inputs through the `model`. + """ + with torch.no_grad(): + return self.model(**inputs) + + def decode(self, outputs): + """ + Uses the `post_processor` to decode the model output. + """ + return self.post_processor(outputs) + + def __call__(self, *args, **kwargs): + if not self.is_initialized: + self.setup() + + encoded_inputs = self.encode(*args, **kwargs) + encoded_inputs = send_to_device(encoded_inputs, self.device) + outputs = self.forward(encoded_inputs) + outputs = send_to_device(outputs, "cpu") + return self.decode(outputs) + + +def launch_gradio_demo(tool_class: Tool): + """ + Launches a gradio demo for a tool. The corresponding tool class needs to properly implement the class attributes + `inputs` and `outputs`. + + Args: + tool_class (`type`): The class of the tool for which to launch the demo. + """ + try: + import gradio as gr + except ImportError: + raise ImportError("Gradio should be installed in order to launch a gradio demo.") + + tool = tool_class() + + def fn(*args, **kwargs): + return tool(*args, **kwargs) + + gr.Interface( + fn=fn, + inputs=tool_class.inputs, + outputs=tool_class.outputs, + title=tool_class.__name__, + article=tool.description, + ).launch() + + +# TODO: Migrate to Accelerate for this once `PartialState.default_device` makes its way into a release. +def get_default_device(): + if not is_torch_available(): + raise ImportError("Please install torch in order to use this tool.") + + if torch.backends.mps.is_available() and torch.backends.mps.is_built(): + return torch.device("mps") + elif torch.cuda.is_available(): + return torch.device("cuda") + else: + return torch.device("cpu") + + +TASK_MAPPING = { + "document-question-answering": "DocumentQuestionAnsweringTool", + "image-captioning": "ImageCaptioningTool", + "image-question-answering": "ImageQuestionAnsweringTool", + "image-segmentation": "ImageSegmentationTool", + "speech-to-text": "SpeechToTextTool", + "summarization": "TextSummarizationTool", + "text-classification": "TextClassificationTool", + "text-question-answering": "TextQuestionAnsweringTool", + "text-to-speech": "TextToSpeechTool", + "translation": "TranslationTool", +} + + +def get_default_endpoints(): + endpoints_file = cached_file("huggingface-tools/default-endpoints", "default_endpoints.json", repo_type="dataset") + with open(endpoints_file, "r", encoding="utf-8") as f: + endpoints = json.load(f) + return endpoints + + +def supports_remote(task_or_repo_id): + endpoints = get_default_endpoints() + return task_or_repo_id in endpoints + + +def load_tool(task_or_repo_id, model_repo_id=None, remote=False, token=None, **kwargs): + """ + Main function to quickly load a tool, be it on the Hub or in the Transformers library. + + Args: + task_or_repo_id (`str`): + The task for which to load the tool or a repo ID of a tool on the Hub. Tasks implemented in Transformers + are: + + - `"document-question-answering"` + - `"image-captioning"` + - `"image-question-answering"` + - `"image-segmentation"` + - `"speech-to-text"` + - `"summarization"` + - `"text-classification"` + - `"text-question-answering"` + - `"text-to-speech"` + - `"translation"` + + model_repo_id (`str`, *optional*): + Use this argument to use a different model than the default one for the tool you selected. + remote (`bool`, *optional*, defaults to `False`): + Whether to use your tool by downloading the model or (if it is available) with an inference endpoint. + token (`str`, *optional*): + The token to identify you on hf.co. If unset, will use the token generated when running `huggingface-cli + login` (stored in `~/.huggingface`). + kwargs: + Additional keyword arguments that will be split in two: all arguments relevant to the Hub (such as + `cache_dir`, `revision`, `subfolder`) will be used when downloading the files for your tool, and the others + will be passed along to its init. + """ + if task_or_repo_id in TASK_MAPPING: + tool_class_name = TASK_MAPPING[task_or_repo_id] + main_module = importlib.import_module("transformers") + tools_module = main_module.tools + tool_class = getattr(tools_module, tool_class_name) + + if remote: + if model_repo_id is None: + endpoints = get_default_endpoints() + if task_or_repo_id not in endpoints: + raise ValueError( + f"Could not infer a default endpoint for {task_or_repo_id}, you need to pass one using the " + "`model_repo_id` argument." + ) + model_repo_id = endpoints[task_or_repo_id] + return RemoteTool(model_repo_id, token=token, tool_class=tool_class) + else: + return tool_class(model_repo_id, token=token, **kwargs) + else: + return Tool.from_hub(task_or_repo_id, model_repo_id=model_repo_id, token=token, remote=remote, **kwargs) + + +def add_description(description): + """ + A decorator that adds a description to a function. + """ + + def inner(func): + func.description = description + func.name = func.__name__ + return func + + return inner + + +## Will move to the Hub +class EndpointClient: + def __init__(self, endpoint_url: str, token: Optional[str] = None): + if token is None: + token = HfFolder().get_token() + self.headers = {"authorization": f"Bearer {token}", "Content-Type": "application/json"} + self.endpoint_url = endpoint_url + + @staticmethod + def encode_image(image): + _bytes = io.BytesIO() + image.save(_bytes, format="PNG") + b64 = base64.b64encode(_bytes.getvalue()) + return b64.decode("utf-8") + + @staticmethod + def decode_image(raw_image): + if not is_vision_available(): + raise ImportError( + "This tool returned an image but Pillow is not installed. Please install it (`pip install Pillow`)." + ) + + from PIL import Image + + b64 = base64.b64decode(raw_image) + _bytes = io.BytesIO(b64) + return Image.open(_bytes) + + def __call__( + self, + inputs: Optional[Union[str, Dict, List[str], List[List[str]]]] = None, + params: Optional[Dict] = None, + data: Optional[bytes] = None, + output_image: bool = False, + ) -> Any: + # Build payload + payload = {} + if inputs: + payload["inputs"] = inputs + if params: + payload["parameters"] = params + + # Make API call + response = get_session().post(self.endpoint_url, headers=self.headers, json=payload, data=data) + + # By default, parse the response for the user. + if output_image: + return self.decode_image(response.content) + else: + return response.json() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/document_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/document_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..8a44a1a9511213e44c7bf90a726adede1a5f2803 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/document_question_answering.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import re + +from ..models.auto import AutoProcessor +from ..models.vision_encoder_decoder import VisionEncoderDecoderModel +from ..utils import is_vision_available +from .base import PipelineTool + + +if is_vision_available(): + from PIL import Image + + +class DocumentQuestionAnsweringTool(PipelineTool): + default_checkpoint = "naver-clova-ix/donut-base-finetuned-docvqa" + description = ( + "This is a tool that answers a question about an document (pdf). It takes an input named `document` which " + "should be the document containing the information, as well as a `question` that is the question about the " + "document. It returns a text that contains the answer to the question." + ) + name = "document_qa" + pre_processor_class = AutoProcessor + model_class = VisionEncoderDecoderModel + + inputs = ["image", "text"] + outputs = ["text"] + + def __init__(self, *args, **kwargs): + if not is_vision_available(): + raise ValueError("Pillow must be installed to use the DocumentQuestionAnsweringTool.") + + super().__init__(*args, **kwargs) + + def encode(self, image: "Image", question: str): + task_prompt = "{user_input}" + prompt = task_prompt.replace("{user_input}", question) + decoder_input_ids = self.pre_processor.tokenizer( + prompt, add_special_tokens=False, return_tensors="pt" + ).input_ids + pixel_values = self.pre_processor(image, return_tensors="pt").pixel_values + + return {"decoder_input_ids": decoder_input_ids, "pixel_values": pixel_values} + + def forward(self, inputs): + return self.model.generate( + inputs["pixel_values"].to(self.device), + decoder_input_ids=inputs["decoder_input_ids"].to(self.device), + max_length=self.model.decoder.config.max_position_embeddings, + early_stopping=True, + pad_token_id=self.pre_processor.tokenizer.pad_token_id, + eos_token_id=self.pre_processor.tokenizer.eos_token_id, + use_cache=True, + num_beams=1, + bad_words_ids=[[self.pre_processor.tokenizer.unk_token_id]], + return_dict_in_generate=True, + ).sequences + + def decode(self, outputs): + sequence = self.pre_processor.batch_decode(outputs)[0] + sequence = sequence.replace(self.pre_processor.tokenizer.eos_token, "") + sequence = sequence.replace(self.pre_processor.tokenizer.pad_token, "") + sequence = re.sub(r"<.*?>", "", sequence, count=1).strip() # remove first task start token + sequence = self.pre_processor.token2json(sequence) + + return sequence["answer"] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/evaluate_agent.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/evaluate_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..47d1d4330ad361eb265f0c41b661f1325e8a52f5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/evaluate_agent.py @@ -0,0 +1,692 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from .agents import BASE_PYTHON_TOOLS, clean_code_for_chat, clean_code_for_run +from .python_interpreter import InterpretorError, evaluate + + +### Fake tools for test +def classifier(text, labels): + return f"This is the classification of {text} along {labels}." + + +def translator(text, src_lang, tgt_lang): + return f"This is the translation of {text} from {src_lang} to {tgt_lang}." + + +def speaker(text): + return f"This is actually a sound reading {text}." + + +def transcriber(audio): + if "sound" not in audio: + raise ValueError(f"`audio` ({audio}) is not a sound.") + return f"This is the transcribed text from {audio}." + + +def image_generator(prompt): + return f"This is actually an image representing {prompt}." + + +def image_captioner(image): + if "image" not in image: + raise ValueError(f"`image` ({image}) is not an image.") + return f"This is a description of {image}." + + +def image_transformer(image, prompt): + if "image" not in image: + raise ValueError(f"`image` ({image}) is not an image.") + return f"This is a transformation of {image} according to {prompt}." + + +def question_answerer(text, question): + return f"This is the answer to {question} from {text}." + + +def image_qa(image, question): + if "image" not in image: + raise ValueError(f"`image` ({image}) is not an image.") + return f"This is the answer to {question} from {image}." + + +def text_downloader(url): + return f"This is the content of {url}." + + +def summarizer(text): + return f"This is a summary of {text}." + + +def video_generator(prompt, seconds=2): + return f"A video of {prompt}" + + +def document_qa(image, question): + return f"This is the answer to {question} from the document {image}." + + +def image_segmenter(image, prompt): + return f"This is the mask of {prompt} in {image}" + + +TEST_TOOLS = { + "text_classifier": classifier, + "translator": translator, + "text_reader": speaker, + "summarizer": summarizer, + "transcriber": transcriber, + "image_generator": image_generator, + "image_captioner": image_captioner, + "image_transformer": image_transformer, + "text_qa": question_answerer, + "text_downloader": text_downloader, + "image_qa": image_qa, + "video_generator": video_generator, + "document_qa": document_qa, + "image_segmenter": image_segmenter, +} + + +class Problem: + """ + A class regrouping all the information to solve a problem on which we will evaluate agents. + + Args: + task (`str` ou `list[str]`): + One or several descriptions of the task to perform. If a list, it should contain variations on the + phrasing, but for the same task. + inputs (`list[str]` or `dict[str, str]`): + The inputs that will be fed to the tools. For this testing environment, only strings are accepted as + values. Pass along a dictionary when you want to specify the values of each inputs, or just the list of + inputs expected (the value used will be `<>` in this case). + answer (`str` or `list[str`]): + The theoretical answer (or list of possible valid answers) to the problem, as code. + """ + + def __init__(self, task, inputs, answer): + self.task = task + self.inputs = inputs + self.answer = answer + + +### The list of problems the agent will be evaluated on. +EVALUATION_TASKS = [ + Problem( + task=[ + "Is the following `text` (in Spanish) positive or negative?", + "Is the text in the variable `text` (in Spanish) positive or negative?", + "Translate the following `text` from Spanish to English then tell me if its positive or negative.", + ], + inputs=["text"], + answer="""text_classifier(translator(text, src_lang="Spanish", tgt_lang="English"), labels=["positive", "negative"])""", + ), + Problem( + task=[ + "Tell me out loud what the `image` contains.", + "Describe the following `image` out loud.", + "Find what is in the picture stored in `image` then read it out loud.", + ], + inputs=["image"], + answer=[ + "text_reader(image_captioner(image))", + "text_reader(image_qa(image, question='What is in the image?'))", + ], + ), + Problem( + task=[ + "Generate an image from the text given in `text_input`. Then transform it according to the text in `prompt`.", + "Use the following `text_input` to generate an image, then transform it by using the text in `prompt`.", + ], + inputs=["text_input", "prompt"], + answer="image_transformer(image_generator(text_input), prompt)", + ), + Problem( + task=[ + "Download the content of `url`, summarize it then generate an image from its content.", + "Use a summary of the web page at `url` to generate an image.", + "Summarize the content of the web page at `url`, and use the result to generate an image.", + ], + inputs=["url"], + answer="image_generator(summarizer(text_downloader(url)))", + ), + Problem( + task=[ + "Transform the following `image` using the prompt in `text`. The prompt is in Spanish.", + "Use the text prompt in `text` (in Spanish) to transform the following `image`.", + "Translate the `text` from Spanish to English then use it to transform the picture in `image`.", + ], + inputs=["text", "image"], + answer="image_transformer(image, translator(text, src_lang='Spanish', tgt_lang='English'))", + ), + Problem( + task=[ + "Download the content of `url`, summarize it then read it out loud to me.", + "Read me a summary of the web page at `url`.", + ], + inputs=["url"], + answer="text_reader(summarizer(text_downloader(url)))", + ), + Problem( + task=[ + "Generate an image from the text given in `text_input`.", + ], + inputs=["text_input"], + answer="image_generator(text_input)", + ), + Problem( + task=[ + "Replace the beaver in the `image` by the `prompt`.", + "Transform the `image` so that it contains the `prompt`.", + "Use `prompt` to transform this `image`.", + ], + inputs=["image", "prompt"], + answer="image_transformer(image, prompt)", + ), + Problem( + task=[ + "Provide me the summary of the `text`, then read it to me before transcribing it and translating it in French.", + "Summarize `text`, read it out loud then transcribe the audio and translate it in French.", + "Read me a summary of the the `text` out loud. Transcribe this and translate it in French.", + ], + inputs=["text"], + answer="translator(transcriber(text_reader(summarizer(text))), src_lang='English', tgt_lang='French')", + ), + Problem( + task=["Generate a video of the `prompt`", "Animate a `prompt`", "Make me a short video using `prompt`."], + inputs={"prompt": "A lobster swimming"}, + answer="video_generator('A lobster swimming')", + ), + Problem( + task=[ + "Download the following file `url`, summarize it in a few words and generate a video from it." + "Fetch the file at this `url`, summarize it, and create an animation out of it." + ], + inputs=["url"], + answer="video_generator(summarizer(text_downloader(url)))", + ), +] + + +EVALUATION_CHATS = [ + [ + Problem( + task=[ + "Translate the following `text` from Spanish to English.", + "Translate the following `text` from Spanish to English.", + ], + inputs=["text"], + answer="translated_text=translator(text, src_lang='Spanish', tgt_lang='English')", + ), + Problem( + task=[ + "Is it positive or negative?", + "Tell me if its positive or negative.", + ], + inputs=[], + answer="text_classifier(translated_text, labels=['positive', 'negative'])", + ), + ], + [ + Problem( + task=[ + "What does this `image` contain?", + "Describe the following `image`.", + "Find what is in the picture stored in `image`", + ], + inputs=["image"], + answer=[ + "description=image_captioner(image)", + "description=image_qa(image, question='What is in the image?')", + ], + ), + Problem( + task=["Now, read the description out loud.", "Great! Can you read it out loud?", "Read it out loud."], + inputs=[], + answer=["audio=text_reader(description)", "audio=text_reader(description)"], + ), + ], + [ + Problem( + task=[ + "Generate an image from the text given in `text_input`.", + "Use the following `text_input` to generate an image", + ], + inputs=["text_input"], + answer="image = image_generator(text_input)", + ), + Problem( + task=[ + "Transform it according to the text in `prompt`.", + "Transform it by using the text in `prompt`.", + ], + inputs=["prompt"], + answer="image_transformer(image, prompt)", + ), + ], + [ + Problem( + task=[ + "Download the content of `url` and summarize it.", + "Summarize the content of the web page at `url`.", + ], + inputs=["url"], + answer="summary = summarizer(text_downloader(url))", + ), + Problem( + task=[ + "Generate an image from its content.", + "Use the previous result to generate an image.", + ], + inputs=[], + answer="image_generator(summary)", + ), + ], + [ + Problem( + task=[ + "Translate this Spanish `text` in English.", + "Translate the `text` from Spanish to English.", + ], + inputs=["text"], + answer="translated_text = translator(text, src_lang='Spanish', tgt_lang='English')", + ), + Problem( + task=[ + "Transform the following `image` using the translated `text`.", + "Use the previous result to transform the following `image`.", + ], + inputs=["image"], + answer="image_transformer(image, translated_text)", + ), + ], + [ + Problem( + task=["Download the content of `url`.", "Get me the text on the weg page `url`."], + inputs=["url"], + answer="text = text_downloader(url)", + ), + Problem( + task=["Summarize this text.", "Summarize this text."], + inputs=[], + answer="summary = summarizer(text)", + ), + Problem( + task=["Read it out loud to me.", "Read me the previous result."], + inputs=[], + answer="text_reader(summary)", + ), + ], + [ + Problem( + task=[ + "Generate an image from the text given in `text_input`.", + ], + inputs=["text_input"], + answer="image_generator(text_input)", + ), + ], + [ + Problem( + task=[ + "Replace the beaver in the `image` by the `prompt`.", + "Transform the `image` so that it contains the `prompt`.", + "Use `prompt` to transform this `image`.", + ], + inputs=["image", "prompt"], + answer="image_transformer(image, prompt)", + ), + ], + [ + Problem( + task=["Provide me the summary of the `text`.", "Summarize `text`."], + inputs=["text"], + answer="summary = summarizer(text)", + ), + Problem( + task=["Read this summary to me.", "Read it out loud."], + inputs=[], + answer="audio = text_reader(summarizer(text))", + ), + Problem( + task=["Transcribing the previous result back in text.", "Transcribe the audio."], + inputs=[], + answer="text = transcriber(audio)", + ), + Problem( + task=["Translating the last result in French.", "Translate this in French."], + inputs=[], + answer="translator(text, src_lang='English', tgt_lang='French')", + ), + ], + [ + Problem( + task=["Generate a video of the `prompt`", "Animate a `prompt`", "Make me a short video using `prompt`."], + inputs={"prompt": "A lobster swimming"}, + answer="video_generator('A lobster swimming')", + ), + ], + [ + Problem( + task=[ + "Download the content of `url` and summarize it.", + "Summarize the content of the web page at `url`.", + ], + inputs=["url"], + answer="summary = summarizer(text_downloader(url))", + ), + Problem( + task=["generate a video from it.", "Create an animation from the last result."], + inputs=[], + answer="video_generator(summary)", + ), + ], +] + + +def get_theoretical_tools(agent_answer, theoretical_answer, code_answer): + if not isinstance(theoretical_answer, list): + return {name for name in TEST_TOOLS if name in code_answer} + + if isinstance(agent_answer, dict): + for one_answer, one_code in zip(theoretical_answer, code_answer): + if one_answer in agent_answer.values(): + return {name for name in TEST_TOOLS if name in one_code} + + for one_answer, one_code in zip(theoretical_answer, code_answer): + if agent_answer == one_answer: + return {name for name in TEST_TOOLS if name in one_code} + + return {name for name in TEST_TOOLS if name in code_answer[0]} + + +def evaluate_code(code, inputs=None, state=None, verbose=False, return_interpretor_error=False): + tools = BASE_PYTHON_TOOLS.copy() + for name, tool in TEST_TOOLS.items(): + if name not in code: + continue + tools[name] = tool + + if isinstance(inputs, dict): + inputs = inputs.copy() + elif inputs is not None: + inputs = {inp: f"<<{inp}>>" for inp in inputs} + + if state is not None: + state.update(inputs) + else: + state = inputs + + try: + return evaluate(code, tools, state) + except InterpretorError as e: + return str(e) + except Exception as e: + if verbose: + print(e) + return None + + +def score_code(agent_answer, theoretical_answer, verbose: bool = False): + if verbose: + print(agent_answer, theoretical_answer) + theoretical_answer = theoretical_answer if isinstance(theoretical_answer, list) else [theoretical_answer] + + if agent_answer in theoretical_answer: + if verbose: + print("Perfect!") + return 1 + elif isinstance(agent_answer, dict) and any(v in theoretical_answer for v in agent_answer.values()): + if verbose: + print("Almsot perfect, result in state!") + return 0.75 + else: + if verbose: + print("Result is not the right one but code executed.") + return 0.3 + + +def evaluate_one_result(explanation, code, agent_answer, theoretical_answer, answer, verbose=False): + tools_in_explanation = {name for name in TEST_TOOLS if f"`{name}`" in explanation} + theoretical_tools = get_theoretical_tools(agent_answer, theoretical_answer, answer) + if tools_in_explanation == theoretical_tools: + tool_selection_score = 1.0 + tool_selection_errors = None + else: + missing_tools = len(theoretical_tools - tools_in_explanation) + unexpected_tools = len(tools_in_explanation - theoretical_tools) + tool_selection_score = max(0, 1.0 - 0.25 * missing_tools - 0.25 * unexpected_tools) + + tool_selection_errors = { + "selected_tools": tools_in_explanation, + "theoretical_tools": theoretical_tools, + } + + tools_in_code = {name for name in TEST_TOOLS if name in code} + if tools_in_code == theoretical_tools: + tool_used_score = 1.0 + tool_used_errors = None + else: + missing_tools = len(theoretical_tools - tools_in_code) + unexpected_tools = len(tools_in_code - theoretical_tools) + tool_used_score = max(0, 1.0 - 0.25 * missing_tools - 0.25 * unexpected_tools) + + tool_used_errors = { + "selected_tools": tools_in_explanation, + "theoretical_tools": theoretical_tools, + } + + score = score_code(agent_answer, theoretical_answer, verbose=verbose) + if score < 1.0: + code_errors = { + "code_produced": code, + "evaluation": agent_answer, + "theoretical_answer": theoretical_answer, + } + else: + code_errors = None + + return (tool_selection_score, tool_used_score, score), (tool_selection_errors, tool_used_errors, code_errors) + + +def evaluate_agent(agent, batch_size=8, verbose=False, return_errors=False): + """ + Evaluates a new agent on all `EVALUATION_TASKS`. + + Example: + + ```py + agent = NewOpenAiAgent(model="text-davinci-003", api_key=your_api_key) + bads = new_evaluate_agent(agent) + for bad in bads: + print(bad) + ``` + """ + # Sanity check + agent_tools = set(agent.toolbox.keys()) + if agent_tools != set(TEST_TOOLS): + missing_tools = set(TEST_TOOLS) - agent_tools + unexpected_tools = set(agent_tools) - TEST_TOOLS + raise ValueError( + f"Fix the test tools in the evaluate_agent module. Tools mising: {missing_tools}. Extra tools: {unexpected_tools}." + ) + + eval_tasks = [] + eval_idx = [] + for idx, pb in enumerate(EVALUATION_TASKS): + if isinstance(pb.task, list): + eval_tasks.extend(pb.task) + eval_idx.extend([idx] * len(pb.task)) + else: + eval_tasks.append(pb.task) + eval_idx.append(idx) + + tool_selection_score = 0 + tool_used_score = 0 + code_score = 0 + + if return_errors: + tool_selection_errors = {} + tool_used_errors = {} + code_errors = {} + + for start_idx in range(0, len(eval_tasks), batch_size): + end_idx = min(start_idx + batch_size, len(eval_tasks)) + batch_tasks = eval_tasks[start_idx:end_idx] + + prompts = [agent.format_prompt(task) for task in batch_tasks] + results = agent.generate_many(prompts, stop=["Task:"]) + + for idx, result in enumerate(results): + problem = EVALUATION_TASKS[eval_idx[start_idx + idx]] + if verbose: + print(f"====Task {start_idx + idx}====\n{batch_tasks[idx]}\n") + explanation, code = clean_code_for_run(result) + + # Evaluate agent answer and code answer + agent_answer = evaluate_code(code, problem.inputs, verbose=verbose) + if isinstance(problem.answer, list): + theoretical_answer = [evaluate_code(answer, problem.inputs) for answer in problem.answer] + else: + theoretical_answer = evaluate_code(problem.answer, problem.inputs) + + scores, errors = evaluate_one_result( + explanation, code, agent_answer, theoretical_answer, problem.answer, verbose=verbose + ) + + tool_selection_score += scores[0] + tool_used_score += scores[1] + code_score += scores[2] + + if return_errors: + if errors[0] is not None: + tool_selection_errors[batch_tasks[idx]] = errors[0] + if errors[1] is not None: + tool_used_errors[batch_tasks[idx]] = errors[1] + if errors[2] is not None: + code_errors[batch_tasks[idx]] = errors[2] + + scores = { + "tool selection score": 100 * (tool_selection_score / len(eval_tasks)), + "tool used score": 100 * (tool_used_score / len(eval_tasks)), + "code score": 100 * (code_score / len(eval_tasks)), + } + + if return_errors: + return scores, tool_selection_errors, tool_used_errors, code_errors + else: + return scores + + +def evaluate_chat_agent(agent, verbose=False, return_errors=False): + """ + Evaluates a new agent on all `EVALUATION_CHATS`. + + Example: + + ```py + agent = NewOpenAiAgent(model="text-davinci-003", api_key=your_api_key) + bads = new_evaluate_agent(agent) + for bad in bads: + print(bad) + ``` + """ + # Sanity check + agent_tools = set(agent.toolbox.keys()) + if agent_tools != set(TEST_TOOLS): + missing_tools = set(TEST_TOOLS) - agent_tools + unexpected_tools = agent_tools - set(TEST_TOOLS) + raise ValueError( + f"Fix the test tools in the evaluate_agent module. Tools mising: {missing_tools}. Extra tools: {unexpected_tools}." + ) + + tool_selection_score = 0 + tool_used_score = 0 + code_score = 0 + total_steps = 0 + + if return_errors: + tool_selection_errors = {} + tool_used_errors = {} + code_errors = {} + + for chat_problem in EVALUATION_CHATS: + if isinstance(chat_problem[0].task, str): + resolved_problems = [chat_problem] + else: + resolved_problems = [ + [Problem(task=pb.task[i], inputs=pb.inputs, answer=pb.answer) for pb in chat_problem] + for i in range(len(chat_problem[0].task)) + ] + for problem in resolved_problems: + agent.prepare_for_new_chat() + agent_state = {} + theoretical_state = ( + [{} for _ in range(len(problem[0].answer))] if isinstance(problem[0].answer, list) else {} + ) + + for step, step_problem in enumerate(problem): + if verbose: + print(step_problem.task) + total_steps += 1 + prompt = agent.format_prompt(step_problem.task, chat_mode=True) + result = agent.generate_one(prompt, stop=["Human:", "====="]) + agent.chat_history = prompt + result + "\n" + + explanation, code = clean_code_for_chat(result) + + if verbose: + print(f"==Explanation from the agent==\n{explanation}") + print(f"\n==Code generated by the agent==\n{code}") + + # Evaluate agent answer and code answer + agent_answer = evaluate_code(code, step_problem.inputs, state=agent_state, verbose=verbose) + + answer = step_problem.answer + if isinstance(answer, list): + theoretical_answer = [ + evaluate_code(a, step_problem.inputs, state=state) + for a, state in zip(answer, theoretical_state) + ] + else: + theoretical_answer = evaluate_code(answer, step_problem.inputs, state=theoretical_state) + + scores, errors = evaluate_one_result( + explanation, code, agent_answer, theoretical_answer, answer, verbose=verbose + ) + + tool_selection_score += scores[0] + tool_used_score += scores[1] + code_score += scores[2] + + if return_errors: + if errors[0] is not None: + tool_selection_errors[step_problem.task] = errors[0] + if errors[1] is not None: + tool_used_errors[step_problem.task] = errors[1] + if errors[2] is not None: + code_errors[step_problem.task] = errors[2] + + scores = { + "tool selection score": 100 * (tool_selection_score / total_steps), + "tool used score": 100 * (tool_used_score / total_steps), + "code score": 100 * (code_score / total_steps), + } + + if return_errors: + return scores, tool_selection_errors, tool_used_errors, code_errors + else: + return scores diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_captioning.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_captioning.py new file mode 100644 index 0000000000000000000000000000000000000000..cfcf0bc8dc2834bf10ba7c03929743692756837a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_captioning.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ..models.auto import AutoModelForVision2Seq +from ..utils import requires_backends +from .base import PipelineTool + + +if TYPE_CHECKING: + from PIL import Image + + +class ImageCaptioningTool(PipelineTool): + default_checkpoint = "Salesforce/blip-image-captioning-base" + description = ( + "This is a tool that generates a description of an image. It takes an input named `image` which should be the " + "image to caption, and returns a text that contains the description in English." + ) + name = "image_captioner" + model_class = AutoModelForVision2Seq + + inputs = ["image"] + outputs = ["text"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + super().__init__(*args, **kwargs) + + def encode(self, image: "Image"): + return self.pre_processor(images=image, return_tensors="pt") + + def forward(self, inputs): + return self.model.generate(**inputs) + + def decode(self, outputs): + return self.pre_processor.batch_decode(outputs, skip_special_tokens=True)[0].strip() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..a9d9ef82b514778a363c9cefea301122860382f2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_question_answering.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +import torch + +from ..models.auto import AutoModelForVisualQuestionAnswering, AutoProcessor +from ..utils import requires_backends +from .base import PipelineTool + + +if TYPE_CHECKING: + from PIL import Image + + +class ImageQuestionAnsweringTool(PipelineTool): + default_checkpoint = "dandelin/vilt-b32-finetuned-vqa" + description = ( + "This is a tool that answers a question about an image. It takes an input named `image` which should be the " + "image containing the information, as well as a `question` which should be the question in English. It " + "returns a text that is the answer to the question." + ) + name = "image_qa" + pre_processor_class = AutoProcessor + model_class = AutoModelForVisualQuestionAnswering + + inputs = ["image", "text"] + outputs = ["text"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + super().__init__(*args, **kwargs) + + def encode(self, image: "Image", question: str): + return self.pre_processor(image, question, return_tensors="pt") + + def forward(self, inputs): + with torch.no_grad(): + return self.model(**inputs).logits + + def decode(self, outputs): + idx = outputs.argmax(-1).item() + return self.model.config.id2label[idx] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_segmentation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_segmentation.py new file mode 100644 index 0000000000000000000000000000000000000000..4471b849052785b6d7d2e71f59263f2a8f507f7b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/image_segmentation.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import numpy as np +import torch + +from ..models.clipseg import CLIPSegForImageSegmentation +from ..utils import is_vision_available, requires_backends +from .base import PipelineTool + + +if is_vision_available(): + from PIL import Image + + +class ImageSegmentationTool(PipelineTool): + description = ( + "This is a tool that creates a segmentation mask of an image according to a label. It cannot create an image." + "It takes two arguments named `image` which should be the original image, and `label` which should be a text " + "describing the elements what should be identified in the segmentation mask. The tool returns the mask." + ) + default_checkpoint = "CIDAS/clipseg-rd64-refined" + name = "image_segmenter" + model_class = CLIPSegForImageSegmentation + + inputs = ["image", "text"] + outputs = ["image"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + super().__init__(*args, **kwargs) + + def encode(self, image: "Image", label: str): + self.pre_processor.image_processor.size = {"width": image.size[0], "height": image.size[1]} + return self.pre_processor(text=[label], images=[image], padding=True, return_tensors="pt") + + def forward(self, inputs): + with torch.no_grad(): + logits = self.model(**inputs).logits + return logits + + def decode(self, outputs): + array = outputs.cpu().detach().numpy() + array[array <= 0] = 0 + array[array > 0] = 1 + return Image.fromarray((array * 255).astype(np.uint8)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/prompts.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..44336277e134e060c167166f4cfc973afec09845 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/prompts.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# docstyle-ignore +RUN_PROMPT_TEMPLATE = """I will ask you to perform a task, your job is to come up with a series of simple commands in Python that will perform the task. +To help you, I will give you access to a set of tools that you can use. Each tool is a Python function and has a description explaining the task it performs, the inputs it expects and the outputs it returns. +You should first explain which tool you will use to perform the task and for what reason, then write the code in Python. +Each instruction in Python should be a simple assignment. You can print intermediate results if it makes sense to do so. + +Tools: +<> + + +Task: "Answer the question in the variable `question` about the image stored in the variable `image`. The question is in French." + +I will use the following tools: `translator` to translate the question into English and then `image_qa` to answer the question on the input image. + +Answer: +```py +translated_question = translator(question=question, src_lang="French", tgt_lang="English") +print(f"The translated question is {translated_question}.") +answer = image_qa(image=image, question=translated_question) +print(f"The answer is {answer}") +``` + +Task: "Identify the oldest person in the `document` and create an image showcasing the result." + +I will use the following tools: `document_qa` to find the oldest person in the document, then `image_generator` to generate an image according to the answer. + +Answer: +```py +answer = document_qa(document, question="What is the oldest person?") +print(f"The answer is {answer}.") +image = image_generator(answer) +``` + +Task: "Generate an image using the text given in the variable `caption`." + +I will use the following tool: `image_generator` to generate an image. + +Answer: +```py +image = image_generator(prompt=caption) +``` + +Task: "Summarize the text given in the variable `text` and read it out loud." + +I will use the following tools: `summarizer` to create a summary of the input text, then `text_reader` to read it out loud. + +Answer: +```py +summarized_text = summarizer(text) +print(f"Summary: {summarized_text}") +audio_summary = text_reader(summarized_text) +``` + +Task: "Answer the question in the variable `question` about the text in the variable `text`. Use the answer to generate an image." + +I will use the following tools: `text_qa` to create the answer, then `image_generator` to generate an image according to the answer. + +Answer: +```py +answer = text_qa(text=text, question=question) +print(f"The answer is {answer}.") +image = image_generator(answer) +``` + +Task: "Caption the following `image`." + +I will use the following tool: `image_captioner` to generate a caption for the image. + +Answer: +```py +caption = image_captioner(image) +``` + +Task: "<>" + +I will use the following""" + + +# docstyle-ignore +CHAT_PROMPT_TEMPLATE = """Below are a series of dialogues between various people and an AI assistant specialized in coding. The AI assistant tries to be helpful, polite, honest, and humble-but-knowledgeable. + +The job of the AI assistant is to come up with a series of simple commands in Python that will perform the task the human wants to perform. +To help with that, the AI assistant has access to a set of tools. Each tool is a Python function and has a description explaining the task it performs, the inputs it expects and the outputs it returns. +The AI assistant should first explain the tools it will use to perform the task and for what reason, then write the code in Python. +Each instruction in Python should be a simple assignment. The AI assistant can print intermediate results if it makes sense to do so. + +Tools: +<> + +===== + +Human: Answer the question in the variable `question` about the image stored in the variable `image`. + +Assistant: I will use the tool `image_qa` to answer the question on the input image. + +```py +answer = image_qa(text=question, image=image) +print(f"The answer is {answer}") +``` + +Human: I tried this code, it worked but didn't give me a good result. The question is in French + +Assistant: In this case, the question needs to be translated first. I will use the tool `translator` to do this. + +```py +translated_question = translator(question=question, src_lang="French", tgt_lang="English") +print(f"The translated question is {translated_question}.") +answer = image_qa(text=translated_question, image=image) +print(f"The answer is {answer}") +``` + +===== + +Human: Identify the oldest person in the `document`. + +Assistant: I will use the tool `document_qa` to find the oldest person in the document. + +```py +answer = document_qa(document, question="What is the oldest person?") +print(f"The answer is {answer}.") +``` + +Human: Can you generate an image with the result? + +Assistant: I will use the tool `image_generator` to do that. + +```py +image = image_generator(answer) +``` + +===== + +Human: Summarize the text given in the variable `text` and read it out loud. + +Assistant: I will use the tool `summarizer` to create a summary of the input text, then the tool `text_reader` to read it out loud. + +```py +summarized_text = summarizer(text) +print(f"Summary: {summarized_text}") +audio_summary = text_reader(text=summary) +``` + +Human: I got the following error: "The variable `summary` is not defined." + +Assistant: My bad! Let's try this code instead. + +```py +summarized_text = summarizer(text) +print(f"Summary: {summarized_text}") +audio_summary = text_reader(text=summarized_text) +``` + +Human: It worked! Can you translate the summary in German? + +Assistant: I will use the tool `translator` to translate the text in German. + +```py +translated_summary = translator(summarized_text, src_lang="English", tgt_lang="German) +``` + +==== +""" + + +# docstyle-ignore +CHAT_MESSAGE_PROMPT = """ +Human: <> + +Assistant: """ diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/python_interpreter.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/python_interpreter.py new file mode 100644 index 0000000000000000000000000000000000000000..ef366c5d2e77771ac83c23da4fc346ce4d7d5056 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/python_interpreter.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import ast +import difflib +from collections.abc import Mapping +from typing import Any, Callable, Dict + + +class InterpretorError(ValueError): + """ + An error raised when the interpretor cannot evaluate a Python expression, due to syntax error or unsupported + operations. + """ + + pass + + +def evaluate(code: str, tools: Dict[str, Callable], state=None, chat_mode=False): + """ + Evaluate a python expression using the content of the variables stored in a state and only evaluating a given set + of functions. + + This function will recurse through the nodes of the tree provided. + + Args: + code (`str`): + The code to evaluate. + tools (`Dict[str, Callable]`): + The functions that may be called during the evaluation. Any call to another function will fail with an + `InterpretorError`. + state (`Dict[str, Any]`): + A dictionary mapping variable names to values. The `state` should contain the initial inputs but will be + updated by this function to contain all variables as they are evaluated. + chat_mode (`bool`, *optional*, defaults to `False`): + Whether or not the function is called from `Agent.chat`. + """ + try: + expression = ast.parse(code) + except SyntaxError as e: + print("The code generated by the agent is not valid.\n", e) + return + if state is None: + state = {} + result = None + for idx, node in enumerate(expression.body): + try: + line_result = evaluate_ast(node, state, tools) + except InterpretorError as e: + msg = f"Evaluation of the code stopped at line {idx} before the end because of the following error" + if chat_mode: + msg += ( + f". Copy paste the following error message and send it back to the agent:\nI get an error: '{e}'" + ) + else: + msg += f":\n{e}" + print(msg) + break + if line_result is not None: + result = line_result + + return result + + +def evaluate_ast(expression: ast.AST, state: Dict[str, Any], tools: Dict[str, Callable]): + """ + Evaluate an absract syntax tree using the content of the variables stored in a state and only evaluating a given + set of functions. + + This function will recurse trough the nodes of the tree provided. + + Args: + expression (`ast.AST`): + The code to evaluate, as an abastract syntax tree. + state (`Dict[str, Any]`): + A dictionary mapping variable names to values. The `state` is updated if need be when the evaluation + encounters assignements. + tools (`Dict[str, Callable]`): + The functions that may be called during the evaluation. Any call to another function will fail with an + `InterpretorError`. + """ + if isinstance(expression, ast.Assign): + # Assignement -> we evaluate the assignement which should update the state + # We return the variable assigned as it may be used to determine the final result. + return evaluate_assign(expression, state, tools) + elif isinstance(expression, ast.Call): + # Function call -> we return the value of the function call + return evaluate_call(expression, state, tools) + elif isinstance(expression, ast.Constant): + # Constant -> just return the value + return expression.value + elif isinstance(expression, ast.Dict): + # Dict -> evaluate all keys and values + keys = [evaluate_ast(k, state, tools) for k in expression.keys] + values = [evaluate_ast(v, state, tools) for v in expression.values] + return dict(zip(keys, values)) + elif isinstance(expression, ast.Expr): + # Expression -> evaluate the content + return evaluate_ast(expression.value, state, tools) + elif isinstance(expression, ast.FormattedValue): + # Formatted value (part of f-string) -> evaluate the content and return + return evaluate_ast(expression.value, state, tools) + elif isinstance(expression, ast.If): + # If -> execute the right branch + return evaluate_if(expression, state, tools) + elif hasattr(ast, "Index") and isinstance(expression, ast.Index): + return evaluate_ast(expression.value, state, tools) + elif isinstance(expression, ast.JoinedStr): + return "".join([str(evaluate_ast(v, state, tools)) for v in expression.values]) + elif isinstance(expression, ast.List): + # List -> evaluate all elements + return [evaluate_ast(elt, state, tools) for elt in expression.elts] + elif isinstance(expression, ast.Name): + # Name -> pick up the value in the state + return evaluate_name(expression, state, tools) + elif isinstance(expression, ast.Subscript): + # Subscript -> return the value of the indexing + return evaluate_subscript(expression, state, tools) + else: + # For now we refuse anything else. Let's add things as we need them. + raise InterpretorError(f"{expression.__class__.__name__} is not supported.") + + +def evaluate_assign(assign, state, tools): + var_names = assign.targets + result = evaluate_ast(assign.value, state, tools) + + if len(var_names) == 1: + state[var_names[0].id] = result + else: + if len(result) != len(var_names): + raise InterpretorError(f"Expected {len(var_names)} values but got {len(result)}.") + for var_name, r in zip(var_names, result): + state[var_name.id] = r + return result + + +def evaluate_call(call, state, tools): + if not isinstance(call.func, ast.Name): + raise InterpretorError( + f"It is not permitted to evaluate other functions than the provided tools (tried to execute {call.func} of " + f"type {type(call.func)}." + ) + func_name = call.func.id + if func_name not in tools: + raise InterpretorError( + f"It is not permitted to evaluate other functions than the provided tools (tried to execute {call.func.id})." + ) + + func = tools[func_name] + # Todo deal with args + args = [evaluate_ast(arg, state, tools) for arg in call.args] + kwargs = {keyword.arg: evaluate_ast(keyword.value, state, tools) for keyword in call.keywords} + return func(*args, **kwargs) + + +def evaluate_subscript(subscript, state, tools): + index = evaluate_ast(subscript.slice, state, tools) + value = evaluate_ast(subscript.value, state, tools) + if isinstance(value, (list, tuple)): + return value[int(index)] + if index in value: + return value[index] + if isinstance(index, str) and isinstance(value, Mapping): + close_matches = difflib.get_close_matches(index, list(value.keys())) + if len(close_matches) > 0: + return value[close_matches[0]] + + raise InterpretorError(f"Could not index {value} with '{index}'.") + + +def evaluate_name(name, state, tools): + if name.id in state: + return state[name.id] + close_matches = difflib.get_close_matches(name.id, list(state.keys())) + if len(close_matches) > 0: + return state[close_matches[0]] + raise InterpretorError(f"The variable `{name.id}` is not defined.") + + +def evaluate_condition(condition, state, tools): + if len(condition.ops) > 1: + raise InterpretorError("Cannot evaluate conditions with multiple operators") + + left = evaluate_ast(condition.left, state, tools) + comparator = condition.ops[0] + right = evaluate_ast(condition.comparators[0], state, tools) + + if isinstance(comparator, ast.Eq): + return left == right + elif isinstance(comparator, ast.NotEq): + return left != right + elif isinstance(comparator, ast.Lt): + return left < right + elif isinstance(comparator, ast.LtE): + return left <= right + elif isinstance(comparator, ast.Gt): + return left > right + elif isinstance(comparator, ast.GtE): + return left >= right + elif isinstance(comparator, ast.Is): + return left is right + elif isinstance(comparator, ast.IsNot): + return left is not right + elif isinstance(comparator, ast.In): + return left in right + elif isinstance(comparator, ast.NotIn): + return left not in right + else: + raise InterpretorError(f"Operator not supported: {comparator}") + + +def evaluate_if(if_statement, state, tools): + result = None + if evaluate_condition(if_statement.test, state, tools): + for line in if_statement.body: + line_result = evaluate_ast(line, state, tools) + if line_result is not None: + result = line_result + else: + for line in if_statement.orelse: + line_result = evaluate_ast(line, state, tools) + if line_result is not None: + result = line_result + return result diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..d3b8fd29ee1ad0809cf8b003df50a470e609400f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/speech_to_text.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ..models.whisper import WhisperForConditionalGeneration, WhisperProcessor +from .base import PipelineTool + + +class SpeechToTextTool(PipelineTool): + default_checkpoint = "openai/whisper-base" + description = ( + "This is a tool that transcribes an audio into text. It takes an input named `audio` and returns the " + "transcribed text." + ) + name = "transcriber" + pre_processor_class = WhisperProcessor + model_class = WhisperForConditionalGeneration + + inputs = ["audio"] + outputs = ["text"] + + def encode(self, audio): + return self.pre_processor(audio, return_tensors="pt").input_features + + def forward(self, inputs): + return self.model.generate(inputs=inputs) + + def decode(self, outputs): + return self.pre_processor.batch_decode(outputs, skip_special_tokens=True)[0] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_classification.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_classification.py new file mode 100644 index 0000000000000000000000000000000000000000..f04cdc05b6ac67cd285a1011d83a7bb2854adfe1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_classification.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import torch + +from ..models.auto import AutoModelForSequenceClassification, AutoTokenizer +from .base import PipelineTool + + +class TextClassificationTool(PipelineTool): + """ + Example: + + ```py + from transformers.tools import TextClassificationTool + + classifier = TextClassificationTool() + classifier("This is a super nice API!", labels=["positive", "negative"]) + ``` + """ + + default_checkpoint = "facebook/bart-large-mnli" + description = ( + "This is a tool that classifies an English text using provided labels. It takes two inputs: `text`, which " + "should be the text to classify, and `labels`, which should be the list of labels to use for classification. " + "It returns the most likely label in the list of provided `labels` for the input text." + ) + name = "text_classifier" + pre_processor_class = AutoTokenizer + model_class = AutoModelForSequenceClassification + + inputs = ["text", ["text"]] + outputs = ["text"] + + def setup(self): + super().setup() + config = self.model.config + self.entailment_id = -1 + for idx, label in config.id2label.items(): + if label.lower().startswith("entail"): + self.entailment_id = int(idx) + if self.entailment_id == -1: + raise ValueError("Could not determine the entailment ID from the model config, please pass it at init.") + + def encode(self, text, labels): + self._labels = labels + return self.pre_processor( + [text] * len(labels), + [f"This example is {label}" for label in labels], + return_tensors="pt", + padding="max_length", + ) + + def decode(self, outputs): + logits = outputs.logits + label_id = torch.argmax(logits[:, 2]).item() + return self._labels[label_id] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_question_answering.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_question_answering.py new file mode 100644 index 0000000000000000000000000000000000000000..2a7c2fc09a63499871bc729825b812c79348c762 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_question_answering.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ..models.auto import AutoModelForSeq2SeqLM, AutoTokenizer +from .base import PipelineTool + + +QA_PROMPT = """Here is a text containing a lot of information: '''{text}'''. + +Can you answer this question about the text: '{question}'""" + + +class TextQuestionAnsweringTool(PipelineTool): + default_checkpoint = "google/flan-t5-base" + description = ( + "This is a tool that answers questions related to a text. It takes two arguments named `text`, which is the " + "text where to find the answer, and `question`, which is the question, and returns the answer to the question." + ) + name = "text_qa" + pre_processor_class = AutoTokenizer + model_class = AutoModelForSeq2SeqLM + + inputs = ["text", "text"] + outputs = ["text"] + + def encode(self, text: str, question: str): + prompt = QA_PROMPT.format(text=text, question=question) + return self.pre_processor(prompt, return_tensors="pt") + + def forward(self, inputs): + output_ids = self.model.generate(**inputs) + + in_b, _ = inputs["input_ids"].shape + out_b = output_ids.shape[0] + + return output_ids.reshape(in_b, out_b // in_b, *output_ids.shape[1:])[0][0] + + def decode(self, outputs): + return self.pre_processor.decode(outputs, skip_special_tokens=True, clean_up_tokenization_spaces=True) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_summarization.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_summarization.py new file mode 100644 index 0000000000000000000000000000000000000000..8eedf234ae50b51e23e829cae2b8de4f3ad287e5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_summarization.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ..models.auto import AutoModelForSeq2SeqLM, AutoTokenizer +from .base import PipelineTool + + +class TextSummarizationTool(PipelineTool): + """ + Example: + + ```py + from transformers.tools import TextSummarizationTool + + summarizer = TextSummarizationTool() + summarizer(long_text) + ``` + """ + + default_checkpoint = "philschmid/bart-large-cnn-samsum" + description = ( + "This is a tool that summarizes an English text. It takes an input `text` containing the text to summarize, " + "and returns a summary of the text." + ) + name = "summarizer" + pre_processor_class = AutoTokenizer + model_class = AutoModelForSeq2SeqLM + + inputs = ["text"] + outputs = ["text"] + + def encode(self, text): + return self.pre_processor(text, return_tensors="pt", truncation=True) + + def forward(self, inputs): + return self.model.generate(**inputs)[0] + + def decode(self, outputs): + return self.pre_processor.decode(outputs, skip_special_tokens=True, clean_up_tokenization_spaces=True) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_to_speech.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_to_speech.py new file mode 100644 index 0000000000000000000000000000000000000000..9faed77b01a35c3bd9c9530cd421f02e348a13af --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/text_to_speech.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import torch + +from ..models.speecht5 import SpeechT5ForTextToSpeech, SpeechT5HifiGan, SpeechT5Processor +from ..utils import is_datasets_available +from .base import PipelineTool + + +if is_datasets_available(): + from datasets import load_dataset + + +class TextToSpeechTool(PipelineTool): + default_checkpoint = "microsoft/speecht5_tts" + description = ( + "This is a tool that reads an English text out loud. It takes an input named `text` which should contain the " + "text to read (in English) and returns a waveform object containing the sound." + ) + name = "text_reader" + pre_processor_class = SpeechT5Processor + model_class = SpeechT5ForTextToSpeech + post_processor_class = SpeechT5HifiGan + + inputs = ["text"] + outputs = ["audio"] + + def setup(self): + if self.post_processor is None: + self.post_processor = "microsoft/speecht5_hifigan" + super().setup() + + def encode(self, text, speaker_embeddings=None): + inputs = self.pre_processor(text=text, return_tensors="pt", truncation=True) + + if speaker_embeddings is None: + if not is_datasets_available(): + raise ImportError("Datasets needs to be installed if not passing speaker embeddings.") + + embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation") + speaker_embeddings = torch.tensor(embeddings_dataset[7305]["xvector"]).unsqueeze(0) + + return {"input_ids": inputs["input_ids"], "speaker_embeddings": speaker_embeddings} + + def forward(self, inputs): + with torch.no_grad(): + return self.model.generate_speech(**inputs) + + def decode(self, outputs): + with torch.no_grad(): + return self.post_processor(outputs).cpu().detach() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/translation.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/translation.py new file mode 100644 index 0000000000000000000000000000000000000000..50a164d5bd6f4f7b647374484bd20c95e74c5dc9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/tools/translation.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ..models.auto import AutoModelForSeq2SeqLM, AutoTokenizer +from .base import PipelineTool + + +LANGUAGE_CODES = { + "Acehnese Arabic": "ace_Arab", + "Acehnese Latin": "ace_Latn", + "Mesopotamian Arabic": "acm_Arab", + "Ta'izzi-Adeni Arabic": "acq_Arab", + "Tunisian Arabic": "aeb_Arab", + "Afrikaans": "afr_Latn", + "South Levantine Arabic": "ajp_Arab", + "Akan": "aka_Latn", + "Amharic": "amh_Ethi", + "North Levantine Arabic": "apc_Arab", + "Modern Standard Arabic": "arb_Arab", + "Modern Standard Arabic Romanized": "arb_Latn", + "Najdi Arabic": "ars_Arab", + "Moroccan Arabic": "ary_Arab", + "Egyptian Arabic": "arz_Arab", + "Assamese": "asm_Beng", + "Asturian": "ast_Latn", + "Awadhi": "awa_Deva", + "Central Aymara": "ayr_Latn", + "South Azerbaijani": "azb_Arab", + "North Azerbaijani": "azj_Latn", + "Bashkir": "bak_Cyrl", + "Bambara": "bam_Latn", + "Balinese": "ban_Latn", + "Belarusian": "bel_Cyrl", + "Bemba": "bem_Latn", + "Bengali": "ben_Beng", + "Bhojpuri": "bho_Deva", + "Banjar Arabic": "bjn_Arab", + "Banjar Latin": "bjn_Latn", + "Standard Tibetan": "bod_Tibt", + "Bosnian": "bos_Latn", + "Buginese": "bug_Latn", + "Bulgarian": "bul_Cyrl", + "Catalan": "cat_Latn", + "Cebuano": "ceb_Latn", + "Czech": "ces_Latn", + "Chokwe": "cjk_Latn", + "Central Kurdish": "ckb_Arab", + "Crimean Tatar": "crh_Latn", + "Welsh": "cym_Latn", + "Danish": "dan_Latn", + "German": "deu_Latn", + "Southwestern Dinka": "dik_Latn", + "Dyula": "dyu_Latn", + "Dzongkha": "dzo_Tibt", + "Greek": "ell_Grek", + "English": "eng_Latn", + "Esperanto": "epo_Latn", + "Estonian": "est_Latn", + "Basque": "eus_Latn", + "Ewe": "ewe_Latn", + "Faroese": "fao_Latn", + "Fijian": "fij_Latn", + "Finnish": "fin_Latn", + "Fon": "fon_Latn", + "French": "fra_Latn", + "Friulian": "fur_Latn", + "Nigerian Fulfulde": "fuv_Latn", + "Scottish Gaelic": "gla_Latn", + "Irish": "gle_Latn", + "Galician": "glg_Latn", + "Guarani": "grn_Latn", + "Gujarati": "guj_Gujr", + "Haitian Creole": "hat_Latn", + "Hausa": "hau_Latn", + "Hebrew": "heb_Hebr", + "Hindi": "hin_Deva", + "Chhattisgarhi": "hne_Deva", + "Croatian": "hrv_Latn", + "Hungarian": "hun_Latn", + "Armenian": "hye_Armn", + "Igbo": "ibo_Latn", + "Ilocano": "ilo_Latn", + "Indonesian": "ind_Latn", + "Icelandic": "isl_Latn", + "Italian": "ita_Latn", + "Javanese": "jav_Latn", + "Japanese": "jpn_Jpan", + "Kabyle": "kab_Latn", + "Jingpho": "kac_Latn", + "Kamba": "kam_Latn", + "Kannada": "kan_Knda", + "Kashmiri Arabic": "kas_Arab", + "Kashmiri Devanagari": "kas_Deva", + "Georgian": "kat_Geor", + "Central Kanuri Arabic": "knc_Arab", + "Central Kanuri Latin": "knc_Latn", + "Kazakh": "kaz_Cyrl", + "Kabiyè": "kbp_Latn", + "Kabuverdianu": "kea_Latn", + "Khmer": "khm_Khmr", + "Kikuyu": "kik_Latn", + "Kinyarwanda": "kin_Latn", + "Kyrgyz": "kir_Cyrl", + "Kimbundu": "kmb_Latn", + "Northern Kurdish": "kmr_Latn", + "Kikongo": "kon_Latn", + "Korean": "kor_Hang", + "Lao": "lao_Laoo", + "Ligurian": "lij_Latn", + "Limburgish": "lim_Latn", + "Lingala": "lin_Latn", + "Lithuanian": "lit_Latn", + "Lombard": "lmo_Latn", + "Latgalian": "ltg_Latn", + "Luxembourgish": "ltz_Latn", + "Luba-Kasai": "lua_Latn", + "Ganda": "lug_Latn", + "Luo": "luo_Latn", + "Mizo": "lus_Latn", + "Standard Latvian": "lvs_Latn", + "Magahi": "mag_Deva", + "Maithili": "mai_Deva", + "Malayalam": "mal_Mlym", + "Marathi": "mar_Deva", + "Minangkabau Arabic ": "min_Arab", + "Minangkabau Latin": "min_Latn", + "Macedonian": "mkd_Cyrl", + "Plateau Malagasy": "plt_Latn", + "Maltese": "mlt_Latn", + "Meitei Bengali": "mni_Beng", + "Halh Mongolian": "khk_Cyrl", + "Mossi": "mos_Latn", + "Maori": "mri_Latn", + "Burmese": "mya_Mymr", + "Dutch": "nld_Latn", + "Norwegian Nynorsk": "nno_Latn", + "Norwegian Bokmål": "nob_Latn", + "Nepali": "npi_Deva", + "Northern Sotho": "nso_Latn", + "Nuer": "nus_Latn", + "Nyanja": "nya_Latn", + "Occitan": "oci_Latn", + "West Central Oromo": "gaz_Latn", + "Odia": "ory_Orya", + "Pangasinan": "pag_Latn", + "Eastern Panjabi": "pan_Guru", + "Papiamento": "pap_Latn", + "Western Persian": "pes_Arab", + "Polish": "pol_Latn", + "Portuguese": "por_Latn", + "Dari": "prs_Arab", + "Southern Pashto": "pbt_Arab", + "Ayacucho Quechua": "quy_Latn", + "Romanian": "ron_Latn", + "Rundi": "run_Latn", + "Russian": "rus_Cyrl", + "Sango": "sag_Latn", + "Sanskrit": "san_Deva", + "Santali": "sat_Olck", + "Sicilian": "scn_Latn", + "Shan": "shn_Mymr", + "Sinhala": "sin_Sinh", + "Slovak": "slk_Latn", + "Slovenian": "slv_Latn", + "Samoan": "smo_Latn", + "Shona": "sna_Latn", + "Sindhi": "snd_Arab", + "Somali": "som_Latn", + "Southern Sotho": "sot_Latn", + "Spanish": "spa_Latn", + "Tosk Albanian": "als_Latn", + "Sardinian": "srd_Latn", + "Serbian": "srp_Cyrl", + "Swati": "ssw_Latn", + "Sundanese": "sun_Latn", + "Swedish": "swe_Latn", + "Swahili": "swh_Latn", + "Silesian": "szl_Latn", + "Tamil": "tam_Taml", + "Tatar": "tat_Cyrl", + "Telugu": "tel_Telu", + "Tajik": "tgk_Cyrl", + "Tagalog": "tgl_Latn", + "Thai": "tha_Thai", + "Tigrinya": "tir_Ethi", + "Tamasheq Latin": "taq_Latn", + "Tamasheq Tifinagh": "taq_Tfng", + "Tok Pisin": "tpi_Latn", + "Tswana": "tsn_Latn", + "Tsonga": "tso_Latn", + "Turkmen": "tuk_Latn", + "Tumbuka": "tum_Latn", + "Turkish": "tur_Latn", + "Twi": "twi_Latn", + "Central Atlas Tamazight": "tzm_Tfng", + "Uyghur": "uig_Arab", + "Ukrainian": "ukr_Cyrl", + "Umbundu": "umb_Latn", + "Urdu": "urd_Arab", + "Northern Uzbek": "uzn_Latn", + "Venetian": "vec_Latn", + "Vietnamese": "vie_Latn", + "Waray": "war_Latn", + "Wolof": "wol_Latn", + "Xhosa": "xho_Latn", + "Eastern Yiddish": "ydd_Hebr", + "Yoruba": "yor_Latn", + "Yue Chinese": "yue_Hant", + "Chinese Simplified": "zho_Hans", + "Chinese Traditional": "zho_Hant", + "Standard Malay": "zsm_Latn", + "Zulu": "zul_Latn", +} + + +class TranslationTool(PipelineTool): + """ + Example: + + ```py + from transformers.tools import TranslationTool + + translator = TranslationTool() + translator("This is a super nice API!", src_lang="English", tgt_lang="French") + ``` + """ + + default_checkpoint = "facebook/nllb-200-distilled-600M" + description = ( + "This is a tool that translates text from a language to another. It takes three inputs: `text`, which should " + "be the text to translate, `src_lang`, which should be the language of the text to translate and `tgt_lang`, " + "which should be the language for the desired ouput language. Both `src_lang` and `tgt_lang` are written in " + "plain English, such as 'Romanian', or 'Albanian'. It returns the text translated in `tgt_lang`." + ) + name = "translator" + pre_processor_class = AutoTokenizer + model_class = AutoModelForSeq2SeqLM + lang_to_code = LANGUAGE_CODES + + inputs = ["text", "text", "text"] + outputs = ["text"] + + def encode(self, text, src_lang, tgt_lang): + if src_lang not in self.lang_to_code: + raise ValueError(f"{src_lang} is not a supported language.") + if tgt_lang not in self.lang_to_code: + raise ValueError(f"{tgt_lang} is not a supported language.") + src_lang = self.lang_to_code[src_lang] + tgt_lang = self.lang_to_code[tgt_lang] + return self.pre_processor._build_translation_inputs( + text, return_tensors="pt", src_lang=src_lang, tgt_lang=tgt_lang + ) + + def forward(self, inputs): + return self.model.generate(**inputs) + + def decode(self, outputs): + return self.post_processor.decode(outputs[0].tolist(), skip_special_tokens=True) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer.py new file mode 100644 index 0000000000000000000000000000000000000000..f7fb3558df7f710bc604f2da686aa21499d9911b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer.py @@ -0,0 +1,3916 @@ +# coding=utf-8 +# Copyright 2020-present the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +The Trainer class, to easily train a 🤗 Transformers from scratch or finetune it on a new task. +""" + +import contextlib +import functools +import glob +import inspect +import math +import os +import random +import re +import shutil +import sys +import time +import warnings +from collections.abc import Mapping +from pathlib import Path +from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union + +from tqdm.auto import tqdm + + +# Integrations must be imported before ML frameworks: +# isort: off +from .integrations import ( + default_hp_search_backend, + get_reporting_integration_callbacks, + hp_params, + is_fairscale_available, + is_optuna_available, + is_ray_tune_available, + is_sigopt_available, + is_wandb_available, + run_hp_search_optuna, + run_hp_search_ray, + run_hp_search_sigopt, + run_hp_search_wandb, +) + +# isort: on + +import numpy as np +import torch +import torch.distributed as dist +from huggingface_hub import Repository, create_repo +from packaging import version +from torch import nn +from torch.utils.data import DataLoader, Dataset, RandomSampler, SequentialSampler +from torch.utils.data.distributed import DistributedSampler + +from . import __version__ +from .configuration_utils import PretrainedConfig +from .data.data_collator import DataCollator, DataCollatorWithPadding, default_data_collator +from .debug_utils import DebugOption, DebugUnderflowOverflow +from .deepspeed import deepspeed_init, is_deepspeed_zero3_enabled +from .dependency_versions_check import dep_version_check +from .modelcard import TrainingSummary +from .modeling_utils import PreTrainedModel, load_sharded_checkpoint, unwrap_model +from .models.auto.modeling_auto import MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, MODEL_MAPPING_NAMES +from .optimization import Adafactor, get_scheduler +from .pytorch_utils import ALL_LAYERNORM_LAYERS, is_torch_greater_or_equal_than_1_10, is_torch_less_than_1_11 +from .tokenization_utils_base import PreTrainedTokenizerBase +from .trainer_callback import ( + CallbackHandler, + DefaultFlowCallback, + PrinterCallback, + ProgressCallback, + TrainerCallback, + TrainerControl, + TrainerState, +) +from .trainer_pt_utils import ( + DistributedLengthGroupedSampler, + DistributedSamplerWithLoop, + DistributedTensorGatherer, + IterableDatasetShard, + LabelSmoother, + LengthGroupedSampler, + SequentialDistributedSampler, + ShardSampler, + distributed_broadcast_scalars, + distributed_concat, + find_batch_size, + get_model_param_count, + get_module_class_from_name, + get_parameter_names, + nested_concat, + nested_detach, + nested_numpify, + nested_truncate, + nested_xla_mesh_reduce, + reissue_pt_warnings, +) +from .trainer_utils import ( + PREFIX_CHECKPOINT_DIR, + BestRun, + EvalLoopOutput, + EvalPrediction, + FSDPOption, + HPSearchBackend, + HubStrategy, + IntervalStrategy, + PredictionOutput, + RemoveColumnsCollator, + ShardedDDPOption, + TrainerMemoryTracker, + TrainOutput, + default_compute_objective, + default_hp_space, + denumpify_detensorize, + enable_full_determinism, + find_executable_batch_size, + get_last_checkpoint, + has_length, + number_of_arguments, + seed_worker, + set_seed, + speed_metrics, +) +from .training_args import OptimizerNames, ParallelMode, TrainingArguments +from .utils import ( + CONFIG_NAME, + SAFE_WEIGHTS_INDEX_NAME, + SAFE_WEIGHTS_NAME, + WEIGHTS_INDEX_NAME, + WEIGHTS_NAME, + can_return_loss, + find_labels, + get_full_repo_name, + is_accelerate_available, + is_apex_available, + is_datasets_available, + is_in_notebook, + is_ipex_available, + is_safetensors_available, + is_sagemaker_dp_enabled, + is_sagemaker_mp_enabled, + is_torch_compile_available, + is_torch_neuroncore_available, + is_torch_tpu_available, + logging, + strtobool, +) +from .utils.generic import ContextManagers + + +_is_native_cpu_amp_available = is_torch_greater_or_equal_than_1_10 + +DEFAULT_CALLBACKS = [DefaultFlowCallback] +DEFAULT_PROGRESS_CALLBACK = ProgressCallback + +if is_in_notebook(): + from .utils.notebook import NotebookProgressCallback + + DEFAULT_PROGRESS_CALLBACK = NotebookProgressCallback + +if is_apex_available(): + from apex import amp + +if is_datasets_available(): + import datasets + +if is_torch_tpu_available(check_device=False): + import torch_xla.core.xla_model as xm + import torch_xla.debug.metrics as met + import torch_xla.distributed.parallel_loader as pl + +if is_fairscale_available(): + dep_version_check("fairscale") + import fairscale + from fairscale.nn.data_parallel import FullyShardedDataParallel as FullyShardedDDP + from fairscale.nn.data_parallel import ShardedDataParallel as ShardedDDP + from fairscale.nn.wrap import auto_wrap + from fairscale.optim import OSS + from fairscale.optim.grad_scaler import ShardedGradScaler + + +if is_sagemaker_mp_enabled(): + import smdistributed.modelparallel.torch as smp + from smdistributed.modelparallel import __version__ as SMP_VERSION + + IS_SAGEMAKER_MP_POST_1_10 = version.parse(SMP_VERSION) >= version.parse("1.10") + + from .trainer_pt_utils import smp_forward_backward, smp_forward_only, smp_gather, smp_nested_concat +else: + IS_SAGEMAKER_MP_POST_1_10 = False + + +if is_safetensors_available(): + import safetensors.torch + + +skip_first_batches = None +if is_accelerate_available(): + from accelerate import __version__ as accelerate_version + + if version.parse(accelerate_version) >= version.parse("0.16"): + from accelerate import skip_first_batches + + +if TYPE_CHECKING: + import optuna + +logger = logging.get_logger(__name__) + + +# Name of the files used for checkpointing +TRAINING_ARGS_NAME = "training_args.bin" +TRAINER_STATE_NAME = "trainer_state.json" +OPTIMIZER_NAME = "optimizer.pt" +SCHEDULER_NAME = "scheduler.pt" +SCALER_NAME = "scaler.pt" + + +class Trainer: + """ + Trainer is a simple but feature-complete training and eval loop for PyTorch, optimized for 🤗 Transformers. + + Args: + model ([`PreTrainedModel`] or `torch.nn.Module`, *optional*): + The model to train, evaluate or use for predictions. If not provided, a `model_init` must be passed. + + + + [`Trainer`] is optimized to work with the [`PreTrainedModel`] provided by the library. You can still use + your own models defined as `torch.nn.Module` as long as they work the same way as the 🤗 Transformers + models. + + + + args ([`TrainingArguments`], *optional*): + The arguments to tweak for training. Will default to a basic instance of [`TrainingArguments`] with the + `output_dir` set to a directory named *tmp_trainer* in the current directory if not provided. + data_collator (`DataCollator`, *optional*): + The function to use to form a batch from a list of elements of `train_dataset` or `eval_dataset`. Will + default to [`default_data_collator`] if no `tokenizer` is provided, an instance of + [`DataCollatorWithPadding`] otherwise. + train_dataset (`torch.utils.data.Dataset` or `torch.utils.data.IterableDataset`, *optional*): + The dataset to use for training. If it is a [`~datasets.Dataset`], columns not accepted by the + `model.forward()` method are automatically removed. + + Note that if it's a `torch.utils.data.IterableDataset` with some randomization and you are training in a + distributed fashion, your iterable dataset should either use a internal attribute `generator` that is a + `torch.Generator` for the randomization that must be identical on all processes (and the Trainer will + manually set the seed of this `generator` at each epoch) or have a `set_epoch()` method that internally + sets the seed of the RNGs used. + eval_dataset (Union[`torch.utils.data.Dataset`, Dict[str, `torch.utils.data.Dataset`]), *optional*): + The dataset to use for evaluation. If it is a [`~datasets.Dataset`], columns not accepted by the + `model.forward()` method are automatically removed. If it is a dictionary, it will evaluate on each + dataset prepending the dictionary key to the metric name. + tokenizer ([`PreTrainedTokenizerBase`], *optional*): + The tokenizer used to preprocess the data. If provided, will be used to automatically pad the inputs to the + maximum length when batching inputs, and it will be saved along the model to make it easier to rerun an + interrupted training or reuse the fine-tuned model. + model_init (`Callable[[], PreTrainedModel]`, *optional*): + A function that instantiates the model to be used. If provided, each call to [`~Trainer.train`] will start + from a new instance of the model as given by this function. + + The function may have zero argument, or a single one containing the optuna/Ray Tune/SigOpt trial object, to + be able to choose different architectures according to hyper parameters (such as layer count, sizes of + inner layers, dropout probabilities etc). + compute_metrics (`Callable[[EvalPrediction], Dict]`, *optional*): + The function that will be used to compute metrics at evaluation. Must take a [`EvalPrediction`] and return + a dictionary string to metric values. + callbacks (List of [`TrainerCallback`], *optional*): + A list of callbacks to customize the training loop. Will add those to the list of default callbacks + detailed in [here](callback). + + If you want to remove one of the default callbacks used, use the [`Trainer.remove_callback`] method. + optimizers (`Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]`, *optional*): A tuple + containing the optimizer and the scheduler to use. Will default to an instance of [`AdamW`] on your model + and a scheduler given by [`get_linear_schedule_with_warmup`] controlled by `args`. + preprocess_logits_for_metrics (`Callable[[torch.Tensor, torch.Tensor], torch.Tensor]`, *optional*): + A function that preprocess the logits right before caching them at each evaluation step. Must take two + tensors, the logits and the labels, and return the logits once processed as desired. The modifications made + by this function will be reflected in the predictions received by `compute_metrics`. + + Note that the labels (second parameter) will be `None` if the dataset does not have them. + + Important attributes: + + - **model** -- Always points to the core model. If using a transformers model, it will be a [`PreTrainedModel`] + subclass. + - **model_wrapped** -- Always points to the most external model in case one or more other modules wrap the + original model. This is the model that should be used for the forward pass. For example, under `DeepSpeed`, + the inner model is wrapped in `DeepSpeed` and then again in `torch.nn.DistributedDataParallel`. If the inner + model hasn't been wrapped, then `self.model_wrapped` is the same as `self.model`. + - **is_model_parallel** -- Whether or not a model has been switched to a model parallel mode (different from + data parallelism, this means some of the model layers are split on different GPUs). + - **place_model_on_device** -- Whether or not to automatically place the model on the device - it will be set + to `False` if model parallel or deepspeed is used, or if the default + `TrainingArguments.place_model_on_device` is overridden to return `False` . + - **is_in_train** -- Whether or not a model is currently running `train` (e.g. when `evaluate` is called while + in `train`) + + """ + + from .trainer_pt_utils import _get_learning_rate, log_metrics, metrics_format, save_metrics, save_state + + def __init__( + self, + model: Union[PreTrainedModel, nn.Module] = None, + args: TrainingArguments = None, + data_collator: Optional[DataCollator] = None, + train_dataset: Optional[Dataset] = None, + eval_dataset: Optional[Union[Dataset, Dict[str, Dataset]]] = None, + tokenizer: Optional[PreTrainedTokenizerBase] = None, + model_init: Optional[Callable[[], PreTrainedModel]] = None, + compute_metrics: Optional[Callable[[EvalPrediction], Dict]] = None, + callbacks: Optional[List[TrainerCallback]] = None, + optimizers: Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None), + preprocess_logits_for_metrics: Optional[Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None, + ): + if args is None: + output_dir = "tmp_trainer" + logger.info(f"No `TrainingArguments` passed, using `output_dir={output_dir}`.") + args = TrainingArguments(output_dir=output_dir) + self.args = args + # Seed must be set before instantiating the model when using model + enable_full_determinism(self.args.seed) if self.args.full_determinism else set_seed(self.args.seed) + self.hp_name = None + self.deepspeed = None + self.is_in_train = False + + # memory metrics - must set up as early as possible + self._memory_tracker = TrainerMemoryTracker(self.args.skip_memory_metrics) + self._memory_tracker.start() + + # set the correct log level depending on the node + log_level = args.get_process_log_level() + logging.set_verbosity(log_level) + + # force device and distributed setup init explicitly + args._setup_devices + + if model is None: + if model_init is not None: + self.model_init = model_init + model = self.call_model_init() + else: + raise RuntimeError("`Trainer` requires either a `model` or `model_init` argument") + else: + if model_init is not None: + warnings.warn( + "`Trainer` requires either a `model` or `model_init` argument, but not both. `model_init` will" + " overwrite your model when calling the `train` method. This will become a fatal error in the next" + " release.", + FutureWarning, + ) + self.model_init = model_init + + if model.__class__.__name__ in MODEL_MAPPING_NAMES: + raise ValueError( + f"The model you have picked ({model.__class__.__name__}) cannot be used as is for training: it only " + "computes hidden states and does not accept any labels. You should choose a model with a head " + "suitable for your task like any of the `AutoModelForXxx` listed at " + "https://huggingface.co/docs/transformers/model_doc/auto." + ) + + if hasattr(model, "is_parallelizable") and model.is_parallelizable and model.model_parallel: + self.is_model_parallel = True + else: + self.is_model_parallel = False + + if ( + getattr(model, "hf_device_map", None) is not None + and len([device for device in set(model.hf_device_map.values()) if device not in ["cpu", "disk"]]) > 1 + and not self.is_model_parallel + ): + self.is_model_parallel = True + + # warn users + logger.info( + "You have loaded a model on multiple GPUs. `is_model_parallel` attribute will be force-set" + " to `True` to avoid any unexpected behavior such as device placement mismatching." + ) + + # At this stage the model is already loaded + if getattr(model, "is_loaded_in_8bit", False): + if getattr(model, "_is_int8_training_enabled", False): + logger.info( + "The model is loaded in 8-bit precision. To train this model you need to add additional modules" + " inside the model such as adapters using `peft` library and freeze the model weights. Please" + " check " + " the examples in https://github.com/huggingface/peft for more details." + ) + else: + raise ValueError( + "The model you want to train is loaded in 8-bit precision. if you want to fine-tune an 8-bit" + " model, please make sure that you have installed `bitsandbytes>=0.37.0`. " + ) + + # Setup Sharded DDP training + self.sharded_ddp = None + if len(args.sharded_ddp) > 0: + if args.deepspeed: + raise ValueError( + "Using --sharded_ddp xxx together with --deepspeed is not possible, deactivate one of those flags." + ) + if len(args.fsdp) > 0: + raise ValueError( + "Using --sharded_ddp xxx together with --fsdp is not possible, deactivate one of those flags." + ) + if args.parallel_mode != ParallelMode.DISTRIBUTED: + raise ValueError("Using sharded DDP only works in distributed training.") + elif not is_fairscale_available(): + raise ImportError("Sharded DDP training requires fairscale: `pip install fairscale`.") + elif ShardedDDPOption.SIMPLE not in args.sharded_ddp and FullyShardedDDP is None: + raise ImportError( + "Sharded DDP in a mode other than simple training requires fairscale version >= 0.3, found " + f"{fairscale.__version__}. Upgrade your fairscale library: `pip install --upgrade fairscale`." + ) + elif ShardedDDPOption.SIMPLE in args.sharded_ddp: + self.sharded_ddp = ShardedDDPOption.SIMPLE + elif ShardedDDPOption.ZERO_DP_2 in args.sharded_ddp: + self.sharded_ddp = ShardedDDPOption.ZERO_DP_2 + elif ShardedDDPOption.ZERO_DP_3 in args.sharded_ddp: + self.sharded_ddp = ShardedDDPOption.ZERO_DP_3 + + self.fsdp = None + if len(args.fsdp) > 0: + if args.deepspeed: + raise ValueError( + "Using --fsdp xxx together with --deepspeed is not possible, deactivate one of those flags." + ) + if not args.fsdp_config["xla"] and args.parallel_mode != ParallelMode.DISTRIBUTED: + raise ValueError("Using fsdp only works in distributed training.") + + # dep_version_check("torch>=1.12.0") + # Would have to update setup.py with torch>=1.12.0 + # which isn't ideally given that it will force people not using FSDP to also use torch>=1.12.0 + # below is the current alternative. + if version.parse(version.parse(torch.__version__).base_version) < version.parse("1.12.0"): + raise ValueError("FSDP requires PyTorch >= 1.12.0") + + from torch.distributed.fsdp.fully_sharded_data_parallel import BackwardPrefetch, ShardingStrategy + + if FSDPOption.FULL_SHARD in args.fsdp: + self.fsdp = ShardingStrategy.FULL_SHARD + elif FSDPOption.SHARD_GRAD_OP in args.fsdp: + self.fsdp = ShardingStrategy.SHARD_GRAD_OP + elif FSDPOption.NO_SHARD in args.fsdp: + self.fsdp = ShardingStrategy.NO_SHARD + + self.backward_prefetch = BackwardPrefetch.BACKWARD_PRE + if "backward_prefetch" in self.args.fsdp_config and "backward_pos" in self.args.fsdp_config.get( + "backward_prefetch", [] + ): + self.backward_prefetch = BackwardPrefetch.BACKWARD_POST + + self.forward_prefetch = False + if self.args.fsdp_config.get("forward_prefect", False): + self.forward_prefetch = True + + self.limit_all_gathers = False + if self.args.fsdp_config.get("limit_all_gathers", False): + self.limit_all_gathers = True + + # one place to sort out whether to place the model on device or not + # postpone switching model to cuda when: + # 1. MP - since we are trying to fit a much bigger than 1 gpu model + # 2. fp16-enabled DeepSpeed loads the model in half the size and it doesn't need .to() anyway, + # and we only use deepspeed for training at the moment + # 3. full bf16 or fp16 eval - since the model needs to be cast to the right dtype first + # 4. Sharded DDP - same as MP + # 5. FSDP - same as MP + self.place_model_on_device = args.place_model_on_device + if ( + self.is_model_parallel + or args.deepspeed + or ((args.fp16_full_eval or args.bf16_full_eval) and not args.do_train) + or (self.sharded_ddp in [ShardedDDPOption.ZERO_DP_2, ShardedDDPOption.ZERO_DP_3]) + or (self.fsdp is not None) + ): + self.place_model_on_device = False + + default_collator = default_data_collator if tokenizer is None else DataCollatorWithPadding(tokenizer) + self.data_collator = data_collator if data_collator is not None else default_collator + self.train_dataset = train_dataset + self.eval_dataset = eval_dataset + self.tokenizer = tokenizer + + if self.place_model_on_device and not getattr(model, "is_loaded_in_8bit", False): + self._move_model_to_device(model, args.device) + + # Force n_gpu to 1 to avoid DataParallel as MP will manage the GPUs + if self.is_model_parallel: + self.args._n_gpu = 1 + + # later use `self.model is self.model_wrapped` to check if it's wrapped or not + self.model_wrapped = model + self.model = model + + self.compute_metrics = compute_metrics + self.preprocess_logits_for_metrics = preprocess_logits_for_metrics + self.optimizer, self.lr_scheduler = optimizers + if model_init is not None and (self.optimizer is not None or self.lr_scheduler is not None): + raise RuntimeError( + "Passing a `model_init` is incompatible with providing the `optimizers` argument. " + "You should subclass `Trainer` and override the `create_optimizer_and_scheduler` method." + ) + if is_torch_tpu_available() and self.optimizer is not None: + for param in self.model.parameters(): + model_device = param.device + break + for param_group in self.optimizer.param_groups: + if len(param_group["params"]) > 0: + optimizer_device = param_group["params"][0].device + break + if model_device != optimizer_device: + raise ValueError( + "The model and the optimizer parameters are not on the same device, which probably means you" + " created an optimizer around your model **before** putting on the device and passing it to the" + " `Trainer`. Make sure the lines `import torch_xla.core.xla_model as xm` and" + " `model.to(xm.xla_device())` is performed before the optimizer creation in your script." + ) + if ((self.sharded_ddp is not None) or args.deepspeed or (self.fsdp is not None)) and ( + self.optimizer is not None or self.lr_scheduler is not None + ): + raise RuntimeError( + "Passing `optimizers` is not allowed if Fairscale, Deepspeed or PyTorch FSDP is enabled." + "You should subclass `Trainer` and override the `create_optimizer_and_scheduler` method." + ) + default_callbacks = DEFAULT_CALLBACKS + get_reporting_integration_callbacks(self.args.report_to) + callbacks = default_callbacks if callbacks is None else default_callbacks + callbacks + self.callback_handler = CallbackHandler( + callbacks, self.model, self.tokenizer, self.optimizer, self.lr_scheduler + ) + self.add_callback(PrinterCallback if self.args.disable_tqdm else DEFAULT_PROGRESS_CALLBACK) + + # Will be set to True by `self._setup_loggers()` on first call to `self.log()`. + self._loggers_initialized = False + + # Create clone of distant repo and output directory if needed + if self.args.push_to_hub: + self.init_git_repo(at_init=True) + # In case of pull, we need to make sure every process has the latest. + if is_torch_tpu_available(): + xm.rendezvous("init git repo") + elif args.parallel_mode == ParallelMode.DISTRIBUTED: + dist.barrier() + + if self.args.should_save: + os.makedirs(self.args.output_dir, exist_ok=True) + + if not callable(self.data_collator) and callable(getattr(self.data_collator, "collate_batch", None)): + raise ValueError("The `data_collator` should be a simple callable (function, class with `__call__`).") + + if args.max_steps > 0: + logger.info("max_steps is given, it will override any value given in num_train_epochs") + + if train_dataset is not None and not has_length(train_dataset) and args.max_steps <= 0: + raise ValueError( + "The train_dataset does not implement __len__, max_steps has to be specified. " + "The number of steps needs to be known in advance for the learning rate scheduler." + ) + + if ( + train_dataset is not None + and isinstance(train_dataset, torch.utils.data.IterableDataset) + and args.group_by_length + ): + raise ValueError("the `--group_by_length` option is only available for `Dataset`, not `IterableDataset") + + self._signature_columns = None + + # Mixed precision setup + self.use_apex = False + self.use_cuda_amp = False + self.use_cpu_amp = False + + # Mixed precision setup for SageMaker Model Parallel + if is_sagemaker_mp_enabled(): + # BF16 + model parallelism in SageMaker: currently not supported, raise an error + if args.bf16: + raise ValueError("SageMaker Model Parallelism does not support BF16 yet. Please use FP16 instead ") + + if IS_SAGEMAKER_MP_POST_1_10: + # When there's mismatch between SMP config and trainer argument, use SMP config as truth + if args.fp16 != smp.state.cfg.fp16: + logger.warning( + f"FP16 provided in SM_HP_MP_PARAMETERS is {smp.state.cfg.fp16}," + f"but FP16 provided in trainer argument is {args.fp16}," + f"setting to {smp.state.cfg.fp16}" + ) + args.fp16 = smp.state.cfg.fp16 + else: + # smp < 1.10 does not support fp16 in trainer. + if hasattr(smp.state.cfg, "fp16"): + logger.warning( + f"FP16 provided in SM_HP_MP_PARAMETERS is {smp.state.cfg.fp16}, " + "but SageMaker Model Parallelism < 1.10 does not support FP16 in trainer." + ) + + if args.fp16 or args.bf16: + if args.half_precision_backend == "auto": + if args.device == torch.device("cpu"): + if args.fp16: + raise ValueError("Tried to use `fp16` but it is not supported on cpu") + elif _is_native_cpu_amp_available: + args.half_precision_backend = "cpu_amp" + else: + raise ValueError("Tried to use cpu amp but native cpu amp is not available") + else: + args.half_precision_backend = "cuda_amp" + + logger.info(f"Using {args.half_precision_backend} half precision backend") + + self.do_grad_scaling = False + if (args.fp16 or args.bf16) and not (args.deepspeed or is_sagemaker_mp_enabled()): + # deepspeed and SageMaker Model Parallel manage their own half precision + if args.half_precision_backend == "cuda_amp": + self.use_cuda_amp = True + self.amp_dtype = torch.float16 if args.fp16 else torch.bfloat16 + # bf16 does not need grad scaling + self.do_grad_scaling = self.amp_dtype == torch.float16 + if self.do_grad_scaling: + if self.sharded_ddp is not None: + self.scaler = ShardedGradScaler() + elif self.fsdp is not None: + from torch.distributed.fsdp.sharded_grad_scaler import ( + ShardedGradScaler as FSDPShardedGradScaler, + ) + + self.scaler = FSDPShardedGradScaler() + elif is_torch_tpu_available(): + from torch_xla.amp import GradScaler + + self.scaler = GradScaler() + else: + self.scaler = torch.cuda.amp.GradScaler() + elif args.half_precision_backend == "cpu_amp": + self.use_cpu_amp = True + self.amp_dtype = torch.bfloat16 + else: + if not is_apex_available(): + raise ImportError( + "Using FP16 with APEX but APEX is not installed, please refer to" + " https://www.github.com/nvidia/apex." + ) + self.use_apex = True + + # FP16 + model parallelism in SageMaker: gradient clipping does not work for now so we raise a helpful error. + if ( + is_sagemaker_mp_enabled() + and self.use_cuda_amp + and args.max_grad_norm is not None + and args.max_grad_norm > 0 + ): + raise ValueError( + "SageMaker Model Parallelism in mixed precision mode does not support gradient clipping yet. Pass " + "along 'max_grad_norm': 0 in your hyperparameters." + ) + + # Label smoothing + if self.args.label_smoothing_factor != 0: + self.label_smoother = LabelSmoother(epsilon=self.args.label_smoothing_factor) + else: + self.label_smoother = None + + self.state = TrainerState( + is_local_process_zero=self.is_local_process_zero(), + is_world_process_zero=self.is_world_process_zero(), + ) + + self.control = TrainerControl() + # Internal variable to count flos in each process, will be accumulated in `self.state.total_flos` then + # returned to 0 every time flos need to be logged + self.current_flos = 0 + self.hp_search_backend = None + self.use_tune_checkpoints = False + default_label_names = find_labels(self.model.__class__) + self.label_names = default_label_names if self.args.label_names is None else self.args.label_names + self.can_return_loss = can_return_loss(self.model.__class__) + self.control = self.callback_handler.on_init_end(self.args, self.state, self.control) + + # Internal variables to keep track of the original batch size + self._train_batch_size = args.train_batch_size + + # very last + self._memory_tracker.stop_and_update_metrics() + + # torch.compile + if args.torch_compile and not is_torch_compile_available(): + raise RuntimeError("Using torch.compile requires PyTorch 2.0 or higher.") + + def add_callback(self, callback): + """ + Add a callback to the current list of [`~transformer.TrainerCallback`]. + + Args: + callback (`type` or [`~transformer.TrainerCallback`]): + A [`~transformer.TrainerCallback`] class or an instance of a [`~transformer.TrainerCallback`]. In the + first case, will instantiate a member of that class. + """ + self.callback_handler.add_callback(callback) + + def pop_callback(self, callback): + """ + Remove a callback from the current list of [`~transformer.TrainerCallback`] and returns it. + + If the callback is not found, returns `None` (and no error is raised). + + Args: + callback (`type` or [`~transformer.TrainerCallback`]): + A [`~transformer.TrainerCallback`] class or an instance of a [`~transformer.TrainerCallback`]. In the + first case, will pop the first member of that class found in the list of callbacks. + + Returns: + [`~transformer.TrainerCallback`]: The callback removed, if found. + """ + return self.callback_handler.pop_callback(callback) + + def remove_callback(self, callback): + """ + Remove a callback from the current list of [`~transformer.TrainerCallback`]. + + Args: + callback (`type` or [`~transformer.TrainerCallback`]): + A [`~transformer.TrainerCallback`] class or an instance of a [`~transformer.TrainerCallback`]. In the + first case, will remove the first member of that class found in the list of callbacks. + """ + self.callback_handler.remove_callback(callback) + + def _move_model_to_device(self, model, device): + model = model.to(device) + # Moving a model to an XLA device disconnects the tied weights, so we have to retie them. + if self.args.parallel_mode == ParallelMode.TPU and hasattr(model, "tie_weights"): + model.tie_weights() + + def _set_signature_columns_if_needed(self): + if self._signature_columns is None: + # Inspect model forward signature to keep only the arguments it accepts. + signature = inspect.signature(self.model.forward) + self._signature_columns = list(signature.parameters.keys()) + # Labels may be named label or label_ids, the default data collator handles that. + self._signature_columns += list(set(["label", "label_ids"] + self.label_names)) + + def _remove_unused_columns(self, dataset: "datasets.Dataset", description: Optional[str] = None): + if not self.args.remove_unused_columns: + return dataset + self._set_signature_columns_if_needed() + signature_columns = self._signature_columns + + ignored_columns = list(set(dataset.column_names) - set(signature_columns)) + if len(ignored_columns) > 0: + dset_description = "" if description is None else f"in the {description} set" + logger.info( + f"The following columns {dset_description} don't have a corresponding argument in " + f"`{self.model.__class__.__name__}.forward` and have been ignored: {', '.join(ignored_columns)}." + f" If {', '.join(ignored_columns)} are not expected by `{self.model.__class__.__name__}.forward`, " + " you can safely ignore this message." + ) + + columns = [k for k in signature_columns if k in dataset.column_names] + + if version.parse(datasets.__version__) < version.parse("1.4.0"): + dataset.set_format( + type=dataset.format["type"], columns=columns, format_kwargs=dataset.format["format_kwargs"] + ) + return dataset + else: + return dataset.remove_columns(ignored_columns) + + def _get_collator_with_removed_columns( + self, data_collator: Callable, description: Optional[str] = None + ) -> Callable: + """Wrap the data collator in a callable removing unused columns.""" + if not self.args.remove_unused_columns: + return data_collator + self._set_signature_columns_if_needed() + signature_columns = self._signature_columns + + remove_columns_collator = RemoveColumnsCollator( + data_collator=data_collator, + signature_columns=signature_columns, + logger=logger, + description=description, + model_name=self.model.__class__.__name__, + ) + return remove_columns_collator + + def _get_train_sampler(self) -> Optional[torch.utils.data.Sampler]: + if self.train_dataset is None or not has_length(self.train_dataset): + return None + + generator = None + if self.args.world_size <= 1: + generator = torch.Generator() + # for backwards compatibility, we generate a seed here (which is sampled from a generator seeded with + # `args.seed`) if data_seed isn't provided. + # Further on in this method, we default to `args.seed` instead. + if self.args.data_seed is None: + seed = int(torch.empty((), dtype=torch.int64).random_().item()) + else: + seed = self.args.data_seed + generator.manual_seed(seed) + + seed = self.args.data_seed if self.args.data_seed is not None else self.args.seed + + # Build the sampler. + if self.args.group_by_length: + if is_datasets_available() and isinstance(self.train_dataset, datasets.Dataset): + lengths = ( + self.train_dataset[self.args.length_column_name] + if self.args.length_column_name in self.train_dataset.column_names + else None + ) + else: + lengths = None + model_input_name = self.tokenizer.model_input_names[0] if self.tokenizer is not None else None + if self.args.world_size <= 1: + return LengthGroupedSampler( + self.args.train_batch_size * self.args.gradient_accumulation_steps, + dataset=self.train_dataset, + lengths=lengths, + model_input_name=model_input_name, + generator=generator, + ) + else: + return DistributedLengthGroupedSampler( + self.args.train_batch_size * self.args.gradient_accumulation_steps, + dataset=self.train_dataset, + num_replicas=self.args.world_size, + rank=self.args.process_index, + lengths=lengths, + model_input_name=model_input_name, + seed=seed, + ) + + else: + if self.args.world_size <= 1: + return RandomSampler(self.train_dataset, generator=generator) + elif ( + self.args.parallel_mode in [ParallelMode.TPU, ParallelMode.SAGEMAKER_MODEL_PARALLEL] + and not self.args.dataloader_drop_last + ): + # Use a loop for TPUs when drop_last is False to have all batches have the same size. + return DistributedSamplerWithLoop( + self.train_dataset, + batch_size=self.args.per_device_train_batch_size, + num_replicas=self.args.world_size, + rank=self.args.process_index, + seed=seed, + ) + else: + return DistributedSampler( + self.train_dataset, + num_replicas=self.args.world_size, + rank=self.args.process_index, + seed=seed, + ) + + def get_train_dataloader(self) -> DataLoader: + """ + Returns the training [`~torch.utils.data.DataLoader`]. + + Will use no sampler if `train_dataset` does not implement `__len__`, a random sampler (adapted to distributed + training if necessary) otherwise. + + Subclass and override this method if you want to inject some custom behavior. + """ + if self.train_dataset is None: + raise ValueError("Trainer: training requires a train_dataset.") + + train_dataset = self.train_dataset + data_collator = self.data_collator + if is_datasets_available() and isinstance(train_dataset, datasets.Dataset): + train_dataset = self._remove_unused_columns(train_dataset, description="training") + else: + data_collator = self._get_collator_with_removed_columns(data_collator, description="training") + + if isinstance(train_dataset, torch.utils.data.IterableDataset): + if self.args.world_size > 1: + train_dataset = IterableDatasetShard( + train_dataset, + batch_size=self._train_batch_size, + drop_last=self.args.dataloader_drop_last, + num_processes=self.args.world_size, + process_index=self.args.process_index, + ) + + return DataLoader( + train_dataset, + batch_size=self._train_batch_size, + collate_fn=data_collator, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + + train_sampler = self._get_train_sampler() + + return DataLoader( + train_dataset, + batch_size=self._train_batch_size, + sampler=train_sampler, + collate_fn=data_collator, + drop_last=self.args.dataloader_drop_last, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + worker_init_fn=seed_worker, + ) + + def _get_eval_sampler(self, eval_dataset: Dataset) -> Optional[torch.utils.data.Sampler]: + # Deprecated code + if self.args.use_legacy_prediction_loop: + if is_torch_tpu_available(): + return SequentialDistributedSampler( + eval_dataset, num_replicas=xm.xrt_world_size(), rank=xm.get_ordinal() + ) + elif is_sagemaker_mp_enabled(): + return SequentialDistributedSampler( + eval_dataset, + num_replicas=smp.dp_size(), + rank=smp.dp_rank(), + batch_size=self.args.per_device_eval_batch_size, + ) + elif self.args.parallel_mode == ParallelMode.DISTRIBUTED: + return SequentialDistributedSampler(eval_dataset) + else: + return SequentialSampler(eval_dataset) + + if self.args.world_size <= 1: + return SequentialSampler(eval_dataset) + else: + return ShardSampler( + eval_dataset, + batch_size=self.args.per_device_eval_batch_size, + num_processes=self.args.world_size, + process_index=self.args.process_index, + ) + + def get_eval_dataloader(self, eval_dataset: Optional[Dataset] = None) -> DataLoader: + """ + Returns the evaluation [`~torch.utils.data.DataLoader`]. + + Subclass and override this method if you want to inject some custom behavior. + + Args: + eval_dataset (`torch.utils.data.Dataset`, *optional*): + If provided, will override `self.eval_dataset`. If it is a [`~datasets.Dataset`], columns not accepted + by the `model.forward()` method are automatically removed. It must implement `__len__`. + """ + if eval_dataset is None and self.eval_dataset is None: + raise ValueError("Trainer: evaluation requires an eval_dataset.") + eval_dataset = eval_dataset if eval_dataset is not None else self.eval_dataset + data_collator = self.data_collator + + if is_datasets_available() and isinstance(eval_dataset, datasets.Dataset): + eval_dataset = self._remove_unused_columns(eval_dataset, description="evaluation") + else: + data_collator = self._get_collator_with_removed_columns(data_collator, description="evaluation") + + if isinstance(eval_dataset, torch.utils.data.IterableDataset): + if self.args.world_size > 1: + eval_dataset = IterableDatasetShard( + eval_dataset, + batch_size=self.args.per_device_eval_batch_size, + drop_last=self.args.dataloader_drop_last, + num_processes=self.args.world_size, + process_index=self.args.process_index, + ) + return DataLoader( + eval_dataset, + batch_size=self.args.eval_batch_size, + collate_fn=data_collator, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + + eval_sampler = self._get_eval_sampler(eval_dataset) + + return DataLoader( + eval_dataset, + sampler=eval_sampler, + batch_size=self.args.eval_batch_size, + collate_fn=data_collator, + drop_last=self.args.dataloader_drop_last, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + + def get_test_dataloader(self, test_dataset: Dataset) -> DataLoader: + """ + Returns the test [`~torch.utils.data.DataLoader`]. + + Subclass and override this method if you want to inject some custom behavior. + + Args: + test_dataset (`torch.utils.data.Dataset`, *optional*): + The test dataset to use. If it is a [`~datasets.Dataset`], columns not accepted by the + `model.forward()` method are automatically removed. It must implement `__len__`. + """ + data_collator = self.data_collator + + if is_datasets_available() and isinstance(test_dataset, datasets.Dataset): + test_dataset = self._remove_unused_columns(test_dataset, description="test") + else: + data_collator = self._get_collator_with_removed_columns(data_collator, description="test") + + if isinstance(test_dataset, torch.utils.data.IterableDataset): + if self.args.world_size > 1: + test_dataset = IterableDatasetShard( + test_dataset, + batch_size=self.args.eval_batch_size, + drop_last=self.args.dataloader_drop_last, + num_processes=self.args.world_size, + process_index=self.args.process_index, + ) + return DataLoader( + test_dataset, + batch_size=self.args.eval_batch_size, + collate_fn=data_collator, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + + test_sampler = self._get_eval_sampler(test_dataset) + + # We use the same batch_size as for eval. + return DataLoader( + test_dataset, + sampler=test_sampler, + batch_size=self.args.eval_batch_size, + collate_fn=data_collator, + drop_last=self.args.dataloader_drop_last, + num_workers=self.args.dataloader_num_workers, + pin_memory=self.args.dataloader_pin_memory, + ) + + def create_optimizer_and_scheduler(self, num_training_steps: int): + """ + Setup the optimizer and the learning rate scheduler. + + We provide a reasonable default that works well. If you want to use something else, you can pass a tuple in the + Trainer's init through `optimizers`, or subclass and override this method (or `create_optimizer` and/or + `create_scheduler`) in a subclass. + """ + self.create_optimizer() + if IS_SAGEMAKER_MP_POST_1_10 and smp.state.cfg.fp16: + # If smp >= 1.10 and fp16 is enabled, we unwrap the optimizer + optimizer = self.optimizer.optimizer + else: + optimizer = self.optimizer + self.create_scheduler(num_training_steps=num_training_steps, optimizer=optimizer) + + def create_optimizer(self): + """ + Setup the optimizer. + + We provide a reasonable default that works well. If you want to use something else, you can pass a tuple in the + Trainer's init through `optimizers`, or subclass and override this method in a subclass. + """ + opt_model = self.model_wrapped if is_sagemaker_mp_enabled() else self.model + + if self.optimizer is None: + decay_parameters = get_parameter_names(opt_model, ALL_LAYERNORM_LAYERS) + decay_parameters = [name for name in decay_parameters if "bias" not in name] + optimizer_grouped_parameters = [ + { + "params": [ + p for n, p in opt_model.named_parameters() if (n in decay_parameters and p.requires_grad) + ], + "weight_decay": self.args.weight_decay, + }, + { + "params": [ + p for n, p in opt_model.named_parameters() if (n not in decay_parameters and p.requires_grad) + ], + "weight_decay": 0.0, + }, + ] + + optimizer_cls, optimizer_kwargs = Trainer.get_optimizer_cls_and_kwargs(self.args) + + if self.sharded_ddp == ShardedDDPOption.SIMPLE: + self.optimizer = OSS( + params=optimizer_grouped_parameters, + optim=optimizer_cls, + **optimizer_kwargs, + ) + else: + self.optimizer = optimizer_cls(optimizer_grouped_parameters, **optimizer_kwargs) + if optimizer_cls.__name__ == "Adam8bit": + import bitsandbytes + + manager = bitsandbytes.optim.GlobalOptimManager.get_instance() + + skipped = 0 + for module in opt_model.modules(): + if isinstance(module, nn.Embedding): + skipped += sum({p.data_ptr(): p.numel() for p in module.parameters()}.values()) + print(f"skipped {module}: {skipped/2**20}M params") + manager.register_module_override(module, "weight", {"optim_bits": 32}) + logger.debug(f"bitsandbytes: will optimize {module} in fp32") + print(f"skipped: {skipped/2**20}M params") + + if is_sagemaker_mp_enabled(): + self.optimizer = smp.DistributedOptimizer(self.optimizer) + + return self.optimizer + + @staticmethod + def get_optimizer_cls_and_kwargs(args: TrainingArguments) -> Tuple[Any, Any]: + """ + Returns the optimizer class and optimizer parameters based on the training arguments. + + Args: + args (`transformers.training_args.TrainingArguments`): + The training arguments for the training session. + + """ + + # parse args.optim_args + optim_args = {} + if args.optim_args: + for mapping in args.optim_args.replace(" ", "").split(","): + key, value = mapping.split("=") + optim_args[key] = value + + optimizer_kwargs = {"lr": args.learning_rate} + + adam_kwargs = { + "betas": (args.adam_beta1, args.adam_beta2), + "eps": args.adam_epsilon, + } + if args.optim == OptimizerNames.ADAFACTOR: + optimizer_cls = Adafactor + optimizer_kwargs.update({"scale_parameter": False, "relative_step": False}) + elif args.optim == OptimizerNames.ADAMW_HF: + from .optimization import AdamW + + optimizer_cls = AdamW + optimizer_kwargs.update(adam_kwargs) + elif args.optim in [OptimizerNames.ADAMW_TORCH, OptimizerNames.ADAMW_TORCH_FUSED]: + from torch.optim import AdamW + + optimizer_cls = AdamW + optimizer_kwargs.update(adam_kwargs) + if args.optim == OptimizerNames.ADAMW_TORCH_FUSED: + optimizer_kwargs.update({"fused": True}) + elif args.optim == OptimizerNames.ADAMW_TORCH_XLA: + try: + from torch_xla.amp.syncfree import AdamW + + optimizer_cls = AdamW + optimizer_kwargs.update(adam_kwargs) + except ImportError: + raise ValueError("Trainer failed to import syncfree AdamW from torch_xla.") + elif args.optim == OptimizerNames.ADAMW_APEX_FUSED: + try: + from apex.optimizers import FusedAdam + + optimizer_cls = FusedAdam + optimizer_kwargs.update(adam_kwargs) + except ImportError: + raise ValueError("Trainer tried to instantiate apex FusedAdam but apex is not installed!") + elif args.optim == OptimizerNames.ADAMW_BNB: + try: + from bitsandbytes.optim import Adam8bit + + optimizer_cls = Adam8bit + optimizer_kwargs.update(adam_kwargs) + except ImportError: + raise ValueError("Trainer tried to instantiate bnb Adam8bit but bnb is not installed!") + elif args.optim == OptimizerNames.ADAMW_ANYPRECISION: + try: + from torchdistx.optimizers import AnyPrecisionAdamW + + optimizer_cls = AnyPrecisionAdamW + optimizer_kwargs.update(adam_kwargs) + + # TODO Change dtypes back to M=FP32, Var = BF16, Kahan = False once they can be cast together in torchdistx. + optimizer_kwargs.update( + { + "use_kahan_summation": strtobool(optim_args.get("use_kahan_summation", "False")), + "momentum_dtype": getattr(torch, optim_args.get("momentum_dtype", "float32")), + "variance_dtype": getattr(torch, optim_args.get("variance_dtype", "float32")), + "compensation_buffer_dtype": getattr( + torch, optim_args.get("compensation_buffer_dtype", "bfloat16") + ), + } + ) + except ImportError: + raise ValueError("Please install https://github.com/pytorch/torchdistx") + elif args.optim == OptimizerNames.SGD: + optimizer_cls = torch.optim.SGD + elif args.optim == OptimizerNames.ADAGRAD: + optimizer_cls = torch.optim.Adagrad + else: + raise ValueError(f"Trainer cannot instantiate unsupported optimizer: {args.optim}") + return optimizer_cls, optimizer_kwargs + + def create_scheduler(self, num_training_steps: int, optimizer: torch.optim.Optimizer = None): + """ + Setup the scheduler. The optimizer of the trainer must have been set up either before this method is called or + passed as an argument. + + Args: + num_training_steps (int): The number of training steps to do. + """ + if self.lr_scheduler is None: + self.lr_scheduler = get_scheduler( + self.args.lr_scheduler_type, + optimizer=self.optimizer if optimizer is None else optimizer, + num_warmup_steps=self.args.get_warmup_steps(num_training_steps), + num_training_steps=num_training_steps, + ) + return self.lr_scheduler + + def num_examples(self, dataloader: DataLoader) -> int: + """ + Helper to get number of samples in a [`~torch.utils.data.DataLoader`] by accessing its dataset. When + dataloader.dataset does not exist or has no length, estimates as best it can + """ + try: + dataset = dataloader.dataset + # Special case for IterableDatasetShard, we need to dig deeper + if isinstance(dataset, IterableDatasetShard): + return len(dataloader.dataset.dataset) + return len(dataloader.dataset) + except (NameError, AttributeError, TypeError): # no dataset or length, estimate by length of dataloader + return len(dataloader) * self.args.per_device_train_batch_size + + def _hp_search_setup(self, trial: Union["optuna.Trial", Dict[str, Any]]): + """HP search setup code""" + self._trial = trial + + if self.hp_search_backend is None or trial is None: + return + if self.hp_search_backend == HPSearchBackend.OPTUNA: + params = self.hp_space(trial) + elif self.hp_search_backend == HPSearchBackend.RAY: + params = trial + params.pop("wandb", None) + elif self.hp_search_backend == HPSearchBackend.SIGOPT: + params = {k: int(v) if isinstance(v, str) else v for k, v in trial.assignments.items()} + elif self.hp_search_backend == HPSearchBackend.WANDB: + params = trial + + for key, value in params.items(): + if not hasattr(self.args, key): + logger.warning( + f"Trying to set {key} in the hyperparameter search but there is no corresponding field in" + " `TrainingArguments`." + ) + continue + old_attr = getattr(self.args, key, None) + # Casting value to the proper type + if old_attr is not None: + value = type(old_attr)(value) + setattr(self.args, key, value) + if self.hp_search_backend == HPSearchBackend.OPTUNA: + logger.info(f"Trial: {trial.params}") + if self.hp_search_backend == HPSearchBackend.SIGOPT: + logger.info(f"SigOpt Assignments: {trial.assignments}") + if self.hp_search_backend == HPSearchBackend.WANDB: + logger.info(f"W&B Sweep parameters: {trial}") + if self.args.deepspeed: + # Rebuild the deepspeed config to reflect the updated training parameters + from transformers.deepspeed import HfTrainerDeepSpeedConfig + + self.args.hf_deepspeed_config = HfTrainerDeepSpeedConfig(self.args.deepspeed) + self.args.hf_deepspeed_config.trainer_config_process(self.args) + + def _report_to_hp_search(self, trial: Union["optuna.Trial", Dict[str, Any]], step: int, metrics: Dict[str, float]): + if self.hp_search_backend is None or trial is None: + return + self.objective = self.compute_objective(metrics.copy()) + if self.hp_search_backend == HPSearchBackend.OPTUNA: + import optuna + + trial.report(self.objective, step) + if trial.should_prune(): + self.callback_handler.on_train_end(self.args, self.state, self.control) + raise optuna.TrialPruned() + elif self.hp_search_backend == HPSearchBackend.RAY: + from ray import tune + + if self.control.should_save: + self._tune_save_checkpoint() + tune.report(objective=self.objective, **metrics) + + def _tune_save_checkpoint(self): + from ray import tune + + if not self.use_tune_checkpoints: + return + with tune.checkpoint_dir(step=self.state.global_step) as checkpoint_dir: + output_dir = os.path.join(checkpoint_dir, f"{PREFIX_CHECKPOINT_DIR}-{self.state.global_step}") + self.save_model(output_dir, _internal_call=True) + if self.args.should_save: + self.state.save_to_json(os.path.join(output_dir, TRAINER_STATE_NAME)) + torch.save(self.optimizer.state_dict(), os.path.join(output_dir, OPTIMIZER_NAME)) + torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, SCHEDULER_NAME)) + + def call_model_init(self, trial=None): + model_init_argcount = number_of_arguments(self.model_init) + if model_init_argcount == 0: + model = self.model_init() + elif model_init_argcount == 1: + model = self.model_init(trial) + else: + raise RuntimeError("model_init should have 0 or 1 argument.") + + if model is None: + raise RuntimeError("model_init should not return None.") + + return model + + def torch_jit_model_eval(self, model, dataloader, training=False): + if not training: + if dataloader is None: + logger.warning("failed to use PyTorch jit mode due to current dataloader is none.") + return model + example_batch = next(iter(dataloader)) + example_batch = self._prepare_inputs(example_batch) + try: + jit_model = model.eval() + with ContextManagers([self.autocast_smart_context_manager(cache_enabled=False), torch.no_grad()]): + if version.parse(version.parse(torch.__version__).base_version) >= version.parse("1.14.0"): + if isinstance(example_batch, dict): + jit_model = torch.jit.trace(jit_model, example_kwarg_inputs=example_batch, strict=False) + else: + jit_model = torch.jit.trace( + jit_model, + example_kwarg_inputs={key: example_batch[key] for key in example_batch}, + strict=False, + ) + else: + jit_inputs = [] + for key in example_batch: + example_tensor = torch.ones_like(example_batch[key]) + jit_inputs.append(example_tensor) + jit_inputs = tuple(jit_inputs) + jit_model = torch.jit.trace(jit_model, jit_inputs, strict=False) + jit_model = torch.jit.freeze(jit_model) + with torch.no_grad(): + jit_model(**example_batch) + jit_model(**example_batch) + model = jit_model + self.use_cpu_amp = False + self.use_cuda_amp = False + except (RuntimeError, TypeError, ValueError, NameError, IndexError) as e: + logger.warning(f"failed to use PyTorch jit mode due to: {e}.") + + return model + + def ipex_optimize_model(self, model, training=False, dtype=torch.float32): + if not is_ipex_available(): + raise ImportError( + "Using IPEX but IPEX is not installed or IPEX's version does not match current PyTorch, please refer" + " to https://github.com/intel/intel-extension-for-pytorch." + ) + + import intel_extension_for_pytorch as ipex + + if not training: + model.eval() + dtype = torch.bfloat16 if not self.is_in_train and self.args.bf16_full_eval else dtype + # conv_bn_folding is disabled as it fails in symbolic tracing, resulting in ipex warnings + model = ipex.optimize(model, dtype=dtype, level="O1", conv_bn_folding=False, inplace=not self.is_in_train) + else: + if not model.training: + model.train() + model, self.optimizer = ipex.optimize( + model, dtype=dtype, optimizer=self.optimizer, inplace=True, level="O1" + ) + + return model + + def _wrap_model(self, model, training=True, dataloader=None): + if self.args.use_ipex: + dtype = torch.bfloat16 if self.use_cpu_amp else torch.float32 + model = self.ipex_optimize_model(model, training, dtype=dtype) + + if is_sagemaker_mp_enabled(): + # Wrapping the base model twice in a DistributedModel will raise an error. + if isinstance(self.model_wrapped, smp.model.DistributedModel): + return self.model_wrapped + return smp.DistributedModel(model, backward_passes_per_step=self.args.gradient_accumulation_steps) + + # already initialized its own DDP and AMP + if self.deepspeed: + return self.deepspeed + + # train/eval could be run multiple-times - if already wrapped, don't re-wrap it again + if unwrap_model(model) is not model: + return model + + # Mixed precision training with apex (torch < 1.6) + if self.use_apex and training: + model, self.optimizer = amp.initialize(model, self.optimizer, opt_level=self.args.fp16_opt_level) + + # Multi-gpu training (should be after apex fp16 initialization) / 8bit models does not support DDP + if self.args.n_gpu > 1 and not getattr(model, "is_loaded_in_8bit", False): + model = nn.DataParallel(model) + + if self.args.jit_mode_eval: + start_time = time.time() + model = self.torch_jit_model_eval(model, dataloader, training) + self.jit_compilation_time = round(time.time() - start_time, 4) + + # Note: in torch.distributed mode, there's no point in wrapping the model + # inside a DistributedDataParallel as we'll be under `no_grad` anyways. + if not training: + return model + + # Distributed training (should be after apex fp16 initialization) + if self.sharded_ddp is not None: + # Sharded DDP! + if self.sharded_ddp == ShardedDDPOption.SIMPLE: + model = ShardedDDP(model, self.optimizer) + else: + mixed_precision = self.args.fp16 or self.args.bf16 + cpu_offload = ShardedDDPOption.OFFLOAD in self.args.sharded_ddp + zero_3 = self.sharded_ddp == ShardedDDPOption.ZERO_DP_3 + # XXX: Breaking the self.model convention but I see no way around it for now. + if ShardedDDPOption.AUTO_WRAP in self.args.sharded_ddp: + model = auto_wrap(model) + self.model = model = FullyShardedDDP( + model, + mixed_precision=mixed_precision, + reshard_after_forward=zero_3, + cpu_offload=cpu_offload, + ).to(self.args.device) + # Distributed training using PyTorch FSDP + elif self.fsdp is not None: + if not self.args.fsdp_config["xla"]: + # PyTorch FSDP! + from torch.distributed.fsdp.fully_sharded_data_parallel import CPUOffload, MixedPrecision + from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP + from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy, transformer_auto_wrap_policy + + if FSDPOption.OFFLOAD in self.args.fsdp: + cpu_offload = CPUOffload(offload_params=True) + else: + cpu_offload = CPUOffload(offload_params=False) + + auto_wrap_policy = None + + if FSDPOption.AUTO_WRAP in self.args.fsdp: + if self.args.fsdp_config["fsdp_min_num_params"] > 0: + auto_wrap_policy = functools.partial( + size_based_auto_wrap_policy, min_num_params=self.args.fsdp_config["fsdp_min_num_params"] + ) + elif self.args.fsdp_config.get("fsdp_transformer_layer_cls_to_wrap", None) is not None: + transformer_cls_to_wrap = set() + for layer_class in self.args.fsdp_config["fsdp_transformer_layer_cls_to_wrap"]: + transformer_cls = get_module_class_from_name(model, layer_class) + if transformer_cls is None: + raise Exception("Could not find the transformer layer class to wrap in the model.") + else: + transformer_cls_to_wrap.add(transformer_cls) + auto_wrap_policy = functools.partial( + transformer_auto_wrap_policy, + # Transformer layer class to wrap + transformer_layer_cls=transformer_cls_to_wrap, + ) + mixed_precision_policy = None + dtype = None + if self.args.fp16: + dtype = torch.float16 + elif self.args.bf16: + dtype = torch.bfloat16 + if dtype is not None: + mixed_precision_policy = MixedPrecision(param_dtype=dtype, reduce_dtype=dtype, buffer_dtype=dtype) + if type(model) != FSDP: + # XXX: Breaking the self.model convention but I see no way around it for now. + signature = inspect.signature(FSDP.__init__).parameters.keys() + kwargs = {} + for arg in ["limit_all_gathers", "forward_prefetch", "backward_prefetch"]: + if arg in signature: + kwargs[arg] = getattr(self, arg) + self.model = model = FSDP( + model, + sharding_strategy=self.fsdp, + cpu_offload=cpu_offload, + auto_wrap_policy=auto_wrap_policy, + mixed_precision=mixed_precision_policy, + device_id=self.args.device, + **kwargs, + ) + else: + try: + from torch_xla.distributed.fsdp import XlaFullyShardedDataParallel as FSDP + from torch_xla.distributed.fsdp import checkpoint_module + from torch_xla.distributed.fsdp.wrap import ( + size_based_auto_wrap_policy, + transformer_auto_wrap_policy, + ) + except ImportError: + raise ImportError("Missing XLA FSDP related module; please make sure to use torch-xla >= 2.0.") + auto_wrap_policy = None + auto_wrapper_callable = None + if self.args.fsdp_config["fsdp_min_num_params"] > 0: + auto_wrap_policy = functools.partial( + size_based_auto_wrap_policy, min_num_params=self.args.fsdp_config["fsdp_min_num_params"] + ) + elif self.args.fsdp_config.get("fsdp_transformer_layer_cls_to_wrap", None) is not None: + transformer_cls_to_wrap = set() + for layer_class in self.args.fsdp_config["fsdp_transformer_layer_cls_to_wrap"]: + transformer_cls = get_module_class_from_name(model, layer_class) + if transformer_cls is None: + raise Exception("Could not find the transformer layer class to wrap in the model.") + else: + transformer_cls_to_wrap.add(transformer_cls) + auto_wrap_policy = functools.partial( + transformer_auto_wrap_policy, + # Transformer layer class to wrap + transformer_layer_cls=transformer_cls_to_wrap, + ) + fsdp_kwargs = self.args.xla_fsdp_config + if self.args.fsdp_config["xla_fsdp_grad_ckpt"]: + # Apply gradient checkpointing to auto-wrapped sub-modules if specified + def auto_wrapper_callable(m, *args, **kwargs): + return FSDP(checkpoint_module(m), *args, **kwargs) + + # Wrap the base model with an outer FSDP wrapper + self.model = model = FSDP( + model, + auto_wrap_policy=auto_wrap_policy, + auto_wrapper_callable=auto_wrapper_callable, + **fsdp_kwargs, + ) + + # Patch `xm.optimizer_step` should not reduce gradients in this case, + # as FSDP does not need gradient reduction over sharded parameters. + def patched_optimizer_step(optimizer, barrier=False, optimizer_args={}): + loss = optimizer.step(**optimizer_args) + if barrier: + xm.mark_step() + return loss + + xm.optimizer_step = patched_optimizer_step + elif is_sagemaker_dp_enabled(): + model = nn.parallel.DistributedDataParallel( + model, device_ids=[int(os.getenv("SMDATAPARALLEL_LOCAL_RANK"))] + ) + elif self.args.parallel_mode == ParallelMode.DISTRIBUTED: + kwargs = {} + if self.args.ddp_find_unused_parameters is not None: + kwargs["find_unused_parameters"] = self.args.ddp_find_unused_parameters + elif isinstance(model, PreTrainedModel): + # find_unused_parameters breaks checkpointing as per + # https://github.com/huggingface/transformers/pull/4659#issuecomment-643356021 + kwargs["find_unused_parameters"] = not model.is_gradient_checkpointing + else: + kwargs["find_unused_parameters"] = True + + if self.args.ddp_bucket_cap_mb is not None: + kwargs["bucket_cap_mb"] = self.args.ddp_bucket_cap_mb + if is_torch_neuroncore_available(): + return model + if any(p.requires_grad for p in model.parameters()): + model = nn.parallel.DistributedDataParallel( + model, + device_ids=[self.args.local_rank] if self.args._n_gpu != 0 else None, + output_device=self.args.local_rank if self.args._n_gpu != 0 else None, + **kwargs, + ) + + # torch.compile() needs to be called after wrapping the model with FSDP or DDP + # to ensure that it accounts for the graph breaks required by those wrappers + if self.args.torch_compile: + model = torch.compile(model, backend=self.args.torch_compile_backend, mode=self.args.torch_compile_mode) + + return model + + def train( + self, + resume_from_checkpoint: Optional[Union[str, bool]] = None, + trial: Union["optuna.Trial", Dict[str, Any]] = None, + ignore_keys_for_eval: Optional[List[str]] = None, + **kwargs, + ): + """ + Main training entry point. + + Args: + resume_from_checkpoint (`str` or `bool`, *optional*): + If a `str`, local path to a saved checkpoint as saved by a previous instance of [`Trainer`]. If a + `bool` and equals `True`, load the last checkpoint in *args.output_dir* as saved by a previous instance + of [`Trainer`]. If present, training will resume from the model/optimizer/scheduler states loaded here. + trial (`optuna.Trial` or `Dict[str, Any]`, *optional*): + The trial run or the hyperparameter dictionary for hyperparameter search. + ignore_keys_for_eval (`List[str]`, *optional*) + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions for evaluation during the training. + kwargs: + Additional keyword arguments used to hide deprecated arguments + """ + if resume_from_checkpoint is False: + resume_from_checkpoint = None + + # memory metrics - must set up as early as possible + self._memory_tracker.start() + + args = self.args + + self.is_in_train = True + + # do_train is not a reliable argument, as it might not be set and .train() still called, so + # the following is a workaround: + if (args.fp16_full_eval or args.bf16_full_eval) and not args.do_train: + self._move_model_to_device(self.model, args.device) + + if "model_path" in kwargs: + resume_from_checkpoint = kwargs.pop("model_path") + warnings.warn( + "`model_path` is deprecated and will be removed in a future version. Use `resume_from_checkpoint` " + "instead.", + FutureWarning, + ) + if len(kwargs) > 0: + raise TypeError(f"train() received got unexpected keyword arguments: {', '.join(list(kwargs.keys()))}.") + # This might change the seed so needs to run first. + self._hp_search_setup(trial) + self._train_batch_size = self.args.train_batch_size + + # Model re-init + model_reloaded = False + if self.model_init is not None: + # Seed must be set before instantiating the model when using model_init. + enable_full_determinism(self.args.seed) if self.args.full_determinism else set_seed(self.args.seed) + self.model = self.call_model_init(trial) + model_reloaded = True + # Reinitializes optimizer and scheduler + self.optimizer, self.lr_scheduler = None, None + + # Load potential model checkpoint + if isinstance(resume_from_checkpoint, bool) and resume_from_checkpoint: + resume_from_checkpoint = get_last_checkpoint(args.output_dir) + if resume_from_checkpoint is None: + raise ValueError(f"No valid checkpoint found in output directory ({args.output_dir})") + + if resume_from_checkpoint is not None and not is_sagemaker_mp_enabled() and args.deepspeed is None: + self._load_from_checkpoint(resume_from_checkpoint) + + # If model was re-initialized, put it on the right device and update self.model_wrapped + if model_reloaded: + if self.place_model_on_device: + self._move_model_to_device(self.model, args.device) + self.model_wrapped = self.model + + inner_training_loop = find_executable_batch_size( + self._inner_training_loop, self._train_batch_size, args.auto_find_batch_size + ) + return inner_training_loop( + args=args, + resume_from_checkpoint=resume_from_checkpoint, + trial=trial, + ignore_keys_for_eval=ignore_keys_for_eval, + ) + + def _inner_training_loop( + self, batch_size=None, args=None, resume_from_checkpoint=None, trial=None, ignore_keys_for_eval=None + ): + self._train_batch_size = batch_size + # Data loader and number of training steps + train_dataloader = self.get_train_dataloader() + + # Setting up training control variables: + # number of training epochs: num_train_epochs + # number of training steps per epoch: num_update_steps_per_epoch + # total number of training steps to execute: max_steps + total_train_batch_size = args.train_batch_size * args.gradient_accumulation_steps * args.world_size + + len_dataloader = None + if has_length(train_dataloader): + len_dataloader = len(train_dataloader) + num_update_steps_per_epoch = len_dataloader // args.gradient_accumulation_steps + num_update_steps_per_epoch = max(num_update_steps_per_epoch, 1) + num_examples = self.num_examples(train_dataloader) + if args.max_steps > 0: + max_steps = args.max_steps + num_train_epochs = args.max_steps // num_update_steps_per_epoch + int( + args.max_steps % num_update_steps_per_epoch > 0 + ) + # May be slightly incorrect if the last batch in the training dataloader has a smaller size but it's + # the best we can do. + num_train_samples = args.max_steps * total_train_batch_size + else: + max_steps = math.ceil(args.num_train_epochs * num_update_steps_per_epoch) + num_train_epochs = math.ceil(args.num_train_epochs) + num_train_samples = self.num_examples(train_dataloader) * args.num_train_epochs + elif args.max_steps > 0: # Rely on max_steps when dataloader does not have a working size + max_steps = args.max_steps + # Setting a very large number of epochs so we go as many times as necessary over the iterator. + num_train_epochs = sys.maxsize + num_update_steps_per_epoch = max_steps + num_examples = total_train_batch_size * args.max_steps + num_train_samples = args.max_steps * total_train_batch_size + else: + raise ValueError( + "args.max_steps must be set to a positive value if dataloader does not have a length, was" + f" {args.max_steps}" + ) + + # Compute absolute values for logging, eval, and save if given as ratio + if args.logging_steps and args.logging_steps < 1: + args.logging_steps = math.ceil(max_steps * args.logging_steps) + if args.eval_steps and args.eval_steps < 1: + args.eval_steps = math.ceil(max_steps * args.eval_steps) + if args.save_steps and args.save_steps < 1: + args.save_steps = math.ceil(max_steps * args.save_steps) + + if DebugOption.UNDERFLOW_OVERFLOW in self.args.debug: + if self.args.n_gpu > 1: + # nn.DataParallel(model) replicates the model, creating new variables and module + # references registered here no longer work on other gpus, breaking the module + raise ValueError( + "Currently --debug underflow_overflow is not supported under DP. Please use DDP" + " (torch.distributed.launch)." + ) + else: + debug_overflow = DebugUnderflowOverflow(self.model) # noqa + + delay_optimizer_creation = ( + self.sharded_ddp is not None + and self.sharded_ddp != ShardedDDPOption.SIMPLE + or is_sagemaker_mp_enabled() + or self.fsdp is not None + ) + if args.deepspeed: + deepspeed_engine, optimizer, lr_scheduler = deepspeed_init( + self, num_training_steps=max_steps, resume_from_checkpoint=resume_from_checkpoint + ) + self.model = deepspeed_engine.module + self.model_wrapped = deepspeed_engine + self.deepspeed = deepspeed_engine + self.optimizer = optimizer + self.lr_scheduler = lr_scheduler + elif not delay_optimizer_creation: + self.create_optimizer_and_scheduler(num_training_steps=max_steps) + + self.state = TrainerState() + self.state.is_hyper_param_search = trial is not None + + # Activate gradient checkpointing if needed + if args.gradient_checkpointing: + self.model.gradient_checkpointing_enable() + + model = self._wrap_model(self.model_wrapped) + + if is_sagemaker_mp_enabled() and resume_from_checkpoint is not None: + self._load_from_checkpoint(resume_from_checkpoint, model) + + # for the rest of this function `model` is the outside model, whether it was wrapped or not + if model is not self.model: + self.model_wrapped = model + + if delay_optimizer_creation: + self.create_optimizer_and_scheduler(num_training_steps=max_steps) + + # Check if saved optimizer or scheduler states exist + self._load_optimizer_and_scheduler(resume_from_checkpoint) + + # important: at this point: + # self.model is the Transformers Model + # self.model_wrapped is DDP(Transformers Model), Deepspeed(Transformers Model), etc. + + # Train! + logger.info("***** Running training *****") + logger.info(f" Num examples = {num_examples:,}") + logger.info(f" Num Epochs = {num_train_epochs:,}") + logger.info(f" Instantaneous batch size per device = {args.per_device_train_batch_size:,}") + logger.info(f" Total train batch size (w. parallel, distributed & accumulation) = {total_train_batch_size:,}") + logger.info(f" Gradient Accumulation steps = {args.gradient_accumulation_steps}") + logger.info(f" Total optimization steps = {max_steps:,}") + logger.info(f" Number of trainable parameters = {get_model_param_count(model, trainable_only=True):,}") + + self.state.epoch = 0 + start_time = time.time() + epochs_trained = 0 + steps_trained_in_current_epoch = 0 + steps_trained_progress_bar = None + + # Check if continuing training from a checkpoint + if resume_from_checkpoint is not None and os.path.isfile( + os.path.join(resume_from_checkpoint, TRAINER_STATE_NAME) + ): + self.state = TrainerState.load_from_json(os.path.join(resume_from_checkpoint, TRAINER_STATE_NAME)) + epochs_trained = self.state.global_step // num_update_steps_per_epoch + if not args.ignore_data_skip: + steps_trained_in_current_epoch = self.state.global_step % (num_update_steps_per_epoch) + steps_trained_in_current_epoch *= args.gradient_accumulation_steps + else: + steps_trained_in_current_epoch = 0 + + logger.info(" Continuing training from checkpoint, will skip to saved global_step") + logger.info(f" Continuing training from epoch {epochs_trained}") + logger.info(f" Continuing training from global step {self.state.global_step}") + if not args.ignore_data_skip: + if skip_first_batches is None: + logger.info( + f" Will skip the first {epochs_trained} epochs then the first" + f" {steps_trained_in_current_epoch} batches in the first epoch. If this takes a lot of time," + " you can install the latest version of Accelerate with `pip install -U accelerate`.You can" + " also add the `--ignore_data_skip` flag to your launch command, but you will resume the" + " training on data already seen by your model." + ) + else: + logger.info( + f" Will skip the first {epochs_trained} epochs then the first" + f" {steps_trained_in_current_epoch} batches in the first epoch." + ) + if self.is_local_process_zero() and not args.disable_tqdm and skip_first_batches is None: + steps_trained_progress_bar = tqdm(total=steps_trained_in_current_epoch) + steps_trained_progress_bar.set_description("Skipping the first batches") + + # Update the references + self.callback_handler.model = self.model + self.callback_handler.optimizer = self.optimizer + self.callback_handler.lr_scheduler = self.lr_scheduler + self.callback_handler.train_dataloader = train_dataloader + if self.hp_name is not None and self._trial is not None: + # use self._trial because the SigOpt/Optuna hpo only call `_hp_search_setup(trial)` instead of passing trial + # parameter to Train when using DDP. + self.state.trial_name = self.hp_name(self._trial) + if trial is not None: + assignments = trial.assignments if self.hp_search_backend == HPSearchBackend.SIGOPT else trial + self.state.trial_params = hp_params(assignments) + else: + self.state.trial_params = None + # This should be the same if the state has been saved but in case the training arguments changed, it's safer + # to set this after the load. + self.state.max_steps = max_steps + self.state.num_train_epochs = num_train_epochs + self.state.is_local_process_zero = self.is_local_process_zero() + self.state.is_world_process_zero = self.is_world_process_zero() + + # tr_loss is a tensor to avoid synchronization of TPUs through .item() + tr_loss = torch.tensor(0.0).to(args.device) + # _total_loss_scalar is updated everytime .item() has to be called on tr_loss and stores the sum of all losses + self._total_loss_scalar = 0.0 + self._globalstep_last_logged = self.state.global_step + model.zero_grad() + + self.control = self.callback_handler.on_train_begin(args, self.state, self.control) + + # Skip the first epochs_trained epochs to get the random state of the dataloader at the right point. + if not args.ignore_data_skip: + for epoch in range(epochs_trained): + is_random_sampler = hasattr(train_dataloader, "sampler") and isinstance( + train_dataloader.sampler, RandomSampler + ) + if is_torch_less_than_1_11 or not is_random_sampler: + # We just need to begin an iteration to create the randomization of the sampler. + # That was before PyTorch 1.11 however... + for _ in train_dataloader: + break + else: + # Otherwise we need to call the whooooole sampler cause there is some random operation added + # AT THE VERY END! + _ = list(train_dataloader.sampler) + + total_batched_samples = 0 + for epoch in range(epochs_trained, num_train_epochs): + if isinstance(train_dataloader, DataLoader) and isinstance(train_dataloader.sampler, DistributedSampler): + train_dataloader.sampler.set_epoch(epoch) + elif hasattr(train_dataloader, "dataset") and isinstance(train_dataloader.dataset, IterableDatasetShard): + train_dataloader.dataset.set_epoch(epoch) + + if is_torch_tpu_available(): + parallel_loader = pl.ParallelLoader(train_dataloader, [args.device]).per_device_loader(args.device) + epoch_iterator = parallel_loader + else: + epoch_iterator = train_dataloader + + # Reset the past mems state at the beginning of each epoch if necessary. + if args.past_index >= 0: + self._past = None + + steps_in_epoch = ( + len(epoch_iterator) + if len_dataloader is not None + else args.max_steps * args.gradient_accumulation_steps + ) + self.control = self.callback_handler.on_epoch_begin(args, self.state, self.control) + + if epoch == epochs_trained and resume_from_checkpoint is not None and steps_trained_in_current_epoch == 0: + self._load_rng_state(resume_from_checkpoint) + + rng_to_sync = False + steps_skipped = 0 + if skip_first_batches is not None and steps_trained_in_current_epoch > 0: + epoch_iterator = skip_first_batches(epoch_iterator, steps_trained_in_current_epoch) + steps_skipped = steps_trained_in_current_epoch + steps_trained_in_current_epoch = 0 + rng_to_sync = True + + step = -1 + for step, inputs in enumerate(epoch_iterator): + total_batched_samples += 1 + if rng_to_sync: + self._load_rng_state(resume_from_checkpoint) + rng_to_sync = False + + # Skip past any already trained steps if resuming training + if steps_trained_in_current_epoch > 0: + steps_trained_in_current_epoch -= 1 + if steps_trained_progress_bar is not None: + steps_trained_progress_bar.update(1) + if steps_trained_in_current_epoch == 0: + self._load_rng_state(resume_from_checkpoint) + continue + elif steps_trained_progress_bar is not None: + steps_trained_progress_bar.close() + steps_trained_progress_bar = None + + if step % args.gradient_accumulation_steps == 0: + self.control = self.callback_handler.on_step_begin(args, self.state, self.control) + + if ( + (total_batched_samples % args.gradient_accumulation_steps != 0) + and args.parallel_mode == ParallelMode.DISTRIBUTED + and args._no_sync_in_gradient_accumulation + and hasattr(model, "no_sync") + ): + # Avoid unnecessary DDP synchronization since there will be no backward pass on this example. + with model.no_sync(): + tr_loss_step = self.training_step(model, inputs) + else: + tr_loss_step = self.training_step(model, inputs) + + if ( + args.logging_nan_inf_filter + and not is_torch_tpu_available() + and (torch.isnan(tr_loss_step) or torch.isinf(tr_loss_step)) + ): + # if loss is nan or inf simply add the average of previous logged losses + tr_loss += tr_loss / (1 + self.state.global_step - self._globalstep_last_logged) + else: + tr_loss += tr_loss_step + + self.current_flos += float(self.floating_point_ops(inputs)) + + # Optimizer step for deepspeed must be called on every step regardless of the value of gradient_accumulation_steps + if self.deepspeed: + self.deepspeed.step() + + if total_batched_samples % args.gradient_accumulation_steps == 0 or ( + # last step in epoch but step is always smaller than gradient_accumulation_steps + steps_in_epoch <= args.gradient_accumulation_steps + and (step + 1) == steps_in_epoch + ): + # Gradient clipping + if args.max_grad_norm is not None and args.max_grad_norm > 0 and not self.deepspeed: + # deepspeed does its own clipping + + if self.do_grad_scaling: + # Reduce gradients first for XLA + if is_torch_tpu_available(): + gradients = xm._fetch_gradients(self.optimizer) + xm.all_reduce("sum", gradients, scale=1.0 / xm.xrt_world_size()) + # AMP: gradients need unscaling + self.scaler.unscale_(self.optimizer) + + if is_sagemaker_mp_enabled() and args.fp16: + self.optimizer.clip_master_grads(args.max_grad_norm) + elif hasattr(self.optimizer, "clip_grad_norm"): + # Some optimizers (like the sharded optimizer) have a specific way to do gradient clipping + self.optimizer.clip_grad_norm(args.max_grad_norm) + elif hasattr(model, "clip_grad_norm_"): + # Some models (like FullyShardedDDP) have a specific way to do gradient clipping + model.clip_grad_norm_(args.max_grad_norm) + else: + # Revert to normal clipping otherwise, handling Apex or full precision + nn.utils.clip_grad_norm_( + amp.master_params(self.optimizer) if self.use_apex else model.parameters(), + args.max_grad_norm, + ) + + # Optimizer step + optimizer_was_run = True + if self.deepspeed: + pass # called outside the loop + elif is_torch_tpu_available(): + if self.do_grad_scaling: + self.scaler.step(self.optimizer) + self.scaler.update() + else: + xm.optimizer_step(self.optimizer) + elif self.do_grad_scaling: + scale_before = self.scaler.get_scale() + self.scaler.step(self.optimizer) + self.scaler.update() + scale_after = self.scaler.get_scale() + optimizer_was_run = scale_before <= scale_after + else: + self.optimizer.step() + + if optimizer_was_run and not self.deepspeed: + # Delay optimizer scheduling until metrics are generated + if not isinstance(self.lr_scheduler, torch.optim.lr_scheduler.ReduceLROnPlateau): + self.lr_scheduler.step() + + model.zero_grad() + self.state.global_step += 1 + self.state.epoch = epoch + (step + 1 + steps_skipped) / steps_in_epoch + self.control = self.callback_handler.on_step_end(args, self.state, self.control) + + self._maybe_log_save_evaluate(tr_loss, model, trial, epoch, ignore_keys_for_eval) + else: + self.control = self.callback_handler.on_substep_end(args, self.state, self.control) + + if self.control.should_epoch_stop or self.control.should_training_stop: + break + if step < 0: + logger.warning( + "There seems to be not a single sample in your epoch_iterator, stopping training at step" + f" {self.state.global_step}! This is expected if you're using an IterableDataset and set" + f" num_steps ({max_steps}) higher than the number of available samples." + ) + self.control.should_training_stop = True + + self.control = self.callback_handler.on_epoch_end(args, self.state, self.control) + self._maybe_log_save_evaluate(tr_loss, model, trial, epoch, ignore_keys_for_eval) + + if DebugOption.TPU_METRICS_DEBUG in self.args.debug: + if is_torch_tpu_available(): + # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.) + xm.master_print(met.metrics_report()) + else: + logger.warning( + "You enabled PyTorch/XLA debug metrics but you don't have a TPU " + "configured. Check your training configuration if this is unexpected." + ) + if self.control.should_training_stop: + break + + if args.past_index and hasattr(self, "_past"): + # Clean the state at the end of training + delattr(self, "_past") + + logger.info("\n\nTraining completed. Do not forget to share your model on huggingface.co/models =)\n\n") + if args.load_best_model_at_end and self.state.best_model_checkpoint is not None: + # Wait for everyone to get here so we are sur the model has been saved by process 0. + if is_torch_tpu_available(): + xm.rendezvous("load_best_model_at_end") + elif args.parallel_mode == ParallelMode.DISTRIBUTED: + dist.barrier() + elif is_sagemaker_mp_enabled(): + smp.barrier() + + self._load_best_model() + + # add remaining tr_loss + self._total_loss_scalar += tr_loss.item() + train_loss = self._total_loss_scalar / self.state.global_step + + metrics = speed_metrics("train", start_time, num_samples=num_train_samples, num_steps=self.state.max_steps) + self.store_flos() + metrics["total_flos"] = self.state.total_flos + metrics["train_loss"] = train_loss + + self.is_in_train = False + + self._memory_tracker.stop_and_update_metrics(metrics) + + self.log(metrics) + + run_dir = self._get_output_dir(trial) + checkpoints_sorted = self._sorted_checkpoints(use_mtime=False, output_dir=run_dir) + + # Delete the last checkpoint when save_total_limit=1 if it's different from the best checkpoint and process allowed to save. + if self.args.should_save and self.state.best_model_checkpoint is not None and self.args.save_total_limit == 1: + for checkpoint in checkpoints_sorted: + if checkpoint != self.state.best_model_checkpoint: + logger.info(f"Deleting older checkpoint [{checkpoint}] due to args.save_total_limit") + shutil.rmtree(checkpoint) + + self.control = self.callback_handler.on_train_end(args, self.state, self.control) + + return TrainOutput(self.state.global_step, train_loss, metrics) + + def _get_output_dir(self, trial): + if self.hp_search_backend is not None and trial is not None: + if self.hp_search_backend == HPSearchBackend.OPTUNA: + run_id = trial.number + elif self.hp_search_backend == HPSearchBackend.RAY: + from ray import tune + + run_id = tune.get_trial_id() + elif self.hp_search_backend == HPSearchBackend.SIGOPT: + run_id = trial.id + elif self.hp_search_backend == HPSearchBackend.WANDB: + import wandb + + run_id = wandb.run.id + run_name = self.hp_name(trial) if self.hp_name is not None else f"run-{run_id}" + run_dir = os.path.join(self.args.output_dir, run_name) + else: + run_dir = self.args.output_dir + return run_dir + + def _load_from_checkpoint(self, resume_from_checkpoint, model=None): + if model is None: + model = self.model + + config_file = os.path.join(resume_from_checkpoint, CONFIG_NAME) + + weights_file = os.path.join(resume_from_checkpoint, WEIGHTS_NAME) + weights_index_file = os.path.join(resume_from_checkpoint, WEIGHTS_INDEX_NAME) + safe_weights_file = os.path.join(resume_from_checkpoint, SAFE_WEIGHTS_NAME) + safe_weights_index_file = os.path.join(resume_from_checkpoint, SAFE_WEIGHTS_INDEX_NAME) + + if not any( + os.path.isfile(f) for f in [weights_file, safe_weights_file, weights_index_file, safe_weights_index_file] + ): + raise ValueError(f"Can't find a valid checkpoint at {resume_from_checkpoint}") + + logger.info(f"Loading model from {resume_from_checkpoint}.") + + if os.path.isfile(config_file): + config = PretrainedConfig.from_json_file(config_file) + checkpoint_version = config.transformers_version + if checkpoint_version is not None and checkpoint_version != __version__: + logger.warning( + f"You are resuming training from a checkpoint trained with {checkpoint_version} of " + f"Transformers but your current version is {__version__}. This is not recommended and could " + "yield to errors or unwanted behaviors." + ) + + if os.path.isfile(weights_file) or os.path.isfile(safe_weights_file): + # If the model is on the GPU, it still works! + if is_sagemaker_mp_enabled(): + if os.path.isfile(os.path.join(resume_from_checkpoint, "user_content.pt")): + # If the 'user_content.pt' file exists, load with the new smp api. + # Checkpoint must have been saved with the new smp api. + smp.resume_from_checkpoint( + path=resume_from_checkpoint, tag=WEIGHTS_NAME, partial=False, load_optimizer=False + ) + else: + # If the 'user_content.pt' file does NOT exist, load with the old smp api. + # Checkpoint must have been saved with the old smp api. + if hasattr(self.args, "fp16") and self.args.fp16 is True: + logger.warning( + "Enabling FP16 and loading from smp < 1.10 checkpoint together is not suppported." + ) + state_dict = torch.load(weights_file, map_location="cpu") + # Required for smp to not auto-translate state_dict from hf to smp (is already smp). + state_dict["_smp_is_partial"] = False + load_result = model.load_state_dict(state_dict, strict=True) + # release memory + del state_dict + else: + # We load the model state dict on the CPU to avoid an OOM error. + if self.args.save_safetensors and os.path.isfile(safe_weights_file): + state_dict = safetensors.torch.load_file(safe_weights_file, device="cpu") + else: + state_dict = torch.load(weights_file, map_location="cpu") + + # workaround for FSDP bug https://github.com/pytorch/pytorch/issues/82963 + # which takes *args instead of **kwargs + load_result = model.load_state_dict(state_dict, False) + # release memory + del state_dict + self._issue_warnings_after_load(load_result) + else: + # We load the sharded checkpoint + load_result = load_sharded_checkpoint( + model, resume_from_checkpoint, strict=is_sagemaker_mp_enabled(), prefer_safe=self.args.save_safetensors + ) + if not is_sagemaker_mp_enabled(): + self._issue_warnings_after_load(load_result) + + def _load_best_model(self): + logger.info(f"Loading best model from {self.state.best_model_checkpoint} (score: {self.state.best_metric}).") + best_model_path = os.path.join(self.state.best_model_checkpoint, WEIGHTS_NAME) + best_safe_model_path = os.path.join(self.state.best_model_checkpoint, SAFE_WEIGHTS_NAME) + model = self.model_wrapped if is_sagemaker_mp_enabled() else self.model + if os.path.exists(best_model_path) or os.path.exists(best_safe_model_path): + if self.deepspeed: + if self.model_wrapped is not None: + # this removes the pre-hooks from the previous engine + self.model_wrapped.destroy() + self.model_wrapped = None + + # temp hack until Deepspeed fixes the problem with resume from an existing engine that did some stepping + deepspeed_engine, optimizer, lr_scheduler = deepspeed_init( + self, + num_training_steps=self.args.max_steps, + resume_from_checkpoint=self.state.best_model_checkpoint, + ) + self.model = deepspeed_engine.module + self.model_wrapped = deepspeed_engine + self.deepspeed = deepspeed_engine + self.optimizer = optimizer + self.lr_scheduler = lr_scheduler + else: + if is_sagemaker_mp_enabled(): + if os.path.isfile(os.path.join(self.state.best_model_checkpoint, "user_content.pt")): + # If the 'user_content.pt' file exists, load with the new smp api. + # Checkpoint must have been saved with the new smp api. + smp.resume_from_checkpoint( + path=self.state.best_model_checkpoint, + tag=WEIGHTS_NAME, + partial=False, + load_optimizer=False, + ) + else: + # If the 'user_content.pt' file does NOT exist, load with the old smp api. + # Checkpoint must have been saved with the old smp api. + if self.args.save_safetensors and os.path.isfile(best_safe_model_path): + state_dict = safetensors.torch.load_file(best_safe_model_path, device="cpu") + else: + state_dict = torch.load(best_model_path, map_location="cpu") + + state_dict["_smp_is_partial"] = False + load_result = model.load_state_dict(state_dict, strict=True) + else: + # We load the model state dict on the CPU to avoid an OOM error. + if self.args.save_safetensors and os.path.isfile(best_safe_model_path): + state_dict = safetensors.torch.load_file(best_safe_model_path, device="cpu") + else: + state_dict = torch.load(best_model_path, map_location="cpu") + + # If the model is on the GPU, it still works! + # workaround for FSDP bug https://github.com/pytorch/pytorch/issues/82963 + # which takes *args instead of **kwargs + load_result = model.load_state_dict(state_dict, False) + if not is_sagemaker_mp_enabled(): + self._issue_warnings_after_load(load_result) + elif os.path.exists(os.path.join(self.state.best_model_checkpoint, WEIGHTS_INDEX_NAME)): + load_result = load_sharded_checkpoint( + model, self.state.best_model_checkpoint, strict=is_sagemaker_mp_enabled() + ) + if not is_sagemaker_mp_enabled(): + self._issue_warnings_after_load(load_result) + else: + logger.warning( + f"Could not locate the best model at {best_model_path}, if you are running a distributed training " + "on multiple nodes, you should activate `--save_on_each_node`." + ) + + def _issue_warnings_after_load(self, load_result): + if len(load_result.missing_keys) != 0: + if self.model._keys_to_ignore_on_save is not None and set(load_result.missing_keys) == set( + self.model._keys_to_ignore_on_save + ): + self.model.tie_weights() + else: + logger.warning(f"There were missing keys in the checkpoint model loaded: {load_result.missing_keys}.") + if len(load_result.unexpected_keys) != 0: + logger.warning( + f"There were unexpected keys in the checkpoint model loaded: {load_result.unexpected_keys}." + ) + + def _maybe_log_save_evaluate(self, tr_loss, model, trial, epoch, ignore_keys_for_eval): + if self.control.should_log: + if is_torch_tpu_available(): + xm.mark_step() + + logs: Dict[str, float] = {} + + # all_gather + mean() to get average loss over all processes + tr_loss_scalar = self._nested_gather(tr_loss).mean().item() + + # reset tr_loss to zero + tr_loss -= tr_loss + + logs["loss"] = round(tr_loss_scalar / (self.state.global_step - self._globalstep_last_logged), 4) + logs["learning_rate"] = self._get_learning_rate() + + self._total_loss_scalar += tr_loss_scalar + self._globalstep_last_logged = self.state.global_step + self.store_flos() + + self.log(logs) + + metrics = None + if self.control.should_evaluate: + if isinstance(self.eval_dataset, dict): + metrics = {} + for eval_dataset_name, eval_dataset in self.eval_dataset.items(): + dataset_metrics = self.evaluate( + eval_dataset=eval_dataset, + ignore_keys=ignore_keys_for_eval, + metric_key_prefix=f"eval_{eval_dataset_name}", + ) + metrics.update(dataset_metrics) + else: + metrics = self.evaluate(ignore_keys=ignore_keys_for_eval) + self._report_to_hp_search(trial, self.state.global_step, metrics) + + # Run delayed LR scheduler now that metrics are populated + if isinstance(self.lr_scheduler, torch.optim.lr_scheduler.ReduceLROnPlateau): + self.lr_scheduler.step(metrics[self.args.metric_for_best_model]) + + if self.control.should_save: + self._save_checkpoint(model, trial, metrics=metrics) + self.control = self.callback_handler.on_save(self.args, self.state, self.control) + + def _load_rng_state(self, checkpoint): + # Load RNG states from `checkpoint` + if checkpoint is None: + return + + if self.args.world_size > 1: + process_index = self.args.process_index + rng_file = os.path.join(checkpoint, f"rng_state_{process_index}.pth") + if not os.path.isfile(rng_file): + logger.info( + f"Didn't find an RNG file for process {process_index}, if you are resuming a training that " + "wasn't launched in a distributed fashion, reproducibility is not guaranteed." + ) + return + else: + rng_file = os.path.join(checkpoint, "rng_state.pth") + if not os.path.isfile(rng_file): + logger.info( + "Didn't find an RNG file, if you are resuming a training that was launched in a distributed " + "fashion, reproducibility is not guaranteed." + ) + return + + checkpoint_rng_state = torch.load(rng_file) + random.setstate(checkpoint_rng_state["python"]) + np.random.set_state(checkpoint_rng_state["numpy"]) + torch.random.set_rng_state(checkpoint_rng_state["cpu"]) + if torch.cuda.is_available(): + if self.args.parallel_mode == ParallelMode.DISTRIBUTED: + torch.cuda.random.set_rng_state_all(checkpoint_rng_state["cuda"]) + else: + try: + torch.cuda.random.set_rng_state(checkpoint_rng_state["cuda"]) + except Exception as e: + logger.info( + f"Didn't manage to set back the RNG states of the GPU because of the following error:\n {e}" + "\nThis won't yield the same results as if the training had not been interrupted." + ) + if is_torch_tpu_available(): + xm.set_rng_state(checkpoint_rng_state["xla"]) + + def _save_checkpoint(self, model, trial, metrics=None): + # In all cases, including ddp/dp/deepspeed, self.model is always a reference to the model we + # want to save except FullyShardedDDP. + # assert unwrap_model(model) is self.model, "internal model should be a reference to self.model" + + # Save model checkpoint + checkpoint_folder = f"{PREFIX_CHECKPOINT_DIR}-{self.state.global_step}" + + if self.hp_search_backend is None and trial is None: + self.store_flos() + + run_dir = self._get_output_dir(trial=trial) + output_dir = os.path.join(run_dir, checkpoint_folder) + self.save_model(output_dir, _internal_call=True) + if self.deepspeed: + # under zero3 model file itself doesn't get saved since it's bogus! Unless deepspeed + # config `stage3_gather_16bit_weights_on_model_save` is True + self.deepspeed.save_checkpoint(output_dir) + + # Save optimizer and scheduler + if self.sharded_ddp == ShardedDDPOption.SIMPLE: + self.optimizer.consolidate_state_dict() + + if self.fsdp: + # FSDP has a different interface for saving optimizer states. + # Needs to be called on all ranks to gather all states. + # full_optim_state_dict will be deprecated after Pytorch 2.2! + full_osd = self.model.__class__.full_optim_state_dict(self.model, self.optimizer) + + if is_torch_tpu_available(): + xm.rendezvous("saving_optimizer_states") + xm.save(self.optimizer.state_dict(), os.path.join(output_dir, OPTIMIZER_NAME)) + with warnings.catch_warnings(record=True) as caught_warnings: + xm.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, SCHEDULER_NAME)) + reissue_pt_warnings(caught_warnings) + elif is_sagemaker_mp_enabled(): + opt_state_dict = self.optimizer.local_state_dict(gather_if_shard=False) + smp.barrier() + if smp.rdp_rank() == 0 or smp.state.cfg.shard_optimizer_state: + smp.save( + opt_state_dict, + os.path.join(output_dir, OPTIMIZER_NAME), + partial=True, + v3=smp.state.cfg.shard_optimizer_state, + ) + if self.args.should_save: + with warnings.catch_warnings(record=True) as caught_warnings: + torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, SCHEDULER_NAME)) + reissue_pt_warnings(caught_warnings) + if self.do_grad_scaling: + torch.save(self.scaler.state_dict(), os.path.join(output_dir, SCALER_NAME)) + elif self.args.should_save and not self.deepspeed: + # deepspeed.save_checkpoint above saves model/optim/sched + if self.fsdp: + torch.save(full_osd, os.path.join(output_dir, OPTIMIZER_NAME)) + else: + torch.save(self.optimizer.state_dict(), os.path.join(output_dir, OPTIMIZER_NAME)) + + with warnings.catch_warnings(record=True) as caught_warnings: + torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, SCHEDULER_NAME)) + reissue_pt_warnings(caught_warnings) + if self.do_grad_scaling: + torch.save(self.scaler.state_dict(), os.path.join(output_dir, SCALER_NAME)) + + # Determine the new best metric / best model checkpoint + if metrics is not None and self.args.metric_for_best_model is not None: + metric_to_check = self.args.metric_for_best_model + if not metric_to_check.startswith("eval_"): + metric_to_check = f"eval_{metric_to_check}" + metric_value = metrics[metric_to_check] + + operator = np.greater if self.args.greater_is_better else np.less + if ( + self.state.best_metric is None + or self.state.best_model_checkpoint is None + or operator(metric_value, self.state.best_metric) + ): + self.state.best_metric = metric_value + self.state.best_model_checkpoint = output_dir + + # Save the Trainer state + if self.args.should_save: + self.state.save_to_json(os.path.join(output_dir, TRAINER_STATE_NAME)) + + # Save RNG state in non-distributed training + rng_states = { + "python": random.getstate(), + "numpy": np.random.get_state(), + "cpu": torch.random.get_rng_state(), + } + if torch.cuda.is_available(): + if self.args.parallel_mode == ParallelMode.DISTRIBUTED: + # In non distributed, we save the global CUDA RNG state (will take care of DataParallel) + rng_states["cuda"] = torch.cuda.random.get_rng_state_all() + else: + rng_states["cuda"] = torch.cuda.random.get_rng_state() + + if is_torch_tpu_available(): + rng_states["xla"] = xm.get_rng_state() + + # A process can arrive here before the process 0 has a chance to save the model, in which case output_dir may + # not yet exist. + os.makedirs(output_dir, exist_ok=True) + + if self.args.world_size <= 1: + torch.save(rng_states, os.path.join(output_dir, "rng_state.pth")) + else: + torch.save(rng_states, os.path.join(output_dir, f"rng_state_{self.args.process_index}.pth")) + + if self.args.push_to_hub: + self._push_from_checkpoint(output_dir) + + # Maybe delete some older checkpoints. + if self.args.should_save: + self._rotate_checkpoints(use_mtime=True, output_dir=run_dir) + + def _load_optimizer_and_scheduler(self, checkpoint): + """If optimizer and scheduler states exist, load them.""" + if checkpoint is None: + return + + if self.deepspeed: + # deepspeed loads optimizer/lr_scheduler together with the model in deepspeed_init + return + + checkpoint_file_exists = ( + glob.glob(os.path.join(checkpoint, OPTIMIZER_NAME) + "_*") + if is_sagemaker_mp_enabled() + else os.path.isfile(os.path.join(checkpoint, OPTIMIZER_NAME)) + ) + if checkpoint_file_exists and os.path.isfile(os.path.join(checkpoint, SCHEDULER_NAME)): + # Load in optimizer and scheduler states + if is_torch_tpu_available(): + # On TPU we have to take some extra precautions to properly load the states on the right device. + optimizer_state = torch.load(os.path.join(checkpoint, OPTIMIZER_NAME), map_location="cpu") + with warnings.catch_warnings(record=True) as caught_warnings: + lr_scheduler_state = torch.load(os.path.join(checkpoint, SCHEDULER_NAME), map_location="cpu") + reissue_pt_warnings(caught_warnings) + + xm.send_cpu_data_to_device(optimizer_state, self.args.device) + xm.send_cpu_data_to_device(lr_scheduler_state, self.args.device) + + self.optimizer.load_state_dict(optimizer_state) + self.lr_scheduler.load_state_dict(lr_scheduler_state) + else: + if is_sagemaker_mp_enabled(): + if os.path.isfile(os.path.join(checkpoint, "user_content.pt")): + # Optimizer checkpoint was saved with smp >= 1.10 + def opt_load_hook(mod, opt): + opt.load_state_dict(smp.load(os.path.join(checkpoint, OPTIMIZER_NAME), partial=True)) + + else: + # Optimizer checkpoint was saved with smp < 1.10 + def opt_load_hook(mod, opt): + if IS_SAGEMAKER_MP_POST_1_10: + opt.load_state_dict( + smp.load(os.path.join(checkpoint, OPTIMIZER_NAME), partial=True, back_compat=True) + ) + else: + opt.load_state_dict(smp.load(os.path.join(checkpoint, OPTIMIZER_NAME), partial=True)) + + self.model_wrapped.register_post_step_hook(opt_load_hook) + else: + # We use the CPU when training on one GPU to avoid OOM for GPU RAM when training big models. + # In distributed training however, we load directly on each GPU and risk the GPU OOM as it's more + # likely to get OOM on CPU (since we load num_gpu times the optimizer state + map_location = self.args.device if self.args.world_size > 1 else "cpu" + if self.fsdp: + full_osd = None + # In FSDP, we need to load the full optimizer state dict on rank 0 and then shard it + if self.args.process_index == 0: + full_osd = torch.load(os.path.join(checkpoint, OPTIMIZER_NAME)) + # call scatter_full_optim_state_dict on all ranks + sharded_osd = self.model.__class__.scatter_full_optim_state_dict(full_osd, self.model) + self.optimizer.load_state_dict(sharded_osd) + else: + self.optimizer.load_state_dict( + torch.load(os.path.join(checkpoint, OPTIMIZER_NAME), map_location=map_location) + ) + with warnings.catch_warnings(record=True) as caught_warnings: + self.lr_scheduler.load_state_dict(torch.load(os.path.join(checkpoint, SCHEDULER_NAME))) + reissue_pt_warnings(caught_warnings) + if self.do_grad_scaling and os.path.isfile(os.path.join(checkpoint, SCALER_NAME)): + self.scaler.load_state_dict(torch.load(os.path.join(checkpoint, SCALER_NAME))) + + def hyperparameter_search( + self, + hp_space: Optional[Callable[["optuna.Trial"], Dict[str, float]]] = None, + compute_objective: Optional[Callable[[Dict[str, float]], float]] = None, + n_trials: int = 20, + direction: str = "minimize", + backend: Optional[Union["str", HPSearchBackend]] = None, + hp_name: Optional[Callable[["optuna.Trial"], str]] = None, + **kwargs, + ) -> BestRun: + """ + Launch an hyperparameter search using `optuna` or `Ray Tune` or `SigOpt`. The optimized quantity is determined + by `compute_objective`, which defaults to a function returning the evaluation loss when no metric is provided, + the sum of all metrics otherwise. + + + + To use this method, you need to have provided a `model_init` when initializing your [`Trainer`]: we need to + reinitialize the model at each new run. This is incompatible with the `optimizers` argument, so you need to + subclass [`Trainer`] and override the method [`~Trainer.create_optimizer_and_scheduler`] for custom + optimizer/scheduler. + + + + Args: + hp_space (`Callable[["optuna.Trial"], Dict[str, float]]`, *optional*): + A function that defines the hyperparameter search space. Will default to + [`~trainer_utils.default_hp_space_optuna`] or [`~trainer_utils.default_hp_space_ray`] or + [`~trainer_utils.default_hp_space_sigopt`] depending on your backend. + compute_objective (`Callable[[Dict[str, float]], float]`, *optional*): + A function computing the objective to minimize or maximize from the metrics returned by the `evaluate` + method. Will default to [`~trainer_utils.default_compute_objective`]. + n_trials (`int`, *optional*, defaults to 100): + The number of trial runs to test. + direction (`str`, *optional*, defaults to `"minimize"`): + Whether to optimize greater or lower objects. Can be `"minimize"` or `"maximize"`, you should pick + `"minimize"` when optimizing the validation loss, `"maximize"` when optimizing one or several metrics. + backend (`str` or [`~training_utils.HPSearchBackend`], *optional*): + The backend to use for hyperparameter search. Will default to optuna or Ray Tune or SigOpt, depending + on which one is installed. If all are installed, will default to optuna. + hp_name (`Callable[["optuna.Trial"], str]]`, *optional*): + A function that defines the trial/run name. Will default to None. + kwargs (`Dict[str, Any]`, *optional*): + Additional keyword arguments passed along to `optuna.create_study` or `ray.tune.run`. For more + information see: + + - the documentation of + [optuna.create_study](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.study.create_study.html) + - the documentation of [tune.run](https://docs.ray.io/en/latest/tune/api_docs/execution.html#tune-run) + - the documentation of [sigopt](https://app.sigopt.com/docs/endpoints/experiments/create) + + Returns: + [`trainer_utils.BestRun`]: All the information about the best run. Experiment summary can be found in + `run_summary` attribute for Ray backend. + """ + if backend is None: + backend = default_hp_search_backend() + if backend is None: + raise RuntimeError( + "At least one of optuna or ray should be installed. " + "To install optuna run `pip install optuna`. " + "To install ray run `pip install ray[tune]`. " + "To install sigopt run `pip install sigopt`." + ) + backend = HPSearchBackend(backend) + if backend == HPSearchBackend.OPTUNA and not is_optuna_available(): + raise RuntimeError("You picked the optuna backend, but it is not installed. Use `pip install optuna`.") + if backend == HPSearchBackend.RAY and not is_ray_tune_available(): + raise RuntimeError( + "You picked the Ray Tune backend, but it is not installed. Use `pip install 'ray[tune]'`." + ) + if backend == HPSearchBackend.SIGOPT and not is_sigopt_available(): + raise RuntimeError("You picked the sigopt backend, but it is not installed. Use `pip install sigopt`.") + if backend == HPSearchBackend.WANDB and not is_wandb_available(): + raise RuntimeError("You picked the wandb backend, but it is not installed. Use `pip install wandb`.") + self.hp_search_backend = backend + if self.model_init is None: + raise RuntimeError( + "To use hyperparameter search, you need to pass your model through a model_init function." + ) + + self.hp_space = default_hp_space[backend] if hp_space is None else hp_space + self.hp_name = hp_name + self.compute_objective = default_compute_objective if compute_objective is None else compute_objective + + backend_dict = { + HPSearchBackend.OPTUNA: run_hp_search_optuna, + HPSearchBackend.RAY: run_hp_search_ray, + HPSearchBackend.SIGOPT: run_hp_search_sigopt, + HPSearchBackend.WANDB: run_hp_search_wandb, + } + best_run = backend_dict[backend](self, n_trials, direction, **kwargs) + + self.hp_search_backend = None + return best_run + + def log(self, logs: Dict[str, float]) -> None: + """ + Log `logs` on the various objects watching training. + + Subclass and override this method to inject custom behavior. + + Args: + logs (`Dict[str, float]`): + The values to log. + """ + if self.state.epoch is not None: + logs["epoch"] = round(self.state.epoch, 2) + + output = {**logs, **{"step": self.state.global_step}} + self.state.log_history.append(output) + self.control = self.callback_handler.on_log(self.args, self.state, self.control, logs) + + def _prepare_input(self, data: Union[torch.Tensor, Any]) -> Union[torch.Tensor, Any]: + """ + Prepares one `data` before feeding it to the model, be it a tensor or a nested list/dictionary of tensors. + """ + if isinstance(data, Mapping): + return type(data)({k: self._prepare_input(v) for k, v in data.items()}) + elif isinstance(data, (tuple, list)): + return type(data)(self._prepare_input(v) for v in data) + elif isinstance(data, torch.Tensor): + kwargs = {"device": self.args.device} + if self.deepspeed and (torch.is_floating_point(data) or torch.is_complex(data)): + # NLP models inputs are int/uint and those get adjusted to the right dtype of the + # embedding. Other models such as wav2vec2's inputs are already float and thus + # may need special handling to match the dtypes of the model + kwargs.update({"dtype": self.args.hf_deepspeed_config.dtype()}) + return data.to(**kwargs) + return data + + def _prepare_inputs(self, inputs: Dict[str, Union[torch.Tensor, Any]]) -> Dict[str, Union[torch.Tensor, Any]]: + """ + Prepare `inputs` before feeding them to the model, converting them to tensors if they are not already and + handling potential state. + """ + inputs = self._prepare_input(inputs) + if len(inputs) == 0: + raise ValueError( + "The batch received was empty, your model won't be able to train on it. Double-check that your " + f"training dataset contains keys expected by the model: {','.join(self._signature_columns)}." + ) + if self.args.past_index >= 0 and self._past is not None: + inputs["mems"] = self._past + + return inputs + + def compute_loss_context_manager(self): + """ + A helper wrapper to group together context managers. + """ + return self.autocast_smart_context_manager() + + def autocast_smart_context_manager(self, cache_enabled: Optional[bool] = True): + """ + A helper wrapper that creates an appropriate context manager for `autocast` while feeding it the desired + arguments, depending on the situation. + """ + if self.use_cuda_amp or self.use_cpu_amp: + if is_torch_greater_or_equal_than_1_10: + ctx_manager = ( + torch.cpu.amp.autocast(cache_enabled=cache_enabled, dtype=self.amp_dtype) + if self.use_cpu_amp + else torch.cuda.amp.autocast(cache_enabled=cache_enabled, dtype=self.amp_dtype) + ) + else: + ctx_manager = torch.cuda.amp.autocast() + else: + ctx_manager = contextlib.nullcontext() if sys.version_info >= (3, 7) else contextlib.suppress() + + return ctx_manager + + def training_step(self, model: nn.Module, inputs: Dict[str, Union[torch.Tensor, Any]]) -> torch.Tensor: + """ + Perform a training step on a batch of inputs. + + Subclass and override to inject custom behavior. + + Args: + model (`nn.Module`): + The model to train. + inputs (`Dict[str, Union[torch.Tensor, Any]]`): + The inputs and targets of the model. + + The dictionary will be unpacked before being fed to the model. Most models expect the targets under the + argument `labels`. Check your model's documentation for all accepted arguments. + + Return: + `torch.Tensor`: The tensor with training loss on this batch. + """ + model.train() + inputs = self._prepare_inputs(inputs) + + if is_sagemaker_mp_enabled(): + loss_mb = smp_forward_backward(model, inputs, self.args.gradient_accumulation_steps) + return loss_mb.reduce_mean().detach().to(self.args.device) + + with self.compute_loss_context_manager(): + loss = self.compute_loss(model, inputs) + + if self.args.n_gpu > 1: + loss = loss.mean() # mean() to average on multi-gpu parallel training + + if self.args.gradient_accumulation_steps > 1 and not self.deepspeed: + # deepspeed handles loss scaling by gradient_accumulation_steps in its `backward` + loss = loss / self.args.gradient_accumulation_steps + + if self.do_grad_scaling: + self.scaler.scale(loss).backward() + elif self.use_apex: + with amp.scale_loss(loss, self.optimizer) as scaled_loss: + scaled_loss.backward() + elif self.deepspeed: + # loss gets scaled under gradient_accumulation_steps in deepspeed + loss = self.deepspeed.backward(loss) + else: + loss.backward() + + return loss.detach() + + def compute_loss(self, model, inputs, return_outputs=False): + """ + How the loss is computed by Trainer. By default, all models return the loss in the first element. + + Subclass and override for custom behavior. + """ + if self.label_smoother is not None and "labels" in inputs: + labels = inputs.pop("labels") + else: + labels = None + outputs = model(**inputs) + # Save past state if it exists + # TODO: this needs to be fixed and made cleaner later. + if self.args.past_index >= 0: + self._past = outputs[self.args.past_index] + + if labels is not None: + if unwrap_model(model)._get_name() in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES.values(): + loss = self.label_smoother(outputs, labels, shift_labels=True) + else: + loss = self.label_smoother(outputs, labels) + else: + if isinstance(outputs, dict) and "loss" not in outputs: + raise ValueError( + "The model did not return a loss from the inputs, only the following keys: " + f"{','.join(outputs.keys())}. For reference, the inputs it received are {','.join(inputs.keys())}." + ) + # We don't use .loss here since the model may return tuples instead of ModelOutput. + loss = outputs["loss"] if isinstance(outputs, dict) else outputs[0] + + return (loss, outputs) if return_outputs else loss + + def is_local_process_zero(self) -> bool: + """ + Whether or not this process is the local (e.g., on one machine if training in a distributed fashion on several + machines) main process. + """ + return self.args.local_process_index == 0 + + def is_world_process_zero(self) -> bool: + """ + Whether or not this process is the global main process (when training in a distributed fashion on several + machines, this is only going to be `True` for one process). + """ + # Special case for SageMaker ModelParallel since there process_index is dp_process_index, not the global + # process index. + if is_sagemaker_mp_enabled(): + return smp.rank() == 0 + else: + return self.args.process_index == 0 + + def save_model(self, output_dir: Optional[str] = None, _internal_call: bool = False): + """ + Will save the model, so you can reload it using `from_pretrained()`. + + Will only save from the main process. + """ + + if output_dir is None: + output_dir = self.args.output_dir + + if is_torch_tpu_available(): + self._save_tpu(output_dir) + elif is_sagemaker_mp_enabled(): + # Calling the state_dict needs to be done on the wrapped model and on all processes. + os.makedirs(output_dir, exist_ok=True) + state_dict = self.model_wrapped.state_dict() + if self.args.should_save: + self._save(output_dir, state_dict=state_dict) + if IS_SAGEMAKER_MP_POST_1_10: + # 'user_content.pt' indicates model state_dict saved with smp >= 1.10 + Path(os.path.join(output_dir, "user_content.pt")).touch() + elif ( + ShardedDDPOption.ZERO_DP_2 in self.args.sharded_ddp + or ShardedDDPOption.ZERO_DP_3 in self.args.sharded_ddp + or self.fsdp is not None + ): + state_dict = self.model.state_dict() + + if self.args.should_save: + self._save(output_dir, state_dict=state_dict) + elif self.deepspeed: + # this takes care of everything as long as we aren't under zero3 + if self.args.should_save: + self._save(output_dir) + + if is_deepspeed_zero3_enabled(): + # It's too complicated to try to override different places where the weights dump gets + # saved, so since under zero3 the file is bogus, simply delete it. The user should + # either user deepspeed checkpoint to resume or to recover full weights use + # zero_to_fp32.py stored in the checkpoint. + if self.args.should_save: + file = os.path.join(output_dir, WEIGHTS_NAME) + if os.path.isfile(file): + # logger.info(f"deepspeed zero3: removing {file}, see zero_to_fp32.py to recover weights") + os.remove(file) + + # now save the real model if stage3_gather_16bit_weights_on_model_save=True + # if false it will not be saved. + # This must be called on all ranks + if not self.deepspeed.save_16bit_model(output_dir, WEIGHTS_NAME): + logger.warning( + "deepspeed.save_16bit_model didn't save the model, since" + " stage3_gather_16bit_weights_on_model_save=false. Saving the full checkpoint instead, use" + " zero_to_fp32.py to recover weights" + ) + self.deepspeed.save_checkpoint(output_dir) + + elif self.args.should_save: + self._save(output_dir) + + # Push to the Hub when `save_model` is called by the user. + if self.args.push_to_hub and not _internal_call: + self.push_to_hub(commit_message="Model save") + + def _save_tpu(self, output_dir: Optional[str] = None): + output_dir = output_dir if output_dir is not None else self.args.output_dir + logger.info(f"Saving model checkpoint to {output_dir}") + + if xm.is_master_ordinal(): + os.makedirs(output_dir, exist_ok=True) + torch.save(self.args, os.path.join(output_dir, TRAINING_ARGS_NAME)) + + # Save a trained model and configuration using `save_pretrained()`. + # They can then be reloaded using `from_pretrained()` + xm.rendezvous("saving_checkpoint") + if not isinstance(self.model, PreTrainedModel): + if isinstance(unwrap_model(self.model), PreTrainedModel): + unwrap_model(self.model).save_pretrained( + output_dir, + is_main_process=self.args.should_save, + state_dict=self.model.state_dict(), + save_function=xm.save, + ) + else: + logger.info("Trainer.model is not a `PreTrainedModel`, only saving its state dict.") + state_dict = self.model.state_dict() + xm.save(state_dict, os.path.join(output_dir, WEIGHTS_NAME)) + else: + self.model.save_pretrained(output_dir, is_main_process=self.args.should_save, save_function=xm.save) + if self.tokenizer is not None and self.args.should_save: + self.tokenizer.save_pretrained(output_dir) + + def _save(self, output_dir: Optional[str] = None, state_dict=None): + # If we are executing this function, we are the process zero, so we don't check for that. + output_dir = output_dir if output_dir is not None else self.args.output_dir + os.makedirs(output_dir, exist_ok=True) + logger.info(f"Saving model checkpoint to {output_dir}") + # Save a trained model and configuration using `save_pretrained()`. + # They can then be reloaded using `from_pretrained()` + if not isinstance(self.model, PreTrainedModel): + if state_dict is None: + state_dict = self.model.state_dict() + + if isinstance(unwrap_model(self.model), PreTrainedModel): + unwrap_model(self.model).save_pretrained( + output_dir, state_dict=state_dict, safe_serialization=self.args.save_safetensors + ) + else: + logger.info("Trainer.model is not a `PreTrainedModel`, only saving its state dict.") + if self.args.save_safetensors: + safetensors.torch.save_file(state_dict, os.path.join(output_dir, SAFE_WEIGHTS_NAME)) + else: + torch.save(state_dict, os.path.join(output_dir, WEIGHTS_NAME)) + else: + self.model.save_pretrained( + output_dir, state_dict=state_dict, safe_serialization=self.args.save_safetensors + ) + + if self.tokenizer is not None: + self.tokenizer.save_pretrained(output_dir) + + # Good practice: save your training arguments together with the trained model + torch.save(self.args, os.path.join(output_dir, TRAINING_ARGS_NAME)) + + def store_flos(self): + # Storing the number of floating-point operations that went into the model + if self.args.parallel_mode == ParallelMode.DISTRIBUTED: + self.state.total_flos += ( + distributed_broadcast_scalars([self.current_flos], device=self.args.device).sum().item() + ) + self.current_flos = 0 + else: + self.state.total_flos += self.current_flos + self.current_flos = 0 + + def _sorted_checkpoints( + self, output_dir=None, checkpoint_prefix=PREFIX_CHECKPOINT_DIR, use_mtime=False + ) -> List[str]: + ordering_and_checkpoint_path = [] + + glob_checkpoints = [str(x) for x in Path(output_dir).glob(f"{checkpoint_prefix}-*") if os.path.isdir(x)] + + for path in glob_checkpoints: + if use_mtime: + ordering_and_checkpoint_path.append((os.path.getmtime(path), path)) + else: + regex_match = re.match(f".*{checkpoint_prefix}-([0-9]+)", path) + if regex_match is not None and regex_match.groups() is not None: + ordering_and_checkpoint_path.append((int(regex_match.groups()[0]), path)) + + checkpoints_sorted = sorted(ordering_and_checkpoint_path) + checkpoints_sorted = [checkpoint[1] for checkpoint in checkpoints_sorted] + # Make sure we don't delete the best model. + if self.state.best_model_checkpoint is not None: + best_model_index = checkpoints_sorted.index(str(Path(self.state.best_model_checkpoint))) + for i in range(best_model_index, len(checkpoints_sorted) - 2): + checkpoints_sorted[i], checkpoints_sorted[i + 1] = checkpoints_sorted[i + 1], checkpoints_sorted[i] + return checkpoints_sorted + + def _rotate_checkpoints(self, use_mtime=False, output_dir=None) -> None: + if self.args.save_total_limit is None or self.args.save_total_limit <= 0: + return + + # Check if we should delete older checkpoint(s) + checkpoints_sorted = self._sorted_checkpoints(use_mtime=use_mtime, output_dir=output_dir) + if len(checkpoints_sorted) <= self.args.save_total_limit: + return + + # If save_total_limit=1 with load_best_model_at_end=True, we could end up deleting the last checkpoint, which + # we don't do to allow resuming. + save_total_limit = self.args.save_total_limit + if ( + self.state.best_model_checkpoint is not None + and self.args.save_total_limit == 1 + and checkpoints_sorted[-1] != self.state.best_model_checkpoint + ): + save_total_limit = 2 + + number_of_checkpoints_to_delete = max(0, len(checkpoints_sorted) - save_total_limit) + checkpoints_to_be_deleted = checkpoints_sorted[:number_of_checkpoints_to_delete] + for checkpoint in checkpoints_to_be_deleted: + logger.info(f"Deleting older checkpoint [{checkpoint}] due to args.save_total_limit") + shutil.rmtree(checkpoint, ignore_errors=True) + + def evaluate( + self, + eval_dataset: Optional[Dataset] = None, + ignore_keys: Optional[List[str]] = None, + metric_key_prefix: str = "eval", + ) -> Dict[str, float]: + """ + Run evaluation and returns metrics. + + The calling script will be responsible for providing a method to compute metrics, as they are task-dependent + (pass it to the init `compute_metrics` argument). + + You can also subclass and override this method to inject custom behavior. + + Args: + eval_dataset (`Dataset`, *optional*): + Pass a dataset if you wish to override `self.eval_dataset`. If it is a [`~datasets.Dataset`], columns + not accepted by the `model.forward()` method are automatically removed. It must implement the `__len__` + method. + ignore_keys (`List[str]`, *optional*): + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions. + metric_key_prefix (`str`, *optional*, defaults to `"eval"`): + An optional prefix to be used as the metrics key prefix. For example the metrics "bleu" will be named + "eval_bleu" if the prefix is "eval" (default) + + Returns: + A dictionary containing the evaluation loss and the potential metrics computed from the predictions. The + dictionary also contains the epoch number which comes from the training state. + """ + # memory metrics - must set up as early as possible + self._memory_tracker.start() + + eval_dataloader = self.get_eval_dataloader(eval_dataset) + start_time = time.time() + + eval_loop = self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop + output = eval_loop( + eval_dataloader, + description="Evaluation", + # No point gathering the predictions if there are no metrics, otherwise we defer to + # self.args.prediction_loss_only + prediction_loss_only=True if self.compute_metrics is None else None, + ignore_keys=ignore_keys, + metric_key_prefix=metric_key_prefix, + ) + + total_batch_size = self.args.eval_batch_size * self.args.world_size + if f"{metric_key_prefix}_jit_compilation_time" in output.metrics: + start_time += output.metrics[f"{metric_key_prefix}_jit_compilation_time"] + output.metrics.update( + speed_metrics( + metric_key_prefix, + start_time, + num_samples=output.num_samples, + num_steps=math.ceil(output.num_samples / total_batch_size), + ) + ) + + self.log(output.metrics) + + if DebugOption.TPU_METRICS_DEBUG in self.args.debug: + # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.) + xm.master_print(met.metrics_report()) + + self.control = self.callback_handler.on_evaluate(self.args, self.state, self.control, output.metrics) + + self._memory_tracker.stop_and_update_metrics(output.metrics) + + return output.metrics + + def predict( + self, test_dataset: Dataset, ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "test" + ) -> PredictionOutput: + """ + Run prediction and returns predictions and potential metrics. + + Depending on the dataset and your use case, your test dataset may contain labels. In that case, this method + will also return metrics, like in `evaluate()`. + + Args: + test_dataset (`Dataset`): + Dataset to run the predictions on. If it is an `datasets.Dataset`, columns not accepted by the + `model.forward()` method are automatically removed. Has to implement the method `__len__` + ignore_keys (`List[str]`, *optional*): + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions. + metric_key_prefix (`str`, *optional*, defaults to `"test"`): + An optional prefix to be used as the metrics key prefix. For example the metrics "bleu" will be named + "test_bleu" if the prefix is "test" (default) + + + + If your predictions or labels have different sequence length (for instance because you're doing dynamic padding + in a token classification task) the predictions will be padded (on the right) to allow for concatenation into + one array. The padding index is -100. + + + + Returns: *NamedTuple* A namedtuple with the following keys: + + - predictions (`np.ndarray`): The predictions on `test_dataset`. + - label_ids (`np.ndarray`, *optional*): The labels (if the dataset contained some). + - metrics (`Dict[str, float]`, *optional*): The potential dictionary of metrics (if the dataset contained + labels). + """ + # memory metrics - must set up as early as possible + self._memory_tracker.start() + + test_dataloader = self.get_test_dataloader(test_dataset) + start_time = time.time() + + eval_loop = self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop + output = eval_loop( + test_dataloader, description="Prediction", ignore_keys=ignore_keys, metric_key_prefix=metric_key_prefix + ) + total_batch_size = self.args.eval_batch_size * self.args.world_size + if f"{metric_key_prefix}_jit_compilation_time" in output.metrics: + start_time += output.metrics[f"{metric_key_prefix}_jit_compilation_time"] + output.metrics.update( + speed_metrics( + metric_key_prefix, + start_time, + num_samples=output.num_samples, + num_steps=math.ceil(output.num_samples / total_batch_size), + ) + ) + + self.control = self.callback_handler.on_predict(self.args, self.state, self.control, output.metrics) + self._memory_tracker.stop_and_update_metrics(output.metrics) + + return PredictionOutput(predictions=output.predictions, label_ids=output.label_ids, metrics=output.metrics) + + def evaluation_loop( + self, + dataloader: DataLoader, + description: str, + prediction_loss_only: Optional[bool] = None, + ignore_keys: Optional[List[str]] = None, + metric_key_prefix: str = "eval", + ) -> EvalLoopOutput: + """ + Prediction/evaluation loop, shared by `Trainer.evaluate()` and `Trainer.predict()`. + + Works both with or without labels. + """ + args = self.args + + prediction_loss_only = prediction_loss_only if prediction_loss_only is not None else args.prediction_loss_only + + # if eval is called w/o train init deepspeed here + if args.deepspeed and not self.deepspeed: + # XXX: eval doesn't have `resume_from_checkpoint` arg but we should be able to do eval + # from the checkpoint eventually + deepspeed_engine, _, _ = deepspeed_init( + self, num_training_steps=0, resume_from_checkpoint=None, inference=True + ) + self.model = deepspeed_engine.module + self.model_wrapped = deepspeed_engine + self.deepspeed = deepspeed_engine + + model = self._wrap_model(self.model, training=False, dataloader=dataloader) + + # if full fp16 or bf16 eval is wanted and this ``evaluation`` or ``predict`` isn't called + # while ``train`` is running, cast it to the right dtype first and then put on device + if not self.is_in_train: + if args.fp16_full_eval: + model = model.to(dtype=torch.float16, device=args.device) + elif args.bf16_full_eval: + model = model.to(dtype=torch.bfloat16, device=args.device) + + batch_size = self.args.eval_batch_size + + logger.info(f"***** Running {description} *****") + if has_length(dataloader): + logger.info(f" Num examples = {self.num_examples(dataloader)}") + else: + logger.info(" Num examples: Unknown") + logger.info(f" Batch size = {batch_size}") + + model.eval() + + self.callback_handler.eval_dataloader = dataloader + # Do this before wrapping. + eval_dataset = getattr(dataloader, "dataset", None) + + if is_torch_tpu_available(): + dataloader = pl.ParallelLoader(dataloader, [args.device]).per_device_loader(args.device) + + if args.past_index >= 0: + self._past = None + + # Initialize containers + # losses/preds/labels on GPU/TPU (accumulated for eval_accumulation_steps) + losses_host = None + preds_host = None + labels_host = None + inputs_host = None + + # losses/preds/labels on CPU (final containers) + all_losses = None + all_preds = None + all_labels = None + all_inputs = None + # Will be useful when we have an iterable dataset so don't know its length. + + observed_num_examples = 0 + # Main evaluation loop + for step, inputs in enumerate(dataloader): + # Update the observed num examples + observed_batch_size = find_batch_size(inputs) + if observed_batch_size is not None: + observed_num_examples += observed_batch_size + # For batch samplers, batch_size is not known by the dataloader in advance. + if batch_size is None: + batch_size = observed_batch_size + + # Prediction step + loss, logits, labels = self.prediction_step(model, inputs, prediction_loss_only, ignore_keys=ignore_keys) + inputs_decode = self._prepare_input(inputs["input_ids"]) if args.include_inputs_for_metrics else None + + if is_torch_tpu_available(): + xm.mark_step() + + # Update containers on host + if loss is not None: + losses = self._nested_gather(loss.repeat(batch_size)) + losses_host = losses if losses_host is None else torch.cat((losses_host, losses), dim=0) + if labels is not None: + labels = self._pad_across_processes(labels) + if inputs_decode is not None: + inputs_decode = self._pad_across_processes(inputs_decode) + inputs_decode = self._nested_gather(inputs_decode) + inputs_host = ( + inputs_decode + if inputs_host is None + else nested_concat(inputs_host, inputs_decode, padding_index=-100) + ) + if logits is not None: + logits = self._pad_across_processes(logits) + if self.preprocess_logits_for_metrics is not None: + logits = self.preprocess_logits_for_metrics(logits, labels) + logits = self._nested_gather(logits) + preds_host = logits if preds_host is None else nested_concat(preds_host, logits, padding_index=-100) + if labels is not None: + labels = self._nested_gather(labels) + labels_host = labels if labels_host is None else nested_concat(labels_host, labels, padding_index=-100) + self.control = self.callback_handler.on_prediction_step(args, self.state, self.control) + + # Gather all tensors and put them back on the CPU if we have done enough accumulation steps. + if args.eval_accumulation_steps is not None and (step + 1) % args.eval_accumulation_steps == 0: + if losses_host is not None: + losses = nested_numpify(losses_host) + all_losses = losses if all_losses is None else np.concatenate((all_losses, losses), axis=0) + if preds_host is not None: + logits = nested_numpify(preds_host) + all_preds = logits if all_preds is None else nested_concat(all_preds, logits, padding_index=-100) + if inputs_host is not None: + inputs_decode = nested_numpify(inputs_host) + all_inputs = ( + inputs_decode + if all_inputs is None + else nested_concat(all_inputs, inputs_decode, padding_index=-100) + ) + if labels_host is not None: + labels = nested_numpify(labels_host) + all_labels = ( + labels if all_labels is None else nested_concat(all_labels, labels, padding_index=-100) + ) + + # Set back to None to begin a new accumulation + losses_host, preds_host, inputs_host, labels_host = None, None, None, None + + if args.past_index and hasattr(self, "_past"): + # Clean the state at the end of the evaluation loop + delattr(self, "_past") + + # Gather all remaining tensors and put them back on the CPU + if losses_host is not None: + losses = nested_numpify(losses_host) + all_losses = losses if all_losses is None else np.concatenate((all_losses, losses), axis=0) + if preds_host is not None: + logits = nested_numpify(preds_host) + all_preds = logits if all_preds is None else nested_concat(all_preds, logits, padding_index=-100) + if inputs_host is not None: + inputs_decode = nested_numpify(inputs_host) + all_inputs = ( + inputs_decode if all_inputs is None else nested_concat(all_inputs, inputs_decode, padding_index=-100) + ) + if labels_host is not None: + labels = nested_numpify(labels_host) + all_labels = labels if all_labels is None else nested_concat(all_labels, labels, padding_index=-100) + + # Number of samples + if has_length(eval_dataset): + num_samples = len(eval_dataset) + # The instance check is weird and does not actually check for the type, but whether the dataset has the right + # methods. Therefore we need to make sure it also has the attribute. + elif isinstance(eval_dataset, IterableDatasetShard) and getattr(eval_dataset, "num_examples", 0) > 0: + num_samples = eval_dataset.num_examples + else: + if has_length(dataloader): + num_samples = self.num_examples(dataloader) + else: # both len(dataloader.dataset) and len(dataloader) fail + num_samples = observed_num_examples + if num_samples == 0 and observed_num_examples > 0: + num_samples = observed_num_examples + + # Number of losses has been rounded to a multiple of batch_size and in a distributed training, the number of + # samplers has been rounded to a multiple of batch_size, so we truncate. + if all_losses is not None: + all_losses = all_losses[:num_samples] + if all_preds is not None: + all_preds = nested_truncate(all_preds, num_samples) + if all_labels is not None: + all_labels = nested_truncate(all_labels, num_samples) + if all_inputs is not None: + all_inputs = nested_truncate(all_inputs, num_samples) + + # Metrics! + if self.compute_metrics is not None and all_preds is not None and all_labels is not None: + if args.include_inputs_for_metrics: + metrics = self.compute_metrics( + EvalPrediction(predictions=all_preds, label_ids=all_labels, inputs=all_inputs) + ) + else: + metrics = self.compute_metrics(EvalPrediction(predictions=all_preds, label_ids=all_labels)) + else: + metrics = {} + + # To be JSON-serializable, we need to remove numpy types or zero-d tensors + metrics = denumpify_detensorize(metrics) + + if all_losses is not None: + metrics[f"{metric_key_prefix}_loss"] = all_losses.mean().item() + if hasattr(self, "jit_compilation_time"): + metrics[f"{metric_key_prefix}_jit_compilation_time"] = self.jit_compilation_time + + # Prefix all keys with metric_key_prefix + '_' + for key in list(metrics.keys()): + if not key.startswith(f"{metric_key_prefix}_"): + metrics[f"{metric_key_prefix}_{key}"] = metrics.pop(key) + + return EvalLoopOutput(predictions=all_preds, label_ids=all_labels, metrics=metrics, num_samples=num_samples) + + def _nested_gather(self, tensors, name=None): + """ + Gather value of `tensors` (tensor or list/tuple of nested tensors) and convert them to numpy before + concatenating them to `gathered` + """ + if tensors is None: + return + if is_torch_tpu_available(): + if name is None: + name = "nested_gather" + tensors = nested_xla_mesh_reduce(tensors, name) + elif is_sagemaker_mp_enabled(): + tensors = smp_gather(tensors) + elif self.args.parallel_mode == ParallelMode.DISTRIBUTED: + tensors = distributed_concat(tensors) + return tensors + + # Copied from Accelerate. + def _pad_across_processes(self, tensor, pad_index=-100): + """ + Recursively pad the tensors in a nested list/tuple/dictionary of tensors from all devices to the same size so + they can safely be gathered. + """ + if isinstance(tensor, (list, tuple)): + return type(tensor)(self._pad_across_processes(t, pad_index=pad_index) for t in tensor) + elif isinstance(tensor, dict): + return type(tensor)({k: self._pad_across_processes(v, pad_index=pad_index) for k, v in tensor.items()}) + elif not isinstance(tensor, torch.Tensor): + raise TypeError( + f"Can't pad the values of type {type(tensor)}, only of nested list/tuple/dicts of tensors." + ) + + if len(tensor.shape) < 2: + return tensor + # Gather all sizes + size = torch.tensor(tensor.shape, device=tensor.device)[None] + sizes = self._nested_gather(size).cpu() + + max_size = max(s[1] for s in sizes) + # When extracting XLA graphs for compilation, max_size is 0, + # so use inequality to avoid errors. + if tensor.shape[1] >= max_size: + return tensor + + # Then pad to the maximum size + old_size = tensor.shape + new_size = list(old_size) + new_size[1] = max_size + new_tensor = tensor.new_zeros(tuple(new_size)) + pad_index + new_tensor[:, : old_size[1]] = tensor + return new_tensor + + def prediction_step( + self, + model: nn.Module, + inputs: Dict[str, Union[torch.Tensor, Any]], + prediction_loss_only: bool, + ignore_keys: Optional[List[str]] = None, + ) -> Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]: + """ + Perform an evaluation step on `model` using `inputs`. + + Subclass and override to inject custom behavior. + + Args: + model (`nn.Module`): + The model to evaluate. + inputs (`Dict[str, Union[torch.Tensor, Any]]`): + The inputs and targets of the model. + + The dictionary will be unpacked before being fed to the model. Most models expect the targets under the + argument `labels`. Check your model's documentation for all accepted arguments. + prediction_loss_only (`bool`): + Whether or not to return the loss only. + ignore_keys (`List[str]`, *optional*): + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions. + + Return: + Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]: A tuple with the loss, + logits and labels (each being optional). + """ + has_labels = False if len(self.label_names) == 0 else all(inputs.get(k) is not None for k in self.label_names) + # For CLIP-like models capable of returning loss values. + # If `return_loss` is not specified or being `None` in `inputs`, we check if the default value of `return_loss` + # is `True` in `model.forward`. + return_loss = inputs.get("return_loss", None) + if return_loss is None: + return_loss = self.can_return_loss + loss_without_labels = True if len(self.label_names) == 0 and return_loss else False + + inputs = self._prepare_inputs(inputs) + if ignore_keys is None: + if hasattr(self.model, "config"): + ignore_keys = getattr(self.model.config, "keys_to_ignore_at_inference", []) + else: + ignore_keys = [] + + # labels may be popped when computing the loss (label smoothing for instance) so we grab them first. + if has_labels or loss_without_labels: + labels = nested_detach(tuple(inputs.get(name) for name in self.label_names)) + if len(labels) == 1: + labels = labels[0] + else: + labels = None + + with torch.no_grad(): + if is_sagemaker_mp_enabled(): + raw_outputs = smp_forward_only(model, inputs) + if has_labels or loss_without_labels: + if isinstance(raw_outputs, dict): + loss_mb = raw_outputs["loss"] + logits_mb = tuple(v for k, v in raw_outputs.items() if k not in ignore_keys + ["loss"]) + else: + loss_mb = raw_outputs[0] + logits_mb = raw_outputs[1:] + + loss = loss_mb.reduce_mean().detach().cpu() + logits = smp_nested_concat(logits_mb) + else: + loss = None + if isinstance(raw_outputs, dict): + logits_mb = tuple(v for k, v in raw_outputs.items() if k not in ignore_keys) + else: + logits_mb = raw_outputs + logits = smp_nested_concat(logits_mb) + else: + if has_labels or loss_without_labels: + with self.compute_loss_context_manager(): + loss, outputs = self.compute_loss(model, inputs, return_outputs=True) + loss = loss.mean().detach() + + if isinstance(outputs, dict): + logits = tuple(v for k, v in outputs.items() if k not in ignore_keys + ["loss"]) + else: + logits = outputs[1:] + else: + loss = None + with self.compute_loss_context_manager(): + outputs = model(**inputs) + if isinstance(outputs, dict): + logits = tuple(v for k, v in outputs.items() if k not in ignore_keys) + else: + logits = outputs + # TODO: this needs to be fixed and made cleaner later. + if self.args.past_index >= 0: + self._past = outputs[self.args.past_index - 1] + + if prediction_loss_only: + return (loss, None, None) + + logits = nested_detach(logits) + if len(logits) == 1: + logits = logits[0] + + return (loss, logits, labels) + + def floating_point_ops(self, inputs: Dict[str, Union[torch.Tensor, Any]]): + """ + For models that inherit from [`PreTrainedModel`], uses that method to compute the number of floating point + operations for every backward + forward pass. If using another model, either implement such a method in the + model or subclass and override this method. + + Args: + inputs (`Dict[str, Union[torch.Tensor, Any]]`): + The inputs and targets of the model. + + Returns: + `int`: The number of floating-point operations. + """ + if hasattr(self.model, "floating_point_ops"): + return self.model.floating_point_ops(inputs) + else: + return 0 + + def init_git_repo(self, at_init: bool = False): + """ + Initializes a git repo in `self.args.hub_model_id`. + + Args: + at_init (`bool`, *optional*, defaults to `False`): + Whether this function is called before any training or not. If `self.args.overwrite_output_dir` is + `True` and `at_init` is `True`, the path to the repo (which is `self.args.output_dir`) might be wiped + out. + """ + if not self.is_world_process_zero(): + return + if self.args.hub_model_id is None: + repo_name = Path(self.args.output_dir).absolute().name + else: + repo_name = self.args.hub_model_id + if "/" not in repo_name: + repo_name = get_full_repo_name(repo_name, token=self.args.hub_token) + + # Make sure the repo exists. + create_repo(repo_name, token=self.args.hub_token, private=self.args.hub_private_repo, exist_ok=True) + try: + self.repo = Repository(self.args.output_dir, clone_from=repo_name, token=self.args.hub_token) + except EnvironmentError: + if self.args.overwrite_output_dir and at_init: + # Try again after wiping output_dir + shutil.rmtree(self.args.output_dir) + self.repo = Repository(self.args.output_dir, clone_from=repo_name, token=self.args.hub_token) + else: + raise + + self.repo.git_pull() + + # By default, ignore the checkpoint folders + if ( + not os.path.exists(os.path.join(self.args.output_dir, ".gitignore")) + and self.args.hub_strategy != HubStrategy.ALL_CHECKPOINTS + ): + with open(os.path.join(self.args.output_dir, ".gitignore"), "w", encoding="utf-8") as writer: + writer.writelines(["checkpoint-*/"]) + + # Add "*.sagemaker" to .gitignore if using SageMaker + if os.environ.get("SM_TRAINING_ENV"): + self._add_sm_patterns_to_gitignore() + + self.push_in_progress = None + + def create_model_card( + self, + language: Optional[str] = None, + license: Optional[str] = None, + tags: Union[str, List[str], None] = None, + model_name: Optional[str] = None, + finetuned_from: Optional[str] = None, + tasks: Union[str, List[str], None] = None, + dataset_tags: Union[str, List[str], None] = None, + dataset: Union[str, List[str], None] = None, + dataset_args: Union[str, List[str], None] = None, + ): + """ + Creates a draft of a model card using the information available to the `Trainer`. + + Args: + language (`str`, *optional*): + The language of the model (if applicable) + license (`str`, *optional*): + The license of the model. Will default to the license of the pretrained model used, if the original + model given to the `Trainer` comes from a repo on the Hub. + tags (`str` or `List[str]`, *optional*): + Some tags to be included in the metadata of the model card. + model_name (`str`, *optional*): + The name of the model. + finetuned_from (`str`, *optional*): + The name of the model used to fine-tune this one (if applicable). Will default to the name of the repo + of the original model given to the `Trainer` (if it comes from the Hub). + tasks (`str` or `List[str]`, *optional*): + One or several task identifiers, to be included in the metadata of the model card. + dataset_tags (`str` or `List[str]`, *optional*): + One or several dataset tags, to be included in the metadata of the model card. + dataset (`str` or `List[str]`, *optional*): + One or several dataset identifiers, to be included in the metadata of the model card. + dataset_args (`str` or `List[str]`, *optional*): + One or several dataset arguments, to be included in the metadata of the model card. + """ + if not self.is_world_process_zero(): + return + + training_summary = TrainingSummary.from_trainer( + self, + language=language, + license=license, + tags=tags, + model_name=model_name, + finetuned_from=finetuned_from, + tasks=tasks, + dataset_tags=dataset_tags, + dataset=dataset, + dataset_args=dataset_args, + ) + model_card = training_summary.to_model_card() + with open(os.path.join(self.args.output_dir, "README.md"), "w") as f: + f.write(model_card) + + def _push_from_checkpoint(self, checkpoint_folder): + # Only push from one node. + if not self.is_world_process_zero() or self.args.hub_strategy == HubStrategy.END: + return + # If we haven't finished the last push, we don't do this one. + if self.push_in_progress is not None and not self.push_in_progress.is_done: + return + + output_dir = self.args.output_dir + # To avoid a new synchronization of all model weights, we just copy the file from the checkpoint folder + modeling_files = [CONFIG_NAME, WEIGHTS_NAME, SAFE_WEIGHTS_NAME] + for modeling_file in modeling_files: + if os.path.isfile(os.path.join(checkpoint_folder, modeling_file)): + shutil.copy(os.path.join(checkpoint_folder, modeling_file), os.path.join(output_dir, modeling_file)) + # Saving the tokenizer is fast and we don't know how many files it may have spawned, so we resave it to be sure. + if self.tokenizer is not None: + self.tokenizer.save_pretrained(output_dir) + # Same for the training arguments + torch.save(self.args, os.path.join(output_dir, TRAINING_ARGS_NAME)) + + try: + if self.args.hub_strategy == HubStrategy.CHECKPOINT: + # Temporarily move the checkpoint just saved for the push + tmp_checkpoint = os.path.join(output_dir, "last-checkpoint") + # We have to remove the "last-checkpoint" dir if it exists, otherwise the checkpoint is moved as a + # subfolder. + if os.path.isdir(tmp_checkpoint): + shutil.rmtree(tmp_checkpoint) + shutil.move(checkpoint_folder, tmp_checkpoint) + + if self.args.save_strategy == IntervalStrategy.STEPS: + commit_message = f"Training in progress, step {self.state.global_step}" + else: + commit_message = f"Training in progress, epoch {int(self.state.epoch)}" + _, self.push_in_progress = self.repo.push_to_hub( + commit_message=commit_message, blocking=False, auto_lfs_prune=True + ) + finally: + if self.args.hub_strategy == HubStrategy.CHECKPOINT: + # Move back the checkpoint to its place + shutil.move(tmp_checkpoint, checkpoint_folder) + + def push_to_hub(self, commit_message: Optional[str] = "End of training", blocking: bool = True, **kwargs) -> str: + """ + Upload *self.model* and *self.tokenizer* to the 🤗 model hub on the repo *self.args.hub_model_id*. + + Parameters: + commit_message (`str`, *optional*, defaults to `"End of training"`): + Message to commit while pushing. + blocking (`bool`, *optional*, defaults to `True`): + Whether the function should return only when the `git push` has finished. + kwargs: + Additional keyword arguments passed along to [`~Trainer.create_model_card`]. + + Returns: + The url of the commit of your model in the given repository if `blocking=False`, a tuple with the url of + the commit and an object to track the progress of the commit if `blocking=True` + """ + # If a user calls manually `push_to_hub` with `self.args.push_to_hub = False`, we try to create the repo but + # it might fail. + if not hasattr(self, "repo"): + self.init_git_repo() + + model_name = kwargs.pop("model_name", None) + if model_name is None and self.args.should_save: + if self.args.hub_model_id is None: + model_name = Path(self.args.output_dir).name + else: + model_name = self.args.hub_model_id.split("/")[-1] + + # Needs to be executed on all processes for TPU training, but will only save on the processed determined by + # self.args.should_save. + self.save_model(_internal_call=True) + + # Only push from one node. + if not self.is_world_process_zero(): + return + + # Cancel any async push in progress if blocking=True. The commits will all be pushed together. + if blocking and self.push_in_progress is not None and not self.push_in_progress.is_done: + self.push_in_progress._process.kill() + self.push_in_progress = None + + git_head_commit_url = self.repo.push_to_hub( + commit_message=commit_message, blocking=blocking, auto_lfs_prune=True + ) + # push separately the model card to be independant from the rest of the model + if self.args.should_save: + self.create_model_card(model_name=model_name, **kwargs) + try: + self.repo.push_to_hub( + commit_message="update model card README.md", blocking=blocking, auto_lfs_prune=True + ) + except EnvironmentError as exc: + logger.error(f"Error pushing update to the model card. Please read logs and retry.\n${exc}") + + return git_head_commit_url + + # + # Deprecated code + # + + def prediction_loop( + self, + dataloader: DataLoader, + description: str, + prediction_loss_only: Optional[bool] = None, + ignore_keys: Optional[List[str]] = None, + metric_key_prefix: str = "eval", + ) -> EvalLoopOutput: + """ + Prediction/evaluation loop, shared by `Trainer.evaluate()` and `Trainer.predict()`. + + Works both with or without labels. + """ + args = self.args + + if not has_length(dataloader): + raise ValueError("dataloader must implement a working __len__") + + prediction_loss_only = prediction_loss_only if prediction_loss_only is not None else args.prediction_loss_only + + # if eval is called w/o train init deepspeed here + if args.deepspeed and not self.deepspeed: + # XXX: eval doesn't have `resume_from_checkpoint` arg but we should be able to do eval + # from the checkpoint eventually + deepspeed_engine, _, _ = deepspeed_init(self, num_training_steps=0, resume_from_checkpoint=None) + self.model = deepspeed_engine.module + self.model_wrapped = deepspeed_engine + self.deepspeed = deepspeed_engine + # XXX: we don't need optim/sched for inference, but this needs to be sorted out, since + # for example the Z3-optimizer is a must for zero3 to work even for inference - what we + # don't need is the deepspeed basic optimizer which is self.optimizer.optimizer + deepspeed_engine.optimizer.optimizer = None + deepspeed_engine.lr_scheduler = None + + model = self._wrap_model(self.model, training=False, dataloader=dataloader) + + # if full fp16 or bf16 eval is wanted and this ``evaluation`` or ``predict`` isn't called + # while ``train`` is running, cast it to the right dtype first and then put on device + if not self.is_in_train: + if args.fp16_full_eval: + model = model.to(dtype=torch.float16, device=args.device) + elif args.bf16_full_eval: + model = model.to(dtype=torch.bfloat16, device=args.device) + + batch_size = dataloader.batch_size + num_examples = self.num_examples(dataloader) + logger.info(f"***** Running {description} *****") + logger.info(f" Num examples = {num_examples}") + logger.info(f" Batch size = {batch_size}") + losses_host: torch.Tensor = None + preds_host: Union[torch.Tensor, List[torch.Tensor]] = None + labels_host: Union[torch.Tensor, List[torch.Tensor]] = None + inputs_host: Union[torch.Tensor, List[torch.Tensor]] = None + + world_size = max(1, args.world_size) + + eval_losses_gatherer = DistributedTensorGatherer(world_size, num_examples, make_multiple_of=batch_size) + if not prediction_loss_only: + # The actual number of eval_sample can be greater than num_examples in distributed settings (when we pass + # a batch size to the sampler) + make_multiple_of = None + if hasattr(dataloader, "sampler") and isinstance(dataloader.sampler, SequentialDistributedSampler): + make_multiple_of = dataloader.sampler.batch_size + preds_gatherer = DistributedTensorGatherer(world_size, num_examples, make_multiple_of=make_multiple_of) + labels_gatherer = DistributedTensorGatherer(world_size, num_examples, make_multiple_of=make_multiple_of) + inputs_gatherer = DistributedTensorGatherer(world_size, num_examples, make_multiple_of=make_multiple_of) + + model.eval() + + if is_torch_tpu_available(): + dataloader = pl.ParallelLoader(dataloader, [args.device]).per_device_loader(args.device) + + if args.past_index >= 0: + self._past = None + + self.callback_handler.eval_dataloader = dataloader + + for step, inputs in enumerate(dataloader): + loss, logits, labels = self.prediction_step(model, inputs, prediction_loss_only, ignore_keys=ignore_keys) + inputs_decode = self._prepare_input(inputs["input_ids"]) if args.include_inputs_for_metrics else None + + if loss is not None: + losses = loss.repeat(batch_size) + losses_host = losses if losses_host is None else torch.cat((losses_host, losses), dim=0) + if logits is not None: + preds_host = logits if preds_host is None else nested_concat(preds_host, logits, padding_index=-100) + if labels is not None: + labels_host = labels if labels_host is None else nested_concat(labels_host, labels, padding_index=-100) + if inputs_decode is not None: + inputs_host = ( + inputs_decode + if inputs_host is None + else nested_concat(inputs_host, inputs_decode, padding_index=-100) + ) + self.control = self.callback_handler.on_prediction_step(args, self.state, self.control) + + # Gather all tensors and put them back on the CPU if we have done enough accumulation steps. + if args.eval_accumulation_steps is not None and (step + 1) % args.eval_accumulation_steps == 0: + eval_losses_gatherer.add_arrays(self._gather_and_numpify(losses_host, "eval_losses")) + if not prediction_loss_only: + preds_gatherer.add_arrays(self._gather_and_numpify(preds_host, "eval_preds")) + labels_gatherer.add_arrays(self._gather_and_numpify(labels_host, "eval_label_ids")) + inputs_gatherer.add_arrays(self._gather_and_numpify(inputs_host, "eval_inputs_ids")) + + # Set back to None to begin a new accumulation + losses_host, preds_host, labels_host, inputs_host = None, None, None, None + + if args.past_index and hasattr(self, "_past"): + # Clean the state at the end of the evaluation loop + delattr(self, "_past") + + # Gather all remaining tensors and put them back on the CPU + eval_losses_gatherer.add_arrays(self._gather_and_numpify(losses_host, "eval_losses")) + if not prediction_loss_only: + preds_gatherer.add_arrays(self._gather_and_numpify(preds_host, "eval_preds")) + labels_gatherer.add_arrays(self._gather_and_numpify(labels_host, "eval_label_ids")) + inputs_gatherer.add_arrays(self._gather_and_numpify(inputs_host, "eval_inputs_ids")) + + eval_loss = eval_losses_gatherer.finalize() + preds = preds_gatherer.finalize() if not prediction_loss_only else None + label_ids = labels_gatherer.finalize() if not prediction_loss_only else None + inputs_ids = inputs_gatherer.finalize() if not prediction_loss_only else None + + if self.compute_metrics is not None and preds is not None and label_ids is not None: + if args.include_inputs_for_metrics: + metrics = self.compute_metrics( + EvalPrediction(predictions=preds, label_ids=label_ids, inputs=inputs_ids) + ) + else: + metrics = self.compute_metrics(EvalPrediction(predictions=preds, label_ids=label_ids)) + else: + metrics = {} + + # To be JSON-serializable, we need to remove numpy types or zero-d tensors + metrics = denumpify_detensorize(metrics) + + if eval_loss is not None: + metrics[f"{metric_key_prefix}_loss"] = eval_loss.mean().item() + + # Prefix all keys with metric_key_prefix + '_' + for key in list(metrics.keys()): + if not key.startswith(f"{metric_key_prefix}_"): + metrics[f"{metric_key_prefix}_{key}"] = metrics.pop(key) + + return EvalLoopOutput(predictions=preds, label_ids=label_ids, metrics=metrics, num_samples=num_examples) + + def _gather_and_numpify(self, tensors, name): + """ + Gather value of `tensors` (tensor or list/tuple of nested tensors) and convert them to numpy before + concatenating them to `gathered` + """ + if tensors is None: + return + if is_torch_tpu_available(): + tensors = nested_xla_mesh_reduce(tensors, name) + elif is_sagemaker_mp_enabled(): + tensors = smp_gather(tensors) + elif self.args.parallel_mode == ParallelMode.DISTRIBUTED: + tensors = distributed_concat(tensors) + + return nested_numpify(tensors) + + def _add_sm_patterns_to_gitignore(self) -> None: + """Add SageMaker Checkpointing patterns to .gitignore file.""" + # Make sure we only do this on the main process + if not self.is_world_process_zero(): + return + + patterns = ["*.sagemaker-uploading", "*.sagemaker-uploaded"] + + # Get current .gitignore content + if os.path.exists(os.path.join(self.repo.local_dir, ".gitignore")): + with open(os.path.join(self.repo.local_dir, ".gitignore"), "r") as f: + current_content = f.read() + else: + current_content = "" + + # Add the patterns to .gitignore + content = current_content + for pattern in patterns: + if pattern not in content: + if content.endswith("\n"): + content += pattern + else: + content += f"\n{pattern}" + + # Write the .gitignore file if it has changed + if content != current_content: + with open(os.path.join(self.repo.local_dir, ".gitignore"), "w") as f: + logger.debug(f"Writing .gitignore file. Content: {content}") + f.write(content) + + self.repo.git_add(".gitignore") + + # avoid race condition with git status + time.sleep(0.5) + + if not self.repo.is_repo_clean(): + self.repo.git_commit("Add *.sagemaker patterns to .gitignore.") + self.repo.git_push() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_callback.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_callback.py new file mode 100644 index 0000000000000000000000000000000000000000..808c1b4702f976345f91de845cdd3e18684a476e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_callback.py @@ -0,0 +1,582 @@ +# coding=utf-8 +# Copyright 2020-present the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Callbacks to use with the Trainer class and customize the training loop. +""" +import dataclasses +import json +from dataclasses import dataclass +from typing import Dict, List, Optional, Union + +import numpy as np +from tqdm.auto import tqdm + +from .trainer_utils import IntervalStrategy, has_length +from .training_args import TrainingArguments +from .utils import logging + + +logger = logging.get_logger(__name__) + + +@dataclass +class TrainerState: + """ + A class containing the [`Trainer`] inner state that will be saved along the model and optimizer when checkpointing + and passed to the [`TrainerCallback`]. + + + + In all this class, one step is to be understood as one update step. When using gradient accumulation, one update + step may require several forward and backward passes: if you use `gradient_accumulation_steps=n`, then one update + step requires going through *n* batches. + + + + Args: + epoch (`float`, *optional*): + Only set during training, will represent the epoch the training is at (the decimal part being the + percentage of the current epoch completed). + global_step (`int`, *optional*, defaults to 0): + During training, represents the number of update steps completed. + max_steps (`int`, *optional*, defaults to 0): + The number of update steps to do during the current training. + total_flos (`float`, *optional*, defaults to 0): + The total number of floating operations done by the model since the beginning of training (stored as floats + to avoid overflow). + log_history (`List[Dict[str, float]]`, *optional*): + The list of logs done since the beginning of training. + best_metric (`float`, *optional*): + When tracking the best model, the value of the best metric encountered so far. + best_model_checkpoint (`str`, *optional*): + When tracking the best model, the value of the name of the checkpoint for the best model encountered so + far. + is_local_process_zero (`bool`, *optional*, defaults to `True`): + Whether or not this process is the local (e.g., on one machine if training in a distributed fashion on + several machines) main process. + is_world_process_zero (`bool`, *optional*, defaults to `True`): + Whether or not this process is the global main process (when training in a distributed fashion on several + machines, this is only going to be `True` for one process). + is_hyper_param_search (`bool`, *optional*, defaults to `False`): + Whether we are in the process of a hyper parameter search using Trainer.hyperparameter_search. This will + impact the way data will be logged in TensorBoard. + """ + + epoch: Optional[float] = None + global_step: int = 0 + max_steps: int = 0 + num_train_epochs: int = 0 + total_flos: float = 0 + log_history: List[Dict[str, float]] = None + best_metric: Optional[float] = None + best_model_checkpoint: Optional[str] = None + is_local_process_zero: bool = True + is_world_process_zero: bool = True + is_hyper_param_search: bool = False + trial_name: str = None + trial_params: Dict[str, Union[str, float, int, bool]] = None + + def __post_init__(self): + if self.log_history is None: + self.log_history = [] + + def save_to_json(self, json_path: str): + """Save the content of this instance in JSON format inside `json_path`.""" + json_string = json.dumps(dataclasses.asdict(self), indent=2, sort_keys=True) + "\n" + with open(json_path, "w", encoding="utf-8") as f: + f.write(json_string) + + @classmethod + def load_from_json(cls, json_path: str): + """Create an instance from the content of `json_path`.""" + with open(json_path, "r", encoding="utf-8") as f: + text = f.read() + return cls(**json.loads(text)) + + +@dataclass +class TrainerControl: + """ + A class that handles the [`Trainer`] control flow. This class is used by the [`TrainerCallback`] to activate some + switches in the training loop. + + Args: + should_training_stop (`bool`, *optional*, defaults to `False`): + Whether or not the training should be interrupted. + + If `True`, this variable will not be set back to `False`. The training will just stop. + should_epoch_stop (`bool`, *optional*, defaults to `False`): + Whether or not the current epoch should be interrupted. + + If `True`, this variable will be set back to `False` at the beginning of the next epoch. + should_save (`bool`, *optional*, defaults to `False`): + Whether or not the model should be saved at this step. + + If `True`, this variable will be set back to `False` at the beginning of the next step. + should_evaluate (`bool`, *optional*, defaults to `False`): + Whether or not the model should be evaluated at this step. + + If `True`, this variable will be set back to `False` at the beginning of the next step. + should_log (`bool`, *optional*, defaults to `False`): + Whether or not the logs should be reported at this step. + + If `True`, this variable will be set back to `False` at the beginning of the next step. + """ + + should_training_stop: bool = False + should_epoch_stop: bool = False + should_save: bool = False + should_evaluate: bool = False + should_log: bool = False + + def _new_training(self): + """Internal method that resets the variable for a new training.""" + self.should_training_stop = False + + def _new_epoch(self): + """Internal method that resets the variable for a new epoch.""" + self.should_epoch_stop = False + + def _new_step(self): + """Internal method that resets the variable for a new step.""" + self.should_save = False + self.should_evaluate = False + self.should_log = False + + +class TrainerCallback: + """ + A class for objects that will inspect the state of the training loop at some events and take some decisions. At + each of those events the following arguments are available: + + Args: + args ([`TrainingArguments`]): + The training arguments used to instantiate the [`Trainer`]. + state ([`TrainerState`]): + The current state of the [`Trainer`]. + control ([`TrainerControl`]): + The object that is returned to the [`Trainer`] and can be used to make some decisions. + model ([`PreTrainedModel`] or `torch.nn.Module`): + The model being trained. + tokenizer ([`PreTrainedTokenizer`]): + The tokenizer used for encoding the data. + optimizer (`torch.optim.Optimizer`): + The optimizer used for the training steps. + lr_scheduler (`torch.optim.lr_scheduler.LambdaLR`): + The scheduler used for setting the learning rate. + train_dataloader (`torch.utils.data.DataLoader`, *optional*): + The current dataloader used for training. + eval_dataloader (`torch.utils.data.DataLoader`, *optional*): + The current dataloader used for training. + metrics (`Dict[str, float]`): + The metrics computed by the last evaluation phase. + + Those are only accessible in the event `on_evaluate`. + logs (`Dict[str, float]`): + The values to log. + + Those are only accessible in the event `on_log`. + + The `control` object is the only one that can be changed by the callback, in which case the event that changes it + should return the modified version. + + The argument `args`, `state` and `control` are positionals for all events, all the others are grouped in `kwargs`. + You can unpack the ones you need in the signature of the event using them. As an example, see the code of the + simple [`~transformer.PrinterCallback`]. + + Example: + + ```python + class PrinterCallback(TrainerCallback): + def on_log(self, args, state, control, logs=None, **kwargs): + _ = logs.pop("total_flos", None) + if state.is_local_process_zero: + print(logs) + ```""" + + def on_init_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the end of the initialization of the [`Trainer`]. + """ + pass + + def on_train_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the beginning of training. + """ + pass + + def on_train_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the end of training. + """ + pass + + def on_epoch_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the beginning of an epoch. + """ + pass + + def on_epoch_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the end of an epoch. + """ + pass + + def on_step_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the beginning of a training step. If using gradient accumulation, one training step might take + several inputs. + """ + pass + + def on_substep_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the end of an substep during gradient accumulation. + """ + pass + + def on_step_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called at the end of a training step. If using gradient accumulation, one training step might take + several inputs. + """ + pass + + def on_evaluate(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called after an evaluation phase. + """ + pass + + def on_predict(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, metrics, **kwargs): + """ + Event called after a successful prediction. + """ + pass + + def on_save(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called after a checkpoint save. + """ + pass + + def on_log(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called after logging the last logs. + """ + pass + + def on_prediction_step(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + """ + Event called after a prediction step. + """ + pass + + +class CallbackHandler(TrainerCallback): + """Internal class that just calls the list of callbacks in order.""" + + def __init__(self, callbacks, model, tokenizer, optimizer, lr_scheduler): + self.callbacks = [] + for cb in callbacks: + self.add_callback(cb) + self.model = model + self.tokenizer = tokenizer + self.optimizer = optimizer + self.lr_scheduler = lr_scheduler + self.train_dataloader = None + self.eval_dataloader = None + + if not any(isinstance(cb, DefaultFlowCallback) for cb in self.callbacks): + logger.warning( + "The Trainer will not work properly if you don't have a `DefaultFlowCallback` in its callbacks. You\n" + + "should add one before training with `trainer.add_callback(DefaultFlowCallback). The current list of" + + "callbacks is\n:" + + self.callback_list + ) + + def add_callback(self, callback): + cb = callback() if isinstance(callback, type) else callback + cb_class = callback if isinstance(callback, type) else callback.__class__ + if cb_class in [c.__class__ for c in self.callbacks]: + logger.warning( + f"You are adding a {cb_class} to the callbacks of this Trainer, but there is already one. The current" + + "list of callbacks is\n:" + + self.callback_list + ) + self.callbacks.append(cb) + + def pop_callback(self, callback): + if isinstance(callback, type): + for cb in self.callbacks: + if isinstance(cb, callback): + self.callbacks.remove(cb) + return cb + else: + for cb in self.callbacks: + if cb == callback: + self.callbacks.remove(cb) + return cb + + def remove_callback(self, callback): + if isinstance(callback, type): + for cb in self.callbacks: + if isinstance(cb, callback): + self.callbacks.remove(cb) + return + else: + self.callbacks.remove(callback) + + @property + def callback_list(self): + return "\n".join(cb.__class__.__name__ for cb in self.callbacks) + + def on_init_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_init_end", args, state, control) + + def on_train_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + control.should_training_stop = False + return self.call_event("on_train_begin", args, state, control) + + def on_train_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_train_end", args, state, control) + + def on_epoch_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + control.should_epoch_stop = False + return self.call_event("on_epoch_begin", args, state, control) + + def on_epoch_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_epoch_end", args, state, control) + + def on_step_begin(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + control.should_log = False + control.should_evaluate = False + control.should_save = False + return self.call_event("on_step_begin", args, state, control) + + def on_substep_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_substep_end", args, state, control) + + def on_step_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_step_end", args, state, control) + + def on_evaluate(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, metrics): + control.should_evaluate = False + return self.call_event("on_evaluate", args, state, control, metrics=metrics) + + def on_predict(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, metrics): + return self.call_event("on_predict", args, state, control, metrics=metrics) + + def on_save(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + control.should_save = False + return self.call_event("on_save", args, state, control) + + def on_log(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, logs): + control.should_log = False + return self.call_event("on_log", args, state, control, logs=logs) + + def on_prediction_step(self, args: TrainingArguments, state: TrainerState, control: TrainerControl): + return self.call_event("on_prediction_step", args, state, control) + + def call_event(self, event, args, state, control, **kwargs): + for callback in self.callbacks: + result = getattr(callback, event)( + args, + state, + control, + model=self.model, + tokenizer=self.tokenizer, + optimizer=self.optimizer, + lr_scheduler=self.lr_scheduler, + train_dataloader=self.train_dataloader, + eval_dataloader=self.eval_dataloader, + **kwargs, + ) + # A Callback can skip the return of `control` if it doesn't change it. + if result is not None: + control = result + return control + + +class DefaultFlowCallback(TrainerCallback): + """ + A [`TrainerCallback`] that handles the default flow of the training loop for logs, evaluation and checkpoints. + """ + + def on_step_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + # Log + if state.global_step == 1 and args.logging_first_step: + control.should_log = True + if args.logging_strategy == IntervalStrategy.STEPS and state.global_step % args.logging_steps == 0: + control.should_log = True + + # Evaluate + if ( + args.evaluation_strategy == IntervalStrategy.STEPS + and state.global_step % args.eval_steps == 0 + and args.eval_delay <= state.global_step + ): + control.should_evaluate = True + + # Save + if ( + args.save_strategy == IntervalStrategy.STEPS + and args.save_steps > 0 + and state.global_step % args.save_steps == 0 + ): + control.should_save = True + + # End training + if state.global_step >= state.max_steps: + control.should_training_stop = True + + return control + + def on_epoch_end(self, args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs): + # Log + if args.logging_strategy == IntervalStrategy.EPOCH: + control.should_log = True + + # Evaluate + if args.evaluation_strategy == IntervalStrategy.EPOCH and args.eval_delay <= state.epoch: + control.should_evaluate = True + + # Save + if args.save_strategy == IntervalStrategy.EPOCH: + control.should_save = True + + return control + + +class ProgressCallback(TrainerCallback): + """ + A [`TrainerCallback`] that displays the progress of training or evaluation. + """ + + def __init__(self): + self.training_bar = None + self.prediction_bar = None + + def on_train_begin(self, args, state, control, **kwargs): + if state.is_local_process_zero: + self.training_bar = tqdm(total=state.max_steps) + self.current_step = 0 + + def on_step_end(self, args, state, control, **kwargs): + if state.is_local_process_zero: + self.training_bar.update(state.global_step - self.current_step) + self.current_step = state.global_step + + def on_prediction_step(self, args, state, control, eval_dataloader=None, **kwargs): + if state.is_local_process_zero and has_length(eval_dataloader): + if self.prediction_bar is None: + self.prediction_bar = tqdm(total=len(eval_dataloader), leave=self.training_bar is None) + self.prediction_bar.update(1) + + def on_evaluate(self, args, state, control, **kwargs): + if state.is_local_process_zero: + if self.prediction_bar is not None: + self.prediction_bar.close() + self.prediction_bar = None + + def on_predict(self, args, state, control, **kwargs): + if state.is_local_process_zero: + if self.prediction_bar is not None: + self.prediction_bar.close() + self.prediction_bar = None + + def on_log(self, args, state, control, logs=None, **kwargs): + if state.is_local_process_zero and self.training_bar is not None: + _ = logs.pop("total_flos", None) + self.training_bar.write(str(logs)) + + def on_train_end(self, args, state, control, **kwargs): + if state.is_local_process_zero: + self.training_bar.close() + self.training_bar = None + + +class PrinterCallback(TrainerCallback): + """ + A bare [`TrainerCallback`] that just prints the logs. + """ + + def on_log(self, args, state, control, logs=None, **kwargs): + _ = logs.pop("total_flos", None) + if state.is_local_process_zero: + print(logs) + + +class EarlyStoppingCallback(TrainerCallback): + """ + A [`TrainerCallback`] that handles early stopping. + + Args: + early_stopping_patience (`int`): + Use with `metric_for_best_model` to stop training when the specified metric worsens for + `early_stopping_patience` evaluation calls. + early_stopping_threshold(`float`, *optional*): + Use with TrainingArguments `metric_for_best_model` and `early_stopping_patience` to denote how much the + specified metric must improve to satisfy early stopping conditions. ` + + This callback depends on [`TrainingArguments`] argument *load_best_model_at_end* functionality to set best_metric + in [`TrainerState`]. Note that if the [`TrainingArguments`] argument *save_steps* differs from *eval_steps*, the + early stopping will not occur until the next save step. + """ + + def __init__(self, early_stopping_patience: int = 1, early_stopping_threshold: Optional[float] = 0.0): + self.early_stopping_patience = early_stopping_patience + self.early_stopping_threshold = early_stopping_threshold + # early_stopping_patience_counter denotes the number of times validation metrics failed to improve. + self.early_stopping_patience_counter = 0 + + def check_metric_value(self, args, state, control, metric_value): + # best_metric is set by code for load_best_model + operator = np.greater if args.greater_is_better else np.less + if state.best_metric is None or ( + operator(metric_value, state.best_metric) + and abs(metric_value - state.best_metric) > self.early_stopping_threshold + ): + self.early_stopping_patience_counter = 0 + else: + self.early_stopping_patience_counter += 1 + + def on_train_begin(self, args, state, control, **kwargs): + assert args.load_best_model_at_end, "EarlyStoppingCallback requires load_best_model_at_end = True" + assert ( + args.metric_for_best_model is not None + ), "EarlyStoppingCallback requires metric_for_best_model is defined" + assert ( + args.evaluation_strategy != IntervalStrategy.NO + ), "EarlyStoppingCallback requires IntervalStrategy of steps or epoch" + + def on_evaluate(self, args, state, control, metrics, **kwargs): + metric_to_check = args.metric_for_best_model + if not metric_to_check.startswith("eval_"): + metric_to_check = f"eval_{metric_to_check}" + metric_value = metrics.get(metric_to_check) + + if metric_value is None: + logger.warning( + f"early stopping required metric_for_best_model, but did not find {metric_to_check} so early stopping" + " is disabled" + ) + return + + self.check_metric_value(args, state, control, metric_value) + if self.early_stopping_patience_counter >= self.early_stopping_patience: + control.should_training_stop = True diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_pt_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_pt_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..dee1dce0f6f741749ea2104300db66fa186c4d77 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_pt_utils.py @@ -0,0 +1,1124 @@ +# coding=utf-8 +# Copyright 2020-present the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Torch utilities for the Trainer class. +""" + +import datetime +import json +import math +import os +import sys +import warnings +from collections.abc import Mapping +from contextlib import contextmanager +from dataclasses import dataclass +from logging import StreamHandler +from typing import Any, Dict, Iterator, List, Optional, Union + +import numpy as np +import torch +import torch.distributed as dist +from torch import nn +from torch.utils.data import Dataset, IterableDataset, RandomSampler, Sampler +from torch.utils.data.distributed import DistributedSampler + +from .deepspeed import is_deepspeed_zero3_enabled +from .tokenization_utils_base import BatchEncoding +from .utils import is_sagemaker_mp_enabled, is_torch_tpu_available, is_training_run_on_sagemaker, logging + + +if is_training_run_on_sagemaker(): + logging.add_handler(StreamHandler(sys.stdout)) + +if is_torch_tpu_available(check_device=False): + import torch_xla.core.xla_model as xm + +# this is used to suppress an undesired warning emitted by pytorch versions 1.4.2-1.7.0 +try: + from torch.optim.lr_scheduler import SAVE_STATE_WARNING +except ImportError: + SAVE_STATE_WARNING = "" + +logger = logging.get_logger(__name__) + + +def atleast_1d(tensor_or_array: Union[torch.Tensor, np.ndarray]): + if isinstance(tensor_or_array, torch.Tensor): + if hasattr(torch, "atleast_1d"): + tensor_or_array = torch.atleast_1d(tensor_or_array) + elif tensor_or_array.ndim < 1: + tensor_or_array = tensor_or_array[None] + else: + tensor_or_array = np.atleast_1d(tensor_or_array) + return tensor_or_array + + +def torch_pad_and_concatenate(tensor1, tensor2, padding_index=-100): + """Concatenates `tensor1` and `tensor2` on first axis, applying padding on the second if necessary.""" + tensor1 = atleast_1d(tensor1) + tensor2 = atleast_1d(tensor2) + + if len(tensor1.shape) == 1 or tensor1.shape[1] == tensor2.shape[1]: + return torch.cat((tensor1, tensor2), dim=0) + + # Let's figure out the new shape + new_shape = (tensor1.shape[0] + tensor2.shape[0], max(tensor1.shape[1], tensor2.shape[1])) + tensor1.shape[2:] + + # Now let's fill the result tensor + result = tensor1.new_full(new_shape, padding_index) + result[: tensor1.shape[0], : tensor1.shape[1]] = tensor1 + result[tensor1.shape[0] :, : tensor2.shape[1]] = tensor2 + return result + + +def numpy_pad_and_concatenate(array1, array2, padding_index=-100): + """Concatenates `array1` and `array2` on first axis, applying padding on the second if necessary.""" + array1 = atleast_1d(array1) + array2 = atleast_1d(array2) + + if len(array1.shape) == 1 or array1.shape[1] == array2.shape[1]: + return np.concatenate((array1, array2), axis=0) + + # Let's figure out the new shape + new_shape = (array1.shape[0] + array2.shape[0], max(array1.shape[1], array2.shape[1])) + array1.shape[2:] + + # Now let's fill the result tensor + result = np.full_like(array1, padding_index, shape=new_shape) + result[: array1.shape[0], : array1.shape[1]] = array1 + result[array1.shape[0] :, : array2.shape[1]] = array2 + return result + + +def nested_concat(tensors, new_tensors, padding_index=-100): + """ + Concat the `new_tensors` to `tensors` on the first dim and pad them on the second if needed. Works for tensors or + nested list/tuples/dict of tensors. + """ + assert type(tensors) == type( + new_tensors + ), f"Expected `tensors` and `new_tensors` to have the same type but found {type(tensors)} and {type(new_tensors)}." + if isinstance(tensors, (list, tuple)): + return type(tensors)(nested_concat(t, n, padding_index=padding_index) for t, n in zip(tensors, new_tensors)) + elif isinstance(tensors, torch.Tensor): + return torch_pad_and_concatenate(tensors, new_tensors, padding_index=padding_index) + elif isinstance(tensors, Mapping): + return type(tensors)( + {k: nested_concat(t, new_tensors[k], padding_index=padding_index) for k, t in tensors.items()} + ) + elif isinstance(tensors, np.ndarray): + return numpy_pad_and_concatenate(tensors, new_tensors, padding_index=padding_index) + else: + raise TypeError(f"Unsupported type for concatenation: got {type(tensors)}") + + +def find_batch_size(tensors): + """ + Find the first dimension of a tensor in a nested list/tuple/dict of tensors. + """ + if isinstance(tensors, (list, tuple)): + for t in tensors: + result = find_batch_size(t) + if result is not None: + return result + elif isinstance(tensors, Mapping): + for key, value in tensors.items(): + result = find_batch_size(value) + if result is not None: + return result + elif isinstance(tensors, torch.Tensor): + return tensors.shape[0] if len(tensors.shape) >= 1 else None + elif isinstance(tensors, np.ndarray): + return tensors.shape[0] if len(tensors.shape) >= 1 else None + + +def nested_numpify(tensors): + "Numpify `tensors` (even if it's a nested list/tuple/dict of tensors)." + if isinstance(tensors, (list, tuple)): + return type(tensors)(nested_numpify(t) for t in tensors) + if isinstance(tensors, Mapping): + return type(tensors)({k: nested_numpify(t) for k, t in tensors.items()}) + + t = tensors.cpu() + if t.dtype == torch.bfloat16: + # As of Numpy 1.21.4, NumPy does not support bfloat16 (see + # https://github.com/numpy/numpy/blob/a47ecdea856986cd60eabbd53265c2ca5916ad5d/doc/source/user/basics.types.rst ). + # Until Numpy adds bfloat16, we must convert float32. + t = t.to(torch.float32) + return t.numpy() + + +def nested_detach(tensors): + "Detach `tensors` (even if it's a nested list/tuple/dict of tensors)." + if isinstance(tensors, (list, tuple)): + return type(tensors)(nested_detach(t) for t in tensors) + elif isinstance(tensors, Mapping): + return type(tensors)({k: nested_detach(t) for k, t in tensors.items()}) + return tensors.detach() + + +def nested_xla_mesh_reduce(tensors, name): + if is_torch_tpu_available(): + import torch_xla.core.xla_model as xm + + if isinstance(tensors, (list, tuple)): + return type(tensors)(nested_xla_mesh_reduce(t, f"{name}_{i}") for i, t in enumerate(tensors)) + if isinstance(tensors, Mapping): + return type(tensors)( + {k: nested_xla_mesh_reduce(t, f"{name}_{i}") for i, (k, t) in enumerate(tensors.items())} + ) + + tensors = atleast_1d(tensors) + return xm.mesh_reduce(name, tensors, torch.cat) + else: + raise ImportError("Torch xla must be installed to use `nested_xla_mesh_reduce`") + + +def distributed_concat(tensor: Any, num_total_examples: Optional[int] = None) -> Any: + try: + if isinstance(tensor, (tuple, list)): + return type(tensor)(distributed_concat(t, num_total_examples) for t in tensor) + if isinstance(tensor, Mapping): + return type(tensor)({k: distributed_concat(t, num_total_examples) for k, t in tensor.items()}) + tensor = atleast_1d(tensor).contiguous() + output_tensors = [tensor.clone() for _ in range(dist.get_world_size())] + dist.all_gather(output_tensors, tensor) + concat = torch.cat(output_tensors, dim=0) + + # truncate the dummy elements added by SequentialDistributedSampler + if num_total_examples is not None: + concat = concat[:num_total_examples] + return concat + except AssertionError: + raise AssertionError("Not currently using distributed training") + + +def distributed_broadcast_scalars( + scalars: List[Union[int, float]], + num_total_examples: Optional[int] = None, + device: Optional[torch.device] = torch.device("cuda"), +) -> torch.Tensor: + try: + tensorized_scalar = torch.tensor(scalars).to(device) + output_tensors = [tensorized_scalar.clone() for _ in range(dist.get_world_size())] + dist.all_gather(output_tensors, tensorized_scalar) + concat = torch.cat(output_tensors, dim=0) + + # truncate the dummy elements added by SequentialDistributedSampler + if num_total_examples is not None: + concat = concat[:num_total_examples] + return concat + except AssertionError: + raise AssertionError("Not currently using distributed training") + + +def reissue_pt_warnings(caught_warnings): + # Reissue warnings that are not the SAVE_STATE_WARNING + if len(caught_warnings) > 1: + for w in caught_warnings: + if w.category != UserWarning or w.message != SAVE_STATE_WARNING: + warnings.warn(w.message, w.category) + + +@contextmanager +def torch_distributed_zero_first(local_rank: int): + """ + Decorator to make all processes in distributed training wait for each local_master to do something. + + Args: + local_rank (`int`): The rank of the local process. + """ + if local_rank not in [-1, 0]: + dist.barrier() + yield + if local_rank == 0: + dist.barrier() + + +class DistributedSamplerWithLoop(DistributedSampler): + """ + Like a torch.utils.data.distributed.DistributedSampler` but loops at the end back to the beginning of the shuffled + samples to make each process have a round multiple of batch_size samples. + + Args: + dataset (`torch.utils.data.Dataset`): + Dataset used for sampling. + batch_size (`int`): + The batch size used with this sampler + kwargs: + All other keyword arguments passed to `DistributedSampler`. + """ + + def __init__(self, dataset, batch_size, **kwargs): + super().__init__(dataset, **kwargs) + self.batch_size = batch_size + + def __iter__(self): + indices = list(super().__iter__()) + remainder = 0 if len(indices) % self.batch_size == 0 else self.batch_size - len(indices) % self.batch_size + # DistributedSampler already added samples from the beginning to make the number of samples a round multiple + # of the world size, so we skip those. + start_remainder = 1 if self.rank < len(self.dataset) % self.num_replicas else 0 + indices += indices[start_remainder : start_remainder + remainder] + return iter(indices) + + +class SequentialDistributedSampler(Sampler): + """ + Distributed Sampler that subsamples indices sequentially, making it easier to collate all results at the end. + + Even though we only use this sampler for eval and predict (no training), which means that the model params won't + have to be synced (i.e. will not hang for synchronization even if varied number of forward passes), we still add + extra samples to the sampler to make it evenly divisible (like in `DistributedSampler`) to make it easy to `gather` + or `reduce` resulting tensors at the end of the loop. + """ + + def __init__(self, dataset, num_replicas=None, rank=None, batch_size=None): + warnings.warn( + "SequentialDistributedSampler is deprecated and will be removed in v5 of Transformers.", + FutureWarning, + ) + if num_replicas is None: + if not dist.is_available(): + raise RuntimeError("Requires distributed package to be available") + num_replicas = dist.get_world_size() + if rank is None: + if not dist.is_available(): + raise RuntimeError("Requires distributed package to be available") + rank = dist.get_rank() + self.dataset = dataset + self.num_replicas = num_replicas + self.rank = rank + num_samples = len(self.dataset) + # Add extra samples to make num_samples a multiple of batch_size if passed + if batch_size is not None: + self.num_samples = int(math.ceil(num_samples / (batch_size * num_replicas))) * batch_size + else: + self.num_samples = int(math.ceil(num_samples / num_replicas)) + self.total_size = self.num_samples * self.num_replicas + self.batch_size = batch_size + + def __iter__(self): + indices = list(range(len(self.dataset))) + + # add extra samples to make it evenly divisible + indices += indices[: (self.total_size - len(indices))] + assert ( + len(indices) == self.total_size + ), f"Indices length {len(indices)} and total size {self.total_size} mismatched" + + # subsample + indices = indices[self.rank * self.num_samples : (self.rank + 1) * self.num_samples] + assert ( + len(indices) == self.num_samples + ), f"Indices length {len(indices)} and sample number {self.num_samples} mismatched" + + return iter(indices) + + def __len__(self): + return self.num_samples + + +def get_tpu_sampler(dataset: torch.utils.data.Dataset, batch_size: int): + if xm.xrt_world_size() <= 1: + return RandomSampler(dataset) + return DistributedSampler(dataset, num_replicas=xm.xrt_world_size(), rank=xm.get_ordinal()) + + +def nested_new_like(arrays, num_samples, padding_index=-100): + """Create the same nested structure as `arrays` with a first dimension always at `num_samples`.""" + if isinstance(arrays, (list, tuple)): + return type(arrays)(nested_new_like(x, num_samples) for x in arrays) + return np.full_like(arrays, padding_index, shape=(num_samples, *arrays.shape[1:])) + + +def expand_like(arrays, new_seq_length, padding_index=-100): + """Expand the `arrays` so that the second dimension grows to `new_seq_length`. Uses `padding_index` for padding.""" + result = np.full_like(arrays, padding_index, shape=(arrays.shape[0], new_seq_length) + arrays.shape[2:]) + result[:, : arrays.shape[1]] = arrays + return result + + +def nested_truncate(tensors, limit): + "Truncate `tensors` at `limit` (even if it's a nested list/tuple/dict of tensors)." + if isinstance(tensors, (list, tuple)): + return type(tensors)(nested_truncate(t, limit) for t in tensors) + if isinstance(tensors, Mapping): + return type(tensors)({k: nested_truncate(t, limit) for k, t in tensors.items()}) + + return tensors[:limit] + + +class DistributedTensorGatherer: + """ + A class responsible for properly gathering tensors (or nested list/tuple of tensors) on the CPU by chunks. + + If our dataset has 16 samples with a batch size of 2 on 3 processes and we gather then transfer on CPU at every + step, our sampler will generate the following indices: + + `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1]` + + to get something of size a multiple of 3 (so that each process gets the same dataset length). Then process 0, 1 and + 2 will be responsible of making predictions for the following samples: + + - P0: `[0, 1, 2, 3, 4, 5]` + - P1: `[6, 7, 8, 9, 10, 11]` + - P2: `[12, 13, 14, 15, 0, 1]` + + The first batch treated on each process will be + + - P0: `[0, 1]` + - P1: `[6, 7]` + - P2: `[12, 13]` + + So if we gather at the end of the first batch, we will get a tensor (nested list/tuple of tensor) corresponding to + the following indices: + + `[0, 1, 6, 7, 12, 13]` + + If we directly concatenate our results without taking any precautions, the user will then get the predictions for + the indices in this order at the end of the prediction loop: + + `[0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 0, 1]` + + For some reason, that's not going to roll their boat. This class is there to solve that problem. + + Args: + world_size (`int`): + The number of processes used in the distributed training. + num_samples (`int`): + The number of samples in our dataset. + make_multiple_of (`int`, *optional*): + If passed, the class assumes the datasets passed to each process are made to be a multiple of this argument + (by adding samples). + padding_index (`int`, *optional*, defaults to -100): + The padding index to use if the arrays don't all have the same sequence length. + """ + + def __init__(self, world_size, num_samples, make_multiple_of=None, padding_index=-100): + warnings.warn( + "DistributedTensorGatherer is deprecated and will be removed in v5 of Transformers.", + FutureWarning, + ) + self.world_size = world_size + self.num_samples = num_samples + total_size = world_size if make_multiple_of is None else world_size * make_multiple_of + self.total_samples = int(np.ceil(num_samples / total_size)) * total_size + self.process_length = self.total_samples // world_size + self._storage = None + self._offsets = None + self.padding_index = padding_index + + def add_arrays(self, arrays): + """ + Add `arrays` to the internal storage, Will initialize the storage to the full size at the first arrays passed + so that if we're bound to get an OOM, it happens at the beginning. + """ + if arrays is None: + return + if self._storage is None: + self._storage = nested_new_like(arrays, self.total_samples, padding_index=self.padding_index) + self._offsets = list(range(0, self.total_samples, self.process_length)) + + slice_len, self._storage = self._nested_set_tensors(self._storage, arrays) + for i in range(self.world_size): + self._offsets[i] += slice_len + + def _nested_set_tensors(self, storage, arrays): + if isinstance(arrays, (list, tuple)): + result = [self._nested_set_tensors(x, y) for x, y in zip(storage, arrays)] + return result[0][0], type(arrays)(r[1] for r in result) + assert ( + arrays.shape[0] % self.world_size == 0 + ), f"Arrays passed should all have a first dimension multiple of {self.world_size}, found {arrays.shape[0]}." + + slice_len = arrays.shape[0] // self.world_size + for i in range(self.world_size): + if len(arrays.shape) == 1: + storage[self._offsets[i] : self._offsets[i] + slice_len] = arrays[i * slice_len : (i + 1) * slice_len] + else: + # Expand the array on the fly if needed. + if len(storage.shape) > 1 and storage.shape[1] < arrays.shape[1]: + storage = expand_like(storage, arrays.shape[1], padding_index=self.padding_index) + storage[self._offsets[i] : self._offsets[i] + slice_len, : arrays.shape[1]] = arrays[ + i * slice_len : (i + 1) * slice_len + ] + return slice_len, storage + + def finalize(self): + """ + Return the properly gathered arrays and truncate to the number of samples (since the sampler added some extras + to get each process a dataset of the same length). + """ + if self._storage is None: + return + if self._offsets[0] != self.process_length: + logger.warning("Not all data has been set. Are you sure you passed all values?") + return nested_truncate(self._storage, self.num_samples) + + +@dataclass +class LabelSmoother: + """ + Adds label-smoothing on a pre-computed output from a Transformers model. + + Args: + epsilon (`float`, *optional*, defaults to 0.1): + The label smoothing factor. + ignore_index (`int`, *optional*, defaults to -100): + The index in the labels to ignore when computing the loss. + """ + + epsilon: float = 0.1 + ignore_index: int = -100 + + def __call__(self, model_output, labels, shift_labels=False): + logits = model_output["logits"] if isinstance(model_output, dict) else model_output[0] + if shift_labels: + logits = logits[..., :-1, :].contiguous() + labels = labels[..., 1:].contiguous() + + log_probs = -nn.functional.log_softmax(logits, dim=-1) + if labels.dim() == log_probs.dim() - 1: + labels = labels.unsqueeze(-1) + + padding_mask = labels.eq(self.ignore_index) + # In case the ignore_index is -100, the gather will fail, so we replace labels by 0. The padding_mask + # will ignore them in any case. + labels = torch.clamp(labels, min=0) + nll_loss = log_probs.gather(dim=-1, index=labels) + # works for fp16 input tensor too, by internally upcasting it to fp32 + smoothed_loss = log_probs.sum(dim=-1, keepdim=True, dtype=torch.float32) + + nll_loss.masked_fill_(padding_mask, 0.0) + smoothed_loss.masked_fill_(padding_mask, 0.0) + + # Take the mean over the label dimensions, then divide by the number of active elements (i.e. not-padded): + num_active_elements = padding_mask.numel() - padding_mask.long().sum() + nll_loss = nll_loss.sum() / num_active_elements + smoothed_loss = smoothed_loss.sum() / (num_active_elements * log_probs.shape[-1]) + return (1 - self.epsilon) * nll_loss + self.epsilon * smoothed_loss + + +def get_length_grouped_indices(lengths, batch_size, mega_batch_mult=None, generator=None): + """ + Return a list of indices so that each slice of `batch_size` consecutive indices correspond to elements of similar + lengths. To do this, the indices are: + + - randomly permuted + - grouped in mega-batches of size `mega_batch_mult * batch_size` + - sorted by length in each mega-batch + + The result is the concatenation of all mega-batches, with the batch of `batch_size` containing the element of + maximum length placed first, so that an OOM happens sooner rather than later. + """ + # Default for mega_batch_mult: 50 or the number to get 4 megabatches, whichever is smaller. + if mega_batch_mult is None: + mega_batch_mult = min(len(lengths) // (batch_size * 4), 50) + # Just in case, for tiny datasets + if mega_batch_mult == 0: + mega_batch_mult = 1 + + # We need to use torch for the random part as a distributed sampler will set the random seed for torch. + indices = torch.randperm(len(lengths), generator=generator) + megabatch_size = mega_batch_mult * batch_size + megabatches = [indices[i : i + megabatch_size].tolist() for i in range(0, len(lengths), megabatch_size)] + megabatches = [sorted(megabatch, key=lambda i: lengths[i], reverse=True) for megabatch in megabatches] + + # The rest is to get the biggest batch first. + # Since each megabatch is sorted by descending length, the longest element is the first + megabatch_maximums = [lengths[megabatch[0]] for megabatch in megabatches] + max_idx = torch.argmax(torch.tensor(megabatch_maximums)).item() + # Switch to put the longest element in first position + megabatches[0][0], megabatches[max_idx][0] = megabatches[max_idx][0], megabatches[0][0] + + return [i for megabatch in megabatches for i in megabatch] + + +class LengthGroupedSampler(Sampler): + r""" + Sampler that samples indices in a way that groups together features of the dataset of roughly the same length while + keeping a bit of randomness. + """ + + def __init__( + self, + batch_size: int, + dataset: Optional[Dataset] = None, + lengths: Optional[List[int]] = None, + model_input_name: Optional[str] = None, + generator=None, + ): + if dataset is None and lengths is None: + raise ValueError("One of dataset and lengths must be provided.") + + self.batch_size = batch_size + if lengths is None: + model_input_name = model_input_name if model_input_name is not None else "input_ids" + if ( + not (isinstance(dataset[0], dict) or isinstance(dataset[0], BatchEncoding)) + or model_input_name not in dataset[0] + ): + raise ValueError( + "Can only automatically infer lengths for datasets whose items are dictionaries with an " + f"'{model_input_name}' key." + ) + lengths = [len(feature[model_input_name]) for feature in dataset] + elif isinstance(lengths, torch.Tensor): + logger.info( + "If lengths is a torch.Tensor, LengthGroupedSampler will be slow. Converting lengths to List[int]..." + ) + lengths = lengths.tolist() + + self.lengths = lengths + self.generator = generator + + def __len__(self): + return len(self.lengths) + + def __iter__(self): + indices = get_length_grouped_indices(self.lengths, self.batch_size, generator=self.generator) + return iter(indices) + + +class DistributedLengthGroupedSampler(DistributedSampler): + r""" + Distributed Sampler that samples indices in a way that groups together features of the dataset of roughly the same + length while keeping a bit of randomness. + """ + + # Copied and adapted from PyTorch DistributedSampler. + def __init__( + self, + batch_size: int, + dataset: Optional[Dataset] = None, + num_replicas: Optional[int] = None, + rank: Optional[int] = None, + seed: int = 0, + drop_last: bool = False, + lengths: Optional[List[int]] = None, + model_input_name: Optional[str] = None, + ): + if dataset is None and lengths is None: + raise ValueError("One of dataset and lengths must be provided.") + if num_replicas is None: + if not dist.is_available(): + raise RuntimeError("Requires distributed package to be available") + num_replicas = dist.get_world_size() + if rank is None: + if not dist.is_available(): + raise RuntimeError("Requires distributed package to be available") + rank = dist.get_rank() + + self.batch_size = batch_size + self.num_replicas = num_replicas + self.rank = rank + self.epoch = 0 + self.drop_last = drop_last + + if lengths is None: + model_input_name = model_input_name if model_input_name is not None else "input_ids" + if ( + not (isinstance(dataset[0], dict) or isinstance(dataset[0], BatchEncoding)) + or model_input_name not in dataset[0] + ): + raise ValueError( + "Can only automatically infer lengths for datasets whose items are dictionaries with an " + f"'{model_input_name}' key." + ) + lengths = [len(feature[model_input_name]) for feature in dataset] + elif isinstance(lengths, torch.Tensor): + logger.info( + "If lengths is a torch.Tensor, DistributedLengthGroupedSampler will be slow. Converting lengths to" + " List[int]..." + ) + lengths = lengths.tolist() + + self.lengths = lengths + + # If the dataset length is evenly divisible by # of replicas, then there + # is no need to drop any data, since the dataset will be split equally. + if self.drop_last and len(self.lengths) % self.num_replicas != 0: + # Split to nearest available length that is evenly divisible. + # This is to ensure each rank receives the same amount of data when + # using this Sampler. + self.num_samples = math.ceil((len(self.lengths) - self.num_replicas) / self.num_replicas) + else: + self.num_samples = math.ceil(len(self.lengths) / self.num_replicas) + self.total_size = self.num_samples * self.num_replicas + self.seed = seed + + def __iter__(self) -> Iterator: + # Deterministically shuffle based on epoch and seed + g = torch.Generator() + g.manual_seed(self.seed + self.epoch) + indices = get_length_grouped_indices(self.lengths, self.batch_size, generator=g) + + if not self.drop_last: + # add extra samples to make it evenly divisible + indices += indices[: (self.total_size - len(indices))] + else: + # remove tail of data to make it evenly divisible. + indices = indices[: self.total_size] + assert len(indices) == self.total_size + + # subsample + indices = indices[self.rank : self.total_size : self.num_replicas] + assert len(indices) == self.num_samples + + return iter(indices) + + +class ShardSampler(Sampler): + """ + Sampler that shards batches between several processes. Dispatches indices batch by batch: on 2 processes with batch + size 4, the first two batches are `[0, 1, 2, 3, 4, 5, 6, 7]` and `[8, 9, 10, 11, 12, 13, 14, 15]`, which shard into + `[0, 1, 2, 3]` and `[8, 9, 10, 11]` for GPU-0 and `[4, 5, 6, 7]` and `[12, 13, 14, 15]` for GPU-1. + + The sampler thus yields `[0, 1, 2, 3, 8, 9, 10, 11]` on GPU-0 and `[4, 5, 6, 7, 12, 13, 14, 15]` on GPU-1. + """ + + def __init__( + self, + dataset: Dataset, + batch_size: int = 1, + drop_last: bool = False, + num_processes: int = 1, + process_index: int = 0, + ): + self.dataset = dataset + self.batch_size = batch_size + self.drop_last = drop_last + self.num_processes = num_processes + self.process_index = process_index + + self.total_batch_size = total_batch_size = batch_size * num_processes + + num_batches = len(dataset) // total_batch_size if drop_last else math.ceil(len(dataset) / total_batch_size) + self.total_num_samples = num_batches * total_batch_size + + def __iter__(self): + indices = list(range(len(self.dataset))) + + # Add extra samples to make it evenly divisible. While loop is there in the edge case we have a tiny dataset + # and it needs to be done several times. + while len(indices) < self.total_num_samples: + indices += indices[: (self.total_num_samples - len(indices))] + + result = [] + for batch_start in range(self.batch_size * self.process_index, self.total_num_samples, self.total_batch_size): + result += indices[batch_start : batch_start + self.batch_size] + + return iter(result) + + def __len__(self): + # Each shard only sees a fraction of total_num_samples. + return self.total_num_samples // self.num_processes + + +class IterableDatasetShard(IterableDataset): + """ + Wraps a PyTorch `IterableDataset` to generate samples for one of the processes only. Instances of this class will + always yield a number of samples that is a round multiple of the actual batch size (which is `batch_size x + num_processes`). Depending on the value of the `drop_last` attribute, it will either stop the iteration at the + first batch that would be too small or loop with indices from the beginning. + + On two processes with an iterable dataset yielding of `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]` with a batch size of + 2: + + - the shard on process 0 will yield `[0, 1, 4, 5, 8, 9]` so will see batches `[0, 1]`, `[4, 5]`, `[8, 9]` + - the shard on process 1 will yield `[2, 3, 6, 7, 10, 11]` so will see batches `[2, 3]`, `[6, 7]`, `[10, 11]` + + + + If your IterableDataset implements some randomization that needs to be applied the same way on all processes + (for instance, a shuffling), you should use a `torch.Generator` in a `generator` attribute of the `dataset` to + generate your random numbers and call the [`~trainer_pt_utils.IterableDatasetShard.set_epoch`] method of this + object. It will set the seed of this `generator` to `seed + epoch` on all processes before starting the + iteration. Alternatively, you can also implement a `set_epoch()` method in your iterable dataset to deal with + this. + + + + Args: + dataset (`torch.utils.data.IterableDataset`): + The batch sampler to split in several shards. + batch_size (`int`, *optional*, defaults to 1): + The size of the batches per shard. + drop_last (`bool`, *optional*, defaults to `False`): + Whether or not to drop the last incomplete batch or complete the last batches by using the samples from the + beginning. + num_processes (`int`, *optional*, defaults to 1): + The number of processes running concurrently. + process_index (`int`, *optional*, defaults to 0): + The index of the current process. + seed (`int`, *optional*, defaults to 0): + A random seed that will be used for the random number generation in + [`~trainer_pt_utils.IterableDatasetShard.set_epoch`]. + """ + + def __init__( + self, + dataset: IterableDataset, + batch_size: int = 1, + drop_last: bool = False, + num_processes: int = 1, + process_index: int = 0, + seed: int = 0, + ): + self.dataset = dataset + self.batch_size = batch_size + self.drop_last = drop_last + self.num_processes = num_processes + self.process_index = process_index + self.seed = seed + self.epoch = 0 + self.num_examples = 0 + + def set_epoch(self, epoch): + self.epoch = epoch + if hasattr(self.dataset, "set_epoch"): + self.dataset.set_epoch(epoch) + + def __iter__(self): + self.num_examples = 0 + if ( + not hasattr(self.dataset, "set_epoch") + and hasattr(self.dataset, "generator") + and isinstance(self.dataset.generator, torch.Generator) + ): + self.dataset.generator.manual_seed(self.seed + self.epoch) + real_batch_size = self.batch_size * self.num_processes + process_slice = range(self.process_index * self.batch_size, (self.process_index + 1) * self.batch_size) + + first_batch = None + current_batch = [] + for element in self.dataset: + self.num_examples += 1 + current_batch.append(element) + # Wait to have a full batch before yielding elements. + if len(current_batch) == real_batch_size: + for i in process_slice: + yield current_batch[i] + if first_batch is None: + first_batch = current_batch.copy() + current_batch = [] + + # Finished if drop_last is True, otherwise complete the last batch with elements from the beginning. + if not self.drop_last and len(current_batch) > 0: + if first_batch is None: + first_batch = current_batch.copy() + while len(current_batch) < real_batch_size: + current_batch += first_batch + for i in process_slice: + yield current_batch[i] + + def __len__(self): + # Will raise an error if the underlying dataset is not sized. + if self.drop_last: + return (len(self.dataset) // (self.batch_size * self.num_processes)) * self.batch_size + else: + return math.ceil(len(self.dataset) / (self.batch_size * self.num_processes)) * self.batch_size + + +# In order to keep `trainer.py` compact and easy to understand, place any secondary PT Trainer +# helper methods here + + +def _get_learning_rate(self): + if self.deepspeed: + # with deepspeed's fp16 and dynamic loss scale enabled the optimizer/scheduler steps may + # not run for the first few dozen steps while loss scale is too large, and thus during + # that time `get_last_lr` will fail if called during that warm up stage, so work around it: + try: + last_lr = self.lr_scheduler.get_last_lr()[0] + except AssertionError as e: + if "need to call step" in str(e): + logger.warning("tried to get lr value before scheduler/optimizer started stepping, returning lr=0") + last_lr = 0 + else: + raise + else: + last_lr = self.lr_scheduler.get_last_lr()[0] + if torch.is_tensor(last_lr): + last_lr = last_lr.item() + return last_lr + + +def _secs2timedelta(secs): + """ + convert seconds to hh:mm:ss.msec, msecs rounded to 2 decimals + """ + + msec = int(abs(secs - int(secs)) * 100) + return f"{datetime.timedelta(seconds=int(secs))}.{msec:02d}" + + +def metrics_format(self, metrics: Dict[str, float]) -> Dict[str, float]: + """ + Reformat Trainer metrics values to a human-readable format + + Args: + metrics (`Dict[str, float]`): + The metrics returned from train/evaluate/predict + + Returns: + metrics (`Dict[str, float]`): The reformatted metrics + """ + + metrics_copy = metrics.copy() + for k, v in metrics_copy.items(): + if "_mem_" in k: + metrics_copy[k] = f"{ v >> 20 }MB" + elif "_runtime" in k: + metrics_copy[k] = _secs2timedelta(v) + elif k == "total_flos": + metrics_copy[k] = f"{ int(v) >> 30 }GF" + elif type(metrics_copy[k]) == float: + metrics_copy[k] = round(v, 4) + + return metrics_copy + + +def log_metrics(self, split, metrics): + """ + Log metrics in a specially formatted way + + Under distributed environment this is done only for a process with rank 0. + + Args: + split (`str`): + Mode/split name: one of `train`, `eval`, `test` + metrics (`Dict[str, float]`): + The metrics returned from train/evaluate/predictmetrics: metrics dict + + Notes on memory reports: + + In order to get memory usage report you need to install `psutil`. You can do that with `pip install psutil`. + + Now when this method is run, you will see a report that will include: : + + ``` + init_mem_cpu_alloc_delta = 1301MB + init_mem_cpu_peaked_delta = 154MB + init_mem_gpu_alloc_delta = 230MB + init_mem_gpu_peaked_delta = 0MB + train_mem_cpu_alloc_delta = 1345MB + train_mem_cpu_peaked_delta = 0MB + train_mem_gpu_alloc_delta = 693MB + train_mem_gpu_peaked_delta = 7MB + ``` + + **Understanding the reports:** + + - the first segment, e.g., `train__`, tells you which stage the metrics are for. Reports starting with `init_` + will be added to the first stage that gets run. So that if only evaluation is run, the memory usage for the + `__init__` will be reported along with the `eval_` metrics. + - the third segment, is either `cpu` or `gpu`, tells you whether it's the general RAM or the gpu0 memory + metric. + - `*_alloc_delta` - is the difference in the used/allocated memory counter between the end and the start of the + stage - it can be negative if a function released more memory than it allocated. + - `*_peaked_delta` - is any extra memory that was consumed and then freed - relative to the current allocated + memory counter - it is never negative. When you look at the metrics of any stage you add up `alloc_delta` + + `peaked_delta` and you know how much memory was needed to complete that stage. + + The reporting happens only for process of rank 0 and gpu 0 (if there is a gpu). Typically this is enough since the + main process does the bulk of work, but it could be not quite so if model parallel is used and then other GPUs may + use a different amount of gpu memory. This is also not the same under DataParallel where gpu0 may require much more + memory than the rest since it stores the gradient and optimizer states for all participating GPUS. Perhaps in the + future these reports will evolve to measure those too. + + The CPU RAM metric measures RSS (Resident Set Size) includes both the memory which is unique to the process and the + memory shared with other processes. It is important to note that it does not include swapped out memory, so the + reports could be imprecise. + + The CPU peak memory is measured using a sampling thread. Due to python's GIL it may miss some of the peak memory if + that thread didn't get a chance to run when the highest memory was used. Therefore this report can be less than + reality. Using `tracemalloc` would have reported the exact peak memory, but it doesn't report memory allocations + outside of python. So if some C++ CUDA extension allocated its own memory it won't be reported. And therefore it + was dropped in favor of the memory sampling approach, which reads the current process memory usage. + + The GPU allocated and peak memory reporting is done with `torch.cuda.memory_allocated()` and + `torch.cuda.max_memory_allocated()`. This metric reports only "deltas" for pytorch-specific allocations, as + `torch.cuda` memory management system doesn't track any memory allocated outside of pytorch. For example, the very + first cuda call typically loads CUDA kernels, which may take from 0.5 to 2GB of GPU memory. + + Note that this tracker doesn't account for memory allocations outside of [`Trainer`]'s `__init__`, `train`, + `evaluate` and `predict` calls. + + Because `evaluation` calls may happen during `train`, we can't handle nested invocations because + `torch.cuda.max_memory_allocated` is a single counter, so if it gets reset by a nested eval call, `train`'s tracker + will report incorrect info. If this [pytorch issue](https://github.com/pytorch/pytorch/issues/16266) gets resolved + it will be possible to change this class to be re-entrant. Until then we will only track the outer level of + `train`, `evaluate` and `predict` methods. Which means that if `eval` is called during `train`, it's the latter + that will account for its memory usage and that of the former. + + This also means that if any other tool that is used along the [`Trainer`] calls + `torch.cuda.reset_peak_memory_stats`, the gpu peak memory stats could be invalid. And the [`Trainer`] will disrupt + the normal behavior of any such tools that rely on calling `torch.cuda.reset_peak_memory_stats` themselves. + + For best performance you may want to consider turning the memory profiling off for production runs. + """ + if not self.is_world_process_zero(): + return + + print(f"***** {split} metrics *****") + metrics_formatted = self.metrics_format(metrics) + k_width = max(len(str(x)) for x in metrics_formatted.keys()) + v_width = max(len(str(x)) for x in metrics_formatted.values()) + for key in sorted(metrics_formatted.keys()): + print(f" {key: <{k_width}} = {metrics_formatted[key]:>{v_width}}") + + +def save_metrics(self, split, metrics, combined=True): + """ + Save metrics into a json file for that split, e.g. `train_results.json`. + + Under distributed environment this is done only for a process with rank 0. + + Args: + split (`str`): + Mode/split name: one of `train`, `eval`, `test`, `all` + metrics (`Dict[str, float]`): + The metrics returned from train/evaluate/predict + combined (`bool`, *optional*, defaults to `True`): + Creates combined metrics by updating `all_results.json` with metrics of this call + + To understand the metrics please read the docstring of [`~Trainer.log_metrics`]. The only difference is that raw + unformatted numbers are saved in the current method. + + """ + if not self.is_world_process_zero(): + return + + path = os.path.join(self.args.output_dir, f"{split}_results.json") + with open(path, "w") as f: + json.dump(metrics, f, indent=4, sort_keys=True) + + if combined: + path = os.path.join(self.args.output_dir, "all_results.json") + if os.path.exists(path): + with open(path, "r") as f: + all_metrics = json.load(f) + else: + all_metrics = {} + + all_metrics.update(metrics) + with open(path, "w") as f: + json.dump(all_metrics, f, indent=4, sort_keys=True) + + +def save_state(self): + """ + Saves the Trainer state, since Trainer.save_model saves only the tokenizer with the model + + Under distributed environment this is done only for a process with rank 0. + """ + if not self.is_world_process_zero(): + return + + path = os.path.join(self.args.output_dir, "trainer_state.json") + self.state.save_to_json(path) + + +def get_model_param_count(model, trainable_only=False): + """ + Calculate model's total param count. If trainable_only is True then count only those requiring grads + """ + if is_deepspeed_zero3_enabled(): + + def numel(p): + return p.ds_numel + + else: + + def numel(p): + return p.numel() + + return sum(numel(p) for p in model.parameters() if not trainable_only or p.requires_grad) + + +def get_parameter_names(model, forbidden_layer_types): + """ + Returns the names of the model parameters that are not inside a forbidden layer. + """ + result = [] + for name, child in model.named_children(): + result += [ + f"{name}.{n}" + for n in get_parameter_names(child, forbidden_layer_types) + if not isinstance(child, tuple(forbidden_layer_types)) + ] + # Add model specific parameters (defined with nn.Parameter) since they are not in any child. + result += list(model._parameters.keys()) + return result + + +def get_module_class_from_name(module, name): + """ + Gets a class from a module by its name. + + Args: + module (`torch.nn.Module`): The module to get the class from. + name (`str`): The name of the class. + """ + modules_children = list(module.children()) + if module.__class__.__name__ == name: + return module.__class__ + elif len(modules_children) == 0: + return + else: + for child_module in modules_children: + module_class = get_module_class_from_name(child_module, name) + if module_class is not None: + return module_class + + +if is_sagemaker_mp_enabled(): + import smdistributed.modelparallel.torch as smp + + @smp.step() + def smp_forward_backward(model, inputs, gradient_accumulation_steps=1): + outputs = model(**inputs) + loss = outputs["loss"] if isinstance(outputs, dict) else outputs[0] + loss /= gradient_accumulation_steps + model.backward(loss) + return loss + + @smp.step() + def smp_forward_only(model, inputs): + return model(**inputs) + + def smp_gather(tensor): + if isinstance(tensor, (list, tuple)): + return type(tensor)(smp_gather(t) for t in tensor) + elif isinstance(tensor, dict): + return type(tensor)({k: smp_gather(v) for k, v in tensor.items()}) + elif not isinstance(tensor, torch.Tensor): + raise TypeError( + f"Can't gather the values of type {type(tensor)}, only of nested list/tuple/dicts of tensors." + ) + all_tensors = smp.allgather(tensor, smp.CommGroup.DP_GROUP) + all_tensors = [atleast_1d(t) for t in all_tensors] + return torch.cat([t.cpu() for t in all_tensors], dim=0) + + def smp_nested_concat(tensor): + if isinstance(tensor, (list, tuple)): + return type(tensor)(smp_nested_concat(t) for t in tensor) + elif isinstance(tensor, dict): + return type(tensor)({k: smp_nested_concat(v) for k, v in tensor.items()}) + # It doesn't seem possible to check here if `tensor` is a StepOutput because StepOutput lives in `smp.step` + # which is also the name of the decorator so Python is confused. + return tensor.concat().detach().cpu() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_seq2seq.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_seq2seq.py new file mode 100644 index 0000000000000000000000000000000000000000..2d7b04c0e199e5d841370f7feb9c416869183609 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_seq2seq.py @@ -0,0 +1,333 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from copy import deepcopy +from pathlib import Path +from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union + +import torch +from torch import nn +from torch.utils.data import Dataset + +from .deepspeed import is_deepspeed_zero3_enabled +from .generation.configuration_utils import GenerationConfig +from .trainer import Trainer +from .utils import logging + + +if TYPE_CHECKING: + from .data.data_collator import DataCollator + from .modeling_utils import PreTrainedModel + from .tokenization_utils_base import PreTrainedTokenizerBase + from .trainer_callback import TrainerCallback + from .trainer_utils import EvalPrediction, PredictionOutput + from .training_args import TrainingArguments + + +logger = logging.get_logger(__name__) + + +class Seq2SeqTrainer(Trainer): + def __init__( + self, + model: Union["PreTrainedModel", nn.Module] = None, + args: "TrainingArguments" = None, + data_collator: Optional["DataCollator"] = None, + train_dataset: Optional[Dataset] = None, + eval_dataset: Optional[Union[Dataset, Dict[str, Dataset]]] = None, + tokenizer: Optional["PreTrainedTokenizerBase"] = None, + model_init: Optional[Callable[[], "PreTrainedModel"]] = None, + compute_metrics: Optional[Callable[["EvalPrediction"], Dict]] = None, + callbacks: Optional[List["TrainerCallback"]] = None, + optimizers: Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None), + preprocess_logits_for_metrics: Optional[Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None, + ): + super().__init__( + model=model, + args=args, + data_collator=data_collator, + train_dataset=train_dataset, + eval_dataset=eval_dataset, + tokenizer=tokenizer, + model_init=model_init, + compute_metrics=compute_metrics, + callbacks=callbacks, + optimizers=optimizers, + preprocess_logits_for_metrics=preprocess_logits_for_metrics, + ) + + # Override self.model.generation_config if a GenerationConfig is specified in args. + # Priority: args.generation_config > model.generation_config > default GenerationConfig. + if self.args.generation_config is not None: + gen_config = self.load_generation_config(self.args.generation_config) + self.model.generation_config = gen_config + + @staticmethod + def load_generation_config(gen_config_arg: Union[str, GenerationConfig]) -> GenerationConfig: + """ + Loads a `~generation.GenerationConfig` from the `Seq2SeqTrainingArguments.generation_config` arguments. + + Args: + gen_config_arg (`str` or [`~generation.GenerationConfig`]): + `Seq2SeqTrainingArguments.generation_config` argument. + + Returns: + A `~generation.GenerationConfig`. + """ + + # GenerationConfig provided, nothing to do + if isinstance(gen_config_arg, GenerationConfig): + return deepcopy(gen_config_arg) + + # str or Path + pretrained_model_name = Path(gen_config_arg) if isinstance(gen_config_arg, str) else gen_config_arg + config_file_name = None + + # Figuring if it is path pointing to a file, pointing to a directory or else a model id or URL + # This step is required in order to determine config_file_name + if pretrained_model_name.is_file(): + config_file_name = pretrained_model_name.name + pretrained_model_name = pretrained_model_name.parent + # dir path + elif pretrained_model_name.is_dir(): + pass + # model id or URL + else: + pretrained_model_name = gen_config_arg + + gen_config = GenerationConfig.from_pretrained(pretrained_model_name, config_file_name) + return gen_config + + def evaluate( + self, + eval_dataset: Optional[Dataset] = None, + ignore_keys: Optional[List[str]] = None, + metric_key_prefix: str = "eval", + **gen_kwargs, + ) -> Dict[str, float]: + """ + Run evaluation and returns metrics. + + The calling script will be responsible for providing a method to compute metrics, as they are task-dependent + (pass it to the init `compute_metrics` argument). + + You can also subclass and override this method to inject custom behavior. + + Args: + eval_dataset (`Dataset`, *optional*): + Pass a dataset if you wish to override `self.eval_dataset`. If it is an [`~datasets.Dataset`], columns + not accepted by the `model.forward()` method are automatically removed. It must implement the `__len__` + method. + ignore_keys (`List[str]`, *optional*): + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions. + metric_key_prefix (`str`, *optional*, defaults to `"eval"`): + An optional prefix to be used as the metrics key prefix. For example the metrics "bleu" will be named + "eval_bleu" if the prefix is `"eval"` (default) + max_length (`int`, *optional*): + The maximum target length to use when predicting with the generate method. + num_beams (`int`, *optional*): + Number of beams for beam search that will be used when predicting with the generate method. 1 means no + beam search. + gen_kwargs: + Additional `generate` specific kwargs. + + Returns: + A dictionary containing the evaluation loss and the potential metrics computed from the predictions. The + dictionary also contains the epoch number which comes from the training state. + """ + + gen_kwargs = gen_kwargs.copy() + if gen_kwargs.get("max_length") is None and gen_kwargs.get("max_new_tokens") is None: + gen_kwargs["max_length"] = self.args.generation_max_length + gen_kwargs["num_beams"] = ( + gen_kwargs["num_beams"] if gen_kwargs.get("num_beams") is not None else self.args.generation_num_beams + ) + self._gen_kwargs = gen_kwargs + + return super().evaluate(eval_dataset, ignore_keys=ignore_keys, metric_key_prefix=metric_key_prefix) + + def predict( + self, + test_dataset: Dataset, + ignore_keys: Optional[List[str]] = None, + metric_key_prefix: str = "test", + **gen_kwargs, + ) -> "PredictionOutput": + """ + Run prediction and returns predictions and potential metrics. + + Depending on the dataset and your use case, your test dataset may contain labels. In that case, this method + will also return metrics, like in `evaluate()`. + + Args: + test_dataset (`Dataset`): + Dataset to run the predictions on. If it is a [`~datasets.Dataset`], columns not accepted by the + `model.forward()` method are automatically removed. Has to implement the method `__len__` + ignore_keys (`List[str]`, *optional*): + A list of keys in the output of your model (if it is a dictionary) that should be ignored when + gathering predictions. + metric_key_prefix (`str`, *optional*, defaults to `"eval"`): + An optional prefix to be used as the metrics key prefix. For example the metrics "bleu" will be named + "eval_bleu" if the prefix is `"eval"` (default) + max_length (`int`, *optional*): + The maximum target length to use when predicting with the generate method. + num_beams (`int`, *optional*): + Number of beams for beam search that will be used when predicting with the generate method. 1 means no + beam search. + gen_kwargs: + Additional `generate` specific kwargs. + + + + If your predictions or labels have different sequence lengths (for instance because you're doing dynamic + padding in a token classification task) the predictions will be padded (on the right) to allow for + concatenation into one array. The padding index is -100. + + + + Returns: *NamedTuple* A namedtuple with the following keys: + + - predictions (`np.ndarray`): The predictions on `test_dataset`. + - label_ids (`np.ndarray`, *optional*): The labels (if the dataset contained some). + - metrics (`Dict[str, float]`, *optional*): The potential dictionary of metrics (if the dataset contained + labels). + """ + + gen_kwargs = gen_kwargs.copy() + if gen_kwargs.get("max_length") is None and gen_kwargs.get("max_new_tokens") is None: + gen_kwargs["max_length"] = self.args.generation_max_length + gen_kwargs["num_beams"] = ( + gen_kwargs["num_beams"] if gen_kwargs.get("num_beams") is not None else self.args.generation_num_beams + ) + self._gen_kwargs = gen_kwargs + + return super().predict(test_dataset, ignore_keys=ignore_keys, metric_key_prefix=metric_key_prefix) + + def prediction_step( + self, + model: nn.Module, + inputs: Dict[str, Union[torch.Tensor, Any]], + prediction_loss_only: bool, + ignore_keys: Optional[List[str]] = None, + ) -> Tuple[Optional[float], Optional[torch.Tensor], Optional[torch.Tensor]]: + """ + Perform an evaluation step on `model` using `inputs`. + + Subclass and override to inject custom behavior. + + Args: + model (`nn.Module`): + The model to evaluate. + inputs (`Dict[str, Union[torch.Tensor, Any]]`): + The inputs and targets of the model. + + The dictionary will be unpacked before being fed to the model. Most models expect the targets under the + argument `labels`. Check your model's documentation for all accepted arguments. + prediction_loss_only (`bool`): + Whether or not to return the loss only. + + Return: + Tuple[Optional[float], Optional[torch.Tensor], Optional[torch.Tensor]]: A tuple with the loss, logits and + labels (each being optional). + """ + + if not self.args.predict_with_generate or prediction_loss_only: + return super().prediction_step( + model, inputs, prediction_loss_only=prediction_loss_only, ignore_keys=ignore_keys + ) + + has_labels = "labels" in inputs + inputs = self._prepare_inputs(inputs) + + # XXX: adapt synced_gpus for fairscale as well + # Priority (handled in generate): + # gen_kwargs > model.generation_config > default GenerationConfig() + gen_kwargs = self._gen_kwargs.copy() + if gen_kwargs.get("max_length") is None and gen_kwargs.get("max_new_tokens") is None: + gen_kwargs["max_length"] = self.model.config.max_length + gen_kwargs["num_beams"] = ( + gen_kwargs["num_beams"] if gen_kwargs.get("num_beams") is not None else self.model.config.num_beams + ) + default_synced_gpus = True if is_deepspeed_zero3_enabled() else False + gen_kwargs["synced_gpus"] = ( + gen_kwargs["synced_gpus"] if gen_kwargs.get("synced_gpus") is not None else default_synced_gpus + ) + + # If the `decoder_input_ids` was created from `labels`, evict the former, so that the model can freely generate + # (otherwise, it would continue generating from the padded `decoder_input_ids`) + if ( + "labels" in inputs + and "decoder_input_ids" in inputs + and inputs["labels"].shape == inputs["decoder_input_ids"].shape + ): + inputs = {k: v for k, v in inputs.items() if k != "decoder_input_ids"} + generated_tokens = self.model.generate(**inputs, **gen_kwargs) + + # Temporary hack to ensure the generation config is not initialized for each iteration of the evaluation loop + # TODO: remove this hack when the legacy code that initializes generation_config from a model config is + # removed in https://github.com/huggingface/transformers/blob/98d88b23f54e5a23e741833f1e973fdf600cc2c5/src/transformers/generation/utils.py#L1183 + if self.model.generation_config._from_model_config: + self.model.generation_config._from_model_config = False + + # Retrieves GenerationConfig from model.generation_config + gen_config = self.model.generation_config + # in case the batch is shorter than max length, the output should be padded + if generated_tokens.shape[-1] < gen_config.max_length: + generated_tokens = self._pad_tensors_to_max_len(generated_tokens, gen_config.max_length) + elif gen_config.max_new_tokens is not None and generated_tokens.shape[-1] < gen_config.max_new_tokens + 1: + generated_tokens = self._pad_tensors_to_max_len(generated_tokens, gen_config.max_new_tokens + 1) + + with torch.no_grad(): + if has_labels: + with self.compute_loss_context_manager(): + outputs = model(**inputs) + if self.label_smoother is not None: + loss = self.label_smoother(outputs, inputs["labels"]).mean().detach() + else: + loss = (outputs["loss"] if isinstance(outputs, dict) else outputs[0]).mean().detach() + else: + loss = None + + if self.args.prediction_loss_only: + return loss, None, None + + if has_labels: + labels = inputs["labels"] + if labels.shape[-1] < gen_config.max_length: + labels = self._pad_tensors_to_max_len(labels, gen_config.max_length) + elif gen_config.max_new_tokens is not None and labels.shape[-1] < gen_config.max_new_tokens + 1: + labels = self._pad_tensors_to_max_len(labels, gen_config.max_new_tokens + 1) + else: + labels = None + + return loss, generated_tokens, labels + + def _pad_tensors_to_max_len(self, tensor, max_length): + if self.tokenizer is not None and hasattr(self.tokenizer, "pad_token_id"): + # If PAD token is not defined at least EOS token has to be defined + pad_token_id = ( + self.tokenizer.pad_token_id if self.tokenizer.pad_token_id is not None else self.tokenizer.eos_token_id + ) + else: + if self.model.config.pad_token_id is not None: + pad_token_id = self.model.config.pad_token_id + else: + raise ValueError("Pad_token_id must be set in the configuration of the model, in order to pad tensors") + + padded_tensor = pad_token_id * torch.ones( + (tensor.shape[0], max_length), dtype=tensor.dtype, device=tensor.device + ) + padded_tensor[:, : tensor.shape[-1]] = tensor + return padded_tensor diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_tf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_tf.py new file mode 100644 index 0000000000000000000000000000000000000000..1f6435b787a02a751df53af90346248b2a5df689 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_tf.py @@ -0,0 +1,801 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tensorflow trainer class.""" + +import datetime +import math +import os +import warnings +from typing import Callable, Dict, Optional, Tuple + +from .utils import ENV_VARS_TRUE_VALUES + + +# Integrations must be imported before ML frameworks: +# isort: off +from .integrations import ( + is_comet_available, + is_wandb_available, +) + +# isort: on + +import numpy as np +import tensorflow as tf +from tensorflow.python.distribute.values import PerReplica + +from .modeling_tf_utils import TFPreTrainedModel +from .optimization_tf import GradientAccumulator, create_optimizer +from .trainer_utils import ( + PREFIX_CHECKPOINT_DIR, + EvalPrediction, + IntervalStrategy, + PredictionOutput, + enable_full_determinism, + set_seed, +) +from .training_args_tf import TFTrainingArguments +from .utils import logging + + +if is_wandb_available(): + import wandb + +if is_comet_available(): + import comet_ml + +logger = logging.get_logger(__name__) + + +class TFTrainer: + """ + TFTrainer is a simple but feature-complete training and eval loop for TensorFlow, optimized for 🤗 Transformers. + + Args: + model ([`TFPreTrainedModel`]): + The model to train, evaluate or use for predictions. + args ([`TFTrainingArguments`]): + The arguments to tweak training. + train_dataset ([`~tf.data.Dataset`], *optional*): + The dataset to use for training. The dataset should yield tuples of `(features, labels)` where `features` + is a dict of input features and `labels` is the labels. If `labels` is a tensor, the loss is calculated by + the model by calling `model(features, labels=labels)`. If `labels` is a dict, such as when using a + QuestionAnswering head model with multiple targets, the loss is instead calculated by calling + `model(features, **labels)`. + eval_dataset ([`~tf.data.Dataset`], *optional*): + The dataset to use for evaluation. The dataset should yield tuples of `(features, labels)` where `features` + is a dict of input features and `labels` is the labels. If `labels` is a tensor, the loss is calculated by + the model by calling `model(features, labels=labels)`. If `labels` is a dict, such as when using a + QuestionAnswering head model with multiple targets, the loss is instead calculated by calling + `model(features, **labels)`. + compute_metrics (`Callable[[EvalPrediction], Dict]`, *optional*): + The function that will be used to compute metrics at evaluation. Must take a [`EvalPrediction`] and return + a dictionary string to metric values. + tb_writer (`tf.summary.SummaryWriter`, *optional*): + Object to write to TensorBoard. + optimizers (`Tuple[tf.keras.optimizers.Optimizer, tf.keras.optimizers.schedules.LearningRateSchedule]`, *optional*): + A tuple containing the optimizer and the scheduler to use. The optimizer default to an instance of + [`tf.keras.optimizers.Adam`] if `args.weight_decay_rate` is 0 else an instance of [`AdamWeightDecay`]. The + scheduler will default to an instance of [`tf.keras.optimizers.schedules.PolynomialDecay`] if + `args.num_warmup_steps` is 0 else an instance of [`WarmUp`]. + """ + + def __init__( + self, + model: TFPreTrainedModel, + args: TFTrainingArguments, + train_dataset: Optional[tf.data.Dataset] = None, + eval_dataset: Optional[tf.data.Dataset] = None, + compute_metrics: Optional[Callable[[EvalPrediction], Dict]] = None, + tb_writer: Optional[tf.summary.SummaryWriter] = None, + optimizers: Tuple[tf.keras.optimizers.Optimizer, tf.keras.optimizers.schedules.LearningRateSchedule] = ( + None, + None, + ), + ): + self.model = model + self.args = args + self.train_dataset = train_dataset + self.eval_dataset = eval_dataset + self.compute_metrics = compute_metrics + self.optimizer, self.lr_scheduler = optimizers + self.gradient_accumulator = GradientAccumulator() + self.global_step = 0 + self.epoch_logging = 0 + self.eval_loss = tf.keras.metrics.Sum() + + warnings.warn( + "The class `TFTrainer` is deprecated and will be removed in version 5 of Transformers. " + "We recommend using native Keras instead, by calling methods like `fit()` and `predict()` " + "directly on the model object. Detailed examples of the Keras style can be found in our " + "examples at https://github.com/huggingface/transformers/tree/main/examples/tensorflow", + FutureWarning, + ) + + if tb_writer is not None: + self.tb_writer = tb_writer + else: + self.tb_writer = tf.summary.create_file_writer(self.args.logging_dir) + + if is_wandb_available(): + self.setup_wandb() + elif os.getenv("WANDB_DISABLED", "").upper() not in ENV_VARS_TRUE_VALUES: + logger.info( + "You are instantiating a Trainer but W&B is not installed. To use wandb logging, " + "run `pip install wandb && wandb login` see https://docs.wandb.com/huggingface." + ) + + if is_comet_available(): + self.setup_comet() + elif os.environ.get("COMET_MODE") != "DISABLED": + logger.info( + "To use comet_ml logging, run `pip/conda install comet_ml` " + "see https://www.comet.ml/docs/python-sdk/huggingface/" + ) + + enable_full_determinism(self.args.seed) if self.args.full_determinism else set_seed(self.args.seed) + + def get_train_tfdataset(self) -> tf.data.Dataset: + """ + Returns the training [`~tf.data.Dataset`]. + + Subclass and override this method if you want to inject some custom behavior. + """ + if self.train_dataset is None: + raise ValueError("Trainer: training requires a train_dataset.") + + self.total_train_batch_size = self.args.train_batch_size * self.args.gradient_accumulation_steps + self.num_train_examples = self.train_dataset.cardinality().numpy() + + if self.num_train_examples < 0: + raise ValueError("The training dataset must have an asserted cardinality") + + ds = ( + self.train_dataset.repeat() + .shuffle(self.num_train_examples, seed=self.args.seed) + .batch(self.total_train_batch_size, drop_remainder=self.args.dataloader_drop_last) + .prefetch(tf.data.experimental.AUTOTUNE) + ) + + return self.args.strategy.experimental_distribute_dataset(ds) + + def get_eval_tfdataset(self, eval_dataset: Optional[tf.data.Dataset] = None) -> tf.data.Dataset: + """ + Returns the evaluation [`~tf.data.Dataset`]. + + Args: + eval_dataset ([`~tf.data.Dataset`], *optional*): + If provided, will override *self.eval_dataset*. The dataset should yield tuples of `(features, labels)` + where `features` is a dict of input features and `labels` is the labels. If `labels` is a tensor, the + loss is calculated by the model by calling `model(features, labels=labels)`. If `labels` is a dict, + such as when using a QuestionAnswering head model with multiple targets, the loss is instead calculated + by calling `model(features, **labels)`. + + Subclass and override this method if you want to inject some custom behavior. + """ + if eval_dataset is None and self.eval_dataset is None: + raise ValueError("Trainer: evaluation requires an eval_dataset.") + + eval_dataset = eval_dataset if eval_dataset is not None else self.eval_dataset + num_examples = eval_dataset.cardinality().numpy() + + if num_examples < 0: + raise ValueError("The training dataset must have an asserted cardinality") + + approx = math.floor if self.args.dataloader_drop_last else math.ceil + steps = approx(num_examples / self.args.eval_batch_size) + ds = ( + eval_dataset.repeat() + .batch(self.args.eval_batch_size, drop_remainder=self.args.dataloader_drop_last) + .prefetch(tf.data.experimental.AUTOTUNE) + ) + + return self.args.strategy.experimental_distribute_dataset(ds), steps, num_examples + + def get_test_tfdataset(self, test_dataset: tf.data.Dataset) -> tf.data.Dataset: + """ + Returns a test [`~tf.data.Dataset`]. + + Args: + test_dataset ([`~tf.data.Dataset`]): + The dataset to use. The dataset should yield tuples of `(features, labels)` where `features` is a dict + of input features and `labels` is the labels. If `labels` is a tensor, the loss is calculated by the + model by calling `model(features, labels=labels)`. If `labels` is a dict, such as when using a + QuestionAnswering head model with multiple targets, the loss is instead calculated by calling + `model(features, **labels)`. + + Subclass and override this method if you want to inject some custom behavior. + """ + + num_examples = test_dataset.cardinality().numpy() + + if num_examples < 0: + raise ValueError("The training dataset must have an asserted cardinality") + + steps = math.ceil(num_examples / self.args.eval_batch_size) + ds = test_dataset.batch(self.args.eval_batch_size).prefetch(tf.data.experimental.AUTOTUNE) + + return self.args.strategy.experimental_distribute_dataset(ds), steps, num_examples + + def create_optimizer_and_scheduler(self, num_training_steps: int): + """ + Setup the optimizer and the learning rate scheduler. + + We provide a reasonable default that works well. If you want to use something else, you can pass a tuple in the + TFTrainer's init through `optimizers`, or subclass and override this method. + """ + if not self.optimizer and not self.lr_scheduler: + warmup_steps = ( + self.args.warmup_steps + if self.args.warmup_steps > 0 + else math.ceil(num_training_steps * self.args.warmup_ratio) + ) + + self.optimizer, self.lr_scheduler = create_optimizer( + self.args.learning_rate, + num_training_steps, + warmup_steps, + adam_beta1=self.args.adam_beta1, + adam_beta2=self.args.adam_beta2, + adam_epsilon=self.args.adam_epsilon, + weight_decay_rate=self.args.weight_decay, + power=self.args.poly_power, + ) + + def setup_wandb(self): + """ + Setup the optional Weights & Biases (`wandb`) integration. + + One can subclass and override this method to customize the setup if needed. Find more information `here + `__. You can also override the following environment variables: + + Environment: + WANDB_PROJECT: + (Optional): str - "huggingface" by default, set this to a custom string to store results in a different + project. + WANDB_DISABLED: + (Optional): boolean - defaults to false, set to "true" to disable wandb entirely. + """ + + logger.info('Automatic Weights & Biases logging enabled, to disable set os.environ["WANDB_DISABLED"] = "true"') + combined_dict = {**self.model.config.to_dict(), **self.args.to_sanitized_dict()} + wandb.init(project=os.getenv("WANDB_PROJECT", "huggingface"), config=combined_dict, name=self.args.run_name) + + def setup_comet(self): + """ + Setup the optional Comet.ml integration. + + Environment: + COMET_MODE: + (Optional): str - "OFFLINE", "ONLINE", or "DISABLED" + COMET_PROJECT_NAME: + (Optional): str - Comet.ml project name for experiments + COMET_OFFLINE_DIRECTORY: + (Optional): str - folder to use for saving offline experiments when `COMET_MODE` is "OFFLINE" + + For a number of configurable items in the environment, see `here + `__ + """ + comet_mode = os.getenv("COMET_MODE", "ONLINE").upper() + args = {"project_name": os.getenv("COMET_PROJECT_NAME", "huggingface")} + experiment = None + if comet_mode == "ONLINE": + experiment = comet_ml.Experiment(**args) + logger.info("Automatic Comet.ml online logging enabled") + elif comet_mode == "OFFLINE": + args["offline_directory"] = os.getenv("COMET_OFFLINE_DIRECTORY", "./") + experiment = comet_ml.OfflineExperiment(**args) + logger.info("Automatic Comet.ml offline logging enabled; use `comet upload` when finished") + if experiment is not None: + experiment._set_model_graph(self.model, framework="transformers") + experiment._log_parameters(self.args, prefix="args/", framework="transformers") + experiment._log_parameters(self.model.config, prefix="config/", framework="transformers") + + def prediction_loop( + self, + dataset: tf.data.Dataset, + steps: int, + num_examples: int, + description: str, + prediction_loss_only: Optional[bool] = None, + ) -> PredictionOutput: + """ + Prediction/evaluation loop, shared by [`~TFTrainer.evaluate`] and [`~TFTrainer.predict`]. + + Works both with or without labels. + """ + + prediction_loss_only = ( + prediction_loss_only if prediction_loss_only is not None else self.args.prediction_loss_only + ) + + logger.info(f"***** Running {description} *****") + logger.info(f" Num examples in dataset = {num_examples}") + if description == "Evaluation": + logger.info(f" Num examples in used in evaluation = {self.args.eval_batch_size * steps}") + logger.info(f" Batch size = {self.args.eval_batch_size}") + + label_ids: np.ndarray = None + preds: np.ndarray = None + self.eval_loss.reset_states() + + # Reset the past mems state at the beginning of the evaluation if necessary. + if self.args.past_index >= 0: + self._past = None + + for step, batch in enumerate(dataset): + logits = self.distributed_prediction_steps(batch) + _, labels = batch + + if not prediction_loss_only: + if isinstance(logits, tuple): + logits = logits[0] + + if isinstance(labels, tuple): + labels = labels[0] + + if self.args.n_replicas > 1: + for val in logits.values: + if preds is None: + preds = val.numpy() + else: + preds = np.append(preds, val.numpy(), axis=0) + + for val in labels.values: + if label_ids is None: + label_ids = val.numpy() + else: + label_ids = np.append(label_ids, val.numpy(), axis=0) + else: + if preds is None: + preds = logits.numpy() + else: + preds = np.append(preds, logits.numpy(), axis=0) + + if label_ids is None: + label_ids = labels.numpy() + else: + label_ids = np.append(label_ids, labels.numpy(), axis=0) + + if step == steps - 1: + break + + if self.compute_metrics is not None and preds is not None and label_ids is not None: + metrics = self.compute_metrics(EvalPrediction(predictions=preds, label_ids=label_ids)) + else: + metrics = {} + + metrics["eval_loss"] = self.eval_loss.result().numpy() / steps + + for key in list(metrics.keys()): + if not key.startswith("eval_"): + metrics[f"eval_{key}"] = metrics.pop(key) + + if self.args.past_index and hasattr(self, "_past"): + # Clean the state at the end of training + delattr(self, "_past") + + return PredictionOutput(predictions=preds, label_ids=label_ids, metrics=metrics) + + def log(self, logs: Dict[str, float]) -> None: + """ + Log `logs` on the various objects watching training. + + Subclass and override this method to inject custom behavior. + + Args: + logs (`Dict[str, float]`): + The values to log. + """ + logs["epoch"] = self.epoch_logging + + if self.tb_writer: + with self.tb_writer.as_default(): + for k, v in logs.items(): + tf.summary.scalar(k, v, step=self.global_step) + self.tb_writer.flush() + + if is_wandb_available(): + wandb.log(logs, step=self.global_step) + + if is_comet_available(): + experiment = comet_ml.config.get_global_experiment() + if experiment is not None: + experiment._log_metrics( + logs, step=self.global_step, epoch=self.epoch_logging, framework="transformers" + ) + + output = {**logs, **{"step": self.global_step}} + + logger.info(output) + + def evaluate(self, eval_dataset: Optional[tf.data.Dataset] = None) -> Dict[str, float]: + """ + Run evaluation and returns metrics. + + The calling script will be responsible for providing a method to compute metrics, as they are task-dependent + (pass it to the init `compute_metrics` argument). + + Args: + eval_dataset ([`~tf.data.Dataset`], *optional*): + Pass a dataset if you wish to override `self.eval_dataset`. The dataset should yield tuples of + `(features, labels)` where `features` is a dict of input features and `labels` is the labels. If + `labels` is a tensor, the loss is calculated by the model by calling `model(features, labels=labels)`. + If `labels` is a dict, such as when using a QuestionAnswering head model with multiple targets, the + loss is instead calculated by calling `model(features, **labels)`. + + Returns: + A dictionary containing the evaluation loss and the potential metrics computed from the predictions. + """ + eval_ds, steps, num_examples = self.get_eval_tfdataset(eval_dataset) + + output = self.prediction_loop(eval_ds, steps, num_examples, description="Evaluation") + logs = {**output.metrics} + logs["epoch"] = self.epoch_logging + + self.log(logs) + + return output.metrics + + def prediction_step( + self, features: tf.Tensor, labels: tf.Tensor, nb_instances_in_global_batch: tf.Tensor + ) -> tf.Tensor: + """ + Compute the prediction on features and update the loss with labels. + + Subclass and override to inject some custom behavior. + """ + per_example_loss, logits = self.run_model(features, labels, False) + scaled_loss = per_example_loss / tf.cast(nb_instances_in_global_batch, dtype=per_example_loss.dtype) + + self.eval_loss.update_state(scaled_loss) + + return logits + + @tf.function + def distributed_prediction_steps(self, batch): + nb_instances_in_batch = self._compute_nb_instances(batch) + inputs = self._get_step_inputs(batch, nb_instances_in_batch) + + logits = self.args.strategy.run(self.prediction_step, inputs) + + return logits + + def train(self) -> None: + """ + Train method to train the model. + """ + train_ds = self.get_train_tfdataset() + + if self.args.debug: + tf.summary.trace_on(graph=True, profiler=True) + + self.gradient_accumulator.reset() + + num_update_steps_per_epoch = self.num_train_examples / self.total_train_batch_size + + # In fact, ``self.args.dataloader_drop_last`` has no effect in `trainer_tf.py`, because + # the dataset is repeated before being batched. + # It has the effect only when TPU is used which requires explicit tensor shape in order to make + # the gradient accumulation implementation work. + approx = math.floor if self.args.dataloader_drop_last else math.ceil + num_update_steps_per_epoch = approx(num_update_steps_per_epoch) + + # At least one update for each epoch. + num_update_steps_per_epoch = max(num_update_steps_per_epoch, 1) + self.steps_per_epoch = num_update_steps_per_epoch + + if self.args.max_steps > 0: + t_total = self.args.max_steps + epochs = (self.args.max_steps // self.steps_per_epoch) + int( + self.args.max_steps % self.steps_per_epoch > 0 + ) + else: + t_total = self.steps_per_epoch * self.args.num_train_epochs + epochs = self.args.num_train_epochs + + # Since ``self.args.num_train_epochs`` can be `float`, we make ``epochs`` be a `float` always. + epochs = float(epochs) + + with self.args.strategy.scope(): + self.create_optimizer_and_scheduler(num_training_steps=t_total) + folder = os.path.join(self.args.output_dir, PREFIX_CHECKPOINT_DIR) + ckpt = tf.train.Checkpoint(optimizer=self.optimizer, model=self.model) + self.model.ckpt_manager = tf.train.CheckpointManager(ckpt, folder, max_to_keep=self.args.save_total_limit) + + iterations = self.optimizer.iterations + epochs_trained = 0 + steps_trained_in_current_epoch = 0 + if self.model.ckpt_manager.latest_checkpoint: + logger.info( + f"Checkpoint file {self.model.ckpt_manager.latest_checkpoint} found and restoring from checkpoint" + ) + ckpt.restore(self.model.ckpt_manager.latest_checkpoint).expect_partial() + + self.global_step = iterations.numpy() + + epochs_trained = self.global_step // self.steps_per_epoch + steps_trained_in_current_epoch = self.global_step % self.steps_per_epoch + + logger.info(" Continuing training from checkpoint, will skip to saved global_step") + logger.info(f" Continuing training from epoch {epochs_trained}") + logger.info(f" Continuing training from global step {self.global_step}") + logger.info(f" Will skip the first {steps_trained_in_current_epoch} steps in the first epoch") + + tf.summary.experimental.set_step(self.global_step) + + with self.tb_writer.as_default(): + tf.summary.text("args", self.args.to_json_string()) + + self.tb_writer.flush() + + logger.info("***** Running training *****") + logger.info(f" Num examples = {self.num_train_examples}") + # TODO: We might want to print a more precise ``epochs`` if self.args.max_steps > 0 ? + logger.info(f" Num Epochs = {epochs}") + logger.info(f" Instantaneous batch size per device = {self.args.per_device_train_batch_size}") + logger.info( + f" Total train batch size (w. parallel, distributed & accumulation) = {self.total_train_batch_size}" + ) + logger.info(f" Gradient Accumulation steps = {self.args.gradient_accumulation_steps}") + logger.info(f" Steps per epoch = {self.steps_per_epoch}") + logger.info(f" Total optimization steps = {t_total}") + + self.train_loss = tf.keras.metrics.Sum() + start_time = datetime.datetime.now() + + for epoch_iter in range(epochs_trained, int(epochs)): + # Reset the past mems state at the beginning of each epoch if necessary. + if self.args.past_index >= 0: + self._past = None + + for step, batch in enumerate(train_ds): + # Skip past any already trained steps if resuming training + if steps_trained_in_current_epoch > 0: + steps_trained_in_current_epoch -= 1 + continue + + self.distributed_training_steps(batch) + + self.global_step = iterations.numpy() + self.epoch_logging = epoch_iter + (step + 1) / self.steps_per_epoch + + training_loss = self.train_loss.result() / (step + 1) + + if self.args.debug: + logs = {} + logs["loss"] = training_loss.numpy() + logs["epoch"] = self.epoch_logging + + self.log(logs) + + if self.global_step == 1 and self.args.debug: + with self.tb_writer.as_default(): + tf.summary.trace_export( + name="training", step=self.global_step, profiler_outdir=self.args.logging_dir + ) + + if ( + self.args.eval_steps > 0 + and self.args.evaluation_strategy == IntervalStrategy.STEPS + and self.global_step % self.args.eval_steps == 0 + ): + self.evaluate() + + if (self.args.logging_steps > 0 and self.global_step % self.args.logging_steps == 0) or ( + self.global_step == 1 and self.args.logging_first_step + ): + logs = {} + logs["loss"] = training_loss.numpy() + logs["learning_rate"] = self.lr_scheduler(self.global_step).numpy() + logs["epoch"] = self.epoch_logging + + self.log(logs) + + if self.args.save_steps > 0 and self.global_step % self.args.save_steps == 0: + ckpt_save_path = self.model.ckpt_manager.save() + + logger.info(f"Saving checkpoint for step {self.global_step} at {ckpt_save_path}") + + if self.args.max_steps > 0 and self.global_step >= t_total: + break + + if self.global_step % self.steps_per_epoch == 0: + break + + self.train_loss.reset_states() + + if self.args.max_steps > 0 and self.global_step >= self.args.max_steps: + break + + end_time = datetime.datetime.now() + + logger.info(f"Training took: {str(end_time - start_time)}") + + if self.args.past_index and hasattr(self, "_past"): + # Clean the state at the end of training + delattr(self, "_past") + + def training_step(self, features, labels, nb_instances_in_global_batch): + """ + Perform a training step on features and labels. + + Subclass and override to inject some custom behavior. + """ + per_example_loss, _ = self.run_model(features, labels, True) + scaled_loss = per_example_loss / tf.cast(nb_instances_in_global_batch, dtype=per_example_loss.dtype) + gradients = tf.gradients(scaled_loss, self.model.trainable_variables) + gradients = [ + g if g is not None else tf.zeros_like(v) for g, v in zip(gradients, self.model.trainable_variables) + ] + + if self.args.gradient_accumulation_steps > 1: + self.gradient_accumulator(gradients) + + self.train_loss.update_state(scaled_loss) + + if self.args.gradient_accumulation_steps == 1: + return gradients + + def apply_gradients(self, features, labels, nb_instances_in_global_batch): + if self.args.gradient_accumulation_steps == 1: + gradients = self.training_step(features, labels, nb_instances_in_global_batch) + + self.optimizer.apply_gradients(list(zip(gradients, self.model.trainable_variables))) + else: + for _ in tf.range(self.args.gradient_accumulation_steps): + reduced_features = { + k: ft[: self.args.train_batch_size // self.args.n_replicas] for k, ft in features.items() + } + + if tf.is_tensor(labels): + reduced_labels = labels[: self.args.train_batch_size // self.args.n_replicas] + elif isinstance(labels, dict): + reduced_labels = { + k: lbl[: self.args.train_batch_size // self.args.n_replicas] for k, lbl in labels.items() + } + else: + raise ValueError("The labels must be either a tf.Tensor or a dict.") + + self.training_step(reduced_features, reduced_labels, nb_instances_in_global_batch) + + features = { + k: tf.concat( + [ft[self.args.train_batch_size // self.args.n_replicas :], reduced_features[k]], + axis=0, + ) + for k, ft in features.items() + } + + if tf.is_tensor(labels): + labels = tf.concat( + [labels[self.args.train_batch_size // self.args.n_replicas :], reduced_labels], axis=0 + ) + elif isinstance(labels, dict): + labels = { + k: tf.concat( + [lbl[self.args.train_batch_size // self.args.n_replicas :], reduced_labels[k]], + axis=0, + ) + for k, lbl in labels.items() + } + else: + raise ValueError("The labels must be either a tf.Tensor or a dict.") + + gradients = self.gradient_accumulator.gradients + gradients = [ + (tf.clip_by_value(grad, -self.args.max_grad_norm, self.args.max_grad_norm)) for grad in gradients + ] + + self.optimizer.apply_gradients(list(zip(gradients, self.model.trainable_variables))) + self.gradient_accumulator.reset() + + @tf.function + def distributed_training_steps(self, batch): + with self.args.strategy.scope(): + nb_instances_in_batch = self._compute_nb_instances(batch) + inputs = self._get_step_inputs(batch, nb_instances_in_batch) + + self.args.strategy.run(self.apply_gradients, inputs) + + @staticmethod + def _compute_nb_instances(batch): + labels = batch[-1] + if isinstance(labels, PerReplica): + labels = tf.concat(labels.values, axis=0) + + nb_instances = tf.reduce_sum(tf.cast(labels != -100, dtype=tf.int32)) + + return nb_instances + + @staticmethod + def _get_step_inputs(batch, nb_instances): + features, labels = batch + + if isinstance(labels, PerReplica): + # need to make a `PerReplica` objects for ``nb_instances`` + nb_instances = PerReplica([nb_instances] * len(labels.values)) + + step_inputs = (features, labels, nb_instances) + + return step_inputs + + def run_model(self, features, labels, training): + """ + Computes the loss of the given features and labels pair. + + Subclass and override this method if you want to inject some custom behavior. + + Args: + features (`tf.Tensor`): A batch of input features. + labels (`tf.Tensor`): A batch of labels. + training (`bool`): Whether or not to run the model in training mode. + + Returns: + A tuple of two `tf.Tensor`: The loss and logits. + """ + + if self.args.past_index >= 0 and getattr(self, "_past", None) is not None: + features["mems"] = self._past + + if isinstance(labels, (dict)): + outputs = self.model(features, training=training, **labels)[:2] + else: + outputs = self.model(features, labels=labels, training=training)[:2] + + loss, logits = outputs[:2] + + if self.args.past_index >= 0: + self._past = outputs[self.args.past_index] + + return loss, logits + + def predict(self, test_dataset: tf.data.Dataset) -> PredictionOutput: + """ + Run prediction and returns predictions and potential metrics. + + Depending on the dataset and your use case, your test dataset may contain labels. In that case, this method + will also return metrics, like in `evaluate()`. + + Args: + test_dataset ([`~tf.data.Dataset`]): + Dataset to run the predictions on. The dataset should yield tuples of `(features, labels)` where + `features` is a dict of input features and `labels` is the labels. If `labels` is a tensor, the loss is + calculated by the model by calling `model(features, labels=labels)`. If `labels` is a dict, such as + when using a QuestionAnswering head model with multiple targets, the loss is instead calculated by + calling `model(features, **labels)` + + Returns: *NamedTuple* A namedtuple with the following keys: + + - predictions (`np.ndarray`): The predictions on `test_dataset`. + - label_ids (`np.ndarray`, *optional*): The labels (if the dataset contained some). + - metrics (`Dict[str, float]`, *optional*): The potential dictionary of metrics (if the dataset contained + labels). + """ + test_ds, steps, num_examples = self.get_test_tfdataset(test_dataset) + + return self.prediction_loop(test_ds, steps, num_examples, description="Prediction") + + def save_model(self, output_dir: Optional[str] = None): + """ + Will save the model, so you can reload it using `from_pretrained()`. + """ + output_dir = output_dir if output_dir is not None else self.args.output_dir + + logger.info(f"Saving model in {output_dir}") + + if not isinstance(self.model, TFPreTrainedModel): + raise ValueError("Trainer.model appears to not be a PreTrainedModel") + + self.model.save_pretrained(output_dir) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..bb44c4c1ab07280da0996c2d50dae7aed0b87c72 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/trainer_utils.py @@ -0,0 +1,704 @@ +# coding=utf-8 +# Copyright 2020-present the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Utilities for the Trainer and TFTrainer class. Should be independent from PyTorch and TensorFlow. +""" + +import copy +import functools +import gc +import inspect +import os +import random +import re +import threading +import time +from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union + +import numpy as np + +from .utils import ( + ExplicitEnum, + is_psutil_available, + is_tf_available, + is_torch_available, + is_torch_cuda_available, + is_torch_tpu_available, + requires_backends, +) + + +if is_torch_available(): + import torch + +if is_tf_available(): + import tensorflow as tf + + +def seed_worker(_): + """ + Helper function to set worker seed during Dataloader initialization. + """ + worker_seed = torch.initial_seed() % 2**32 + set_seed(worker_seed) + + +def enable_full_determinism(seed: int): + """ + Helper function for reproducible behavior during distributed training. See + - https://pytorch.org/docs/stable/notes/randomness.html for pytorch + - https://www.tensorflow.org/api_docs/python/tf/config/experimental/enable_op_determinism for tensorflow + """ + # set seed first + set_seed(seed) + + if is_torch_available(): + # Enable PyTorch deterministic mode. This potentially requires either the environment + # variable 'CUDA_LAUNCH_BLOCKING' or 'CUBLAS_WORKSPACE_CONFIG' to be set, + # depending on the CUDA version, so we set them both here + os.environ["CUDA_LAUNCH_BLOCKING"] = "1" + os.environ["CUBLAS_WORKSPACE_CONFIG"] = ":16:8" + torch.use_deterministic_algorithms(True) + + # Enable CUDNN deterministic mode + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + if is_tf_available(): + tf.config.experimental.enable_op_determinism() + + +def set_seed(seed: int): + """ + Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch` and/or `tf` (if installed). + + Args: + seed (`int`): The seed to set. + """ + random.seed(seed) + np.random.seed(seed) + if is_torch_available(): + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + # ^^ safe to call this function even if cuda is not available + if is_tf_available(): + tf.random.set_seed(seed) + + +class EvalPrediction: + """ + Evaluation output (always contains labels), to be used to compute metrics. + + Parameters: + predictions (`np.ndarray`): Predictions of the model. + label_ids (`np.ndarray`): Targets to be matched. + inputs (`np.ndarray`, *optional*) + """ + + def __init__( + self, + predictions: Union[np.ndarray, Tuple[np.ndarray]], + label_ids: Union[np.ndarray, Tuple[np.ndarray]], + inputs: Optional[Union[np.ndarray, Tuple[np.ndarray]]] = None, + ): + self.predictions = predictions + self.label_ids = label_ids + self.inputs = inputs + + def __iter__(self): + if self.inputs is not None: + return iter((self.predictions, self.label_ids, self.inputs)) + else: + return iter((self.predictions, self.label_ids)) + + def __getitem__(self, idx): + if idx < 0 or idx > 2: + raise IndexError("tuple index out of range") + if idx == 2 and self.inputs is None: + raise IndexError("tuple index out of range") + if idx == 0: + return self.predictions + elif idx == 1: + return self.label_ids + elif idx == 2: + return self.inputs + + +class EvalLoopOutput(NamedTuple): + predictions: Union[np.ndarray, Tuple[np.ndarray]] + label_ids: Optional[Union[np.ndarray, Tuple[np.ndarray]]] + metrics: Optional[Dict[str, float]] + num_samples: Optional[int] + + +class PredictionOutput(NamedTuple): + predictions: Union[np.ndarray, Tuple[np.ndarray]] + label_ids: Optional[Union[np.ndarray, Tuple[np.ndarray]]] + metrics: Optional[Dict[str, float]] + + +class TrainOutput(NamedTuple): + global_step: int + training_loss: float + metrics: Dict[str, float] + + +PREFIX_CHECKPOINT_DIR = "checkpoint" +_re_checkpoint = re.compile(r"^" + PREFIX_CHECKPOINT_DIR + r"\-(\d+)$") + + +def get_last_checkpoint(folder): + content = os.listdir(folder) + checkpoints = [ + path + for path in content + if _re_checkpoint.search(path) is not None and os.path.isdir(os.path.join(folder, path)) + ] + if len(checkpoints) == 0: + return + return os.path.join(folder, max(checkpoints, key=lambda x: int(_re_checkpoint.search(x).groups()[0]))) + + +class IntervalStrategy(ExplicitEnum): + NO = "no" + STEPS = "steps" + EPOCH = "epoch" + + +class EvaluationStrategy(ExplicitEnum): + NO = "no" + STEPS = "steps" + EPOCH = "epoch" + + +class HubStrategy(ExplicitEnum): + END = "end" + EVERY_SAVE = "every_save" + CHECKPOINT = "checkpoint" + ALL_CHECKPOINTS = "all_checkpoints" + + +class BestRun(NamedTuple): + """ + The best run found by a hyperparameter search (see [`~Trainer.hyperparameter_search`]). + + Parameters: + run_id (`str`): + The id of the best run (if models were saved, the corresponding checkpoint will be in the folder ending + with run-{run_id}). + objective (`float`): + The objective that was obtained for this run. + hyperparameters (`Dict[str, Any]`): + The hyperparameters picked to get this run. + run_summary (`Optional[Any]`): + A summary of tuning experiments. `ray.tune.ExperimentAnalysis` object for Ray backend. + """ + + run_id: str + objective: float + hyperparameters: Dict[str, Any] + run_summary: Optional[Any] = None + + +def default_compute_objective(metrics: Dict[str, float]) -> float: + """ + The default objective to maximize/minimize when doing an hyperparameter search. It is the evaluation loss if no + metrics are provided to the [`Trainer`], the sum of all metrics otherwise. + + Args: + metrics (`Dict[str, float]`): The metrics returned by the evaluate method. + + Return: + `float`: The objective to minimize or maximize + """ + metrics = copy.deepcopy(metrics) + loss = metrics.pop("eval_loss", None) + _ = metrics.pop("epoch", None) + # Remove speed metrics + speed_metrics = [ + m + for m in metrics.keys() + if m.endswith("_runtime") or m.endswith("_per_second") or m.endswith("_compilation_time") + ] + for sm in speed_metrics: + _ = metrics.pop(sm, None) + return loss if len(metrics) == 0 else sum(metrics.values()) + + +def default_hp_space_optuna(trial) -> Dict[str, float]: + from .integrations import is_optuna_available + + assert is_optuna_available(), "This function needs Optuna installed: `pip install optuna`" + return { + "learning_rate": trial.suggest_float("learning_rate", 1e-6, 1e-4, log=True), + "num_train_epochs": trial.suggest_int("num_train_epochs", 1, 5), + "seed": trial.suggest_int("seed", 1, 40), + "per_device_train_batch_size": trial.suggest_categorical("per_device_train_batch_size", [4, 8, 16, 32, 64]), + } + + +def default_hp_space_ray(trial) -> Dict[str, float]: + from .integrations import is_ray_tune_available + + assert is_ray_tune_available(), "This function needs ray installed: `pip install ray[tune]`" + from ray import tune + + return { + "learning_rate": tune.loguniform(1e-6, 1e-4), + "num_train_epochs": tune.choice(list(range(1, 6))), + "seed": tune.uniform(1, 40), + "per_device_train_batch_size": tune.choice([4, 8, 16, 32, 64]), + } + + +def default_hp_space_sigopt(trial): + return [ + {"bounds": {"min": 1e-6, "max": 1e-4}, "name": "learning_rate", "type": "double", "transformamtion": "log"}, + {"bounds": {"min": 1, "max": 6}, "name": "num_train_epochs", "type": "int"}, + {"bounds": {"min": 1, "max": 40}, "name": "seed", "type": "int"}, + { + "categorical_values": ["4", "8", "16", "32", "64"], + "name": "per_device_train_batch_size", + "type": "categorical", + }, + ] + + +def default_hp_space_wandb(trial) -> Dict[str, float]: + from .integrations import is_wandb_available + + if not is_wandb_available(): + raise ImportError("This function needs wandb installed: `pip install wandb`") + + return { + "method": "random", + "metric": {"name": "objective", "goal": "minimize"}, + "parameters": { + "learning_rate": {"distribution": "uniform", "min": 1e-6, "max": 1e-4}, + "num_train_epochs": {"distribution": "int_uniform", "min": 1, "max": 6}, + "seed": {"distribution": "int_uniform", "min": 1, "max": 40}, + "per_device_train_batch_size": {"values": [4, 8, 16, 32, 64]}, + }, + } + + +class HPSearchBackend(ExplicitEnum): + OPTUNA = "optuna" + RAY = "ray" + SIGOPT = "sigopt" + WANDB = "wandb" + + +default_hp_space = { + HPSearchBackend.OPTUNA: default_hp_space_optuna, + HPSearchBackend.RAY: default_hp_space_ray, + HPSearchBackend.SIGOPT: default_hp_space_sigopt, + HPSearchBackend.WANDB: default_hp_space_wandb, +} + + +def is_main_process(local_rank): + """ + Whether or not the current process is the local process, based on `xm.get_ordinal()` (for TPUs) first, then on + `local_rank`. + """ + if is_torch_tpu_available(check_device=True): + import torch_xla.core.xla_model as xm + + return xm.get_ordinal() == 0 + return local_rank in [-1, 0] + + +def total_processes_number(local_rank): + """ + Return the number of processes launched in parallel. Works with `torch.distributed` and TPUs. + """ + if is_torch_tpu_available(check_device=True): + import torch_xla.core.xla_model as xm + + return xm.xrt_world_size() + elif local_rank != -1 and is_torch_available(): + import torch + + return torch.distributed.get_world_size() + return 1 + + +def speed_metrics(split, start_time, num_samples=None, num_steps=None): + """ + Measure and return speed performance metrics. + + This function requires a time snapshot `start_time` before the operation to be measured starts and this function + should be run immediately after the operation to be measured has completed. + + Args: + - split: name to prefix metric (like train, eval, test...) + - start_time: operation start time + - num_samples: number of samples processed + """ + runtime = time.time() - start_time + result = {f"{split}_runtime": round(runtime, 4)} + if num_samples is not None: + samples_per_second = num_samples / runtime + result[f"{split}_samples_per_second"] = round(samples_per_second, 3) + if num_steps is not None: + steps_per_second = num_steps / runtime + result[f"{split}_steps_per_second"] = round(steps_per_second, 3) + return result + + +class SchedulerType(ExplicitEnum): + LINEAR = "linear" + COSINE = "cosine" + COSINE_WITH_RESTARTS = "cosine_with_restarts" + POLYNOMIAL = "polynomial" + CONSTANT = "constant" + CONSTANT_WITH_WARMUP = "constant_with_warmup" + INVERSE_SQRT = "inverse_sqrt" + REDUCE_ON_PLATEAU = "reduce_lr_on_plateau" + + +class TrainerMemoryTracker: + """ + A helper class that tracks cpu and gpu memory. + + This class will silently skip unless `psutil` is available. Install with `pip install psutil`. + + When a stage completes, it can pass metrics dict to update with the memory metrics gathered during this stage. + + Example : + + ```python + self._memory_tracker = TrainerMemoryTracker(self.args.skip_memory_metrics) + self._memory_tracker.start() + # code ... + metrics = {"train_runtime": 10.5} + self._memory_tracker.stop_and_update_metrics(metrics) + ``` + + At the moment GPU tracking is only for `pytorch`, but can be extended to support `tensorflow`. + + To understand this class' intricacies please read the documentation of [`~Trainer.log_metrics`]. + """ + + # map trainer methods to metrics prefix + stages = { + "__init__": "init", + "train": "train", + "_inner_training_loop": "train", + "evaluate": "eval", + "predict": "test", + } + + def __init__(self, skip_memory_metrics=False): + self.skip_memory_metrics = skip_memory_metrics + + if not is_psutil_available(): + # soft dependency on psutil + self.skip_memory_metrics = True + + if self.skip_memory_metrics: + return + + import psutil # noqa + + if is_torch_cuda_available(): + import torch + + self.torch = torch + self.gpu = {} + else: + self.torch = None + + self.process = psutil.Process() + + self.cur_stage = None + self.cpu = {} + self.init_reported = False + + def derive_stage(self): + """derives the stage/caller name automatically""" + caller = inspect.currentframe().f_back.f_back.f_code.co_name + if caller in self.stages: + return self.stages[caller] + else: + raise ValueError( + f"was called from {caller}, but only expect to be called from one of {self.stages.keys()}" + ) + + def cpu_mem_used(self): + """get resident set size memory for the current process""" + return self.process.memory_info().rss + + def peak_monitor_func(self): + self.cpu_mem_used_peak = -1 + + while True: + self.cpu_mem_used_peak = max(self.cpu_mem_used(), self.cpu_mem_used_peak) + + # can't sleep or will not catch the peak right (this comment is here on purpose) + # time.sleep(0.001) # 1msec + + if not self.peak_monitoring: + break + + def start(self): + """start tracking for the caller's stage""" + if self.skip_memory_metrics: + return + + stage = self.derive_stage() + # deal with nested calls of eval during train - simply ignore those + if self.cur_stage is not None and self.cur_stage != stage: + return + + self.cur_stage = stage + + gc.collect() + + if self.torch is not None: + self.torch.cuda.reset_peak_memory_stats() + self.torch.cuda.empty_cache() + + # gpu + if self.torch is not None: + self.gpu_mem_used_at_start = self.torch.cuda.memory_allocated() + + # cpu + self.cpu_mem_used_at_start = self.cpu_mem_used() + + self.peak_monitoring = True + peak_monitor_thread = threading.Thread(target=self.peak_monitor_func) + peak_monitor_thread.daemon = True + peak_monitor_thread.start() + + def stop(self, stage): + """stop tracking for the passed stage""" + + # deal with nested calls of eval during train - simply ignore those + if self.cur_stage is not None and self.cur_stage != stage: + return + + # this sends a signal to peak_monitor_func to complete its loop + self.peak_monitoring = False + + # first ensure all objects get collected and their memory is freed + gc.collect() + + if self.torch is not None: + self.torch.cuda.empty_cache() + + # concepts: + # - alloc_delta: the difference of allocated memory between the end and the start + # - peaked_delta: the difference between the peak memory and the current memory + # in order to know how much memory the measured code consumed one needs to sum these two + + # gpu + if self.torch is not None: + self.gpu_mem_used_now = self.torch.cuda.memory_allocated() + self.gpu_mem_used_peak = self.torch.cuda.max_memory_allocated() + self.gpu[self.cur_stage] = { + "begin": self.gpu_mem_used_at_start, + "end": self.gpu_mem_used_now, + "alloc": (self.gpu_mem_used_now - self.gpu_mem_used_at_start), + "peaked": max(0, self.gpu_mem_used_peak - self.gpu_mem_used_now), + } + + # cpu + self.cpu_mem_used_now = self.cpu_mem_used() + self.cpu[self.cur_stage] = { + "begin": self.cpu_mem_used_at_start, + "end": self.cpu_mem_used_now, + "alloc": (self.cpu_mem_used_now - self.cpu_mem_used_at_start), + "peaked": max(0, self.cpu_mem_used_peak - self.cpu_mem_used_now), + } + + # reset - cycle finished + self.cur_stage = None + + def update_metrics(self, stage, metrics): + """updates the metrics""" + if self.skip_memory_metrics: + return + + # deal with nested calls of eval during train - simply ignore those + if self.cur_stage is not None and self.cur_stage != stage: + return + + # since we don't have a way to return init metrics, we push them into the first of train/val/predict + stages = [stage] + if not self.init_reported: + stages.insert(0, "init") + self.init_reported = True + + for stage in stages: + for t in ["alloc", "peaked"]: + if stage in self.cpu and t in self.cpu[stage]: + metrics[f"{stage}_mem_cpu_{t}_delta"] = self.cpu[stage][t] + if self.torch is not None and stage in self.gpu and t in self.gpu[stage]: + metrics[f"{stage}_mem_gpu_{t}_delta"] = self.gpu[stage][t] + # if we need additional debug info, enable the following + # for t in ["begin", "end"]: + # if stage in self.cpu and t in self.cpu[stage]: + # metrics[f"{stage}_mem_cpu_{t}"] = self.cpu[stage][t] + # if self.torch is not None and stage in self.gpu and t in self.gpu[stage]: + # metrics[f"{stage}_mem_gpu_{t}"] = self.gpu[stage][t] + + # since memory can be allocated before init, and it might be difficult to track overall + # memory usage, in particular for GPU, let's report memory usage at the point init was called + if stages[0] == "init": + metrics["before_init_mem_cpu"] = self.cpu["init"]["begin"] + if self.torch is not None: + metrics["before_init_mem_gpu"] = self.gpu["init"]["begin"] + # if we also wanted to report any additional memory allocations in between init and + # whatever the next stage was we could also report this: + # if self.cpu["init"]["end"] != self.cpu[stage]["begin"]: + # metrics[f"after_init_mem_cpu_delta"] = self.cpu[stage]["begin"] - self.cpu["init"]["end"] + # if self.torch is not None and self.gpu["init"]["end"] != self.gpu[stage]["begin"]: + # metrics[f"after_init_mem_gpu_delta"] = self.gpu[stage]["begin"] - self.gpu["init"]["end"] + + def stop_and_update_metrics(self, metrics=None): + """combine stop and metrics update in one call for simpler code""" + if self.skip_memory_metrics: + return + + stage = self.derive_stage() + self.stop(stage) + + # init doesn't have metrics to update so we just save that data for later stages to retrieve + if metrics is not None: + self.update_metrics(stage, metrics) + + +def has_length(dataset): + """ + Checks if the dataset implements __len__() and it doesn't raise an error + """ + try: + return len(dataset) is not None + except TypeError: + # TypeError: len() of unsized object + return False + + +def denumpify_detensorize(metrics): + """ + Recursively calls `.item()` on the element of the dictionary passed + """ + if isinstance(metrics, (list, tuple)): + return type(metrics)(denumpify_detensorize(m) for m in metrics) + elif isinstance(metrics, dict): + return type(metrics)({k: denumpify_detensorize(v) for k, v in metrics.items()}) + elif isinstance(metrics, np.generic): + return metrics.item() + elif is_torch_available() and isinstance(metrics, torch.Tensor) and metrics.numel() == 1: + return metrics.item() + return metrics + + +def number_of_arguments(func): + """ + Return the number of arguments of the passed function, even if it's a partial function. + """ + if isinstance(func, functools.partial): + total_args = len(inspect.signature(func.func).parameters) + return total_args - len(func.args) - len(func.keywords) + return len(inspect.signature(func).parameters) + + +class ShardedDDPOption(ExplicitEnum): + SIMPLE = "simple" + ZERO_DP_2 = "zero_dp_2" + ZERO_DP_3 = "zero_dp_3" + OFFLOAD = "offload" + AUTO_WRAP = "auto_wrap" + + +def find_executable_batch_size( + function: callable = None, starting_batch_size: int = 128, auto_find_batch_size: bool = False +): + """ + Args: + A basic decorator that will try to execute `function`. If it fails from exceptions related to out-of-memory or + CUDNN, the batch size is cut in half and passed to `function` `function` must take in a `batch_size` parameter as + its first argument. + function (`callable`, *optional*) + A function to wrap + starting_batch_size (`int`, *optional*) + The batch size to try and fit into memory + auto_find_batch_size (`bool`, *optional*) + If False, will just execute `function` + """ + if function is None: + return functools.partial( + find_executable_batch_size, + starting_batch_size=starting_batch_size, + auto_find_batch_size=auto_find_batch_size, + ) + + if auto_find_batch_size: + requires_backends(find_executable_batch_size, "accelerate") + from accelerate.utils import find_executable_batch_size as accelerate_find_executable_batch_size + + return accelerate_find_executable_batch_size(function=function, starting_batch_size=starting_batch_size) + + return functools.partial(function, batch_size=starting_batch_size) + + +class FSDPOption(ExplicitEnum): + FULL_SHARD = "full_shard" + SHARD_GRAD_OP = "shard_grad_op" + NO_SHARD = "no_shard" + OFFLOAD = "offload" + AUTO_WRAP = "auto_wrap" + + +class RemoveColumnsCollator: + """Wrap the data collator to remove unused columns before they are passed to the collator.""" + + def __init__( + self, + data_collator, + signature_columns, + logger=None, + model_name: Optional[str] = None, + description: Optional[str] = None, + ): + self.data_collator = data_collator + self.signature_columns = signature_columns + self.logger = logger + self.description = description + self.model_name = model_name + self.message_logged = False + + def _remove_columns(self, feature: dict) -> dict: + if not isinstance(feature, dict): + return feature + if not self.message_logged and self.logger and self.model_name: + ignored_columns = list(set(feature.keys()) - set(self.signature_columns)) + if len(ignored_columns) > 0: + dset_description = "" if self.description is None else f"in the {self.description} set" + self.logger.info( + f"The following columns {dset_description} don't have a corresponding argument in " + f"`{self.model_name}.forward` and have been ignored: {', '.join(ignored_columns)}." + f" If {', '.join(ignored_columns)} are not expected by `{self.model_name}.forward`, " + " you can safely ignore this message." + ) + self.message_logged = True + return {k: v for k, v in feature.items() if k in self.signature_columns} + + def __call__(self, features: List[dict]): + features = [self._remove_columns(feature) for feature in features] + return self.data_collator(features) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args.py new file mode 100644 index 0000000000000000000000000000000000000000..44f28ff99ef4035f5df524c9c39a50a7da248c4e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args.py @@ -0,0 +1,2476 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import contextlib +import io +import json +import math +import os +import warnings +from dataclasses import asdict, dataclass, field, fields +from datetime import timedelta +from enum import Enum +from pathlib import Path +from typing import Any, Dict, List, Optional, Union + +from packaging import version + +from .debug_utils import DebugOption +from .trainer_utils import ( + EvaluationStrategy, + FSDPOption, + HubStrategy, + IntervalStrategy, + SchedulerType, + ShardedDDPOption, +) +from .utils import ( + ExplicitEnum, + cached_property, + get_full_repo_name, + is_accelerate_available, + is_safetensors_available, + is_sagemaker_dp_enabled, + is_sagemaker_mp_enabled, + is_torch_available, + is_torch_bf16_cpu_available, + is_torch_bf16_gpu_available, + is_torch_neuroncore_available, + is_torch_tf32_available, + is_torch_tpu_available, + logging, + requires_backends, +) +from .utils.import_utils import is_optimum_neuron_available + + +logger = logging.get_logger(__name__) +log_levels = logging.get_log_levels_dict().copy() +trainer_log_levels = dict(**log_levels, passive=-1) + +if is_torch_available(): + import torch + import torch.distributed as dist + +if is_accelerate_available(): + from accelerate import PartialState + from accelerate.utils import DistributedType + +if is_torch_tpu_available(check_device=False): + import torch_xla.core.xla_model as xm + +if is_torch_neuroncore_available(check_device=False): + # torchrun support + # https://github.com/pytorch/xla/pull/3609 + if os.environ.get("TORCHELASTIC_RUN_ID"): + if is_optimum_neuron_available(): + logger.info( + "Make sure that you are performing the training with the TrainiumTrainer from optimum[neuron], this " + "will fail otherwise." + ) + else: + logger.warning( + "Please use the TrainiumTrainer from optimum[neuron] instead of the Transformers library to perform " + "training on AWS Trainium instances. More information here: " + "https://github.com/huggingface/optimum-neuron" + ) + import torch_xla.distributed.xla_backend as xbn + + if not isinstance(torch.distributed.group.WORLD, xbn.ProcessGroupXla): + torch.distributed.init_process_group(backend="xla") + if not isinstance(torch.distributed.group.WORLD, xbn.ProcessGroupXla): + raise AssertionError("Failed to initialize torch.distributed process group using XLA backend.") + + +if is_sagemaker_mp_enabled(): + import smdistributed.modelparallel.torch as smp + + smp.init() + + +def default_logdir() -> str: + """ + Same default as PyTorch + """ + import socket + from datetime import datetime + + current_time = datetime.now().strftime("%b%d_%H-%M-%S") + return os.path.join("runs", current_time + "_" + socket.gethostname()) + + +def get_int_from_env(env_keys, default): + """Returns the first positive env value found in the `env_keys` list or the default.""" + for e in env_keys: + val = int(os.environ.get(e, -1)) + if val >= 0: + return val + return default + + +def get_xla_device_type(device: "torch.device") -> Optional[str]: + """ + Returns the xla device type (CPU|GPU|TPU) or None if the device is a non-xla device. + """ + if is_torch_tpu_available(): + return xm.xla_real_devices([device])[0].split(":")[0] + return None + + +class OptimizerNames(ExplicitEnum): + """ + Stores the acceptable string identifiers for optimizers. + """ + + ADAMW_HF = "adamw_hf" + ADAMW_TORCH = "adamw_torch" + ADAMW_TORCH_FUSED = "adamw_torch_fused" + ADAMW_TORCH_XLA = "adamw_torch_xla" + ADAMW_APEX_FUSED = "adamw_apex_fused" + ADAFACTOR = "adafactor" + ADAMW_BNB = "adamw_bnb_8bit" + ADAMW_ANYPRECISION = "adamw_anyprecision" + SGD = "sgd" + ADAGRAD = "adagrad" + + +@dataclass +class TrainingArguments: + """ + TrainingArguments is the subset of the arguments we use in our example scripts **which relate to the training loop + itself**. + + Using [`HfArgumentParser`] we can turn this class into + [argparse](https://docs.python.org/3/library/argparse#module-argparse) arguments that can be specified on the + command line. + + Parameters: + output_dir (`str`): + The output directory where the model predictions and checkpoints will be written. + overwrite_output_dir (`bool`, *optional*, defaults to `False`): + If `True`, overwrite the content of the output directory. Use this to continue training if `output_dir` + points to a checkpoint directory. + do_train (`bool`, *optional*, defaults to `False`): + Whether to run training or not. This argument is not directly used by [`Trainer`], it's intended to be used + by your training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + do_eval (`bool`, *optional*): + Whether to run evaluation on the validation set or not. Will be set to `True` if `evaluation_strategy` is + different from `"no"`. This argument is not directly used by [`Trainer`], it's intended to be used by your + training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + do_predict (`bool`, *optional*, defaults to `False`): + Whether to run predictions on the test set or not. This argument is not directly used by [`Trainer`], it's + intended to be used by your training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + evaluation_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"no"`): + The evaluation strategy to adopt during training. Possible values are: + + - `"no"`: No evaluation is done during training. + - `"steps"`: Evaluation is done (and logged) every `eval_steps`. + - `"epoch"`: Evaluation is done at the end of each epoch. + + prediction_loss_only (`bool`, *optional*, defaults to `False`): + When performing evaluation and generating predictions, only returns the loss. + per_device_train_batch_size (`int`, *optional*, defaults to 8): + The batch size per GPU/TPU core/CPU for training. + per_device_eval_batch_size (`int`, *optional*, defaults to 8): + The batch size per GPU/TPU core/CPU for evaluation. + gradient_accumulation_steps (`int`, *optional*, defaults to 1): + Number of updates steps to accumulate the gradients for, before performing a backward/update pass. + + + + When using gradient accumulation, one step is counted as one step with backward pass. Therefore, logging, + evaluation, save will be conducted every `gradient_accumulation_steps * xxx_step` training examples. + + + + eval_accumulation_steps (`int`, *optional*): + Number of predictions steps to accumulate the output tensors for, before moving the results to the CPU. If + left unset, the whole predictions are accumulated on GPU/TPU before being moved to the CPU (faster but + requires more memory). + eval_delay (`float`, *optional*): + Number of epochs or steps to wait for before the first evaluation can be performed, depending on the + evaluation_strategy. + learning_rate (`float`, *optional*, defaults to 5e-5): + The initial learning rate for [`AdamW`] optimizer. + weight_decay (`float`, *optional*, defaults to 0): + The weight decay to apply (if not zero) to all layers except all bias and LayerNorm weights in [`AdamW`] + optimizer. + adam_beta1 (`float`, *optional*, defaults to 0.9): + The beta1 hyperparameter for the [`AdamW`] optimizer. + adam_beta2 (`float`, *optional*, defaults to 0.999): + The beta2 hyperparameter for the [`AdamW`] optimizer. + adam_epsilon (`float`, *optional*, defaults to 1e-8): + The epsilon hyperparameter for the [`AdamW`] optimizer. + max_grad_norm (`float`, *optional*, defaults to 1.0): + Maximum gradient norm (for gradient clipping). + num_train_epochs(`float`, *optional*, defaults to 3.0): + Total number of training epochs to perform (if not an integer, will perform the decimal part percents of + the last epoch before stopping training). + max_steps (`int`, *optional*, defaults to -1): + If set to a positive number, the total number of training steps to perform. Overrides `num_train_epochs`. + In case of using a finite iterable dataset the training may stop before reaching the set number of steps + when all data is exhausted + lr_scheduler_type (`str` or [`SchedulerType`], *optional*, defaults to `"linear"`): + The scheduler type to use. See the documentation of [`SchedulerType`] for all possible values. + warmup_ratio (`float`, *optional*, defaults to 0.0): + Ratio of total training steps used for a linear warmup from 0 to `learning_rate`. + warmup_steps (`int`, *optional*, defaults to 0): + Number of steps used for a linear warmup from 0 to `learning_rate`. Overrides any effect of `warmup_ratio`. + log_level (`str`, *optional*, defaults to `passive`): + Logger log level to use on the main process. Possible choices are the log levels as strings: 'debug', + 'info', 'warning', 'error' and 'critical', plus a 'passive' level which doesn't set anything and keeps the + current log level for the Transformers library (which will be `"warning"` by default). + log_level_replica (`str`, *optional*, defaults to `"warning"`): + Logger log level to use on replicas. Same choices as `log_level`" + log_on_each_node (`bool`, *optional*, defaults to `True`): + In multinode distributed training, whether to log using `log_level` once per node, or only on the main + node. + logging_dir (`str`, *optional*): + [TensorBoard](https://www.tensorflow.org/tensorboard) log directory. Will default to + *output_dir/runs/**CURRENT_DATETIME_HOSTNAME***. + logging_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The logging strategy to adopt during training. Possible values are: + + - `"no"`: No logging is done during training. + - `"epoch"`: Logging is done at the end of each epoch. + - `"steps"`: Logging is done every `logging_steps`. + + logging_first_step (`bool`, *optional*, defaults to `False`): + Whether to log and evaluate the first `global_step` or not. + logging_steps (`int` or `float`, *optional*, defaults to 500): + Number of update steps between two logs if `logging_strategy="steps"`. Should be an integer or a float in + range `[0,1)`. If smaller than 1, will be interpreted as ratio of total training steps. + logging_nan_inf_filter (`bool`, *optional*, defaults to `True`): + Whether to filter `nan` and `inf` losses for logging. If set to `True` the loss of every step that is `nan` + or `inf` is filtered and the average loss of the current logging window is taken instead. + + + + `logging_nan_inf_filter` only influences the logging of loss values, it does not change the behavior the + gradient is computed or applied to the model. + + + + save_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The checkpoint save strategy to adopt during training. Possible values are: + + - `"no"`: No save is done during training. + - `"epoch"`: Save is done at the end of each epoch. + - `"steps"`: Save is done every `save_steps`. + save_steps (`int` or `float`, *optional*, defaults to 500): + Number of updates steps before two checkpoint saves if `save_strategy="steps"`. Should be an integer or a + float in range `[0,1)`. If smaller than 1, will be interpreted as ratio of total training steps. + save_total_limit (`int`, *optional*): + If a value is passed, will limit the total amount of checkpoints. Deletes the older checkpoints in + `output_dir`. + save_safetensors (`bool`, *optional*, defaults to `False`): + Use [safetensors](https://huggingface.co/docs/safetensors) saving and loading for state dicts instead of + default `torch.load` and `torch.save`. + save_on_each_node (`bool`, *optional*, defaults to `False`): + When doing multi-node distributed training, whether to save models and checkpoints on each node, or only on + the main one. + + This should not be activated when the different nodes use the same storage as the files will be saved with + the same names for each node. + no_cuda (`bool`, *optional*, defaults to `False`): + Whether to not use CUDA even when it is available or not. + seed (`int`, *optional*, defaults to 42): + Random seed that will be set at the beginning of training. To ensure reproducibility across runs, use the + [`~Trainer.model_init`] function to instantiate the model if it has some randomly initialized parameters. + data_seed (`int`, *optional*): + Random seed to be used with data samplers. If not set, random generators for data sampling will use the + same seed as `seed`. This can be used to ensure reproducibility of data sampling, independent of the model + seed. + jit_mode_eval (`bool`, *optional*, defaults to `False`): + Whether or not to use PyTorch jit trace for inference. + use_ipex (`bool`, *optional*, defaults to `False`): + Use Intel extension for PyTorch when it is available. [IPEX + installation](https://github.com/intel/intel-extension-for-pytorch). + bf16 (`bool`, *optional*, defaults to `False`): + Whether to use bf16 16-bit (mixed) precision training instead of 32-bit training. Requires Ampere or higher + NVIDIA architecture or using CPU (no_cuda). This is an experimental API and it may change. + fp16 (`bool`, *optional*, defaults to `False`): + Whether to use fp16 16-bit (mixed) precision training instead of 32-bit training. + fp16_opt_level (`str`, *optional*, defaults to 'O1'): + For `fp16` training, Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']. See details on + the [Apex documentation](https://nvidia.github.io/apex/amp). + fp16_backend (`str`, *optional*, defaults to `"auto"`): + This argument is deprecated. Use `half_precision_backend` instead. + half_precision_backend (`str`, *optional*, defaults to `"auto"`): + The backend to use for mixed precision training. Must be one of `"auto", "cuda_amp", "apex", "cpu_amp"`. + `"auto"` will use CPU/CUDA AMP or APEX depending on the PyTorch version detected, while the other choices + will force the requested backend. + bf16_full_eval (`bool`, *optional*, defaults to `False`): + Whether to use full bfloat16 evaluation instead of 32-bit. This will be faster and save memory but can harm + metric values. This is an experimental API and it may change. + fp16_full_eval (`bool`, *optional*, defaults to `False`): + Whether to use full float16 evaluation instead of 32-bit. This will be faster and save memory but can harm + metric values. + tf32 (`bool`, *optional*): + Whether to enable the TF32 mode, available in Ampere and newer GPU architectures. The default value depends + on PyTorch's version default of `torch.backends.cuda.matmul.allow_tf32`. For more details please refer to + the [TF32](https://huggingface.co/docs/transformers/performance#tf32) documentation. This is an + experimental API and it may change. + local_rank (`int`, *optional*, defaults to -1): + Rank of the process during distributed training. + ddp_backend (`str`, *optional*): + The backend to use for distributed training. Must be one of `"nccl"`, `"mpi"`, `"ccl"`, `"gloo"`. + tpu_num_cores (`int`, *optional*): + When training on TPU, the number of TPU cores (automatically passed by launcher script). + dataloader_drop_last (`bool`, *optional*, defaults to `False`): + Whether to drop the last incomplete batch (if the length of the dataset is not divisible by the batch size) + or not. + eval_steps (`int` or `float`, *optional*): + Number of update steps between two evaluations if `evaluation_strategy="steps"`. Will default to the same + value as `logging_steps` if not set. Should be an integer or a float in range `[0,1)`. If smaller than 1, + will be interpreted as ratio of total training steps. + dataloader_num_workers (`int`, *optional*, defaults to 0): + Number of subprocesses to use for data loading (PyTorch only). 0 means that the data will be loaded in the + main process. + past_index (`int`, *optional*, defaults to -1): + Some models like [TransformerXL](../model_doc/transformerxl) or [XLNet](../model_doc/xlnet) can make use of + the past hidden states for their predictions. If this argument is set to a positive int, the `Trainer` will + use the corresponding output (usually index 2) as the past state and feed it to the model at the next + training step under the keyword argument `mems`. + run_name (`str`, *optional*): + A descriptor for the run. Typically used for [wandb](https://www.wandb.com/) and + [mlflow](https://www.mlflow.org/) logging. + disable_tqdm (`bool`, *optional*): + Whether or not to disable the tqdm progress bars and table of metrics produced by + [`~notebook.NotebookTrainingTracker`] in Jupyter Notebooks. Will default to `True` if the logging level is + set to warn or lower (default), `False` otherwise. + remove_unused_columns (`bool`, *optional*, defaults to `True`): + Whether or not to automatically remove the columns unused by the model forward method. + + (Note that this behavior is not implemented for [`TFTrainer`] yet.) + label_names (`List[str]`, *optional*): + The list of keys in your dictionary of inputs that correspond to the labels. + + Will eventually default to the list of argument names accepted by the model that contain the word "label", + except if the model used is one of the `XxxForQuestionAnswering` in which case it will also include the + `["start_positions", "end_positions"]` keys. + load_best_model_at_end (`bool`, *optional*, defaults to `False`): + Whether or not to load the best model found during training at the end of training. + + + + When set to `True`, the parameters `save_strategy` needs to be the same as `evaluation_strategy`, and in + the case it is "steps", `save_steps` must be a round multiple of `eval_steps`. + + + + metric_for_best_model (`str`, *optional*): + Use in conjunction with `load_best_model_at_end` to specify the metric to use to compare two different + models. Must be the name of a metric returned by the evaluation with or without the prefix `"eval_"`. Will + default to `"loss"` if unspecified and `load_best_model_at_end=True` (to use the evaluation loss). + + If you set this value, `greater_is_better` will default to `True`. Don't forget to set it to `False` if + your metric is better when lower. + greater_is_better (`bool`, *optional*): + Use in conjunction with `load_best_model_at_end` and `metric_for_best_model` to specify if better models + should have a greater metric or not. Will default to: + + - `True` if `metric_for_best_model` is set to a value that isn't `"loss"` or `"eval_loss"`. + - `False` if `metric_for_best_model` is not set, or set to `"loss"` or `"eval_loss"`. + ignore_data_skip (`bool`, *optional*, defaults to `False`): + When resuming training, whether or not to skip the epochs and batches to get the data loading at the same + stage as in the previous training. If set to `True`, the training will begin faster (as that skipping step + can take a long time) but will not yield the same results as the interrupted training would have. + sharded_ddp (`bool`, `str` or list of [`~trainer_utils.ShardedDDPOption`], *optional*, defaults to `False`): + Use Sharded DDP training from [FairScale](https://github.com/facebookresearch/fairscale) (in distributed + training only). This is an experimental feature. + + A list of options along the following: + + - `"simple"`: to use first instance of sharded DDP released by fairscale (`ShardedDDP`) similar to ZeRO-2. + - `"zero_dp_2"`: to use the second instance of sharded DPP released by fairscale (`FullyShardedDDP`) in + Zero-2 mode (with `reshard_after_forward=False`). + - `"zero_dp_3"`: to use the second instance of sharded DPP released by fairscale (`FullyShardedDDP`) in + Zero-3 mode (with `reshard_after_forward=True`). + - `"offload"`: to add ZeRO-offload (only compatible with `"zero_dp_2"` and `"zero_dp_3"`). + + If a string is passed, it will be split on space. If a bool is passed, it will be converted to an empty + list for `False` and `["simple"]` for `True`. + fsdp (`bool`, `str` or list of [`~trainer_utils.FSDPOption`], *optional*, defaults to `False`): + Use PyTorch Distributed Parallel Training (in distributed training only). + + A list of options along the following: + + - `"full_shard"`: Shard parameters, gradients and optimizer states. + - `"shard_grad_op"`: Shard optimizer states and gradients. + - `"offload"`: Offload parameters and gradients to CPUs (only compatible with `"full_shard"` and + `"shard_grad_op"`). + - `"auto_wrap"`: Automatically recursively wrap layers with FSDP using `default_auto_wrap_policy`. + fsdp_config (`str` or `dict`, *optional*): + Config to be used with fsdp (Pytorch Distributed Parallel Training). The value is either a location of + deepspeed json config file (e.g., `ds_config.json`) or an already loaded json file as `dict`. + + A List of config and its options: + - fsdp_min_num_params (`int`, *optional*, defaults to `0`): + FSDP's minimum number of parameters for Default Auto Wrapping. (useful only when `fsdp` field is + passed). + - fsdp_transformer_layer_cls_to_wrap (`List[str]`, *optional*): + List of transformer layer class names (case-sensitive) to wrap, e.g, `BertLayer`, `GPTJBlock`, + `T5Block` .... (useful only when `fsdp` flag is passed). + - fsdp_backward_prefetch (`str`, *optional*) + FSDP's backward prefetch mode. Controls when to prefetch next set of parameters (useful only when + `fsdp` field is passed). + + A list of options along the following: + + - `"backward_pre"` : Prefetches the next set of parameters before the current set of parameter's + gradient + computation. + - `"backward_pos"` : This prefetches the next set of parameters after the current set of + parameter’s + gradient computation. + - fsdp_forward_prefetch (`bool`, *optional*, defaults to `False`) + FSDP's forward prefetch mode (useful only when `fsdp` field is passed). + If `"True"`, then FSDP explicitly prefetches the next upcoming all-gather while executing in the + forward pass. + - limit_all_gathers (`bool`, *optional*, defaults to `False`) + FSDP's limit_all_gathers (useful only when `fsdp` field is passed). + If `"True"`, FSDP explicitly synchronizes the CPU thread to prevent too many in-flight + all-gathers. + - xla (`bool`, *optional*, defaults to `False`): + Whether to use PyTorch/XLA Fully Sharded Data Parallel Training. This is an experimental feature + and its API may evolve in the future. + - xla_fsdp_settings (`dict`, *optional*) + The value is a dictionary which stores the XLA FSDP wrapping parameters. + + For a complete list of options, please see [here]( + https://github.com/pytorch/xla/blob/master/torch_xla/distributed/fsdp/xla_fully_sharded_data_parallel.py). + - xla_fsdp_grad_ckpt (`bool`, *optional*, defaults to `False`): + Will use gradient checkpointing over each nested XLA FSDP wrapped layer. This setting can only be + used when the xla flag is set to true, and an auto wrapping policy is specified through + fsdp_min_num_params or fsdp_transformer_layer_cls_to_wrap. + + deepspeed (`str` or `dict`, *optional*): + Use [Deepspeed](https://github.com/microsoft/deepspeed). This is an experimental feature and its API may + evolve in the future. The value is either the location of DeepSpeed json config file (e.g., + `ds_config.json`) or an already loaded json file as a `dict`" + label_smoothing_factor (`float`, *optional*, defaults to 0.0): + The label smoothing factor to use. Zero means no label smoothing, otherwise the underlying onehot-encoded + labels are changed from 0s and 1s to `label_smoothing_factor/num_labels` and `1 - label_smoothing_factor + + label_smoothing_factor/num_labels` respectively. + debug (`str` or list of [`~debug_utils.DebugOption`], *optional*, defaults to `""`): + Enable one or more debug features. This is an experimental feature. + + Possible options are: + + - `"underflow_overflow"`: detects overflow in model's input/outputs and reports the last frames that led to + the event + - `"tpu_metrics_debug"`: print debug metrics on TPU + + The options should be separated by whitespaces. + optim (`str` or [`training_args.OptimizerNames`], *optional*, defaults to `"adamw_hf"`): + The optimizer to use: adamw_hf, adamw_torch, adamw_torch_fused, adamw_apex_fused, adamw_anyprecision or + adafactor. + optim_args (`str`, *optional*): + Optional arguments that are supplied to AnyPrecisionAdamW. + group_by_length (`bool`, *optional*, defaults to `False`): + Whether or not to group together samples of roughly the same length in the training dataset (to minimize + padding applied and be more efficient). Only useful if applying dynamic padding. + length_column_name (`str`, *optional*, defaults to `"length"`): + Column name for precomputed lengths. If the column exists, grouping by length will use these values rather + than computing them on train startup. Ignored unless `group_by_length` is `True` and the dataset is an + instance of `Dataset`. + report_to (`str` or `List[str]`, *optional*, defaults to `"all"`): + The list of integrations to report the results and logs to. Supported platforms are `"azure_ml"`, + `"comet_ml"`, `"mlflow"`, `"neptune"`, `"tensorboard"`,`"clearml"` and `"wandb"`. Use `"all"` to report to + all integrations installed, `"none"` for no integrations. + ddp_find_unused_parameters (`bool`, *optional*): + When using distributed training, the value of the flag `find_unused_parameters` passed to + `DistributedDataParallel`. Will default to `False` if gradient checkpointing is used, `True` otherwise. + ddp_bucket_cap_mb (`int`, *optional*): + When using distributed training, the value of the flag `bucket_cap_mb` passed to `DistributedDataParallel`. + dataloader_pin_memory (`bool`, *optional*, defaults to `True`): + Whether you want to pin memory in data loaders or not. Will default to `True`. + skip_memory_metrics (`bool`, *optional*, defaults to `True`): + Whether to skip adding of memory profiler reports to metrics. This is skipped by default because it slows + down the training and evaluation speed. + push_to_hub (`bool`, *optional*, defaults to `False`): + Whether or not to push the model to the Hub every time the model is saved. If this is activated, + `output_dir` will begin a git directory synced with the repo (determined by `hub_model_id`) and the content + will be pushed each time a save is triggered (depending on your `save_strategy`). Calling + [`~Trainer.save_model`] will also trigger a push. + + + + If `output_dir` exists, it needs to be a local clone of the repository to which the [`Trainer`] will be + pushed. + + + + resume_from_checkpoint (`str`, *optional*): + The path to a folder with a valid checkpoint for your model. This argument is not directly used by + [`Trainer`], it's intended to be used by your training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + hub_model_id (`str`, *optional*): + The name of the repository to keep in sync with the local *output_dir*. It can be a simple model ID in + which case the model will be pushed in your namespace. Otherwise it should be the whole repository name, + for instance `"user_name/model"`, which allows you to push to an organization you are a member of with + `"organization_name/model"`. Will default to `user_name/output_dir_name` with *output_dir_name* being the + name of `output_dir`. + + Will default to the name of `output_dir`. + hub_strategy (`str` or [`~trainer_utils.HubStrategy`], *optional*, defaults to `"every_save"`): + Defines the scope of what is pushed to the Hub and when. Possible values are: + + - `"end"`: push the model, its configuration, the tokenizer (if passed along to the [`Trainer`]) and a + draft of a model card when the [`~Trainer.save_model`] method is called. + - `"every_save"`: push the model, its configuration, the tokenizer (if passed along to the [`Trainer`]) and + a draft of a model card each time there is a model save. The pushes are asynchronous to not block + training, and in case the save are very frequent, a new push is only attempted if the previous one is + finished. A last push is made with the final model at the end of training. + - `"checkpoint"`: like `"every_save"` but the latest checkpoint is also pushed in a subfolder named + last-checkpoint, allowing you to resume training easily with + `trainer.train(resume_from_checkpoint="last-checkpoint")`. + - `"all_checkpoints"`: like `"checkpoint"` but all checkpoints are pushed like they appear in the output + folder (so you will get one checkpoint folder per folder in your final repository) + + hub_token (`str`, *optional*): + The token to use to push the model to the Hub. Will default to the token in the cache folder obtained with + `huggingface-cli login`. + hub_private_repo (`bool`, *optional*, defaults to `False`): + If True, the Hub repo will be set to private. + gradient_checkpointing (`bool`, *optional*, defaults to `False`): + If True, use gradient checkpointing to save memory at the expense of slower backward pass. + include_inputs_for_metrics (`bool`, *optional*, defaults to `False`): + Whether or not the inputs will be passed to the `compute_metrics` function. This is intended for metrics + that need inputs, predictions and references for scoring calculation in Metric class. + auto_find_batch_size (`bool`, *optional*, defaults to `False`) + Whether to find a batch size that will fit into memory automatically through exponential decay, avoiding + CUDA Out-of-Memory errors. Requires accelerate to be installed (`pip install accelerate`) + full_determinism (`bool`, *optional*, defaults to `False`) + If `True`, [`enable_full_determinism`] is called instead of [`set_seed`] to ensure reproducible results in + distributed training. Important: this will negatively impact the performance, so only use it for debugging. + torchdynamo (`str`, *optional*): + If set, the backend compiler for TorchDynamo. Possible choices are `"eager"`, `"aot_eager"`, `"inductor"`, + `"nvfuser"`, `"aot_nvfuser"`, `"aot_cudagraphs"`, `"ofi"`, `"fx2trt"`, `"onnxrt"` and `"ipex"`. + ray_scope (`str`, *optional*, defaults to `"last"`): + The scope to use when doing hyperparameter search with Ray. By default, `"last"` will be used. Ray will + then use the last checkpoint of all trials, compare those, and select the best one. However, other options + are also available. See the [Ray documentation]( + https://docs.ray.io/en/latest/tune/api_docs/analysis.html#ray.tune.ExperimentAnalysis.get_best_trial) for + more options. + ddp_timeout (`int`, *optional*, defaults to 1800): + The timeout for `torch.distributed.init_process_group` calls, used to avoid GPU socket timeouts when + performing slow operations in distributed runnings. Please refer the [PyTorch documentation] + (https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group) for more + information. + use_mps_device (`bool`, *optional*, defaults to `False`): + Whether to use Apple Silicon chip based `mps` device. + torch_compile (`bool`, *optional*, defaults to `False`): + Whether or not to compile the model using PyTorch 2.0 + [`torch.compile`](https://pytorch.org/get-started/pytorch-2.0/). + + This will use the best defaults for the [`torch.compile` + API](https://pytorch.org/docs/stable/generated/torch.compile.html?highlight=torch+compile#torch.compile). + You can customize the defaults with the argument `torch_compile_backend` and `torch_compile_mode` but we + don't guarantee any of them will work as the support is progressively rolled in in PyTorch. + + This flag and the whole compile API is experimental and subject to change in future releases. + torch_compile_backend (`str`, *optional*): + The backend to use in `torch.compile`. If set to any value, `torch_compile` will be set to `True`. + + Refer to the PyTorch doc for possible values and note that they may change across PyTorch versions. + + This flag is experimental and subject to change in future releases. + torch_compile_mode (`str`, *optional*): + The mode to use in `torch.compile`. If set to any value, `torch_compile` will be set to `True`. + + Refer to the PyTorch doc for possible values and note that they may change across PyTorch versions. + + This flag is experimental and subject to change in future releases. + """ + + framework = "pt" + output_dir: str = field( + metadata={"help": "The output directory where the model predictions and checkpoints will be written."}, + ) + overwrite_output_dir: bool = field( + default=False, + metadata={ + "help": ( + "Overwrite the content of the output directory. " + "Use this to continue training if output_dir points to a checkpoint directory." + ) + }, + ) + + do_train: bool = field(default=False, metadata={"help": "Whether to run training."}) + do_eval: bool = field(default=False, metadata={"help": "Whether to run eval on the dev set."}) + do_predict: bool = field(default=False, metadata={"help": "Whether to run predictions on the test set."}) + evaluation_strategy: Union[IntervalStrategy, str] = field( + default="no", + metadata={"help": "The evaluation strategy to use."}, + ) + prediction_loss_only: bool = field( + default=False, + metadata={"help": "When performing evaluation and predictions, only returns the loss."}, + ) + + per_device_train_batch_size: int = field( + default=8, metadata={"help": "Batch size per GPU/TPU core/CPU for training."} + ) + per_device_eval_batch_size: int = field( + default=8, metadata={"help": "Batch size per GPU/TPU core/CPU for evaluation."} + ) + + per_gpu_train_batch_size: Optional[int] = field( + default=None, + metadata={ + "help": ( + "Deprecated, the use of `--per_device_train_batch_size` is preferred. " + "Batch size per GPU/TPU core/CPU for training." + ) + }, + ) + per_gpu_eval_batch_size: Optional[int] = field( + default=None, + metadata={ + "help": ( + "Deprecated, the use of `--per_device_eval_batch_size` is preferred. " + "Batch size per GPU/TPU core/CPU for evaluation." + ) + }, + ) + + gradient_accumulation_steps: int = field( + default=1, + metadata={"help": "Number of updates steps to accumulate before performing a backward/update pass."}, + ) + eval_accumulation_steps: Optional[int] = field( + default=None, + metadata={"help": "Number of predictions steps to accumulate before moving the tensors to the CPU."}, + ) + + eval_delay: Optional[float] = field( + default=0, + metadata={ + "help": ( + "Number of epochs or steps to wait for before the first evaluation can be performed, depending on the" + " evaluation_strategy." + ) + }, + ) + + learning_rate: float = field(default=5e-5, metadata={"help": "The initial learning rate for AdamW."}) + weight_decay: float = field(default=0.0, metadata={"help": "Weight decay for AdamW if we apply some."}) + adam_beta1: float = field(default=0.9, metadata={"help": "Beta1 for AdamW optimizer"}) + adam_beta2: float = field(default=0.999, metadata={"help": "Beta2 for AdamW optimizer"}) + adam_epsilon: float = field(default=1e-8, metadata={"help": "Epsilon for AdamW optimizer."}) + max_grad_norm: float = field(default=1.0, metadata={"help": "Max gradient norm."}) + + num_train_epochs: float = field(default=3.0, metadata={"help": "Total number of training epochs to perform."}) + max_steps: int = field( + default=-1, + metadata={"help": "If > 0: set total number of training steps to perform. Override num_train_epochs."}, + ) + lr_scheduler_type: Union[SchedulerType, str] = field( + default="linear", + metadata={"help": "The scheduler type to use."}, + ) + warmup_ratio: float = field( + default=0.0, metadata={"help": "Linear warmup over warmup_ratio fraction of total steps."} + ) + warmup_steps: int = field(default=0, metadata={"help": "Linear warmup over warmup_steps."}) + + log_level: Optional[str] = field( + default="passive", + metadata={ + "help": ( + "Logger log level to use on the main node. Possible choices are the log levels as strings: 'debug'," + " 'info', 'warning', 'error' and 'critical', plus a 'passive' level which doesn't set anything and" + " lets the application set the level. Defaults to 'passive'." + ), + "choices": trainer_log_levels.keys(), + }, + ) + log_level_replica: Optional[str] = field( + default="warning", + metadata={ + "help": "Logger log level to use on replica nodes. Same choices and defaults as ``log_level``", + "choices": trainer_log_levels.keys(), + }, + ) + log_on_each_node: bool = field( + default=True, + metadata={ + "help": ( + "When doing a multinode distributed training, whether to log once per node or just once on the main" + " node." + ) + }, + ) + logging_dir: Optional[str] = field(default=None, metadata={"help": "Tensorboard log dir."}) + logging_strategy: Union[IntervalStrategy, str] = field( + default="steps", + metadata={"help": "The logging strategy to use."}, + ) + logging_first_step: bool = field(default=False, metadata={"help": "Log the first global_step"}) + logging_steps: float = field( + default=500, + metadata={ + "help": ( + "Log every X updates steps. Should be an integer or a float in range `[0,1)`." + "If smaller than 1, will be interpreted as ratio of total training steps." + ) + }, + ) + logging_nan_inf_filter: bool = field(default=True, metadata={"help": "Filter nan and inf losses for logging."}) + save_strategy: Union[IntervalStrategy, str] = field( + default="steps", + metadata={"help": "The checkpoint save strategy to use."}, + ) + save_steps: float = field( + default=500, + metadata={ + "help": ( + "Save checkpoint every X updates steps. Should be an integer or a float in range `[0,1)`." + "If smaller than 1, will be interpreted as ratio of total training steps." + ) + }, + ) + save_total_limit: Optional[int] = field( + default=None, + metadata={ + "help": ( + "Limit the total amount of checkpoints. " + "Deletes the older checkpoints in the output_dir. Default is unlimited checkpoints" + ) + }, + ) + save_safetensors: Optional[bool] = field( + default=False, + metadata={ + "help": "Use safetensors saving and loading for state dicts instead of default torch.load and torch.save." + }, + ) + save_on_each_node: bool = field( + default=False, + metadata={ + "help": ( + "When doing multi-node distributed training, whether to save models and checkpoints on each node, or" + " only on the main one" + ) + }, + ) + no_cuda: bool = field(default=False, metadata={"help": "Do not use CUDA even when it is available"}) + use_mps_device: bool = field( + default=False, metadata={"help": "Whether to use Apple Silicon chip based `mps` device."} + ) + seed: int = field(default=42, metadata={"help": "Random seed that will be set at the beginning of training."}) + data_seed: Optional[int] = field(default=None, metadata={"help": "Random seed to be used with data samplers."}) + jit_mode_eval: bool = field( + default=False, metadata={"help": "Whether or not to use PyTorch jit trace for inference"} + ) + use_ipex: bool = field( + default=False, + metadata={ + "help": ( + "Use Intel extension for PyTorch when it is available, installation:" + " 'https://github.com/intel/intel-extension-for-pytorch'" + ) + }, + ) + bf16: bool = field( + default=False, + metadata={ + "help": ( + "Whether to use bf16 (mixed) precision instead of 32-bit. Requires Ampere or higher NVIDIA" + " architecture or using CPU (no_cuda). This is an experimental API and it may change." + ) + }, + ) + fp16: bool = field( + default=False, + metadata={"help": "Whether to use fp16 (mixed) precision instead of 32-bit"}, + ) + fp16_opt_level: str = field( + default="O1", + metadata={ + "help": ( + "For fp16: Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']. " + "See details at https://nvidia.github.io/apex/amp.html" + ) + }, + ) + half_precision_backend: str = field( + default="auto", + metadata={ + "help": "The backend to be used for half precision.", + "choices": ["auto", "cuda_amp", "apex", "cpu_amp"], + }, + ) + bf16_full_eval: bool = field( + default=False, + metadata={ + "help": ( + "Whether to use full bfloat16 evaluation instead of 32-bit. This is an experimental API and it may" + " change." + ) + }, + ) + fp16_full_eval: bool = field( + default=False, + metadata={"help": "Whether to use full float16 evaluation instead of 32-bit"}, + ) + tf32: Optional[bool] = field( + default=None, + metadata={ + "help": ( + "Whether to enable tf32 mode, available in Ampere and newer GPU architectures. This is an experimental" + " API and it may change." + ) + }, + ) + local_rank: int = field(default=-1, metadata={"help": "For distributed training: local_rank"}) + ddp_backend: Optional[str] = field( + default=None, + metadata={ + "help": "The backend to be used for distributed training", + "choices": ["nccl", "gloo", "mpi", "ccl"], + }, + ) + tpu_num_cores: Optional[int] = field( + default=None, metadata={"help": "TPU: Number of TPU cores (automatically passed by launcher script)"} + ) + tpu_metrics_debug: bool = field( + default=False, + metadata={ + "help": ( + "Deprecated, the use of `--debug tpu_metrics_debug` is preferred. TPU: Whether to print debug metrics" + ) + }, + ) + debug: str = field( + default="", + metadata={ + "help": ( + "Whether or not to enable debug mode. Current options: " + "`underflow_overflow` (Detect underflow and overflow in activations and weights), " + "`tpu_metrics_debug` (print debug metrics on TPU)." + ) + }, + ) + + dataloader_drop_last: bool = field( + default=False, metadata={"help": "Drop the last incomplete batch if it is not divisible by the batch size."} + ) + eval_steps: Optional[float] = field( + default=None, + metadata={ + "help": ( + "Run an evaluation every X steps. Should be an integer or a float in range `[0,1)`." + "If smaller than 1, will be interpreted as ratio of total training steps." + ) + }, + ) + dataloader_num_workers: int = field( + default=0, + metadata={ + "help": ( + "Number of subprocesses to use for data loading (PyTorch only). 0 means that the data will be loaded" + " in the main process." + ) + }, + ) + + past_index: int = field( + default=-1, + metadata={"help": "If >=0, uses the corresponding part of the output as the past state for next step."}, + ) + + run_name: Optional[str] = field( + default=None, metadata={"help": "An optional descriptor for the run. Notably used for wandb logging."} + ) + disable_tqdm: Optional[bool] = field( + default=None, metadata={"help": "Whether or not to disable the tqdm progress bars."} + ) + + remove_unused_columns: Optional[bool] = field( + default=True, metadata={"help": "Remove columns not required by the model when using an nlp.Dataset."} + ) + label_names: Optional[List[str]] = field( + default=None, metadata={"help": "The list of keys in your dictionary of inputs that correspond to the labels."} + ) + + load_best_model_at_end: Optional[bool] = field( + default=False, + metadata={"help": "Whether or not to load the best model found during training at the end of training."}, + ) + metric_for_best_model: Optional[str] = field( + default=None, metadata={"help": "The metric to use to compare two different models."} + ) + greater_is_better: Optional[bool] = field( + default=None, metadata={"help": "Whether the `metric_for_best_model` should be maximized or not."} + ) + ignore_data_skip: bool = field( + default=False, + metadata={ + "help": ( + "When resuming training, whether or not to skip the first epochs and batches to get to the same" + " training data." + ) + }, + ) + sharded_ddp: str = field( + default="", + metadata={ + "help": ( + "Whether or not to use sharded DDP training (in distributed training only). The base option should be" + " `simple`, `zero_dp_2` or `zero_dp_3` and you can add CPU-offload to `zero_dp_2` or `zero_dp_3` like" + " this: zero_dp_2 offload` or `zero_dp_3 offload`. You can add auto-wrap to `zero_dp_2` or `zero_dp_3`" + " with the same syntax: zero_dp_2 auto_wrap` or `zero_dp_3 auto_wrap`." + ), + }, + ) + fsdp: str = field( + default="", + metadata={ + "help": ( + "Whether or not to use PyTorch Fully Sharded Data Parallel (FSDP) training (in distributed training" + " only). The base option should be `full_shard`, `shard_grad_op` or `no_shard` and you can add" + " CPU-offload to `full_shard` or `shard_grad_op` like this: full_shard offload` or `shard_grad_op" + " offload`. You can add auto-wrap to `full_shard` or `shard_grad_op` with the same syntax: full_shard" + " auto_wrap` or `shard_grad_op auto_wrap`." + ), + }, + ) + fsdp_min_num_params: int = field( + default=0, + metadata={ + "help": ( + "This parameter is deprecated. FSDP's minimum number of parameters for Default Auto Wrapping. (useful" + " only when `fsdp` field is passed)." + ) + }, + ) + fsdp_config: Optional[str] = field( + default=None, + metadata={ + "help": ( + "Config to be used with FSDP (Pytorch Fully Sharded Data Parallel). The value is either a" + "fsdp json config file (e.g., `fsdp_config.json`) or an already loaded json file as `dict`." + ) + }, + ) + fsdp_transformer_layer_cls_to_wrap: Optional[str] = field( + default=None, + metadata={ + "help": ( + "This parameter is deprecated. Transformer layer class name (case-sensitive) to wrap, e.g," + " `BertLayer`, `GPTJBlock`, `T5Block` .... (useful only when `fsdp` flag is passed)." + ) + }, + ) + deepspeed: Optional[str] = field( + default=None, + metadata={ + "help": ( + "Enable deepspeed and pass the path to deepspeed json config file (e.g. ds_config.json) or an already" + " loaded json file as a dict" + ) + }, + ) + label_smoothing_factor: float = field( + default=0.0, metadata={"help": "The label smoothing epsilon to apply (zero means no label smoothing)."} + ) + + default_optim = "adamw_hf" + # XXX: enable when pytorch==2.0.1 comes out - we want to give it time to get all the bugs sorted out + # if is_torch_available() and version.parse(version.parse(torch.__version__).base_version) >= version.parse("2.1.0"): + # default_optim = "adamw_torch_fused" + # and update the doc above to: + # optim (`str` or [`training_args.OptimizerNames`], *optional*, defaults to `"adamw_torch_fused"` (for torch<2.1.0 `"adamw_hf"`): + optim: Union[OptimizerNames, str] = field( + default=default_optim, + metadata={"help": "The optimizer to use."}, + ) + optim_args: Optional[str] = field(default=None, metadata={"help": "Optional arguments to supply to optimizer."}) + adafactor: bool = field(default=False, metadata={"help": "Whether or not to replace AdamW by Adafactor."}) + group_by_length: bool = field( + default=False, + metadata={"help": "Whether or not to group samples of roughly the same length together when batching."}, + ) + length_column_name: Optional[str] = field( + default="length", + metadata={"help": "Column name with precomputed lengths to use when grouping by length."}, + ) + report_to: Optional[List[str]] = field( + default=None, metadata={"help": "The list of integrations to report the results and logs to."} + ) + ddp_find_unused_parameters: Optional[bool] = field( + default=None, + metadata={ + "help": ( + "When using distributed training, the value of the flag `find_unused_parameters` passed to " + "`DistributedDataParallel`." + ) + }, + ) + ddp_bucket_cap_mb: Optional[int] = field( + default=None, + metadata={ + "help": ( + "When using distributed training, the value of the flag `bucket_cap_mb` passed to " + "`DistributedDataParallel`." + ) + }, + ) + dataloader_pin_memory: bool = field( + default=True, metadata={"help": "Whether or not to pin memory for DataLoader."} + ) + skip_memory_metrics: bool = field( + default=True, metadata={"help": "Whether or not to skip adding of memory profiler reports to metrics."} + ) + use_legacy_prediction_loop: bool = field( + default=False, metadata={"help": "Whether or not to use the legacy prediction_loop in the Trainer."} + ) + push_to_hub: bool = field( + default=False, metadata={"help": "Whether or not to upload the trained model to the model hub after training."} + ) + resume_from_checkpoint: Optional[str] = field( + default=None, + metadata={"help": "The path to a folder with a valid checkpoint for your model."}, + ) + hub_model_id: Optional[str] = field( + default=None, metadata={"help": "The name of the repository to keep in sync with the local `output_dir`."} + ) + hub_strategy: Union[HubStrategy, str] = field( + default="every_save", + metadata={"help": "The hub strategy to use when `--push_to_hub` is activated."}, + ) + hub_token: Optional[str] = field(default=None, metadata={"help": "The token to use to push to the Model Hub."}) + hub_private_repo: bool = field(default=False, metadata={"help": "Whether the model repository is private or not."}) + gradient_checkpointing: bool = field( + default=False, + metadata={ + "help": "If True, use gradient checkpointing to save memory at the expense of slower backward pass." + }, + ) + include_inputs_for_metrics: bool = field( + default=False, metadata={"help": "Whether or not the inputs will be passed to the `compute_metrics` function."} + ) + # Deprecated arguments + fp16_backend: str = field( + default="auto", + metadata={ + "help": "Deprecated. Use half_precision_backend instead", + "choices": ["auto", "cuda_amp", "apex", "cpu_amp"], + }, + ) + push_to_hub_model_id: Optional[str] = field( + default=None, metadata={"help": "The name of the repository to which push the `Trainer`."} + ) + push_to_hub_organization: Optional[str] = field( + default=None, metadata={"help": "The name of the organization in with to which push the `Trainer`."} + ) + push_to_hub_token: Optional[str] = field( + default=None, metadata={"help": "The token to use to push to the Model Hub."} + ) + _n_gpu: int = field(init=False, repr=False, default=-1) + mp_parameters: str = field( + default="", + metadata={"help": "Used by the SageMaker launcher to send mp-specific args. Ignored in Trainer"}, + ) + + auto_find_batch_size: bool = field( + default=False, + metadata={ + "help": ( + "Whether to automatically decrease the batch size in half and rerun the training loop again each time" + " a CUDA Out-of-Memory was reached" + ) + }, + ) + full_determinism: bool = field( + default=False, + metadata={ + "help": ( + "Whether to call enable_full_determinism instead of set_seed for reproducibility in distributed" + " training. Important: this will negatively impact the performance, so only use it for debugging." + ) + }, + ) + torchdynamo: Optional[str] = field( + default=None, + metadata={ + "help": "This argument is deprecated, use `--torch_compile_backend` instead.", + }, + ) + ray_scope: Optional[str] = field( + default="last", + metadata={ + "help": ( + 'The scope to use when doing hyperparameter search with Ray. By default, `"last"` will be used. Ray' + " will then use the last checkpoint of all trials, compare those, and select the best one. However," + " other options are also available. See the Ray documentation" + " (https://docs.ray.io/en/latest/tune/api_docs/analysis.html" + "#ray.tune.ExperimentAnalysis.get_best_trial)" + " for more options." + ) + }, + ) + ddp_timeout: Optional[int] = field( + default=1800, + metadata={ + "help": "Overrides the default timeout for distributed training (value should be given in seconds)." + }, + ) + torch_compile: bool = field( + default=False, metadata={"help": "If set to `True`, the model will be wrapped in `torch.compile`."} + ) + torch_compile_backend: Optional[str] = field( + default=None, + metadata={ + "help": "Which backend to use with `torch.compile`, passing one will trigger a model compilation.", + }, + ) + torch_compile_mode: Optional[str] = field( + default=None, + metadata={ + "help": "Which mode to use with `torch.compile`, passing one will trigger a model compilation.", + }, + ) + + xpu_backend: Optional[str] = field( + default=None, + metadata={ + "help": "The backend to be used for distributed training on Intel XPU.", + "choices": ["mpi", "ccl", "gloo"], + }, + ) + + def __post_init__(self): + # expand paths, if not os.makedirs("~/bar") will make directory + # in the current directory instead of the actual home + # see https://github.com/huggingface/transformers/issues/10628 + if self.output_dir is not None: + self.output_dir = os.path.expanduser(self.output_dir) + if self.logging_dir is None and self.output_dir is not None: + self.logging_dir = os.path.join(self.output_dir, default_logdir()) + if self.logging_dir is not None: + self.logging_dir = os.path.expanduser(self.logging_dir) + + if self.disable_tqdm is None: + self.disable_tqdm = logger.getEffectiveLevel() > logging.WARN + + if isinstance(self.evaluation_strategy, EvaluationStrategy): + warnings.warn( + "using `EvaluationStrategy` for `evaluation_strategy` is deprecated and will be removed in version 5" + " of 🤗 Transformers. Use `IntervalStrategy` instead", + FutureWarning, + ) + # Go back to the underlying string or we won't be able to instantiate `IntervalStrategy` on it. + self.evaluation_strategy = self.evaluation_strategy.value + + if self.xpu_backend is not None: + warnings.warn( + "using `xpu_backend` is deprecated and will be removed in version 4.31" + " of 🤗 Transformers. Use `ddp_backend` instead", + FutureWarning, + ) + self.ddp_backend = self.xpu_backend + + self.evaluation_strategy = IntervalStrategy(self.evaluation_strategy) + self.logging_strategy = IntervalStrategy(self.logging_strategy) + self.save_strategy = IntervalStrategy(self.save_strategy) + self.hub_strategy = HubStrategy(self.hub_strategy) + + self.lr_scheduler_type = SchedulerType(self.lr_scheduler_type) + if self.do_eval is False and self.evaluation_strategy != IntervalStrategy.NO: + self.do_eval = True + + # eval_steps has to be defined and non-zero, fallbacks to logging_steps if the latter is non-zero + if self.evaluation_strategy == IntervalStrategy.STEPS and (self.eval_steps is None or self.eval_steps == 0): + if self.logging_steps > 0: + logger.info(f"using `logging_steps` to initialize `eval_steps` to {self.logging_steps}") + self.eval_steps = self.logging_steps + else: + raise ValueError( + f"evaluation strategy {self.evaluation_strategy} requires either non-zero --eval_steps or" + " --logging_steps" + ) + + # logging_steps must be non-zero for logging_strategy that is other than 'no' + if self.logging_strategy == IntervalStrategy.STEPS and self.logging_steps == 0: + raise ValueError(f"logging strategy {self.logging_strategy} requires non-zero --logging_steps") + + if self.logging_strategy == IntervalStrategy.STEPS and self.logging_steps > 1: + if self.logging_steps != int(self.logging_steps): + raise ValueError(f"--logging_steps must be an integer if bigger than 1: {self.logging_steps}") + self.logging_steps = int(self.logging_steps) + if self.evaluation_strategy == IntervalStrategy.STEPS and self.eval_steps > 1: + if self.eval_steps != int(self.eval_steps): + raise ValueError(f"--eval_steps must be an integer if bigger than 1: {self.eval_steps}") + self.eval_steps = int(self.eval_steps) + if self.save_strategy == IntervalStrategy.STEPS and self.save_steps > 1: + if self.save_steps != int(self.save_steps): + raise ValueError(f"--save_steps must be an integer if bigger than 1: {self.save_steps}") + self.save_steps = int(self.save_steps) + + # Sanity checks for load_best_model_at_end: we require save and eval strategies to be compatible. + if self.load_best_model_at_end: + if self.evaluation_strategy != self.save_strategy: + raise ValueError( + "--load_best_model_at_end requires the save and eval strategy to match, but found\n- Evaluation " + f"strategy: {self.evaluation_strategy}\n- Save strategy: {self.save_strategy}" + ) + if self.evaluation_strategy == IntervalStrategy.STEPS and self.save_steps % self.eval_steps != 0: + if self.eval_steps < 1 or self.save_steps < 1: + if not (self.eval_steps < 1 and self.save_steps < 1): + raise ValueError( + "--load_best_model_at_end requires the saving steps to be a multiple of the evaluation " + "steps, which cannot get guaranteed when mixing ratio and absolute steps for save_steps" + f"{self.save_steps} and eval_steps {self.eval_steps}." + ) + # Work around floating point precision issues + LARGE_MULTIPLIER = 1_000_000 + if (self.save_steps * LARGE_MULTIPLIER) % (self.eval_steps * LARGE_MULTIPLIER) != 0: + raise ValueError( + "--load_best_model_at_end requires the saving steps to be a multiple of the evaluation " + f"steps, but found {self.save_steps}, which is not a multiple of {self.eval_steps}." + ) + raise ValueError( + "--load_best_model_at_end requires the saving steps to be a round multiple of the evaluation " + f"steps, but found {self.save_steps}, which is not a round multiple of {self.eval_steps}." + ) + + safetensors_available = is_safetensors_available() + if self.save_safetensors and not safetensors_available: + raise ValueError(f"--save_safetensors={self.save_safetensors} requires safetensors to be installed!") + if not self.save_safetensors and safetensors_available: + logger.info( + f"Found safetensors installation, but --save_safetensors={self.save_safetensors}. " + f"Safetensors should be a preferred weights saving format due to security and performance reasons. " + f"If your model cannot be saved by safetensors please feel free to open an issue at " + f"https://github.com/huggingface/safetensors!" + ) + + if ( + self.load_best_model_at_end or self.lr_scheduler_type == SchedulerType.REDUCE_ON_PLATEAU + ) and self.metric_for_best_model is None: + self.metric_for_best_model = "loss" + if self.greater_is_better is None and self.metric_for_best_model is not None: + self.greater_is_better = self.metric_for_best_model not in ["loss", "eval_loss"] + if self.run_name is None: + self.run_name = self.output_dir + if self.framework == "pt" and is_torch_available(): + if self.fp16_backend and self.fp16_backend != "auto": + warnings.warn( + "`fp16_backend` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" + " `half_precision_backend` instead", + FutureWarning, + ) + self.half_precision_backend = self.fp16_backend + + if self.bf16 or self.bf16_full_eval: + if self.no_cuda and not is_torch_bf16_cpu_available() and not is_torch_tpu_available(): + # cpu + raise ValueError("Your setup doesn't support bf16/(cpu, tpu, neuroncore). You need torch>=1.10") + elif not self.no_cuda and torch.cuda.is_available() and not is_torch_bf16_gpu_available(): + # gpu + raise ValueError( + "Your setup doesn't support bf16/gpu. You need torch>=1.10, using Ampere GPU with cuda>=11.0" + ) + + if self.fp16 and self.bf16: + raise ValueError("At most one of fp16 and bf16 can be True, but not both") + + if self.fp16_full_eval and self.bf16_full_eval: + raise ValueError("At most one of fp16 and bf16 can be True for full eval, but not both") + + if self.bf16: + if self.half_precision_backend == "apex": + raise ValueError( + " `--half_precision_backend apex`: GPU bf16 is not supported by apex. Use" + " `--half_precision_backend cuda_amp` instead" + ) + if not (self.sharded_ddp == "" or not self.sharded_ddp): + raise ValueError("sharded_ddp is not supported with bf16") + + if self.lr_scheduler_type == SchedulerType.REDUCE_ON_PLATEAU: + if self.evaluation_strategy == IntervalStrategy.NO: + raise ValueError("lr_scheduler_type reduce_lr_on_plateau requires an eval strategy") + if not is_torch_available(): + raise ValueError("lr_scheduler_type reduce_lr_on_plateau requires torch>=0.2.0") + + self.optim = OptimizerNames(self.optim) + if self.adafactor: + warnings.warn( + "`--adafactor` is deprecated and will be removed in version 5 of 🤗 Transformers. Use `--optim" + " adafactor` instead", + FutureWarning, + ) + self.optim = OptimizerNames.ADAFACTOR + if self.optim == OptimizerNames.ADAMW_TORCH_FUSED and is_torch_available(): + if version.parse(version.parse(torch.__version__).base_version) < version.parse("2.0.0"): + raise ValueError("--optim adamw_torch_fused requires PyTorch 2.0 or higher") + # there is a bug in fp16/AMP in pt-2.0.0 + if version.parse(version.parse(torch.__version__).base_version) == version.parse("2.0.0") and self.fp16: + raise ValueError("--optim adamw_torch_fused with --fp16 requires PyTorch>2.0") + + if ( + self.framework == "pt" + and is_torch_available() + and (self.device.type != "cuda") + and (get_xla_device_type(self.device) != "GPU") + and (self.fp16 or self.fp16_full_eval) + ): + raise ValueError( + "FP16 Mixed precision training with AMP or APEX (`--fp16`) and FP16 half precision evaluation" + " (`--fp16_full_eval`) can only be used on CUDA devices." + ) + + if ( + self.framework == "pt" + and is_torch_available() + and (self.device.type != "cuda") + and (get_xla_device_type(self.device) != "GPU") + and (get_xla_device_type(self.device) != "TPU") + and (self.device.type != "cpu") + and (self.bf16 or self.bf16_full_eval) + ): + raise ValueError( + "BF16 Mixed precision training with AMP (`--bf16`) and BF16 half precision evaluation" + " (`--bf16_full_eval`) can only be used on CUDA or CPU/TPU/NeuronCore devices." + ) + + if self.torchdynamo is not None: + warnings.warn( + "`torchdynamo` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" + " `torch_compile_backend` instead", + FutureWarning, + ) + self.torch_compile_backend = self.torchdynamo + if (self.torch_compile_mode is not None or self.torch_compile_backend is not None) and not self.torch_compile: + self.torch_compile = True + if self.torch_compile and self.torch_compile_backend is None: + self.torch_compile_backend = "inductor" + if self.framework == "pt" and is_torch_available() and self.torch_compile: + if is_torch_tf32_available(): + if self.tf32 is None and not self.fp16 or self.bf16: + logger.info( + "Setting TF32 in CUDA backends to speedup torch compile, you won't see any improvement" + " otherwise." + ) + torch.backends.cuda.matmul.allow_tf32 = True + else: + logger.warning( + "The speedups for torchdynamo mostly come wih GPU Ampere or higher and which is not detected here." + ) + if self.framework == "pt" and is_torch_available() and self.tf32 is not None: + if self.tf32: + if is_torch_tf32_available(): + torch.backends.cuda.matmul.allow_tf32 = True + else: + raise ValueError("--tf32 requires Ampere or a newer GPU arch, cuda>=11 and torch>=1.7") + else: + if is_torch_tf32_available(): + torch.backends.cuda.matmul.allow_tf32 = False + # no need to assert on else + + if self.report_to is None: + logger.info( + "The default value for the training argument `--report_to` will change in v5 (from all installed " + "integrations to none). In v5, you will need to use `--report_to all` to get the same behavior as " + "now. You should start updating your code and make this info disappear :-)." + ) + self.report_to = "all" + if self.report_to == "all" or self.report_to == ["all"]: + # Import at runtime to avoid a circular import. + from .integrations import get_available_reporting_integrations + + self.report_to = get_available_reporting_integrations() + elif self.report_to == "none" or self.report_to == ["none"]: + self.report_to = [] + elif not isinstance(self.report_to, list): + self.report_to = [self.report_to] + + if self.warmup_ratio < 0 or self.warmup_ratio > 1: + raise ValueError("warmup_ratio must lie in range [0,1]") + elif self.warmup_ratio > 0 and self.warmup_steps > 0: + logger.info( + "Both warmup_ratio and warmup_steps given, warmup_steps will override any effect of warmup_ratio" + " during training" + ) + + if isinstance(self.sharded_ddp, bool): + self.sharded_ddp = "simple" if self.sharded_ddp else "" + if isinstance(self.sharded_ddp, str): + self.sharded_ddp = [ShardedDDPOption(s) for s in self.sharded_ddp.split()] + if self.sharded_ddp == [ShardedDDPOption.OFFLOAD]: + raise ValueError( + "`--sharded_ddp offload` can't work on its own. It needs to be added to `--sharded_ddp zero_dp_2` or " + '`--sharded_ddp zero_dp_3`. For example, `--sharded_ddp "zero_dp_2 offload"`.' + ) + elif len(self.sharded_ddp) > 1 and ShardedDDPOption.SIMPLE in self.sharded_ddp: + raise ValueError("`--sharded_ddp simple` is not compatible with any other option.") + elif ShardedDDPOption.ZERO_DP_2 in self.sharded_ddp and ShardedDDPOption.ZERO_DP_3 in self.sharded_ddp: + raise ValueError("`--sharded_ddp zero_dp_2` is not compatible with `--sharded_ddp zero_dp_3`.") + + if isinstance(self.fsdp, bool): + self.fsdp = "full_shard" if self.fsdp else "" + if isinstance(self.fsdp, str): + self.fsdp = [FSDPOption(s) for s in self.fsdp.split()] + if self.fsdp == [FSDPOption.OFFLOAD]: + raise ValueError( + "`--fsdp offload` can't work on its own. It needs to be added to `--fsdp full_shard` or " + '`--fsdp shard_grad_op`. For example, `--fsdp "full_shard offload"`.' + ) + elif FSDPOption.FULL_SHARD in self.fsdp and FSDPOption.SHARD_GRAD_OP in self.fsdp: + raise ValueError("`--fsdp full_shard` is not compatible with `--fsdp shard_grad_op`.") + + if self.fsdp_config is None: + self.fsdp_config = {} + + if isinstance(self.fsdp_config, str): + with io.open(self.fsdp_config, "r", encoding="utf-8") as f: + self.fsdp_config = json.load(f) + + if self.fsdp_min_num_params > 0: + warnings.warn("using `--fsdp_min_num_params` is deprecated. Use fsdp_config instead ", FutureWarning) + + self.fsdp_config["fsdp_min_num_params"] = max( + self.fsdp_config.get("fsdp_min_num_params", 0), self.fsdp_min_num_params + ) + + # if fsdp_config["fsdp_transformer_layer_cls_to_wrap"] is specified as a string, convert it to a list with a single object + if isinstance(self.fsdp_config.get("fsdp_transformer_layer_cls_to_wrap", None), str): + self.fsdp_config["fsdp_transformer_layer_cls_to_wrap"] = [ + self.fsdp_config["fsdp_transformer_layer_cls_to_wrap"] + ] + + if self.fsdp_transformer_layer_cls_to_wrap is not None: + warnings.warn( + "using `--fsdp_transformer_layer_cls_to_wrap` is deprecated. Use fsdp_config instead ", FutureWarning + ) + self.fsdp_config["fsdp_transformer_layer_cls_to_wrap"] = self.fsdp_config.get( + "fsdp_transformer_layer_cls_to_wrap", [] + ) + [self.fsdp_transformer_layer_cls_to_wrap] + + if len(self.fsdp) == 0 and self.fsdp_config["fsdp_min_num_params"] > 0: + warnings.warn("`--fsdp_min_num_params` is useful only when `--fsdp` is specified.") + + if len(self.fsdp) == 0 and self.fsdp_config.get("fsdp_transformer_layer_cls_to_wrap", None) is not None: + warnings.warn("`--fsdp_transformer_layer_cls_to_wrap` is useful only when `--fsdp` is specified.") + + if ( + len(self.fsdp) > 0 + and self.fsdp_config["fsdp_min_num_params"] > 0 + and self.fsdp_config.get("fsdp_transformer_layer_cls_to_wrap", None) is not None + ): + raise ValueError( + "`--fsdp_min_num_params` and `--fsdp_transformer_layer_cls_to_wrap` are mutually exclusive." + ) + self.fsdp_config["xla"] = self.fsdp_config.get("xla", False) + self.fsdp_config["xla_fsdp_grad_ckpt"] = self.fsdp_config.get("xla_fsdp_grad_ckpt", False) + if self.fsdp_config["xla"]: + if len(self.fsdp) > 0: + # store XLA fsdp configuration parameters into a dictionary + self.xla_fsdp_config = self.fsdp_config.get("xla_fsdp_settings", {}) + # apply appropriate string to torch.dtype conversions for parameters + if "compute_dtype" in self.xla_fsdp_config: + self.xla_fsdp_config["compute_dtype"] = getattr(torch, self.xla_fsdp_config["compute_dtype"]) + if "buffer_dtype" in self.xla_fsdp_config: + self.xla_fsdp_config["buffer_dtype"] = getattr(torch, self.xla_fsdp_config["buffer_dtype"]) + else: + warnings.warn("XLA FSDP can be used only when `--fsdp` is specified.") + else: + if self.fsdp_config["xla_fsdp_grad_ckpt"]: + warnings.warn("`--xla_fsdp_grad_ckpt` is useful only when `--xla` is set to true.") + + if self.tpu_metrics_debug: + warnings.warn( + "using `--tpu_metrics_debug` is deprecated and will be removed in version 5 of 🤗 Transformers. Use" + " `--debug tpu_metrics_debug` instead", + FutureWarning, + ) + self.debug += " tpu_metrics_debug" + self.tpu_metrics_debug = False + if isinstance(self.debug, str): + self.debug = [DebugOption(s) for s in self.debug.split()] + + if self.deepspeed: + # - must be run very last in arg parsing, since it will use a lot of these settings. + # - must be run before the model is created. + if not is_accelerate_available(): + raise ValueError("--deepspeed requires Accelerate to be installed: `pip install accelerate`.") + from transformers.deepspeed import HfTrainerDeepSpeedConfig + + # will be used later by the Trainer + # note: leave self.deepspeed unmodified in case a user relies on it not to be modified) + self.hf_deepspeed_config = HfTrainerDeepSpeedConfig(self.deepspeed) + self.hf_deepspeed_config.trainer_config_process(self) + + if self.push_to_hub_token is not None: + warnings.warn( + "`--push_to_hub_token` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " + "`--hub_token` instead.", + FutureWarning, + ) + self.hub_token = self.push_to_hub_token + + if self.push_to_hub_model_id is not None: + self.hub_model_id = get_full_repo_name( + self.push_to_hub_model_id, organization=self.push_to_hub_organization, token=self.hub_token + ) + if self.push_to_hub_organization is not None: + warnings.warn( + "`--push_to_hub_model_id` and `--push_to_hub_organization` are deprecated and will be removed in " + "version 5 of 🤗 Transformers. Use `--hub_model_id` instead and pass the full repo name to this " + f"argument (in this case {self.hub_model_id}).", + FutureWarning, + ) + else: + warnings.warn( + "`--push_to_hub_model_id` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " + "`--hub_model_id` instead and pass the full repo name to this argument (in this case " + f"{self.hub_model_id}).", + FutureWarning, + ) + elif self.push_to_hub_organization is not None: + self.hub_model_id = f"{self.push_to_hub_organization}/{Path(self.output_dir).name}" + warnings.warn( + "`--push_to_hub_organization` is deprecated and will be removed in version 5 of 🤗 Transformers. Use " + "`--hub_model_id` instead and pass the full repo name to this argument (in this case " + f"{self.hub_model_id}).", + FutureWarning, + ) + + def __str__(self): + self_as_dict = asdict(self) + + # Remove deprecated arguments. That code should be removed once + # those deprecated arguments are removed from TrainingArguments. (TODO: v5) + del self_as_dict["per_gpu_train_batch_size"] + del self_as_dict["per_gpu_eval_batch_size"] + + self_as_dict = {k: f"<{k.upper()}>" if k.endswith("_token") else v for k, v in self_as_dict.items()} + + attrs_as_str = [f"{k}={v},\n" for k, v in sorted(self_as_dict.items())] + return f"{self.__class__.__name__}(\n{''.join(attrs_as_str)})" + + __repr__ = __str__ + + @property + def train_batch_size(self) -> int: + """ + The actual batch size for training (may differ from `per_gpu_train_batch_size` in distributed training). + """ + if self.per_gpu_train_batch_size: + logger.warning( + "Using deprecated `--per_gpu_train_batch_size` argument which will be removed in a future " + "version. Using `--per_device_train_batch_size` is preferred." + ) + per_device_batch_size = self.per_gpu_train_batch_size or self.per_device_train_batch_size + train_batch_size = per_device_batch_size * max(1, self.n_gpu) + return train_batch_size + + @property + def eval_batch_size(self) -> int: + """ + The actual batch size for evaluation (may differ from `per_gpu_eval_batch_size` in distributed training). + """ + if self.per_gpu_eval_batch_size: + logger.warning( + "Using deprecated `--per_gpu_eval_batch_size` argument which will be removed in a future " + "version. Using `--per_device_eval_batch_size` is preferred." + ) + per_device_batch_size = self.per_gpu_eval_batch_size or self.per_device_eval_batch_size + eval_batch_size = per_device_batch_size * max(1, self.n_gpu) + return eval_batch_size + + @property + def ddp_timeout_delta(self) -> timedelta: + """ + The actual timeout for torch.distributed.init_process_group since it expects a timedelta variable. + """ + return timedelta(seconds=self.ddp_timeout) + + @cached_property + def _setup_devices(self) -> "torch.device": + requires_backends(self, ["torch"]) + logger.info("PyTorch: setting up devices") + if not is_sagemaker_mp_enabled() and not is_accelerate_available(check_partial_state=True): + raise ImportError( + "Using the `Trainer` with `PyTorch` requires `accelerate`: Run `pip install --upgrade accelerate`" + ) + if self.no_cuda: + self.distributed_state = PartialState(cpu=True, backend=self.ddp_backend) + self._n_gpu = 0 + elif is_sagemaker_mp_enabled(): + local_rank = smp.local_rank() + device = torch.device("cuda", local_rank) + self._n_gpu = 1 + torch.cuda.set_device(device) + elif self.deepspeed: + # Need to do similar for Accelerator init + os.environ["ACCELERATE_USE_DEEPSPEED"] = "true" + self.distributed_state = PartialState(timeout=timedelta(seconds=self.ddp_timeout)) + del os.environ["ACCELERATE_USE_DEEPSPEED"] + self._n_gpu = 1 + else: + self.distributed_state = PartialState(backend=self.ddp_backend) + self._n_gpu = 1 + if not is_sagemaker_mp_enabled(): + device = self.distributed_state.device + self.local_rank = self.distributed_state.local_process_index + if ( + torch.distributed.is_available() + and torch.distributed.is_initialized() + and self.distributed_state.distributed_type == DistributedType.NO + ): + logger.warning( + "torch.distributed process group is initialized, but parallel_mode != ParallelMode.DISTRIBUTED. " + "In order to use Torch DDP, launch your script with `python -m torch.distributed.launch" + ) + if is_torch_tpu_available(): + device = self.distributed_state.device + self._n_gpu = 0 + elif is_sagemaker_dp_enabled(): + self._n_gpu = 1 + elif self.distributed_state.distributed_type == DistributedType.NO: + if self.use_mps_device: + if not torch.backends.mps.is_available(): + if not torch.backends.mps.is_built(): + raise AssertionError( + "MPS not available because the current PyTorch install was not " + "built with MPS enabled. Please install torch version >=1.12.0 on " + "your Apple silicon Mac running macOS 12.3 or later with a native " + "version (arm64) of Python" + ) + else: + raise AssertionError( + "MPS not available because the current MacOS version is not 12.3+ " + "and/or you do not have an MPS-enabled device on this machine." + ) + else: + if not version.parse(version.parse(torch.__version__).base_version) > version.parse("1.12.0"): + warnings.warn( + "We strongly recommend to install PyTorch >= 1.13 (nightly version at the time of writing)" + " on your MacOS machine. It has major fixes related to model correctness and performance" + " improvements for transformer based models. Please refer to" + " https://github.com/pytorch/pytorch/issues/82707 for more details." + ) + device = torch.device("mps") + self._n_gpu = 1 + + else: + # if n_gpu is > 1 we'll use nn.DataParallel. + # If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0` + # Explicitly set CUDA to the first (index 0) CUDA device, otherwise `set_device` will + # trigger an error that a device index is missing. Index 0 takes into account the + # GPUs available in the environment, so `CUDA_VISIBLE_DEVICES=1,2` with `cuda:0` + # will use the first GPU in that env, i.e. GPU#1 + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + # Sometimes the line in the postinit has not been run before we end up here, so just checking we're not at + # the default value. + self._n_gpu = torch.cuda.device_count() + if device.type == "cuda": + torch.cuda.set_device(device) + return device + + @property + def device(self) -> "torch.device": + """ + The device used by this process. + """ + requires_backends(self, ["torch"]) + return self._setup_devices + + @property + def n_gpu(self): + """ + The number of GPUs used by this process. + + Note: + This will only be greater than one when you have multiple GPUs available but are not using distributed + training. For distributed training, it will always be 1. + """ + requires_backends(self, ["torch"]) + # Make sure `self._n_gpu` is properly setup. + _ = self._setup_devices + return self._n_gpu + + @property + def parallel_mode(self): + """ + The current mode used for parallelism if multiple GPUs/TPU cores are available. One of: + + - `ParallelMode.NOT_PARALLEL`: no parallelism (CPU or one GPU). + - `ParallelMode.NOT_DISTRIBUTED`: several GPUs in one single process (uses `torch.nn.DataParallel`). + - `ParallelMode.DISTRIBUTED`: several GPUs, each having its own process (uses + `torch.nn.DistributedDataParallel`). + - `ParallelMode.TPU`: several TPU cores. + """ + requires_backends(self, ["torch"]) + if is_torch_tpu_available(): + return ParallelMode.TPU + elif is_sagemaker_mp_enabled(): + return ParallelMode.SAGEMAKER_MODEL_PARALLEL + elif is_sagemaker_dp_enabled(): + return ParallelMode.SAGEMAKER_DATA_PARALLEL + elif hasattr(self, "distributed_state") and self.distributed_state.distributed_type != DistributedType.NO: + return ParallelMode.DISTRIBUTED + elif self.n_gpu > 1: + return ParallelMode.NOT_DISTRIBUTED + else: + return ParallelMode.NOT_PARALLEL + + @property + def world_size(self): + """ + The number of processes used in parallel. + """ + requires_backends(self, ["torch"]) + + if is_torch_tpu_available(): + return xm.xrt_world_size() + elif is_sagemaker_mp_enabled(): + return smp.dp_size() if not smp.state.cfg.prescaled_batch else smp.rdp_size() + elif is_sagemaker_dp_enabled(): + return dist.get_world_size() + elif self.parallel_mode == ParallelMode.DISTRIBUTED: + return torch.distributed.get_world_size() + return 1 + + @property + def process_index(self): + """ + The index of the current process used. + """ + requires_backends(self, ["torch"]) + if is_torch_tpu_available(): + return xm.get_ordinal() + elif is_sagemaker_mp_enabled(): + return smp.dp_rank() if not smp.state.cfg.prescaled_batch else smp.rdp_rank() + elif is_sagemaker_dp_enabled(): + return dist.get_rank() + elif self.parallel_mode == ParallelMode.DISTRIBUTED: + return torch.distributed.get_rank() + return 0 + + @property + def local_process_index(self): + """ + The index of the local process used. + """ + requires_backends(self, ["torch"]) + if is_torch_tpu_available(): + return xm.get_local_ordinal() + elif is_sagemaker_mp_enabled(): + return smp.local_rank() + elif is_sagemaker_dp_enabled(): + return dist.get_rank() + elif self.parallel_mode == ParallelMode.DISTRIBUTED: + return self.local_rank + return 0 + + @property + def should_log(self): + """ + Whether or not the current process should produce log. + """ + if self.log_on_each_node: + return self.local_process_index == 0 + else: + if is_sagemaker_mp_enabled(): + return smp.rank() == 0 + else: + return self.process_index == 0 + + @property + def should_save(self): + """ + Whether or not the current process should write to disk, e.g., to save models and checkpoints. + """ + if self.save_on_each_node: + return self.local_process_index == 0 + else: + if is_sagemaker_mp_enabled(): + return smp.rank() == 0 + else: + return self.process_index == 0 + + def get_process_log_level(self): + """ + Returns the log level to be used depending on whether this process is the main process of node 0, main process + of node non-0, or a non-main process. + + For the main process the log level defaults to the logging level set (`logging.WARNING` if you didn't do + anything) unless overridden by `log_level` argument. + + For the replica processes the log level defaults to `logging.WARNING` unless overridden by `log_level_replica` + argument. + + The choice between the main and replica process settings is made according to the return value of `should_log`. + """ + + # convert to int + log_level = trainer_log_levels[self.log_level] + log_level_replica = trainer_log_levels[self.log_level_replica] + + log_level_main_node = logging.get_verbosity() if log_level == -1 else log_level + log_level_replica_node = logging.get_verbosity() if log_level_replica == -1 else log_level_replica + return log_level_main_node if self.should_log else log_level_replica_node + + @property + def place_model_on_device(self): + """ + Can be subclassed and overridden for some specific integrations. + """ + return not is_sagemaker_mp_enabled() + + @property + def _no_sync_in_gradient_accumulation(self): + """ + Whether or not to use no_sync for the gradients when doing gradient accumulation. + """ + return not ( + self.deepspeed or is_sagemaker_dp_enabled() or is_sagemaker_mp_enabled() or is_torch_neuroncore_available() + ) + + @contextlib.contextmanager + def main_process_first(self, local=True, desc="work"): + """ + A context manager for torch distributed environment where on needs to do something on the main process, while + blocking replicas, and when it's finished releasing the replicas. + + One such use is for `datasets`'s `map` feature which to be efficient should be run once on the main process, + which upon completion saves a cached version of results and which then automatically gets loaded by the + replicas. + + Args: + local (`bool`, *optional*, defaults to `True`): + if `True` first means process of rank 0 of each node if `False` first means process of rank 0 of node + rank 0 In multi-node environment with a shared filesystem you most likely will want to use + `local=False` so that only the main process of the first node will do the processing. If however, the + filesystem is not shared, then the main process of each node will need to do the processing, which is + the default behavior. + desc (`str`, *optional*, defaults to `"work"`): + a work description to be used in debug logs + + """ + if is_torch_available() and self.world_size > 1: + main_process_desc = "main process" + if local: + is_main_process = self.local_process_index == 0 + main_process_desc = "main local process" + elif is_sagemaker_mp_enabled(): + is_main_process = smp.rank() == 0 + else: + is_main_process = self.process_index == 0 + + try: + if not is_main_process: + # tell all replicas to wait + logger.debug(f"{self.process_index}: waiting for the {main_process_desc} to perform {desc}") + if is_torch_tpu_available(): + xm.rendezvous(desc) + elif is_sagemaker_dp_enabled(): + dist.barrier() + else: + torch.distributed.barrier() + yield + finally: + if is_main_process: + # the wait is over + logger.debug(f"{self.process_index}: {main_process_desc} completed {desc}, releasing all replicas") + if is_torch_tpu_available(): + xm.rendezvous(desc) + elif is_sagemaker_dp_enabled(): + dist.barrier() + else: + torch.distributed.barrier() + else: + yield + + def get_warmup_steps(self, num_training_steps: int): + """ + Get number of steps used for a linear warmup. + """ + warmup_steps = ( + self.warmup_steps if self.warmup_steps > 0 else math.ceil(num_training_steps * self.warmup_ratio) + ) + return warmup_steps + + def to_dict(self): + """ + Serializes this instance while replace `Enum` by their values (for JSON serialization support). It obfuscates + the token values by removing their value. + """ + # filter out fields that are defined as field(init=False) + d = {field.name: getattr(self, field.name) for field in fields(self) if field.init} + + for k, v in d.items(): + if isinstance(v, Enum): + d[k] = v.value + if isinstance(v, list) and len(v) > 0 and isinstance(v[0], Enum): + d[k] = [x.value for x in v] + if k.endswith("_token"): + d[k] = f"<{k.upper()}>" + return d + + def to_json_string(self): + """ + Serializes this instance to a JSON string. + """ + return json.dumps(self.to_dict(), indent=2) + + def to_sanitized_dict(self) -> Dict[str, Any]: + """ + Sanitized serialization to use with TensorBoard’s hparams + """ + d = self.to_dict() + d = {**d, **{"train_batch_size": self.train_batch_size, "eval_batch_size": self.eval_batch_size}} + + valid_types = [bool, int, float, str] + if is_torch_available(): + valid_types.append(torch.Tensor) + + return {k: v if type(v) in valid_types else str(v) for k, v in d.items()} + + # The following methods are there to simplify the instantiation of `TrainingArguments` + def set_training( + self, + learning_rate: float = 5e-5, + batch_size: int = 8, + weight_decay: float = 0, + num_epochs: float = 3, + max_steps: int = -1, + gradient_accumulation_steps: int = 1, + seed: int = 42, + gradient_checkpointing: bool = False, + ): + """ + A method that regroups all basic arguments linked to the training. + + + + Calling this method will automatically set `self.do_train` to `True`. + + + + Args: + learning_rate (`float`, *optional*, defaults to 5e-5): + The initial learning rate for the optimizer. + batch_size (`int` *optional*, defaults to 8): + The batch size per device (GPU/TPU core/CPU...) used for training. + weight_decay (`float`, *optional*, defaults to 0): + The weight decay to apply (if not zero) to all layers except all bias and LayerNorm weights in the + optimizer. + num_train_epochs(`float`, *optional*, defaults to 3.0): + Total number of training epochs to perform (if not an integer, will perform the decimal part percents + of the last epoch before stopping training). + max_steps (`int`, *optional*, defaults to -1): + If set to a positive number, the total number of training steps to perform. Overrides + `num_train_epochs`. In case of using a finite iterable dataset the training may stop before reaching + the set number of steps when all data is exhausted. + gradient_accumulation_steps (`int`, *optional*, defaults to 1): + Number of updates steps to accumulate the gradients for, before performing a backward/update pass. + + + + When using gradient accumulation, one step is counted as one step with backward pass. Therefore, + logging, evaluation, save will be conducted every `gradient_accumulation_steps * xxx_step` training + examples. + + + + seed (`int`, *optional*, defaults to 42): + Random seed that will be set at the beginning of training. To ensure reproducibility across runs, use + the [`~Trainer.model_init`] function to instantiate the model if it has some randomly initialized + parameters. + gradient_checkpointing (`bool`, *optional*, defaults to `False`): + If True, use gradient checkpointing to save memory at the expense of slower backward pass. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_training(learning_rate=1e-4, batch_size=32) + >>> args.learning_rate + 1e-4 + ``` + """ + self.do_train = True + self.learning_rate = learning_rate + self.per_device_train_batch_size = batch_size + self.weight_decay = weight_decay + self.num_train_epochs = num_epochs + self.max_steps = max_steps + self.gradient_accumulation_steps = gradient_accumulation_steps + self.seed = seed + self.gradient_checkpointing = gradient_checkpointing + return self + + def set_evaluate( + self, + strategy: Union[str, IntervalStrategy] = "no", + steps: int = 500, + batch_size: int = 8, + accumulation_steps: Optional[int] = None, + delay: Optional[float] = None, + loss_only: bool = False, + jit_mode: bool = False, + ): + """ + A method that regroups all arguments linked to the evaluation. + + Args: + strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"no"`): + The evaluation strategy to adopt during training. Possible values are: + + - `"no"`: No evaluation is done during training. + - `"steps"`: Evaluation is done (and logged) every `steps`. + - `"epoch"`: Evaluation is done at the end of each epoch. + + Setting a `strategy` different from `"no"` will set `self.do_eval` to `True`. + steps (`int`, *optional*, defaults to 500): + Number of update steps between two evaluations if `strategy="steps"`. + batch_size (`int` *optional*, defaults to 8): + The batch size per device (GPU/TPU core/CPU...) used for evaluation. + accumulation_steps (`int`, *optional*): + Number of predictions steps to accumulate the output tensors for, before moving the results to the CPU. + If left unset, the whole predictions are accumulated on GPU/TPU before being moved to the CPU (faster + but requires more memory). + delay (`float`, *optional*): + Number of epochs or steps to wait for before the first evaluation can be performed, depending on the + evaluation_strategy. + loss_only (`bool`, *optional*, defaults to `False`): + Ignores all outputs except the loss. + jit_mode (`bool`, *optional*): + Whether or not to use PyTorch jit trace for inference. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_evaluate(strategy="steps", steps=100) + >>> args.eval_steps + 100 + ``` + """ + self.evaluation_strategy = IntervalStrategy(strategy) + if self.evaluation_strategy == IntervalStrategy.STEPS and steps == 0: + raise ValueError("Setting `strategy` as 'steps' requires a positive value for `steps`.") + self.do_eval = self.evaluation_strategy != IntervalStrategy.NO + self.eval_steps = steps + self.per_device_eval_batch_size = batch_size + self.eval_accumulation_steps = accumulation_steps + self.eval_delay = delay + self.prediction_loss_only = loss_only + self.jit_mode_eval = jit_mode + return self + + def set_testing( + self, + batch_size: int = 8, + loss_only: bool = False, + jit_mode: bool = False, + ): + """ + A method that regroups all basic arguments linked to testing on a held-out dataset. + + + + Calling this method will automatically set `self.do_predict` to `True`. + + + + Args: + batch_size (`int` *optional*, defaults to 8): + The batch size per device (GPU/TPU core/CPU...) used for testing. + loss_only (`bool`, *optional*, defaults to `False`): + Ignores all outputs except the loss. + jit_mode (`bool`, *optional*): + Whether or not to use PyTorch jit trace for inference. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_testing(batch_size=32) + >>> args.per_device_eval_batch_size + 32 + ``` + """ + self.do_predict = True + self.per_device_eval_batch_size = batch_size + self.prediction_loss_only = loss_only + self.jit_mode_eval = jit_mode + return self + + def set_save( + self, + strategy: Union[str, IntervalStrategy] = "steps", + steps: int = 500, + total_limit: Optional[int] = None, + on_each_node: bool = False, + ): + """ + A method that regroups all arguments linked to the evaluation. + + Args: + strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The checkpoint save strategy to adopt during training. Possible values are: + + - `"no"`: No save is done during training. + - `"epoch"`: Save is done at the end of each epoch. + - `"steps"`: Save is done every `save_steps`. + + steps (`int`, *optional*, defaults to 500): + Number of updates steps before two checkpoint saves if `strategy="steps"`. + total_limit (`int`, *optional*): + If a value is passed, will limit the total amount of checkpoints. Deletes the older checkpoints in + `output_dir`. + on_each_node (`bool`, *optional*, defaults to `False`): + When doing multi-node distributed training, whether to save models and checkpoints on each node, or + only on the main one. + + This should not be activated when the different nodes use the same storage as the files will be saved + with the same names for each node. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_save(strategy="steps", steps=100) + >>> args.save_steps + 100 + ``` + """ + self.save_strategy = IntervalStrategy(strategy) + if self.save_strategy == IntervalStrategy.STEPS and steps == 0: + raise ValueError("Setting `strategy` as 'steps' requires a positive value for `steps`.") + self.save_steps = steps + self.save_total_limit = total_limit + self.save_on_each_node = on_each_node + return self + + def set_logging( + self, + strategy: Union[str, IntervalStrategy] = "steps", + steps: int = 500, + report_to: Union[str, List[str]] = "none", + level: str = "passive", + first_step: bool = False, + nan_inf_filter: bool = False, + on_each_node: bool = False, + replica_level: str = "passive", + ): + """ + A method that regroups all arguments linked to the evaluation. + + Args: + strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The logging strategy to adopt during training. Possible values are: + + - `"no"`: No save is done during training. + - `"epoch"`: Save is done at the end of each epoch. + - `"steps"`: Save is done every `save_steps`. + + steps (`int`, *optional*, defaults to 500): + Number of update steps between two logs if `strategy="steps"`. + level (`str`, *optional*, defaults to `"passive"`): + Logger log level to use on the main process. Possible choices are the log levels as strings: `"debug"`, + `"info"`, `"warning"`, `"error"` and `"critical"`, plus a `"passive"` level which doesn't set anything + and lets the application set the level. + report_to (`str` or `List[str]`, *optional*, defaults to `"none"`): + The list of integrations to report the results and logs to. Supported platforms are `"azure_ml"`, + `"comet_ml"`, `"mlflow"`, `"neptune"`, `"tensorboard"`,`"clearml"` and `"wandb"`. Use `"all"` to report + to all integrations installed, `"none"` for no integrations. + first_step (`bool`, *optional*, defaults to `False`): + Whether to log and evaluate the first `global_step` or not. + nan_inf_filter (`bool`, *optional*, defaults to `True`): + Whether to filter `nan` and `inf` losses for logging. If set to `True` the loss of every step that is + `nan` or `inf` is filtered and the average loss of the current logging window is taken instead. + + + + `nan_inf_filter` only influences the logging of loss values, it does not change the behavior the + gradient is computed or applied to the model. + + + + on_each_node (`bool`, *optional*, defaults to `True`): + In multinode distributed training, whether to log using `log_level` once per node, or only on the main + node. + replica_level (`str`, *optional*, defaults to `"passive"`): + Logger log level to use on replicas. Same choices as `log_level` + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_logging(strategy="steps", steps=100) + >>> args.logging_steps + 100 + ``` + """ + self.logging_strategy = IntervalStrategy(strategy) + if self.logging_strategy == IntervalStrategy.STEPS and steps == 0: + raise ValueError("Setting `strategy` as 'steps' requires a positive value for `steps`.") + self.logging_steps = steps + self.report_to = report_to + self.log_level = level + self.logging_first_step = first_step + self.logging_nan_inf_filter = nan_inf_filter + self.log_on_each_node = on_each_node + self.log_level_replica = replica_level + return self + + def set_push_to_hub( + self, + model_id: str, + strategy: Union[str, HubStrategy] = "every_save", + token: Optional[str] = None, + private_repo: bool = False, + ): + """ + A method that regroups all arguments linked to synchronizing checkpoints with the Hub. + + + + Calling this method will set `self.push_to_hub` to `True`, which means the `output_dir` will begin a git + directory synced with the repo (determined by `model_id`) and the content will be pushed each time a save is + triggered (depending on`self.save_strategy`). Calling [`~Trainer.save_model`] will also trigger a push. + + + + Args: + model_id (`str`): + The name of the repository to keep in sync with the local *output_dir*. It can be a simple model ID in + which case the model will be pushed in your namespace. Otherwise it should be the whole repository + name, for instance `"user_name/model"`, which allows you to push to an organization you are a member of + with `"organization_name/model"`. + strategy (`str` or [`~trainer_utils.HubStrategy`], *optional*, defaults to `"every_save"`): + Defines the scope of what is pushed to the Hub and when. Possible values are: + + - `"end"`: push the model, its configuration, the tokenizer (if passed along to the [`Trainer`]) and a + draft of a model card when the [`~Trainer.save_model`] method is called. + - `"every_save"`: push the model, its configuration, the tokenizer (if passed along to the [`Trainer`]) + and + a draft of a model card each time there is a model save. The pushes are asynchronous to not block + training, and in case the save are very frequent, a new push is only attempted if the previous one is + finished. A last push is made with the final model at the end of training. + - `"checkpoint"`: like `"every_save"` but the latest checkpoint is also pushed in a subfolder named + last-checkpoint, allowing you to resume training easily with + `trainer.train(resume_from_checkpoint="last-checkpoint")`. + - `"all_checkpoints"`: like `"checkpoint"` but all checkpoints are pushed like they appear in the + output + folder (so you will get one checkpoint folder per folder in your final repository) + + token (`str`, *optional*): + The token to use to push the model to the Hub. Will default to the token in the cache folder obtained + with `huggingface-cli login`. + private_repo (`bool`, *optional*, defaults to `False`): + If True, the Hub repo will be set to private. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_push_to_hub("me/awesome-model") + >>> args.hub_model_id + 'me/awesome-model' + ``` + """ + self.push_to_hub = True + self.hub_model_id = model_id + self.hub_strategy = HubStrategy(strategy) + self.hub_token = token + self.hub_private_repo = private_repo + return self + + def set_optimizer( + self, + name: Union[str, OptimizerNames] = "adamw_hf", + learning_rate: float = 5e-5, + weight_decay: float = 0, + beta1: float = 0.9, + beta2: float = 0.999, + epsilon: float = 1e-8, + args: Optional[str] = None, + ): + """ + A method that regroups all arguments linked to the optimizer and its hyperparameters. + + Args: + name (`str` or [`training_args.OptimizerNames`], *optional*, defaults to `"adamw_hf"`): + The optimizer to use: `"adamw_hf"`, `"adamw_torch"`, `"adamw_torch_fused"`, `"adamw_apex_fused"`, + `"adamw_anyprecision"` or `"adafactor"`. + learning_rate (`float`, *optional*, defaults to 5e-5): + The initial learning rate. + weight_decay (`float`, *optional*, defaults to 0): + The weight decay to apply (if not zero) to all layers except all bias and LayerNorm weights. + beta1 (`float`, *optional*, defaults to 0.9): + The beta1 hyperparameter for the adam optimizer or its variants. + beta2 (`float`, *optional*, defaults to 0.999): + The beta2 hyperparameter for the adam optimizer or its variants. + epsilon (`float`, *optional*, defaults to 1e-8): + The epsilon hyperparameter for the adam optimizer or its variants. + args (`str`, *optional*): + Optional arguments that are supplied to AnyPrecisionAdamW (only useful when + `optim="adamw_anyprecision"`). + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_optimizer(name="adamw_torch", beta1=0.8) + >>> args.optim + 'adamw_torch' + ``` + """ + self.optim = OptimizerNames(name) + self.learning_rate = learning_rate + self.weight_decay = weight_decay + self.adam_beta1 = beta1 + self.adam_beta2 = beta2 + self.adam_epsilon = epsilon + self.optim_args = args + return self + + def set_lr_scheduler( + self, + name: Union[str, SchedulerType] = "linear", + num_epochs: float = 3.0, + max_steps: int = -1, + warmup_ratio: float = 0, + warmup_steps: int = 0, + ): + """ + A method that regroups all arguments linked to the learning rate scheduler and its hyperparameters. + + Args: + name (`str` or [`SchedulerType`], *optional*, defaults to `"linear"`): + The scheduler type to use. See the documentation of [`SchedulerType`] for all possible values. + num_epochs(`float`, *optional*, defaults to 3.0): + Total number of training epochs to perform (if not an integer, will perform the decimal part percents + of the last epoch before stopping training). + max_steps (`int`, *optional*, defaults to -1): + If set to a positive number, the total number of training steps to perform. Overrides + `num_train_epochs`. In case of using a finite iterable dataset the training may stop before reaching + the set number of steps when all data is exhausted. + warmup_ratio (`float`, *optional*, defaults to 0.0): + Ratio of total training steps used for a linear warmup from 0 to `learning_rate`. + warmup_steps (`int`, *optional*, defaults to 0): + Number of steps used for a linear warmup from 0 to `learning_rate`. Overrides any effect of + `warmup_ratio`. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_lr_scheduler(name="cosine", warmup_ratio=0.05) + >>> args.warmup_ratio + 0.05 + ``` + """ + self.lr_scheduler_type = SchedulerType(name) + self.num_train_epochs = num_epochs + self.max_steps = max_steps + self.warmup_ratio = warmup_ratio + self.warmup_steps = warmup_steps + return self + + def set_dataloader( + self, + train_batch_size: int = 8, + eval_batch_size: int = 8, + drop_last: bool = False, + num_workers: int = 0, + pin_memory: bool = True, + auto_find_batch_size: bool = False, + ignore_data_skip: bool = False, + sampler_seed: Optional[int] = None, + ): + """ + A method that regroups all arguments linked to the dataloaders creation. + + Args: + drop_last (`bool`, *optional*, defaults to `False`): + Whether to drop the last incomplete batch (if the length of the dataset is not divisible by the batch + size) or not. + num_workers (`int`, *optional*, defaults to 0): + Number of subprocesses to use for data loading (PyTorch only). 0 means that the data will be loaded in + the main process. + pin_memory (`bool`, *optional*, defaults to `True`): + Whether you want to pin memory in data loaders or not. Will default to `True`. + auto_find_batch_size (`bool`, *optional*, defaults to `False`) + Whether to find a batch size that will fit into memory automatically through exponential decay, + avoiding CUDA Out-of-Memory errors. Requires accelerate to be installed (`pip install accelerate`) + ignore_data_skip (`bool`, *optional*, defaults to `False`): + When resuming training, whether or not to skip the epochs and batches to get the data loading at the + same stage as in the previous training. If set to `True`, the training will begin faster (as that + skipping step can take a long time) but will not yield the same results as the interrupted training + would have. + sampler_seed (`int`, *optional*): + Random seed to be used with data samplers. If not set, random generators for data sampling will use the + same seed as `self.seed`. This can be used to ensure reproducibility of data sampling, independent of + the model seed. + + Example: + + ```py + >>> from transformers import TrainingArguments + + >>> args = TrainingArguments("working_dir") + >>> args = args.set_dataloader(train_batch_size=16, eval_batch_size=64) + >>> args.per_device_train_batch_size + 16 + ``` + """ + self.per_device_train_batch_size = train_batch_size + self.per_device_eval_batch_size = eval_batch_size + self.dataloader_drop_last = drop_last + self.dataloader_num_workers = num_workers + self.dataloader_pin_memory = pin_memory + self.auto_find_batch_size = auto_find_batch_size + self.ignore_data_skip = ignore_data_skip + self.data_seed = sampler_seed + return self + + +class ParallelMode(Enum): + NOT_PARALLEL = "not_parallel" + NOT_DISTRIBUTED = "not_distributed" + DISTRIBUTED = "distributed" + SAGEMAKER_MODEL_PARALLEL = "sagemaker_model_parallel" + SAGEMAKER_DATA_PARALLEL = "sagemaker_data_parallel" + TPU = "tpu" diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_seq2seq.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_seq2seq.py new file mode 100644 index 0000000000000000000000000000000000000000..ccacbbb370270811c0cfd77d6862716febbe69e1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_seq2seq.py @@ -0,0 +1,97 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +from dataclasses import dataclass, field +from pathlib import Path +from typing import Optional, Union + +from .generation.configuration_utils import GenerationConfig +from .training_args import TrainingArguments +from .utils import add_start_docstrings + + +logger = logging.getLogger(__name__) + + +@dataclass +@add_start_docstrings(TrainingArguments.__doc__) +class Seq2SeqTrainingArguments(TrainingArguments): + """ + Args: + sortish_sampler (`bool`, *optional*, defaults to `False`): + Whether to use a *sortish sampler* or not. Only possible if the underlying datasets are *Seq2SeqDataset* + for now but will become generally available in the near future. + + It sorts the inputs according to lengths in order to minimize the padding size, with a bit of randomness + for the training set. + predict_with_generate (`bool`, *optional*, defaults to `False`): + Whether to use generate to calculate generative metrics (ROUGE, BLEU). + generation_max_length (`int`, *optional*): + The `max_length` to use on each evaluation loop when `predict_with_generate=True`. Will default to the + `max_length` value of the model configuration. + generation_num_beams (`int`, *optional*): + The `num_beams` to use on each evaluation loop when `predict_with_generate=True`. Will default to the + `num_beams` value of the model configuration. + generation_config (`str` or `Path` or [`~generation.GenerationConfig`], *optional*): + Allows to load a [`~generation.GenerationConfig`] from the `from_pretrained` method. This can be either: + + - a string, the *model id* of a pretrained model configuration hosted inside a model repo on + huggingface.co. Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced + under a user or organization name, like `dbmdz/bert-base-german-cased`. + - a path to a *directory* containing a configuration file saved using the + [`~GenerationConfig.save_pretrained`] method, e.g., `./my_model_directory/`. + - a [`~generation.GenerationConfig`] object. + """ + + sortish_sampler: bool = field(default=False, metadata={"help": "Whether to use SortishSampler or not."}) + predict_with_generate: bool = field( + default=False, metadata={"help": "Whether to use generate to calculate generative metrics (ROUGE, BLEU)."} + ) + generation_max_length: Optional[int] = field( + default=None, + metadata={ + "help": ( + "The `max_length` to use on each evaluation loop when `predict_with_generate=True`. Will default " + "to the `max_length` value of the model configuration." + ) + }, + ) + generation_num_beams: Optional[int] = field( + default=None, + metadata={ + "help": ( + "The `num_beams` to use on each evaluation loop when `predict_with_generate=True`. Will default " + "to the `num_beams` value of the model configuration." + ) + }, + ) + generation_config: Optional[Union[str, Path, GenerationConfig]] = field( + default=None, + metadata={ + "help": "Model id, file path or url pointing to a GenerationConfig json file, to use during prediction." + }, + ) + + def to_dict(self): + """ + Serializes this instance while replace `Enum` by their values and `GenerationConfig` by dictionaries (for JSON + serialization support). It obfuscates the token values by removing their value. + """ + # filter out fields that are defined as field(init=False) + d = super().to_dict() + for k, v in d.items(): + if isinstance(v, GenerationConfig): + d[k] = v.to_dict() + return d diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_tf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_tf.py new file mode 100644 index 0000000000000000000000000000000000000000..847bbdb78a15b27c25003aade3339ad91730fa6f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/training_args_tf.py @@ -0,0 +1,295 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import warnings +from dataclasses import dataclass, field +from typing import Optional, Tuple + +from .training_args import TrainingArguments +from .utils import cached_property, is_tf_available, logging, requires_backends + + +logger = logging.get_logger(__name__) + +if is_tf_available(): + import tensorflow as tf + + +@dataclass +class TFTrainingArguments(TrainingArguments): + """ + TrainingArguments is the subset of the arguments we use in our example scripts **which relate to the training loop + itself**. + + Using [`HfArgumentParser`] we can turn this class into + [argparse](https://docs.python.org/3/library/argparse#module-argparse) arguments that can be specified on the + command line. + + Parameters: + output_dir (`str`): + The output directory where the model predictions and checkpoints will be written. + overwrite_output_dir (`bool`, *optional*, defaults to `False`): + If `True`, overwrite the content of the output directory. Use this to continue training if `output_dir` + points to a checkpoint directory. + do_train (`bool`, *optional*, defaults to `False`): + Whether to run training or not. This argument is not directly used by [`Trainer`], it's intended to be used + by your training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + do_eval (`bool`, *optional*): + Whether to run evaluation on the validation set or not. Will be set to `True` if `evaluation_strategy` is + different from `"no"`. This argument is not directly used by [`Trainer`], it's intended to be used by your + training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + do_predict (`bool`, *optional*, defaults to `False`): + Whether to run predictions on the test set or not. This argument is not directly used by [`Trainer`], it's + intended to be used by your training/evaluation scripts instead. See the [example + scripts](https://github.com/huggingface/transformers/tree/main/examples) for more details. + evaluation_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"no"`): + The evaluation strategy to adopt during training. Possible values are: + + - `"no"`: No evaluation is done during training. + - `"steps"`: Evaluation is done (and logged) every `eval_steps`. + - `"epoch"`: Evaluation is done at the end of each epoch. + + per_device_train_batch_size (`int`, *optional*, defaults to 8): + The batch size per GPU/TPU core/CPU for training. + per_device_eval_batch_size (`int`, *optional*, defaults to 8): + The batch size per GPU/TPU core/CPU for evaluation. + gradient_accumulation_steps: (`int`, *optional*, defaults to 1): + Number of updates steps to accumulate the gradients for, before performing a backward/update pass. + + + + When using gradient accumulation, one step is counted as one step with backward pass. Therefore, logging, + evaluation, save will be conducted every `gradient_accumulation_steps * xxx_step` training examples. + + + + learning_rate (`float`, *optional*, defaults to 5e-5): + The initial learning rate for Adam. + weight_decay (`float`, *optional*, defaults to 0): + The weight decay to apply (if not zero). + adam_beta1 (`float`, *optional*, defaults to 0.9): + The beta1 hyperparameter for the Adam optimizer. + adam_beta2 (`float`, *optional*, defaults to 0.999): + The beta2 hyperparameter for the Adam optimizer. + adam_epsilon (`float`, *optional*, defaults to 1e-8): + The epsilon hyperparameter for the Adam optimizer. + max_grad_norm (`float`, *optional*, defaults to 1.0): + Maximum gradient norm (for gradient clipping). + num_train_epochs(`float`, *optional*, defaults to 3.0): + Total number of training epochs to perform. + max_steps (`int`, *optional*, defaults to -1): + If set to a positive number, the total number of training steps to perform. Overrides `num_train_epochs`. + warmup_ratio (`float`, *optional*, defaults to 0.0): + Ratio of total training steps used for a linear warmup from 0 to `learning_rate`. + warmup_steps (`int`, *optional*, defaults to 0): + Number of steps used for a linear warmup from 0 to `learning_rate`. Overrides any effect of `warmup_ratio`. + logging_dir (`str`, *optional*): + [TensorBoard](https://www.tensorflow.org/tensorboard) log directory. Will default to + *runs/**CURRENT_DATETIME_HOSTNAME***. + logging_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The logging strategy to adopt during training. Possible values are: + + - `"no"`: No logging is done during training. + - `"epoch"`: Logging is done at the end of each epoch. + - `"steps"`: Logging is done every `logging_steps`. + + logging_first_step (`bool`, *optional*, defaults to `False`): + Whether to log and evaluate the first `global_step` or not. + logging_steps (`int`, *optional*, defaults to 500): + Number of update steps between two logs if `logging_strategy="steps"`. + save_strategy (`str` or [`~trainer_utils.IntervalStrategy`], *optional*, defaults to `"steps"`): + The checkpoint save strategy to adopt during training. Possible values are: + + - `"no"`: No save is done during training. + - `"epoch"`: Save is done at the end of each epoch. + - `"steps"`: Save is done every `save_steps`. + + save_steps (`int`, *optional*, defaults to 500): + Number of updates steps before two checkpoint saves if `save_strategy="steps"`. + save_total_limit (`int`, *optional*): + If a value is passed, will limit the total amount of checkpoints. Deletes the older checkpoints in + `output_dir`. + no_cuda (`bool`, *optional*, defaults to `False`): + Whether to not use CUDA even when it is available or not. + seed (`int`, *optional*, defaults to 42): + Random seed that will be set at the beginning of training. + fp16 (`bool`, *optional*, defaults to `False`): + Whether to use 16-bit (mixed) precision training (through NVIDIA Apex) instead of 32-bit training. + fp16_opt_level (`str`, *optional*, defaults to 'O1'): + For `fp16` training, Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']. See details on + the [Apex documentation](https://nvidia.github.io/apex/amp). + local_rank (`int`, *optional*, defaults to -1): + During distributed training, the rank of the process. + tpu_num_cores (`int`, *optional*): + When training on TPU, the number of TPU cores (automatically passed by launcher script). + debug (`bool`, *optional*, defaults to `False`): + Whether to activate the trace to record computation graphs and profiling information or not. + dataloader_drop_last (`bool`, *optional*, defaults to `False`): + Whether to drop the last incomplete batch (if the length of the dataset is not divisible by the batch size) + or not. + eval_steps (`int`, *optional*, defaults to 1000): + Number of update steps before two evaluations. + past_index (`int`, *optional*, defaults to -1): + Some models like [TransformerXL](../model_doc/transformerxl) or :doc*XLNet <../model_doc/xlnet>* can make + use of the past hidden states for their predictions. If this argument is set to a positive int, the + `Trainer` will use the corresponding output (usually index 2) as the past state and feed it to the model at + the next training step under the keyword argument `mems`. + tpu_name (`str`, *optional*): + The name of the TPU the process is running on. + tpu_zone (`str`, *optional*): + The zone of the TPU the process is running on. If not specified, we will attempt to automatically detect + from metadata. + gcp_project (`str`, *optional*): + Google Cloud Project name for the Cloud TPU-enabled project. If not specified, we will attempt to + automatically detect from metadata. + run_name (`str`, *optional*): + A descriptor for the run. Notably used for wandb logging. + xla (`bool`, *optional*): + Whether to activate the XLA compilation or not. + """ + + framework = "tf" + tpu_name: Optional[str] = field( + default=None, + metadata={"help": "Name of TPU"}, + ) + + tpu_zone: Optional[str] = field( + default=None, + metadata={"help": "Zone of TPU"}, + ) + + gcp_project: Optional[str] = field( + default=None, + metadata={"help": "Name of Cloud TPU-enabled project"}, + ) + + poly_power: float = field( + default=1.0, + metadata={"help": "Power for the Polynomial decay LR scheduler."}, + ) + + xla: bool = field(default=False, metadata={"help": "Whether to activate the XLA compilation or not"}) + + @cached_property + def _setup_strategy(self) -> Tuple["tf.distribute.Strategy", int]: + requires_backends(self, ["tf"]) + logger.info("Tensorflow: setting up strategy") + + gpus = tf.config.list_physical_devices("GPU") + + # Set to float16 at first + if self.fp16: + tf.keras.mixed_precision.set_global_policy("mixed_float16") + + if self.no_cuda: + strategy = tf.distribute.OneDeviceStrategy(device="/cpu:0") + else: + try: + if self.tpu_name: + tpu = tf.distribute.cluster_resolver.TPUClusterResolver( + self.tpu_name, zone=self.tpu_zone, project=self.gcp_project + ) + else: + tpu = tf.distribute.cluster_resolver.TPUClusterResolver() + except ValueError: + if self.tpu_name: + raise RuntimeError(f"Couldn't connect to TPU {self.tpu_name}!") + else: + tpu = None + + if tpu: + # Set to bfloat16 in case of TPU + if self.fp16: + tf.keras.mixed_precision.set_global_policy("mixed_bfloat16") + + tf.config.experimental_connect_to_cluster(tpu) + tf.tpu.experimental.initialize_tpu_system(tpu) + + strategy = tf.distribute.TPUStrategy(tpu) + + elif len(gpus) == 0: + strategy = tf.distribute.OneDeviceStrategy(device="/cpu:0") + elif len(gpus) == 1: + strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0") + elif len(gpus) > 1: + # If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0` + strategy = tf.distribute.MirroredStrategy() + else: + raise ValueError("Cannot find the proper strategy, please check your environment properties.") + + return strategy + + @property + def strategy(self) -> "tf.distribute.Strategy": + """ + The strategy used for distributed training. + """ + requires_backends(self, ["tf"]) + return self._setup_strategy + + @property + def n_replicas(self) -> int: + """ + The number of replicas (CPUs, GPUs or TPU cores) used in this training. + """ + requires_backends(self, ["tf"]) + return self._setup_strategy.num_replicas_in_sync + + @property + def should_log(self): + """ + Whether or not the current process should produce log. + """ + return False # TF Logging is handled by Keras not the Trainer + + @property + def train_batch_size(self) -> int: + """ + The actual batch size for training (may differ from `per_gpu_train_batch_size` in distributed training). + """ + if self.per_gpu_train_batch_size: + logger.warning( + "Using deprecated `--per_gpu_train_batch_size` argument which will be removed in a future " + "version. Using `--per_device_train_batch_size` is preferred." + ) + per_device_batch_size = self.per_gpu_train_batch_size or self.per_device_train_batch_size + return per_device_batch_size * self.n_replicas + + @property + def eval_batch_size(self) -> int: + """ + The actual batch size for evaluation (may differ from `per_gpu_eval_batch_size` in distributed training). + """ + if self.per_gpu_eval_batch_size: + logger.warning( + "Using deprecated `--per_gpu_eval_batch_size` argument which will be removed in a future " + "version. Using `--per_device_eval_batch_size` is preferred." + ) + per_device_batch_size = self.per_gpu_eval_batch_size or self.per_device_eval_batch_size + return per_device_batch_size * self.n_replicas + + @property + def n_gpu(self) -> int: + """ + The number of replicas (CPUs, GPUs or TPU cores) used in this training. + """ + requires_backends(self, ["tf"]) + warnings.warn( + "The n_gpu argument is deprecated and will be removed in a future version, use n_replicas instead.", + FutureWarning, + ) + return self._setup_strategy.num_replicas_in_sync diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a44a8360c6674707c4b321133e3b852a5b124fe5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/__init__.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from packaging import version + +from .. import __version__ +from .constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD +from .doc import ( + add_code_sample_docstrings, + add_end_docstrings, + add_start_docstrings, + add_start_docstrings_to_model_forward, + copy_func, + replace_return_docstrings, +) +from .generic import ( + ContextManagers, + ExplicitEnum, + ModelOutput, + PaddingStrategy, + TensorType, + add_model_info_to_auto_map, + cached_property, + can_return_loss, + expand_dims, + find_labels, + flatten_dict, + is_jax_tensor, + is_numpy_array, + is_tensor, + is_tf_symbolic_tensor, + is_tf_tensor, + is_torch_device, + is_torch_dtype, + is_torch_tensor, + reshape, + squeeze, + strtobool, + tensor_size, + to_numpy, + to_py_obj, + transpose, + working_or_temp_dir, +) +from .hub import ( + CLOUDFRONT_DISTRIB_PREFIX, + DISABLE_TELEMETRY, + HF_MODULES_CACHE, + HUGGINGFACE_CO_PREFIX, + HUGGINGFACE_CO_RESOLVE_ENDPOINT, + PYTORCH_PRETRAINED_BERT_CACHE, + PYTORCH_TRANSFORMERS_CACHE, + S3_BUCKET_PREFIX, + TRANSFORMERS_CACHE, + TRANSFORMERS_DYNAMIC_MODULE_NAME, + EntryNotFoundError, + PushToHubMixin, + RepositoryNotFoundError, + RevisionNotFoundError, + cached_file, + default_cache_path, + define_sagemaker_information, + download_url, + extract_commit_hash, + get_cached_models, + get_file_from_repo, + get_full_repo_name, + has_file, + http_user_agent, + is_offline_mode, + is_remote_url, + move_cache, + send_example_telemetry, + try_to_load_from_cache, +) +from .import_utils import ( + ENV_VARS_TRUE_AND_AUTO_VALUES, + ENV_VARS_TRUE_VALUES, + TORCH_FX_REQUIRED_VERSION, + USE_JAX, + USE_TF, + USE_TORCH, + DummyObject, + OptionalDependencyNotAvailable, + _LazyModule, + ccl_version, + direct_transformers_import, + is_accelerate_available, + is_apex_available, + is_bitsandbytes_available, + is_bs4_available, + is_coloredlogs_available, + is_cython_available, + is_datasets_available, + is_decord_available, + is_detectron2_available, + is_faiss_available, + is_flax_available, + is_ftfy_available, + is_in_notebook, + is_ipex_available, + is_jieba_available, + is_jumanpp_available, + is_kenlm_available, + is_keras_nlp_available, + is_librosa_available, + is_natten_available, + is_ninja_available, + is_onnx_available, + is_openai_available, + is_optimum_available, + is_pandas_available, + is_peft_available, + is_phonemizer_available, + is_protobuf_available, + is_psutil_available, + is_py3nvml_available, + is_pyctcdecode_available, + is_pytesseract_available, + is_pytorch_quantization_available, + is_rjieba_available, + is_sacremoses_available, + is_safetensors_available, + is_sagemaker_dp_enabled, + is_sagemaker_mp_enabled, + is_scipy_available, + is_sentencepiece_available, + is_sklearn_available, + is_soundfile_availble, + is_spacy_available, + is_speech_available, + is_sudachi_available, + is_tensorflow_probability_available, + is_tensorflow_text_available, + is_tf2onnx_available, + is_tf_available, + is_timm_available, + is_tokenizers_available, + is_torch_available, + is_torch_bf16_available, + is_torch_bf16_cpu_available, + is_torch_bf16_gpu_available, + is_torch_compile_available, + is_torch_cuda_available, + is_torch_fx_available, + is_torch_fx_proxy, + is_torch_neuroncore_available, + is_torch_tensorrt_fx_available, + is_torch_tf32_available, + is_torch_tpu_available, + is_torchaudio_available, + is_torchdistx_available, + is_torchdynamo_available, + is_torchvision_available, + is_training_run_on_sagemaker, + is_vision_available, + requires_backends, + torch_only_method, + torch_version, +) + + +WEIGHTS_NAME = "pytorch_model.bin" +WEIGHTS_INDEX_NAME = "pytorch_model.bin.index.json" +TF2_WEIGHTS_NAME = "tf_model.h5" +TF2_WEIGHTS_INDEX_NAME = "tf_model.h5.index.json" +TF_WEIGHTS_NAME = "model.ckpt" +FLAX_WEIGHTS_NAME = "flax_model.msgpack" +FLAX_WEIGHTS_INDEX_NAME = "flax_model.msgpack.index.json" +SAFE_WEIGHTS_NAME = "model.safetensors" +SAFE_WEIGHTS_INDEX_NAME = "model.safetensors.index.json" +CONFIG_NAME = "config.json" +FEATURE_EXTRACTOR_NAME = "preprocessor_config.json" +IMAGE_PROCESSOR_NAME = FEATURE_EXTRACTOR_NAME +GENERATION_CONFIG_NAME = "generation_config.json" +MODEL_CARD_NAME = "modelcard.json" + +SENTENCEPIECE_UNDERLINE = "▁" +SPIECE_UNDERLINE = SENTENCEPIECE_UNDERLINE # Kept for backward compatibility + +MULTIPLE_CHOICE_DUMMY_INPUTS = [ + [[0, 1, 0, 1], [1, 0, 0, 1]] +] * 2 # Needs to have 0s and 1s only since XLM uses it for langs too. +DUMMY_INPUTS = [[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]] +DUMMY_MASK = [[1, 1, 1, 1, 1], [1, 1, 1, 0, 0], [0, 0, 0, 1, 1]] + + +def check_min_version(min_version): + if version.parse(__version__) < version.parse(min_version): + if "dev" in min_version: + error_message = ( + "This example requires a source install from HuggingFace Transformers (see " + "`https://huggingface.co/transformers/installation.html#installing-from-source`)," + ) + else: + error_message = f"This example requires a minimum version of {min_version}," + error_message += f" but the version found is {__version__}.\n" + raise ImportError( + error_message + + "Check out https://huggingface.co/transformers/examples.html for the examples corresponding to other " + "versions of HuggingFace Transformers." + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/backbone_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/backbone_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..8c6b7107eb0e609d6a5f0b0991a751b8a31a07eb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/backbone_utils.py @@ -0,0 +1,203 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" Collection of utils to be used by backbones and their components.""" + +import inspect +from typing import Iterable, List, Optional, Tuple, Union + + +def verify_out_features_out_indices( + out_features: Optional[Iterable[str]], out_indices: Optional[Iterable[int]], stage_names: Optional[Iterable[str]] +): + """ + Verify that out_indices and out_features are valid for the given stage_names. + """ + if stage_names is None: + raise ValueError("Stage_names must be set for transformers backbones") + + if out_features is not None: + if not isinstance(out_features, (list,)): + raise ValueError(f"out_features must be a list {type(out_features)}") + if any(feat not in stage_names for feat in out_features): + raise ValueError(f"out_features must be a subset of stage_names: {stage_names} got {out_features}") + + if out_indices is not None: + if not isinstance(out_indices, (list, tuple)): + raise ValueError(f"out_indices must be a list or tuple, got {type(out_indices)}") + if any(idx >= len(stage_names) for idx in out_indices): + raise ValueError("out_indices must be valid indices for stage_names {stage_names}, got {out_indices}") + + if out_features is not None and out_indices is not None: + if len(out_features) != len(out_indices): + raise ValueError("out_features and out_indices should have the same length if both are set") + if out_features != [stage_names[idx] for idx in out_indices]: + raise ValueError("out_features and out_indices should correspond to the same stages if both are set") + + +def _align_output_features_output_indices( + out_features: Optional[List[str]], + out_indices: Optional[Union[List[int], Tuple[int]]], + stage_names: List[str], +): + """ + Finds the corresponding `out_features` and `out_indices` for the given `stage_names`. + + The logic is as follows: + - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the + `out_indices`. + - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the + `out_features`. + - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage. + - `out_indices` and `out_features` set: input `out_indices` and `out_features` are returned. + + Args: + out_features (`List[str]`): The names of the features for the backbone to output. + out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output. + stage_names (`List[str]`): The names of the stages of the backbone. + """ + if out_indices is None and out_features is None: + out_indices = [len(stage_names) - 1] + out_features = [stage_names[-1]] + elif out_indices is None and out_features is not None: + out_indices = [stage_names.index(layer) for layer in stage_names if layer in out_features] + elif out_features is None and out_indices is not None: + out_features = [stage_names[idx] for idx in out_indices] + return out_features, out_indices + + +def get_aligned_output_features_output_indices( + out_features: Optional[List[str]], + out_indices: Optional[Union[List[int], Tuple[int]]], + stage_names: List[str], +) -> Tuple[List[str], List[int]]: + """ + Get the `out_features` and `out_indices` so that they are aligned. + + The logic is as follows: + - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the + `out_indices`. + - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the + `out_features`. + - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage. + - `out_indices` and `out_features` set: they are verified to be aligned. + + Args: + out_features (`List[str]`): The names of the features for the backbone to output. + out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output. + stage_names (`List[str]`): The names of the stages of the backbone. + """ + # First verify that the out_features and out_indices are valid + verify_out_features_out_indices(out_features=out_features, out_indices=out_indices, stage_names=stage_names) + output_features, output_indices = _align_output_features_output_indices( + out_features=out_features, out_indices=out_indices, stage_names=stage_names + ) + # Verify that the aligned out_features and out_indices are valid + verify_out_features_out_indices(out_features=output_features, out_indices=output_indices, stage_names=stage_names) + return output_features, output_indices + + +class BackboneMixin: + @property + def out_feature_channels(self): + # the current backbones will output the number of channels for each stage + # even if that stage is not in the out_features list. + return {stage: self.num_features[i] for i, stage in enumerate(self.stage_names)} + + @property + def channels(self): + return [self.out_feature_channels[name] for name in self.out_features] + + def forward_with_filtered_kwargs(self, *args, **kwargs): + signature = dict(inspect.signature(self.forward).parameters) + filtered_kwargs = {k: v for k, v in kwargs.items() if k in signature} + return self(*args, **filtered_kwargs) + + def forward( + self, + pixel_values, + output_hidden_states: Optional[bool] = None, + output_attentions: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + raise NotImplementedError("This method should be implemented by the derived class.") + + @property + def out_features(self): + return self._out_features + + @out_features.setter + def out_features(self, out_features: List[str]): + """ + Set the out_features attribute. This will also update the out_indices attribute to match the new out_features. + """ + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + out_features=out_features, out_indices=None, stage_names=self.stage_names + ) + + @property + def out_indices(self): + return self._out_indices + + @out_indices.setter + def out_indices(self, out_indices: Union[Tuple[int], List[int]]): + """ + Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices. + """ + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + out_features=None, out_indices=out_indices, stage_names=self.stage_names + ) + + +class BackboneConfigMixin: + """ + A Mixin to support handling the `out_features` and `out_indices` attributes for the backbone configurations. + """ + + @property + def out_features(self): + return self._out_features + + @out_features.setter + def out_features(self, out_features: List[str]): + """ + Set the out_features attribute. This will also update the out_indices attribute to match the new out_features. + """ + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + out_features=out_features, out_indices=None, stage_names=self.stage_names + ) + + @property + def out_indices(self): + return self._out_indices + + @out_indices.setter + def out_indices(self, out_indices: Union[Tuple[int], List[int]]): + """ + Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices. + """ + self._out_features, self._out_indices = get_aligned_output_features_output_indices( + out_features=None, out_indices=out_indices, stage_names=self.stage_names + ) + + def to_dict(self): + """ + Serializes this instance to a Python dictionary. Override the default `to_dict()` from `PretrainedConfig` to + include the `out_features` and `out_indices` attributes. + """ + output = super().to_dict() + output["out_features"] = output.pop("_out_features") + output["out_indices"] = output.pop("_out_indices") + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/bitsandbytes.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/bitsandbytes.py new file mode 100644 index 0000000000000000000000000000000000000000..3768506f41138e37959b5fc93e6a4138e2ff8737 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/bitsandbytes.py @@ -0,0 +1,202 @@ +from copy import deepcopy + +from packaging import version + +from .import_utils import importlib_metadata, is_accelerate_available, is_bitsandbytes_available + + +if is_bitsandbytes_available(): + import bitsandbytes as bnb + import torch + import torch.nn as nn + +if is_accelerate_available(): + from accelerate import init_empty_weights + from accelerate.utils import find_tied_parameters + + +def set_module_8bit_tensor_to_device(module, tensor_name, device, value=None, fp16_statistics=None): + """ + A helper function to set a given tensor (parameter of buffer) of a module on a specific device (note that doing + `param.to(device)` creates a new tensor not linked to the parameter, which is why we need this function). The + function is adapted from `set_module_tensor_to_device` function from accelerate that is adapted to support the + class `Int8Params` from `bitsandbytes`. + + Args: + module (`torch.nn.Module`): + The module in which the tensor we want to move lives. + tensor_name (`str`): + The full name of the parameter/buffer. + device (`int`, `str` or `torch.device`): + The device on which to set the tensor. + value (`torch.Tensor`, *optional*): + The value of the tensor (useful when going from the meta device to any other device). + fp16_statistics (`torch.HalfTensor`, *optional*): + The list of fp16 statistics to set on the module, used for serialization. + """ + # Recurse if needed + if "." in tensor_name: + splits = tensor_name.split(".") + for split in splits[:-1]: + new_module = getattr(module, split) + if new_module is None: + raise ValueError(f"{module} has no attribute {split}.") + module = new_module + tensor_name = splits[-1] + + if tensor_name not in module._parameters and tensor_name not in module._buffers: + raise ValueError(f"{module} does not have a parameter or a buffer named {tensor_name}.") + is_buffer = tensor_name in module._buffers + old_value = getattr(module, tensor_name) + + if old_value.device == torch.device("meta") and device not in ["meta", torch.device("meta")] and value is None: + raise ValueError(f"{tensor_name} is on the meta device, we need a `value` to put in on {device}.") + + if is_buffer: + has_fp16_weights = None + else: + has_fp16_weights = getattr(module._parameters[tensor_name], "has_fp16_weights", None) + + if has_fp16_weights is not None: + param = module._parameters[tensor_name] + if param.device.type != "cuda": + if value is None: + new_value = old_value.to(device) + elif isinstance(value, torch.Tensor): + new_value = value.to("cpu") + if value.dtype == torch.int8: + is_8bit_serializable = version.parse(importlib_metadata.version("bitsandbytes")) > version.parse( + "0.37.2" + ) + if not is_8bit_serializable: + raise ValueError( + "Detected int8 weights but the version of bitsandbytes is not compatible with int8 serialization. " + "Make sure to download the latest `bitsandbytes` version. `pip install --upgrade bitsandbytes`." + ) + else: + new_value = torch.tensor(value, device="cpu") + new_value = bnb.nn.Int8Params(new_value, requires_grad=False, has_fp16_weights=has_fp16_weights).to(device) + module._parameters[tensor_name] = new_value + + if fp16_statistics is not None: + setattr(module.weight, "SCB", fp16_statistics.to(device)) + else: + if value is None: + new_value = old_value.to(device) + elif isinstance(value, torch.Tensor): + new_value = value.to(device) + else: + new_value = torch.tensor(value, device=device) + + if is_buffer: + module._buffers[tensor_name] = new_value + else: + new_value = nn.Parameter(new_value, requires_grad=old_value.requires_grad) + module._parameters[tensor_name] = new_value + + +def replace_8bit_linear(model, threshold=6.0, modules_to_not_convert=None, current_key_name=None): + """ + A helper function to replace all `torch.nn.Linear` modules by `bnb.nn.Linear8bit` modules from the `bitsandbytes` + library. This will enable running your models using mixed int8 precision as described by the paper `GPT3.int8(): + 8-bit Matrix Multiplication for Transformers at Scale`. Make sure `bitsandbytes` compiled with the correct CUDA + version of your hardware is installed before running this function. `pip install -i https://test.pypi.org/simple/ + bitsandbytes` + + The function will be run recursively and replace all `torch.nn.Linear` modules except for the `lm_head` that should + be kept as a `torch.nn.Linear` module. The replacement is done under `init_empty_weights` context manager so no + CPU/GPU memory is required to run this function. Int8 mixed-precision matrix decomposition works by separating a + matrix multiplication into two streams: (1) and systematic feature outlier stream matrix multiplied in fp16 + (0.01%), (2) a regular stream of int8 matrix multiplication (99.9%). With this method, int8 inference with no + predictive degradation is possible for very large models (>=176B parameters). + + Parameters: + model (`torch.nn.Module`): + Input model or `torch.nn.Module` as the function is run recursively. + threshold (`float`, *optional*, defaults to 6.0): + `int8_threshold` for outlier detection as described in the formentioned paper. This parameters is set to + `6.0` as described by the paper. + modules_to_not_convert (`List[`str`]`, *optional*, defaults to `["lm_head"]`): + Names of the modules to not convert in `Linear8bitLt`. In practice we keep the `lm_head` in full precision + for numerical stability reasons. + current_key_name (`List[`str`]`, *optional*): + An array to track the current key of the recursion. This is used to check whether the current key (part of + it) is not in the list of modules to not convert (for instances modules that are offloaded to `cpu` or + `disk`). + """ + modules_to_not_convert = ["lm_head"] if modules_to_not_convert is None else modules_to_not_convert + for name, module in model.named_children(): + if current_key_name is None: + current_key_name = [] + current_key_name.append(name) + + if len(list(module.children())) > 0: + replace_8bit_linear(module, threshold, modules_to_not_convert, current_key_name) + + if isinstance(module, nn.Linear) and name not in modules_to_not_convert: + # Check if the current key is not in the `modules_to_not_convert` + if not any(key in ".".join(current_key_name) for key in modules_to_not_convert): + with init_empty_weights(): + model._modules[name] = bnb.nn.Linear8bitLt( + module.in_features, + module.out_features, + module.bias is not None, + has_fp16_weights=False, + threshold=threshold, + ) + # Force requires grad to False to avoid unexpected errors + model._modules[name].requires_grad_(False) + # Remove the last key for recursion + current_key_name.pop(-1) + return model + + +def get_keys_to_not_convert(model): + r""" + An utility function to get the key of the module to keep in full precision if any For example for CausalLM modules + we may want to keep the lm_head in full precision for numerical stability reasons. For other architectures, we want + to keep the tied weights of the model. The function will return a list of the keys of the modules to not convert in + int8. + + Parameters: + model (`torch.nn.Module`): + Input model + """ + # Create a copy of the model and tie the weights, then + # check if it contains tied weights + tied_model = deepcopy(model) # this has 0 cost since it is done inside `init_empty_weights` context manager` + tied_model.tie_weights() + + tied_params = find_tied_parameters(tied_model) + # For compatibility with Accelerate < 0.18 + if isinstance(tied_params, dict): + tied_keys = list(tied_params.values()) + else: + tied_keys = sum([x[1:] for x in tied_params], []) + has_tied_params = len(tied_keys) > 0 + + # Check if it is a base model + is_base_model = not hasattr(model, model.base_model_prefix) + + # Ignore this for base models (BertModel, GPT2Model, etc.) + if (not has_tied_params) and is_base_model: + return [] + + # otherwise they have an attached head + list_modules = list(model.named_parameters()) + list_last_module = [list_modules[-1][0]] + + # add last module together with tied weights + intersection = set(list_last_module) - set(tied_keys) + list_untouched = tied_keys + list(intersection) + + # remove ".weight" from the keys + names_to_remove = [".weight", ".bias"] + filtered_module_names = [] + for name in list_untouched: + for name_to_remove in names_to_remove: + if name_to_remove in name: + name = name.replace(name_to_remove, "") + filtered_module_names.append(name) + + return filtered_module_names diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/constants.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..fefd1b4601da04e073ff2880099ccaf87d0b1666 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/constants.py @@ -0,0 +1,6 @@ +IMAGENET_DEFAULT_MEAN = [0.485, 0.456, 0.406] +IMAGENET_DEFAULT_STD = [0.229, 0.224, 0.225] +IMAGENET_STANDARD_MEAN = [0.5, 0.5, 0.5] +IMAGENET_STANDARD_STD = [0.5, 0.5, 0.5] +OPENAI_CLIP_MEAN = [0.48145466, 0.4578275, 0.40821073] +OPENAI_CLIP_STD = [0.26862954, 0.26130258, 0.27577711] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/doc.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/doc.py new file mode 100644 index 0000000000000000000000000000000000000000..f5eea7ae4e11a91127eab21e8f5d6b75003989b4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/doc.py @@ -0,0 +1,1175 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Doc utilities: Utilities related to documentation +""" + +import functools +import re +import types + + +def add_start_docstrings(*docstr): + def docstring_decorator(fn): + fn.__doc__ = "".join(docstr) + (fn.__doc__ if fn.__doc__ is not None else "") + return fn + + return docstring_decorator + + +def add_start_docstrings_to_model_forward(*docstr): + def docstring_decorator(fn): + docstring = "".join(docstr) + (fn.__doc__ if fn.__doc__ is not None else "") + class_name = f"[`{fn.__qualname__.split('.')[0]}`]" + intro = f" The {class_name} forward method, overrides the `__call__` special method." + note = r""" + + + + Although the recipe for forward pass needs to be defined within this function, one should call the [`Module`] + instance afterwards instead of this since the former takes care of running the pre and post processing steps while + the latter silently ignores them. + + +""" + + fn.__doc__ = intro + note + docstring + return fn + + return docstring_decorator + + +def add_end_docstrings(*docstr): + def docstring_decorator(fn): + fn.__doc__ = (fn.__doc__ if fn.__doc__ is not None else "") + "".join(docstr) + return fn + + return docstring_decorator + + +PT_RETURN_INTRODUCTION = r""" + Returns: + [`{full_output_type}`] or `tuple(torch.FloatTensor)`: A [`{full_output_type}`] or a tuple of + `torch.FloatTensor` (if `return_dict=False` is passed or when `config.return_dict=False`) comprising various + elements depending on the configuration ([`{config_class}`]) and inputs. + +""" + + +TF_RETURN_INTRODUCTION = r""" + Returns: + [`{full_output_type}`] or `tuple(tf.Tensor)`: A [`{full_output_type}`] or a tuple of `tf.Tensor` (if + `return_dict=False` is passed or when `config.return_dict=False`) comprising various elements depending on the + configuration ([`{config_class}`]) and inputs. + +""" + + +def _get_indent(t): + """Returns the indentation in the first line of t""" + search = re.search(r"^(\s*)\S", t) + return "" if search is None else search.groups()[0] + + +def _convert_output_args_doc(output_args_doc): + """Convert output_args_doc to display properly.""" + # Split output_arg_doc in blocks argument/description + indent = _get_indent(output_args_doc) + blocks = [] + current_block = "" + for line in output_args_doc.split("\n"): + # If the indent is the same as the beginning, the line is the name of new arg. + if _get_indent(line) == indent: + if len(current_block) > 0: + blocks.append(current_block[:-1]) + current_block = f"{line}\n" + else: + # Otherwise it's part of the description of the current arg. + # We need to remove 2 spaces to the indentation. + current_block += f"{line[2:]}\n" + blocks.append(current_block[:-1]) + + # Format each block for proper rendering + for i in range(len(blocks)): + blocks[i] = re.sub(r"^(\s+)(\S+)(\s+)", r"\1- **\2**\3", blocks[i]) + blocks[i] = re.sub(r":\s*\n\s*(\S)", r" -- \1", blocks[i]) + + return "\n".join(blocks) + + +def _prepare_output_docstrings(output_type, config_class, min_indent=None): + """ + Prepares the return part of the docstring using `output_type`. + """ + output_docstring = output_type.__doc__ + + # Remove the head of the docstring to keep the list of args only + lines = output_docstring.split("\n") + i = 0 + while i < len(lines) and re.search(r"^\s*(Args|Parameters):\s*$", lines[i]) is None: + i += 1 + if i < len(lines): + params_docstring = "\n".join(lines[(i + 1) :]) + params_docstring = _convert_output_args_doc(params_docstring) + + # Add the return introduction + full_output_type = f"{output_type.__module__}.{output_type.__name__}" + intro = TF_RETURN_INTRODUCTION if output_type.__name__.startswith("TF") else PT_RETURN_INTRODUCTION + intro = intro.format(full_output_type=full_output_type, config_class=config_class) + result = intro + params_docstring + + # Apply minimum indent if necessary + if min_indent is not None: + lines = result.split("\n") + # Find the indent of the first nonempty line + i = 0 + while len(lines[i]) == 0: + i += 1 + indent = len(_get_indent(lines[i])) + # If too small, add indentation to all nonempty lines + if indent < min_indent: + to_add = " " * (min_indent - indent) + lines = [(f"{to_add}{line}" if len(line) > 0 else line) for line in lines] + result = "\n".join(lines) + + return result + + +FAKE_MODEL_DISCLAIMER = """ + + + This example uses a random model as the real ones are all very big. To get proper results, you should use + {real_checkpoint} instead of {fake_checkpoint}. If you get out-of-memory when loading that checkpoint, you can try + adding `device_map="auto"` in the `from_pretrained` call. + + +""" + + +PT_TOKEN_CLASSIFICATION_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer( + ... "HuggingFace is a company based in Paris and New York", add_special_tokens=False, return_tensors="pt" + ... ) + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> predicted_token_class_ids = logits.argmax(-1) + + >>> # Note that tokens are classified rather then input words which means that + >>> # there might be more predicted token classes than words. + >>> # Multiple token classes might account for the same word + >>> predicted_tokens_classes = [model.config.id2label[t.item()] for t in predicted_token_class_ids[0]] + >>> predicted_tokens_classes + {expected_output} + + >>> labels = predicted_token_class_ids + >>> loss = model(**inputs, labels=labels).loss + >>> round(loss.item(), 2) + {expected_loss} + ``` +""" + +PT_QUESTION_ANSWERING_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" + + >>> inputs = tokenizer(question, text, return_tensors="pt") + >>> with torch.no_grad(): + ... outputs = model(**inputs) + + >>> answer_start_index = outputs.start_logits.argmax() + >>> answer_end_index = outputs.end_logits.argmax() + + >>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] + >>> tokenizer.decode(predict_answer_tokens, skip_special_tokens=True) + {expected_output} + + >>> # target is "nice puppet" + >>> target_start_index = torch.tensor([{qa_target_start_index}]) + >>> target_end_index = torch.tensor([{qa_target_end_index}]) + + >>> outputs = model(**inputs, start_positions=target_start_index, end_positions=target_end_index) + >>> loss = outputs.loss + >>> round(loss.item(), 2) + {expected_loss} + ``` +""" + +PT_SEQUENCE_CLASSIFICATION_SAMPLE = r""" + Example of single-label classification: + + ```python + >>> import torch + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> predicted_class_id = logits.argmax().item() + >>> model.config.id2label[predicted_class_id] + {expected_output} + + >>> # To train a model on `num_labels` classes, you can pass `num_labels=num_labels` to `.from_pretrained(...)` + >>> num_labels = len(model.config.id2label) + >>> model = {model_class}.from_pretrained("{checkpoint}", num_labels=num_labels) + + >>> labels = torch.tensor([1]) + >>> loss = model(**inputs, labels=labels).loss + >>> round(loss.item(), 2) + {expected_loss} + ``` + + Example of multi-label classification: + + ```python + >>> import torch + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}", problem_type="multi_label_classification") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> predicted_class_ids = torch.arange(0, logits.shape[-1])[torch.sigmoid(logits).squeeze(dim=0) > 0.5] + + >>> # To train a model on `num_labels` classes, you can pass `num_labels=num_labels` to `.from_pretrained(...)` + >>> num_labels = len(model.config.id2label) + >>> model = {model_class}.from_pretrained( + ... "{checkpoint}", num_labels=num_labels, problem_type="multi_label_classification" + ... ) + + >>> labels = torch.sum( + ... torch.nn.functional.one_hot(predicted_class_ids[None, :].clone(), num_classes=num_labels), dim=1 + ... ).to(torch.float) + >>> loss = model(**inputs, labels=labels).loss + ``` +""" + +PT_MASKED_LM_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("The capital of France is {mask}.", return_tensors="pt") + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> # retrieve index of {mask} + >>> mask_token_index = (inputs.input_ids == tokenizer.mask_token_id)[0].nonzero(as_tuple=True)[0] + + >>> predicted_token_id = logits[0, mask_token_index].argmax(axis=-1) + >>> tokenizer.decode(predicted_token_id) + {expected_output} + + >>> labels = tokenizer("The capital of France is Paris.", return_tensors="pt")["input_ids"] + >>> # mask labels of non-{mask} tokens + >>> labels = torch.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) + + >>> outputs = model(**inputs, labels=labels) + >>> round(outputs.loss.item(), 2) + {expected_loss} + ``` +""" + +PT_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + ``` +""" + +PT_MULTIPLE_CHOICE_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import torch + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." + >>> choice0 = "It is eaten with a fork and a knife." + >>> choice1 = "It is eaten while held in the hand." + >>> labels = torch.tensor(0).unsqueeze(0) # choice0 is correct (according to Wikipedia ;)), batch size 1 + + >>> encoding = tokenizer([prompt, prompt], [choice0, choice1], return_tensors="pt", padding=True) + >>> outputs = model(**{{k: v.unsqueeze(0) for k, v in encoding.items()}}, labels=labels) # batch size is 1 + + >>> # the linear classifier still needs to be trained + >>> loss = outputs.loss + >>> logits = outputs.logits + ``` +""" + +PT_CAUSAL_LM_SAMPLE = r""" + Example: + + ```python + >>> import torch + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") + >>> outputs = model(**inputs, labels=inputs["input_ids"]) + >>> loss = outputs.loss + >>> logits = outputs.logits + ``` +""" + +PT_SPEECH_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoProcessor, {model_class} + >>> import torch + >>> from datasets import load_dataset + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> processor = AutoProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt") + >>> with torch.no_grad(): + ... outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + {expected_output} + ``` +""" + +PT_SPEECH_CTC_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoProcessor, {model_class} + >>> from datasets import load_dataset + >>> import torch + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> processor = AutoProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt") + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + >>> predicted_ids = torch.argmax(logits, dim=-1) + + >>> # transcribe speech + >>> transcription = processor.batch_decode(predicted_ids) + >>> transcription[0] + {expected_output} + + >>> inputs["labels"] = processor(text=dataset[0]["text"], return_tensors="pt").input_ids + + >>> # compute loss + >>> loss = model(**inputs).loss + >>> round(loss.item(), 2) + {expected_loss} + ``` +""" + +PT_SPEECH_SEQ_CLASS_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoFeatureExtractor, {model_class} + >>> from datasets import load_dataset + >>> import torch + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = feature_extractor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt") + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> predicted_class_ids = torch.argmax(logits, dim=-1).item() + >>> predicted_label = model.config.id2label[predicted_class_ids] + >>> predicted_label + {expected_output} + + >>> # compute loss - target_label is e.g. "down" + >>> target_label = model.config.id2label[0] + >>> inputs["labels"] = torch.tensor([model.config.label2id[target_label]]) + >>> loss = model(**inputs).loss + >>> round(loss.item(), 2) + {expected_loss} + ``` +""" + + +PT_SPEECH_FRAME_CLASS_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoFeatureExtractor, {model_class} + >>> from datasets import load_dataset + >>> import torch + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = feature_extractor(dataset[0]["audio"]["array"], return_tensors="pt", sampling_rate=sampling_rate) + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> probabilities = torch.sigmoid(logits[0]) + >>> # labels is a one-hot array of shape (num_frames, num_speakers) + >>> labels = (probabilities > 0.5).long() + >>> labels[0].tolist() + {expected_output} + ``` +""" + + +PT_SPEECH_XVECTOR_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoFeatureExtractor, {model_class} + >>> from datasets import load_dataset + >>> import torch + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> feature_extractor = AutoFeatureExtractor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = feature_extractor( + ... [d["array"] for d in dataset[:2]["audio"]], sampling_rate=sampling_rate, return_tensors="pt", padding=True + ... ) + >>> with torch.no_grad(): + ... embeddings = model(**inputs).embeddings + + >>> embeddings = torch.nn.functional.normalize(embeddings, dim=-1).cpu() + + >>> # the resulting embeddings can be used for cosine similarity-based retrieval + >>> cosine_sim = torch.nn.CosineSimilarity(dim=-1) + >>> similarity = cosine_sim(embeddings[0], embeddings[1]) + >>> threshold = 0.7 # the optimal threshold is dataset-dependent + >>> if similarity < threshold: + ... print("Speakers are not the same!") + >>> round(similarity.item(), 2) + {expected_output} + ``` +""" + +PT_VISION_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoImageProcessor, {model_class} + >>> import torch + >>> from datasets import load_dataset + + >>> dataset = load_dataset("huggingface/cats-image") + >>> image = dataset["test"]["image"][0] + + >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = image_processor(image, return_tensors="pt") + + >>> with torch.no_grad(): + ... outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + {expected_output} + ``` +""" + +PT_VISION_SEQ_CLASS_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoImageProcessor, {model_class} + >>> import torch + >>> from datasets import load_dataset + + >>> dataset = load_dataset("huggingface/cats-image") + >>> image = dataset["test"]["image"][0] + + >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = image_processor(image, return_tensors="pt") + + >>> with torch.no_grad(): + ... logits = model(**inputs).logits + + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_label = logits.argmax(-1).item() + >>> print(model.config.id2label[predicted_label]) + {expected_output} + ``` +""" + + +PT_SAMPLE_DOCSTRINGS = { + "SequenceClassification": PT_SEQUENCE_CLASSIFICATION_SAMPLE, + "QuestionAnswering": PT_QUESTION_ANSWERING_SAMPLE, + "TokenClassification": PT_TOKEN_CLASSIFICATION_SAMPLE, + "MultipleChoice": PT_MULTIPLE_CHOICE_SAMPLE, + "MaskedLM": PT_MASKED_LM_SAMPLE, + "LMHead": PT_CAUSAL_LM_SAMPLE, + "BaseModel": PT_BASE_MODEL_SAMPLE, + "SpeechBaseModel": PT_SPEECH_BASE_MODEL_SAMPLE, + "CTC": PT_SPEECH_CTC_SAMPLE, + "AudioClassification": PT_SPEECH_SEQ_CLASS_SAMPLE, + "AudioFrameClassification": PT_SPEECH_FRAME_CLASS_SAMPLE, + "AudioXVector": PT_SPEECH_XVECTOR_SAMPLE, + "VisionBaseModel": PT_VISION_BASE_MODEL_SAMPLE, + "ImageClassification": PT_VISION_SEQ_CLASS_SAMPLE, +} + + +TF_TOKEN_CLASSIFICATION_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer( + ... "HuggingFace is a company based in Paris and New York", add_special_tokens=False, return_tensors="tf" + ... ) + + >>> logits = model(**inputs).logits + >>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) + + >>> # Note that tokens are classified rather then input words which means that + >>> # there might be more predicted token classes than words. + >>> # Multiple token classes might account for the same word + >>> predicted_tokens_classes = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] + >>> predicted_tokens_classes + {expected_output} + ``` + + ```python + >>> labels = predicted_token_class_ids + >>> loss = tf.math.reduce_mean(model(**inputs, labels=labels).loss) + >>> round(float(loss), 2) + {expected_loss} + ``` +""" + +TF_QUESTION_ANSWERING_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" + + >>> inputs = tokenizer(question, text, return_tensors="tf") + >>> outputs = model(**inputs) + + >>> answer_start_index = int(tf.math.argmax(outputs.start_logits, axis=-1)[0]) + >>> answer_end_index = int(tf.math.argmax(outputs.end_logits, axis=-1)[0]) + + >>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1] + >>> tokenizer.decode(predict_answer_tokens) + {expected_output} + ``` + + ```python + >>> # target is "nice puppet" + >>> target_start_index = tf.constant([{qa_target_start_index}]) + >>> target_end_index = tf.constant([{qa_target_end_index}]) + + >>> outputs = model(**inputs, start_positions=target_start_index, end_positions=target_end_index) + >>> loss = tf.math.reduce_mean(outputs.loss) + >>> round(float(loss), 2) + {expected_loss} + ``` +""" + +TF_SEQUENCE_CLASSIFICATION_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") + + >>> logits = model(**inputs).logits + + >>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0]) + >>> model.config.id2label[predicted_class_id] + {expected_output} + ``` + + ```python + >>> # To train a model on `num_labels` classes, you can pass `num_labels=num_labels` to `.from_pretrained(...)` + >>> num_labels = len(model.config.id2label) + >>> model = {model_class}.from_pretrained("{checkpoint}", num_labels=num_labels) + + >>> labels = tf.constant(1) + >>> loss = model(**inputs, labels=labels).loss + >>> round(float(loss), 2) + {expected_loss} + ``` +""" + +TF_MASKED_LM_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("The capital of France is {mask}.", return_tensors="tf") + >>> logits = model(**inputs).logits + + >>> # retrieve index of {mask} + >>> mask_token_index = tf.where((inputs.input_ids == tokenizer.mask_token_id)[0]) + >>> selected_logits = tf.gather_nd(logits[0], indices=mask_token_index) + + >>> predicted_token_id = tf.math.argmax(selected_logits, axis=-1) + >>> tokenizer.decode(predicted_token_id) + {expected_output} + ``` + + ```python + >>> labels = tokenizer("The capital of France is Paris.", return_tensors="tf")["input_ids"] + >>> # mask labels of non-{mask} tokens + >>> labels = tf.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100) + + >>> outputs = model(**inputs, labels=labels) + >>> round(float(outputs.loss), 2) + {expected_loss} + ``` +""" + +TF_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") + >>> outputs = model(inputs) + + >>> last_hidden_states = outputs.last_hidden_state + ``` +""" + +TF_MULTIPLE_CHOICE_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." + >>> choice0 = "It is eaten with a fork and a knife." + >>> choice1 = "It is eaten while held in the hand." + + >>> encoding = tokenizer([prompt, prompt], [choice0, choice1], return_tensors="tf", padding=True) + >>> inputs = {{k: tf.expand_dims(v, 0) for k, v in encoding.items()}} + >>> outputs = model(inputs) # batch size is 1 + + >>> # the linear classifier still needs to be trained + >>> logits = outputs.logits + ``` +""" + +TF_CAUSAL_LM_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + >>> import tensorflow as tf + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="tf") + >>> outputs = model(inputs) + >>> logits = outputs.logits + ``` +""" + +TF_SPEECH_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoProcessor, {model_class} + >>> from datasets import load_dataset + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> processor = AutoProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="tf") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + {expected_output} + ``` +""" + +TF_SPEECH_CTC_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoProcessor, {model_class} + >>> from datasets import load_dataset + >>> import tensorflow as tf + + >>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation") + >>> dataset = dataset.sort("id") + >>> sampling_rate = dataset.features["audio"].sampling_rate + + >>> processor = AutoProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> # audio file is decoded on the fly + >>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="tf") + >>> logits = model(**inputs).logits + >>> predicted_ids = tf.math.argmax(logits, axis=-1) + + >>> # transcribe speech + >>> transcription = processor.batch_decode(predicted_ids) + >>> transcription[0] + {expected_output} + ``` + + ```python + >>> inputs["labels"] = processor(text=dataset[0]["text"], return_tensors="tf").input_ids + + >>> # compute loss + >>> loss = model(**inputs).loss + >>> round(float(loss), 2) + {expected_loss} + ``` +""" + +TF_VISION_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoImageProcessor, {model_class} + >>> from datasets import load_dataset + + >>> dataset = load_dataset("huggingface/cats-image") + >>> image = dataset["test"]["image"][0] + + >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = image_processor(image, return_tensors="tf") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + {expected_output} + ``` +""" + +TF_VISION_SEQ_CLASS_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoImageProcessor, {model_class} + >>> import tensorflow as tf + >>> from datasets import load_dataset + + >>> dataset = load_dataset("huggingface/cats-image") + >>> image = dataset["test"]["image"][0] + + >>> image_processor = AutoImageProcessor.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = image_processor(image, return_tensors="tf") + >>> logits = model(**inputs).logits + + >>> # model predicts one of the 1000 ImageNet classes + >>> predicted_label = int(tf.math.argmax(logits, axis=-1)) + >>> print(model.config.id2label[predicted_label]) + {expected_output} + ``` +""" + +TF_SAMPLE_DOCSTRINGS = { + "SequenceClassification": TF_SEQUENCE_CLASSIFICATION_SAMPLE, + "QuestionAnswering": TF_QUESTION_ANSWERING_SAMPLE, + "TokenClassification": TF_TOKEN_CLASSIFICATION_SAMPLE, + "MultipleChoice": TF_MULTIPLE_CHOICE_SAMPLE, + "MaskedLM": TF_MASKED_LM_SAMPLE, + "LMHead": TF_CAUSAL_LM_SAMPLE, + "BaseModel": TF_BASE_MODEL_SAMPLE, + "SpeechBaseModel": TF_SPEECH_BASE_MODEL_SAMPLE, + "CTC": TF_SPEECH_CTC_SAMPLE, + "VisionBaseModel": TF_VISION_BASE_MODEL_SAMPLE, + "ImageClassification": TF_VISION_SEQ_CLASS_SAMPLE, +} + + +FLAX_TOKEN_CLASSIFICATION_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") + + >>> outputs = model(**inputs) + >>> logits = outputs.logits + ``` +""" + +FLAX_QUESTION_ANSWERING_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" + >>> inputs = tokenizer(question, text, return_tensors="jax") + + >>> outputs = model(**inputs) + >>> start_scores = outputs.start_logits + >>> end_scores = outputs.end_logits + ``` +""" + +FLAX_SEQUENCE_CLASSIFICATION_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") + + >>> outputs = model(**inputs) + >>> logits = outputs.logits + ``` +""" + +FLAX_MASKED_LM_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("The capital of France is {mask}.", return_tensors="jax") + + >>> outputs = model(**inputs) + >>> logits = outputs.logits + ``` +""" + +FLAX_BASE_MODEL_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="jax") + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + ``` +""" + +FLAX_MULTIPLE_CHOICE_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced." + >>> choice0 = "It is eaten with a fork and a knife." + >>> choice1 = "It is eaten while held in the hand." + + >>> encoding = tokenizer([prompt, prompt], [choice0, choice1], return_tensors="jax", padding=True) + >>> outputs = model(**{{k: v[None, :] for k, v in encoding.items()}}) + + >>> logits = outputs.logits + ``` +""" + +FLAX_CAUSAL_LM_SAMPLE = r""" + Example: + + ```python + >>> from transformers import AutoTokenizer, {model_class} + + >>> tokenizer = AutoTokenizer.from_pretrained("{checkpoint}") + >>> model = {model_class}.from_pretrained("{checkpoint}") + + >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="np") + >>> outputs = model(**inputs) + + >>> # retrieve logts for next token + >>> next_token_logits = outputs.logits[:, -1] + ``` +""" + +FLAX_SAMPLE_DOCSTRINGS = { + "SequenceClassification": FLAX_SEQUENCE_CLASSIFICATION_SAMPLE, + "QuestionAnswering": FLAX_QUESTION_ANSWERING_SAMPLE, + "TokenClassification": FLAX_TOKEN_CLASSIFICATION_SAMPLE, + "MultipleChoice": FLAX_MULTIPLE_CHOICE_SAMPLE, + "MaskedLM": FLAX_MASKED_LM_SAMPLE, + "BaseModel": FLAX_BASE_MODEL_SAMPLE, + "LMHead": FLAX_CAUSAL_LM_SAMPLE, +} + + +def filter_outputs_from_example(docstring, **kwargs): + """ + Removes the lines testing an output with the doctest syntax in a code sample when it's set to `None`. + """ + for key, value in kwargs.items(): + if value is not None: + continue + + doc_key = "{" + key + "}" + docstring = re.sub(rf"\n([^\n]+)\n\s+{doc_key}\n", "\n", docstring) + + return docstring + + +def add_code_sample_docstrings( + *docstr, + processor_class=None, + checkpoint=None, + output_type=None, + config_class=None, + mask="[MASK]", + qa_target_start_index=14, + qa_target_end_index=15, + model_cls=None, + modality=None, + expected_output=None, + expected_loss=None, + real_checkpoint=None, +): + def docstring_decorator(fn): + # model_class defaults to function's class if not specified otherwise + model_class = fn.__qualname__.split(".")[0] if model_cls is None else model_cls + + if model_class[:2] == "TF": + sample_docstrings = TF_SAMPLE_DOCSTRINGS + elif model_class[:4] == "Flax": + sample_docstrings = FLAX_SAMPLE_DOCSTRINGS + else: + sample_docstrings = PT_SAMPLE_DOCSTRINGS + + # putting all kwargs for docstrings in a dict to be used + # with the `.format(**doc_kwargs)`. Note that string might + # be formatted with non-existing keys, which is fine. + doc_kwargs = { + "model_class": model_class, + "processor_class": processor_class, + "checkpoint": checkpoint, + "mask": mask, + "qa_target_start_index": qa_target_start_index, + "qa_target_end_index": qa_target_end_index, + "expected_output": expected_output, + "expected_loss": expected_loss, + "real_checkpoint": real_checkpoint, + "fake_checkpoint": checkpoint, + "true": "{true}", # For syntax that conflicts with formatting. + } + + if ("SequenceClassification" in model_class or "AudioClassification" in model_class) and modality == "audio": + code_sample = sample_docstrings["AudioClassification"] + elif "SequenceClassification" in model_class: + code_sample = sample_docstrings["SequenceClassification"] + elif "QuestionAnswering" in model_class: + code_sample = sample_docstrings["QuestionAnswering"] + elif "TokenClassification" in model_class: + code_sample = sample_docstrings["TokenClassification"] + elif "MultipleChoice" in model_class: + code_sample = sample_docstrings["MultipleChoice"] + elif "MaskedLM" in model_class or model_class in ["FlaubertWithLMHeadModel", "XLMWithLMHeadModel"]: + code_sample = sample_docstrings["MaskedLM"] + elif "LMHead" in model_class or "CausalLM" in model_class: + code_sample = sample_docstrings["LMHead"] + elif "CTC" in model_class: + code_sample = sample_docstrings["CTC"] + elif "AudioFrameClassification" in model_class: + code_sample = sample_docstrings["AudioFrameClassification"] + elif "XVector" in model_class and modality == "audio": + code_sample = sample_docstrings["AudioXVector"] + elif "Model" in model_class and modality == "audio": + code_sample = sample_docstrings["SpeechBaseModel"] + elif "Model" in model_class and modality == "vision": + code_sample = sample_docstrings["VisionBaseModel"] + elif "Model" in model_class or "Encoder" in model_class: + code_sample = sample_docstrings["BaseModel"] + elif "ImageClassification" in model_class: + code_sample = sample_docstrings["ImageClassification"] + else: + raise ValueError(f"Docstring can't be built for model {model_class}") + + code_sample = filter_outputs_from_example( + code_sample, expected_output=expected_output, expected_loss=expected_loss + ) + if real_checkpoint is not None: + code_sample = FAKE_MODEL_DISCLAIMER + code_sample + func_doc = (fn.__doc__ or "") + "".join(docstr) + output_doc = "" if output_type is None else _prepare_output_docstrings(output_type, config_class) + built_doc = code_sample.format(**doc_kwargs) + fn.__doc__ = func_doc + output_doc + built_doc + return fn + + return docstring_decorator + + +def replace_return_docstrings(output_type=None, config_class=None): + def docstring_decorator(fn): + func_doc = fn.__doc__ + lines = func_doc.split("\n") + i = 0 + while i < len(lines) and re.search(r"^\s*Returns?:\s*$", lines[i]) is None: + i += 1 + if i < len(lines): + indent = len(_get_indent(lines[i])) + lines[i] = _prepare_output_docstrings(output_type, config_class, min_indent=indent) + func_doc = "\n".join(lines) + else: + raise ValueError( + f"The function {fn} should have an empty 'Return:' or 'Returns:' in its docstring as placeholder, " + f"current docstring is:\n{func_doc}" + ) + fn.__doc__ = func_doc + return fn + + return docstring_decorator + + +def copy_func(f): + """Returns a copy of a function f.""" + # Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard) + g = types.FunctionType(f.__code__, f.__globals__, name=f.__name__, argdefs=f.__defaults__, closure=f.__closure__) + g = functools.update_wrapper(g, f) + g.__kwdefaults__ = f.__kwdefaults__ + return g diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_detectron2_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_detectron2_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..41dfb6f81d34ef2f18ad67ef46d25180ca7cd602 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_detectron2_objects.py @@ -0,0 +1,14 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import requires_backends + + +LAYOUTLM_V2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LayoutLMv2Model: + def __init__(self, *args, **kwargs): + requires_backends(self, ["detectron2"]) + + @classmethod + def from_pretrained(cls, *args, **kwargs): + requires_backends(cls, ["detectron2"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_flax_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_flax_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..ce571bc9f8d004b5bb5ef7a4b657691537d6f7c8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_flax_objects.py @@ -0,0 +1,1290 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class FlaxForcedBOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxForcedEOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGenerationMixin(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLogitsProcessor(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLogitsProcessorList(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLogitsWarper(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMinLengthLogitsProcessor(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxTemperatureLogitsWarper(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxTopKLogitsWarper(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxTopPLogitsWarper(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAlbertPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +FLAX_MODEL_FOR_CAUSAL_LM_MAPPING = None + + +FLAX_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = None + + +FLAX_MODEL_FOR_MASKED_LM_MAPPING = None + + +FLAX_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = None + + +FLAX_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = None + + +FLAX_MODEL_FOR_PRETRAINING_MAPPING = None + + +FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING = None + + +FLAX_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = None + + +FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = None + + +FLAX_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = None + + +FLAX_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = None + + +FLAX_MODEL_FOR_VISION_2_SEQ_MAPPING = None + + +FLAX_MODEL_MAPPING = None + + +class FlaxAutoModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForImageClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForNextSentencePrediction(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForSeq2SeqLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForSpeechSeq2Seq(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxAutoModelForVision2Seq(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartDecoderPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBartPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBeitForImageClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBeitForMaskedImageModeling(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBeitModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBeitPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBertPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBigBirdPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotSmallForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotSmallModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxBlenderbotSmallPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPTextModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPTextPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPVisionModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxCLIPVisionPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxDistilBertPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxElectraPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxEncoderDecoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPT2LMHeadModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPT2Model(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPT2PreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTNeoForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTNeoModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTNeoPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTJForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTJModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxGPTJPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLongT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLongT5Model(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxLongT5PreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMarianModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMarianMTModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMarianPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMBartForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMBartForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMBartModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMBartPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMT5EncoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxMT5Model(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxOPTForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxOPTModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxOPTPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxPegasusForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxPegasusModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxPegasusPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRegNetForImageClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRegNetModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRegNetPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxResNetForImageClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxResNetModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxResNetPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRobertaPreLayerNormPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxRoFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxSpeechEncoderDecoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxT5EncoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxT5Model(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxT5PreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxVisionEncoderDecoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxVisionTextDualEncoderModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxViTForImageClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxViTModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxViTPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWav2Vec2ForCTC(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWav2Vec2ForPreTraining(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWav2Vec2Model(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWav2Vec2PreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWhisperForAudioClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWhisperForConditionalGeneration(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWhisperModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxWhisperPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXGLMForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXGLMModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXGLMPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +FLAX_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FlaxXLMRobertaForCausalLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaForMaskedLM(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaForTokenClassification(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) + + +class FlaxXLMRobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["flax"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["flax"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_keras_nlp_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_keras_nlp_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..c6bb86a6d9b49e78f8936f3c1eb3cfc8b8db7951 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_keras_nlp_objects.py @@ -0,0 +1,9 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class TFGPT2Tokenizer(metaclass=DummyObject): + _backends = ["keras_nlp"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["keras_nlp"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_pt_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_pt_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..eeb799e1887523b6af24f3770cedbf842773683b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_pt_objects.py @@ -0,0 +1,7983 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class PyTorchBenchmark(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PyTorchBenchmarkArguments(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GlueDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GlueDataTrainingArguments(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LineByLineTextDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LineByLineWithRefDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LineByLineWithSOPTextDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SquadDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SquadDataTrainingArguments(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TextDataset(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TextDatasetForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeamScorer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeamSearchScorer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConstrainedBeamSearchScorer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Constraint(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConstraintListState(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DisjunctiveConstraint(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ForcedBOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ForcedEOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GenerationMixin(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class HammingDiversityLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class InfNanRemoveLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LogitsProcessorList(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LogitsWarper(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MaxLengthCriteria(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MaxTimeCriteria(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MinLengthLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MinNewTokensLengthLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NoBadWordsLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NoRepeatNGramLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PhrasalConstraint(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PrefixConstrainedLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RepetitionPenaltyLogitsProcessor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class StoppingCriteria(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class StoppingCriteriaList(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TemperatureLogitsWarper(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TopKLogitsWarper(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TopPLogitsWarper(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TypicalLogitsWarper(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def top_k_top_p_filtering(*args, **kwargs): + requires_backends(top_k_top_p_filtering, ["torch"]) + + +class PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class AlbertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlbertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_albert(*args, **kwargs): + requires_backends(load_tf_weights_in_albert, ["torch"]) + + +ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class AlignModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlignPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlignTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AlignVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ALTCLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class AltCLIPModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AltCLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AltCLIPTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AltCLIPVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +AUDIO_SPECTROGRAM_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ASTForAudioClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ASTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ASTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_AUDIO_XVECTOR_MAPPING = None + + +MODEL_FOR_BACKBONE_MAPPING = None + + +MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING = None + + +MODEL_FOR_CAUSAL_LM_MAPPING = None + + +MODEL_FOR_CTC_MAPPING = None + + +MODEL_FOR_DEPTH_ESTIMATION_MAPPING = None + + +MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING = None + + +MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_IMAGE_SEGMENTATION_MAPPING = None + + +MODEL_FOR_INSTANCE_SEGMENTATION_MAPPING = None + + +MODEL_FOR_MASK_GENERATION_MAPPING = None + + +MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING = None + + +MODEL_FOR_MASKED_LM_MAPPING = None + + +MODEL_FOR_MULTIPLE_CHOICE_MAPPING = None + + +MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = None + + +MODEL_FOR_OBJECT_DETECTION_MAPPING = None + + +MODEL_FOR_PRETRAINING_MAPPING = None + + +MODEL_FOR_QUESTION_ANSWERING_MAPPING = None + + +MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING = None + + +MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = None + + +MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = None + + +MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING = None + + +MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_UNIVERSAL_SEGMENTATION_MAPPING = None + + +MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_VISION_2_SEQ_MAPPING = None + + +MODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING = None + + +MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING = None + + +MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING = None + + +MODEL_MAPPING = None + + +MODEL_WITH_LM_HEAD_MAPPING = None + + +class AutoBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForAudioClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForAudioXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForDepthEstimation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForDocumentQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForImageSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForInstanceSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForMaskGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForSeq2SeqLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForSpeechSeq2Seq(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForTableQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForUniversalSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForVideoClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForVision2Seq(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForVisualQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForZeroShotImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelForZeroShotObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AutoModelWithLMHead(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BART_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BartForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BartForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BartForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BartForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BartModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BartPretrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PretrainedBartModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BEIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BeitForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeitForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeitForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeitModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BeitPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_bert(*args, **kwargs): + requires_backends(load_tf_weights_in_bert, ["torch"]) + + +class BertGenerationDecoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertGenerationEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BertGenerationPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_bert_generation(*args, **kwargs): + requires_backends(load_tf_weights_in_bert_generation, ["torch"]) + + +BIG_BIRD_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BigBirdForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_big_bird(*args, **kwargs): + requires_backends(load_tf_weights_in_big_bird, ["torch"]) + + +BIGBIRD_PEGASUS_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BigBirdPegasusForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPegasusForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPegasusForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPegasusForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPegasusModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BigBirdPegasusPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BIOGPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BioGptForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BioGptForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BioGptForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BioGptModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BioGptPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BitBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BitForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BitModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BitPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BLENDERBOT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BlenderbotForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BLENDERBOT_SMALL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BlenderbotSmallForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotSmallForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotSmallModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlenderbotSmallPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BlipForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipForImageTextRetrieval(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BlipVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BLIP_2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Blip2ForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Blip2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Blip2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Blip2QFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Blip2VisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BLOOM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BloomForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BloomForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BloomForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BloomForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BloomModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BloomPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +BRIDGETOWER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class BridgeTowerForContrastiveLearning(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BridgeTowerForImageAndTextRetrieval(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BridgeTowerForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BridgeTowerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class BridgeTowerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CAMEMBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CamembertForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CamembertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CANINE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CanineForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CanineForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CanineForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CanineForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CanineLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CanineModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CaninePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_canine(*args, **kwargs): + requires_backends(load_tf_weights_in_canine, ["torch"]) + + +CHINESE_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ChineseCLIPModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ChineseCLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ChineseCLIPTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ChineseCLIPVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CLAP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ClapAudioModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapAudioModelWithProjection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapFeatureExtractor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ClapTextModelWithProjection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CLIPModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPTextModelWithProjection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPVisionModelWithProjection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CLIPSEG_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CLIPSegForImageSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPSegModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPSegPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPSegTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CLIPSegVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CODEGEN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CodeGenForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CodeGenModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CodeGenPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CONDITIONAL_DETR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ConditionalDetrForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConditionalDetrForSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConditionalDetrModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConditionalDetrPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CONVBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ConvBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_convbert(*args, **kwargs): + requires_backends(load_tf_weights_in_convbert, ["torch"]) + + +CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ConvNextBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CONVNEXTV2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ConvNextV2Backbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextV2ForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextV2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ConvNextV2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CPMANT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CpmAntForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CpmAntModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CpmAntPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CTRL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CTRLForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CTRLLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CTRLModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CTRLPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +CVT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class CvtForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CvtModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class CvtPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DATA2VEC_AUDIO_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +DATA2VEC_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Data2VecAudioForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecAudioForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecAudioForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecAudioForXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecAudioModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecAudioPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecTextPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecVisionForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecVisionForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Data2VecVisionPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DebertaForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DebertaV2ForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2ForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2ForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2ForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2ForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DebertaV2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DecisionTransformerGPT2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DecisionTransformerGPT2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DecisionTransformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DecisionTransformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DEFORMABLE_DETR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DeformableDetrForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeformableDetrModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeformableDetrPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DEIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DeiTForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeiTForImageClassificationWithTeacher(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeiTForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeiTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DeiTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DETA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DetaForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DetaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DetaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DETR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DetrForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DetrForSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DetrModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DetrPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DINAT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DinatBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DinatForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DinatModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DinatPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DistilBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DistilBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DonutSwinModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DonutSwinPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DPRContextEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRPretrainedContextEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRPretrainedQuestionEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRPretrainedReader(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRQuestionEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPRReader(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +DPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class DPTForDepthEstimation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPTForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class DPTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class EfficientFormerForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EfficientFormerForImageClassificationWithTeacher(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EfficientFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EfficientFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +EFFICIENTNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class EfficientNetForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EfficientNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EfficientNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ElectraForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ElectraPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_electra(*args, **kwargs): + requires_backends(load_tf_weights_in_electra, ["torch"]) + + +class EncoderDecoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ErnieForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErniePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ErnieMForInformationExtraction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ErnieMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ESM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class EsmFoldPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmForProteinFolding(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class EsmPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FlaubertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlaubertWithLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FlavaForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaImageCodebook(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaImageModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaMultimodalModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FlavaTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +FNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FNetForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +FOCALNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FocalNetBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FocalNetForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FocalNetForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FocalNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FocalNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FSMTForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FSMTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PretrainedFSMTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class FunnelBaseModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class FunnelPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_funnel(*args, **kwargs): + requires_backends(load_tf_weights_in_funnel, ["torch"]) + + +GIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GitForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GitModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GitPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GitVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GLPN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GLPNForDepthEstimation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GLPNModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GLPNPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GPT2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPT2DoubleHeadsModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2ForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2ForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2ForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2LMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPT2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_gpt2(*args, **kwargs): + requires_backends(load_tf_weights_in_gpt2, ["torch"]) + + +GPT_BIGCODE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTBigCodeForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTBigCodeForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTBigCodeForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTBigCodeModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTBigCodePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GPT_NEO_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTNeoForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_gpt_neo(*args, **kwargs): + requires_backends(load_tf_weights_in_gpt_neo, ["torch"]) + + +GPT_NEOX_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTNeoXForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GPT_NEOX_JAPANESE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTNeoXJapaneseForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXJapaneseLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXJapaneseModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTNeoXJapanesePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GPTJ_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTJForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTJForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTJForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTJModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTJPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GPTSAN_JAPANESE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GPTSanJapaneseForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTSanJapaneseModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GPTSanJapanesePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GRAPHORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GraphormerForGraphClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GraphormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GraphormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class GroupViTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GroupViTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GroupViTTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class GroupViTVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +HUBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class HubertForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class HubertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class HubertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class HubertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +IBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class IBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class IBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +IMAGEGPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ImageGPTForCausalImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ImageGPTForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ImageGPTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ImageGPTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_imagegpt(*args, **kwargs): + requires_backends(load_tf_weights_in_imagegpt, ["torch"]) + + +INFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class InformerForPrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class InformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class InformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +JUKEBOX_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class JukeboxModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class JukeboxPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class JukeboxPrior(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class JukeboxVQVAE(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LayoutLMForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LAYOUTLMV2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LayoutLMv2ForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv2ForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv2ForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LayoutLMv3ForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv3ForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv3ForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv3Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LayoutLMv3PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LED_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LEDForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LEDForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LEDForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LEDModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LEDPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LEVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LevitForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LevitForImageClassificationWithTeacher(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LevitModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LevitPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LILT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LiltForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LiltForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LiltForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LiltModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LiltPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LlamaForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LlamaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LlamaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LlamaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LONGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LongformerForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongformerSelfAttention(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LONGT5_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LongT5EncoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongT5Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LongT5PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +LUKE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class LukeForEntityClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForEntityPairClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForEntitySpanClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukeModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LukePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertVisualFeatureEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class LxmertXLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +M2M_100_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class M2M100ForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class M2M100Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class M2M100PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarianForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarianModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarianMTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MARKUPLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MarkupLMForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarkupLMForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarkupLMForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarkupLMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MarkupLMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MASK2FORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Mask2FormerForUniversalSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Mask2FormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Mask2FormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MASKFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MaskFormerForInstanceSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MaskFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MaskFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MaskFormerSwinBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MBartPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MCTCT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MCTCTForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MCTCTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MCTCTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MEGA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MegaForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MEGATRON_BERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MegatronBertForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MegatronBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MGP_STR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MgpstrForSceneTextRecognition(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MgpstrModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MgpstrPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MMBTForClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MMBTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ModalEmbeddings(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MobileBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_mobilebert(*args, **kwargs): + requires_backends(load_tf_weights_in_mobilebert, ["torch"]) + + +MOBILENET_V1_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MobileNetV1ForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileNetV1Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileNetV1PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_mobilenet_v1(*args, **kwargs): + requires_backends(load_tf_weights_in_mobilenet_v1, ["torch"]) + + +MOBILENET_V2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MobileNetV2ForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileNetV2ForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileNetV2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileNetV2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_mobilenet_v2(*args, **kwargs): + requires_backends(load_tf_weights_in_mobilenet_v2, ["torch"]) + + +MOBILEVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MobileViTForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileViTForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileViTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MobileViTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MPNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MPNetForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MPNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MT5EncoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MT5Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MT5PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +MVP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class MvpForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MvpForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MvpForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MvpForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MvpModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class MvpPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +NAT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class NatBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NatForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NatModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NatPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +NEZHA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class NezhaForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NezhaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +NLLB_MOE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class NllbMoeForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NllbMoeModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NllbMoePreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NllbMoeSparseMLP(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NllbMoeTop2Router(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +NYSTROMFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class NystromformerForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class NystromformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ONEFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class OneFormerForUniversalSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OneFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OneFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenLlamaForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenLlamaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenLlamaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenLlamaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class OpenAIGPTDoubleHeadsModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenAIGPTForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenAIGPTLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenAIGPTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OpenAIGPTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_openai_gpt(*args, **kwargs): + requires_backends(load_tf_weights_in_openai_gpt, ["torch"]) + + +OPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class OPTForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OPTForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OPTForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OPTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OPTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +OWLVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class OwlViTForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OwlViTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OwlViTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OwlViTTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class OwlViTVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +PEGASUS_X_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class PegasusXForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusXModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PegasusXPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +PERCEIVER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class PerceiverForImageClassificationConvProcessing(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForImageClassificationFourier(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForImageClassificationLearned(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForMultimodalAutoencoding(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForOpticalFlow(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PerceiverPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +PIX2STRUCT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Pix2StructForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Pix2StructPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Pix2StructTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Pix2StructVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +PLBART_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class PLBartForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PLBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PLBartForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PLBartModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PLBartPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +POOLFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class PoolFormerForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PoolFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class PoolFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +PROPHETNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ProphetNetDecoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ProphetNetEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ProphetNetForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ProphetNetForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ProphetNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ProphetNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +QDQBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class QDQBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class QDQBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_qdqbert(*args, **kwargs): + requires_backends(load_tf_weights_in_qdqbert, ["torch"]) + + +class RagModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RagPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RagSequenceForGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RagTokenForGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +REALM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RealmEmbedder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmForOpenQA(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmKnowledgeAugEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmReader(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmRetriever(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RealmScorer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_realm(*args, **kwargs): + requires_backends(load_tf_weights_in_realm, ["torch"]) + + +REFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ReformerAttention(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerModelWithLMHead(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ReformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +REGNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RegNetForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RegNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RegNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +REMBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RemBertForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RemBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_rembert(*args, **kwargs): + requires_backends(load_tf_weights_in_rembert, ["torch"]) + + +RESNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ResNetBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ResNetForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ResNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ResNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +RETRIBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RetriBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RetriBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RobertaForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ROBERTA_PRELAYERNORM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RobertaPreLayerNormForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RobertaPreLayerNormPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +ROC_BERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RoCBertForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoCBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_roc_bert(*args, **kwargs): + requires_backends(load_tf_weights_in_roc_bert, ["torch"]) + + +ROFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RoFormerForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RoFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_roformer(*args, **kwargs): + requires_backends(load_tf_weights_in_roformer, ["torch"]) + + +RWKV_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class RwkvForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RwkvModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class RwkvPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SAM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SamModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SamPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SegformerDecodeHead(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SegformerForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SegformerForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SegformerLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SegformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SegformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SEW_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SEWForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SEW_D_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SEWDForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWDForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWDModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SEWDPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechEncoderDecoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SPEECH_TO_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Speech2TextForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Speech2TextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Speech2TextPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Speech2Text2ForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Speech2Text2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SPEECHT5_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SpeechT5ForSpeechToSpeech(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechT5ForSpeechToText(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechT5ForTextToSpeech(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechT5HifiGan(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechT5Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SpeechT5PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SPLINTER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SplinterForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SplinterForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SplinterLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SplinterModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SplinterPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SQUEEZEBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SqueezeBertForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertModule(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SqueezeBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SWIN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SwinBackbone(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwinForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwinForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwinModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwinPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SWIN2SR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Swin2SRForImageSuperResolution(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Swin2SRModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Swin2SRPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SWINV2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Swinv2ForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Swinv2ForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Swinv2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Swinv2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +SWITCH_TRANSFORMERS_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class SwitchTransformersEncoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwitchTransformersForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwitchTransformersModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwitchTransformersPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwitchTransformersSparseMLP(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class SwitchTransformersTop1Router(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +T5_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class T5EncoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class T5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class T5Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class T5PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_t5(*args, **kwargs): + requires_backends(load_tf_weights_in_t5, ["torch"]) + + +TABLE_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TableTransformerForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TableTransformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TableTransformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TapasForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TapasForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TapasForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TapasModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TapasPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_tapas(*args, **kwargs): + requires_backends(load_tf_weights_in_tapas, ["torch"]) + + +TIME_SERIES_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TimeSeriesTransformerForPrediction(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TimeSeriesTransformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TimeSeriesTransformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +TIMESFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TimesformerForVideoClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TimesformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TimesformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +TRAJECTORY_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TrajectoryTransformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TrajectoryTransformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +TRANSFO_XL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class AdaptiveEmbedding(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TransfoXLForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TransfoXLLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TransfoXLModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TransfoXLPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_transfo_xl(*args, **kwargs): + requires_backends(load_tf_weights_in_transfo_xl, ["torch"]) + + +TROCR_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TrOCRForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TrOCRPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +TVLT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TvltForAudioVisualClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TvltForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TvltModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class TvltPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +UNISPEECH_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class UniSpeechForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +UNISPEECH_SAT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class UniSpeechSatForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatForXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UniSpeechSatPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UperNetForSemanticSegmentation(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class UperNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VAN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class VanForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VanModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VanPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VIDEOMAE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class VideoMAEForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VideoMAEForVideoClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VideoMAEModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VideoMAEPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VILT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ViltForImageAndTextRetrieval(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltForImagesAndTextClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViltPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisionEncoderDecoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisionTextDualEncoderModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VISUAL_BERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class VisualBertForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertForRegionToPhraseAlignment(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertForVisualReasoning(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class VisualBertPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ViTForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTForMaskedImageModeling(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ViTHybridForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTHybridModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTHybridPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VIT_MAE_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ViTMAEForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTMAELayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTMAEModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTMAEPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +VIT_MSN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class ViTMSNForImageClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTMSNModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class ViTMSNPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Wav2Vec2ForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ForXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2Model(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2PreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +WAV2VEC2_CONFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class Wav2Vec2ConformerForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerForPreTraining(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerForXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Wav2Vec2ConformerPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +WAVLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class WavLMForAudioFrameClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WavLMForCTC(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WavLMForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WavLMForXVector(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WavLMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WavLMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class WhisperForAudioClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WhisperForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WhisperModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class WhisperPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XCLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XCLIPModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XCLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XCLIPTextModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XCLIPVisionModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XGLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XGLMForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XGLMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XGLMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XLMForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMWithLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XLM_PROPHETNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XLMProphetNetDecoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMProphetNetEncoder(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMProphetNetForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMProphetNetForConditionalGeneration(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMProphetNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMProphetNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XLMRobertaForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XLM_ROBERTA_XL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XLMRobertaXLForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLMRobertaXLPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +XLNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XLNetForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetLMHeadModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XLNetPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def load_tf_weights_in_xlnet(*args, **kwargs): + requires_backends(load_tf_weights_in_xlnet, ["torch"]) + + +XMOD_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class XmodForCausalLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class XmodPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +YOLOS_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class YolosForObjectDetection(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YolosModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YolosPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +YOSO_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class YosoForMaskedLM(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoForMultipleChoice(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoForQuestionAnswering(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoForSequenceClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoForTokenClassification(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoLayer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class YosoPreTrainedModel(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class Adafactor(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +class AdamW(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def get_constant_schedule(*args, **kwargs): + requires_backends(get_constant_schedule, ["torch"]) + + +def get_constant_schedule_with_warmup(*args, **kwargs): + requires_backends(get_constant_schedule_with_warmup, ["torch"]) + + +def get_cosine_schedule_with_warmup(*args, **kwargs): + requires_backends(get_cosine_schedule_with_warmup, ["torch"]) + + +def get_cosine_with_hard_restarts_schedule_with_warmup(*args, **kwargs): + requires_backends(get_cosine_with_hard_restarts_schedule_with_warmup, ["torch"]) + + +def get_inverse_sqrt_schedule(*args, **kwargs): + requires_backends(get_inverse_sqrt_schedule, ["torch"]) + + +def get_linear_schedule_with_warmup(*args, **kwargs): + requires_backends(get_linear_schedule_with_warmup, ["torch"]) + + +def get_polynomial_decay_schedule_with_warmup(*args, **kwargs): + requires_backends(get_polynomial_decay_schedule_with_warmup, ["torch"]) + + +def get_scheduler(*args, **kwargs): + requires_backends(get_scheduler, ["torch"]) + + +class Conv1D(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def apply_chunking_to_forward(*args, **kwargs): + requires_backends(apply_chunking_to_forward, ["torch"]) + + +def prune_layer(*args, **kwargs): + requires_backends(prune_layer, ["torch"]) + + +class Trainer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) + + +def torch_distributed_zero_first(*args, **kwargs): + requires_backends(torch_distributed_zero_first, ["torch"]) + + +class Seq2SeqTrainer(metaclass=DummyObject): + _backends = ["torch"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["torch"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_and_tokenizers_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_and_tokenizers_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..38775330a81d91030f000e58c0e6035bba1c0f31 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_and_tokenizers_objects.py @@ -0,0 +1,9 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +SLOW_TO_FAST_CONVERTERS = None + + +def convert_slow_tokenizer(*args, **kwargs): + requires_backends(convert_slow_tokenizer, ["sentencepiece", "tokenizers"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..7e0f78d6c713d0ea5911929151d5080dd658d7f5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_sentencepiece_objects.py @@ -0,0 +1,219 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class AlbertTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class BarthezTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class BartphoTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class BertGenerationTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class BigBirdTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class CamembertTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class CpmTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class DebertaV2Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class ErnieMTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class FNetTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class GPTSw3Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class LayoutXLMTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class LlamaTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class M2M100Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class MarianTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class MBart50Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class MBartTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class MLukeTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class MT5Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class NllbTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class PegasusTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class PLBartTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class ReformerTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class RemBertTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class Speech2TextTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class SpeechT5Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class T5Tokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class XGLMTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class XLMProphetNetTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class XLMRobertaTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) + + +class XLNetTokenizer(metaclass=DummyObject): + _backends = ["sentencepiece"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["sentencepiece"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_speech_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_speech_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..f85182c8bc40ed5b65471f5c51c159823f63a909 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_speech_objects.py @@ -0,0 +1,37 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class ASTFeatureExtractor(metaclass=DummyObject): + _backends = ["speech"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["speech"]) + + +class MCTCTFeatureExtractor(metaclass=DummyObject): + _backends = ["speech"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["speech"]) + + +class Speech2TextFeatureExtractor(metaclass=DummyObject): + _backends = ["speech"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["speech"]) + + +class SpeechT5FeatureExtractor(metaclass=DummyObject): + _backends = ["speech"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["speech"]) + + +class TvltFeatureExtractor(metaclass=DummyObject): + _backends = ["speech"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["speech"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tensorflow_text_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tensorflow_text_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..70c7ad5cbf4077609e36592566e461c1a1ded28a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tensorflow_text_objects.py @@ -0,0 +1,9 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class TFBertTokenizer(metaclass=DummyObject): + _backends = ["tensorflow_text"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tensorflow_text"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tf_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tf_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..2a043f50f3500033ee2e4ec6ff9e07fd1fa6fd62 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tf_objects.py @@ -0,0 +1,2868 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class TensorFlowBenchmarkArguments(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TensorFlowBenchmark(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFForcedBOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFForcedEOSTokenLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGenerationMixin(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLogitsProcessorList(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLogitsWarper(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMinLengthLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFNoBadWordsLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFNoRepeatNGramLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRepetitionPenaltyLogitsProcessor(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTemperatureLogitsWarper(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTopKLogitsWarper(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTopPLogitsWarper(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +def tf_top_k_top_p_filtering(*args, **kwargs): + requires_backends(tf_top_k_top_p_filtering, ["tf"]) + + +class KerasMetricCallback(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class PushToHubCallback(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSequenceSummary(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSharedEmbeddings(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +def shape_list(*args, **kwargs): + requires_backends(shape_list, ["tf"]) + + +TF_ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFAlbertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAlbertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_MODEL_FOR_CAUSAL_LM_MAPPING = None + + +TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING = None + + +TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING = None + + +TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING = None + + +TF_MODEL_FOR_MASKED_LM_MAPPING = None + + +TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = None + + +TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING = None + + +TF_MODEL_FOR_PRETRAINING_MAPPING = None + + +TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING = None + + +TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING = None + + +TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING = None + + +TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = None + + +TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING = None + + +TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING = None + + +TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = None + + +TF_MODEL_FOR_VISION_2_SEQ_MAPPING = None + + +TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING = None + + +TF_MODEL_MAPPING = None + + +TF_MODEL_WITH_LM_HEAD_MAPPING = None + + +class TFAutoModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForDocumentQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForNextSentencePrediction(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForSemanticSegmentation(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForSeq2SeqLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForSpeechSeq2Seq(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForTableQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForVision2Seq(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelForZeroShotImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFAutoModelWithLMHead(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBartForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBartModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBartPretrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_BERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFBertEmbeddings(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotSmallForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotSmallModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlenderbotSmallPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_BLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFBlipForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipForImageTextRetrieval(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipTextModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFBlipVisionModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_CAMEMBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFCamembertForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCamembertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFCLIPModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCLIPPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCLIPTextModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCLIPVisionModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_CONVBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFConvBertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvBertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvNextForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvNextModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFConvNextPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_CTRL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFCTRLForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCTRLLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCTRLModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCTRLPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFCvtForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCvtModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFCvtPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFData2VecVisionForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFData2VecVisionForSemanticSegmentation(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFData2VecVisionModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFData2VecVisionPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFDebertaForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFDebertaV2ForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaV2ForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaV2ForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaV2ForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaV2Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDebertaV2PreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFDeiTForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDeiTForImageClassificationWithTeacher(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDeiTForMaskedImageModeling(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDeiTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDeiTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFDistilBertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDistilBertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFDPRContextEncoder(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDPRPretrainedContextEncoder(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDPRPretrainedQuestionEncoder(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDPRPretrainedReader(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDPRQuestionEncoder(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFDPRReader(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFElectraForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFElectraPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFEncoderDecoderModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +ESM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFEsmForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFEsmForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFEsmForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFEsmModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFEsmPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFFlaubertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFlaubertWithLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFFunnelBaseModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFFunnelPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_GPT2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFGPT2DoubleHeadsModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPT2ForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPT2LMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPT2MainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPT2Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPT2PreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPTJForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPTJForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPTJForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPTJModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGPTJPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFGroupViTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGroupViTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGroupViTTextModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFGroupViTVisionModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_HUBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFHubertForCTC(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFHubertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFHubertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFLayoutLMForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFLayoutLMv3ForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMv3ForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMv3ForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMv3Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLayoutLMv3PreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLEDForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLEDModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLEDPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_LONGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFLongformerForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLongformerSelfAttention(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_LXMERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFLxmertForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLxmertMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLxmertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLxmertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFLxmertVisualFeatureEncoder(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMarianModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMarianMTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMarianPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMBartForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMBartModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMBartPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFMobileBertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForNextSentencePrediction(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileBertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_MOBILEVIT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFMobileViTForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileViTForSemanticSegmentation(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileViTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMobileViTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_MPNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFMPNetForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMPNetPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMT5EncoderModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFMT5Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFOpenAIGPTDoubleHeadsModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOpenAIGPTForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOpenAIGPTLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOpenAIGPTMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOpenAIGPTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOpenAIGPTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOPTForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOPTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFOPTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFPegasusForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFPegasusModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFPegasusPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRagModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRagPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRagSequenceForGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRagTokenForGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_REGNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFRegNetForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRegNetModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRegNetPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_REMBERT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFRemBertForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRemBertPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_RESNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFResNetForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFResNetModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFResNetPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFRobertaForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_ROBERTA_PRELAYERNORM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFRobertaPreLayerNormForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRobertaPreLayerNormPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_ROFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFRoFormerForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFRoFormerPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFSegformerDecodeHead(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSegformerForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSegformerForSemanticSegmentation(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSegformerModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSegformerPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_SPEECH_TO_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFSpeech2TextForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSpeech2TextModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSpeech2TextPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFSwinForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSwinForMaskedImageModeling(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSwinModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFSwinPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_T5_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFT5EncoderModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFT5ForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFT5Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFT5PreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFTapasForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTapasForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTapasForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTapasModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTapasPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_TRANSFO_XL_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFAdaptiveEmbedding(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTransfoXLForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTransfoXLLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTransfoXLMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTransfoXLModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFTransfoXLPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFVisionEncoderDecoderModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFVisionTextDualEncoderModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTForImageClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTMAEForPreTraining(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTMAEModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFViTMAEPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_WAV_2_VEC_2_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFWav2Vec2ForCTC(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFWav2Vec2ForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFWav2Vec2Model(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFWav2Vec2PreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_WHISPER_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFWhisperForConditionalGeneration(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFWhisperModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFWhisperPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_XGLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFXGLMForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXGLMModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXGLMPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_XLM_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFXLMForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMWithLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_XLM_ROBERTA_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFXLMRobertaForCausalLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaForMaskedLM(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaForQuestionAnswering(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLMRobertaPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +TF_XLNET_PRETRAINED_MODEL_ARCHIVE_LIST = None + + +class TFXLNetForMultipleChoice(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetForQuestionAnsweringSimple(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetForSequenceClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetForTokenClassification(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetLMHeadModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetMainLayer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class TFXLNetPreTrainedModel(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class AdamWeightDecay(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class GradientAccumulator(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +class WarmUp(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) + + +def create_optimizer(*args, **kwargs): + requires_backends(create_optimizer, ["tf"]) + + +class TFTrainer(metaclass=DummyObject): + _backends = ["tf"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tf"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tokenizers_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tokenizers_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..5ab17d1348e5cb5d90d11d94c078d37d6c2563b1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_tokenizers_objects.py @@ -0,0 +1,408 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class AlbertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BartTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BarthezTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BigBirdTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BlenderbotTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BlenderbotSmallTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class BloomTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class CamembertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class CLIPTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class CodeGenTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class ConvBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class CpmTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DebertaTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DebertaV2TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DistilBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DPRContextEncoderTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DPRQuestionEncoderTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class DPRReaderTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class ElectraTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class FNetTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class FunnelTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class GPT2TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class GPTNeoXTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class GPTNeoXJapaneseTokenizer(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class HerbertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LayoutLMTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LayoutLMv2TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LayoutLMv3TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LayoutXLMTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LEDTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LlamaTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LongformerTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class LxmertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MarkupLMTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MBartTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MBart50TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MobileBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MPNetTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MT5TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class MvpTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class NllbTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class OpenAIGPTTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class PegasusTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class RealmTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class ReformerTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class RemBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class RetriBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class RobertaTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class RoFormerTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class SplinterTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class SqueezeBertTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class T5TokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class WhisperTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class XGLMTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class XLMRobertaTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class XLNetTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) + + +class PreTrainedTokenizerFast(metaclass=DummyObject): + _backends = ["tokenizers"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["tokenizers"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_vision_objects.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_vision_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..bfb3cdcaff5ac121f4a695c79dbc8e65de2de2d8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/dummy_vision_objects.py @@ -0,0 +1,513 @@ +# This file is autogenerated by the command `make fix-copies`, do not edit. +from ..utils import DummyObject, requires_backends + + +class ImageProcessingMixin(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ImageFeatureExtractionMixin(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class BeitFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class BeitImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class BitImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class BlipImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class BridgeTowerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ChineseCLIPFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ChineseCLIPImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class CLIPFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class CLIPImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ConditionalDetrFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ConditionalDetrImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ConvNextFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ConvNextImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DeformableDetrFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DeformableDetrImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DeiTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DeiTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DetaImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DetrFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DetrImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DonutFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DonutImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DPTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class DPTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class EfficientFormerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class EfficientNetImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class FlavaFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class FlavaImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class FlavaProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class GLPNFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class GLPNImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ImageGPTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ImageGPTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LayoutLMv2FeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LayoutLMv2ImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LayoutLMv3FeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LayoutLMv3ImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LevitFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class LevitImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class Mask2FormerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MaskFormerFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MaskFormerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileNetV1FeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileNetV1ImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileNetV2FeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileNetV2ImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileViTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class MobileViTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class OneFormerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class OwlViTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class OwlViTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class PerceiverFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class PerceiverImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class Pix2StructImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class PoolFormerFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class PoolFormerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class SamImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class SegformerFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class SegformerImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class Swin2SRImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class TvltImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class VideoMAEFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class VideoMAEImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViltFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViltImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViltProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViTFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViTImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class ViTHybridImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class YolosFeatureExtractor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) + + +class YolosImageProcessor(metaclass=DummyObject): + _backends = ["vision"] + + def __init__(self, *args, **kwargs): + requires_backends(self, ["vision"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/fx.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/fx.py new file mode 100644 index 0000000000000000000000000000000000000000..e82d44c80281420848d44942bfce84cf21e49d53 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/fx.py @@ -0,0 +1,1256 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import builtins +import collections +import functools +import inspect +import math +import operator +import os +import random +import warnings +from typing import Any, Callable, Dict, List, Optional, Type, Union + +import torch +from packaging import version +from torch import nn +from torch.fx import Graph, GraphModule, Proxy, Tracer +from torch.fx._compatibility import compatibility +from torch.fx.proxy import ParameterProxy + +from .. import PretrainedConfig, PreTrainedModel, logging +from ..models.auto import get_values +from ..models.auto.modeling_auto import ( + MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_BACKBONE_MAPPING_NAMES, + MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, + MODEL_FOR_CTC_MAPPING_NAMES, + MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES, + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES, + MODEL_FOR_MASKED_LM_MAPPING_NAMES, + MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES, + MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES, + MODEL_FOR_PRETRAINING_MAPPING_NAMES, + MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES, + MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES, + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES, + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES, + MODEL_MAPPING_NAMES, +) +from ..utils import ENV_VARS_TRUE_VALUES, TORCH_FX_REQUIRED_VERSION, is_peft_available, is_torch_fx_available +from ..utils.versions import importlib_metadata + + +if is_peft_available(): + from peft import PeftModel + + +logger = logging.get_logger(__name__) +_IS_IN_DEBUG_MODE = os.environ.get("FX_DEBUG_MODE", "").upper() in ENV_VARS_TRUE_VALUES + + +def _generate_supported_model_class_names( + model_name: Type[PretrainedConfig], + supported_tasks: Optional[Union[str, List[str]]] = None, +) -> List[str]: + task_mapping = { + "default": MODEL_MAPPING_NAMES, + "pretraining": MODEL_FOR_PRETRAINING_MAPPING_NAMES, + "next-sentence-prediction": MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES, + "masked-lm": MODEL_FOR_MASKED_LM_MAPPING_NAMES, + "causal-lm": MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, + "seq2seq-lm": MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES, + "speech-seq2seq": MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES, + "multiple-choice": MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES, + "document-question-answering": MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES, + "question-answering": MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES, + "sequence-classification": MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES, + "token-classification": MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES, + "masked-image-modeling": MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES, + "image-classification": MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES, + "zero-shot-image-classification": MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES, + "ctc": MODEL_FOR_CTC_MAPPING_NAMES, + "audio-classification": MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES, + "semantic-segmentation": MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES, + "backbone": MODEL_FOR_BACKBONE_MAPPING_NAMES, + } + + if supported_tasks is None: + supported_tasks = task_mapping.keys() + if isinstance(supported_tasks, str): + supported_tasks = [supported_tasks] + + model_class_names = [] + for task in supported_tasks: + class_name = task_mapping[task].get(model_name, None) + if class_name: + model_class_names.append(class_name) + + return model_class_names + + +_REGULAR_SUPPORTED_MODEL_NAMES_AND_TASKS = [ + "altclip", + "albert", + "bart", + "bert", + "blenderbot", + "blenderbot-small", + "bloom", + "clip", + "convnext", + "deberta", + "deberta-v2", + "distilbert", + "donut-swin", + "electra", + "gpt2", + "gpt_neo", + "gptj", + "hubert", + "layoutlm", + "lxmert", + "m2m_100", + "marian", + "mbart", + "megatron-bert", + "mobilebert", + "mt5", + "nezha", + "opt", + "pegasus", + "plbart", + "resnet", + "roberta", + "segformer", + "speech_to_text", + "speech_to_text_2", + "swin", + "t5", + "trocr", + "vit", + "xglm", + "wav2vec2", + # "xlnet", +] + +_REGULAR_SUPPORTED_MODELS = [] +for item in _REGULAR_SUPPORTED_MODEL_NAMES_AND_TASKS: + if isinstance(item, dict): + _REGULAR_SUPPORTED_MODELS.extend(_generate_supported_model_class_names(**item)) + else: + _REGULAR_SUPPORTED_MODELS.extend(_generate_supported_model_class_names(item)) + +_SPECIAL_SUPPORTED_MODELS = [ + "CLIPTextModel", + "CLIPTextModelWithProjection", + "CLIPVisionModel", + "CLIPVisionModelWithProjection", + "AltCLIPTextModel", + "AltCLIPVisionModel", + "GitVisionModel", + "GPT2DoubleHeadsModel", + "Speech2Text2Decoder", + "TrOCRDecoder", + "PeftModelForCausalLM", + "PeftModelForSeq2SeqLM" + # TODO: add support for them as it should be quite easy to do so (small blocking issues). + # XLNetForQuestionAnswering, +] +_SUPPORTED_MODELS = tuple(sorted(set(_REGULAR_SUPPORTED_MODELS + _SPECIAL_SUPPORTED_MODELS))) + + +def torch_nn_embedding(self, input): + return torch.empty(*input.shape, self.weight.shape[-1], device="meta", dtype=self.weight.dtype) + + +def torch_nn_functional_embedding( + input, weight, padding_idx=None, max_norm=None, norm_type=2.0, scale_grad_by_freq=False, sparse=False +): + return torch.empty(*input.shape, weight.shape[-1], device="meta", dtype=weight.dtype) + + +def torch_nn_layernorm(self, input): + return input + + +def torch_nn_groupnorm(self, input): + return input + + +def torch_nn_linear(self, input): + return torch.empty(input.shape[:-1] + (self.out_features,), device="meta") + + +def torch_relu(x): + return x + + +def torch_nn_relu(self, x): + return x + + +def torch_nn_functional_relu(x, inplace=False): + if not inplace: + raise ValueError("Don't support in-place functional.relu for MetaTensor analysis") + return x + + +def torch_where(condition, x, y): + # torch.where returns the broadcasted tensor of condition, x, and y, + # so hack it by using addition + return condition.to(device="meta") + x.to(device="meta") + y.to(device="meta") + + +def torch_abs(input, *, out=None): + if out is not None: + raise ValueError("Don't support in-place abs for MetaTensor analysis") + return input + + +def torch_arange(*args, **kwargs): + n = len(args) + step = 1 + if n == 1: + start = 0 + end = args[0] + elif n == 2: + start, end = args + else: + start, end, step = args + if isinstance(start, float): + start = int(start) + if isinstance(end, float): + start = int(end) + if isinstance(step, float): + step = int(step) + step = kwargs.get("step", step) + dtype = kwargs.get("dtype") + return torch.empty((end - start) // step, dtype=dtype, device="meta") + + +def torch_full(*args, **kwargs): + args = list(args) + if isinstance(args[1], torch.Tensor) and args[1].device == torch.device("meta"): + args[1] = 1 # Any value. + kwargs_without_device = dict(kwargs) + kwargs_without_device.pop("device", None) + return torch.full(*args, **kwargs_without_device) + + +def torch_cat(tensors, dim=None, axis=None, *, out=None): + if dim is None and axis is None: + dim = 0 + if dim is None and axis is not None: + dim = axis + if dim < 0: + dim = tensors[0].dim() + dim + shapes = [t.shape for t in tensors] + shape = list(shapes[0]) + concatenated_dim = sum(shape[dim] for shape in shapes) + final_shape = shape[:dim] + [concatenated_dim] + shape[dim + 1 :] + return torch.empty(final_shape, device="meta") + + +def torch_stack(tensors, dim=None, axis=None, *, out=None): + if dim is None and axis is None: + dim = 0 + if dim is None and axis is not None: + dim = axis + if dim < 0: + dim = tensors[0].dim() + 1 + dim + shape = list(tensors[0].shape) + shape.insert(dim, len(tensors)) + return torch.empty(shape, device="meta") + + +def torch_add(input, other, *, alpha=1, out=None): + if not isinstance(input, torch.Tensor): + return torch.empty_like(other, device="meta") + if not isinstance(other, torch.Tensor): + return torch.empty_like(input, device="meta") + max_length = max(input.dim(), other.dim()) + input_shape = list(input.shape) + [1] * (max_length - input.dim()) + other_shape = list(other.shape) + [1] * (max_length - other.dim()) + shape = [] + for i in range(max_length): + shape.append(max(input_shape[i], other_shape[i])) + return torch.empty(shape, device="meta") + + +def torch_mul(input, other, *, out=None): + return torch_add(input, other, out=out) + + +def torch_tensor_mul(self, other): + return torch_mul(self, other) + + +def torch_matmul(input, other, *, out=None): + d1 = input.dim() + d2 = other.dim() + shape = None + if d1 == 1 and d2 == 1: + shape = None + elif d1 == 2 and d2 == 2: + shape = (input.size(0), other.size(1)) + elif d1 == 1 and d2 == 2: + shape = (other.size(1),) + elif d1 == 2 and d1 == 1: + shape = (input.size(0),) + else: + max_length = max(input.dim(), other.dim()) + shape1 = list(input.shape) + shape2 = list(other.shape) + if d1 == 1: + shape1 = [1] + shape1 + if d2 == 1: + shape2.append(1) + shape1 = [-1] * (max_length - d1) + list(input.shape) + shape2 = [-1] * (max_length - d2) + list(other.shape) + shape = [] + for i in range(max_length): + shape.append(max(shape1[i], shape2[i])) + shape[-2] = shape1[-2] + shape[-1] = shape2[-1] + if d1 == 1: + shape.pop(-2) + if d2 == 1: + shape.pop(-1) + if shape is None: + return torch.tensor(0.0, device="meta") + return torch.empty(*shape, device="meta") + + +def torch_bmm(input, mat2, *, out=None): + if out is not None: + raise ValueError("Don't support in-place bmm for MetaTensor analysis") + batch_size, n, m = input.shape + _, _, p = mat2.shape + return torch.empty(batch_size, n, p, device="meta") + + +def torch_baddbmm(input, batch1, batch2, *, beta=1, alpha=1, out=None): + if out is not None: + raise ValueError("Don't support in-place baddbmm for MetaTensor analysis") + return torch_bmm(batch1, batch2) + + +def torch_tensor_baddbmm(self, batch1, batch2, *, beta=1, alpha=1, out=None): + return torch_baddbmm(self, batch1, batch2, beta=beta, alpha=alpha, out=out) + + +def torch_einsum(equation, *operands): + # TODO: infer shape without performing the computation, this might be quite hard. + concrete_operands = (torch.empty_like(operand, device="cpu") for operand in operands) + return torch.einsum(equation, *concrete_operands).to("meta") + + +def torch_tensor_repeat(self, *sizes): + shape = list(self.shape) + for i, x in enumerate(sizes): + shape[i] *= x + return torch.empty(shape, device="meta") + + +def torch_repeat_interleave(*args, dim=None, output_size=None): + num_args = len(args) + if num_args == 1: + shape = [output_size if output_size is not None else args[0].sum()] + else: + shape = list(args[0].shape) + if dim is None: + if num_args > 2: + dim = args[2] + else: + shape = [sum(shape)] + dim = 0 + repeats = args[1] + if isinstance(repeats, int) or torch.numel(repeats) == 1: + shape[dim] *= int(repeats) + else: + shape[dim] = output_size if output_size is not None else repeats.sum() + return torch.empty(*shape, device="meta") + + +def torch_index_select(input, dim, index, *, out=None): + shape = list(input.shape) + shape[dim] = len(index) + return torch.empty(*shape, device="meta") + + +def torch_tensor_index_select(self, dim, index): + return torch_index_select(self, dim, index) + + +def torch_gather(input, dim, index, *, sparse_grad=False, out=None): + shape = list(input.shape) + shape[dim] = index.shape[dim] + return torch.empty(*shape, device="meta") + + +def torch_tensor_gather(self, dim, index): + return torch_gather(self, dim, index) + + +def torch_roll(input, shifts, dims=None): + return input + + +def torch_flip(input, dims): + return input + + +def torch_tensor_flip(self, dims): + return self + + +def torch_nn_conv1d(self, input): + l_in = input.shape[-1] + shape = None + padding = self.padding + if padding == "valid": + padding = (0, 0) + if padding == "same": + shape = list(input.shape) + if shape is None: + shape = list(input.shape) + l_out = math.floor( + (l_in + 2 * padding[0] - self.dilation[0] * (self.kernel_size[0] - 1) - 1) / self.stride[0] + 1 + ) + shape[-1] = l_out + shape[-2] = self.out_channels + return torch.empty(shape, device="meta") + + +def torch_nn_conv2d(self, input): + h_in, w_in = input.shape[-2:] + shape = None + padding = self.padding + if padding == "valid": + padding = (0, 0) + if padding == "same": + shape = list(input.shape) + if shape is None: + shape = list(input.shape) + h_out = math.floor( + (h_in + 2 * padding[0] - self.dilation[0] * (self.kernel_size[0] - 1) - 1) / self.stride[0] + 1 + ) + w_out = math.floor( + (w_in + 2 * padding[1] - self.dilation[1] * (self.kernel_size[1] - 1) - 1) / self.stride[1] + 1 + ) + shape[-2:] = [h_out, w_out] + shape[-3] = self.out_channels + return torch.empty(shape, device="meta") + + +def torch_squeeze(input, dim=None): + shape = list(input.shape) + if dim is not None: + if dim < 0: + dim = input.dim() + dim + if shape[dim] == 1: + shape.pop(dim) + else: + new_shape = [] + for dim_value in shape: + if dim_value == 1: + continue + new_shape.append(dim_value) + shape = new_shape + return torch.empty(shape, device="meta") + + +def torch_tensor_squeeze(self, dim=None): + return torch_squeeze(self, dim) + + +def torch_unsqueeze(input, dim): + shape = list(input.shape) + if dim < 0: + dim = input.dim() + 1 + dim + shape.insert(dim, 1) + return torch.empty(shape, device="meta") + + +def torch_tensor_unsqueeze(self, dim): + return torch_unsqueeze(self, dim) + + +def torch_unique_consecutive(input, **kwargs): + output = torch.unique_consecutive(torch.zeros_like(input, device="cpu"), **kwargs) + if isinstance(output, torch.Tensor): + return output.to("meta") + else: + return tuple(map(output, lambda x: x.to("meta"))) + + +def torch_nn_functional_one_hot(tensor, num_classes=-1): + if num_classes < 0: + raise ValueError("Don't support automatic num_classes inference for MetaTensor analysis") + shape = list(tensor.shape) + [num_classes] + return torch.empty(shape, device="meta") + + +def torch_nn_mseloss(self, input, target): + if self.reduction == "none": + shape = target.shape + else: + shape = (1,) + return torch.empty(shape, device="meta") + + +def torch_nn_crossentropyloss(self, input, target): + if self.reduction == "none": + shape = target.shape + else: + shape = (1,) + return torch.empty(shape, device="meta") + + +def torch_nn_bcewithlogitsloss(self, input, target): + if self.reduction == "none": + shape = target.shape + else: + shape = (1,) + return torch.empty(shape, device="meta") + + +def operator_getitem(a, b): + def to_concrete(t): + if isinstance(t, torch.Tensor): + concrete = torch.ones_like(t, device="cpu") + if concrete.dtype in [torch.float16, torch.float32, torch.float64, torch.int32]: + concrete = concrete.to(torch.int64) + return concrete + return t + + if isinstance(a, torch.Tensor): + # TODO: infer shape without performing the computation. + if isinstance(b, tuple): + b = tuple(map(to_concrete, b)) + else: + b = to_concrete(b) + return operator.getitem(torch.empty_like(a, device="cpu"), b).to("meta") + return operator.getitem(a, b) + + +_MANUAL_META_OVERRIDES: Dict[Callable, Callable] = { + torch.nn.Embedding: torch_nn_embedding, + torch.nn.functional.embedding: torch_nn_functional_embedding, + torch.nn.LayerNorm: torch_nn_layernorm, + torch.nn.GroupNorm: torch_nn_groupnorm, + torch.nn.Linear: torch_nn_linear, + torch.relu: torch_relu, + torch.nn.functional.relu: torch_nn_functional_relu, + torch.nn.ReLU: torch_nn_relu, + torch.where: torch_where, + torch.abs: torch_abs, + torch.arange: torch_arange, + torch.full: torch_full, + torch.cat: torch_cat, + torch.stack: torch_stack, + torch.add: torch_add, + torch.mul: torch_mul, + torch.Tensor.mul: torch_tensor_mul, + torch.matmul: torch_matmul, + torch.bmm: torch_bmm, + torch.baddbmm: torch_baddbmm, + torch.Tensor.baddbmm: torch_tensor_baddbmm, + torch.einsum: torch_einsum, + torch.Tensor.repeat: torch_tensor_repeat, + torch.repeat_interleave: torch_repeat_interleave, + torch.roll: torch_roll, + torch.flip: torch_flip, + torch.Tensor.flip: torch_tensor_flip, + torch.index_select: torch_index_select, + torch.Tensor.index_select: torch_tensor_index_select, + torch.gather: torch_gather, + torch.Tensor.gather: torch_tensor_gather, + torch.nn.Conv1d: torch_nn_conv1d, + torch.nn.Conv2d: torch_nn_conv2d, + torch.squeeze: torch_squeeze, + torch.Tensor.squeeze: torch_tensor_squeeze, + torch.unsqueeze: torch_unsqueeze, + torch.Tensor.unsqueeze: torch_tensor_unsqueeze, + torch.unique_consecutive: torch_unique_consecutive, + torch.nn.functional.one_hot: torch_nn_functional_one_hot, + torch.nn.MSELoss: torch_nn_mseloss, + torch.nn.CrossEntropyLoss: torch_nn_crossentropyloss, + torch.nn.BCEWithLogitsLoss: torch_nn_bcewithlogitsloss, + operator.getitem: operator_getitem, +} + + +class HFProxy(Proxy): + """ + Proxy that uses metadata to handle data-dependent control-flow. + """ + + def install_metadata(self, metadata): + self._metadata = metadata + + @property + def shape(self): + return self.tracer.create_proxy("call_method", "size", (self,), {}) + + @property + def device(self): + # Hack so we can track when devices are used. During meta-tensor propagation, + # replace these values with a constant 'meta' + return MetaDeviceAttribute(self, "device") + + def __len__(self): + if hasattr(self, "_metadata") and self._metadata is not None: + return len(self._metadata) + return super().__len__() + + def __bool__(self): + if hasattr(self, "_metadata") and self._metadata is not None: + return self._metadata + return super().__bool__() + + def __getattr__(self, k): + if k == "_metadata": + return self.__getattribute__(k) + # note: not added to the graph yet, if this is a method call + # we peephole optimize to the method invocation + return HFAttribute(self, k) + + def __setitem__(self, indices, values): + return self.tracer.create_proxy("call_function", operator.setitem, (self, indices, values), {}) + + def __contains__(self, key): + if hasattr(self, "_metadata") and self._metadata is not None: + return key in self._metadata + return super().__contains__(key) + + +class HFAttribute(HFProxy): + def __init__(self, root, attr: str): + self.root = root + self.attr = attr + self.tracer = root.tracer + self._node = None + + if hasattr(self.root, "_metadata"): + self.install_metadata(getattr(self.root._metadata, attr)) + + @property + def node(self): + # the node for attributes is added lazily, since most will just be method calls + # which do not rely on the getitem call + if self._node is None: + self._node = self.tracer.create_proxy("call_function", builtins.getattr, (self.root, self.attr), {}).node + return self._node + + def __call__(self, *args, **kwargs): + return self.tracer.create_proxy("call_method", self.attr, (self.root,) + args, kwargs) + + +class MetaDeviceAttribute(HFAttribute): + pass + + +def _proxies_to_metas(v): + """Returns the underlying metadata for HFProxies, and behaves like the identity for the others.""" + if isinstance(v, MetaDeviceAttribute): + return "meta" + if isinstance(v, torch.fx.Proxy): + if not (isinstance(v, HFProxy) and hasattr(v, "_metadata")): + raise RuntimeError(f"No metadata was found for {v}") + return v._metadata + return v + + +def _gen_constructor_wrapper(target): + @functools.wraps(target) + def wrapper(*args, **kwargs): + proxy = None + + def check_has_proxy(v): + if isinstance(v, Proxy): + nonlocal proxy + proxy = v + + torch.fx.node.map_aggregate(args, check_has_proxy) + torch.fx.node.map_aggregate(kwargs, check_has_proxy) + + if proxy is not None: + return proxy.tracer.create_proxy("call_function", target, args, kwargs) + else: + return target(*args, **kwargs) + + return wrapper, target + + +def _generate_random_int(low: int = 10, high: int = 20, forbidden_values: Optional[List[int]] = None): + if forbidden_values is None: + forbidden_values = [] + value = random.randint(low, high) + while value in forbidden_values: + value = random.randint(low, high) + return value + + +class HFTracer(Tracer): + """ + Tracer that is able to symbolically trace models from the library. To do that, it uses the HFProxy instead of the + regular PyTorch torch.fx.Proxy. + """ + + # Feature flag for proxying accesses to buffer values + proxy_buffer_attributes: bool = True + allow_insert_stateless_mods: bool = True + _TORCH_METHODS_TO_PATCH = [ + "arange", + "zeros", + "ones", + "full", + "full_like", + "eye", + "empty", + "tensor", + "clamp", + "finfo", + ] + supported_archs = (PreTrainedModel,) if not is_peft_available() else (PreTrainedModel, PeftModel) + + def __init__(self, autowrap_modules=(math,), autowrap_functions=()): + super().__init__(autowrap_modules=autowrap_modules, autowrap_functions=autowrap_functions) + + if not is_torch_fx_available(): + torch_version = version.parse(importlib_metadata.version("torch")) + raise ImportError( + f"Found an incompatible version of torch. Found version {torch_version}, but only version " + f"{TORCH_FX_REQUIRED_VERSION} is supported." + ) + + def _generate_dummy_input( + self, model: PreTrainedModel, input_name: str, shape: List[int] + ) -> Dict[str, torch.Tensor]: + """Generates dummy input for model inference recording.""" + # Retrieving the model class, either from the "class_for_deserialization" attribute if the model was restored + # from pickle, or from the "__class__" attribute in the general case. + model_class_name = getattr(model, "class_for_deserialization", model.__class__).__name__ + device = model.device + inputs_dict = {} + + if input_name in ["labels", "start_positions", "end_positions"]: + batch_size = shape[0] + if model_class_name in [ + *get_values(MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES), + *get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES), + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_BACKBONE_MAPPING_NAMES), + *get_values(MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES), + ]: + inputs_dict["labels"] = torch.zeros(batch_size, dtype=torch.long, device=device) + elif model_class_name in [ + *get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES), + *get_values(MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES), + "XLNetForQuestionAnswering", + ]: + inputs_dict["start_positions"] = torch.zeros(batch_size, dtype=torch.long, device=device) + inputs_dict["end_positions"] = torch.zeros(batch_size, dtype=torch.long, device=device) + elif model_class_name in get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES): + if not hasattr(model.config, "problem_type") or model.config.problem_type is None: + raise ValueError( + "Could not retrieve the problem type for the sequence classification task, please set " + 'model.config.problem_type to one of the following values: "regression", ' + '"single_label_classification", or "multi_label_classification".' + ) + + if model.config.problem_type == "regression": + labels_shape = (batch_size, model.config.num_labels) + labels_dtype = torch.float32 + elif model.config.problem_type == "single_label_classification": + labels_shape = (batch_size,) + labels_dtype = torch.long + elif model.config.problem_type == "multi_label_classification": + labels_shape = (batch_size, model.config.num_labels) + labels_dtype = torch.float32 + else: + raise ValueError( + 'Expected model.config.problem_type to be either: "regression", "single_label_classification"' + f', or "multi_label_classification", but "{model.config.problem_type}" was provided.' + ) + inputs_dict["labels"] = torch.zeros(*labels_shape, dtype=labels_dtype, device=device) + + elif model_class_name in [ + *get_values(MODEL_FOR_PRETRAINING_MAPPING_NAMES), + *get_values(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_CAUSAL_LM_MAPPING_NAMES), + *get_values(MODEL_FOR_MASKED_LM_MAPPING_NAMES), + *get_values(MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES), + *get_values(MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES), + "GPT2DoubleHeadsModel", + "PeftModelForCausalLM", + "PeftModelForSeq2SeqLM", + ]: + inputs_dict["labels"] = torch.zeros(shape, dtype=torch.long, device=device) + elif model_class_name in [*get_values(MODEL_FOR_CTC_MAPPING_NAMES)]: + inputs_dict["labels"] = torch.zeros(shape, dtype=torch.float32, device=device) + else: + raise NotImplementedError( + f"Generating the dummy input named {input_name} for {model_class_name} is not supported yet." + ) + elif "pixel_values" in input_name: + batch_size = shape[0] + image_size = getattr(model.config, "image_size", None) + if image_size is None: + if hasattr(model.config, "vision_config"): + image_size = model.config.vision_config.image_size + elif hasattr(model.config, "encoder"): + image_size = model.config.encoder.image_size + else: + image_size = (_generate_random_int(), _generate_random_int()) + + # If no num_channels is in the config, use some arbitrary value. + num_channels = getattr(model.config, "num_channels", 3) + if not isinstance(image_size, collections.abc.Iterable): + image_size = (image_size, image_size) + height, width = image_size + inputs_dict[input_name] = torch.zeros( + batch_size, num_channels, height, width, dtype=torch.float32, device=device + ) + elif "bbox" in input_name: + inputs_dict[input_name] = torch.zeros(*shape, 4, dtype=torch.float, device=device) + elif "input_features" in input_name: + inputs_dict[input_name] = torch.zeros( + *shape, model.config.input_feat_per_channel, dtype=torch.float, device=device + ) + elif "visual_feats" in input_name: + inputs_dict[input_name] = torch.zeros( + shape + + [ + model.config.visual_feat_dim, + ], + dtype=torch.float, + device=device, + ) + elif "visual_pos" in input_name: + inputs_dict[input_name] = torch.zeros( + shape + + [ + model.config.visual_pos_dim, + ], + dtype=torch.float, + device=device, + ) + elif "inputs" in input_name: + inputs_dict[input_name] = torch.zeros(*shape, dtype=torch.float, device=device) + elif "input_values" in input_name: + batch_size, _ = shape + # Generating big sequence length for audio inputs. + seq_length = _generate_random_int(low=10000, high=20000) + inputs_dict[input_name] = torch.zeros(batch_size, seq_length, dtype=torch.float, device=device) + elif "mask" in input_name or "ids" in input_name: + inputs_dict[input_name] = torch.zeros(shape, dtype=torch.long, device=device) + else: + shape_with_hidden_size = shape + [model.config.hidden_size] + inputs_dict[input_name] = torch.zeros(shape_with_hidden_size, dtype=torch.float, device=device) + + return inputs_dict + + def create_proxy(self, kind, target, args, kwargs, name=None, type_expr=None, proxy_factory_fn=None): + rv = super().create_proxy(kind, target, args, kwargs, name, type_expr, proxy_factory_fn) + + if kind == "placeholder" and target in self.meta_args: + rv.install_metadata(self.meta_args[target]) + return rv + + if target in self.orig_fns: + # NOTE: tensor constructors in PyTorch define the `device` argument as + # *kwargs-only*. That is why this works. If you add methods to + # _TORCH_METHODS_TO_PATCH that do not define `device` as kwarg-only, + # this will break and you will likely see issues where we cannot infer + # the size of the output. + if "device" in kwargs: + kwargs["device"] = "meta" + + try: + args_metas = torch.fx.node.map_aggregate(args, _proxies_to_metas) + kwargs_metas = torch.fx.node.map_aggregate(kwargs, _proxies_to_metas) + + if kind == "call_function": + meta_target = _MANUAL_META_OVERRIDES.get(target, target) + meta_out = meta_target(*args_metas, **kwargs_metas) + if isinstance(meta_out, torch.Tensor): + meta_out = meta_out.to(device="meta") + elif kind == "call_method": + method = getattr(args_metas[0].__class__, target) + meta_target = _MANUAL_META_OVERRIDES.get(method, method) + meta_out = meta_target(*args_metas, **kwargs_metas) + elif kind == "call_module": + if not hasattr(self, "orig_forward"): + raise AttributeError(f"{self} does not have an attribute called orig_forward") + self._disable_module_getattr = True + try: + mod = self.root.get_submodule(target) + mod_type = type(mod) + if mod_type in _MANUAL_META_OVERRIDES: + meta_out = _MANUAL_META_OVERRIDES[mod_type](mod, *args_metas, **kwargs_metas) + else: + meta_out = self.orig_forward(*args_metas, **kwargs_metas) + finally: + self._disable_module_getattr = False + elif kind == "get_attr": + self._disable_module_getattr = True + try: + attr_itr = self.root + atoms = target.split(".") + for atom in atoms: + attr_itr = getattr(attr_itr, atom) + if isinstance(attr_itr, torch.Tensor): + meta_out = attr_itr.to(device="meta") + else: + meta_out = attr_itr + finally: + self._disable_module_getattr = False + else: + return rv + + if not isinstance(rv, Proxy): + raise ValueError("Don't support composite output yet") + rv.install_metadata(meta_out) + except Exception as e: + if _IS_IN_DEBUG_MODE: + warnings.warn(f"Could not compute metadata for {kind} target {target}: {e}") + + return rv + + # Replaced by .getattr from PyTorch 1.13 + def _module_getattr(self, attr, attr_val, parameter_proxy_cache): + if getattr(self, "_disable_module_getattr", False): + return attr_val + else: + + def maybe_get_proxy_for_attr(attr_val, collection_to_search, parameter_proxy_cache): + for n, p in collection_to_search: + if attr_val is p: + if n not in parameter_proxy_cache: + kwargs = {} + if "proxy_factory_fn" in inspect.signature(self.create_proxy).parameters: + kwargs["proxy_factory_fn"] = ( + None + if not self.param_shapes_constant + else lambda node: ParameterProxy(self, node, n, attr_val) + ) + val_proxy = self.create_proxy("get_attr", n, (), {}, **kwargs) # type: ignore[arg-type] + parameter_proxy_cache[n] = val_proxy + return parameter_proxy_cache[n] + return None + + if isinstance(attr_val, torch.nn.Parameter): + maybe_parameter_proxy = maybe_get_proxy_for_attr( + attr_val, self.root.named_parameters(), parameter_proxy_cache + ) + if maybe_parameter_proxy is not None: + return maybe_parameter_proxy + + if self.proxy_buffer_attributes and isinstance(attr_val, torch.Tensor): + maybe_buffer_proxy = maybe_get_proxy_for_attr( + attr_val, self.root.named_buffers(), parameter_proxy_cache + ) + if maybe_buffer_proxy is not None: + return maybe_buffer_proxy + + return attr_val + + # Needed for PyTorch 1.13+ + def getattr(self, attr: str, attr_val: Any, parameter_proxy_cache: Dict[str, Any]): + return self._module_getattr(attr, attr_val, parameter_proxy_cache) + + def call_module(self, m, forward, args, kwargs): + self.orig_forward = forward + return super().call_module(m, forward, args, kwargs) + + def proxy(self, node): + return HFProxy(node, self) + + def trace( + self, + root: Union[torch.nn.Module, Callable[..., Any]], + concrete_args: Optional[Dict[str, Any]] = None, + dummy_inputs: Optional[Dict[str, Any]] = None, + complete_concrete_args_with_inputs_not_in_dummy_inputs: bool = True, + ) -> Graph: + """ + Traces `root` and returns the corresponding FX `torch.fx.Graph` representation. `root` can either be a + `torch.nn.Module` instance or a Python callable. Note that after this call, `self.root` may be different from + the `root` passed in here. For example, when a free function is passed to `trace()`, we will create a + `torch.nn.Module` instance to use as the root and add embedded constants to. + + Args: + root (`torch.nn.Module` or `Callable`): + Either a `torch.nn.Module`` or a function to be traced through. If root is not a + [`~transformers.PreTrainedModel`], then `dummy_inputs` must be passed, otherwise tracing will fail. + concrete_args (`Dict[str, Any], *optional*): + Concrete arguments that should not be treated as Proxies + dummy_inputs (`Dict[str, Any]`, *optional*): + The dummy inputs needed to handle data-dependent control-flow if `root` is not a + [`~transformers.PreTrainedModel`]. It can also be used when `root` is a + [`~transformers.PreTrainedModel`] to specify custom dummy inputs for a subset or all the model inputs. + complete_concrete_args_with_inputs_not_in_dummy_inputs (`bool`, *optional*, defaults to `True`): + If `True`, and `dummy_inputs` is specified, every argument that `root` can take that is not in + `dummy_inputs` and not in `concrete_args` will be added to `concrete_args`, otherwise does nothing. + + Returns: + `torch.fx.Graph`: + A FX `torch.fx.Graph` representing the semantics of the passed-in `root`. + + """ + sig = inspect.signature(root.forward if isinstance(root, torch.nn.Module) else root) + + if concrete_args is None: + concrete_args = {} + + if dummy_inputs is not None and complete_concrete_args_with_inputs_not_in_dummy_inputs: + for param in sig.parameters.values(): + if param.name in dummy_inputs: + continue + if param.default is inspect.Parameter.empty: + raise ValueError(f"You need to specify a default value for the parameter {param.name}.") + concrete_args.update( + { + p.name: p.default + for p in sig.parameters.values() + if (p.name not in dummy_inputs and p.name not in concrete_args) + } + ) + + input_names = sig.parameters.keys() - concrete_args.keys() + + # Creating a random input shape to generate dummy inputs. + batch_size = _generate_random_int() + sequence_length = _generate_random_int() + shape = [batch_size, sequence_length] + + if root.__class__.__name__ in get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES): + num_choices = _generate_random_int(low=2, high=5) + shape.insert(1, num_choices) + + inputs = dict(dummy_inputs) if dummy_inputs is not None else {} + for input_name in input_names: + if input_name in inputs: + continue + # We enforce that root must either be a PreTrainedModel or deserialized from a serialized traced model to + # be able to use HFTracer._generate_dummy_input. + if isinstance(root, self.supported_archs) or type(root).__qualname__.startswith( + "_deserialize_graph_module" + ): + inputs.update(self._generate_dummy_input(root, input_name, shape)) + else: + raise RuntimeError( + f"Could not generate input named {input_name} for because root is not a" + " transformers.PreTrainedModel." + ) + + concrete_metas = { + input_name: input_.to("meta") if isinstance(input_, torch.Tensor) else input_ + for input_name, input_ in inputs.items() + } + for param in sig.parameters.values(): + if param.kind == inspect.Parameter.VAR_KEYWORD and param.name not in input_names: + concrete_metas[f"**{param.name}"] = {} + self.meta_args = concrete_metas + self.patched_torch_methods = { + target: _gen_constructor_wrapper(getattr(torch, target)) for target in self._TORCH_METHODS_TO_PATCH + } + self.orig_fns = set() + + for name, (wrapper, orig) in self.patched_torch_methods.items(): + setattr(torch, name, wrapper) + self.orig_fns.add(orig) + + try: + self.graph = super().trace(root, concrete_args=concrete_args) + finally: + for name, (_, orig) in self.patched_torch_methods.items(): + setattr(torch, name, orig) + + # This is necessary because concrete args are added as input to the traced module since + # https://github.com/pytorch/pytorch/pull/55888. + for node in self.graph.nodes: + if node.op == "placeholder": + # Removing default values for inputs as the forward pass will fail with them. + if node.target in input_names: + node.args = () + # Without this, torch.jit.script fails because the inputs type is Optional[torch.Tensor]. + # It cannot infer on the attributes and methods the input should have, and fails. + node.type = torch.Tensor + # It is a concrete arg so it is not used and should be removed. + else: + to_visit = [node] + to_delete = collections.OrderedDict() + while to_visit: + n = to_visit.pop(0) + to_delete[n] = None + to_visit += list(n.users.keys()) + + for user in reversed(to_delete.keys()): + self.graph.erase_node(user) + + # TODO: solves GraphModule creation. + # Without this, return type annotation "Tuple" is causing code execution failure. + if node.op == "output": + node.type = None + + return self.graph + + def _stateless_mod_instanciation_depends_on_proxies(self, mod: nn.Module) -> bool: + """ + Whether the module was instantiated with Proxies. If that is the case, such module cannot be a leaf module + because its attributes are input-dependent. + """ + return any(isinstance(attr, Proxy) for attr in mod.__dict__.values()) + + def _insert_module_as_submodule(self, mod: nn.Module) -> str: + """ + Helper method which tries to insert a module that was not declared as submodule. + """ + # If one of the module attributes is a Proxy, it means that its instantiation is input-dependent. + # It is not possible to insert such modules, those should be traced through. + if self._stateless_mod_instanciation_depends_on_proxies(mod): + return "" + idx = 0 + mod_name = mod.__class__.__name__.lower() + path = f"{mod_name}_{idx}" + already_inserted = False + while hasattr(self.root, path): + if getattr(self.root, path) is mod: + already_inserted = True + break + path = f"{mod_name}_{idx}" + idx += 1 + + # No need to add multiple instances of the same module. + if not already_inserted: + self.root.add_module(path, mod) + return path + + def path_of_module(self, mod: nn.Module) -> str: + """ + Helper method to find the qualified name of `mod` in the Module hierarchy of `root`. For example, if `root` has + a submodule named `foo`, which has a submodule named `bar`, passing `bar` into this function will return the + string "foo.bar". + + Args: + mod (str): The `Module` to retrieve the qualified name for. + """ + try: + return super().path_of_module(mod) + except NameError as e: + if self.allow_insert_stateless_mods and len(list(mod.parameters())) == 0 and len(list(mod.buffers())) == 0: + path = self._insert_module_as_submodule(mod) + return path + raise e + + def is_leaf_module(self, m: torch.nn.Module, module_qualified_name: str) -> bool: + return (not self._stateless_mod_instanciation_depends_on_proxies(m)) and super().is_leaf_module( + m, module_qualified_name + ) + + @compatibility(is_backward_compatible=True) + def keys(self, obj: "Proxy") -> Any: + """Called when a proxy object is has the keys() method called. + This is what happens when ** is called on a proxy. This should return an iterator if ** is supposed to work in + your custom tracer. + """ + attribute = HFAttribute(obj, "keys")() + if obj.node.target == "**kwargs": + return attribute._metadata + return attribute + + +def get_concrete_args(model: nn.Module, input_names: List[str]): + sig = inspect.signature(model.forward) + + if not (set(input_names) <= set(sig.parameters.keys())): + formatted_input_names = input_names[0] if len(input_names) == 1 else ", ".join(input_names) + formatted_allowed_input_names = ", ".join(sig.parameters.keys()) + raise ValueError( + f"The model does not have input(s) named: {formatted_input_names}, expected a subset of the following:" + f" {formatted_allowed_input_names}" + ) + + return {p.name: p.default for p in sig.parameters.values() if p.name not in input_names} + + +def check_if_model_is_supported(model: PreTrainedModel): + if model.__class__.__name__ not in _SUPPORTED_MODELS: + supported_model_names = ", ".join(_SUPPORTED_MODELS) + raise NotImplementedError( + f"Model {model.__class__.__name__} is not supported yet, supported models: {supported_model_names}" + ) + + +def symbolic_trace( + model: PreTrainedModel, + input_names: Optional[List[str]] = None, + disable_check: bool = False, + tracer_cls: Type[HFTracer] = HFTracer, +) -> GraphModule: + """ + Performs symbolic tracing on the model. + + Args: + model ([`PretrainedModel`]): + The model to trace. + input_names (`List[str]`, *optional*): + The names of the inputs of the traced model. If unset, model.dummy_inputs.keys() are used instead. + disable_check (`bool`, *optional*, defaults to `False`): + If `True`, no check is done before trying to trace the model, this is mostly usesul for debugging purposes. + tracer_cls (`Type[HFTracer]`, *optional*, defaults to `HFTracer`): + The tracer class to use for instantiating the tracer. If unset, `HFTracer` is used instead. + + Returns: + `torch.fx.GraphModule`: A GraphModule constructed by recording operations seen while tracing the model. + + Example: + + ```python + from transformers.utils.fx import symbolic_trace + + traced_model = symbolic_trace(model, input_names=["input_ids", "attention_mask", "token_type_ids"]) + ``` + """ + if input_names is None: + input_names = model.dummy_inputs.keys() + + input_names = list(input_names) + concrete_args = get_concrete_args(model, input_names) + + if not disable_check: + check_if_model_is_supported(model) + + # Tracing. + tracer = tracer_cls() + traced_graph = tracer.trace(model, concrete_args=concrete_args) + traced = torch.fx.GraphModule(model, traced_graph) + + traced.config = model.config + # The model class must be stored as an attribute to allow model deserialization, which uses trace, and thus + # _generate_dummy_input, where the model class is needed. + traced.class_for_deserialization = model.__class__ + traced.device = model.device + + return traced diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/generic.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/generic.py new file mode 100644 index 0000000000000000000000000000000000000000..23214db8f8591f1addbcf8483af49be55135a30d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/generic.py @@ -0,0 +1,567 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Generic utilities +""" + +import inspect +import tempfile +from collections import OrderedDict, UserDict +from collections.abc import MutableMapping +from contextlib import ExitStack, contextmanager +from dataclasses import fields +from enum import Enum +from typing import Any, ContextManager, List, Tuple + +import numpy as np + +from .import_utils import is_flax_available, is_tf_available, is_torch_available, is_torch_fx_proxy + + +if is_flax_available(): + import jax.numpy as jnp + + +class cached_property(property): + """ + Descriptor that mimics @property but caches output in member variable. + + From tensorflow_datasets + + Built-in in functools from Python 3.8. + """ + + def __get__(self, obj, objtype=None): + # See docs.python.org/3/howto/descriptor.html#properties + if obj is None: + return self + if self.fget is None: + raise AttributeError("unreadable attribute") + attr = "__cached_" + self.fget.__name__ + cached = getattr(obj, attr, None) + if cached is None: + cached = self.fget(obj) + setattr(obj, attr, cached) + return cached + + +# vendored from distutils.util +def strtobool(val): + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. + Raises ValueError if 'val' is anything else. + """ + val = val.lower() + if val in {"y", "yes", "t", "true", "on", "1"}: + return 1 + if val in {"n", "no", "f", "false", "off", "0"}: + return 0 + raise ValueError(f"invalid truth value {val!r}") + + +def is_tensor(x): + """ + Tests if `x` is a `torch.Tensor`, `tf.Tensor`, `jaxlib.xla_extension.DeviceArray` or `np.ndarray`. + """ + if is_torch_fx_proxy(x): + return True + if is_torch_available(): + import torch + + if isinstance(x, torch.Tensor): + return True + if is_tf_available(): + import tensorflow as tf + + if isinstance(x, tf.Tensor): + return True + + if is_flax_available(): + import jax.numpy as jnp + from jax.core import Tracer + + if isinstance(x, (jnp.ndarray, Tracer)): + return True + + return isinstance(x, np.ndarray) + + +def _is_numpy(x): + return isinstance(x, np.ndarray) + + +def is_numpy_array(x): + """ + Tests if `x` is a numpy array or not. + """ + return _is_numpy(x) + + +def _is_torch(x): + import torch + + return isinstance(x, torch.Tensor) + + +def is_torch_tensor(x): + """ + Tests if `x` is a torch tensor or not. Safe to call even if torch is not installed. + """ + return False if not is_torch_available() else _is_torch(x) + + +def _is_torch_device(x): + import torch + + return isinstance(x, torch.device) + + +def is_torch_device(x): + """ + Tests if `x` is a torch device or not. Safe to call even if torch is not installed. + """ + return False if not is_torch_available() else _is_torch_device(x) + + +def _is_torch_dtype(x): + import torch + + if isinstance(x, str): + if hasattr(torch, x): + x = getattr(torch, x) + else: + return False + return isinstance(x, torch.dtype) + + +def is_torch_dtype(x): + """ + Tests if `x` is a torch dtype or not. Safe to call even if torch is not installed. + """ + return False if not is_torch_available() else _is_torch_dtype(x) + + +def _is_tensorflow(x): + import tensorflow as tf + + return isinstance(x, tf.Tensor) + + +def is_tf_tensor(x): + """ + Tests if `x` is a tensorflow tensor or not. Safe to call even if tensorflow is not installed. + """ + return False if not is_tf_available() else _is_tensorflow(x) + + +def _is_tf_symbolic_tensor(x): + import tensorflow as tf + + # the `is_symbolic_tensor` predicate is only available starting with TF 2.14 + if hasattr(tf, "is_symbolic_tensor"): + return tf.is_symbolic_tensor(x) + return type(x) == tf.Tensor + + +def is_tf_symbolic_tensor(x): + """ + Tests if `x` is a tensorflow symbolic tensor or not (ie. not eager). Safe to call even if tensorflow is not + installed. + """ + return False if not is_tf_available() else _is_tf_symbolic_tensor(x) + + +def _is_jax(x): + import jax.numpy as jnp # noqa: F811 + + return isinstance(x, jnp.ndarray) + + +def is_jax_tensor(x): + """ + Tests if `x` is a Jax tensor or not. Safe to call even if jax is not installed. + """ + return False if not is_flax_available() else _is_jax(x) + + +def to_py_obj(obj): + """ + Convert a TensorFlow tensor, PyTorch tensor, Numpy array or python list to a python list. + """ + if isinstance(obj, (dict, UserDict)): + return {k: to_py_obj(v) for k, v in obj.items()} + elif isinstance(obj, (list, tuple)): + return [to_py_obj(o) for o in obj] + elif is_tf_tensor(obj): + return obj.numpy().tolist() + elif is_torch_tensor(obj): + return obj.detach().cpu().tolist() + elif is_jax_tensor(obj): + return np.asarray(obj).tolist() + elif isinstance(obj, (np.ndarray, np.number)): # tolist also works on 0d np arrays + return obj.tolist() + else: + return obj + + +def to_numpy(obj): + """ + Convert a TensorFlow tensor, PyTorch tensor, Numpy array or python list to a Numpy array. + """ + if isinstance(obj, (dict, UserDict)): + return {k: to_numpy(v) for k, v in obj.items()} + elif isinstance(obj, (list, tuple)): + return np.array(obj) + elif is_tf_tensor(obj): + return obj.numpy() + elif is_torch_tensor(obj): + return obj.detach().cpu().numpy() + elif is_jax_tensor(obj): + return np.asarray(obj) + else: + return obj + + +class ModelOutput(OrderedDict): + """ + Base class for all model outputs as dataclass. Has a `__getitem__` that allows indexing by integer or slice (like a + tuple) or strings (like a dictionary) that will ignore the `None` attributes. Otherwise behaves like a regular + python dictionary. + + + + You can't unpack a `ModelOutput` directly. Use the [`~utils.ModelOutput.to_tuple`] method to convert it to a tuple + before. + + + """ + + def __post_init__(self): + class_fields = fields(self) + + # Safety and consistency checks + if not len(class_fields): + raise ValueError(f"{self.__class__.__name__} has no fields.") + if not all(field.default is None for field in class_fields[1:]): + raise ValueError(f"{self.__class__.__name__} should not have more than one required field.") + + first_field = getattr(self, class_fields[0].name) + other_fields_are_none = all(getattr(self, field.name) is None for field in class_fields[1:]) + + if other_fields_are_none and not is_tensor(first_field): + if isinstance(first_field, dict): + iterator = first_field.items() + first_field_iterator = True + else: + try: + iterator = iter(first_field) + first_field_iterator = True + except TypeError: + first_field_iterator = False + + # if we provided an iterator as first field and the iterator is a (key, value) iterator + # set the associated fields + if first_field_iterator: + for idx, element in enumerate(iterator): + if ( + not isinstance(element, (list, tuple)) + or not len(element) == 2 + or not isinstance(element[0], str) + ): + if idx == 0: + # If we do not have an iterator of key/values, set it as attribute + self[class_fields[0].name] = first_field + else: + # If we have a mixed iterator, raise an error + raise ValueError( + f"Cannot set key/value for {element}. It needs to be a tuple (key, value)." + ) + break + setattr(self, element[0], element[1]) + if element[1] is not None: + self[element[0]] = element[1] + elif first_field is not None: + self[class_fields[0].name] = first_field + else: + for field in class_fields: + v = getattr(self, field.name) + if v is not None: + self[field.name] = v + + def __delitem__(self, *args, **kwargs): + raise Exception(f"You cannot use ``__delitem__`` on a {self.__class__.__name__} instance.") + + def setdefault(self, *args, **kwargs): + raise Exception(f"You cannot use ``setdefault`` on a {self.__class__.__name__} instance.") + + def pop(self, *args, **kwargs): + raise Exception(f"You cannot use ``pop`` on a {self.__class__.__name__} instance.") + + def update(self, *args, **kwargs): + raise Exception(f"You cannot use ``update`` on a {self.__class__.__name__} instance.") + + def __getitem__(self, k): + if isinstance(k, str): + inner_dict = dict(self.items()) + return inner_dict[k] + else: + return self.to_tuple()[k] + + def __setattr__(self, name, value): + if name in self.keys() and value is not None: + # Don't call self.__setitem__ to avoid recursion errors + super().__setitem__(name, value) + super().__setattr__(name, value) + + def __setitem__(self, key, value): + # Will raise a KeyException if needed + super().__setitem__(key, value) + # Don't call self.__setattr__ to avoid recursion errors + super().__setattr__(key, value) + + def to_tuple(self) -> Tuple[Any]: + """ + Convert self to a tuple containing all the attributes/keys that are not `None`. + """ + return tuple(self[k] for k in self.keys()) + + +class ExplicitEnum(str, Enum): + """ + Enum with more explicit error message for missing values. + """ + + @classmethod + def _missing_(cls, value): + raise ValueError( + f"{value} is not a valid {cls.__name__}, please select one of {list(cls._value2member_map_.keys())}" + ) + + +class PaddingStrategy(ExplicitEnum): + """ + Possible values for the `padding` argument in [`PreTrainedTokenizerBase.__call__`]. Useful for tab-completion in an + IDE. + """ + + LONGEST = "longest" + MAX_LENGTH = "max_length" + DO_NOT_PAD = "do_not_pad" + + +class TensorType(ExplicitEnum): + """ + Possible values for the `return_tensors` argument in [`PreTrainedTokenizerBase.__call__`]. Useful for + tab-completion in an IDE. + """ + + PYTORCH = "pt" + TENSORFLOW = "tf" + NUMPY = "np" + JAX = "jax" + + +class ContextManagers: + """ + Wrapper for `contextlib.ExitStack` which enters a collection of context managers. Adaptation of `ContextManagers` + in the `fastcore` library. + """ + + def __init__(self, context_managers: List[ContextManager]): + self.context_managers = context_managers + self.stack = ExitStack() + + def __enter__(self): + for context_manager in self.context_managers: + self.stack.enter_context(context_manager) + + def __exit__(self, *args, **kwargs): + self.stack.__exit__(*args, **kwargs) + + +def can_return_loss(model_class): + """ + Check if a given model can return loss. + + Args: + model_class (`type`): The class of the model. + """ + base_classes = str(inspect.getmro(model_class)) + + if "keras.engine.training.Model" in base_classes: + signature = inspect.signature(model_class.call) # TensorFlow models + elif "torch.nn.modules.module.Module" in base_classes: + signature = inspect.signature(model_class.forward) # PyTorch models + else: + signature = inspect.signature(model_class.__call__) # Flax models + + for p in signature.parameters: + if p == "return_loss" and signature.parameters[p].default is True: + return True + + return False + + +def find_labels(model_class): + """ + Find the labels used by a given model. + + Args: + model_class (`type`): The class of the model. + """ + model_name = model_class.__name__ + base_classes = str(inspect.getmro(model_class)) + + if "keras.engine.training.Model" in base_classes: + signature = inspect.signature(model_class.call) # TensorFlow models + elif "torch.nn.modules.module.Module" in base_classes: + signature = inspect.signature(model_class.forward) # PyTorch models + else: + signature = inspect.signature(model_class.__call__) # Flax models + + if "QuestionAnswering" in model_name: + return [p for p in signature.parameters if "label" in p or p in ("start_positions", "end_positions")] + else: + return [p for p in signature.parameters if "label" in p] + + +def flatten_dict(d: MutableMapping, parent_key: str = "", delimiter: str = "."): + """Flatten a nested dict into a single level dict.""" + + def _flatten_dict(d, parent_key="", delimiter="."): + for k, v in d.items(): + key = str(parent_key) + delimiter + str(k) if parent_key else k + if v and isinstance(v, MutableMapping): + yield from flatten_dict(v, key, delimiter=delimiter).items() + else: + yield key, v + + return dict(_flatten_dict(d, parent_key, delimiter)) + + +@contextmanager +def working_or_temp_dir(working_dir, use_temp_dir: bool = False): + if use_temp_dir: + with tempfile.TemporaryDirectory() as tmp_dir: + yield tmp_dir + else: + yield working_dir + + +def transpose(array, axes=None): + """ + Framework-agnostic version of `numpy.transpose` that will work on torch/TensorFlow/Jax tensors as well as NumPy + arrays. + """ + if is_numpy_array(array): + return np.transpose(array, axes=axes) + elif is_torch_tensor(array): + return array.T if axes is None else array.permute(*axes) + elif is_tf_tensor(array): + import tensorflow as tf + + return tf.transpose(array, perm=axes) + elif is_jax_tensor(array): + return jnp.transpose(array, axes=axes) + else: + raise ValueError(f"Type not supported for transpose: {type(array)}.") + + +def reshape(array, newshape): + """ + Framework-agnostic version of `numpy.reshape` that will work on torch/TensorFlow/Jax tensors as well as NumPy + arrays. + """ + if is_numpy_array(array): + return np.reshape(array, newshape) + elif is_torch_tensor(array): + return array.reshape(*newshape) + elif is_tf_tensor(array): + import tensorflow as tf + + return tf.reshape(array, newshape) + elif is_jax_tensor(array): + return jnp.reshape(array, newshape) + else: + raise ValueError(f"Type not supported for reshape: {type(array)}.") + + +def squeeze(array, axis=None): + """ + Framework-agnostic version of `numpy.squeeze` that will work on torch/TensorFlow/Jax tensors as well as NumPy + arrays. + """ + if is_numpy_array(array): + return np.squeeze(array, axis=axis) + elif is_torch_tensor(array): + return array.squeeze() if axis is None else array.squeeze(dim=axis) + elif is_tf_tensor(array): + import tensorflow as tf + + return tf.squeeze(array, axis=axis) + elif is_jax_tensor(array): + return jnp.squeeze(array, axis=axis) + else: + raise ValueError(f"Type not supported for squeeze: {type(array)}.") + + +def expand_dims(array, axis): + """ + Framework-agnostic version of `numpy.expand_dims` that will work on torch/TensorFlow/Jax tensors as well as NumPy + arrays. + """ + if is_numpy_array(array): + return np.expand_dims(array, axis) + elif is_torch_tensor(array): + return array.unsqueeze(dim=axis) + elif is_tf_tensor(array): + import tensorflow as tf + + return tf.expand_dims(array, axis=axis) + elif is_jax_tensor(array): + return jnp.expand_dims(array, axis=axis) + else: + raise ValueError(f"Type not supported for expand_dims: {type(array)}.") + + +def tensor_size(array): + """ + Framework-agnostic version of `numpy.size` that will work on torch/TensorFlow/Jax tensors as well as NumPy arrays. + """ + if is_numpy_array(array): + return np.size(array) + elif is_torch_tensor(array): + return array.numel() + elif is_tf_tensor(array): + import tensorflow as tf + + return tf.size(array) + elif is_jax_tensor(array): + return array.size + else: + raise ValueError(f"Type not supported for expand_dims: {type(array)}.") + + +def add_model_info_to_auto_map(auto_map, repo_id): + """ + Adds the information of the repo_id to a given auto map. + """ + for key, value in auto_map.items(): + if isinstance(value, (tuple, list)): + auto_map[key] = [f"{repo_id}--{v}" if (v is not None and "--" not in v) else v for v in value] + elif value is not None and "--" not in value: + auto_map[key] = f"{repo_id}--{value}" + + return auto_map diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hp_naming.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hp_naming.py new file mode 100644 index 0000000000000000000000000000000000000000..f7c5cb5259f8452b09cc910aee1fec7f1ba438c8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hp_naming.py @@ -0,0 +1,162 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import re + + +class TrialShortNamer: + PREFIX = "hp" + DEFAULTS = {} + NAMING_INFO = None + + @classmethod + def set_defaults(cls, prefix, defaults): + cls.PREFIX = prefix + cls.DEFAULTS = defaults + cls.build_naming_info() + + @staticmethod + def shortname_for_word(info, word): + if len(word) == 0: + return "" + short_word = None + if any(char.isdigit() for char in word): + raise Exception(f"Parameters should not contain numbers: '{word}' contains a number") + if word in info["short_word"]: + return info["short_word"][word] + for prefix_len in range(1, len(word) + 1): + prefix = word[:prefix_len] + if prefix in info["reverse_short_word"]: + continue + else: + short_word = prefix + break + + if short_word is None: + # Paranoid fallback + def int_to_alphabetic(integer): + s = "" + while integer != 0: + s = chr(ord("A") + integer % 10) + s + integer //= 10 + return s + + i = 0 + while True: + sword = word + "#" + int_to_alphabetic(i) + if sword in info["reverse_short_word"]: + continue + else: + short_word = sword + break + + info["short_word"][word] = short_word + info["reverse_short_word"][short_word] = word + return short_word + + @staticmethod + def shortname_for_key(info, param_name): + words = param_name.split("_") + + shortname_parts = [TrialShortNamer.shortname_for_word(info, word) for word in words] + + # We try to create a separatorless short name, but if there is a collision we have to fallback + # to a separated short name + separators = ["", "_"] + + for separator in separators: + shortname = separator.join(shortname_parts) + if shortname not in info["reverse_short_param"]: + info["short_param"][param_name] = shortname + info["reverse_short_param"][shortname] = param_name + return shortname + + return param_name + + @staticmethod + def add_new_param_name(info, param_name): + short_name = TrialShortNamer.shortname_for_key(info, param_name) + info["short_param"][param_name] = short_name + info["reverse_short_param"][short_name] = param_name + + @classmethod + def build_naming_info(cls): + if cls.NAMING_INFO is not None: + return + + info = { + "short_word": {}, + "reverse_short_word": {}, + "short_param": {}, + "reverse_short_param": {}, + } + + field_keys = list(cls.DEFAULTS.keys()) + + for k in field_keys: + cls.add_new_param_name(info, k) + + cls.NAMING_INFO = info + + @classmethod + def shortname(cls, params): + cls.build_naming_info() + assert cls.PREFIX is not None + name = [copy.copy(cls.PREFIX)] + + for k, v in params.items(): + if k not in cls.DEFAULTS: + raise Exception(f"You should provide a default value for the param name {k} with value {v}") + if v == cls.DEFAULTS[k]: + # The default value is not added to the name + continue + + key = cls.NAMING_INFO["short_param"][k] + + if isinstance(v, bool): + v = 1 if v else 0 + + sep = "" if isinstance(v, (int, float)) else "-" + e = f"{key}{sep}{v}" + name.append(e) + + return "_".join(name) + + @classmethod + def parse_repr(cls, repr): + repr = repr[len(cls.PREFIX) + 1 :] + if repr == "": + values = [] + else: + values = repr.split("_") + + parameters = {} + + for value in values: + if "-" in value: + p_k, p_v = value.split("-") + else: + p_k = re.sub("[0-9.]", "", value) + p_v = float(re.sub("[^0-9.]", "", value)) + + key = cls.NAMING_INFO["reverse_short_param"][p_k] + + parameters[key] = p_v + + for k in cls.DEFAULTS: + if k not in parameters: + parameters[k] = cls.DEFAULTS[k] + + return parameters diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hub.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hub.py new file mode 100644 index 0000000000000000000000000000000000000000..58aac59d24e8e6e0f960505a03b022cc59b249aa --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/hub.py @@ -0,0 +1,1138 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Hub utilities: utilities related to download and cache models +""" +import json +import os +import re +import shutil +import sys +import tempfile +import traceback +import warnings +from pathlib import Path +from typing import Dict, List, Optional, Tuple, Union +from urllib.parse import urlparse +from uuid import uuid4 + +import huggingface_hub +import requests +from huggingface_hub import ( + CommitOperationAdd, + create_commit, + create_repo, + get_hf_file_metadata, + hf_hub_download, + hf_hub_url, + whoami, +) +from huggingface_hub.file_download import REGEX_COMMIT_HASH, http_get +from huggingface_hub.utils import ( + EntryNotFoundError, + LocalEntryNotFoundError, + RepositoryNotFoundError, + RevisionNotFoundError, + build_hf_headers, + hf_raise_for_status, +) +from requests.exceptions import HTTPError + +from . import __version__, logging +from .generic import working_or_temp_dir +from .import_utils import ( + ENV_VARS_TRUE_VALUES, + _tf_version, + _torch_version, + is_tf_available, + is_torch_available, + is_training_run_on_sagemaker, +) +from .logging import tqdm + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +_is_offline_mode = True if os.environ.get("TRANSFORMERS_OFFLINE", "0").upper() in ENV_VARS_TRUE_VALUES else False + + +def is_offline_mode(): + return _is_offline_mode + + +torch_cache_home = os.getenv("TORCH_HOME", os.path.join(os.getenv("XDG_CACHE_HOME", "~/.cache"), "torch")) +old_default_cache_path = os.path.join(torch_cache_home, "transformers") +# New default cache, shared with the Datasets library +hf_cache_home = os.path.expanduser( + os.getenv("HF_HOME", os.path.join(os.getenv("XDG_CACHE_HOME", "~/.cache"), "huggingface")) +) +default_cache_path = os.path.join(hf_cache_home, "hub") + +# Onetime move from the old location to the new one if no ENV variable has been set. +if ( + os.path.isdir(old_default_cache_path) + and not os.path.isdir(default_cache_path) + and "PYTORCH_PRETRAINED_BERT_CACHE" not in os.environ + and "PYTORCH_TRANSFORMERS_CACHE" not in os.environ + and "TRANSFORMERS_CACHE" not in os.environ +): + logger.warning( + "In Transformers v4.0.0, the default path to cache downloaded models changed from" + " '~/.cache/torch/transformers' to '~/.cache/huggingface/transformers'. Since you don't seem to have" + " overridden and '~/.cache/torch/transformers' is a directory that exists, we're moving it to" + " '~/.cache/huggingface/transformers' to avoid redownloading models you have already in the cache. You should" + " only see this message once." + ) + shutil.move(old_default_cache_path, default_cache_path) + +PYTORCH_PRETRAINED_BERT_CACHE = os.getenv("PYTORCH_PRETRAINED_BERT_CACHE", default_cache_path) +PYTORCH_TRANSFORMERS_CACHE = os.getenv("PYTORCH_TRANSFORMERS_CACHE", PYTORCH_PRETRAINED_BERT_CACHE) +HUGGINGFACE_HUB_CACHE = os.getenv("HUGGINGFACE_HUB_CACHE", PYTORCH_TRANSFORMERS_CACHE) +TRANSFORMERS_CACHE = os.getenv("TRANSFORMERS_CACHE", HUGGINGFACE_HUB_CACHE) +HF_MODULES_CACHE = os.getenv("HF_MODULES_CACHE", os.path.join(hf_cache_home, "modules")) +TRANSFORMERS_DYNAMIC_MODULE_NAME = "transformers_modules" +SESSION_ID = uuid4().hex +DISABLE_TELEMETRY = os.getenv("DISABLE_TELEMETRY", False) in ENV_VARS_TRUE_VALUES + +S3_BUCKET_PREFIX = "https://s3.amazonaws.com/models.huggingface.co/bert" +CLOUDFRONT_DISTRIB_PREFIX = "https://cdn.huggingface.co" + +_staging_mode = os.environ.get("HUGGINGFACE_CO_STAGING", "NO").upper() in ENV_VARS_TRUE_VALUES +_default_endpoint = "https://hub-ci.huggingface.co" if _staging_mode else "https://huggingface.co" + +HUGGINGFACE_CO_RESOLVE_ENDPOINT = _default_endpoint +if os.environ.get("HUGGINGFACE_CO_RESOLVE_ENDPOINT", None) is not None: + warnings.warn( + "Using the environment variable `HUGGINGFACE_CO_RESOLVE_ENDPOINT` is deprecated and will be removed in " + "Transformers v5. Use `HF_ENDPOINT` instead.", + FutureWarning, + ) + HUGGINGFACE_CO_RESOLVE_ENDPOINT = os.environ.get("HUGGINGFACE_CO_RESOLVE_ENDPOINT", None) +HUGGINGFACE_CO_RESOLVE_ENDPOINT = os.environ.get("HF_ENDPOINT", HUGGINGFACE_CO_RESOLVE_ENDPOINT) +HUGGINGFACE_CO_PREFIX = HUGGINGFACE_CO_RESOLVE_ENDPOINT + "/{model_id}/resolve/{revision}/{filename}" +HUGGINGFACE_CO_EXAMPLES_TELEMETRY = HUGGINGFACE_CO_RESOLVE_ENDPOINT + "/api/telemetry/examples" + +# Return value when trying to load a file from cache but the file does not exist in the distant repo. +_CACHED_NO_EXIST = object() + + +def is_remote_url(url_or_filename): + parsed = urlparse(url_or_filename) + return parsed.scheme in ("http", "https") + + +def get_cached_models(cache_dir: Union[str, Path] = None) -> List[Tuple]: + """ + Returns a list of tuples representing model binaries that are cached locally. Each tuple has shape `(model_url, + etag, size_MB)`. Filenames in `cache_dir` are use to get the metadata for each model, only urls ending with *.bin* + are added. + + Args: + cache_dir (`Union[str, Path]`, *optional*): + The cache directory to search for models within. Will default to the transformers cache if unset. + + Returns: + List[Tuple]: List of tuples each with shape `(model_url, etag, size_MB)` + """ + if cache_dir is None: + cache_dir = TRANSFORMERS_CACHE + elif isinstance(cache_dir, Path): + cache_dir = str(cache_dir) + if not os.path.isdir(cache_dir): + return [] + + cached_models = [] + for file in os.listdir(cache_dir): + if file.endswith(".json"): + meta_path = os.path.join(cache_dir, file) + with open(meta_path, encoding="utf-8") as meta_file: + metadata = json.load(meta_file) + url = metadata["url"] + etag = metadata["etag"] + if url.endswith(".bin"): + size_MB = os.path.getsize(meta_path.strip(".json")) / 1e6 + cached_models.append((url, etag, size_MB)) + + return cached_models + + +def define_sagemaker_information(): + try: + instance_data = requests.get(os.environ["ECS_CONTAINER_METADATA_URI"]).json() + dlc_container_used = instance_data["Image"] + dlc_tag = instance_data["Image"].split(":")[1] + except Exception: + dlc_container_used = None + dlc_tag = None + + sagemaker_params = json.loads(os.getenv("SM_FRAMEWORK_PARAMS", "{}")) + runs_distributed_training = True if "sagemaker_distributed_dataparallel_enabled" in sagemaker_params else False + account_id = os.getenv("TRAINING_JOB_ARN").split(":")[4] if "TRAINING_JOB_ARN" in os.environ else None + + sagemaker_object = { + "sm_framework": os.getenv("SM_FRAMEWORK_MODULE", None), + "sm_region": os.getenv("AWS_REGION", None), + "sm_number_gpu": os.getenv("SM_NUM_GPUS", 0), + "sm_number_cpu": os.getenv("SM_NUM_CPUS", 0), + "sm_distributed_training": runs_distributed_training, + "sm_deep_learning_container": dlc_container_used, + "sm_deep_learning_container_tag": dlc_tag, + "sm_account_id": account_id, + } + return sagemaker_object + + +def http_user_agent(user_agent: Union[Dict, str, None] = None) -> str: + """ + Formats a user-agent string with basic info about a request. + """ + ua = f"transformers/{__version__}; python/{sys.version.split()[0]}; session_id/{SESSION_ID}" + if is_torch_available(): + ua += f"; torch/{_torch_version}" + if is_tf_available(): + ua += f"; tensorflow/{_tf_version}" + if DISABLE_TELEMETRY: + return ua + "; telemetry/off" + if is_training_run_on_sagemaker(): + ua += "; " + "; ".join(f"{k}/{v}" for k, v in define_sagemaker_information().items()) + # CI will set this value to True + if os.environ.get("TRANSFORMERS_IS_CI", "").upper() in ENV_VARS_TRUE_VALUES: + ua += "; is_ci/true" + if isinstance(user_agent, dict): + ua += "; " + "; ".join(f"{k}/{v}" for k, v in user_agent.items()) + elif isinstance(user_agent, str): + ua += "; " + user_agent + return ua + + +def extract_commit_hash(resolved_file: Optional[str], commit_hash: Optional[str]): + """ + Extracts the commit hash from a resolved filename toward a cache file. + """ + if resolved_file is None or commit_hash is not None: + return commit_hash + resolved_file = str(Path(resolved_file).as_posix()) + search = re.search(r"snapshots/([^/]+)/", resolved_file) + if search is None: + return None + commit_hash = search.groups()[0] + return commit_hash if REGEX_COMMIT_HASH.match(commit_hash) else None + + +def try_to_load_from_cache( + repo_id: str, + filename: str, + cache_dir: Union[str, Path, None] = None, + revision: Optional[str] = None, + repo_type: Optional[str] = None, +) -> Optional[str]: + """ + Explores the cache to return the latest cached file for a given revision if found. + + This function will not raise any exception if the file in not cached. + + Args: + cache_dir (`str` or `os.PathLike`): + The folder where the cached files lie. + repo_id (`str`): + The ID of the repo on huggingface.co. + filename (`str`): + The filename to look for inside `repo_id`. + revision (`str`, *optional*): + The specific model version to use. Will default to `"main"` if it's not provided and no `commit_hash` is + provided either. + repo_type (`str`, *optional*): + The type of the repo. + + Returns: + `Optional[str]` or `_CACHED_NO_EXIST`: + Will return `None` if the file was not cached. Otherwise: + - The exact path to the cached file if it's found in the cache + - A special value `_CACHED_NO_EXIST` if the file does not exist at the given commit hash and this fact was + cached. + """ + if revision is None: + revision = "main" + + if cache_dir is None: + cache_dir = TRANSFORMERS_CACHE + + object_id = repo_id.replace("/", "--") + if repo_type is None: + repo_type = "model" + repo_cache = os.path.join(cache_dir, f"{repo_type}s--{object_id}") + if not os.path.isdir(repo_cache): + # No cache for this model + return None + for subfolder in ["refs", "snapshots"]: + if not os.path.isdir(os.path.join(repo_cache, subfolder)): + return None + + # Resolve refs (for instance to convert main to the associated commit sha) + cached_refs = os.listdir(os.path.join(repo_cache, "refs")) + if revision in cached_refs: + with open(os.path.join(repo_cache, "refs", revision)) as f: + revision = f.read() + + if os.path.isfile(os.path.join(repo_cache, ".no_exist", revision, filename)): + return _CACHED_NO_EXIST + + cached_shas = os.listdir(os.path.join(repo_cache, "snapshots")) + if revision not in cached_shas: + # No cache for this revision and we won't try to return a random revision + return None + + cached_file = os.path.join(repo_cache, "snapshots", revision, filename) + return cached_file if os.path.isfile(cached_file) else None + + +def cached_file( + path_or_repo_id: Union[str, os.PathLike], + filename: str, + cache_dir: Optional[Union[str, os.PathLike]] = None, + force_download: bool = False, + resume_download: bool = False, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, + revision: Optional[str] = None, + local_files_only: bool = False, + subfolder: str = "", + repo_type: Optional[str] = None, + user_agent: Optional[Union[str, Dict[str, str]]] = None, + _raise_exceptions_for_missing_entries: bool = True, + _raise_exceptions_for_connection_errors: bool = True, + _commit_hash: Optional[str] = None, +): + """ + Tries to locate a file in a local folder and repo, downloads and cache it if necessary. + + Args: + path_or_repo_id (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a model repo on huggingface.co. + - a path to a *directory* potentially containing the file. + filename (`str`): + The name of the file to locate in `path_or_repo`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the standard + cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the configuration files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, will only try to load the tokenizer configuration from local files. + subfolder (`str`, *optional*, defaults to `""`): + In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can + specify the folder name here. + repo_type (`str`, *optional*): + Specify the repo type (useful when downloading from a space for instance). + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Returns: + `Optional[str]`: Returns the resolved file (to the cache folder if downloaded from a repo). + + Examples: + + ```python + # Download a model weight from the Hub and cache it. + model_weights_file = cached_file("bert-base-uncased", "pytorch_model.bin") + ```""" + # Private arguments + # _raise_exceptions_for_missing_entries: if False, do not raise an exception for missing entries but return + # None. + # _raise_exceptions_for_connection_errors: if False, do not raise an exception for connection errors but return + # None. + # _commit_hash: passed when we are chaining several calls to various files (e.g. when loading a tokenizer or + # a pipeline). If files are cached for this commit hash, avoid calls to head and get from the cache. + if is_offline_mode() and not local_files_only: + logger.info("Offline mode: forcing local_files_only=True") + local_files_only = True + if subfolder is None: + subfolder = "" + + path_or_repo_id = str(path_or_repo_id) + full_filename = os.path.join(subfolder, filename) + if os.path.isdir(path_or_repo_id): + resolved_file = os.path.join(os.path.join(path_or_repo_id, subfolder), filename) + if not os.path.isfile(resolved_file): + if _raise_exceptions_for_missing_entries: + raise EnvironmentError( + f"{path_or_repo_id} does not appear to have a file named {full_filename}. Checkout " + f"'https://huggingface.co/{path_or_repo_id}/{revision}' for available files." + ) + else: + return None + return resolved_file + + if cache_dir is None: + cache_dir = TRANSFORMERS_CACHE + if isinstance(cache_dir, Path): + cache_dir = str(cache_dir) + + if _commit_hash is not None and not force_download: + # If the file is cached under that commit hash, we return it directly. + resolved_file = try_to_load_from_cache( + path_or_repo_id, full_filename, cache_dir=cache_dir, revision=_commit_hash, repo_type=repo_type + ) + if resolved_file is not None: + if resolved_file is not _CACHED_NO_EXIST: + return resolved_file + elif not _raise_exceptions_for_missing_entries: + return None + else: + raise EnvironmentError(f"Could not locate {full_filename} inside {path_or_repo_id}.") + + user_agent = http_user_agent(user_agent) + try: + # Load from URL or cache if already cached + resolved_file = hf_hub_download( + path_or_repo_id, + filename, + subfolder=None if len(subfolder) == 0 else subfolder, + repo_type=repo_type, + revision=revision, + cache_dir=cache_dir, + user_agent=user_agent, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + use_auth_token=use_auth_token, + local_files_only=local_files_only, + ) + + except RepositoryNotFoundError: + raise EnvironmentError( + f"{path_or_repo_id} is not a local folder and is not a valid model identifier " + "listed on 'https://huggingface.co/models'\nIf this is a private repository, make sure to " + "pass a token having permission to this repo with `use_auth_token` or log in with " + "`huggingface-cli login` and pass `use_auth_token=True`." + ) + except RevisionNotFoundError: + raise EnvironmentError( + f"{revision} is not a valid git identifier (branch name, tag name or commit id) that exists " + "for this model name. Check the model page at " + f"'https://huggingface.co/{path_or_repo_id}' for available revisions." + ) + except LocalEntryNotFoundError: + # We try to see if we have a cached version (not up to date): + resolved_file = try_to_load_from_cache(path_or_repo_id, full_filename, cache_dir=cache_dir, revision=revision) + if resolved_file is not None and resolved_file != _CACHED_NO_EXIST: + return resolved_file + if not _raise_exceptions_for_missing_entries or not _raise_exceptions_for_connection_errors: + return None + raise EnvironmentError( + f"We couldn't connect to '{HUGGINGFACE_CO_RESOLVE_ENDPOINT}' to load this file, couldn't find it in the" + f" cached files and it looks like {path_or_repo_id} is not the path to a directory containing a file named" + f" {full_filename}.\nCheckout your internet connection or see how to run the library in offline mode at" + " 'https://huggingface.co/docs/transformers/installation#offline-mode'." + ) + except EntryNotFoundError: + if not _raise_exceptions_for_missing_entries: + return None + if revision is None: + revision = "main" + raise EnvironmentError( + f"{path_or_repo_id} does not appear to have a file named {full_filename}. Checkout " + f"'https://huggingface.co/{path_or_repo_id}/{revision}' for available files." + ) + except HTTPError as err: + # First we try to see if we have a cached version (not up to date): + resolved_file = try_to_load_from_cache(path_or_repo_id, full_filename, cache_dir=cache_dir, revision=revision) + if resolved_file is not None and resolved_file != _CACHED_NO_EXIST: + return resolved_file + if not _raise_exceptions_for_connection_errors: + return None + + raise EnvironmentError(f"There was a specific connection error when trying to load {path_or_repo_id}:\n{err}") + + return resolved_file + + +def get_file_from_repo( + path_or_repo: Union[str, os.PathLike], + filename: str, + cache_dir: Optional[Union[str, os.PathLike]] = None, + force_download: bool = False, + resume_download: bool = False, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, + revision: Optional[str] = None, + local_files_only: bool = False, + subfolder: str = "", +): + """ + Tries to locate a file in a local folder and repo, downloads and cache it if necessary. + + Args: + path_or_repo (`str` or `os.PathLike`): + This can be either: + + - a string, the *model id* of a model repo on huggingface.co. + - a path to a *directory* potentially containing the file. + filename (`str`): + The name of the file to locate in `path_or_repo`. + cache_dir (`str` or `os.PathLike`, *optional*): + Path to a directory in which a downloaded pretrained model configuration should be cached if the standard + cache should not be used. + force_download (`bool`, *optional*, defaults to `False`): + Whether or not to force to (re-)download the configuration files and override the cached versions if they + exist. + resume_download (`bool`, *optional*, defaults to `False`): + Whether or not to delete incompletely received file. Attempts to resume the download if such a file exists. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + use_auth_token (`str` or *bool*, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). + revision (`str`, *optional*, defaults to `"main"`): + The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a + git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any + identifier allowed by git. + local_files_only (`bool`, *optional*, defaults to `False`): + If `True`, will only try to load the tokenizer configuration from local files. + subfolder (`str`, *optional*, defaults to `""`): + In case the relevant files are located inside a subfolder of the model repo on huggingface.co, you can + specify the folder name here. + + + + Passing `use_auth_token=True` is required when you want to use a private model. + + + + Returns: + `Optional[str]`: Returns the resolved file (to the cache folder if downloaded from a repo) or `None` if the + file does not exist. + + Examples: + + ```python + # Download a tokenizer configuration from huggingface.co and cache. + tokenizer_config = get_file_from_repo("bert-base-uncased", "tokenizer_config.json") + # This model does not have a tokenizer config so the result will be None. + tokenizer_config = get_file_from_repo("xlm-roberta-base", "tokenizer_config.json") + ```""" + return cached_file( + path_or_repo_id=path_or_repo, + filename=filename, + cache_dir=cache_dir, + force_download=force_download, + resume_download=resume_download, + proxies=proxies, + use_auth_token=use_auth_token, + revision=revision, + local_files_only=local_files_only, + subfolder=subfolder, + _raise_exceptions_for_missing_entries=False, + _raise_exceptions_for_connection_errors=False, + ) + + +def download_url(url, proxies=None): + """ + Downloads a given url in a temporary file. This function is not safe to use in multiple processes. Its only use is + for deprecated behavior allowing to download config/models with a single url instead of using the Hub. + + Args: + url (`str`): The url of the file to download. + proxies (`Dict[str, str]`, *optional*): + A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128', + 'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request. + + Returns: + `str`: The location of the temporary file where the url was downloaded. + """ + warnings.warn( + f"Using `from_pretrained` with the url of a file (here {url}) is deprecated and won't be possible anymore in" + " v5 of Transformers. You should host your file on the Hub (hf.co) instead and use the repository ID. Note" + " that this is not compatible with the caching system (your file will be downloaded at each execution) or" + " multiple processes (each process will download the file in a different temporary file)." + ) + tmp_file = tempfile.mktemp() + with open(tmp_file, "wb") as f: + http_get(url, f, proxies=proxies) + return tmp_file + + +def has_file( + path_or_repo: Union[str, os.PathLike], + filename: str, + revision: Optional[str] = None, + proxies: Optional[Dict[str, str]] = None, + use_auth_token: Optional[Union[bool, str]] = None, +): + """ + Checks if a repo contains a given file without downloading it. Works for remote repos and local folders. + + + + This function will raise an error if the repository `path_or_repo` is not valid or if `revision` does not exist for + this repo, but will return False for regular connection errors. + + + """ + if os.path.isdir(path_or_repo): + return os.path.isfile(os.path.join(path_or_repo, filename)) + + url = hf_hub_url(path_or_repo, filename=filename, revision=revision) + headers = build_hf_headers(use_auth_token=use_auth_token, user_agent=http_user_agent()) + + r = requests.head(url, headers=headers, allow_redirects=False, proxies=proxies, timeout=10) + try: + hf_raise_for_status(r) + return True + except RepositoryNotFoundError as e: + logger.error(e) + raise EnvironmentError(f"{path_or_repo} is not a local folder or a valid repository name on 'https://hf.co'.") + except RevisionNotFoundError as e: + logger.error(e) + raise EnvironmentError( + f"{revision} is not a valid git identifier (branch name, tag name or commit id) that exists for this " + f"model name. Check the model page at 'https://huggingface.co/{path_or_repo}' for available revisions." + ) + except requests.HTTPError: + # We return false for EntryNotFoundError (logical) as well as any connection error. + return False + + +class PushToHubMixin: + """ + A Mixin containing the functionality to push a model or tokenizer to the hub. + """ + + def _create_repo( + self, + repo_id: str, + private: Optional[bool] = None, + use_auth_token: Optional[Union[bool, str]] = None, + repo_url: Optional[str] = None, + organization: Optional[str] = None, + ) -> str: + """ + Create the repo if needed, cleans up repo_id with deprecated kwargs `repo_url` and `organization`, retrieves + the token. + """ + if repo_url is not None: + warnings.warn( + "The `repo_url` argument is deprecated and will be removed in v5 of Transformers. Use `repo_id` " + "instead." + ) + repo_id = repo_url.replace(f"{HUGGINGFACE_CO_RESOLVE_ENDPOINT}/", "") + if organization is not None: + warnings.warn( + "The `organization` argument is deprecated and will be removed in v5 of Transformers. Set your " + "organization directly in the `repo_id` passed instead (`repo_id={organization}/{model_id}`)." + ) + if not repo_id.startswith(organization): + if "/" in repo_id: + repo_id = repo_id.split("/")[-1] + repo_id = f"{organization}/{repo_id}" + + url = create_repo(repo_id=repo_id, token=use_auth_token, private=private, exist_ok=True) + + # If the namespace is not there, add it or `upload_file` will complain + if "/" not in repo_id and url != f"{HUGGINGFACE_CO_RESOLVE_ENDPOINT}/{repo_id}": + repo_id = get_full_repo_name(repo_id, token=use_auth_token) + return repo_id + + def _get_files_timestamps(self, working_dir: Union[str, os.PathLike]): + """ + Returns the list of files with their last modification timestamp. + """ + return {f: os.path.getmtime(os.path.join(working_dir, f)) for f in os.listdir(working_dir)} + + def _upload_modified_files( + self, + working_dir: Union[str, os.PathLike], + repo_id: str, + files_timestamps: Dict[str, float], + commit_message: Optional[str] = None, + token: Optional[Union[bool, str]] = None, + create_pr: bool = False, + ): + """ + Uploads all modified files in `working_dir` to `repo_id`, based on `files_timestamps`. + """ + if commit_message is None: + if "Model" in self.__class__.__name__: + commit_message = "Upload model" + elif "Config" in self.__class__.__name__: + commit_message = "Upload config" + elif "Tokenizer" in self.__class__.__name__: + commit_message = "Upload tokenizer" + elif "FeatureExtractor" in self.__class__.__name__: + commit_message = "Upload feature extractor" + elif "Processor" in self.__class__.__name__: + commit_message = "Upload processor" + else: + commit_message = f"Upload {self.__class__.__name__}" + modified_files = [ + f + for f in os.listdir(working_dir) + if f not in files_timestamps or os.path.getmtime(os.path.join(working_dir, f)) > files_timestamps[f] + ] + operations = [] + for file in modified_files: + operations.append(CommitOperationAdd(path_or_fileobj=os.path.join(working_dir, file), path_in_repo=file)) + logger.info(f"Uploading the following files to {repo_id}: {','.join(modified_files)}") + return create_commit( + repo_id=repo_id, operations=operations, commit_message=commit_message, token=token, create_pr=create_pr + ) + + def push_to_hub( + self, + repo_id: str, + use_temp_dir: Optional[bool] = None, + commit_message: Optional[str] = None, + private: Optional[bool] = None, + use_auth_token: Optional[Union[bool, str]] = None, + max_shard_size: Optional[Union[int, str]] = "10GB", + create_pr: bool = False, + **deprecated_kwargs, + ) -> str: + """ + Upload the {object_files} to the 🤗 Model Hub while synchronizing a local clone of the repo in + `repo_path_or_name`. + + Parameters: + repo_id (`str`): + The name of the repository you want to push your {object} to. It should contain your organization name + when pushing to a given organization. + use_temp_dir (`bool`, *optional*): + Whether or not to use a temporary directory to store the files saved before they are pushed to the Hub. + Will default to `True` if there is no directory named like `repo_id`, `False` otherwise. + commit_message (`str`, *optional*): + Message to commit while pushing. Will default to `"Upload {object}"`. + private (`bool`, *optional*): + Whether or not the repository created should be private. + use_auth_token (`bool` or `str`, *optional*): + The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated + when running `huggingface-cli login` (stored in `~/.huggingface`). Will default to `True` if `repo_url` + is not specified. + max_shard_size (`int` or `str`, *optional*, defaults to `"10GB"`): + Only applicable for models. The maximum size for a checkpoint before being sharded. Checkpoints shard + will then be each of size lower than this size. If expressed as a string, needs to be digits followed + by a unit (like `"5MB"`). + create_pr (`bool`, *optional*, defaults to `False`): + Whether or not to create a PR with the uploaded files or directly commit. + + Examples: + + ```python + from transformers import {object_class} + + {object} = {object_class}.from_pretrained("bert-base-cased") + + # Push the {object} to your namespace with the name "my-finetuned-bert". + {object}.push_to_hub("my-finetuned-bert") + + # Push the {object} to an organization with the name "my-finetuned-bert". + {object}.push_to_hub("huggingface/my-finetuned-bert") + ``` + """ + if "repo_path_or_name" in deprecated_kwargs: + warnings.warn( + "The `repo_path_or_name` argument is deprecated and will be removed in v5 of Transformers. Use " + "`repo_id` instead." + ) + repo_id = deprecated_kwargs.pop("repo_path_or_name") + # Deprecation warning will be sent after for repo_url and organization + repo_url = deprecated_kwargs.pop("repo_url", None) + organization = deprecated_kwargs.pop("organization", None) + + if os.path.isdir(repo_id): + working_dir = repo_id + repo_id = repo_id.split(os.path.sep)[-1] + else: + working_dir = repo_id.split("/")[-1] + + repo_id = self._create_repo( + repo_id, private=private, use_auth_token=use_auth_token, repo_url=repo_url, organization=organization + ) + + if use_temp_dir is None: + use_temp_dir = not os.path.isdir(working_dir) + + with working_or_temp_dir(working_dir=working_dir, use_temp_dir=use_temp_dir) as work_dir: + files_timestamps = self._get_files_timestamps(work_dir) + + # Save all files. + self.save_pretrained(work_dir, max_shard_size=max_shard_size) + + return self._upload_modified_files( + work_dir, + repo_id, + files_timestamps, + commit_message=commit_message, + token=use_auth_token, + create_pr=create_pr, + ) + + +def get_full_repo_name(model_id: str, organization: Optional[str] = None, token: Optional[str] = None): + if organization is None: + username = whoami(token)["name"] + return f"{username}/{model_id}" + else: + return f"{organization}/{model_id}" + + +def send_example_telemetry(example_name, *example_args, framework="pytorch"): + """ + Sends telemetry that helps tracking the examples use. + + Args: + example_name (`str`): The name of the example. + *example_args (dataclasses or `argparse.ArgumentParser`): The arguments to the script. This function will only + try to extract the model and dataset name from those. Nothing else is tracked. + framework (`str`, *optional*, defaults to `"pytorch"`): The framework for the example. + """ + if is_offline_mode(): + return + + data = {"example": example_name, "framework": framework} + for args in example_args: + args_as_dict = {k: v for k, v in args.__dict__.items() if not k.startswith("_") and v is not None} + if "model_name_or_path" in args_as_dict: + model_name = args_as_dict["model_name_or_path"] + # Filter out local paths + if not os.path.isdir(model_name): + data["model_name"] = args_as_dict["model_name_or_path"] + if "dataset_name" in args_as_dict: + data["dataset_name"] = args_as_dict["dataset_name"] + elif "task_name" in args_as_dict: + # Extract script name from the example_name + script_name = example_name.replace("tf_", "").replace("flax_", "").replace("run_", "") + script_name = script_name.replace("_no_trainer", "") + data["dataset_name"] = f"{script_name}-{args_as_dict['task_name']}" + + headers = {"user-agent": http_user_agent(data)} + try: + r = requests.head(HUGGINGFACE_CO_EXAMPLES_TELEMETRY, headers=headers) + r.raise_for_status() + except Exception: + # We don't want to error in case of connection errors of any kind. + pass + + +def convert_file_size_to_int(size: Union[int, str]): + """ + Converts a size expressed as a string with digits an unit (like `"5MB"`) to an integer (in bytes). + + Args: + size (`int` or `str`): The size to convert. Will be directly returned if an `int`. + + Example: + ```py + >>> convert_file_size_to_int("1MiB") + 1048576 + ``` + """ + if isinstance(size, int): + return size + if size.upper().endswith("GIB"): + return int(size[:-3]) * (2**30) + if size.upper().endswith("MIB"): + return int(size[:-3]) * (2**20) + if size.upper().endswith("KIB"): + return int(size[:-3]) * (2**10) + if size.upper().endswith("GB"): + int_size = int(size[:-2]) * (10**9) + return int_size // 8 if size.endswith("b") else int_size + if size.upper().endswith("MB"): + int_size = int(size[:-2]) * (10**6) + return int_size // 8 if size.endswith("b") else int_size + if size.upper().endswith("KB"): + int_size = int(size[:-2]) * (10**3) + return int_size // 8 if size.endswith("b") else int_size + raise ValueError("`size` is not in a valid format. Use an integer followed by the unit, e.g., '5GB'.") + + +def get_checkpoint_shard_files( + pretrained_model_name_or_path, + index_filename, + cache_dir=None, + force_download=False, + proxies=None, + resume_download=False, + local_files_only=False, + use_auth_token=None, + user_agent=None, + revision=None, + subfolder="", + _commit_hash=None, +): + """ + For a given model: + + - download and cache all the shards of a sharded checkpoint if `pretrained_model_name_or_path` is a model ID on the + Hub + - returns the list of paths to all the shards, as well as some metadata. + + For the description of each arg, see [`PreTrainedModel.from_pretrained`]. `index_filename` is the full path to the + index (downloaded and cached if `pretrained_model_name_or_path` is a model ID on the Hub). + """ + import json + + if not os.path.isfile(index_filename): + raise ValueError(f"Can't find a checkpoint index ({index_filename}) in {pretrained_model_name_or_path}.") + + with open(index_filename, "r") as f: + index = json.loads(f.read()) + + shard_filenames = sorted(set(index["weight_map"].values())) + sharded_metadata = index["metadata"] + sharded_metadata["all_checkpoint_keys"] = list(index["weight_map"].keys()) + sharded_metadata["weight_map"] = index["weight_map"].copy() + + # First, let's deal with local folder. + if os.path.isdir(pretrained_model_name_or_path): + shard_filenames = [os.path.join(pretrained_model_name_or_path, subfolder, f) for f in shard_filenames] + return shard_filenames, sharded_metadata + + # At this stage pretrained_model_name_or_path is a model identifier on the Hub + cached_filenames = [] + # Check if the model is already cached or not. We only try the last checkpoint, this should cover most cases of + # downloaded (if interrupted). + last_shard = try_to_load_from_cache( + pretrained_model_name_or_path, shard_filenames[-1], cache_dir=cache_dir, revision=_commit_hash + ) + show_progress_bar = last_shard is None or force_download + for shard_filename in tqdm(shard_filenames, desc="Downloading shards", disable=not show_progress_bar): + try: + # Load from URL + cached_filename = cached_file( + pretrained_model_name_or_path, + shard_filename, + cache_dir=cache_dir, + force_download=force_download, + proxies=proxies, + resume_download=resume_download, + local_files_only=local_files_only, + use_auth_token=use_auth_token, + user_agent=user_agent, + revision=revision, + subfolder=subfolder, + _commit_hash=_commit_hash, + ) + # We have already dealt with RepositoryNotFoundError and RevisionNotFoundError when getting the index, so + # we don't have to catch them here. + except EntryNotFoundError: + raise EnvironmentError( + f"{pretrained_model_name_or_path} does not appear to have a file named {shard_filename} which is " + "required according to the checkpoint index." + ) + except HTTPError: + raise EnvironmentError( + f"We couldn't connect to '{HUGGINGFACE_CO_RESOLVE_ENDPOINT}' to load {shard_filename}. You should try" + " again after checking your internet connection." + ) + + cached_filenames.append(cached_filename) + + return cached_filenames, sharded_metadata + + +# All what is below is for conversion between old cache format and new cache format. + + +def get_all_cached_files(cache_dir=None): + """ + Returns a list for all files cached with appropriate metadata. + """ + if cache_dir is None: + cache_dir = TRANSFORMERS_CACHE + else: + cache_dir = str(cache_dir) + if not os.path.isdir(cache_dir): + return [] + + cached_files = [] + for file in os.listdir(cache_dir): + meta_path = os.path.join(cache_dir, f"{file}.json") + if not os.path.isfile(meta_path): + continue + + with open(meta_path, encoding="utf-8") as meta_file: + metadata = json.load(meta_file) + url = metadata["url"] + etag = metadata["etag"].replace('"', "") + cached_files.append({"file": file, "url": url, "etag": etag}) + + return cached_files + + +def extract_info_from_url(url): + """ + Extract repo_name, revision and filename from an url. + """ + search = re.search(r"^https://huggingface\.co/(.*)/resolve/([^/]*)/(.*)$", url) + if search is None: + return None + repo, revision, filename = search.groups() + cache_repo = "--".join(["models"] + repo.split("/")) + return {"repo": cache_repo, "revision": revision, "filename": filename} + + +def clean_files_for(file): + """ + Remove, if they exist, file, file.json and file.lock + """ + for f in [file, f"{file}.json", f"{file}.lock"]: + if os.path.isfile(f): + os.remove(f) + + +def move_to_new_cache(file, repo, filename, revision, etag, commit_hash): + """ + Move file to repo following the new huggingface hub cache organization. + """ + os.makedirs(repo, exist_ok=True) + + # refs + os.makedirs(os.path.join(repo, "refs"), exist_ok=True) + if revision != commit_hash: + ref_path = os.path.join(repo, "refs", revision) + with open(ref_path, "w") as f: + f.write(commit_hash) + + # blobs + os.makedirs(os.path.join(repo, "blobs"), exist_ok=True) + blob_path = os.path.join(repo, "blobs", etag) + shutil.move(file, blob_path) + + # snapshots + os.makedirs(os.path.join(repo, "snapshots"), exist_ok=True) + os.makedirs(os.path.join(repo, "snapshots", commit_hash), exist_ok=True) + pointer_path = os.path.join(repo, "snapshots", commit_hash, filename) + huggingface_hub.file_download._create_relative_symlink(blob_path, pointer_path) + clean_files_for(file) + + +def move_cache(cache_dir=None, new_cache_dir=None, token=None): + if new_cache_dir is None: + new_cache_dir = TRANSFORMERS_CACHE + if cache_dir is None: + # Migrate from old cache in .cache/huggingface/hub + old_cache = Path(TRANSFORMERS_CACHE).parent / "transformers" + if os.path.isdir(str(old_cache)): + cache_dir = str(old_cache) + else: + cache_dir = new_cache_dir + cached_files = get_all_cached_files(cache_dir=cache_dir) + logger.info(f"Moving {len(cached_files)} files to the new cache system") + + hub_metadata = {} + for file_info in tqdm(cached_files): + url = file_info.pop("url") + if url not in hub_metadata: + try: + hub_metadata[url] = get_hf_file_metadata(url, token=token) + except requests.HTTPError: + continue + + etag, commit_hash = hub_metadata[url].etag, hub_metadata[url].commit_hash + if etag is None or commit_hash is None: + continue + + if file_info["etag"] != etag: + # Cached file is not up to date, we just throw it as a new version will be downloaded anyway. + clean_files_for(os.path.join(cache_dir, file_info["file"])) + continue + + url_info = extract_info_from_url(url) + if url_info is None: + # Not a file from huggingface.co + continue + + repo = os.path.join(new_cache_dir, url_info["repo"]) + move_to_new_cache( + file=os.path.join(cache_dir, file_info["file"]), + repo=repo, + filename=url_info["filename"], + revision=url_info["revision"], + etag=etag, + commit_hash=commit_hash, + ) + + +cache_version_file = os.path.join(TRANSFORMERS_CACHE, "version.txt") +if not os.path.isfile(cache_version_file): + cache_version = 0 +else: + with open(cache_version_file) as f: + try: + cache_version = int(f.read()) + except ValueError: + cache_version = 0 + +cache_is_not_empty = os.path.isdir(TRANSFORMERS_CACHE) and len(os.listdir(TRANSFORMERS_CACHE)) > 0 + +if cache_version < 1 and cache_is_not_empty: + if is_offline_mode(): + logger.warning( + "You are offline and the cache for model files in Transformers v4.22.0 has been updated while your local " + "cache seems to be the one of a previous version. It is very likely that all your calls to any " + "`from_pretrained()` method will fail. Remove the offline mode and enable internet connection to have " + "your cache be updated automatically, then you can go back to offline mode." + ) + else: + logger.warning( + "The cache for model files in Transformers v4.22.0 has been updated. Migrating your old cache. This is a " + "one-time only operation. You can interrupt this and resume the migration later on by calling " + "`transformers.utils.move_cache()`." + ) + try: + if TRANSFORMERS_CACHE != default_cache_path: + # Users set some env variable to customize cache storage + move_cache(TRANSFORMERS_CACHE, TRANSFORMERS_CACHE) + else: + move_cache() + except Exception as e: + trace = "\n".join(traceback.format_tb(e.__traceback__)) + logger.error( + f"There was a problem when trying to move your cache:\n\n{trace}\n{e.__class__.__name__}: {e}\n\nPlease " + "file an issue at https://github.com/huggingface/transformers/issues/new/choose and copy paste this whole " + "message and we will do our best to help." + ) + +if cache_version < 1: + try: + os.makedirs(TRANSFORMERS_CACHE, exist_ok=True) + with open(cache_version_file, "w") as f: + f.write("1") + except Exception: + logger.warning( + f"There was a problem when trying to write in your cache folder ({TRANSFORMERS_CACHE}). You should set " + "the environment variable TRANSFORMERS_CACHE to a writable directory." + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/import_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/import_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..af169332eccbdf951f150c1dc6a48a1b2f026309 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/import_utils.py @@ -0,0 +1,1203 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Import utilities: Utilities related to imports and our lazy inits. +""" + +import importlib.util +import json +import os +import shutil +import sys +import warnings +from collections import OrderedDict +from functools import lru_cache +from itertools import chain +from types import ModuleType +from typing import Any + +from packaging import version + +from . import logging +from .versions import importlib_metadata + + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +ENV_VARS_TRUE_VALUES = {"1", "ON", "YES", "TRUE"} +ENV_VARS_TRUE_AND_AUTO_VALUES = ENV_VARS_TRUE_VALUES.union({"AUTO"}) + +USE_TF = os.environ.get("USE_TF", "AUTO").upper() +USE_TORCH = os.environ.get("USE_TORCH", "AUTO").upper() +USE_JAX = os.environ.get("USE_FLAX", "AUTO").upper() + +FORCE_TF_AVAILABLE = os.environ.get("FORCE_TF_AVAILABLE", "AUTO").upper() + +_torch_version = "N/A" +if USE_TORCH in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TF not in ENV_VARS_TRUE_VALUES: + _torch_available = importlib.util.find_spec("torch") is not None + if _torch_available: + try: + _torch_version = importlib_metadata.version("torch") + logger.info(f"PyTorch version {_torch_version} available.") + except importlib_metadata.PackageNotFoundError: + _torch_available = False +else: + logger.info("Disabling PyTorch because USE_TF is set") + _torch_available = False + + +_tf_version = "N/A" +if FORCE_TF_AVAILABLE in ENV_VARS_TRUE_VALUES: + _tf_available = True +else: + if USE_TF in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TORCH not in ENV_VARS_TRUE_VALUES: + _tf_available = importlib.util.find_spec("tensorflow") is not None + if _tf_available: + candidates = ( + "tensorflow", + "tensorflow-cpu", + "tensorflow-gpu", + "tf-nightly", + "tf-nightly-cpu", + "tf-nightly-gpu", + "intel-tensorflow", + "intel-tensorflow-avx512", + "tensorflow-rocm", + "tensorflow-macos", + "tensorflow-aarch64", + ) + _tf_version = None + # For the metadata, we have to look for both tensorflow and tensorflow-cpu + for pkg in candidates: + try: + _tf_version = importlib_metadata.version(pkg) + break + except importlib_metadata.PackageNotFoundError: + pass + _tf_available = _tf_version is not None + if _tf_available: + if version.parse(_tf_version) < version.parse("2"): + logger.info( + f"TensorFlow found but with version {_tf_version}. Transformers requires version 2 minimum." + ) + _tf_available = False + else: + logger.info(f"TensorFlow version {_tf_version} available.") + else: + logger.info("Disabling Tensorflow because USE_TORCH is set") + _tf_available = False + + +if USE_JAX in ENV_VARS_TRUE_AND_AUTO_VALUES: + _flax_available = importlib.util.find_spec("jax") is not None and importlib.util.find_spec("flax") is not None + if _flax_available: + try: + _jax_version = importlib_metadata.version("jax") + _flax_version = importlib_metadata.version("flax") + logger.info(f"JAX version {_jax_version}, Flax version {_flax_version} available.") + except importlib_metadata.PackageNotFoundError: + _flax_available = False +else: + _flax_available = False + + +_datasets_available = importlib.util.find_spec("datasets") is not None +try: + # Check we're not importing a "datasets" directory somewhere but the actual library by trying to grab the version + # AND checking it has an author field in the metadata that is HuggingFace. + _ = importlib_metadata.version("datasets") + _datasets_metadata = importlib_metadata.metadata("datasets") + if _datasets_metadata.get("author", "") != "HuggingFace Inc.": + _datasets_available = False +except importlib_metadata.PackageNotFoundError: + _datasets_available = False + + +_diffusers_available = importlib.util.find_spec("diffusers") is not None +try: + _diffusers_version = importlib_metadata.version("diffusers") + logger.debug(f"Successfully imported diffusers version {_diffusers_version}") +except importlib_metadata.PackageNotFoundError: + _diffusers_available = False + + +_detectron2_available = importlib.util.find_spec("detectron2") is not None +try: + _detectron2_version = importlib_metadata.version("detectron2") + logger.debug(f"Successfully imported detectron2 version {_detectron2_version}") +except importlib_metadata.PackageNotFoundError: + _detectron2_available = False + + +_faiss_available = importlib.util.find_spec("faiss") is not None +try: + _faiss_version = importlib_metadata.version("faiss") + logger.debug(f"Successfully imported faiss version {_faiss_version}") +except importlib_metadata.PackageNotFoundError: + try: + _faiss_version = importlib_metadata.version("faiss-cpu") + logger.debug(f"Successfully imported faiss version {_faiss_version}") + except importlib_metadata.PackageNotFoundError: + _faiss_available = False + + +_ftfy_available = importlib.util.find_spec("ftfy") is not None +try: + _ftfy_version = importlib_metadata.version("ftfy") + logger.debug(f"Successfully imported ftfy version {_ftfy_version}") +except importlib_metadata.PackageNotFoundError: + _ftfy_available = False + + +coloredlogs = importlib.util.find_spec("coloredlogs") is not None +try: + _coloredlogs_available = importlib_metadata.version("coloredlogs") + logger.debug(f"Successfully imported sympy version {_coloredlogs_available}") +except importlib_metadata.PackageNotFoundError: + _coloredlogs_available = False + + +sympy_available = importlib.util.find_spec("sympy") is not None +try: + _sympy_available = importlib_metadata.version("sympy") + logger.debug(f"Successfully imported sympy version {_sympy_available}") +except importlib_metadata.PackageNotFoundError: + _sympy_available = False + + +_tf2onnx_available = importlib.util.find_spec("tf2onnx") is not None +try: + _tf2onnx_version = importlib_metadata.version("tf2onnx") + logger.debug(f"Successfully imported tf2onnx version {_tf2onnx_version}") +except importlib_metadata.PackageNotFoundError: + _tf2onnx_available = False + + +_onnx_available = importlib.util.find_spec("onnxruntime") is not None +try: + _onxx_version = importlib_metadata.version("onnx") + logger.debug(f"Successfully imported onnx version {_onxx_version}") +except importlib_metadata.PackageNotFoundError: + _onnx_available = False + + +_opencv_available = importlib.util.find_spec("cv2") is not None + + +_pytorch_quantization_available = importlib.util.find_spec("pytorch_quantization") is not None +try: + _pytorch_quantization_version = importlib_metadata.version("pytorch_quantization") + logger.debug(f"Successfully imported pytorch-quantization version {_pytorch_quantization_version}") +except importlib_metadata.PackageNotFoundError: + _pytorch_quantization_available = False + + +_soundfile_available = importlib.util.find_spec("soundfile") is not None +try: + _soundfile_version = importlib_metadata.version("soundfile") + logger.debug(f"Successfully imported soundfile version {_soundfile_version}") +except importlib_metadata.PackageNotFoundError: + _soundfile_available = False + + +_tensorflow_probability_available = importlib.util.find_spec("tensorflow_probability") is not None +try: + _tensorflow_probability_version = importlib_metadata.version("tensorflow_probability") + logger.debug(f"Successfully imported tensorflow-probability version {_tensorflow_probability_version}") +except importlib_metadata.PackageNotFoundError: + _tensorflow_probability_available = False + + +_timm_available = importlib.util.find_spec("timm") is not None +try: + _timm_version = importlib_metadata.version("timm") + logger.debug(f"Successfully imported timm version {_timm_version}") +except importlib_metadata.PackageNotFoundError: + _timm_available = False + + +_natten_available = importlib.util.find_spec("natten") is not None +try: + _natten_version = importlib_metadata.version("natten") + logger.debug(f"Successfully imported natten version {_natten_version}") +except importlib_metadata.PackageNotFoundError: + _natten_available = False + + +_torchaudio_available = importlib.util.find_spec("torchaudio") is not None +try: + _torchaudio_version = importlib_metadata.version("torchaudio") + logger.debug(f"Successfully imported torchaudio version {_torchaudio_version}") +except importlib_metadata.PackageNotFoundError: + _torchaudio_available = False + + +_phonemizer_available = importlib.util.find_spec("phonemizer") is not None +try: + _phonemizer_version = importlib_metadata.version("phonemizer") + logger.debug(f"Successfully imported phonemizer version {_phonemizer_version}") +except importlib_metadata.PackageNotFoundError: + _phonemizer_available = False + + +_pyctcdecode_available = importlib.util.find_spec("pyctcdecode") is not None +try: + _pyctcdecode_version = importlib_metadata.version("pyctcdecode") + logger.debug(f"Successfully imported pyctcdecode version {_pyctcdecode_version}") +except importlib_metadata.PackageNotFoundError: + _pyctcdecode_available = False + + +_librosa_available = importlib.util.find_spec("librosa") is not None +try: + _librosa_version = importlib_metadata.version("librosa") + logger.debug(f"Successfully imported librosa version {_librosa_version}") +except importlib_metadata.PackageNotFoundError: + _librosa_available = False + +ccl_version = "N/A" +_is_ccl_available = ( + importlib.util.find_spec("torch_ccl") is not None + or importlib.util.find_spec("oneccl_bindings_for_pytorch") is not None +) +try: + ccl_version = importlib_metadata.version("oneccl_bind_pt") + logger.debug(f"Successfully imported oneccl_bind_pt version {ccl_version}") +except importlib_metadata.PackageNotFoundError: + _is_ccl_available = False + +_decord_availale = importlib.util.find_spec("decord") is not None +try: + _decord_version = importlib_metadata.version("decord") + logger.debug(f"Successfully imported decord version {_decord_version}") +except importlib_metadata.PackageNotFoundError: + _decord_availale = False + +_jieba_available = importlib.util.find_spec("jieba") is not None +try: + _jieba_version = importlib_metadata.version("jieba") + logger.debug(f"Successfully imported jieba version {_jieba_version}") +except importlib_metadata.PackageNotFoundError: + _jieba_available = False + +# This is the version of torch required to run torch.fx features and torch.onnx with dictionary inputs. +TORCH_FX_REQUIRED_VERSION = version.parse("1.10") + + +def is_kenlm_available(): + return importlib.util.find_spec("kenlm") is not None + + +def is_torch_available(): + return _torch_available + + +def is_torchvision_available(): + return importlib.util.find_spec("torchvision") is not None + + +def is_pyctcdecode_available(): + return _pyctcdecode_available + + +def is_librosa_available(): + return _librosa_available + + +def is_torch_cuda_available(): + if is_torch_available(): + import torch + + return torch.cuda.is_available() + else: + return False + + +def is_torch_bf16_gpu_available(): + if not is_torch_available(): + return False + + import torch + + # since currently no utility function is available we build our own. + # some bits come from https://github.com/pytorch/pytorch/blob/2289a12f21c54da93bf5d696e3f9aea83dd9c10d/torch/testing/_internal/common_cuda.py#L51 + # with additional check for torch version + # to succeed: + # 1. torch >= 1.10 (1.9 should be enough for AMP API has changed in 1.10, so using 1.10 as minimal) + # 2. the hardware needs to support bf16 (GPU arch >= Ampere, or CPU) + # 3. if using gpu, CUDA >= 11 + # 4. torch.autocast exists + # XXX: one problem here is that it may give invalid results on mixed gpus setup, so it's + # really only correct for the 0th gpu (or currently set default device if different from 0) + if version.parse(version.parse(torch.__version__).base_version) < version.parse("1.10"): + return False + + if torch.cuda.is_available() and torch.version.cuda is not None: + if torch.cuda.get_device_properties(torch.cuda.current_device()).major < 8: + return False + if int(torch.version.cuda.split(".")[0]) < 11: + return False + if not hasattr(torch.cuda.amp, "autocast"): + return False + else: + return False + + return True + + +def is_torch_bf16_cpu_available(): + if not is_torch_available(): + return False + + import torch + + if version.parse(version.parse(torch.__version__).base_version) < version.parse("1.10"): + return False + + try: + # multiple levels of AttributeError depending on the pytorch version so do them all in one check + _ = torch.cpu.amp.autocast + except AttributeError: + return False + + return True + + +def is_torch_bf16_available(): + # the original bf16 check was for gpu only, but later a cpu/bf16 combo has emerged so this util + # has become ambiguous and therefore deprecated + warnings.warn( + "The util is_torch_bf16_available is deprecated, please use is_torch_bf16_gpu_available " + "or is_torch_bf16_cpu_available instead according to whether it's used with cpu or gpu", + FutureWarning, + ) + return is_torch_bf16_gpu_available() + + +def is_torch_tf32_available(): + if not is_torch_available(): + return False + + import torch + + if not torch.cuda.is_available() or torch.version.cuda is None: + return False + if torch.cuda.get_device_properties(torch.cuda.current_device()).major < 8: + return False + if int(torch.version.cuda.split(".")[0]) < 11: + return False + if version.parse(version.parse(torch.__version__).base_version) < version.parse("1.7"): + return False + + return True + + +torch_version = None +_torch_fx_available = False +if _torch_available: + torch_version = version.parse(importlib_metadata.version("torch")) + _torch_fx_available = (torch_version.major, torch_version.minor) >= ( + TORCH_FX_REQUIRED_VERSION.major, + TORCH_FX_REQUIRED_VERSION.minor, + ) + + +def is_torch_fx_available(): + return _torch_fx_available + + +def is_peft_available(): + return importlib.util.find_spec("peft") is not None + + +def is_bs4_available(): + return importlib.util.find_spec("bs4") is not None + + +def is_tf_available(): + return _tf_available + + +def is_coloredlogs_available(): + return _coloredlogs_available + + +def is_tf2onnx_available(): + return _tf2onnx_available + + +def is_onnx_available(): + return _onnx_available + + +def is_openai_available(): + return importlib.util.find_spec("openai") is not None + + +def is_flax_available(): + return _flax_available + + +def is_ftfy_available(): + return _ftfy_available + + +@lru_cache() +def is_torch_tpu_available(check_device=True): + "Checks if `torch_xla` is installed and potentially if a TPU is in the environment" + if not _torch_available: + return False + if importlib.util.find_spec("torch_xla") is not None: + if check_device: + # We need to check if `xla_device` can be found, will raise a RuntimeError if not + try: + import torch_xla.core.xla_model as xm + + _ = xm.xla_device() + return True + except RuntimeError: + return False + return True + return False + + +@lru_cache() +def is_torch_neuroncore_available(check_device=True): + if importlib.util.find_spec("torch_neuronx") is not None: + return is_torch_tpu_available(check_device) + return False + + +def is_torchdynamo_available(): + if not is_torch_available(): + return False + try: + import torch._dynamo as dynamo # noqa: F401 + + return True + except Exception: + return False + + +def is_torch_compile_available(): + if not is_torch_available(): + return False + + import torch + + # We don't do any version check here to support nighlies marked as 1.14. Ultimately needs to check version against + # 2.0 but let's do it later. + return hasattr(torch, "compile") + + +def is_torch_tensorrt_fx_available(): + if importlib.util.find_spec("torch_tensorrt") is None: + return False + return importlib.util.find_spec("torch_tensorrt.fx") is not None + + +def is_datasets_available(): + return _datasets_available + + +def is_detectron2_available(): + return _detectron2_available + + +def is_rjieba_available(): + return importlib.util.find_spec("rjieba") is not None + + +def is_psutil_available(): + return importlib.util.find_spec("psutil") is not None + + +def is_py3nvml_available(): + return importlib.util.find_spec("py3nvml") is not None + + +def is_sacremoses_available(): + return importlib.util.find_spec("sacremoses") is not None + + +def is_apex_available(): + return importlib.util.find_spec("apex") is not None + + +def is_ninja_available(): + return importlib.util.find_spec("ninja") is not None + + +def is_ipex_available(): + def get_major_and_minor_from_version(full_version): + return str(version.parse(full_version).major) + "." + str(version.parse(full_version).minor) + + if not is_torch_available() or importlib.util.find_spec("intel_extension_for_pytorch") is None: + return False + _ipex_version = "N/A" + try: + _ipex_version = importlib_metadata.version("intel_extension_for_pytorch") + except importlib_metadata.PackageNotFoundError: + return False + torch_major_and_minor = get_major_and_minor_from_version(_torch_version) + ipex_major_and_minor = get_major_and_minor_from_version(_ipex_version) + if torch_major_and_minor != ipex_major_and_minor: + logger.warning( + f"Intel Extension for PyTorch {ipex_major_and_minor} needs to work with PyTorch {ipex_major_and_minor}.*," + f" but PyTorch {_torch_version} is found. Please switch to the matching version and run again." + ) + return False + return True + + +def is_bitsandbytes_available(): + return importlib.util.find_spec("bitsandbytes") is not None + + +def is_torchdistx_available(): + return importlib.util.find_spec("torchdistx") is not None + + +def is_faiss_available(): + return _faiss_available + + +def is_scipy_available(): + return importlib.util.find_spec("scipy") is not None + + +def is_sklearn_available(): + if importlib.util.find_spec("sklearn") is None: + return False + return is_scipy_available() and importlib.util.find_spec("sklearn.metrics") + + +def is_sentencepiece_available(): + return importlib.util.find_spec("sentencepiece") is not None + + +def is_protobuf_available(): + if importlib.util.find_spec("google") is None: + return False + return importlib.util.find_spec("google.protobuf") is not None + + +def is_accelerate_available(check_partial_state=False): + accelerate_available = importlib.util.find_spec("accelerate") is not None + if accelerate_available: + if check_partial_state: + return version.parse(importlib_metadata.version("accelerate")) >= version.parse("0.17.0") + else: + return True + else: + return False + + +def is_optimum_available(): + return importlib.util.find_spec("optimum") is not None + + +def is_optimum_neuron_available(): + return importlib.util.find_spec("optimum.neuron") is not None + + +def is_safetensors_available(): + if is_torch_available(): + if version.parse(_torch_version) >= version.parse("1.10"): + return importlib.util.find_spec("safetensors") is not None + else: + return False + else: + return importlib.util.find_spec("safetensors") is not None + + +def is_tokenizers_available(): + return importlib.util.find_spec("tokenizers") is not None + + +def is_vision_available(): + return importlib.util.find_spec("PIL") is not None + + +def is_pytesseract_available(): + return importlib.util.find_spec("pytesseract") is not None + + +def is_spacy_available(): + return importlib.util.find_spec("spacy") is not None + + +def is_tensorflow_text_available(): + return is_tf_available() and importlib.util.find_spec("tensorflow_text") is not None + + +def is_keras_nlp_available(): + return is_tensorflow_text_available() and importlib.util.find_spec("keras_nlp") is not None + + +def is_in_notebook(): + try: + # Test adapted from tqdm.autonotebook: https://github.com/tqdm/tqdm/blob/master/tqdm/autonotebook.py + get_ipython = sys.modules["IPython"].get_ipython + if "IPKernelApp" not in get_ipython().config: + raise ImportError("console") + if "VSCODE_PID" in os.environ: + raise ImportError("vscode") + if "DATABRICKS_RUNTIME_VERSION" in os.environ and os.environ["DATABRICKS_RUNTIME_VERSION"] < "11.0": + # Databricks Runtime 11.0 and above uses IPython kernel by default so it should be compatible with Jupyter notebook + # https://docs.microsoft.com/en-us/azure/databricks/notebooks/ipython-kernel + raise ImportError("databricks") + + return importlib.util.find_spec("IPython") is not None + except (AttributeError, ImportError, KeyError): + return False + + +def is_pytorch_quantization_available(): + return _pytorch_quantization_available + + +def is_tensorflow_probability_available(): + return _tensorflow_probability_available + + +def is_pandas_available(): + return importlib.util.find_spec("pandas") is not None + + +def is_sagemaker_dp_enabled(): + # Get the sagemaker specific env variable. + sagemaker_params = os.getenv("SM_FRAMEWORK_PARAMS", "{}") + try: + # Parse it and check the field "sagemaker_distributed_dataparallel_enabled". + sagemaker_params = json.loads(sagemaker_params) + if not sagemaker_params.get("sagemaker_distributed_dataparallel_enabled", False): + return False + except json.JSONDecodeError: + return False + # Lastly, check if the `smdistributed` module is present. + return importlib.util.find_spec("smdistributed") is not None + + +def is_sagemaker_mp_enabled(): + # Get the sagemaker specific mp parameters from smp_options variable. + smp_options = os.getenv("SM_HP_MP_PARAMETERS", "{}") + try: + # Parse it and check the field "partitions" is included, it is required for model parallel. + smp_options = json.loads(smp_options) + if "partitions" not in smp_options: + return False + except json.JSONDecodeError: + return False + + # Get the sagemaker specific framework parameters from mpi_options variable. + mpi_options = os.getenv("SM_FRAMEWORK_PARAMS", "{}") + try: + # Parse it and check the field "sagemaker_distributed_dataparallel_enabled". + mpi_options = json.loads(mpi_options) + if not mpi_options.get("sagemaker_mpi_enabled", False): + return False + except json.JSONDecodeError: + return False + # Lastly, check if the `smdistributed` module is present. + return importlib.util.find_spec("smdistributed") is not None + + +def is_training_run_on_sagemaker(): + return "SAGEMAKER_JOB_NAME" in os.environ + + +def is_soundfile_availble(): + return _soundfile_available + + +def is_timm_available(): + return _timm_available + + +def is_natten_available(): + return _natten_available + + +def is_torchaudio_available(): + return _torchaudio_available + + +def is_speech_available(): + # For now this depends on torchaudio but the exact dependency might evolve in the future. + return _torchaudio_available + + +def is_phonemizer_available(): + return _phonemizer_available + + +def torch_only_method(fn): + def wrapper(*args, **kwargs): + if not _torch_available: + raise ImportError( + "You need to install pytorch to use this method or class, " + "or activate it with environment variables USE_TORCH=1 and USE_TF=0." + ) + else: + return fn(*args, **kwargs) + + return wrapper + + +def is_ccl_available(): + return _is_ccl_available + + +def is_decord_available(): + return _decord_availale + + +def is_sudachi_available(): + return importlib.util.find_spec("sudachipy") is not None + + +def is_jumanpp_available(): + return (importlib.util.find_spec("rhoknp") is not None) and (shutil.which("jumanpp") is not None) + + +def is_cython_available(): + return importlib.util.find_spec("pyximport") is not None + + +def is_jieba_available(): + return _jieba_available + + +# docstyle-ignore +DATASETS_IMPORT_ERROR = """ +{0} requires the 🤗 Datasets library but it was not found in your environment. You can install it with: +``` +pip install datasets +``` +In a notebook or a colab, you can install it by executing a cell with +``` +!pip install datasets +``` +then restarting your kernel. + +Note that if you have a local folder named `datasets` or a local python file named `datasets.py` in your current +working directory, python may try to import this instead of the 🤗 Datasets library. You should rename this folder or +that python file if that's the case. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +TOKENIZERS_IMPORT_ERROR = """ +{0} requires the 🤗 Tokenizers library but it was not found in your environment. You can install it with: +``` +pip install tokenizers +``` +In a notebook or a colab, you can install it by executing a cell with +``` +!pip install tokenizers +``` +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +SENTENCEPIECE_IMPORT_ERROR = """ +{0} requires the SentencePiece library but it was not found in your environment. Checkout the instructions on the +installation page of its repo: https://github.com/google/sentencepiece#installation and follow the ones +that match your environment. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +PROTOBUF_IMPORT_ERROR = """ +{0} requires the protobuf library but it was not found in your environment. Checkout the instructions on the +installation page of its repo: https://github.com/protocolbuffers/protobuf/tree/master/python#installation and follow the ones +that match your environment. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +FAISS_IMPORT_ERROR = """ +{0} requires the faiss library but it was not found in your environment. Checkout the instructions on the +installation page of its repo: https://github.com/facebookresearch/faiss/blob/master/INSTALL.md and follow the ones +that match your environment. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +PYTORCH_IMPORT_ERROR = """ +{0} requires the PyTorch library but it was not found in your environment. Checkout the instructions on the +installation page: https://pytorch.org/get-started/locally/ and follow the ones that match your environment. +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +TORCHVISION_IMPORT_ERROR = """ +{0} requires the Torchvision library but it was not found in your environment. Checkout the instructions on the +installation page: https://pytorch.org/get-started/locally/ and follow the ones that match your environment. +Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +PYTORCH_IMPORT_ERROR_WITH_TF = """ +{0} requires the PyTorch library but it was not found in your environment. +However, we were able to find a TensorFlow installation. TensorFlow classes begin +with "TF", but are otherwise identically named to our PyTorch classes. This +means that the TF equivalent of the class you tried to import would be "TF{0}". +If you want to use TensorFlow, please use TF classes instead! + +If you really do want to use PyTorch please go to +https://pytorch.org/get-started/locally/ and follow the instructions that +match your environment. +""" + +# docstyle-ignore +TF_IMPORT_ERROR_WITH_PYTORCH = """ +{0} requires the TensorFlow library but it was not found in your environment. +However, we were able to find a PyTorch installation. PyTorch classes do not begin +with "TF", but are otherwise identically named to our TF classes. +If you want to use PyTorch, please use those classes instead! + +If you really do want to use TensorFlow, please follow the instructions on the +installation page https://www.tensorflow.org/install that match your environment. +""" + +# docstyle-ignore +BS4_IMPORT_ERROR = """ +{0} requires the Beautiful Soup library but it was not found in your environment. You can install it with pip: +`pip install beautifulsoup4`. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +SKLEARN_IMPORT_ERROR = """ +{0} requires the scikit-learn library but it was not found in your environment. You can install it with: +``` +pip install -U scikit-learn +``` +In a notebook or a colab, you can install it by executing a cell with +``` +!pip install -U scikit-learn +``` +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +TENSORFLOW_IMPORT_ERROR = """ +{0} requires the TensorFlow library but it was not found in your environment. Checkout the instructions on the +installation page: https://www.tensorflow.org/install and follow the ones that match your environment. +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +DETECTRON2_IMPORT_ERROR = """ +{0} requires the detectron2 library but it was not found in your environment. Checkout the instructions on the +installation page: https://github.com/facebookresearch/detectron2/blob/master/INSTALL.md and follow the ones +that match your environment. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +FLAX_IMPORT_ERROR = """ +{0} requires the FLAX library but it was not found in your environment. Checkout the instructions on the +installation page: https://github.com/google/flax and follow the ones that match your environment. +Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +FTFY_IMPORT_ERROR = """ +{0} requires the ftfy library but it was not found in your environment. Checkout the instructions on the +installation section: https://github.com/rspeer/python-ftfy/tree/master#installing and follow the ones +that match your environment. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +PYTORCH_QUANTIZATION_IMPORT_ERROR = """ +{0} requires the pytorch-quantization library but it was not found in your environment. You can install it with pip: +`pip install pytorch-quantization --extra-index-url https://pypi.ngc.nvidia.com` +Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +TENSORFLOW_PROBABILITY_IMPORT_ERROR = """ +{0} requires the tensorflow_probability library but it was not found in your environment. You can install it with pip as +explained here: https://github.com/tensorflow/probability. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +TENSORFLOW_TEXT_IMPORT_ERROR = """ +{0} requires the tensorflow_text library but it was not found in your environment. You can install it with pip as +explained here: https://www.tensorflow.org/text/guide/tf_text_intro. +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +PANDAS_IMPORT_ERROR = """ +{0} requires the pandas library but it was not found in your environment. You can install it with pip as +explained here: https://pandas.pydata.org/pandas-docs/stable/getting_started/install.html. +Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +PHONEMIZER_IMPORT_ERROR = """ +{0} requires the phonemizer library but it was not found in your environment. You can install it with pip: +`pip install phonemizer`. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +SACREMOSES_IMPORT_ERROR = """ +{0} requires the sacremoses library but it was not found in your environment. You can install it with pip: +`pip install sacremoses`. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +SCIPY_IMPORT_ERROR = """ +{0} requires the scipy library but it was not found in your environment. You can install it with pip: +`pip install scipy`. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +SPEECH_IMPORT_ERROR = """ +{0} requires the torchaudio library but it was not found in your environment. You can install it with pip: +`pip install torchaudio`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +TIMM_IMPORT_ERROR = """ +{0} requires the timm library but it was not found in your environment. You can install it with pip: +`pip install timm`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +NATTEN_IMPORT_ERROR = """ +{0} requires the natten library but it was not found in your environment. You can install it by referring to: +shi-labs.com/natten . You can also install it with pip (may take longer to build): +`pip install natten`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +VISION_IMPORT_ERROR = """ +{0} requires the PIL library but it was not found in your environment. You can install it with pip: +`pip install pillow`. Please note that you may need to restart your runtime after installation. +""" + + +# docstyle-ignore +PYTESSERACT_IMPORT_ERROR = """ +{0} requires the PyTesseract library but it was not found in your environment. You can install it with pip: +`pip install pytesseract`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +PYCTCDECODE_IMPORT_ERROR = """ +{0} requires the pyctcdecode library but it was not found in your environment. You can install it with pip: +`pip install pyctcdecode`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +ACCELERATE_IMPORT_ERROR = """ +{0} requires the accelerate library but it was not found in your environment. You can install it with pip: +`pip install accelerate`. Please note that you may need to restart your runtime after installation. +""" + +# docstyle-ignore +CCL_IMPORT_ERROR = """ +{0} requires the torch ccl library but it was not found in your environment. You can install it with pip: +`pip install oneccl_bind_pt -f https://developer.intel.com/ipex-whl-stable` +Please note that you may need to restart your runtime after installation. +""" + +DECORD_IMPORT_ERROR = """ +{0} requires the decord library but it was not found in your environment. You can install it with pip: `pip install +decord`. Please note that you may need to restart your runtime after installation. +""" + +CYTHON_IMPORT_ERROR = """ +{0} requires the Cython library but it was not found in your environment. You can install it with pip: `pip install +Cython`. Please note that you may need to restart your runtime after installation. +""" + +JIEBA_IMPORT_ERROR = """ +{0} requires the jieba library but it was not found in your environment. You can install it with pip: `pip install +jieba`. Please note that you may need to restart your runtime after installation. +""" + +BACKENDS_MAPPING = OrderedDict( + [ + ("bs4", (is_bs4_available, BS4_IMPORT_ERROR)), + ("datasets", (is_datasets_available, DATASETS_IMPORT_ERROR)), + ("detectron2", (is_detectron2_available, DETECTRON2_IMPORT_ERROR)), + ("faiss", (is_faiss_available, FAISS_IMPORT_ERROR)), + ("flax", (is_flax_available, FLAX_IMPORT_ERROR)), + ("ftfy", (is_ftfy_available, FTFY_IMPORT_ERROR)), + ("pandas", (is_pandas_available, PANDAS_IMPORT_ERROR)), + ("phonemizer", (is_phonemizer_available, PHONEMIZER_IMPORT_ERROR)), + ("protobuf", (is_protobuf_available, PROTOBUF_IMPORT_ERROR)), + ("pyctcdecode", (is_pyctcdecode_available, PYCTCDECODE_IMPORT_ERROR)), + ("pytesseract", (is_pytesseract_available, PYTESSERACT_IMPORT_ERROR)), + ("sacremoses", (is_sacremoses_available, SACREMOSES_IMPORT_ERROR)), + ("pytorch_quantization", (is_pytorch_quantization_available, PYTORCH_QUANTIZATION_IMPORT_ERROR)), + ("sentencepiece", (is_sentencepiece_available, SENTENCEPIECE_IMPORT_ERROR)), + ("sklearn", (is_sklearn_available, SKLEARN_IMPORT_ERROR)), + ("speech", (is_speech_available, SPEECH_IMPORT_ERROR)), + ("tensorflow_probability", (is_tensorflow_probability_available, TENSORFLOW_PROBABILITY_IMPORT_ERROR)), + ("tf", (is_tf_available, TENSORFLOW_IMPORT_ERROR)), + ("tensorflow_text", (is_tensorflow_text_available, TENSORFLOW_TEXT_IMPORT_ERROR)), + ("timm", (is_timm_available, TIMM_IMPORT_ERROR)), + ("natten", (is_natten_available, NATTEN_IMPORT_ERROR)), + ("tokenizers", (is_tokenizers_available, TOKENIZERS_IMPORT_ERROR)), + ("torch", (is_torch_available, PYTORCH_IMPORT_ERROR)), + ("torchvision", (is_torchvision_available, TORCHVISION_IMPORT_ERROR)), + ("vision", (is_vision_available, VISION_IMPORT_ERROR)), + ("scipy", (is_scipy_available, SCIPY_IMPORT_ERROR)), + ("accelerate", (is_accelerate_available, ACCELERATE_IMPORT_ERROR)), + ("oneccl_bind_pt", (is_ccl_available, CCL_IMPORT_ERROR)), + ("decord", (is_decord_available, DECORD_IMPORT_ERROR)), + ("cython", (is_cython_available, CYTHON_IMPORT_ERROR)), + ("jieba", (is_jieba_available, JIEBA_IMPORT_ERROR)), + ] +) + + +def requires_backends(obj, backends): + if not isinstance(backends, (list, tuple)): + backends = [backends] + + name = obj.__name__ if hasattr(obj, "__name__") else obj.__class__.__name__ + + # Raise an error for users who might not realize that classes without "TF" are torch-only + if "torch" in backends and "tf" not in backends and not is_torch_available() and is_tf_available(): + raise ImportError(PYTORCH_IMPORT_ERROR_WITH_TF.format(name)) + + # Raise the inverse error for PyTorch users trying to load TF classes + if "tf" in backends and "torch" not in backends and is_torch_available() and not is_tf_available(): + raise ImportError(TF_IMPORT_ERROR_WITH_PYTORCH.format(name)) + + checks = (BACKENDS_MAPPING[backend] for backend in backends) + failed = [msg.format(name) for available, msg in checks if not available()] + if failed: + raise ImportError("".join(failed)) + + +class DummyObject(type): + """ + Metaclass for the dummy objects. Any class inheriting from it will return the ImportError generated by + `requires_backend` each time a user tries to access any method of that class. + """ + + def __getattribute__(cls, key): + if key.startswith("_") and key != "_from_config": + return super().__getattribute__(key) + requires_backends(cls, cls._backends) + + +def is_torch_fx_proxy(x): + if is_torch_fx_available(): + import torch.fx + + return isinstance(x, torch.fx.Proxy) + return False + + +class _LazyModule(ModuleType): + """ + Module class that surfaces all objects but only performs associated imports when the objects are requested. + """ + + # Very heavily inspired by optuna.integration._IntegrationModule + # https://github.com/optuna/optuna/blob/master/optuna/integration/__init__.py + def __init__(self, name, module_file, import_structure, module_spec=None, extra_objects=None): + super().__init__(name) + self._modules = set(import_structure.keys()) + self._class_to_module = {} + for key, values in import_structure.items(): + for value in values: + self._class_to_module[value] = key + # Needed for autocompletion in an IDE + self.__all__ = list(import_structure.keys()) + list(chain(*import_structure.values())) + self.__file__ = module_file + self.__spec__ = module_spec + self.__path__ = [os.path.dirname(module_file)] + self._objects = {} if extra_objects is None else extra_objects + self._name = name + self._import_structure = import_structure + + # Needed for autocompletion in an IDE + def __dir__(self): + result = super().__dir__() + # The elements of self.__all__ that are submodules may or may not be in the dir already, depending on whether + # they have been accessed or not. So we only add the elements of self.__all__ that are not already in the dir. + for attr in self.__all__: + if attr not in result: + result.append(attr) + return result + + def __getattr__(self, name: str) -> Any: + if name in self._objects: + return self._objects[name] + if name in self._modules: + value = self._get_module(name) + elif name in self._class_to_module.keys(): + module = self._get_module(self._class_to_module[name]) + value = getattr(module, name) + else: + raise AttributeError(f"module {self.__name__} has no attribute {name}") + + setattr(self, name, value) + return value + + def _get_module(self, module_name: str): + try: + return importlib.import_module("." + module_name, self.__name__) + except Exception as e: + raise RuntimeError( + f"Failed to import {self.__name__}.{module_name} because of the following error (look up to see its" + f" traceback):\n{e}" + ) from e + + def __reduce__(self): + return (self.__class__, (self._name, self.__file__, self._import_structure)) + + +class OptionalDependencyNotAvailable(BaseException): + """Internally used error class for signalling an optional dependency was not found.""" + + +def direct_transformers_import(path: str, file="__init__.py") -> ModuleType: + """Imports transformers directly + + Args: + path (`str`): The path to the source file + file (`str`, optional): The file to join with the path. Defaults to "__init__.py". + + Returns: + `ModuleType`: The resulting imported module + """ + name = "transformers" + location = os.path.join(path, file) + spec = importlib.util.spec_from_file_location(name, location, submodule_search_locations=[path]) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + module = sys.modules[name] + return module diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/logging.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..b84b5029ce0e66ee4beb30707105543e74a8c062 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/logging.py @@ -0,0 +1,362 @@ +# coding=utf-8 +# Copyright 2020 Optuna, Hugging Face +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Logging utilities.""" + + +import functools +import logging +import os +import sys +import threading +from logging import ( + CRITICAL, # NOQA + DEBUG, # NOQA + ERROR, # NOQA + FATAL, # NOQA + INFO, # NOQA + NOTSET, # NOQA + WARN, # NOQA + WARNING, # NOQA +) +from typing import Optional + +import huggingface_hub.utils as hf_hub_utils +from tqdm import auto as tqdm_lib + + +_lock = threading.Lock() +_default_handler: Optional[logging.Handler] = None + +log_levels = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warning": logging.WARNING, + "error": logging.ERROR, + "critical": logging.CRITICAL, +} + +_default_log_level = logging.WARNING + +_tqdm_active = True + + +def _get_default_logging_level(): + """ + If TRANSFORMERS_VERBOSITY env var is set to one of the valid choices return that as the new default level. If it is + not - fall back to `_default_log_level` + """ + env_level_str = os.getenv("TRANSFORMERS_VERBOSITY", None) + if env_level_str: + if env_level_str in log_levels: + return log_levels[env_level_str] + else: + logging.getLogger().warning( + f"Unknown option TRANSFORMERS_VERBOSITY={env_level_str}, " + f"has to be one of: { ', '.join(log_levels.keys()) }" + ) + return _default_log_level + + +def _get_library_name() -> str: + return __name__.split(".")[0] + + +def _get_library_root_logger() -> logging.Logger: + return logging.getLogger(_get_library_name()) + + +def _configure_library_root_logger() -> None: + global _default_handler + + with _lock: + if _default_handler: + # This library has already configured the library root logger. + return + _default_handler = logging.StreamHandler() # Set sys.stderr as stream. + _default_handler.flush = sys.stderr.flush + + # Apply our default configuration to the library root logger. + library_root_logger = _get_library_root_logger() + library_root_logger.addHandler(_default_handler) + library_root_logger.setLevel(_get_default_logging_level()) + library_root_logger.propagate = False + + +def _reset_library_root_logger() -> None: + global _default_handler + + with _lock: + if not _default_handler: + return + + library_root_logger = _get_library_root_logger() + library_root_logger.removeHandler(_default_handler) + library_root_logger.setLevel(logging.NOTSET) + _default_handler = None + + +def get_log_levels_dict(): + return log_levels + + +def get_logger(name: Optional[str] = None) -> logging.Logger: + """ + Return a logger with the specified name. + + This function is not supposed to be directly accessed unless you are writing a custom transformers module. + """ + + if name is None: + name = _get_library_name() + + _configure_library_root_logger() + return logging.getLogger(name) + + +def get_verbosity() -> int: + """ + Return the current level for the 🤗 Transformers's root logger as an int. + + Returns: + `int`: The logging level. + + + + 🤗 Transformers has following logging levels: + + - 50: `transformers.logging.CRITICAL` or `transformers.logging.FATAL` + - 40: `transformers.logging.ERROR` + - 30: `transformers.logging.WARNING` or `transformers.logging.WARN` + - 20: `transformers.logging.INFO` + - 10: `transformers.logging.DEBUG` + + """ + + _configure_library_root_logger() + return _get_library_root_logger().getEffectiveLevel() + + +def set_verbosity(verbosity: int) -> None: + """ + Set the verbosity level for the 🤗 Transformers's root logger. + + Args: + verbosity (`int`): + Logging level, e.g., one of: + + - `transformers.logging.CRITICAL` or `transformers.logging.FATAL` + - `transformers.logging.ERROR` + - `transformers.logging.WARNING` or `transformers.logging.WARN` + - `transformers.logging.INFO` + - `transformers.logging.DEBUG` + """ + + _configure_library_root_logger() + _get_library_root_logger().setLevel(verbosity) + + +def set_verbosity_info(): + """Set the verbosity to the `INFO` level.""" + return set_verbosity(INFO) + + +def set_verbosity_warning(): + """Set the verbosity to the `WARNING` level.""" + return set_verbosity(WARNING) + + +def set_verbosity_debug(): + """Set the verbosity to the `DEBUG` level.""" + return set_verbosity(DEBUG) + + +def set_verbosity_error(): + """Set the verbosity to the `ERROR` level.""" + return set_verbosity(ERROR) + + +def disable_default_handler() -> None: + """Disable the default handler of the HuggingFace Transformers's root logger.""" + + _configure_library_root_logger() + + assert _default_handler is not None + _get_library_root_logger().removeHandler(_default_handler) + + +def enable_default_handler() -> None: + """Enable the default handler of the HuggingFace Transformers's root logger.""" + + _configure_library_root_logger() + + assert _default_handler is not None + _get_library_root_logger().addHandler(_default_handler) + + +def add_handler(handler: logging.Handler) -> None: + """adds a handler to the HuggingFace Transformers's root logger.""" + + _configure_library_root_logger() + + assert handler is not None + _get_library_root_logger().addHandler(handler) + + +def remove_handler(handler: logging.Handler) -> None: + """removes given handler from the HuggingFace Transformers's root logger.""" + + _configure_library_root_logger() + + assert handler is not None and handler not in _get_library_root_logger().handlers + _get_library_root_logger().removeHandler(handler) + + +def disable_propagation() -> None: + """ + Disable propagation of the library log outputs. Note that log propagation is disabled by default. + """ + + _configure_library_root_logger() + _get_library_root_logger().propagate = False + + +def enable_propagation() -> None: + """ + Enable propagation of the library log outputs. Please disable the HuggingFace Transformers's default handler to + prevent double logging if the root logger has been configured. + """ + + _configure_library_root_logger() + _get_library_root_logger().propagate = True + + +def enable_explicit_format() -> None: + """ + Enable explicit formatting for every HuggingFace Transformers's logger. The explicit formatter is as follows: + ``` + [LEVELNAME|FILENAME|LINE NUMBER] TIME >> MESSAGE + ``` + All handlers currently bound to the root logger are affected by this method. + """ + handlers = _get_library_root_logger().handlers + + for handler in handlers: + formatter = logging.Formatter("[%(levelname)s|%(filename)s:%(lineno)s] %(asctime)s >> %(message)s") + handler.setFormatter(formatter) + + +def reset_format() -> None: + """ + Resets the formatting for HuggingFace Transformers's loggers. + + All handlers currently bound to the root logger are affected by this method. + """ + handlers = _get_library_root_logger().handlers + + for handler in handlers: + handler.setFormatter(None) + + +def warning_advice(self, *args, **kwargs): + """ + This method is identical to `logger.warning()`, but if env var TRANSFORMERS_NO_ADVISORY_WARNINGS=1 is set, this + warning will not be printed + """ + no_advisory_warnings = os.getenv("TRANSFORMERS_NO_ADVISORY_WARNINGS", False) + if no_advisory_warnings: + return + self.warning(*args, **kwargs) + + +logging.Logger.warning_advice = warning_advice + + +@functools.lru_cache(None) +def warning_once(self, *args, **kwargs): + """ + This method is identical to `logger.warning()`, but will emit the warning with the same message only once + + Note: The cache is for the function arguments, so 2 different callers using the same arguments will hit the cache. + The assumption here is that all warning messages are unique across the code. If they aren't then need to switch to + another type of cache that includes the caller frame information in the hashing function. + """ + self.warning(*args, **kwargs) + + +logging.Logger.warning_once = warning_once + + +class EmptyTqdm: + """Dummy tqdm which doesn't do anything.""" + + def __init__(self, *args, **kwargs): # pylint: disable=unused-argument + self._iterator = args[0] if args else None + + def __iter__(self): + return iter(self._iterator) + + def __getattr__(self, _): + """Return empty function.""" + + def empty_fn(*args, **kwargs): # pylint: disable=unused-argument + return + + return empty_fn + + def __enter__(self): + return self + + def __exit__(self, type_, value, traceback): + return + + +class _tqdm_cls: + def __call__(self, *args, **kwargs): + if _tqdm_active: + return tqdm_lib.tqdm(*args, **kwargs) + else: + return EmptyTqdm(*args, **kwargs) + + def set_lock(self, *args, **kwargs): + self._lock = None + if _tqdm_active: + return tqdm_lib.tqdm.set_lock(*args, **kwargs) + + def get_lock(self): + if _tqdm_active: + return tqdm_lib.tqdm.get_lock() + + +tqdm = _tqdm_cls() + + +def is_progress_bar_enabled() -> bool: + """Return a boolean indicating whether tqdm progress bars are enabled.""" + global _tqdm_active + return bool(_tqdm_active) + + +def enable_progress_bar(): + """Enable tqdm progress bar.""" + global _tqdm_active + _tqdm_active = True + hf_hub_utils.enable_progress_bars() + + +def disable_progress_bar(): + """Disable tqdm progress bar.""" + global _tqdm_active + _tqdm_active = False + hf_hub_utils.disable_progress_bars() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/model_parallel_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/model_parallel_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7ec79a5e23cbc976e2cb26934abe94e7bbe890d7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/model_parallel_utils.py @@ -0,0 +1,56 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from math import ceil + + +def assert_device_map(device_map, num_blocks): + blocks = list(range(0, num_blocks)) + + device_map_blocks = [item for sublist in list(device_map.values()) for item in sublist] + + # Duplicate check + duplicate_blocks = [] + for i in device_map_blocks: + if device_map_blocks.count(i) > 1 and i not in duplicate_blocks: + duplicate_blocks.append(i) + # Missing blocks + missing_blocks = [i for i in blocks if i not in device_map_blocks] + extra_blocks = [i for i in device_map_blocks if i not in blocks] + + if len(duplicate_blocks) != 0: + raise ValueError( + "Duplicate attention blocks specified in device_map. Attention blocks must be specified to one device." + " These attention blocks were specified more than once: " + str(duplicate_blocks) + ) + if len(missing_blocks) != 0: + raise ValueError( + "There are attention blocks for this model that are not specified in the device_map. Add these attention " + "blocks to a device on the device_map: " + str(missing_blocks) + ) + if len(extra_blocks) != 0: + raise ValueError( + "The device_map contains more attention blocks than this model has. Remove these from the device_map:" + + str(extra_blocks) + ) + + +def get_device_map(n_layers, devices): + """Returns a dictionary of layers distributed evenly across all devices.""" + layers = list(range(n_layers)) + n_blocks = int(ceil(n_layers / len(devices))) + layers_list = [layers[i : i + n_blocks] for i in range(0, n_layers, n_blocks)] + + return dict(zip(devices, layers_list)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/notebook.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/notebook.py new file mode 100644 index 0000000000000000000000000000000000000000..7894f4ad9ca6f62d17435292e666f2cefe070a99 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/notebook.py @@ -0,0 +1,360 @@ +# coding=utf-8 +# Copyright 2020 Hugging Face +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +import time +from typing import Optional + +import IPython.display as disp + +from ..trainer_callback import TrainerCallback +from ..trainer_utils import IntervalStrategy, has_length + + +def format_time(t): + "Format `t` (in seconds) to (h):mm:ss" + t = int(t) + h, m, s = t // 3600, (t // 60) % 60, t % 60 + return f"{h}:{m:02d}:{s:02d}" if h != 0 else f"{m:02d}:{s:02d}" + + +def html_progress_bar(value, total, prefix, label, width=300): + # docstyle-ignore + return f""" +
+ {prefix} + + {label} +
+ """ + + +def text_to_html_table(items): + "Put the texts in `items` in an HTML table." + html_code = """\n""" + html_code += """ \n \n""" + for i in items[0]: + html_code += f" \n" + html_code += " \n \n \n" + for line in items[1:]: + html_code += " \n" + for elt in line: + elt = f"{elt:.6f}" if isinstance(elt, float) else str(elt) + html_code += f" \n" + html_code += " \n" + html_code += " \n
{i}
{elt}

" + return html_code + + +class NotebookProgressBar: + """ + A progress par for display in a notebook. + + Class attributes (overridden by derived classes) + + - **warmup** (`int`) -- The number of iterations to do at the beginning while ignoring `update_every`. + - **update_every** (`float`) -- Since calling the time takes some time, we only do it every presumed + `update_every` seconds. The progress bar uses the average time passed up until now to guess the next value + for which it will call the update. + + Args: + total (`int`): + The total number of iterations to reach. + prefix (`str`, *optional*): + A prefix to add before the progress bar. + leave (`bool`, *optional*, defaults to `True`): + Whether or not to leave the progress bar once it's completed. You can always call the + [`~utils.notebook.NotebookProgressBar.close`] method to make the bar disappear. + parent ([`~notebook.NotebookTrainingTracker`], *optional*): + A parent object (like [`~utils.notebook.NotebookTrainingTracker`]) that spawns progress bars and handle + their display. If set, the object passed must have a `display()` method. + width (`int`, *optional*, defaults to 300): + The width (in pixels) that the bar will take. + + Example: + + ```python + import time + + pbar = NotebookProgressBar(100) + for val in range(100): + pbar.update(val) + time.sleep(0.07) + pbar.update(100) + ```""" + + warmup = 5 + update_every = 0.2 + + def __init__( + self, + total: int, + prefix: Optional[str] = None, + leave: bool = True, + parent: Optional["NotebookTrainingTracker"] = None, + width: int = 300, + ): + self.total = total + self.prefix = "" if prefix is None else prefix + self.leave = leave + self.parent = parent + self.width = width + self.last_value = None + self.comment = None + self.output = None + + def update(self, value: int, force_update: bool = False, comment: str = None): + """ + The main method to update the progress bar to `value`. + + Args: + value (`int`): + The value to use. Must be between 0 and `total`. + force_update (`bool`, *optional*, defaults to `False`): + Whether or not to force and update of the internal state and display (by default, the bar will wait for + `value` to reach the value it predicted corresponds to a time of more than the `update_every` attribute + since the last update to avoid adding boilerplate). + comment (`str`, *optional*): + A comment to add on the left of the progress bar. + """ + self.value = value + if comment is not None: + self.comment = comment + if self.last_value is None: + self.start_time = self.last_time = time.time() + self.start_value = self.last_value = value + self.elapsed_time = self.predicted_remaining = None + self.first_calls = self.warmup + self.wait_for = 1 + self.update_bar(value) + elif value <= self.last_value and not force_update: + return + elif force_update or self.first_calls > 0 or value >= min(self.last_value + self.wait_for, self.total): + if self.first_calls > 0: + self.first_calls -= 1 + current_time = time.time() + self.elapsed_time = current_time - self.start_time + # We could have value = self.start_value if the update is called twixe with the same start value. + if value > self.start_value: + self.average_time_per_item = self.elapsed_time / (value - self.start_value) + else: + self.average_time_per_item = None + if value >= self.total: + value = self.total + self.predicted_remaining = None + if not self.leave: + self.close() + elif self.average_time_per_item is not None: + self.predicted_remaining = self.average_time_per_item * (self.total - value) + self.update_bar(value) + self.last_value = value + self.last_time = current_time + if self.average_time_per_item is None: + self.wait_for = 1 + else: + self.wait_for = max(int(self.update_every / self.average_time_per_item), 1) + + def update_bar(self, value, comment=None): + spaced_value = " " * (len(str(self.total)) - len(str(value))) + str(value) + if self.elapsed_time is None: + self.label = f"[{spaced_value}/{self.total} : < :" + elif self.predicted_remaining is None: + self.label = f"[{spaced_value}/{self.total} {format_time(self.elapsed_time)}" + else: + self.label = ( + f"[{spaced_value}/{self.total} {format_time(self.elapsed_time)} <" + f" {format_time(self.predicted_remaining)}" + ) + self.label += f", {1/self.average_time_per_item:.2f} it/s" + self.label += "]" if self.comment is None or len(self.comment) == 0 else f", {self.comment}]" + self.display() + + def display(self): + self.html_code = html_progress_bar(self.value, self.total, self.prefix, self.label, self.width) + if self.parent is not None: + # If this is a child bar, the parent will take care of the display. + self.parent.display() + return + if self.output is None: + self.output = disp.display(disp.HTML(self.html_code), display_id=True) + else: + self.output.update(disp.HTML(self.html_code)) + + def close(self): + "Closes the progress bar." + if self.parent is None and self.output is not None: + self.output.update(disp.HTML("")) + + +class NotebookTrainingTracker(NotebookProgressBar): + """ + An object tracking the updates of an ongoing training with progress bars and a nice table reporting metrics. + + Args: + num_steps (`int`): The number of steps during training. column_names (`List[str]`, *optional*): + The list of column names for the metrics table (will be inferred from the first call to + [`~utils.notebook.NotebookTrainingTracker.write_line`] if not set). + """ + + def __init__(self, num_steps, column_names=None): + super().__init__(num_steps) + self.inner_table = None if column_names is None else [column_names] + self.child_bar = None + + def display(self): + self.html_code = html_progress_bar(self.value, self.total, self.prefix, self.label, self.width) + if self.inner_table is not None: + self.html_code += text_to_html_table(self.inner_table) + if self.child_bar is not None: + self.html_code += self.child_bar.html_code + if self.output is None: + self.output = disp.display(disp.HTML(self.html_code), display_id=True) + else: + self.output.update(disp.HTML(self.html_code)) + + def write_line(self, values): + """ + Write the values in the inner table. + + Args: + values (`Dict[str, float]`): The values to display. + """ + if self.inner_table is None: + self.inner_table = [list(values.keys()), list(values.values())] + else: + columns = self.inner_table[0] + if len(self.inner_table) == 1: + # We give a chance to update the column names at the first iteration + for key in values.keys(): + if key not in columns: + columns.append(key) + self.inner_table[0] = columns + self.inner_table.append([values[c] for c in columns]) + + def add_child(self, total, prefix=None, width=300): + """ + Add a child progress bar displayed under the table of metrics. The child progress bar is returned (so it can be + easily updated). + + Args: + total (`int`): The number of iterations for the child progress bar. + prefix (`str`, *optional*): A prefix to write on the left of the progress bar. + width (`int`, *optional*, defaults to 300): The width (in pixels) of the progress bar. + """ + self.child_bar = NotebookProgressBar(total, prefix=prefix, parent=self, width=width) + return self.child_bar + + def remove_child(self): + """ + Closes the child progress bar. + """ + self.child_bar = None + self.display() + + +class NotebookProgressCallback(TrainerCallback): + """ + A [`TrainerCallback`] that displays the progress of training or evaluation, optimized for Jupyter Notebooks or + Google colab. + """ + + def __init__(self): + self.training_tracker = None + self.prediction_bar = None + self._force_next_update = False + + def on_train_begin(self, args, state, control, **kwargs): + self.first_column = "Epoch" if args.evaluation_strategy == IntervalStrategy.EPOCH else "Step" + self.training_loss = 0 + self.last_log = 0 + column_names = [self.first_column] + ["Training Loss"] + if args.evaluation_strategy != IntervalStrategy.NO: + column_names.append("Validation Loss") + self.training_tracker = NotebookTrainingTracker(state.max_steps, column_names) + + def on_step_end(self, args, state, control, **kwargs): + epoch = int(state.epoch) if int(state.epoch) == state.epoch else f"{state.epoch:.2f}" + self.training_tracker.update( + state.global_step + 1, + comment=f"Epoch {epoch}/{state.num_train_epochs}", + force_update=self._force_next_update, + ) + self._force_next_update = False + + def on_prediction_step(self, args, state, control, eval_dataloader=None, **kwargs): + if not has_length(eval_dataloader): + return + if self.prediction_bar is None: + if self.training_tracker is not None: + self.prediction_bar = self.training_tracker.add_child(len(eval_dataloader)) + else: + self.prediction_bar = NotebookProgressBar(len(eval_dataloader)) + self.prediction_bar.update(1) + else: + self.prediction_bar.update(self.prediction_bar.value + 1) + + def on_predict(self, args, state, control, **kwargs): + if self.prediction_bar is not None: + self.prediction_bar.close() + self.prediction_bar = None + + def on_log(self, args, state, control, logs=None, **kwargs): + # Only for when there is no evaluation + if args.evaluation_strategy == IntervalStrategy.NO and "loss" in logs: + values = {"Training Loss": logs["loss"]} + # First column is necessarily Step sine we're not in epoch eval strategy + values["Step"] = state.global_step + self.training_tracker.write_line(values) + + def on_evaluate(self, args, state, control, metrics=None, **kwargs): + if self.training_tracker is not None: + values = {"Training Loss": "No log", "Validation Loss": "No log"} + for log in reversed(state.log_history): + if "loss" in log: + values["Training Loss"] = log["loss"] + break + + if self.first_column == "Epoch": + values["Epoch"] = int(state.epoch) + else: + values["Step"] = state.global_step + metric_key_prefix = "eval" + for k in metrics: + if k.endswith("_loss"): + metric_key_prefix = re.sub(r"\_loss$", "", k) + _ = metrics.pop("total_flos", None) + _ = metrics.pop("epoch", None) + _ = metrics.pop(f"{metric_key_prefix}_runtime", None) + _ = metrics.pop(f"{metric_key_prefix}_samples_per_second", None) + _ = metrics.pop(f"{metric_key_prefix}_steps_per_second", None) + _ = metrics.pop(f"{metric_key_prefix}_jit_compilation_time", None) + for k, v in metrics.items(): + if k == f"{metric_key_prefix}_loss": + values["Validation Loss"] = v + else: + splits = k.split("_") + name = " ".join([part.capitalize() for part in splits[1:]]) + values[name] = v + self.training_tracker.write_line(values) + self.training_tracker.remove_child() + self.prediction_bar = None + # Evaluation takes a long time so we should force the next update. + self._force_next_update = True + + def on_train_end(self, args, state, control, **kwargs): + self.training_tracker.update( + state.global_step, comment=f"Epoch {int(state.epoch)}/{state.num_train_epochs}", force_update=True + ) + self.training_tracker = None diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/quantization_config.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/quantization_config.py new file mode 100644 index 0000000000000000000000000000000000000000..f123faaab32f59c78ddd351b38d35a79b33dbd79 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/quantization_config.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import copy +import json +import os +from dataclasses import dataclass +from typing import Any, Dict, Union + +from ..utils import logging + + +logger = logging.get_logger(__name__) + + +@dataclass +class BitsAndBytesConfig: + """ + This is a wrapper class about all possible attributes and features that you can play with a model that has been + loaded using `bitsandbytes`. + + This replaces `load_in_8bit` therefore both options are mutually exclusive. + + For now, only arguments that are relative to `LLM.int8()` are supported, therefore the arguments are all termed as + `llm_int8_*`. If more methods are added to `bitsandbytes`, then more arguments will be added to this class. + + Args: + load_in_8bit (`bool`, *optional*, defaults to `False`): + This flag is used to enable 8-bit quantization with LLM.int8(). + llm_int8_threshold (`float`, *optional*, defaults to 6): + This corresponds to the outlier threshold for outlier detection as described in `LLM.int8() : 8-bit Matrix + Multiplication for Transformers at Scale` paper: https://arxiv.org/abs/2208.07339 Any hidden states value + that is above this threshold will be considered an outlier and the operation on those values will be done + in fp16. Values are usually normally distributed, that is, most values are in the range [-3.5, 3.5], but + there are some exceptional systematic outliers that are very differently distributed for large models. + These outliers are often in the interval [-60, -6] or [6, 60]. Int8 quantization works well for values of + magnitude ~5, but beyond that, there is a significant performance penalty. A good default threshold is 6, + but a lower threshold might be needed for more unstable models (small models, fine-tuning). + llm_int8_skip_modules (`List[str]`, *optional*): + An explicit list of the modules that we do not want to convert in 8-bit. This is useful for models such as + Jukebox that has several heads in different places and not necessarily at the last position. For example + for `CausalLM` models, the last `lm_head` is kept in its original `dtype`. + llm_int8_enable_fp32_cpu_offload (`bool`, *optional*, defaults to `False`): + This flag is used for advanced use cases and users that are aware of this feature. If you want to split + your model in different parts and run some parts in int8 on GPU and some parts in fp32 on CPU, you can use + this flag. This is useful for offloading large models such as `google/flan-t5-xxl`. Note that the int8 + operations will not be run on CPU. + kwargs (`Dict[str, Any]`, *optional*): + Additional parameters from which to initialize the configuration object. + """ + + def __init__( + self, + load_in_8bit=False, + llm_int8_threshold=6.0, + llm_int8_skip_modules=None, + llm_int8_enable_fp32_cpu_offload=False, + **kwargs, + ): + self.load_in_8bit = load_in_8bit + self.llm_int8_threshold = llm_int8_threshold + self.llm_int8_skip_modules = llm_int8_skip_modules + self.llm_int8_enable_fp32_cpu_offload = llm_int8_enable_fp32_cpu_offload + + self.post_init() + + def post_init(self): + r""" + Safety checker that arguments are correct - also replaces some NoneType arguments with their default values. + """ + if not isinstance(self.llm_int8_threshold, float): + raise ValueError("llm_int8_threshold must be a float") + + if self.llm_int8_skip_modules is not None and not isinstance(self.llm_int8_skip_modules, list): + raise ValueError("llm_int8_skip_modules must be a list of strings") + + if not isinstance(self.llm_int8_enable_fp32_cpu_offload, bool): + raise ValueError("llm_int8_enable_fp32_cpu_offload must be a boolean") + + @classmethod + def from_dict(cls, config_dict, return_unused_kwargs, **kwargs): + """ + Instantiates a [`BitsAndBytesConfig`] from a Python dictionary of parameters. + + Args: + config_dict (`Dict[str, Any]`): + Dictionary that will be used to instantiate the configuration object. + return_unused_kwargs (`bool`): + Whether or not to return a list of unused keyword arguments. Used for `from_pretrained` method in + `PreTrainedModel`. + kwargs (`Dict[str, Any]`): + Additional parameters from which to initialize the configuration object. + + Returns: + [`BitsAndBytesConfig`]: The configuration object instantiated from those parameters. + """ + config = cls(**config_dict) + + to_remove = [] + for key, value in kwargs.items(): + if hasattr(config, key): + setattr(config, key, value) + to_remove.append(key) + for key in to_remove: + kwargs.pop(key, None) + + if return_unused_kwargs: + return config, kwargs + else: + return config + + def to_json_file(self, json_file_path: Union[str, os.PathLike]): + """ + Save this instance to a JSON file. + + Args: + json_file_path (`str` or `os.PathLike`): + Path to the JSON file in which this configuration instance's parameters will be saved. + use_diff (`bool`, *optional*, defaults to `True`): + If set to `True`, only the difference between the config instance and the default + `BitsAndBytesConfig()` is serialized to JSON file. + """ + with open(json_file_path, "w", encoding="utf-8") as writer: + config_dict = self.to_dict() + json_string = json.dumps(config_dict, indent=2, sort_keys=True) + "\n" + + writer.write(json_string) + + def to_dict(self) -> Dict[str, Any]: + """ + Serializes this instance to a Python dictionary. Returns: + `Dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance. + """ + output = copy.deepcopy(self.__dict__) + return output diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/sentencepiece_model_pb2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/sentencepiece_model_pb2.py new file mode 100644 index 0000000000000000000000000000000000000000..458fe913d63a74a741b5b0737ad9eb3eb77c59c5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/sentencepiece_model_pb2.py @@ -0,0 +1,1511 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: sentencepiece_model.proto + +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor.FileDescriptor( + name="sentencepiece_model.proto", + package="sentencepiece", + syntax="proto2", + serialized_options=b"H\003", + create_key=_descriptor._internal_create_key, + serialized_pb=( + b'\n\x19sentencepiece_model.proto\x12\rsentencepiece"\xa1\n\n\x0bTrainerSpec\x12\r\n\x05input\x18\x01' + b" \x03(\t\x12\x14\n\x0cinput_format\x18\x07 \x01(\t\x12\x14\n\x0cmodel_prefix\x18\x02" + b" \x01(\t\x12\x41\n\nmodel_type\x18\x03" + b" \x01(\x0e\x32$.sentencepiece.TrainerSpec.ModelType:\x07UNIGRAM\x12\x18\n\nvocab_size\x18\x04" + b" \x01(\x05:\x04\x38\x30\x30\x30\x12\x17\n\x0f\x61\x63\x63\x65pt_language\x18\x05 \x03(\t\x12" + b' \n\x15self_test_sample_size\x18\x06 \x01(\x05:\x01\x30\x12"\n\x12\x63haracter_coverage\x18\n' + b" \x01(\x02:\x06\x30.9995\x12\x1e\n\x13input_sentence_size\x18\x0b" + b" \x01(\x04:\x01\x30\x12$\n\x16shuffle_input_sentence\x18\x13 \x01(\x08:\x04true\x12" + b' \n\x14mining_sentence_size\x18\x0c \x01(\x05\x42\x02\x18\x01\x12"\n\x16training_sentence_size\x18\r' + b" \x01(\x05\x42\x02\x18\x01\x12(\n\x17seed_sentencepiece_size\x18\x0e" + b" \x01(\x05:\x07\x31\x30\x30\x30\x30\x30\x30\x12\x1e\n\x10shrinking_factor\x18\x0f" + b" \x01(\x02:\x04\x30.75\x12!\n\x13max_sentence_length\x18\x12" + b" \x01(\x05:\x04\x34\x31\x39\x32\x12\x17\n\x0bnum_threads\x18\x10" + b" \x01(\x05:\x02\x31\x36\x12\x1d\n\x12num_sub_iterations\x18\x11" + b" \x01(\x05:\x01\x32\x12$\n\x18max_sentencepiece_length\x18\x14" + b" \x01(\x05:\x02\x31\x36\x12%\n\x17split_by_unicode_script\x18\x15" + b" \x01(\x08:\x04true\x12\x1d\n\x0fsplit_by_number\x18\x17" + b" \x01(\x08:\x04true\x12!\n\x13split_by_whitespace\x18\x16" + b" \x01(\x08:\x04true\x12)\n\x1atreat_whitespace_as_suffix\x18\x18" + b" \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0csplit_digits\x18\x19" + b" \x01(\x08:\x05\x66\x61lse\x12\x17\n\x0f\x63ontrol_symbols\x18\x1e" + b" \x03(\t\x12\x1c\n\x14user_defined_symbols\x18\x1f \x03(\t\x12\x16\n\x0erequired_chars\x18$" + b" \x01(\t\x12\x1c\n\rbyte_fallback\x18# \x01(\x08:\x05\x66\x61lse\x12+\n\x1dvocabulary_output_piece_score\x18" + b' \x01(\x08:\x04true\x12\x1e\n\x10hard_vocab_limit\x18! \x01(\x08:\x04true\x12\x1c\n\ruse_all_vocab\x18"' + b" \x01(\x08:\x05\x66\x61lse\x12\x11\n\x06unk_id\x18( \x01(\x05:\x01\x30\x12\x11\n\x06\x62os_id\x18)" + b" \x01(\x05:\x01\x31\x12\x11\n\x06\x65os_id\x18* \x01(\x05:\x01\x32\x12\x12\n\x06pad_id\x18+" + b" \x01(\x05:\x02-1\x12\x18\n\tunk_piece\x18- \x01(\t:\x05\x12\x16\n\tbos_piece\x18." + b" \x01(\t:\x03\x12\x17\n\teos_piece\x18/ \x01(\t:\x04\x12\x18\n\tpad_piece\x18\x30" + b" \x01(\t:\x05\x12\x1a\n\x0bunk_surface\x18, \x01(\t:\x05 \xe2\x81\x87" + b" \x12+\n\x1ctrain_extremely_large_corpus\x18\x31" + b' \x01(\x08:\x05\x66\x61lse"5\n\tModelType\x12\x0b\n\x07UNIGRAM\x10\x01\x12\x07\n\x03\x42PE\x10\x02\x12\x08\n\x04WORD\x10\x03\x12\x08\n\x04\x43HAR\x10\x04*\t\x08\xc8\x01\x10\x80\x80\x80\x80\x02"\xd1\x01\n\x0eNormalizerSpec\x12\x0c\n\x04name\x18\x01' + b" \x01(\t\x12\x1c\n\x14precompiled_charsmap\x18\x02 \x01(\x0c\x12\x1e\n\x10\x61\x64\x64_dummy_prefix\x18\x03" + b" \x01(\x08:\x04true\x12&\n\x18remove_extra_whitespaces\x18\x04 \x01(\x08:\x04true\x12" + b" \n\x12\x65scape_whitespaces\x18\x05 \x01(\x08:\x04true\x12\x1e\n\x16normalization_rule_tsv\x18\x06" + b' \x01(\t*\t\x08\xc8\x01\x10\x80\x80\x80\x80\x02"y\n\x0cSelfTestData\x12\x33\n\x07samples\x18\x01' + b' \x03(\x0b\x32".sentencepiece.SelfTestData.Sample\x1a)\n\x06Sample\x12\r\n\x05input\x18\x01' + b" \x01(\t\x12\x10\n\x08\x65xpected\x18\x02" + b' \x01(\t*\t\x08\xc8\x01\x10\x80\x80\x80\x80\x02"\xfe\x03\n\nModelProto\x12\x37\n\x06pieces\x18\x01' + b" \x03(\x0b\x32'.sentencepiece.ModelProto.SentencePiece\x12\x30\n\x0ctrainer_spec\x18\x02" + b" \x01(\x0b\x32\x1a.sentencepiece.TrainerSpec\x12\x36\n\x0fnormalizer_spec\x18\x03" + b" \x01(\x0b\x32\x1d.sentencepiece.NormalizerSpec\x12\x33\n\x0eself_test_data\x18\x04" + b" \x01(\x0b\x32\x1b.sentencepiece.SelfTestData\x12\x38\n\x11\x64\x65normalizer_spec\x18\x05" + b" \x01(\x0b\x32\x1d.sentencepiece.NormalizerSpec\x1a\xd2\x01\n\rSentencePiece\x12\r\n\x05piece\x18\x01" + b" \x01(\t\x12\r\n\x05score\x18\x02 \x01(\x02\x12\x42\n\x04type\x18\x03" + b' \x01(\x0e\x32,.sentencepiece.ModelProto.SentencePiece.Type:\x06NORMAL"T\n\x04Type\x12\n\n\x06NORMAL\x10\x01\x12\x0b\n\x07UNKNOWN\x10\x02\x12\x0b\n\x07\x43ONTROL\x10\x03\x12\x10\n\x0cUSER_DEFINED\x10\x04\x12\x08\n\x04\x42YTE\x10\x06\x12\n\n\x06UNUSED\x10\x05*\t\x08\xc8\x01\x10\x80\x80\x80\x80\x02*\t\x08\xc8\x01\x10\x80\x80\x80\x80\x02\x42\x02H\x03' + ), +) + + +_TRAINERSPEC_MODELTYPE = _descriptor.EnumDescriptor( + name="ModelType", + full_name="sentencepiece.TrainerSpec.ModelType", + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name="UNIGRAM", + index=0, + number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="BPE", + index=1, + number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="WORD", + index=2, + number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="CHAR", + index=3, + number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + ], + containing_type=None, + serialized_options=None, + serialized_start=1294, + serialized_end=1347, +) +_sym_db.RegisterEnumDescriptor(_TRAINERSPEC_MODELTYPE) + +_MODELPROTO_SENTENCEPIECE_TYPE = _descriptor.EnumDescriptor( + name="Type", + full_name="sentencepiece.ModelProto.SentencePiece.Type", + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name="NORMAL", + index=0, + number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="UNKNOWN", + index=1, + number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="CONTROL", + index=2, + number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="USER_DEFINED", + index=3, + number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="BYTE", + index=4, + number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="UNUSED", + index=5, + number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + ], + containing_type=None, + serialized_options=None, + serialized_start=2100, + serialized_end=2184, +) +_sym_db.RegisterEnumDescriptor(_MODELPROTO_SENTENCEPIECE_TYPE) + + +_TRAINERSPEC = _descriptor.Descriptor( + name="TrainerSpec", + full_name="sentencepiece.TrainerSpec", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="input", + full_name="sentencepiece.TrainerSpec.input", + index=0, + number=1, + type=9, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="input_format", + full_name="sentencepiece.TrainerSpec.input_format", + index=1, + number=7, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="model_prefix", + full_name="sentencepiece.TrainerSpec.model_prefix", + index=2, + number=2, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="model_type", + full_name="sentencepiece.TrainerSpec.model_type", + index=3, + number=3, + type=14, + cpp_type=8, + label=1, + has_default_value=True, + default_value=1, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="vocab_size", + full_name="sentencepiece.TrainerSpec.vocab_size", + index=4, + number=4, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=8000, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="accept_language", + full_name="sentencepiece.TrainerSpec.accept_language", + index=5, + number=5, + type=9, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="self_test_sample_size", + full_name="sentencepiece.TrainerSpec.self_test_sample_size", + index=6, + number=6, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="character_coverage", + full_name="sentencepiece.TrainerSpec.character_coverage", + index=7, + number=10, + type=2, + cpp_type=6, + label=1, + has_default_value=True, + default_value=float(0.9995), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="input_sentence_size", + full_name="sentencepiece.TrainerSpec.input_sentence_size", + index=8, + number=11, + type=4, + cpp_type=4, + label=1, + has_default_value=True, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="shuffle_input_sentence", + full_name="sentencepiece.TrainerSpec.shuffle_input_sentence", + index=9, + number=19, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="mining_sentence_size", + full_name="sentencepiece.TrainerSpec.mining_sentence_size", + index=10, + number=12, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=b"\030\001", + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="training_sentence_size", + full_name="sentencepiece.TrainerSpec.training_sentence_size", + index=11, + number=13, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=b"\030\001", + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="seed_sentencepiece_size", + full_name="sentencepiece.TrainerSpec.seed_sentencepiece_size", + index=12, + number=14, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=1000000, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="shrinking_factor", + full_name="sentencepiece.TrainerSpec.shrinking_factor", + index=13, + number=15, + type=2, + cpp_type=6, + label=1, + has_default_value=True, + default_value=float(0.75), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="max_sentence_length", + full_name="sentencepiece.TrainerSpec.max_sentence_length", + index=14, + number=18, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=4192, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="num_threads", + full_name="sentencepiece.TrainerSpec.num_threads", + index=15, + number=16, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=16, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="num_sub_iterations", + full_name="sentencepiece.TrainerSpec.num_sub_iterations", + index=16, + number=17, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=2, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="max_sentencepiece_length", + full_name="sentencepiece.TrainerSpec.max_sentencepiece_length", + index=17, + number=20, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=16, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="split_by_unicode_script", + full_name="sentencepiece.TrainerSpec.split_by_unicode_script", + index=18, + number=21, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="split_by_number", + full_name="sentencepiece.TrainerSpec.split_by_number", + index=19, + number=23, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="split_by_whitespace", + full_name="sentencepiece.TrainerSpec.split_by_whitespace", + index=20, + number=22, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="treat_whitespace_as_suffix", + full_name="sentencepiece.TrainerSpec.treat_whitespace_as_suffix", + index=21, + number=24, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="split_digits", + full_name="sentencepiece.TrainerSpec.split_digits", + index=22, + number=25, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="control_symbols", + full_name="sentencepiece.TrainerSpec.control_symbols", + index=23, + number=30, + type=9, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="user_defined_symbols", + full_name="sentencepiece.TrainerSpec.user_defined_symbols", + index=24, + number=31, + type=9, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="required_chars", + full_name="sentencepiece.TrainerSpec.required_chars", + index=25, + number=36, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="byte_fallback", + full_name="sentencepiece.TrainerSpec.byte_fallback", + index=26, + number=35, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="vocabulary_output_piece_score", + full_name="sentencepiece.TrainerSpec.vocabulary_output_piece_score", + index=27, + number=32, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="hard_vocab_limit", + full_name="sentencepiece.TrainerSpec.hard_vocab_limit", + index=28, + number=33, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="use_all_vocab", + full_name="sentencepiece.TrainerSpec.use_all_vocab", + index=29, + number=34, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="unk_id", + full_name="sentencepiece.TrainerSpec.unk_id", + index=30, + number=40, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="bos_id", + full_name="sentencepiece.TrainerSpec.bos_id", + index=31, + number=41, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=1, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="eos_id", + full_name="sentencepiece.TrainerSpec.eos_id", + index=32, + number=42, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=2, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="pad_id", + full_name="sentencepiece.TrainerSpec.pad_id", + index=33, + number=43, + type=5, + cpp_type=1, + label=1, + has_default_value=True, + default_value=-1, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="unk_piece", + full_name="sentencepiece.TrainerSpec.unk_piece", + index=34, + number=45, + type=9, + cpp_type=9, + label=1, + has_default_value=True, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="bos_piece", + full_name="sentencepiece.TrainerSpec.bos_piece", + index=35, + number=46, + type=9, + cpp_type=9, + label=1, + has_default_value=True, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="eos_piece", + full_name="sentencepiece.TrainerSpec.eos_piece", + index=36, + number=47, + type=9, + cpp_type=9, + label=1, + has_default_value=True, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="pad_piece", + full_name="sentencepiece.TrainerSpec.pad_piece", + index=37, + number=48, + type=9, + cpp_type=9, + label=1, + has_default_value=True, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="unk_surface", + full_name="sentencepiece.TrainerSpec.unk_surface", + index=38, + number=44, + type=9, + cpp_type=9, + label=1, + has_default_value=True, + default_value=b" \342\201\207 ".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="train_extremely_large_corpus", + full_name="sentencepiece.TrainerSpec.train_extremely_large_corpus", + index=39, + number=49, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[ + _TRAINERSPEC_MODELTYPE, + ], + serialized_options=None, + is_extendable=True, + syntax="proto2", + extension_ranges=[ + (200, 536870912), + ], + oneofs=[], + serialized_start=45, + serialized_end=1358, +) + + +_NORMALIZERSPEC = _descriptor.Descriptor( + name="NormalizerSpec", + full_name="sentencepiece.NormalizerSpec", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="name", + full_name="sentencepiece.NormalizerSpec.name", + index=0, + number=1, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="precompiled_charsmap", + full_name="sentencepiece.NormalizerSpec.precompiled_charsmap", + index=1, + number=2, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"", + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="add_dummy_prefix", + full_name="sentencepiece.NormalizerSpec.add_dummy_prefix", + index=2, + number=3, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="remove_extra_whitespaces", + full_name="sentencepiece.NormalizerSpec.remove_extra_whitespaces", + index=3, + number=4, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="escape_whitespaces", + full_name="sentencepiece.NormalizerSpec.escape_whitespaces", + index=4, + number=5, + type=8, + cpp_type=7, + label=1, + has_default_value=True, + default_value=True, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="normalization_rule_tsv", + full_name="sentencepiece.NormalizerSpec.normalization_rule_tsv", + index=5, + number=6, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + serialized_options=None, + is_extendable=True, + syntax="proto2", + extension_ranges=[ + (200, 536870912), + ], + oneofs=[], + serialized_start=1361, + serialized_end=1570, +) + + +_SELFTESTDATA_SAMPLE = _descriptor.Descriptor( + name="Sample", + full_name="sentencepiece.SelfTestData.Sample", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="input", + full_name="sentencepiece.SelfTestData.Sample.input", + index=0, + number=1, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="expected", + full_name="sentencepiece.SelfTestData.Sample.expected", + index=1, + number=2, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + serialized_options=None, + is_extendable=False, + syntax="proto2", + extension_ranges=[], + oneofs=[], + serialized_start=1641, + serialized_end=1682, +) + +_SELFTESTDATA = _descriptor.Descriptor( + name="SelfTestData", + full_name="sentencepiece.SelfTestData", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="samples", + full_name="sentencepiece.SelfTestData.samples", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[ + _SELFTESTDATA_SAMPLE, + ], + enum_types=[], + serialized_options=None, + is_extendable=True, + syntax="proto2", + extension_ranges=[ + (200, 536870912), + ], + oneofs=[], + serialized_start=1572, + serialized_end=1693, +) + + +_MODELPROTO_SENTENCEPIECE = _descriptor.Descriptor( + name="SentencePiece", + full_name="sentencepiece.ModelProto.SentencePiece", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="piece", + full_name="sentencepiece.ModelProto.SentencePiece.piece", + index=0, + number=1, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="score", + full_name="sentencepiece.ModelProto.SentencePiece.score", + index=1, + number=2, + type=2, + cpp_type=6, + label=1, + has_default_value=False, + default_value=float(0), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="type", + full_name="sentencepiece.ModelProto.SentencePiece.type", + index=2, + number=3, + type=14, + cpp_type=8, + label=1, + has_default_value=True, + default_value=1, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[ + _MODELPROTO_SENTENCEPIECE_TYPE, + ], + serialized_options=None, + is_extendable=True, + syntax="proto2", + extension_ranges=[ + (200, 536870912), + ], + oneofs=[], + serialized_start=1985, + serialized_end=2195, +) + +_MODELPROTO = _descriptor.Descriptor( + name="ModelProto", + full_name="sentencepiece.ModelProto", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="pieces", + full_name="sentencepiece.ModelProto.pieces", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="trainer_spec", + full_name="sentencepiece.ModelProto.trainer_spec", + index=1, + number=2, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="normalizer_spec", + full_name="sentencepiece.ModelProto.normalizer_spec", + index=2, + number=3, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="self_test_data", + full_name="sentencepiece.ModelProto.self_test_data", + index=3, + number=4, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="denormalizer_spec", + full_name="sentencepiece.ModelProto.denormalizer_spec", + index=4, + number=5, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[ + _MODELPROTO_SENTENCEPIECE, + ], + enum_types=[], + serialized_options=None, + is_extendable=True, + syntax="proto2", + extension_ranges=[ + (200, 536870912), + ], + oneofs=[], + serialized_start=1696, + serialized_end=2206, +) + +_TRAINERSPEC.fields_by_name["model_type"].enum_type = _TRAINERSPEC_MODELTYPE +_TRAINERSPEC_MODELTYPE.containing_type = _TRAINERSPEC +_SELFTESTDATA_SAMPLE.containing_type = _SELFTESTDATA +_SELFTESTDATA.fields_by_name["samples"].message_type = _SELFTESTDATA_SAMPLE +_MODELPROTO_SENTENCEPIECE.fields_by_name["type"].enum_type = _MODELPROTO_SENTENCEPIECE_TYPE +_MODELPROTO_SENTENCEPIECE.containing_type = _MODELPROTO +_MODELPROTO_SENTENCEPIECE_TYPE.containing_type = _MODELPROTO_SENTENCEPIECE +_MODELPROTO.fields_by_name["pieces"].message_type = _MODELPROTO_SENTENCEPIECE +_MODELPROTO.fields_by_name["trainer_spec"].message_type = _TRAINERSPEC +_MODELPROTO.fields_by_name["normalizer_spec"].message_type = _NORMALIZERSPEC +_MODELPROTO.fields_by_name["self_test_data"].message_type = _SELFTESTDATA +_MODELPROTO.fields_by_name["denormalizer_spec"].message_type = _NORMALIZERSPEC +DESCRIPTOR.message_types_by_name["TrainerSpec"] = _TRAINERSPEC +DESCRIPTOR.message_types_by_name["NormalizerSpec"] = _NORMALIZERSPEC +DESCRIPTOR.message_types_by_name["SelfTestData"] = _SELFTESTDATA +DESCRIPTOR.message_types_by_name["ModelProto"] = _MODELPROTO +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +TrainerSpec = _reflection.GeneratedProtocolMessageType( + "TrainerSpec", + (_message.Message,), + { + "DESCRIPTOR": _TRAINERSPEC, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.TrainerSpec) + }, +) +_sym_db.RegisterMessage(TrainerSpec) + +NormalizerSpec = _reflection.GeneratedProtocolMessageType( + "NormalizerSpec", + (_message.Message,), + { + "DESCRIPTOR": _NORMALIZERSPEC, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.NormalizerSpec) + }, +) +_sym_db.RegisterMessage(NormalizerSpec) + +SelfTestData = _reflection.GeneratedProtocolMessageType( + "SelfTestData", + (_message.Message,), + { + "Sample": _reflection.GeneratedProtocolMessageType( + "Sample", + (_message.Message,), + { + "DESCRIPTOR": _SELFTESTDATA_SAMPLE, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.SelfTestData.Sample) + }, + ), + "DESCRIPTOR": _SELFTESTDATA, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.SelfTestData) + }, +) +_sym_db.RegisterMessage(SelfTestData) +_sym_db.RegisterMessage(SelfTestData.Sample) + +ModelProto = _reflection.GeneratedProtocolMessageType( + "ModelProto", + (_message.Message,), + { + "SentencePiece": _reflection.GeneratedProtocolMessageType( + "SentencePiece", + (_message.Message,), + { + "DESCRIPTOR": _MODELPROTO_SENTENCEPIECE, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.ModelProto.SentencePiece) + }, + ), + "DESCRIPTOR": _MODELPROTO, + "__module__": "sentencepiece_model_pb2" + # @@protoc_insertion_point(class_scope:sentencepiece.ModelProto) + }, +) +_sym_db.RegisterMessage(ModelProto) +_sym_db.RegisterMessage(ModelProto.SentencePiece) + + +DESCRIPTOR._options = None +_TRAINERSPEC.fields_by_name["mining_sentence_size"]._options = None +_TRAINERSPEC.fields_by_name["training_sentence_size"]._options = None +# @@protoc_insertion_point(module_scope) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/versions.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/versions.py new file mode 100644 index 0000000000000000000000000000000000000000..b97e75a336828202e876a6ba4a5a1e423ba2977c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/src/transformers/utils/versions.py @@ -0,0 +1,123 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Utilities for working with package versions +""" + +import operator +import re +import sys +from typing import Optional + +from packaging import version + + +# The package importlib_metadata is in a different place, depending on the python version. +if sys.version_info < (3, 8): + import importlib_metadata +else: + import importlib.metadata as importlib_metadata + + +ops = { + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _compare_versions(op, got_ver, want_ver, requirement, pkg, hint): + if got_ver is None or want_ver is None: + raise ValueError( + f"Unable to compare versions for {requirement}: need={want_ver} found={got_ver}. This is unusual. Consider" + f" reinstalling {pkg}." + ) + if not ops[op](version.parse(got_ver), version.parse(want_ver)): + raise ImportError( + f"{requirement} is required for a normal functioning of this module, but found {pkg}=={got_ver}.{hint}" + ) + + +def require_version(requirement: str, hint: Optional[str] = None) -> None: + """ + Perform a runtime check of the dependency versions, using the exact same syntax used by pip. + + The installed module version comes from the *site-packages* dir via *importlib_metadata*. + + Args: + requirement (`str`): pip style definition, e.g., "tokenizers==0.9.4", "tqdm>=4.27", "numpy" + hint (`str`, *optional*): what suggestion to print in case of requirements not being met + + Example: + + ```python + require_version("pandas>1.1.2") + require_version("numpy>1.18.5", "this is important to have for whatever reason") + ```""" + + hint = f"\n{hint}" if hint is not None else "" + + # non-versioned check + if re.match(r"^[\w_\-\d]+$", requirement): + pkg, op, want_ver = requirement, None, None + else: + match = re.findall(r"^([^!=<>\s]+)([\s!=<>]{1,2}.+)", requirement) + if not match: + raise ValueError( + "requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23, but" + f" got {requirement}" + ) + pkg, want_full = match[0] + want_range = want_full.split(",") # there could be multiple requirements + wanted = {} + for w in want_range: + match = re.findall(r"^([\s!=<>]{1,2})(.+)", w) + if not match: + raise ValueError( + "requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23," + f" but got {requirement}" + ) + op, want_ver = match[0] + wanted[op] = want_ver + if op not in ops: + raise ValueError(f"{requirement}: need one of {list(ops.keys())}, but got {op}") + + # special case + if pkg == "python": + got_ver = ".".join([str(x) for x in sys.version_info[:3]]) + for op, want_ver in wanted.items(): + _compare_versions(op, got_ver, want_ver, requirement, pkg, hint) + return + + # check if any version is installed + try: + got_ver = importlib_metadata.version(pkg) + except importlib_metadata.PackageNotFoundError: + raise importlib_metadata.PackageNotFoundError( + f"The '{requirement}' distribution was not found and is required by this application. {hint}" + ) + + # check that the right version is installed if version number or a range was provided + if want_ver is not None: + for op, want_ver in wanted.items(): + _compare_versions(op, got_ver, want_ver, requirement, pkg, hint) + + +def require_version_core(requirement): + """require_version wrapper which emits a core-specific hint on failure""" + hint = "Try: pip install transformers -U or pip install -e '.[dev]' if you're working with git main" + return require_version(requirement, hint) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/README.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/README.md new file mode 100644 index 0000000000000000000000000000000000000000..935f21c5ca8ab22d043bdee76041c279baf58866 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/README.md @@ -0,0 +1,39 @@ + + +This folder contains a template to add a tokenization test. + +## Usage + +Using the `cookiecutter` utility requires to have all the `dev` dependencies installed. + +Let's first [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the `transformers` repo on github. Once it's done you can clone your fork and install `transformers` in our environment: + +```shell script +git clone https://github.com/YOUR-USERNAME/transformers +cd transformers +pip install -e ".[dev]" +``` + +Once the installation is done, you can generate the template by running the following command. Be careful, the template will be generated inside a new folder in your current working directory. + +```shell script +cookiecutter path-to-the folder/adding_a_missing_tokenization_test/ +``` + +You will then have to answer some questions about the tokenizer for which you want to add tests. The `modelname` should be cased according to the plain text casing, i.e., BERT, RoBERTa, DeBERTa. + +Once the command has finished, you should have a one new file inside the newly created folder named `test_tokenization_Xxx.py`. At this point the template is finished and you can move it to the sub-folder of the corresponding model in the test folder. diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter-template-{{cookiecutter.modelname}}/test_tokenization_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter-template-{{cookiecutter.modelname}}/test_tokenization_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..36e35c04ed336eb364073756eeb3f0251d41e2c8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter-template-{{cookiecutter.modelname}}/test_tokenization_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,78 @@ +# coding=utf-8 +# Copyright 2022 {{cookiecutter.authors}}. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the {{cookiecutter.modelname}} tokenizer. """ + + +import unittest + +{% if cookiecutter.has_slow_class == "True" and cookiecutter.has_fast_class == "True" -%} +from transformers import {{cookiecutter.camelcase_modelname}}Tokenizer, {{cookiecutter.camelcase_modelname}}TokenizerFast +{% elif cookiecutter.has_slow_class == "True" -%} +from transformers import {{cookiecutter.camelcase_modelname}}Tokenizer +{% elif cookiecutter.has_fast_class == "True" -%} +from transformers import {{cookiecutter.camelcase_modelname}}TokenizerFast +{% endif -%} +{% if cookiecutter.has_fast_class == "True" and cookiecutter.slow_tokenizer_use_sentencepiece == "True" -%} +from transformers.testing_utils import require_sentencepiece, require_tokenizers +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_sentencepiece +@require_tokenizers +{% elif cookiecutter.slow_tokenizer_use_sentencepiece == "True" -%} +from transformers.testing_utils import require_sentencepiece +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_sentencepiece +{% elif cookiecutter.has_fast_class == "True" -%} +from transformers.testing_utils import require_tokenizers +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +{% else -%} +from ...test_tokenization_common import TokenizerTesterMixin + + +{% endif -%} +class {{cookiecutter.camelcase_modelname}}TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + {% if cookiecutter.has_slow_class == "True" -%} + tokenizer_class = {{cookiecutter.camelcase_modelname}}Tokenizer + test_slow_tokenizer = True + {% else -%} + tokenizer_class = None + test_slow_tokenizer = False + {% endif -%} + {% if cookiecutter.has_fast_class == "True" -%} + rust_tokenizer_class = {{cookiecutter.camelcase_modelname}}TokenizerFast + test_rust_tokenizer = True + {% else -%} + rust_tokenizer_class = None + test_rust_tokenizer = False + {% endif -%} + {% if cookiecutter.slow_tokenizer_use_sentencepiece == "True" -%} + test_sentencepiece = True + {% endif -%} + # TODO: Check in `TokenizerTesterMixin` if other attributes need to be changed + def setUp(self): + super().setUp() + + raise NotImplementedError( + "Here you have to implement the saving of a toy tokenizer in " + "`self.tmpdirname`." + ) + + # TODO: add tests with hard-coded target values \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter.json new file mode 100644 index 0000000000000000000000000000000000000000..2e53818f9bb65842172365b7a6d9a9ec982f4390 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_missing_tokenization_test/cookiecutter.json @@ -0,0 +1,10 @@ +{ + "modelname": "BrandNewBERT", + "uppercase_modelname": "BRAND_NEW_BERT", + "lowercase_modelname": "brand_new_bert", + "camelcase_modelname": "BrandNewBert", + "has_slow_class": ["True", "False"], + "has_fast_class": ["True", "False"], + "slow_tokenizer_use_sentencepiece": ["True", "False"], + "authors": "The HuggingFace Team" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/README.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cbab2f3c3a3d0129f3edb7e60acc8bd515e11768 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/README.md @@ -0,0 +1,38 @@ + + +# How to add a new example script in 🤗 Transformers + +This folder provide a template for adding a new example script implementing a training or inference task with the +models in the 🤗 Transformers library. To use it, you will need to install cookiecutter: +``` +pip install cookiecutter +``` +or refer to the installation page of the [cookiecutter documentation](https://cookiecutter.readthedocs.io/). + +You can then run the following command inside the `examples` folder of the transformers repo: +``` +cookiecutter ../templates/adding_a_new_example_script/ +``` +and answer the questions asked, which will generate a new folder where you will find a pre-filled template for your +example following the best practices we recommend for them. + +Adjust the way the data is preprocessed, the model is loaded or the Trainer is instantiated then when you're happy, add +a `README.md` in the folder (or complete the existing one if you added a script to an existing folder) telling a user +how to run your script. + +Make a PR to the 🤗 Transformers repo. Don't forget to tweet about your new example with a carbon screenshot of how to +run it and tag @huggingface! diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/cookiecutter.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/cookiecutter.json new file mode 100644 index 0000000000000000000000000000000000000000..dd8dfdae3f2c35f3ed2ecf0a1f05fe256306842a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/cookiecutter.json @@ -0,0 +1,9 @@ +{ + "example_name": "text classification", + "directory_name": "{{cookiecutter.example_name|lower|replace(' ', '-')}}", + "example_shortcut": "{{cookiecutter.directory_name}}", + "model_class": "AutoModel", + "authors": "The HuggingFace Team", + "can_train_from_scratch": ["True", "False"], + "with_trainer": ["True", "False"] +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/{{cookiecutter.directory_name}}/run_{{cookiecutter.example_shortcut}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/{{cookiecutter.directory_name}}/run_{{cookiecutter.example_shortcut}}.py new file mode 100644 index 0000000000000000000000000000000000000000..e7a622edd71527b9766d7cc99d59fc94977977ca --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_example_script/{{cookiecutter.directory_name}}/run_{{cookiecutter.example_shortcut}}.py @@ -0,0 +1,905 @@ +#!/usr/bin/env python +# coding=utf-8 +# Copyright 2022 {{cookiecutter.authors}} and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Fine-tuning a 🤗 Transformers model on {{cookiecutter.example_name}}. +""" +# You can also adapt this script on your own {{cookiecutter.example_name}} task. Pointers for this are left as comments. + +{%- if cookiecutter.with_trainer == "True" %} + +import logging +import math +import os +import sys +from dataclasses import dataclass, field +from typing import Optional, List + +import datasets +import torch +from datasets import load_dataset + +import transformers +from transformers import ( + CONFIG_MAPPING, + MODEL_MAPPING, + AutoConfig, + {{cookiecutter.model_class}}, + AutoTokenizer, + DataCollatorWithPadding, + HfArgumentParser, + Trainer, + TrainingArguments, + default_data_collator, + set_seed, +) +from transformers.trainer_utils import get_last_checkpoint +from transformers.utils import send_example_telemetry + + +logger = logging.getLogger(__name__) + + +{%- if cookiecutter.can_train_from_scratch == "True" %} +# You should update this to your particular problem to have better documentation of `model_type` +MODEL_CONFIG_CLASSES = list(MODEL_MAPPING.keys()) +MODEL_TYPES = tuple(conf.model_type for conf in MODEL_CONFIG_CLASSES) + + +@dataclass +class ModelArguments: + """ + Arguments pertaining to which model/config/tokenizer we are going to fine-tune, or train from scratch. + """ + + model_name_or_path: Optional[str] = field( + default=None, + metadata={ + "help": "The model checkpoint for weights initialization." + "Don't set if you want to train a model from scratch." + }, + ) + model_type: Optional[str] = field( + default=None, + metadata={"help": "If training from scratch, pass a model type from the list: " + ", ".join(MODEL_TYPES)}, + ) + config_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} + ) + tokenizer_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} + ) + cache_dir: Optional[str] = field( + default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"} + ) + use_fast_tokenizer: bool = field( + default=True, + metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, + ) +{%- elif cookiecutter.can_train_from_scratch == "False" %} +@dataclass +class ModelArguments: + """ + Arguments pertaining to which model/config/tokenizer we are going to fine-tune from. + """ + + model_name_or_path: str = field( + metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"} + ) + config_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} + ) + tokenizer_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} + ) + cache_dir: Optional[str] = field( + default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"} + ) + use_fast_tokenizer: bool = field( + default=True, + metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, + ) + model_revision: str = field( + default="main", + metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."}, + ) + use_auth_token: bool = field( + default=False, + metadata={ + "help": "Will use the token generated when running `huggingface-cli login` (necessary to use this script " + "with private models)." + }, + ) +{% endif %} + + +@dataclass +class DataTrainingArguments: + """ + Arguments pertaining to what data we are going to input our model for training and eval. + """ + + dataset_name: Optional[str] = field( + default=None, metadata={"help": "The name of the dataset to use (via the datasets library)."} + ) + dataset_config_name: Optional[str] = field( + default=None, metadata={"help": "The configuration name of the dataset to use (via the datasets library)."} + ) + train_file: Optional[str] = field(default=None, metadata={"help": "The input training data file (a text file)."}) + validation_file: Optional[str] = field( + default=None, + metadata={"help": "An optional input evaluation data file to evaluate the perplexity on (a text file)."}, + ) + test_file: Optional[str] = field( + default=None, + metadata={"help": "An optional input test data file to predict the label on (a text file)."}, + ) + overwrite_cache: bool = field( + default=False, metadata={"help": "Overwrite the cached training and evaluation sets"} + ) + preprocessing_num_workers: Optional[int] = field( + default=None, + metadata={"help": "The number of processes to use for the preprocessing."}, + ) + max_train_samples: Optional[int] = field( + default=None, + metadata={ + "help": "For debugging purposes or quicker training, truncate the number of training examples to this " + "value if set." + }, + ) + max_eval_samples: Optional[int] = field( + default=None, + metadata={ + "help": "For debugging purposes or quicker training, truncate the number of evaluation examples to this " + "value if set." + }, + ) + max_predict_samples: Optional[int] = field( + default=None, + metadata={ + "help": "For debugging purposes or quicker training, truncate the number of prediction examples to this " + "value if set." + }, + ) + + def __post_init__(self): + if ( + self.dataset_name is None + and self.train_file is None + and self.validation_file is None + and self.test_file is None + ): + raise ValueError("Need either a dataset name or a training/validation/test file.") + else: + if self.train_file is not None: + extension = self.train_file.split(".")[-1] + assert extension in ["csv", "json", "txt"], "`train_file` should be a csv, a json or a txt file." + if self.validation_file is not None: + extension = self.validation_file.split(".")[-1] + assert extension in ["csv", "json", "txt"], "`validation_file` should be a csv, a json or a txt file." + if self.test_file is not None: + extension = self.test_file.split(".")[-1] + assert extension in ["csv", "json", "txt"], "`test_file` should be a csv, a json or a txt file." + + +def main(): + # See all possible arguments in src/transformers/training_args.py + # or by passing the --help flag to this script. + # We now keep distinct sets of args, for a cleaner separation of concerns. + + parser = HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)) + if len(sys.argv) == 2 and sys.argv[1].endswith(".json"): + # If we pass only one argument to the script and it's the path to a json file, + # let's parse it to get our arguments. + model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1])) + else: + model_args, data_args, training_args = parser.parse_args_into_dataclasses() + + # Sending telemetry. Tracking the example usage helps us better allocate resources to maintain them. The + # information sent is the one passed as arguments along with your Python/PyTorch versions. + send_example_telemetry("run_{{cookiecutter.example_shortcut}}", model_args, data_args) + + # Detecting last checkpoint. + last_checkpoint = None + if os.path.isdir(training_args.output_dir) and training_args.do_train and not training_args.overwrite_output_dir: + last_checkpoint = get_last_checkpoint(training_args.output_dir) + if last_checkpoint is None and len(os.listdir(training_args.output_dir)) > 0: + raise ValueError( + f"Output directory ({training_args.output_dir}) already exists and is not empty. " + "Use --overwrite_output_dir to overcome." + ) + elif last_checkpoint is not None: + logger.info( + f"Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change " + "the `--output_dir` or add `--overwrite_output_dir` to train from scratch." + ) + + # Setup logging + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", + datefmt="%m/%d/%Y %H:%M:%S", + handlers=[logging.StreamHandler(sys.stdout)], + ) + + log_level = training_args.get_process_log_level() + logger.setLevel(log_level) + datasets.utils.logging.set_verbosity(log_level) + transformers.utils.logging.set_verbosity(log_level) + transformers.utils.logging.enable_default_handler() + transformers.utils.logging.enable_explicit_format() + + # Log on each process the small summary: + logger.warning( + f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}" + + f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}" + ) + logger.info(f"Training/evaluation parameters {training_args}") + + # Set seed before initializing model. + set_seed(training_args.seed) + + # Get the datasets: you can either provide your own CSV/JSON/TXT training and evaluation files (see below) + # or just provide the name of one of the public datasets available on the hub at https://huggingface.co/datasets/ + # (the dataset will be downloaded automatically from the datasets Hub). + # + # For CSV/JSON files, this script will use the column called 'text' or the first column if no column called + # 'text' is found. You can easily tweak this behavior (see below). + # + # In distributed training, the load_dataset function guarantee that only one local process can concurrently + # download the dataset. + if data_args.dataset_name is not None: + # Downloading and loading a dataset from the hub. + raw_datasets = load_dataset(data_args.dataset_name, data_args.dataset_config_name) + else: + data_files = {} + if data_args.train_file is not None: + data_files["train"] = data_args.train_file + extension = data_args.train_file.split(".")[-1] + if data_args.validation_file is not None: + data_files["validation"] = data_args.validation_file + extension = data_args.validation_file.split(".")[-1] + if data_args.test_file is not None: + data_files["test"] = data_args.test_file + extension = data_args.test_file.split(".")[-1] + if extension == "txt": + extension = "text" + raw_datasets = load_dataset(extension, data_files=data_files) + # See more about loading any type of standard or custom dataset (from files, python dict, pandas DataFrame, etc) at + # https://huggingface.co/docs/datasets/loading_datasets.html. + + # Load pretrained model and tokenizer + # + # Distributed training: + # The .from_pretrained methods guarantee that only one local process can concurrently + # download model & vocab. +{%- if cookiecutter.can_train_from_scratch == "True" %} + config_kwargs = { + "cache_dir": model_args.cache_dir, + "revision": model_args.model_revision, + "use_auth_token": True if model_args.use_auth_token else None, + } + if model_args.config_name: + config = AutoConfig.from_pretrained(model_args.config_name, **config_kwargs) + elif model_args.model_name_or_path: + config = AutoConfig.from_pretrained(model_args.model_name_or_path, **config_kwargs) + else: + config = CONFIG_MAPPING[model_args.model_type]() + logger.warning("You are instantiating a new config instance from scratch.") + + tokenizer_kwargs = { + "cache_dir": model_args.cache_dir, + "use_fast": model_args.use_fast_tokenizer, + "revision": model_args.model_revision, + "use_auth_token": True if model_args.use_auth_token else None, + } + if model_args.tokenizer_name: + tokenizer = AutoTokenizer.from_pretrained(model_args.tokenizer_name, **tokenizer_kwargs) + elif model_args.model_name_or_path: + tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, **tokenizer_kwargs) + else: + raise ValueError( + "You are instantiating a new tokenizer from scratch. This is not supported by this script." + "You can do it from another script, save it, and load it from here, using --tokenizer_name." + ) + + if model_args.model_name_or_path: + model = {{cookiecutter.model_class}}.from_pretrained( + model_args.model_name_or_path, + from_tf=bool(".ckpt" in model_args.model_name_or_path), + config=config, + cache_dir=model_args.cache_dir, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, + ) + else: + logger.info("Training new model from scratch") + model = {{cookiecutter.model_class}}.from_config(config) + + model.resize_token_embeddings(len(tokenizer)) +{%- elif cookiecutter.can_train_from_scratch == "False" %} + config = AutoConfig.from_pretrained( + model_args.config_name if model_args.config_name else model_args.model_name_or_path, + # num_labels=num_labels, Uncomment if you have a certain number of labels + finetuning_task=data_args.task_name, + cache_dir=model_args.cache_dir, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, + ) + tokenizer = AutoTokenizer.from_pretrained( + model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path, + cache_dir=model_args.cache_dir, + use_fast=model_args.use_fast_tokenizer, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, + ) + model = AutoModelForSequenceClassification.from_pretrained( + model_args.model_name_or_path, + from_tf=bool(".ckpt" in model_args.model_name_or_path), + config=config, + cache_dir=model_args.cache_dir, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, + ) +{% endif %} + + # Preprocessing the datasets. + # First we tokenize all the texts. + if training_args.do_train: + column_names = raw_datasets["train"].column_names + elif training_args.do_eval: + column_names = raw_datasets["validation"].column_names + elif training_args.do_predict: + column_names = raw_datasets["test"].column_names + text_column_name = "text" if "text" in column_names else column_names[0] + + def tokenize_function(examples): + return tokenizer(examples[text_column_name], padding="max_length", truncation=True) + + if training_args.do_train: + if "train" not in raw_datasets: + raise ValueError("--do_train requires a train dataset") + train_dataset = raw_datasets["train"] + if data_args.max_train_samples is not None: + # Select Sample from Dataset + train_dataset = train_dataset.select(range(data_args.max_train_samples)) + # tokenize train dataset in batch + with training_args.main_process_first(desc="train dataset map tokenization"): + train_dataset = train_dataset.map( + tokenize_function, + batched=True, + num_proc=data_args.preprocessing_num_workers, + remove_columns=[text_column_name], + load_from_cache_file=not data_args.overwrite_cache, + ) + + if training_args.do_eval: + if "validation" not in raw_datasets: + raise ValueError("--do_eval requires a validation dataset") + eval_dataset = raw_datasets["validation"] + # Selecting samples from dataset + if data_args.max_eval_samples is not None: + eval_dataset = eval_dataset.select(range(data_args.max_eval_samples)) + # tokenize validation dataset + with training_args.main_process_first(desc="validation dataset map tokenization"): + eval_dataset = eval_dataset.map( + tokenize_function, + batched=True, + num_proc=data_args.preprocessing_num_workers, + remove_columns=[text_column_name], + load_from_cache_file=not data_args.overwrite_cache, + ) + + if training_args.do_predict: + if "test" not in raw_datasets: + raise ValueError("--do_predict requires a test dataset") + predict_dataset = raw_datasets["test"] + # Selecting samples from dataset + if data_args.max_predict_samples is not None: + predict_dataset = predict_dataset.select(range(data_args.max_predict_samples)) + # tokenize predict dataset + with training_args.main_process_first(desc="prediction dataset map tokenization"): + predict_dataset = predict_dataset.map( + tokenize_function, + batched=True, + num_proc=data_args.preprocessing_num_workers, + remove_columns=[text_column_name], + load_from_cache_file=not data_args.overwrite_cache, + ) + + # Data collator + data_collator=default_data_collator if not training_args.fp16 else DataCollatorWithPadding(tokenizer, pad_to_multiple_of=8) + + # Initialize our Trainer + trainer = Trainer( + model=model, + args=training_args, + train_dataset=train_dataset if training_args.do_train else None, + eval_dataset=eval_dataset if training_args.do_eval else None, + tokenizer=tokenizer, + data_collator=data_collator, + ) + + # Training + if training_args.do_train: +{%- if cookiecutter.can_train_from_scratch == "False" %} + if last_checkpoint is not None: + checkpoint = last_checkpoint + elif os.path.isdir(model_args.model_name_or_path): + checkpoint = model_args.model_name_or_path + else: + checkpoint = None +{%- elif cookiecutter.can_train_from_scratch == "True" %} + if last_checkpoint is not None: + checkpoint = last_checkpoint + elif model_args.model_name_or_path is not None and os.path.isdir(model_args.model_name_or_path): + checkpoint = model_args.model_name_or_path + else: + checkpoint = None +{% endif %} + train_result = trainer.train(resume_from_checkpoint=checkpoint) + trainer.save_model() # Saves the tokenizer too for easy upload + + metrics = train_result.metrics + max_train_samples = ( + data_args.max_train_samples if data_args.max_train_samples is not None else len(train_dataset) + ) + metrics["train_samples"] = min(max_train_samples, len(train_dataset)) + + trainer.log_metrics("train", metrics) + trainer.save_metrics("train", metrics) + trainer.save_state() + + # Evaluation + if training_args.do_eval: + logger.info("*** Evaluate ***") + + metrics = trainer.evaluate() + + max_eval_samples = data_args.max_eval_samples if data_args.max_eval_samples is not None else len(eval_dataset) + metrics["eval_samples"] = min(max_eval_samples, len(eval_dataset)) + + trainer.log_metrics("eval", metrics) + trainer.save_metrics("eval", metrics) + + # Prediction + if training_args.do_predict: + logger.info("*** Predict ***") + predictions, labels, metrics = trainer.predict(predict_dataset) + + max_predict_samples = data_args.max_predict_samples if data_args.max_predict_samples is not None else len(predict_dataset) + metrics["predict_samples"] = min(max_predict_samples, len(predict_dataset)) + + trainer.log_metrics("predict", metrics) + trainer.save_metrics("predict", metrics) + + # write custom code for saving predictions according to task + +def _mp_fn(index): + # For xla_spawn (TPUs) + main() + + +if __name__ == "__main__": + main() + +{%- elif cookiecutter.with_trainer == "False" %} + +import argparse +import logging +import math +import os +import random + +import datasets +from datasets import load_dataset, load_metric +from torch.utils.data import DataLoader +from tqdm.auto import tqdm + +import transformers +from accelerate import Accelerator +from transformers import ( + CONFIG_MAPPING, + MODEL_MAPPING, + AdamW, + AutoConfig, + {{cookiecutter.model_class}}, + AutoTokenizer, + DataCollatorWithPadding, + PretrainedConfig, + SchedulerType, + default_data_collator, + get_scheduler, + set_seed, +) +from transformers.utils import send_example_telemetry + + +logger = logging.getLogger(__name__) + + +{%- if cookiecutter.can_train_from_scratch == "True" %} +# You should update this to your particular problem to have better documentation of `model_type` +MODEL_CONFIG_CLASSES = list(MODEL_MAPPING.keys()) +MODEL_TYPES = tuple(conf.model_type for conf in MODEL_CONFIG_CLASSES) +{% endif %} + +def parse_args(): + parser = argparse.ArgumentParser(description="Finetune a transformers model on a text classification task") + parser.add_argument( + "--dataset_name", + type=str, + default=None, + help="The name of the dataset to use (via the datasets library).", + ) + parser.add_argument( + "--dataset_config_name", + type=str, + default=None, + help= "The configuration name of the dataset to use (via the datasets library).", + ) + parser.add_argument( + "--train_file", type=str, default=None, help="A csv or a json file containing the training data." + ) + parser.add_argument( + "--validation_file", type=str, default=None, help="A csv or a json file containing the validation data." + ) + parser.add_argument( + "--max_length", + type=int, + default=128, + help=( + "The maximum total input sequence length after tokenization. Sequences longer than this will be truncated," + " sequences shorter will be padded if `--pad_to_max_lengh` is passed." + ), + ) + parser.add_argument( + "--pad_to_max_length", + action="store_true", + help="If passed, pad all samples to `max_length`. Otherwise, dynamic padding is used.", + ) + parser.add_argument( + "--model_name_or_path", + type=str, + help="Path to pretrained model or model identifier from huggingface.co/models.", + required=True, + ) + parser.add_argument( + "--config_name", + type=str, + default=None, + help="Pretrained config name or path if not the same as model_name", + ) + parser.add_argument( + "--tokenizer_name", + type=str, + default=None, + help="Pretrained tokenizer name or path if not the same as model_name", + ) + parser.add_argument( + "--use_slow_tokenizer", + action="store_true", + help="If passed, will use a slow tokenizer (not backed by the 🤗 Tokenizers library).", + ) + parser.add_argument( + "--per_device_train_batch_size", + type=int, + default=8, + help="Batch size (per device) for the training dataloader.", + ) + parser.add_argument( + "--per_device_eval_batch_size", + type=int, + default=8, + help="Batch size (per device) for the evaluation dataloader.", + ) + parser.add_argument( + "--learning_rate", + type=float, + default=5e-5, + help="Initial learning rate (after the potential warmup period) to use.", + ) + parser.add_argument("--weight_decay", type=float, default=0.0, help="Weight decay to use.") + parser.add_argument("--num_train_epochs", type=int, default=3, help="Total number of training epochs to perform.") + parser.add_argument( + "--max_train_steps", + type=int, + default=None, + help="Total number of training steps to perform. If provided, overrides num_train_epochs.", + ) + parser.add_argument( + "--gradient_accumulation_steps", + type=int, + default=1, + help="Number of updates steps to accumulate before performing a backward/update pass.", + ) + parser.add_argument( + "--lr_scheduler_type", + type=SchedulerType, + default="linear", + help="The scheduler type to use.", + choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], + ) + parser.add_argument( + "--num_warmup_steps", type=int, default=0, help="Number of steps for the warmup in the lr scheduler." + ) + parser.add_argument("--output_dir", type=str, default=None, help="Where to store the final model.") + parser.add_argument("--seed", type=int, default=None, help="A seed for reproducible training.") +{%- if cookiecutter.can_train_from_scratch == "True" %} + parser.add_argument( + "--model_type", + type=str, + default=None, + help="Model type to use if training from scratch.", + choices=MODEL_TYPES, + ) +{% endif %} + args = parser.parse_args() + + # Sanity checks + if args.task_name is None and args.train_file is None and args.validation_file is None: + raise ValueError("Need either a task name or a training/validation file.") + else: + if args.train_file is not None: + extension = args.train_file.split(".")[-1] + assert extension in ["csv", "json"], "`train_file` should be a csv or a json file." + if args.validation_file is not None: + extension = args.validation_file.split(".")[-1] + assert extension in ["csv", "json"], "`validation_file` should be a csv or a json file." + + if args.output_dir is not None: + os.makedirs(args.output_dir, exist_ok=True) + + return args + + +def main(): + args = parse_args() + + # Sending telemetry. Tracking the example usage helps us better allocate resources to maintain them. The + # information sent is the one passed as arguments along with your Python/PyTorch versions. + send_example_telemetry("run_{{cookiecutter.example_shortcut}", args) + + # Initialize the accelerator. We will let the accelerator handle device placement for us in this example. + accelerator = Accelerator() + # Make one log on every process with the configuration for debugging. + logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", + datefmt="%m/%d/%Y %H:%M:%S", + level=logging.INFO, + ) + logger.info(accelerator.state) + + # Setup logging, we only want one process per machine to log things on the screen. + # accelerator.is_local_main_process is only True for one process per machine. + logger.setLevel(logging.INFO if accelerator.is_local_main_process else logging.ERROR) + if accelerator.is_local_main_process: + datasets.utils.logging.set_verbosity_warning() + transformers.utils.logging.set_verbosity_info() + else: + datasets.utils.logging.set_verbosity_error() + transformers.utils.logging.set_verbosity_error() + + # If passed along, set the training seed now. + if args.seed is not None: + set_seed(args.seed) + + # Get the datasets: you can either provide your own CSV/JSON/TXT training and evaluation files (see below) + # or just provide the name of one of the public datasets available on the hub at https://huggingface.co/datasets/ + # (the dataset will be downloaded automatically from the datasets Hub). + # + # For CSV/JSON files, this script will use the column called 'text' or the first column if no column called + # 'text' is found. You can easily tweak this behavior (see below). + # + # In distributed training, the load_dataset function guarantee that only one local process can concurrently + # download the dataset. + if args.dataset_name is not None: + # Downloading and loading a dataset from the hub. + raw_datasets = load_dataset(args.dataset_name, args.dataset_config_name) + else: + data_files = {} + if args.train_file is not None: + data_files["train"] = args.train_file + if args.validation_file is not None: + data_files["validation"] = args.validation_file + extension = args.train_file.split(".")[-1] + raw_datasets = load_dataset(extension, data_files=data_files) + # See more about loading any type of standard or custom dataset (from files, python dict, pandas DataFrame, etc) at + # https://huggingface.co/docs/datasets/loading_datasets.html. + + # Load pretrained model and tokenizer + # + # In distributed training, the .from_pretrained methods guarantee that only one local process can concurrently + # download model & vocab. +{%- if cookiecutter.can_train_from_scratch == "True" %} + if model_args.config_name: + config = AutoConfig.from_pretrained(args.model_name_or_path) + elif model_args.model_name_or_path: + config = AutoConfig.from_pretrained(args.model_name_or_path) + else: + config = CONFIG_MAPPING[args.model_type]() + logger.warning("You are instantiating a new config instance from scratch.") + + if model_args.tokenizer_name: + tokenizer = AutoTokenizer.from_pretrained(model_args.tokenizer_name, use_fast=not args.use_slow_tokenizer) + elif model_args.model_name_or_path: + tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, use_fast=not args.use_slow_tokenizer) + else: + raise ValueError( + "You are instantiating a new tokenizer from scratch. This is not supported by this script." + "You can do it from another script, save it, and load it from here, using --tokenizer_name." + ) + + if model_args.model_name_or_path: + model = {{cookiecutter.model_class}}.from_pretrained( + model_args.model_name_or_path, + from_tf=bool(".ckpt" in model_args.model_name_or_path), + config=config, + ) + else: + logger.info("Training new model from scratch") + model = {{cookiecutter.model_class}}.from_config(config) + + model.resize_token_embeddings(len(tokenizer)) +{%- elif cookiecutter.can_train_from_scratch == "False" %} + config = AutoConfig.from_pretrained( + args.config_name if model_args.config_name else args.model_name_or_path, + # num_labels=num_labels, Uncomment if you have a certain number of labels + finetuning_task=data_args.task_name, + ) + tokenizer = AutoTokenizer.from_pretrained( + args.tokenizer_name if model_args.tokenizer_name else args.model_name_or_path, + use_fast=not args.use_slow_tokenizer, + ) + model = AutoModelForSequenceClassification.from_pretrained( + model_args.model_name_or_path, + from_tf=bool(".ckpt" in model_args.model_name_or_path), + config=config, + ) +{% endif %} + + # Preprocessing the datasets. + # First we tokenize all the texts. + column_names = raw_datasets["train"].column_names + text_column_name = "text" if "text" in column_names else column_names[0] + + padding = "max_length" if args.pad_to_max_length else False + def tokenize_function(examples): + result = tokenizer(examples[text_column_name], padding=padding, max_length=args.max_length, truncation=True) + if "label" in examples: + result["labels"] = examples["label"] + return result + + processed_datasets = raw_datasets.map( + preprocess_function, batched=True, remove_columns=raw_datasets["train"].column_names + ) + + train_dataset = processed_datasets["train"] + eval_dataset = processed_datasets["validation"] + + # Log a few random samples from the training set: + for index in random.sample(range(len(train_dataset)), 3): + logger.info(f"Sample {index} of the training set: {train_dataset[index]}.") + + # DataLoaders creation: + if args.pad_to_max_length: + # If padding was already done ot max length, we use the default data collator that will just convert everything + # to tensors. + data_collator = default_data_collator + else: + # Otherwise, `DataCollatorWithPadding` will apply dynamic padding for us (by padding to the maximum length of + # the samples passed). When using mixed precision, we add `pad_to_multiple_of=8` to pad all tensors to multiple + # of 8s, which will enable the use of Tensor Cores on NVIDIA hardware with compute capability >= 7.5 (Volta). + data_collator = DataCollatorWithPadding(tokenizer, pad_to_multiple_of=(8 if accelerator.use_fp16 else None)) + + train_dataloader = DataLoader( + train_dataset, shuffle=True, collate_fn=data_collator, batch_size=args.per_device_train_batch_size + ) + eval_dataloader = DataLoader(eval_dataset, collate_fn=data_collator, batch_size=args.per_device_eval_batch_size) + + # Optimizer + # Split weights in two groups, one with weight decay and the other not. + no_decay = ["bias", "LayerNorm.weight"] + optimizer_grouped_parameters = [ + { + "params": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)], + "weight_decay": args.weight_decay, + }, + { + "params": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)], + "weight_decay": 0.0, + }, + ] + optimizer = AdamW(optimizer_grouped_parameters, lr=args.learning_rate) + + # Prepare everything with our `accelerator`. + model, optimizer, train_dataloader, eval_dataloader = accelerator.prepare( + model, optimizer, train_dataloader, eval_dataloader + ) + + # Note -> the training dataloader needs to be prepared before we grab his length below (cause its length will be + # shorter in multiprocess) + + # Scheduler and math around the number of training steps. + num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) + if args.max_train_steps is None: + args.max_train_steps = args.num_train_epochs * num_update_steps_per_epoch + else: + args.num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) + + lr_scheduler = get_scheduler( + name=args.lr_scheduler_type, + optimizer=optimizer, + num_warmup_steps=args.num_warmup_steps, + num_training_steps=args.max_train_steps, + ) + + # TODO Get the proper metric function + # metric = load_metric(xxx) + + # Train! + total_batch_size = args.per_device_train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps + + logger.info("***** Running training *****") + logger.info(f" Num examples = {len(train_dataset)}") + logger.info(f" Num Epochs = {args.num_train_epochs}") + logger.info(f" Instantaneous batch size per device = {args.per_device_train_batch_size}") + logger.info(f" Total train batch size (w. parallel, distributed & accumulation) = {total_batch_size}") + logger.info(f" Gradient Accumulation steps = {args.gradient_accumulation_steps}") + logger.info(f" Total optimization steps = {args.max_train_steps}") + # Only show the progress bar once on each machine. + progress_bar = tqdm(range(args.max_train_steps), disable=not accelerator.is_local_main_process) + completed_steps = 0 + + for epoch in range(args.num_train_epochs): + model.train() + for step, batch in enumerate(train_dataloader): + outputs = model(**batch) + loss = outputs.loss + loss = loss / args.gradient_accumulation_steps + accelerator.backward(loss) + if step % args.gradient_accumulation_steps == 0 or step == len(train_dataloader) - 1: + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad() + progress_bar.update(1) + completed_steps += 1 + + if completed_steps >= args.max_train_steps: + break + + model.eval() + for step, batch in enumerate(eval_dataloader): + with torch.no_grad(): + outputs = model(**batch) + predictions = outputs.logits.argmax(dim=-1) + metric.add_batch( + predictions=accelerator.gather(predictions), + references=accelerator.gather(batch["labels"]), + ) + + eval_metric = metric.compute() + logger.info(f"epoch {epoch}: {eval_metric}") + + if args.output_dir is not None: + accelerator.wait_for_everyone() + unwrapped_model = accelerator.unwrap_model(model) + unwrapped_model.save_pretrained(args.output_dir, save_function=accelerator.save) + + +if __name__ == "__main__": + main() + +{% endif %} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/ADD_NEW_MODEL_PROPOSAL_TEMPLATE.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/ADD_NEW_MODEL_PROPOSAL_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..2018068375911c1b8ef17db84dc0adc5bb799ee6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/ADD_NEW_MODEL_PROPOSAL_TEMPLATE.md @@ -0,0 +1,1141 @@ +**TEMPLATE** +===================================== + +*search & replace the following keywords, e.g.:* +`:%s/\[name of model\]/brand_new_bert/g` + +-[lowercase name of model] # e.g. brand_new_bert + +-[camelcase name of model] # e.g. BrandNewBert + +-[name of mentor] # e.g. [Peter](https://github.com/peter) + +-[link to original repo] + +-[start date] + +-[end date] + + + +How to add [camelcase name of model] to 🤗 Transformers? +===================================== + +Mentor: [name of mentor] + +Begin: [start date] + +Estimated End: [end date] + +Adding a new model is often difficult and requires an in-depth knowledge +of the 🤗 Transformers library and ideally also of the model's original +repository. At Hugging Face, we are trying to empower the community more +and more to add models independently. + +The following sections explain in detail how to add [camelcase name of model] +to Transformers. You will work closely with [name of mentor] to +integrate [camelcase name of model] into Transformers. By doing so, you will both gain a +theoretical and deep practical understanding of [camelcase name of model]. +But more importantly, you will have made a major +open-source contribution to Transformers. Along the way, you will: + +- get insights into open-source best practices +- understand the design principles of one of the most popular NLP + libraries +- learn how to do efficiently test large NLP models +- learn how to integrate Python utilities like `black`, `ruff`, + `make fix-copies` into a library to always ensure clean and readable + code + +To start, let's try to get a general overview of the Transformers +library. + +General overview of 🤗 Transformers +---------------------------------- + +First, you should get a general overview of 🤗 Transformers. Transformers +is a very opinionated library, so there is a chance that +you don't agree with some of the library's philosophies or design +choices. From our experience, however, we found that the fundamental +design choices and philosophies of the library are crucial to +efficiently scale Transformers while keeping maintenance costs at a +reasonable level. + +A good first starting point to better understand the library is to read +the [documentation of our philosophy](https://huggingface.co/transformers/philosophy.html). +As a result of our way of working, there are some choices that we try to apply to all models: + +- Composition is generally favored over abstraction +- Duplicating code is not always bad if it strongly improves the + readability or accessibility of a model +- Model files are as self-contained as possible so that when you read + the code of a specific model, you ideally only have to look into the + respective `modeling_....py` file. + +In our opinion, the library's code is not just a means to provide a +product, *e.g.*, the ability to use BERT for inference, but also as the +very product that we want to improve. Hence, when adding a model, the +user is not only the person that will use your model, but also everybody +that will read, try to understand, and possibly tweak your code. + +With this in mind, let's go a bit deeper into the general library +design. + +### Overview of models + +To successfully add a model, it is important to understand the +interaction between your model and its config, +`PreTrainedModel`, and `PretrainedConfig`. For +exemplary purposes, we will call the PyTorch model to be added to 🤗 Transformers +`BrandNewBert`. + +Let's take a look: + +![image](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers_overview.png) + +As you can see, we do make use of inheritance in 🤗 Transformers, but we +keep the level of abstraction to an absolute minimum. There are never +more than two levels of abstraction for any model in the library. +`BrandNewBertModel` inherits from +`BrandNewBertPreTrainedModel` which in +turn inherits from `PreTrainedModel` and that's it. +As a general rule, we want to make sure +that a new model only depends on `PreTrainedModel`. The +important functionalities that are automatically provided to every new +model are +`PreTrainedModel.from_pretrained` and `PreTrainedModel.save_pretrained`, which are +used for serialization and deserialization. All +of the other important functionalities, such as +`BrandNewBertModel.forward` should be +completely defined in the new `modeling_brand_new_bert.py` module. Next, +we want to make sure that a model with a specific head layer, such as +`BrandNewBertForMaskedLM` does not inherit +from `BrandNewBertModel`, but rather uses +`BrandNewBertModel` as a component that +can be called in its forward pass to keep the level of abstraction low. +Every new model requires a configuration class, called +`BrandNewBertConfig`. This configuration +is always stored as an attribute in +`PreTrainedModel`, and +thus can be accessed via the `config` attribute for all classes +inheriting from `BrandNewBertPreTrainedModel` + +```python +# assuming that `brand_new_bert` belongs to the organization `brandy` +model = BrandNewBertModel.from_pretrained("brandy/brand_new_bert") +model.config # model has access to its config +``` + +Similar to the model, the configuration inherits basic serialization and +deserialization functionalities from +`PretrainedConfig`. Note +that the configuration and the model are always serialized into two +different formats - the model to a `pytorch_model.bin` file +and the configuration to a `config.json` file. Calling +`PreTrainedModel.save_pretrained` will automatically call +`PretrainedConfig.save_pretrained`, so that both model and configuration are saved. + +### Overview of tokenizers + +Not quite ready yet :-( This section will be added soon! + +Step-by-step recipe to add a model to 🤗 Transformers +---------------------------------------------------- + +Everyone has different preferences of how to port a model so it can be +very helpful for you to take a look at summaries of how other +contributors ported models to Hugging Face. Here is a list of community +blog posts on how to port a model: + +1. [Porting GPT2 + Model](https://medium.com/huggingface/from-tensorflow-to-pytorch-265f40ef2a28) + by [Thomas](https://huggingface.co/thomwolf) +2. [Porting WMT19 MT Model](https://huggingface.co/blog/porting-fsmt) + by [Stas](https://huggingface.co/stas) + +From experience, we can tell you that the most important things to keep +in mind when adding a model are: + +- Don't reinvent the wheel! Most parts of the code you will add for + the new 🤗 Transformers model already exist somewhere in 🤗 + Transformers. Take some time to find similar, already existing + models and tokenizers you can copy from. + [grep](https://www.gnu.org/software/grep/) and + [rg](https://github.com/BurntSushi/ripgrep) are your friends. Note + that it might very well happen that your model's tokenizer is based + on one model implementation, and your model's modeling code on + another one. *E.g.*, FSMT's modeling code is based on BART, while + FSMT's tokenizer code is based on XLM. +- It's more of an engineering challenge than a scientific challenge. + You should spend more time on creating an efficient debugging + environment than trying to understand all theoretical aspects of the + model in the paper. +- Ask for help when you're stuck! Models are the core component of 🤗 + Transformers so we, at Hugging Face, are more than happy to help + you at every step to add your model. Don't hesitate to ask if you + notice you are not making progress. + +In the following, we try to give you a general recipe that we found most +useful when porting a model to 🤗 Transformers. + +The following list is a summary of everything that has to be done to add +a model and can be used by you as a To-Do List: + +1. [ ] (Optional) Understood theoretical aspects + +2. [ ] Prepared transformers dev environment + +3. [ ] Set up debugging environment of the original repository + +4. [ ] Created script that successfully runs forward pass using + original repository and checkpoint + +5. [ ] Successfully opened a PR and added the model skeleton to Transformers + +6. [ ] Successfully converted original checkpoint to Transformers + checkpoint + +7. [ ] Successfully ran forward pass in Transformers that gives + identical output to original checkpoint + +8. [ ] Finished model tests in Transformers + +9. [ ] Successfully added Tokenizer in Transformers + +10. [ ] Run end-to-end integration tests + +11. [ ] Finished docs + +12. [ ] Uploaded model weights to the hub + +13. [ ] Submitted the pull request for review + +14. [ ] (Optional) Added a demo notebook + +To begin with, we usually recommend to start by getting a good +theoretical understanding of `[camelcase name of model]`. However, if you prefer to +understand the theoretical aspects of the model *on-the-job*, then it is +totally fine to directly dive into the `[camelcase name of model]`'s code-base. This +option might suit you better, if your engineering skills are better than +your theoretical skill, if you have trouble understanding +`[camelcase name of model]`'s paper, or if you just enjoy programming much more than +reading scientific papers. + +### 1. (Optional) Theoretical aspects of [camelcase name of model] + +You should take some time to read *[camelcase name of model]'s* paper, if such +descriptive work exists. There might be large sections of the paper that +are difficult to understand. If this is the case, this is fine - don't +worry! The goal is not to get a deep theoretical understanding of the +paper, but to extract the necessary information required to effectively +re-implement the model in 🤗 Transformers. That being said, you don't +have to spend too much time on the theoretical aspects, but rather focus +on the practical ones, namely: + +- What type of model is *[camelcase name of model]*? BERT-like encoder-only + model? GPT2-like decoder-only model? BART-like encoder-decoder + model? Look at the `model_summary` if + you're not familiar with the differences between those. +- What are the applications of *[camelcase name of model]*? Text + classification? Text generation? Seq2Seq tasks, *e.g.,* + summarization? +- What is the novel feature of the model making it different from + BERT/GPT-2/BART? +- Which of the already existing [🤗 Transformers + models](https://huggingface.co/transformers/#contents) is most + similar to *[camelcase name of model]*? +- What type of tokenizer is used? A sentencepiece tokenizer? Word + piece tokenizer? Is it the same tokenizer as used for BERT or BART? + +After you feel like you have gotten a good overview of the architecture +of the model, you might want to write to [name of mentor] with any +questions you might have. This might include questions regarding the +model's architecture, its attention layer, etc. We will be more than +happy to help you. + + +#### Additional resources + + Before diving into the code, here are some additional resources that might be worth taking a look at: + + - [link 1] + - [link 2] + - [link 3] + - ... + +#### Make sure you've understood the fundamental aspects of [camelcase name of model] + +Alright, now you should be ready to take a closer look into the actual code of [camelcase name of model]. +You should have understood the following aspects of [camelcase name of model] by now: + +- [characteristic 1 of [camelcase name of model]] +- [characteristic 2 of [camelcase name of model]] +- ... + +If any of the mentioned aspects above are **not** clear to you, now is a great time to talk to [name of mentor]. + +### 2. Next prepare your environment + +1. Fork the [repository](https://github.com/huggingface/transformers) + by clicking on the 'Fork' button on the repository's page. This + creates a copy of the code under your GitHub user account. + +2. Clone your `transformers` fork to your local disk, and add the base + repository as a remote: + + ```bash + git clone https://github.com/[your Github handle]/transformers.git + cd transformers + git remote add upstream https://github.com/huggingface/transformers.git + ``` + +3. Set up a development environment, for instance by running the + following command: + + ```bash + python -m venv .env + source .env/bin/activate + pip install -e ".[dev]" + ``` + +and return to the parent directory + +```bash +cd .. +``` + +4. We recommend adding the PyTorch version of *[camelcase name of model]* to + Transformers. To install PyTorch, please follow the instructions [here](https://pytorch.org/get-started/locally/). + +**Note:** You don't need to have CUDA installed. Making the new model +work on CPU is sufficient. + +5. To port *[camelcase name of model]*, you will also need access to its + original repository: + +```bash +git clone [link to original repo].git +cd [lowercase name of model] +pip install -e . +``` + +Now you have set up a development environment to port *[camelcase name of model]* +to 🤗 Transformers. + +### Run a pretrained checkpoint using the original repository + +**3. Set up debugging environment** + +At first, you will work on the original *[camelcase name of model]* repository. +Often, the original implementation is very "researchy". Meaning that +documentation might be lacking and the code can be difficult to +understand. But this should be exactly your motivation to reimplement +*[camelcase name of model]*. At Hugging Face, one of our main goals is to *make +people stand on the shoulders of giants* which translates here very well +into taking a working model and rewriting it to make it as **accessible, +user-friendly, and beautiful** as possible. This is the number-one +motivation to re-implement models into 🤗 Transformers - trying to make +complex new NLP technology accessible to **everybody**. + +You should start thereby by diving into the [original repository]([link to original repo]). + +Successfully running the official pretrained model in the original +repository is often **the most difficult** step. From our experience, it +is very important to spend some time getting familiar with the original +code-base. You need to figure out the following: + +- Where to find the pretrained weights? +- How to load the pretrained weights into the corresponding model? +- How to run the tokenizer independently from the model? +- Trace one forward pass so that you know which classes and functions + are required for a simple forward pass. Usually, you only have to + reimplement those functions. +- Be able to locate the important components of the model: Where is + the model's class? Are there model sub-classes, *e.g.*, + EncoderModel, DecoderModel? Where is the self-attention layer? Are + there multiple different attention layers, *e.g.*, *self-attention*, + *cross-attention*...? +- How can you debug the model in the original environment of the repo? + Do you have to add `print` statements, can you work with + an interactive debugger like [ipdb](https://pypi.org/project/ipdb/), or should you use + an efficient IDE to debug the model, like PyCharm? + +It is very important that before you start the porting process, that you +can **efficiently** debug code in the original repository! Also, +remember that you are working with an open-source library, so do not +hesitate to open an issue, or even a pull request in the original +repository. The maintainers of this repository are most likely very +happy about someone looking into their code! + +At this point, it is really up to you which debugging environment and +strategy you prefer to use to debug the original model. We strongly +advise against setting up a costly GPU environment, but simply work on a +CPU both when starting to dive into the original repository and also +when starting to write the 🤗 Transformers implementation of the model. +Only at the very end, when the model has already been successfully +ported to 🤗 Transformers, one should verify that the model also works as +expected on GPU. + +In general, there are two possible debugging environments for running +the original model + +- [Jupyter notebooks](https://jupyter.org/) / [google colab](https://colab.research.google.com/notebooks/intro.ipynb) +- Local python scripts. + +Jupyter notebooks have the advantage that they allow for cell-by-cell +execution which can be helpful to better split logical components from +one another and to have faster debugging cycles as intermediate results +can be stored. Also, notebooks are often easier to share with other +contributors, which might be very helpful if you want to ask the Hugging +Face team for help. If you are familiar with Jupyter notebooks, we +strongly recommend you to work with them. + +The obvious disadvantage of Jupyter notebooks is that if you are not +used to working with them you will have to spend some time adjusting to +the new programming environment and that you might not be able to use +your known debugging tools anymore, like `ipdb`. + +**4. Successfully run forward pass** + +For each code-base, a good first step is always to load a **small** +pretrained checkpoint and to be able to reproduce a single forward pass +using a dummy integer vector of input IDs as an input. Such a script +could look like this (in pseudocode): + +```python +model = [camelcase name of model]Model.load_pretrained_checkpoint("/path/to/checkpoint/") +input_ids = [0, 4, 5, 2, 3, 7, 9] # vector of input ids +original_output = model.predict(input_ids) +``` + +Next, regarding the debugging strategy, there are generally a few from +which to choose from: + +- Decompose the original model into many small testable components and + run a forward pass on each of those for verification +- Decompose the original model only into the original *tokenizer* and + the original *model*, run a forward pass on those, and use + intermediate print statements or breakpoints for verification + +Again, it is up to you which strategy to choose. Often, one or the other +is advantageous depending on the original code base. + +If the original code-base allows you to decompose the model into smaller +sub-components, *e.g.*, if the original code-base can easily be run in +eager mode, it is usually worth the effort to do so. There are some +important advantages to taking the more difficult road in the beginning: + +- at a later stage when comparing the original model to the Hugging + Face implementation, you can verify automatically for each component + individually that the corresponding component of the 🤗 Transformers + implementation matches instead of relying on visual comparison via + print statements +- it can give you some rope to decompose the big problem of porting a + model into smaller problems of just porting individual components + and thus structure your work better +- separating the model into logical meaningful components will help + you to get a better overview of the model's design and thus to + better understand the model +- at a later stage those component-by-component tests help you to + ensure that no regression occurs as you continue changing your code + +[Lysandre's](https://gist.github.com/LysandreJik/db4c948f6b4483960de5cbac598ad4ed) +integration checks for ELECTRA gives a nice example of how this can be +done. + +However, if the original code-base is very complex or only allows +intermediate components to be run in a compiled mode, it might be too +time-consuming or even impossible to separate the model into smaller +testable sub-components. A good example is [T5's +MeshTensorFlow](https://github.com/tensorflow/mesh/tree/master/mesh_tensorflow) +library which is very complex and does not offer a simple way to +decompose the model into its sub-components. For such libraries, one +often relies on verifying print statements. + +No matter which strategy you choose, the recommended procedure is often +the same in that you should start to debug the starting layers first and +the ending layers last. + +It is recommended that you retrieve the output, either by print +statements or sub-component functions, of the following layers in the +following order: + +1. Retrieve the input IDs passed to the model +2. Retrieve the word embeddings +3. Retrieve the input of the first Transformer layer +4. Retrieve the output of the first Transformer layer +5. Retrieve the output of the following n - 1 Transformer layers +6. Retrieve the output of the whole [camelcase name of model] Model + +Input IDs should thereby consists of an array of integers, *e.g.*, +`input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19]` + +The outputs of the following layers often consist of multi-dimensional +float arrays and can look like this: + +```bash +[[ + [-0.1465, -0.6501, 0.1993, ..., 0.1451, 0.3430, 0.6024], + [-0.4417, -0.5920, 0.3450, ..., -0.3062, 0.6182, 0.7132], + [-0.5009, -0.7122, 0.4548, ..., -0.3662, 0.6091, 0.7648], + ..., + [-0.5613, -0.6332, 0.4324, ..., -0.3792, 0.7372, 0.9288], + [-0.5416, -0.6345, 0.4180, ..., -0.3564, 0.6992, 0.9191], + [-0.5334, -0.6403, 0.4271, ..., -0.3339, 0.6533, 0.8694]]], +``` + +We expect that every model added to 🤗 Transformers passes a couple of +integration tests, meaning that the original model and the reimplemented +version in 🤗 Transformers have to give the exact same output up to a +precision of 0.001! Since it is normal that the exact same model written +in different libraries can give a slightly different output depending on +the library framework, we accept an error tolerance of 1e-3 (0.001). It +is not enough if the model gives nearly the same output, they have to be +the almost identical. Therefore, you will certainly compare the +intermediate outputs of the 🤗 Transformers version multiple times +against the intermediate outputs of the original implementation of +*[camelcase name of model]* in which case an **efficient** debugging environment +of the original repository is absolutely important. Here is some advice +to make your debugging environment as efficient as possible. + +- Find the best way of debugging intermediate results. Is the original + repository written in PyTorch? Then you should probably take the + time to write a longer script that decomposes the original model + into smaller sub-components to retrieve intermediate values. Is the + original repository written in Tensorflow 1? Then you might have to + rely on TensorFlow print operations like + [tf.print](https://www.tensorflow.org/api_docs/python/tf/print) to + output intermediate values. Is the original repository written in + Jax? Then make sure that the model is **not jitted** when running + the forward pass, *e.g.*, check-out [this + link](https://github.com/google/jax/issues/196). +- Use the smallest pretrained checkpoint you can find. The smaller the + checkpoint, the faster your debug cycle becomes. It is not efficient + if your pretrained model is so big that your forward pass takes more + than 10 seconds. In case only very large checkpoints are available, + it might make more sense to create a dummy model in the new + environment with randomly initialized weights and save those weights + for comparison with the 🤗 Transformers version of your model +- Make sure you are using the easiest way of calling a forward pass in + the original repository. Ideally, you want to find the function in + the original repository that **only** calls a single forward pass, + *i.e.* that is often called `predict`, `evaluate`, `forward` or + `__call__`. You don't want to debug a function that calls `forward` + multiple times, *e.g.*, to generate text, like + `autoregressive_sample`, `generate`. +- Try to separate the tokenization from the model's + forward pass. If the original repository shows + examples where you have to input a string, then try to find out + where in the forward call the string input is changed to input ids + and start from this point. This might mean that you have to possibly + write a small script yourself or change the original code so that + you can directly input the ids instead of an input string. +- Make sure that the model in your debugging setup is **not** in + training mode, which often causes the model to yield random outputs + due to multiple dropout layers in the model. Make sure that the + forward pass in your debugging environment is **deterministic** so + that the dropout layers are not used. Or use + `transformers.utils.set_seed` if the old and new + implementations are in the same framework. + +#### More details on how to create a debugging environment for [camelcase name of model] + +[TODO FILL: Here the mentor should add very specific information on what the student should do] +[to set up an efficient environment for the special requirements of this model] + +### Port [camelcase name of model] to 🤗 Transformers + +Next, you can finally start adding new code to 🤗 Transformers. Go into +the clone of your 🤗 Transformers' fork: + + cd transformers + +In the special case that you are adding a model whose architecture +exactly matches the model architecture of an existing model you only +have to add a conversion script as described in [this +section](#write-a-conversion-script). In this case, you can just re-use +the whole model architecture of the already existing model. + +Otherwise, let's start generating a new model with the amazing +Cookiecutter! + +**Use the Cookiecutter to automatically generate the model's code** + +To begin with head over to the [🤗 Transformers +templates](https://github.com/huggingface/transformers/tree/main/templates/adding_a_new_model) +to make use of our `cookiecutter` implementation to automatically +generate all the relevant files for your model. Again, we recommend only +adding the PyTorch version of the model at first. Make sure you follow +the instructions of the `README.md` on the [🤗 Transformers +templates](https://github.com/huggingface/transformers/tree/main/templates/adding_a_new_model) +carefully. + +**Open a Pull Request on the main huggingface/transformers repo** + +Before starting to adapt the automatically generated code, now is the +time to open a "Work in progress (WIP)" pull request, *e.g.*, "\[WIP\] +Add *[camelcase name of model]*", in 🤗 Transformers so that you and the Hugging +Face team can work side-by-side on integrating the model into 🤗 +Transformers. + +You should do the following: + +1. Create a branch with a descriptive name from your main branch + +``` + git checkout -b add_[lowercase name of model] +``` + +2. Commit the automatically generated code: + +``` + git add . + git commit +``` + +3. Fetch and rebase to current main + +``` + git fetch upstream + git rebase upstream/main +``` + +4. Push the changes to your account using: + +``` + git push -u origin a-descriptive-name-for-my-changes +``` + +5. Once you are satisfied, go to the webpage of your fork on GitHub. + Click on "Pull request". Make sure to add the GitHub handle of + [name of mentor] as a reviewer, so that the Hugging + Face team gets notified for future changes. + +6. Change the PR into a draft by clicking on "Convert to draft" on the + right of the GitHub pull request web page. + +In the following, whenever you have done some progress, don't forget to +commit your work and push it to your account so that it shows in the +pull request. Additionally, you should make sure to update your work +with the current main from time to time by doing: + + git fetch upstream + git merge upstream/main + +In general, all questions you might have regarding the model or your +implementation should be asked in your PR and discussed/solved in the +PR. This way, [name of mentor] will always be notified when you are +committing new code or if you have a question. It is often very helpful +to point [name of mentor] to your added code so that the Hugging +Face team can efficiently understand your problem or question. + +To do so, you can go to the "Files changed" tab where you see all of +your changes, go to a line regarding which you want to ask a question, +and click on the "+" symbol to add a comment. Whenever a question or +problem has been solved, you can click on the "Resolve" button of the +created comment. + +In the same way, [name of mentor] will open comments when reviewing +your code. We recommend asking most questions on GitHub on your PR. For +some very general questions that are not very useful for the public, +feel free to ping [name of mentor] by Slack or email. + +**5. Adapt the generated models code for [camelcase name of model]** + +At first, we will focus only on the model itself and not care about the +tokenizer. All the relevant code should be found in the generated files +`src/transformers/models/[lowercase name of model]/modeling_[lowercase name of model].py` and +`src/transformers/models/[lowercase name of model]/configuration_[lowercase name of model].py`. + +Now you can finally start coding :). The generated code in +`src/transformers/models/[lowercase name of model]/modeling_[lowercase name of model].py` will +either have the same architecture as BERT if it's an encoder-only model +or BART if it's an encoder-decoder model. At this point, you should +remind yourself what you've learned in the beginning about the +theoretical aspects of the model: *How is the model different from BERT +or BART?*\". Implement those changes which often means to change the +*self-attention* layer, the order of the normalization layer, etc... +Again, it is often useful to look at the similar architecture of already +existing models in Transformers to get a better feeling of how your +model should be implemented. + +**Note** that at this point, you don't have to be very sure that your +code is fully correct or clean. Rather, it is advised to add a first +*unclean*, copy-pasted version of the original code to +`src/transformers/models/[lowercase name of model]/modeling_[lowercase name of model].py` +until you feel like all the necessary code is added. From our +experience, it is much more efficient to quickly add a first version of +the required code and improve/correct the code iteratively with the +conversion script as described in the next section. The only thing that +has to work at this point is that you can instantiate the 🤗 Transformers +implementation of *[camelcase name of model]*, *i.e.* the following command +should work: + +```python +from transformers import [camelcase name of model]Model, [camelcase name of model]Config +model = [camelcase name of model]Model([camelcase name of model]Config()) +``` + +The above command will create a model according to the default +parameters as defined in `[camelcase name of model]Config()` with random weights, +thus making sure that the `init()` methods of all components works. + +[TODO FILL: Here the mentor should add very specific information on what exactly has to be changed for this model] +[...] +[...] + +**6. Write a conversion script** + +Next, you should write a conversion script that lets you convert the +checkpoint you used to debug *[camelcase name of model]* in the original +repository to a checkpoint compatible with your just created 🤗 +Transformers implementation of *[camelcase name of model]*. It is not advised to +write the conversion script from scratch, but rather to look through +already existing conversion scripts in 🤗 Transformers for one that has +been used to convert a similar model that was written in the same +framework as *[camelcase name of model]*. Usually, it is enough to copy an +already existing conversion script and slightly adapt it for your use +case. Don't hesitate to ask [name of mentor] to point you to a +similar already existing conversion script for your model. + +- If you are porting a model from TensorFlow to PyTorch, a good + starting point might be BERT's conversion script + [here](https://github.com/huggingface/transformers/blob/7acfa95afb8194f8f9c1f4d2c6028224dbed35a2/src/transformers/models/bert/modeling_bert.py#L91) +- If you are porting a model from PyTorch to PyTorch, a good starting + point might be BART's conversion script + [here](https://github.com/huggingface/transformers/blob/main/src/transformers/models/bart/convert_bart_original_pytorch_checkpoint_to_pytorch.py) + +In the following, we'll quickly explain how PyTorch models store layer +weights and define layer names. In PyTorch, the name of a layer is +defined by the name of the class attribute you give the layer. Let's +define a dummy model in PyTorch, called `SimpleModel` as follows: + +```python +from torch import nn + +class SimpleModel(nn.Module): + def __init__(self): + super().__init__() + self.dense = nn.Linear(10, 10) + self.intermediate = nn.Linear(10, 10) + self.layer_norm = nn.LayerNorm(10) +``` + +Now we can create an instance of this model definition which will fill +all weights: `dense`, `intermediate`, `layer_norm` with random weights. +We can print the model to see its architecture + +```python +model = SimpleModel() + +print(model) +``` + +This will print out the following: + +```bash +SimpleModel( + (dense): Linear(in_features=10, out_features=10, bias=True) + (intermediate): Linear(in_features=10, out_features=10, bias=True) + (layer_norm): LayerNorm((10,), eps=1e-05, elementwise_affine=True) +) +``` + +We can see that the layer names are defined by the name of the class +attribute in PyTorch. You can print out the weight values of a specific +layer: + +```python +print(model.dense.weight.data) +``` + +to see that the weights were randomly initialized + +```bash +tensor([[-0.0818, 0.2207, -0.0749, -0.0030, 0.0045, -0.1569, -0.1598, 0.0212, + -0.2077, 0.2157], + [ 0.1044, 0.0201, 0.0990, 0.2482, 0.3116, 0.2509, 0.2866, -0.2190, + 0.2166, -0.0212], + [-0.2000, 0.1107, -0.1999, -0.3119, 0.1559, 0.0993, 0.1776, -0.1950, + -0.1023, -0.0447], + [-0.0888, -0.1092, 0.2281, 0.0336, 0.1817, -0.0115, 0.2096, 0.1415, + -0.1876, -0.2467], + [ 0.2208, -0.2352, -0.1426, -0.2636, -0.2889, -0.2061, -0.2849, -0.0465, + 0.2577, 0.0402], + [ 0.1502, 0.2465, 0.2566, 0.0693, 0.2352, -0.0530, 0.1859, -0.0604, + 0.2132, 0.1680], + [ 0.1733, -0.2407, -0.1721, 0.1484, 0.0358, -0.0633, -0.0721, -0.0090, + 0.2707, -0.2509], + [-0.1173, 0.1561, 0.2945, 0.0595, -0.1996, 0.2988, -0.0802, 0.0407, + 0.1829, -0.1568], + [-0.1164, -0.2228, -0.0403, 0.0428, 0.1339, 0.0047, 0.1967, 0.2923, + 0.0333, -0.0536], + [-0.1492, -0.1616, 0.1057, 0.1950, -0.2807, -0.2710, -0.1586, 0.0739, + 0.2220, 0.2358]]). +``` + +In the conversion script, you should fill those randomly initialized +weights with the exact weights of the corresponding layer in the +checkpoint. *E.g.*, + +```python +# retrieve matching layer weights, e.g. by +# recursive algorithm +layer_name = "dense" +pretrained_weight = array_of_dense_layer + +model_pointer = getattr(model, "dense") + +model_pointer.weight.data = torch.from_numpy(pretrained_weight) +``` + +While doing so, you must verify that each randomly initialized weight of +your PyTorch model and its corresponding pretrained checkpoint weight +exactly match in both **shape and name**. To do so, it is **necessary** +to add assert statements for the shape and print out the names of the +checkpoints weights. *E.g.*, you should add statements like: + +```python +assert ( + model_pointer.weight.shape == pretrained_weight.shape +), f"Pointer shape of random weight {model_pointer.shape} and array shape of checkpoint weight {pretrained_weight.shape} mismatched" +``` + +Besides, you should also print out the names of both weights to make +sure they match, *e.g.*, + +```python +logger.info(f"Initialize PyTorch weight {layer_name} from {pretrained_weight.name}") +``` + +If either the shape or the name doesn't match, you probably assigned +the wrong checkpoint weight to a randomly initialized layer of the 🤗 +Transformers implementation. + +An incorrect shape is most likely due to an incorrect setting of the +config parameters in `[camelcase name of model]Config()` that do not exactly match +those that were used for the checkpoint you want to convert. However, it +could also be that PyTorch's implementation of a layer requires the +weight to be transposed beforehand. + +Finally, you should also check that **all** required weights are +initialized and print out all checkpoint weights that were not used for +initialization to make sure the model is correctly converted. It is +completely normal, that the conversion trials fail with either a wrong +shape statement or wrong name assignment. This is most likely because +either you used incorrect parameters in `[camelcase name of model]Config()`, have a +wrong architecture in the 🤗 Transformers implementation, you have a bug +in the `init()` functions of one of the components of the 🤗 Transformers +implementation or you need to transpose one of the checkpoint weights. + +This step should be iterated with the previous step until all weights of +the checkpoint are correctly loaded in the Transformers model. Having +correctly loaded the checkpoint into the 🤗 Transformers implementation, +you can then save the model under a folder of your choice +`/path/to/converted/checkpoint/folder` that should then contain both a +`pytorch_model.bin` file and a `config.json` file: + +```python +model.save_pretrained("/path/to/converted/checkpoint/folder") +``` + +[TODO FILL: Here the mentor should add very specific information on what exactly has to be done for the conversion of this model] +[...] +[...] + +**7. Implement the forward pass** + +Having managed to correctly load the pretrained weights into the 🤗 +Transformers implementation, you should now make sure that the forward +pass is correctly implemented. In [Get familiar with the original +repository](#34-run-a-pretrained-checkpoint-using-the-original-repository), +you have already created a script that runs a forward pass of the model +using the original repository. Now you should write an analogous script +using the 🤗 Transformers implementation instead of the original one. It +should look as follows: + +[TODO FILL: Here the model name might have to be adapted, *e.g.*, maybe [camelcase name of model]ForConditionalGeneration instead of [camelcase name of model]Model] + +```python +model = [camelcase name of model]Model.from_pretrained("/path/to/converted/checkpoint/folder") +input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19] +output = model(input_ids).last_hidden_states +``` + +It is very likely that the 🤗 Transformers implementation and the +original model implementation don't give the exact same output the very +first time or that the forward pass throws an error. Don't be +disappointed - it's expected! First, you should make sure that the +forward pass doesn't throw any errors. It often happens that the wrong +dimensions are used leading to a `"Dimensionality mismatch"` +error or that the wrong data type object is used, *e.g.*, `torch.long` +instead of `torch.float32`. Don't hesitate to ask [name of mentor] +for help, if you don't manage to solve certain errors. + +The final part to make sure the 🤗 Transformers implementation works +correctly is to ensure that the outputs are equivalent to a precision of +`1e-3`. First, you should ensure that the output shapes are identical, +*i.e.* `outputs.shape` should yield the same value for the script of the +🤗 Transformers implementation and the original implementation. Next, you +should make sure that the output values are identical as well. This one +of the most difficult parts of adding a new model. Common mistakes why +the outputs are not identical are: + +- Some layers were not added, *i.e.* an activation layer + was not added, or the residual connection was forgotten +- The word embedding matrix was not tied +- The wrong positional embeddings are used because the original + implementation uses on offset +- Dropout is applied during the forward pass. To fix this make sure + `model.training is False` and that no dropout layer is + falsely activated during the forward pass, *i.e.* pass + `self.training` to [PyTorch's functional + dropout](https://pytorch.org/docs/stable/nn.functional.html?highlight=dropout#torch.nn.functional.dropout) + +The best way to fix the problem is usually to look at the forward pass +of the original implementation and the 🤗 Transformers implementation +side-by-side and check if there are any differences. Ideally, you should +debug/print out intermediate outputs of both implementations of the +forward pass to find the exact position in the network where the 🤗 +Transformers implementation shows a different output than the original +implementation. First, make sure that the hard-coded `input_ids` in both +scripts are identical. Next, verify that the outputs of the first +transformation of the `input_ids` (usually the word embeddings) are +identical. And then work your way up to the very last layer of the +network. At some point, you will notice a difference between the two +implementations, which should point you to the bug in the 🤗 Transformers +implementation. From our experience, a simple and efficient way is to +add many print statements in both the original implementation and 🤗 +Transformers implementation, at the same positions in the network +respectively, and to successively remove print statements showing the +same values for intermediate presentions. + +When you're confident that both implementations yield the same output, +verifying the outputs with +`torch.allclose(original_output, output, atol=1e-3)`, you're done with +the most difficult part! Congratulations - the work left to be done +should be a cakewalk 😊. + +**8. Adding all necessary model tests** + +At this point, you have successfully added a new model. However, it is +very much possible that the model does not yet fully comply with the +required design. To make sure, the implementation is fully compatible +with 🤗 Transformers, all common tests should pass. The Cookiecutter +should have automatically added a test file for your model, probably +under the same `tests/test_modeling_[lowercase name of model].py`. Run this test +file to verify that all common tests pass: + +```python +pytest tests/test_modeling_[lowercase name of model].py +``` + +[TODO FILL: Here the mentor should add very specific information on what tests are likely to fail after having implemented the model +, e.g. given the model, it might be very likely that `test_attention_output` fails] +[...] +[...] + +Having fixed all common tests, it is now crucial to ensure that all the +nice work you have done is well tested, so that + +- a) The community can easily understand your work by looking at + specific tests of *[camelcase name of model]* + +- b) Future changes to your model will not break any important + feature of the model. + +At first, integration tests should be added. Those integration tests +essentially do the same as the debugging scripts you used earlier to +implement the model to 🤗 Transformers. A template of those model tests +is already added by the Cookiecutter, called +`[camelcase name of model]ModelIntegrationTests` and only has to be filled out by +you. To ensure that those tests are passing, run + +```python +RUN_SLOW=1 pytest -sv tests/test_modeling_[lowercase name of model].py::[camelcase name of model]ModelIntegrationTests +``` + +**Note:** In case you are using Windows, you should replace `RUN_SLOW=1` with `SET RUN_SLOW=1` + +Second, all features that are special to *[camelcase name of model]* should be +tested additionally in a separate test under +`[camelcase name of model]ModelTester`/`[camelcase name of model]ModelTest`. This part is often +forgotten but is extremely useful in two ways: + +- It helps to transfer the knowledge you have acquired during the + model addition to the community by showing how the special features + of *[camelcase name of model]* should work. +- Future contributors can quickly test changes to the model by running + those special tests. + +[TODO FILL: Here the mentor should add very specific information on what special features of the model should be tested additionally] +[...] +[...] + +**9. Implement the tokenizer** + +Next, we should add the tokenizer of *[camelcase name of model]*. Usually, the +tokenizer is equivalent or very similar to an already existing tokenizer +of 🤗 Transformers. + +[TODO FILL: Here the mentor should add a comment whether a new tokenizer is required or if this is not the case which existing tokenizer closest resembles + [camelcase name of model]'s tokenizer and how the tokenizer should be implemented] + [...] + [...] + +It is very important to find/extract the original tokenizer file and to +manage to load this file into the 🤗 Transformers' implementation of the +tokenizer. + +For [camelcase name of model], the tokenizer files can be found here: +- [To be filled out by mentor] + +and having implemented the 🤗 Transformers' version of the tokenizer can be loaded as follows: + +[To be filled out by mentor] + +To ensure that the tokenizer works correctly, it is recommended to first +create a script in the original repository that inputs a string and +returns the `input_ids`. It could look similar to this (in pseudo-code): + +```bash +input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words." +model = [camelcase name of model]Model.load_pretrained_checkpoint("/path/to/checkpoint/") +input_ids = model.tokenize(input_str) +``` + +You might have to take a deeper look again into the original repository +to find the correct tokenizer function or you might even have to do +changes to your clone of the original repository to only output the +`input_ids`. Having written a functional tokenization script that uses +the original repository, an analogous script for 🤗 Transformers should +be created. It should look similar to this: + +```python +from transformers import [camelcase name of model]Tokenizer +input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words." + +tokenizer = [camelcase name of model]Tokenizer.from_pretrained("/path/to/tokenizer/folder/") + +input_ids = tokenizer(input_str).input_ids +``` + +When both `input_ids` yield the same values, as a final step a tokenizer +test file should also be added. + +[TODO FILL: Here mentor should point the student to test files of similar tokenizers] + +Analogous to the modeling test files of *[camelcase name of model]*, the +tokenization test files of *[camelcase name of model]* should contain a couple of +hard-coded integration tests. + +[TODO FILL: Here mentor should again point to an existing similar test of another model that the student can copy & adapt] + +**10. Run End-to-end integration tests** + +Having added the tokenizer, you should also add a couple of end-to-end +integration tests using both the model and the tokenizer to +`tests/test_modeling_[lowercase name of model].py` in 🤗 Transformers. Such a test +should show on a meaningful text-to-text sample that the 🤗 Transformers +implementation works as expected. A meaningful text-to-text sample can +include *e.g.* a source-to-target-translation pair, an +article-to-summary pair, a question-to-answer pair, etc... If none of +the ported checkpoints has been fine-tuned on a downstream task it is +enough to simply rely on the model tests. In a final step to ensure that +the model is fully functional, it is advised that you also run all tests +on GPU. It can happen that you forgot to add some `.to(self.device)` +statements to internal tensors of the model, which in such a test would +show in an error. In case you have no access to a GPU, the Hugging Face +team can take care of running those tests for you. + +**11. Add Docstring** + +Now, all the necessary functionality for *[camelcase name of model]* is added - +you're almost done! The only thing left to add is a nice docstring and +a doc page. The Cookiecutter should have added a template file called +`docs/source/model_doc/[lowercase name of model].rst` that you should fill out. +Users of your model will usually first look at this page before using +your model. Hence, the documentation must be understandable and concise. +It is very useful for the community to add some *Tips* to show how the +model should be used. Don't hesitate to ping [name of mentor] +regarding the docstrings. + +Next, make sure that the docstring added to +`src/transformers/models/[lowercase name of model]/modeling_[lowercase name of model].py` is +correct and included all necessary inputs and outputs. It is always to +good to remind oneself that documentation should be treated at least as +carefully as the code in 🤗 Transformers since the documentation is +usually the first contact point of the community with the model. + +**Code refactor** + +Great, now you have added all the necessary code for *[camelcase name of model]*. +At this point, you should correct some potential incorrect code style by +running: + +```bash +make style +``` + +and verify that your coding style passes the quality check: + +```bash +make quality +``` + +There are a couple of other very strict design tests in 🤗 Transformers +that might still be failing, which shows up in the tests of your pull +request. This is often because of some missing information in the +docstring or some incorrect naming. [name of mentor] will surely +help you if you're stuck here. + +Lastly, it is always a good idea to refactor one's code after having +ensured that the code works correctly. With all tests passing, now it's +a good time to go over the added code again and do some refactoring. + +You have now finished the coding part, congratulation! 🎉 You are +Awesome! 😎 + +**12. Upload the models to the model hub** + +In this final part, you should convert and upload all checkpoints to the +model hub and add a model card for each uploaded model checkpoint. You +should work alongside [name of mentor] here to decide on a fitting +name for each checkpoint and to get the required access rights to be +able to upload the model under the author's organization of +*[camelcase name of model]*. + +It is worth spending some time to create fitting model cards for each +checkpoint. The model cards should highlight the specific +characteristics of this particular checkpoint, *e.g.*, On which dataset +was the checkpoint pretrained/fine-tuned on? On what down-stream task +should the model be used? And also include some code on how to correctly +use the model. + +**13. (Optional) Add notebook** + +It is very helpful to add a notebook that showcases in-detail how +*[camelcase name of model]* can be used for inference and/or fine-tuned on a +downstream task. This is not mandatory to merge your PR, but very useful +for the community. + +**14. Submit your finished PR** + +You're done programming now and can move to the last step, which is +getting your PR merged into main. Usually, [name of mentor] +should have helped you already at this point, but it is worth taking +some time to give your finished PR a nice description and eventually add +comments to your code, if you want to point out certain design choices +to your reviewer. + +### Share your work!! + +Now, it's time to get some credit from the community for your work! +Having completed a model addition is a major contribution to +Transformers and the whole NLP community. Your code and the ported +pre-trained models will certainly be used by hundreds and possibly even +thousands of developers and researchers. You should be proud of your +work and share your achievement with the community. + +**You have made another model that is super easy to access for everyone +in the community! 🤯** diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/README.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/README.md new file mode 100644 index 0000000000000000000000000000000000000000..42c423c02e28a82a9e22e85ec62da1788b38be16 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/README.md @@ -0,0 +1,272 @@ + + +# Adding a new model + +This folder contains templates to generate new models that fit the current API and pass all tests. It generates +models in both PyTorch, TensorFlow, and Flax and completes the `__init__.py` and auto-modeling files, and creates the +documentation. Their use is described in the [next section](#cookiecutter-templates). + +There is also a CLI tool to generate a new model like an existing one called `transformers-cli add-new-model-like`. +Jump to the [Add new model like section](#add-new-model-like-command) to learn how to use it. + +## Cookiecutter Templates + +Using the `cookiecutter` utility requires to have all the `dev` dependencies installed. Let's first clone the +repository and install it in our environment: + +```shell script +git clone https://github.com/huggingface/transformers +cd transformers +pip install -e ".[dev]" +``` + +Depending on your OS, and since the number of optional dependencies of Transformers is growing, you might get a +failure with this command. If that's the case make sure to install the Deep Learning framework you are working with +(PyTorch, TensorFlow and/or Flax) then do: + +```bash +pip install -e ".[quality]" +``` + +Once the installation is done, you can use the CLI command `add-new-model` to generate your models: + +```shell script +transformers-cli add-new-model +``` + +This should launch the `cookiecutter` package which should prompt you to fill in the configuration. + +The `modelname` should be cased according to the plain text casing, i.e., BERT, RoBERTa, DeBERTa. +``` +modelname []: +uppercase_modelname []: +lowercase_modelname []: +camelcase_modelname []: +``` + +Fill in the `authors` with your team members: +``` +authors [The HuggingFace Team]: +``` + +The checkpoint identifier is the checkpoint that will be used in the examples across the files. Put the name you wish, +as it will appear on the modelhub. Do not forget to include the organisation. +``` +checkpoint_identifier [organisation/-base-cased]: +``` + +The tokenizer should either be based on BERT if it behaves exactly like the BERT tokenizer, or a standalone otherwise. +``` +Select tokenizer_type: +1 - Based on BERT +2 - Standalone +Choose from 1, 2 [1]: +``` + + +Once the command has finished, you should have a total of 7 new files spread across the repository: +``` +docs/source/model_doc/.mdx +src/transformers/models//configuration_.py +src/transformers/models//modeling_.py +src/transformers/models//modeling_tf_.py +src/transformers/models//tokenization_.py +tests/test_modeling_.py +tests/test_modeling_tf_.py +``` + +You can run the tests to ensure that they all pass: + +``` +python -m pytest ./tests/test_**.py +``` + +Feel free to modify each file to mimic the behavior of your model. + +⚠ You should be careful about the classes preceded by the following line:️ + +```python +# Copied from transformers.[...] +``` + +This line ensures that the copy does not diverge from the source. If it *should* diverge, because the implementation +is different, this line needs to be deleted. If you don't delete this line and run `make fix-copies`, +your changes will be overwritten. + +Once you have edited the files to fit your architecture, simply re-run the tests (and edit them if a change +is needed!) afterwards to make sure everything works as expected. + +Once the files are generated and you are happy with your changes, here's a checklist to ensure that your contribution +will be merged quickly: + +- You should run the `make fixup` utility to fix the style of the files and to ensure the code quality meets the + library's standards. +- You should complete the documentation file (`docs/source/model_doc/.rst`) so that your model may be + usable. + +## Add new model like command + +Using the `transformers-cli add-new-model-like` command requires to have all the `dev` dependencies installed. Let's +first clone the repository and install it in our environment: + +```shell script +git clone https://github.com/huggingface/transformers +cd transformers +pip install -e ".[dev]" +``` + +Depending on your OS, and since the number of optional dependencies of Transformers is growing, you might get a +failure with this command. If that's the case make sure to install the Deep Learning framework you are working with +(PyTorch, TensorFlow and/or Flax) then do: + +```bash +pip install -e ".[quality]" +``` + +Once the installation is done, you can use the CLI command `add-new-model-like` to generate your models: + +```shell script +transformers-cli add-new-model-like +``` + +This will start a small questionnaire you have to fill. + +``` +What identifier would you like to use for the model type of this model? +``` + +You will have to input the model type of the model you want to clone. The model type can be found in several places: +- inside the configuration of any checkpoint of that model +- the name of the documentation page of that model + +For instance the doc page of `BigBirdPegasus` is `https://huggingface.co/docs/transformers/model_doc/bigbird_pegasus` +so its model type is `"bigbird_pegasus"`. + +If you make a typo, the command will suggest you the closest model types it can find. + +Once this is done, the questionnaire will ask you for the new model name and its various casings: + +``` +What is the name for your new model? +What identifier would you like to use for the model type of this model? +What name would you like to use for the module of this model? +What prefix (camel-cased) would you like to use for the model classes of this model? +What prefix (upper-cased) would you like to use for the constants relative to this model? +``` + +From your answer to the first question, defaults will be determined for all others. The first name should be written +as you want your model be named in the doc, with no special casing (like RoBERTa) and from there, you can either stick +with the defaults or change the cased versions. + +Next will be the name of the config class to use for this model: + +``` +What will be the name of the config class for this model? +``` + +Then, you will be asked for a checkpoint identifier: + +``` +Please give a checkpoint identifier (on the model Hub) for this new model. +``` + +This is the checkpoint that will be used in the examples across the files and the integration tests. Put the name you +wish, as it will appear on the Model Hub. Do not forget to include the organisation. + +Then you will have to say whether your model re-uses the same processing classes as the model you're cloning: + +``` +Will your new model use the same processing class as Xxx (XxxTokenizer/XxxFeatureExtractor/XxxImageProcessor) +``` + +Answer yes if you have no intentions to make any change to the class used for preprocessing. It can use different +files (for instance you can reuse the `BertTokenizer` with a new vocab file). + +If you answer no, you will have to give the name of the classes +for the new tokenizer/image processor/feature extractor/processor (depending on the model you're cloning). + +Next the questionnaire will ask + +``` +Should we add # Copied from statements when creating the new modeling file? +``` + +This is the intenal mechanism used in the library to make sure code copied from various modeling files stay consistent. +If you plan to completely rewrite the modeling file, you should answer no, whereas if you just want to tweak one part +of the model, you should answer yes. + +Lastly, the questionnaire will inquire about frameworks: + +``` +Should we add a version of your new model in all the frameworks implemented by Old Model (xxx)? +``` + +If you answer yes, the new model will have files for all the frameworks implemented by the model you're cloning. +Otherwise, you will get a new question to select the frameworks you want. + +Once the command has finished, you will see a new subfolder in the `src/transformers/models/` folder, with the +necessary files (configuration and modeling files for all frameworks requested, and maybe the processing files, +depending on your choices). + +You will also see a doc file and tests for your new models. First you should run + +``` +make style +make fix-copies +``` + +and then you can start tweaking your model. You should: +- fill the doc file at `docs/source/model_doc/model_name.mdx` +- tweak the configuration and modeling files to your need + +Once you're done, you can run the tests to ensure that they all pass: + +``` +python -m pytest ./tests/test_**.py +``` + +⚠ You should be careful about the classes preceded by the following line:️ + +```python +# Copied from transformers.[...] +``` + +This line ensures that the copy does not diverge from the source. If it *should* diverge, because the implementation +is different, this line needs to be deleted. If you don't delete this line and run `make fix-copies`, +your changes will be overwritten. + +Once you have edited the files to fit your architecture, simply re-run the tests (and edit them if a change +is needed!) afterwards to make sure everything works as expected. + +Once the files are generated and you are happy with your changes, here's a checklist to ensure that your contribution +will be merged quickly: + +- You should run the `make fixup` utility to fix the style of the files and to ensure the code quality meets the + library's standards. +- You should add your model to the main README then run `make fix-copies`. diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5dd27ef591a180494a1dcd67d3eb7921de551091 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/__init__.py @@ -0,0 +1,286 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import TYPE_CHECKING + +from ...utils import _LazyModule, OptionalDependencyNotAvailable, is_tokenizers_available + + +{%- if "TensorFlow" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +from ...utils import is_tf_available + + +{% endif %} +{%- if "PyTorch" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +from ...utils import is_torch_available + + +{% endif %} +{%- if "Flax" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +from ...utils import is_flax_available + + +{% endif %} + +_import_structure = { + "configuration_{{cookiecutter.lowercase_modelname}}": ["{{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP", "{{cookiecutter.camelcase_modelname}}Config"], + "tokenization_{{cookiecutter.lowercase_modelname}}": ["{{cookiecutter.camelcase_modelname}}Tokenizer"], +} + +try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["tokenization_{{cookiecutter.lowercase_modelname}}_fast"] = ["{{cookiecutter.camelcase_modelname}}TokenizerFast"] + +{%- if "PyTorch" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_{{cookiecutter.lowercase_modelname}}"] = [ + "{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "{{cookiecutter.camelcase_modelname}}ForCausalLM", + "{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "{{cookiecutter.camelcase_modelname}}Layer", + "{{cookiecutter.camelcase_modelname}}Model", + "{{cookiecutter.camelcase_modelname}}PreTrainedModel", + "load_tf_weights_in_{{cookiecutter.lowercase_modelname}}", + ] +{% else %} +try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_{{cookiecutter.lowercase_modelname}}"] = [ + "{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "{{cookiecutter.camelcase_modelname}}ForCausalLM", + "{{cookiecutter.camelcase_modelname}}Model", + "{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] +{% endif %} +{% endif %} + + +{%- if "TensorFlow" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_{{cookiecutter.lowercase_modelname}}"] = [ + "TF_{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "TF{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "TF{{cookiecutter.camelcase_modelname}}ForCausalLM", + "TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "TF{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "TF{{cookiecutter.camelcase_modelname}}Layer", + "TF{{cookiecutter.camelcase_modelname}}Model", + "TF{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] +{% else %} +try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_tf_{{cookiecutter.lowercase_modelname}}"] = [ + "TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "TF{{cookiecutter.camelcase_modelname}}Model", + "TF{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] +{% endif %} +{% endif %} + + +{%- if "Flax" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_{{cookiecutter.lowercase_modelname}}"] = [ + "Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "Flax{{cookiecutter.camelcase_modelname}}ForCausalLM", + "Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "Flax{{cookiecutter.camelcase_modelname}}Layer", + "Flax{{cookiecutter.camelcase_modelname}}Model", + "Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] +{% else %} +try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() +except OptionalDependencyNotAvailable: + pass +else: + _import_structure["modeling_flax_{{cookiecutter.lowercase_modelname}}"] = [ + "Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "Flax{{cookiecutter.camelcase_modelname}}Model", + "Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] +{% endif %} +{% endif %} + + +if TYPE_CHECKING: + from .configuration_{{cookiecutter.lowercase_modelname}} import {{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP, {{cookiecutter.camelcase_modelname}}Config + from .tokenization_{{cookiecutter.lowercase_modelname}} import {{cookiecutter.camelcase_modelname}}Tokenizer + + try: + if not is_tokenizers_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .tokenization_{{cookiecutter.lowercase_modelname}}_fast import {{cookiecutter.camelcase_modelname}}TokenizerFast + +{%- if "PyTorch" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + {{cookiecutter.camelcase_modelname}}ForMaskedLM, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForMultipleChoice, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}ForTokenClassification, + {{cookiecutter.camelcase_modelname}}Layer, + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}PreTrainedModel, + load_tf_weights_in_{{cookiecutter.lowercase_modelname}}, + ) +{% else %} + try: + if not is_torch_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + {{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif %} +{% endif %} +{%- if "TensorFlow" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_{{cookiecutter.lowercase_modelname}} import ( + TF_{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + TF{{cookiecutter.camelcase_modelname}}ForMaskedLM, + TF{{cookiecutter.camelcase_modelname}}ForCausalLM, + TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + TF{{cookiecutter.camelcase_modelname}}ForTokenClassification, + TF{{cookiecutter.camelcase_modelname}}Layer, + TF{{cookiecutter.camelcase_modelname}}Model, + TF{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% else %} + try: + if not is_tf_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_tf_{{cookiecutter.lowercase_modelname}} import ( + TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + TF{{cookiecutter.camelcase_modelname}}Model, + TF{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif %} +{% endif %} +{%- if "Flax" in cookiecutter.generate_tensorflow_pytorch_and_flax %} +{% if cookiecutter.is_encoder_decoder_model == "False" %} + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_{{cookiecutter.lowercase_modelname}} import ( + Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM, + Flax{{cookiecutter.camelcase_modelname}}ForCausalLM, + Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification, + Flax{{cookiecutter.camelcase_modelname}}Layer, + Flax{{cookiecutter.camelcase_modelname}}Model, + Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% else %} + try: + if not is_flax_available(): + raise OptionalDependencyNotAvailable() + except OptionalDependencyNotAvailable: + pass + else: + from .modeling_{{cookiecutter.lowercase_modelname}} import ( + Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}Model, + Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif %} +{% endif %} + +else: + import sys + + sys.modules[__name__] = _LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration.json new file mode 100644 index 0000000000000000000000000000000000000000..fea453b421fa20a2e27c5c628f9b4a9d476c3bbe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration.json @@ -0,0 +1,11 @@ +{ + "modelname": "{{cookiecutter.modelname}}", + "uppercase_modelname": "{{cookiecutter.uppercase_modelname}}", + "lowercase_modelname": "{{cookiecutter.lowercase_modelname}}", + "camelcase_modelname": "{{cookiecutter.camelcase_modelname}}", + "authors": "{{cookiecutter.authors}}", + "checkpoint_identifier": "{{cookiecutter.checkpoint_identifier}}", + "tokenizer_type": "{{cookiecutter.tokenizer_type}}", + "generate_tensorflow_pytorch_and_flax": "{{cookiecutter.generate_tensorflow_pytorch_and_flax}}", + "is_encoder_decoder_model": "{{cookiecutter.is_encoder_decoder_model}}" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..3221696317bde219d24c1e6bc599c0e39af3f1c6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/configuration_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,241 @@ +# coding=utf-8 +# Copyright 2022 {{cookiecutter.authors}} and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" {{cookiecutter.modelname}} model configuration """ + +from ...configuration_utils import PretrainedConfig +from ...utils import logging + + +logger = logging.get_logger(__name__) + +{{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP = { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/config.json", + # See all {{cookiecutter.modelname}} models at https://huggingface.co/models?filter={{cookiecutter.lowercase_modelname}} +} + + +class {{cookiecutter.camelcase_modelname}}Config(PretrainedConfig): + r""" + This is the configuration class to store the configuration of a [`~{{cookiecutter.camelcase_modelname}}Model`]. + It is used to instantiate an {{cookiecutter.modelname}} model according to the specified arguments, defining the model + architecture. Instantiating a configuration with the defaults will yield a similar configuration to that of + the {{cookiecutter.modelname}} [{{cookiecutter.checkpoint_identifier}}](https://huggingface.co/{{cookiecutter.checkpoint_identifier}}) architecture. + + Configuration objects inherit from [`PretrainedConfig`] and can be used + to control the model outputs. Read the documentation from [`PretrainedConfig`] + for more information. + + + Args: + {% if cookiecutter.is_encoder_decoder_model == "False" -%} + vocab_size (`int`, *optional*, defaults to 30522): + Vocabulary size of the {{cookiecutter.modelname}} model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`~{{cookiecutter.camelcase_modelname}}Model`] or + [`~TF{{cookiecutter.camelcase_modelname}}Model`]. + hidden_size (`int`, *optional*, defaults to 768): + Dimension of the encoder layers and the pooler layer. + num_hidden_layers (`int`, *optional*, defaults to 12): + Number of hidden layers in the Transformer encoder. + num_attention_heads (`int`, *optional*, defaults to 12): + Number of attention heads for each attention layer in the Transformer encoder. + intermediate_size (`int`, *optional*, defaults to 3072): + Dimension of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder. + hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. + If string, `"gelu"`, `"relu"`, `"selu"` and `"gelu_new"` are supported. + hidden_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler. + attention_probs_dropout_prob (`float`, *optional*, defaults to 0.1): + The dropout ratio for the attention probabilities. + max_position_embeddings (`int`, *optional*, defaults to 512): + The maximum sequence length that this model might ever be used with. + Typically set this to something large just in case (e.g., 512 or 1024 or 2048). + type_vocab_size (`int`, *optional*, defaults to 2): + The vocabulary size of the `token_type_ids` passed when calling [`~{{cookiecutter.camelcase_modelname}}Model`] or + [`~TF{{cookiecutter.camelcase_modelname}}Model`]. + initializer_range (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + layer_norm_eps (`float`, *optional*, defaults to 1e-12): + The epsilon used by the layer normalization layers. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). Only + relevant if `config.is_decoder=True`. + {% else -%} + vocab_size (`int`, *optional*, defaults to 50265): + Vocabulary size of the {{cookiecutter.modelname}} model. Defines the number of different tokens that can be represented by the + `inputs_ids` passed when calling [`~{{cookiecutter.camelcase_modelname}}Model`] or + [`~TF{{cookiecutter.camelcase_modelname}}Model`]. + d_model (`int`, *optional*, defaults to 1024): + Dimension of the layers and the pooler layer. + encoder_layers (`int`, *optional*, defaults to 12): + Number of encoder layers. + decoder_layers (`int`, *optional*, defaults to 12): + Number of decoder layers. + encoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer encoder. + decoder_attention_heads (`int`, *optional*, defaults to 16): + Number of attention heads for each attention layer in the Transformer decoder. + decoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + encoder_ffn_dim (`int`, *optional*, defaults to 4096): + Dimension of the "intermediate" (often named feed-forward) layer in decoder. + activation_function (`str` or `function`, *optional*, defaults to `"gelu"`): + The non-linear activation function (function or string) in the encoder and pooler. If string, + `"gelu"`, `"relu"`, `"silu"` and `"gelu_new"` are supported. + dropout (`float`, *optional*, defaults to 0.1): + The dropout probability for all fully connected layers in the embeddings, encoder, and pooler. + attention_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for the attention probabilities. + activation_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for activations inside the fully connected layer. + classifier_dropout (`float`, *optional*, defaults to 0.0): + The dropout ratio for classifier. + max_position_embeddings (`int`, *optional*, defaults to 1024): + The maximum sequence length that this model might ever be used with. Typically set this to something large + just in case (e.g., 512 or 1024 or 2048). + init_std (`float`, *optional*, defaults to 0.02): + The standard deviation of the truncated_normal_initializer for initializing all weight matrices. + encoder_layerdrop: (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the encoder. See the [LayerDrop paper](see + https://arxiv.org/abs/1909.11556) for more details. + decoder_layerdrop: (`float`, *optional*, defaults to 0.0): + The LayerDrop probability for the decoder. See the [LayerDrop paper](see + https://arxiv.org/abs/1909.11556) for more details. + use_cache (`bool`, *optional*, defaults to `True`): + Whether or not the model should return the last key/values attentions (not used by all models). + {% endif -%} + + Example: + + ```python + >>> from transformers import {{cookiecutter.camelcase_modelname}}Model, {{cookiecutter.camelcase_modelname}}Config + + >>> # Initializing a {{cookiecutter.modelname}} {{cookiecutter.checkpoint_identifier}} style configuration + >>> configuration = {{cookiecutter.camelcase_modelname}}Config() + + >>> # Initializing a model from the {{cookiecutter.checkpoint_identifier}} style configuration + >>> model = {{cookiecutter.camelcase_modelname}}Model(configuration) + + >>> # Accessing the model configuration + >>> configuration = model.config + ``` +""" + model_type = "{{cookiecutter.lowercase_modelname}}" + {% if cookiecutter.is_encoder_decoder_model == "False" -%} + {% else -%} + keys_to_ignore_at_inference = ["past_key_values"] + {% endif -%} + + {% if cookiecutter.is_encoder_decoder_model == "False" %} + {%- else %} + attribute_map = { + "num_attention_heads": "encoder_attention_heads", + "hidden_size": "d_model" + } + + {%- endif %} + + def __init__( + self, + {% if cookiecutter.is_encoder_decoder_model == "False" -%} + vocab_size=30522, + hidden_size=768, + num_hidden_layers=12, + num_attention_heads=12, + intermediate_size=3072, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + use_cache=True, + {% else -%} + vocab_size=50265, + max_position_embeddings=1024, + encoder_layers=12, + encoder_ffn_dim=4096, + encoder_attention_heads=16, + decoder_layers=12, + decoder_ffn_dim=4096, + decoder_attention_heads=16, + encoder_layerdrop=0.0, + decoder_layerdrop=0.0, + use_cache=True, + is_encoder_decoder=True, + activation_function="gelu", + d_model=1024, + dropout=0.1, + attention_dropout=0.0, + activation_dropout=0.0, + init_std=0.02, + decoder_start_token_id=2, + classifier_dropout=0.0, + scale_embedding=False, + {% endif -%} + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + **kwargs + ): + self.vocab_size = vocab_size + self.max_position_embeddings = max_position_embeddings + {% if cookiecutter.is_encoder_decoder_model == "False" -%} + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.type_vocab_size = type_vocab_size + self.layer_norm_eps = layer_norm_eps + self.use_cache = use_cache + {% else -%} + self.d_model = d_model + self.encoder_ffn_dim = encoder_ffn_dim + self.encoder_layers = encoder_layers + self.encoder_attention_heads = encoder_attention_heads + self.decoder_ffn_dim = decoder_ffn_dim + self.decoder_layers = decoder_layers + self.decoder_attention_heads = decoder_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.activation_function = activation_function + self.init_std = init_std + self.encoder_layerdrop = encoder_layerdrop + self.decoder_layerdrop = decoder_layerdrop + self.classifier_dropout = classifier_dropout + self.use_cache = use_cache + self.num_hidden_layers = encoder_layers + self.scale_embedding = scale_embedding # scale factor will be sqrt(d_model) if True + + {% endif -%} + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + {% if cookiecutter.is_encoder_decoder_model == "False" -%} + {% else -%} + is_encoder_decoder=is_encoder_decoder, + decoder_start_token_id=decoder_start_token_id, + {% endif -%} + **kwargs + ) + + \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_flax_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_flax_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_tf_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_tf_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/modeling_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_flax_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_flax_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..37b22a75c3e9707ff198953f1bef122e5d4c3de5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_flax_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,669 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{% if cookiecutter.is_encoder_decoder_model == "False" %} + +import unittest + +from transformers import is_flax_available, {{cookiecutter.camelcase_modelname}}Config +from transformers.testing_utils import require_flax, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor + +if is_flax_available(): + import numpy as np + from transformers import ( + Flax{{cookiecutter.camelcase_modelname}}ForCausalLM, + Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM, + Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification, + Flax{{cookiecutter.camelcase_modelname}}Model, + ) + + +class Flax{{cookiecutter.camelcase_modelname}}ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = {{cookiecutter.camelcase_modelname}}Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + return_dict=True, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Flax{{cookiecutter.camelcase_modelname}}Model(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + + inputs = [input_ids, input_mask] + + result = model(*inputs) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_lm_head( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.is_decoder = True + model = Flax{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + prediction_scores = model(**inputs)["logits"] + self.parent.assertListEqual( + list(prediction_scores.shape), [self.batch_size, self.seq_length, self.vocab_size] + ) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(**inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(**inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice(config=config) + multiple_choice_inputs_ids = np.tile(np.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = np.tile(np.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = np.tile(np.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(**inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(**inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(**inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_flax +class Flax{{cookiecutter.camelcase_modelname}}ModelTest(FlaxModelTesterMixin, unittest.TestCase): + + all_model_classes = ( + ( + Flax{{cookiecutter.camelcase_modelname}}Model, + Flax{{cookiecutter.camelcase_modelname}}ForCausalLM, + Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification, + Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + ) + if is_flax_available() + else () + ) + + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = Flax{{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + model = Flax{{cookiecutter.camelcase_modelname}}Model.from_pretrained("{{cookiecutter.checkpoint_identifier}}") + self.assertIsNotNone(model) + + +def _assert_tensors_equal(a, b, atol=1e-12, prefix=""): + """If tensors not close, or a and b arent both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if _assert_tensors_equal(a, b, atol=atol): + return True + raise + except Exception: + if len(prefix) > 0: + prefix = f"{prefix}: " + raise AssertionError(f"{prefix}{a} != {b}") + + +@require_flax +class Flax{{cookiecutter.camelcase_modelname}}ModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM.from_pretrained("{{cookiecutter.checkpoint_identifier}}") + input_ids = np.array([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + # TODO Replace vocab size + vocab_size = 32000 + + expected_shape = [1, 6, vocab_size] + self.assertEqual(output.shape, expected_shape) + + print(output[:, :3, :3]) + + # TODO Replace values below with what was printed above. + expected_slice = np.array( + [ + [ + [-0.05243197, -0.04498899, 0.05512108], + [-0.07444685, -0.01064632, 0.04352357], + [-0.05020351, 0.05530146, 0.00700043], + ] + ] + ) + _assert_tensors_equal(output[:, :3, :3], expected_slice, atol=1e-4) + +{% else %} +import unittest + +from transformers import ( + is_flax_available, + {{cookiecutter.camelcase_modelname}}Config, + {{cookiecutter.camelcase_modelname}}Tokenizer, +) +from transformers.testing_utils import require_sentencepiece, require_flax, require_tokenizers, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor + + +if is_flax_available(): + import numpy as np + import jax.numpy as jnp + from transformers import ( + Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}Model, + ) + + +@require_flax +class Flax{{cookiecutter.camelcase_modelname}}ModelTester: + config_cls = {{cookiecutter.camelcase_modelname}}Config + config_updates = {} + hidden_act = "gelu" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + + def prepare_config_and_inputs_for_common(self): + input_ids = ids_tensor([self.batch_size, self.seq_length - 1], self.vocab_size).clip(3, self.vocab_size) + eos_tensor = np.expand_dims(np.array([self.eos_token_id] * self.batch_size), 1) + input_ids = np.concatenate([input_ids, eos_tensor], axis=1) + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = 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, + ) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def check_use_cache_forward(self, model_class_name, config, inputs_dict): + max_decoder_length = 20 + model = model_class_name(config) + + encoder_outputs = model.encode(inputs_dict["input_ids"]) + + decoder_input_ids, decoder_attention_mask = ( + inputs_dict["decoder_input_ids"], + inputs_dict["decoder_attention_mask"], + ) + + past_key_values = model.init_cache(decoder_input_ids.shape[0], max_decoder_length, encoder_outputs) + decoder_attention_mask = jnp.ones((decoder_input_ids.shape[0], max_decoder_length), dtype="i4") + + decoder_position_ids = jnp.broadcast_to( + jnp.arange(decoder_input_ids.shape[-1] - 1)[None, :], + (decoder_input_ids.shape[0], decoder_input_ids.shape[-1] - 1), + ) + outputs_cache = model.decode( + decoder_input_ids[:, :-1], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + past_key_values=past_key_values, + decoder_position_ids=decoder_position_ids, + ) + + decoder_position_ids = jnp.array(decoder_input_ids.shape[0] * [[decoder_input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model.decode( + decoder_input_ids[:, -1:], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + past_key_values=outputs_cache.past_key_values, + decoder_position_ids=decoder_position_ids, + ) + + outputs = model.decode(decoder_input_ids, encoder_outputs) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def check_use_cache_forward_with_attn_mask(self, model_class_name, config, inputs_dict): + max_decoder_length = 20 + model = model_class_name(config) + + encoder_outputs = model.encode(inputs_dict["input_ids"]) + + decoder_input_ids, decoder_attention_mask = ( + inputs_dict["decoder_input_ids"], + inputs_dict["decoder_attention_mask"], + ) + + decoder_attention_mask_cache = jnp.concatenate( + [ + decoder_attention_mask, + jnp.zeros((decoder_attention_mask.shape[0], max_decoder_length - decoder_attention_mask.shape[1])), + ], + axis=-1, + ) + + past_key_values = model.init_cache(decoder_input_ids.shape[0], max_decoder_length, encoder_outputs) + decoder_position_ids = jnp.broadcast_to( + jnp.arange(decoder_input_ids.shape[-1] - 1)[None, :], + (decoder_input_ids.shape[0], decoder_input_ids.shape[-1] - 1), + ) + + outputs_cache = model.decode( + decoder_input_ids[:, :-1], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask_cache, + past_key_values=past_key_values, + decoder_position_ids=decoder_position_ids, + ) + decoder_position_ids = jnp.array(decoder_input_ids.shape[0] * [[decoder_input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model.decode( + decoder_input_ids[:, -1:], + encoder_outputs, + past_key_values=outputs_cache.past_key_values, + decoder_attention_mask=decoder_attention_mask_cache, + decoder_position_ids=decoder_position_ids, + ) + + outputs = model.decode(decoder_input_ids, encoder_outputs, decoder_attention_mask=decoder_attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + +def prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, +): + if attention_mask is None: + attention_mask = np.not_equal(input_ids, config.pad_token_id).astype(np.int8) + if decoder_attention_mask is None: + decoder_attention_mask = np.concatenate([np.ones(decoder_input_ids[:, :1].shape, dtype=np.int8), np.not_equal(decoder_input_ids[:, 1:], config.pad_token_id).astype(np.int8)], axis=-1) + return { + "input_ids": input_ids, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": decoder_attention_mask, + } + + +@require_flax +class Flax{{cookiecutter.camelcase_modelname}}ModelTest(FlaxModelTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}Model, + ) if is_flax_available() + else () + ) + all_generative_model_classes = (Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration,) if is_flax_available() else () + is_encoder_decoder = True + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = Flax{{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_use_cache_forward(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + self.model_tester.check_use_cache_forward(model_class, config, inputs_dict) + + def test_use_cache_forward_with_attn_mask(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + self.model_tester.check_use_cache_forward_with_attn_mask(model_class, config, inputs_dict) + + +def _assert_tensors_equal(a, b, atol=1e-12, prefix=""): + """If tensors not close, or a and b arent both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if _assert_tensors_equal(a, b, atol=atol): + return True + raise + except Exception: + if len(prefix) > 0: + prefix = f"{prefix}: " + raise AssertionError(f"{prefix}{a} != {b}") + + +def _long_tensor(tok_lst): + return np.array(tok_lst, dtype=np.int32) + + +TOLERANCE = 1e-4 + + +@slow +@require_sentencepiece +@require_tokenizers +@require_flax +class Flax{{cookiecutter.camelcase_modelname}}ModelIntegrationTest(unittest.TestCase): + def test_inference_no_head(self): + model = Flax{{cookiecutter.camelcase_modelname}}Model.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + # change to intended input here + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 11, 1024) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = np.array( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], + ) + _assert_tensors_equal(output[:, :3, :3], expected_slice, atol=TOLERANCE) + + def test_inference_with_head(self): + model = Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + # change to intended input here + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 11, 1024) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = np.array( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], + ) + _assert_tensors_equal(output[:, :3, :3], expected_slice, atol=TOLERANCE) + + def test_seq_to_seq_generation(self): + hf = Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + tok = {{cookiecutter.camelcase_modelname}}Tokenizer.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + + batch_input = [ + # string 1, + # string 2, + # string 3, + # string 4, + ] + + # The below article tests that we don't add any hypotheses outside of the top n_beams + dct = tok.batch_encode_plus( + batch_input, + max_length=512, + padding="max_length", + truncation_strategy="only_first", + truncation=True, + return_tensors="np", + ) + + hypotheses_batch = hf.generate( + input_ids=dct["input_ids"], + attention_mask=dct["attention_mask"], + num_beams=2, + ) + + EXPECTED = [ + # here expected 1, + # here expected 2, + # here expected 3, + # here expected 4, + ] + + generated = tok.batch_decode( + hypotheses_batch.tolist(), clean_up_tokenization_spaces=True, skip_special_tokens=True + ) + assert generated == EXPECTED +{%- endif %} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_tf_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_tf_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..28c28884e248c69f34149b44eb5b84a724cdb418 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_tf_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,991 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{% if cookiecutter.is_encoder_decoder_model == "False" %} + +import unittest + +from transformers import is_tf_available, {{cookiecutter.camelcase_modelname}}Config +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TF{{cookiecutter.camelcase_modelname}}ForCausalLM, + TF{{cookiecutter.camelcase_modelname}}ForMaskedLM, + TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + TF{{cookiecutter.camelcase_modelname}}ForTokenClassification, + TF{{cookiecutter.camelcase_modelname}}Model, + ) + + +class TF{{cookiecutter.camelcase_modelname}}ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = {{cookiecutter.camelcase_modelname}}Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + return_dict=True, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TF{{cookiecutter.camelcase_modelname}}Model(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_causal_lm_base_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.is_decoder = True + + model = TF{{cookiecutter.camelcase_modelname}}Model(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TF{{cookiecutter.camelcase_modelname}}Model(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + "encoder_hidden_states": encoder_hidden_states, + "encoder_attention_mask": encoder_attention_mask, + } + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs, token_type_ids=token_type_ids, encoder_hidden_states=encoder_hidden_states) + + # Also check the case where encoder outputs are not passed + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_causal_lm_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.is_decoder = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + prediction_scores = model(inputs)["logits"] + self.parent.assertListEqual( + list(prediction_scores.numpy().shape), [self.batch_size, self.seq_length, self.vocab_size] + ) + + def create_and_check_causal_lm_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + "encoder_hidden_states": encoder_hidden_states, + "encoder_attention_mask": encoder_attention_mask, + } + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs, token_type_ids=token_type_ids, encoder_hidden_states=encoder_hidden_states) + + prediction_scores = result["logits"] + self.parent.assertListEqual( + list(prediction_scores.numpy().shape), [self.batch_size, self.seq_length, self.vocab_size] + ) + + + def create_and_check_causal_lm_model_past( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + + # first forward pass + outputs = model(input_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids) + outputs_no_past = model(input_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and attn_mask + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + + output_from_no_past = model(next_input_ids, output_hidden_states=True).hidden_states[0] + output_from_past = model( + next_tokens, past_key_values=past_key_values, output_hidden_states=True + ).hidden_states[0] + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_causal_lm_model_past_with_attn_mask( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + + # create attention mask + half_seq_length = self.seq_length // 2 + attn_mask_begin = tf.ones((self.batch_size, half_seq_length), dtype=tf.int32) + attn_mask_end = tf.zeros((self.batch_size, self.seq_length - half_seq_length), dtype=tf.int32) + attn_mask = tf.concat([attn_mask_begin, attn_mask_end], axis=1) + + # first forward pass + outputs = model(input_ids, attention_mask=attn_mask, use_cache=True) + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + past_key_values = outputs.past_key_values + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).numpy() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, self.seq_length), config.vocab_size) + vector_condition = tf.range(self.seq_length) == (self.seq_length - random_seq_idx_to_change) + condition = tf.transpose( + tf.broadcast_to(tf.expand_dims(vector_condition, -1), (self.seq_length, self.batch_size)) + ) + input_ids = tf.where(condition, random_other_next_tokens, input_ids) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + attn_mask = tf.concat( + [attn_mask, tf.ones((attn_mask.shape[0], 1), dtype=tf.int32)], + axis=1, + ) + + output_from_no_past = model( + next_input_ids, + attention_mask=attn_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, past_key_values=past_key_values, attention_mask=attn_mask, output_hidden_states=True + ).hidden_states[0] + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_causal_lm_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, use_cache=True) + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + ).hidden_states[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TF{{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + encoder_hidden_states = encoder_hidden_states[:1, :, :] + encoder_attention_mask = encoder_attention_mask[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + ).hidden_states[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TF{{cookiecutter.camelcase_modelname}}ForMaskedLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TF{{cookiecutter.camelcase_modelname}}ForTokenClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TF{{cookiecutter.camelcase_modelname}}ModelTest(TFModelTesterMixin, unittest.TestCase): + + all_model_classes = ( + ( + TF{{cookiecutter.camelcase_modelname}}Model, + TF{{cookiecutter.camelcase_modelname}}ForCausalLM, + TF{{cookiecutter.camelcase_modelname}}ForMaskedLM, + TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + TF{{cookiecutter.camelcase_modelname}}ForTokenClassification, + TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + ) + if is_tf_available() + else () + ) + + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TF{{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + """Test the base model""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="Template classes interact badly with this test.") + def test_keras_fit(self): + pass + + def test_causal_lm_base_model(self): + """Test the base model of the causal LM model + + is_deocder=True, no cross_attention, no encoder outputs + """ + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_base_model(*config_and_inputs) + + def test_model_as_decoder(self): + """Test the base model as a decoder (of an encoder-decoder architecture) + + is_deocder=True + cross_attention + pass encoder outputs + """ + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_causal_lm(self): + """Test the causal LM model""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_model(*config_and_inputs) + + def test_causal_lm_model_as_decoder(self): + """Test the causal LM model as a decoder""" + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_causal_lm_model_as_decoder(*config_and_inputs) + + def test_causal_lm_model_past(self): + """Test causal LM model with `past_key_values`""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_model_past(*config_and_inputs) + + def test_causal_lm_model_past_with_attn_mask(self): + """Test the causal LM model with `past_key_values` and `attention_mask`""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_model_past_with_attn_mask(*config_and_inputs) + + def test_causal_lm_model_past_with_large_inputs(self): + """Test the causal LM model with `past_key_values` and a longer decoder sequence length""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_model_past_large_inputs(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs(self): + """Similar to `test_causal_lm_model_past_with_large_inputs` but with cross-attention""" + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + model = TF{{cookiecutter.camelcase_modelname}}Model.from_pretrained("{{cookiecutter.checkpoint_identifier}}") + self.assertIsNotNone(model) + +@require_tf +class TF{{cookiecutter.camelcase_modelname}}ModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TF{{cookiecutter.camelcase_modelname}}ForMaskedLM.from_pretrained("{{cookiecutter.checkpoint_identifier}}") + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + # TODO Replace vocab size + vocab_size = 32000 + + expected_shape = [1, 6, vocab_size] + self.assertEqual(output.shape, expected_shape) + + print(output[:, :3, :3]) + + # TODO Replace values below with what was printed above. + expected_slice = tf.constant( + [ + [ + [-0.05243197, -0.04498899, 0.05512108], + [-0.07444685, -0.01064632, 0.04352357], + [-0.05020351, 0.05530146, 0.00700043], + ] + ] + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-4) + +{% else %} +import unittest + +from transformers import ( + is_tf_available, + {{cookiecutter.camelcase_modelname}}Config, + {{cookiecutter.camelcase_modelname}}Tokenizer, +) +from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + TF{{cookiecutter.camelcase_modelname}}Model, + ) + + +@require_tf +class TF{{cookiecutter.camelcase_modelname}}ModelTester: + config_cls = {{cookiecutter.camelcase_modelname}}Config + config_updates = {} + hidden_act = "gelu" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + + def prepare_config_and_inputs_for_common(self): + input_ids = ids_tensor([self.batch_size, self.seq_length - 1], self.vocab_size) + eos_tensor = tf.expand_dims(tf.constant([self.eos_token_id] * self.batch_size), 1) + input_ids = tf.concat([input_ids, eos_tensor], axis=1) + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = 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, + ) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = TF{{cookiecutter.camelcase_modelname}}Model(config=config).get_decoder() + input_ids = inputs_dict["input_ids"] + + input_ids = input_ids[:1, :] + attention_mask = inputs_dict["attention_mask"][:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([attention_mask, next_attn_mask], axis=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)[0] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + +def prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, +): + if attention_mask is None: + attention_mask = tf.cast(tf.math.not_equal(input_ids, config.pad_token_id), tf.int32) + if decoder_attention_mask is None: + decoder_attention_mask = tf.concat([tf.ones(decoder_input_ids[:, :1].shape, dtype=tf.int32), tf.cast(tf.math.not_equal(decoder_input_ids[:, 1:], config.pad_token_id), tf.int32)], axis=-1) + return { + "input_ids": input_ids, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": decoder_attention_mask, + } + + +@require_tf +class TF{{cookiecutter.camelcase_modelname}}ModelTest(TFModelTesterMixin, unittest.TestCase): + all_model_classes = (TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, TF{{cookiecutter.camelcase_modelname}}Model) if is_tf_available() else () + all_generative_model_classes = (TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration,) if is_tf_available() else () + is_encoder_decoder = True + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TF{{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_decoder_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in self.all_generative_model_classes: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + @unittest.skip(reason="Template classes interact badly with this test.") + def test_keras_fit(self): + pass + + +def _assert_tensors_equal(a, b, atol=1e-12, prefix=""): + """If tensors not close, or a and b arent both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if tf.debugging.assert_near(a, b, atol=atol): + return True + raise + except Exception: + if len(prefix) > 0: + prefix = f"{prefix}: " + raise AssertionError(f"{prefix}{a} != {b}") + + +def _long_tensor(tok_lst): + return tf.constant(tok_lst, dtype=tf.int32) + + +TOLERANCE = 1e-4 + + +@slow +@require_sentencepiece +@require_tokenizers +@require_tf +class TF{{cookiecutter.camelcase_modelname}}ModelIntegrationTest(unittest.TestCase): + def test_inference_no_head(self): + model = TF{{cookiecutter.camelcase_modelname}}Model.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + # change to intended input here + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 11, 1024) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = tf.Tensor( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=TOLERANCE) + + def test_inference_with_head(self): + model = TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + # change to intended input here + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 11, 1024) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = tf.Tensor( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=TOLERANCE) + + def test_seq_to_seq_generation(self): + hf = TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + tok = {{cookiecutter.camelcase_modelname}}Tokenizer.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + + batch_input = [ + # string 1, + # string 2, + # string 3, + # string 4, + ] + + # The below article tests that we don't add any hypotheses outside of the top n_beams + dct = tok.batch_encode_plus( + batch_input, + max_length=512, + padding="max_length", + truncation_strategy="only_first", + truncation=True, + return_tensors="tf", + ) + + hypotheses_batch = hf.generate( + input_ids=dct["input_ids"], + attention_mask=dct["attention_mask"], + num_beams=2, + ) + + EXPECTED = [ + # here expected 1, + # here expected 2, + # here expected 3, + # here expected 4, + ] + + generated = tok.batch_decode( + hypotheses_batch.tolist(), clean_up_tokenization_spaces=True, skip_special_tokens=True + ) + assert generated == EXPECTED +{%- endif %} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..6d5b3fe79682efbfca6a6f6468f490832f867dac --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/test_modeling_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,1070 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch {{cookiecutter.modelname}} model. """ + + +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +import unittest + +from ...test_modeling_common import floats_tensor +from transformers import is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from transformers import {{cookiecutter.camelcase_modelname}}Config +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask + + +if is_torch_available(): + import torch + + from transformers import ( + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForMaskedLM, + {{cookiecutter.camelcase_modelname}}ForMultipleChoice, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}ForTokenClassification, + {{cookiecutter.camelcase_modelname}}Model, + ) + from transformers.models.{{cookiecutter.lowercase_modelname}}.modeling_{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + ) + + +class {{cookiecutter.camelcase_modelname}}ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return {{cookiecutter.camelcase_modelname}}Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = {{cookiecutter.camelcase_modelname}}Model(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = {{cookiecutter.camelcase_modelname}}Model(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_causal_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + model = {{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = {{cookiecutter.camelcase_modelname}}ForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.is_decoder = True + config.add_cross_attention = True + model = {{cookiecutter.camelcase_modelname}}ForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + )["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = {{cookiecutter.camelcase_modelname}}ForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = {{cookiecutter.camelcase_modelname}}ForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = {{cookiecutter.camelcase_modelname}}ForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = {{cookiecutter.camelcase_modelname}}ForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class {{cookiecutter.camelcase_modelname}}ModelTest(ModelTesterMixin, unittest.TestCase): + + all_model_classes = ( + ( + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}ForMaskedLM, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForMultipleChoice, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}ForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = ({{cookiecutter.camelcase_modelname}}ForCausalLM,) if is_torch_available() else () + + def setUp(self): + self.model_tester = {{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_model_as_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + @slow + def test_model_from_pretrained(self): + for model_name in {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = {{cookiecutter.camelcase_modelname}}Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class {{cookiecutter.camelcase_modelname}}ModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = {{cookiecutter.camelcase_modelname}}ForMaskedLM.from_pretrained("{{cookiecutter.checkpoint_identifier}}") + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + # TODO Replace vocab size + vocab_size = 32000 + + expected_shape = torch.Size((1, 6, vocab_size)) + self.assertEqual(output.shape, expected_shape) + + # TODO Replace values below with what was printed above. + expected_slice = torch.tensor( + [[[-0.0483, 0.1188, -0.0313], [-0.0606, 0.1435, 0.0199], [-0.0235, 0.1519, 0.0175]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) + + +{% else -%} +import copy +import tempfile +import unittest + +from transformers import is_torch_available +from transformers.utils import cached_property +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...generation.test_utils import GenerationTesterMixin +from ...test_modeling_common import ModelTesterMixin, ids_tensor + + +if is_torch_available(): + import torch + + from transformers import ( + {{cookiecutter.camelcase_modelname}}Config, + {{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}Tokenizer, + ) + from transformers.models.{{cookiecutter.lowercase_modelname}}.modeling_{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.camelcase_modelname}}Decoder, + {{cookiecutter.camelcase_modelname}}Encoder, + ) + + +def prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, +): + if attention_mask is None: + attention_mask = input_ids.ne(config.pad_token_id) + if decoder_attention_mask is None: + decoder_attention_mask = decoder_input_ids.ne(config.pad_token_id) + return { + "input_ids": input_ids, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": attention_mask, + } + + +@require_torch +class {{cookiecutter.camelcase_modelname}}ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size).clamp( + 3, + ) + input_ids[:, -1] = self.eos_token_id # Eos Token + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = {{cookiecutter.camelcase_modelname}}Config( + 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_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + ) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + def create_and_check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = {{cookiecutter.camelcase_modelname}}Model(config=config).get_decoder().to(torch_device).eval() + input_ids = inputs_dict["input_ids"] + attention_mask = inputs_dict["attention_mask"] + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([attention_mask, next_attn_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-2)) + + def check_encoder_decoder_model_standalone(self, config, inputs_dict): + model = {{cookiecutter.camelcase_modelname}}Model(config=config).to(torch_device).eval() + outputs = model(**inputs_dict) + + encoder_last_hidden_state = outputs.encoder_last_hidden_state + last_hidden_state = outputs.last_hidden_state + + with tempfile.TemporaryDirectory() as tmpdirname: + encoder = model.get_encoder() + encoder.save_pretrained(tmpdirname) + encoder = {{cookiecutter.camelcase_modelname}}Encoder.from_pretrained(tmpdirname).to(torch_device) + + encoder_last_hidden_state_2 = encoder(inputs_dict["input_ids"], attention_mask=inputs_dict["attention_mask"])[ + 0 + ] + + self.parent.assertTrue((encoder_last_hidden_state_2 - encoder_last_hidden_state).abs().max().item() < 1e-3) + + with tempfile.TemporaryDirectory() as tmpdirname: + decoder = model.get_decoder() + decoder.save_pretrained(tmpdirname) + decoder = {{cookiecutter.camelcase_modelname}}Decoder.from_pretrained(tmpdirname).to(torch_device) + + last_hidden_state_2 = decoder( + input_ids=inputs_dict["decoder_input_ids"], + attention_mask=inputs_dict["decoder_attention_mask"], + encoder_hidden_states=encoder_last_hidden_state, + encoder_attention_mask=inputs_dict["attention_mask"], + )[0] + + self.parent.assertTrue((last_hidden_state_2 - last_hidden_state).abs().max().item() < 1e-3) + + +@require_torch +class {{cookiecutter.camelcase_modelname}}ModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + all_model_classes = ( + ({{cookiecutter.camelcase_modelname}}Model, {{cookiecutter.camelcase_modelname}}ForConditionalGeneration, {{cookiecutter.camelcase_modelname}}ForSequenceClassification, {{cookiecutter.camelcase_modelname}}ForQuestionAnswering) + if is_torch_available() + else () + ) + all_generative_model_classes = ({{cookiecutter.camelcase_modelname}}ForConditionalGeneration,) if is_torch_available() else () + is_encoder_decoder = True + test_pruning = False + test_head_masking = False + test_missing_keys = False + + def setUp(self): + self.model_tester = {{cookiecutter.camelcase_modelname}}ModelTester(self) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_save_load_strict(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_encoder_decoder_model_standalone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_encoder_decoder_model_standalone(*config_and_inputs) + + # {{cookiecutter.camelcase_modelname}}ForSequenceClassification does not support inputs_embeds + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in ({{cookiecutter.camelcase_modelname}}Model, {{cookiecutter.camelcase_modelname}}ForConditionalGeneration, {{cookiecutter.camelcase_modelname}}ForQuestionAnswering): + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + wte = model.get_input_embeddings() + if not self.is_encoder_decoder: + inputs["inputs_embeds"] = wte(input_ids) + else: + inputs["inputs_embeds"] = wte(encoder_input_ids) + inputs["decoder_inputs_embeds"] = wte(decoder_input_ids) + + with torch.no_grad(): + model(**inputs)[0] + + def test_generate_fp16(self): + config, input_dict = self.model_tester.prepare_config_and_inputs() + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + model = {{cookiecutter.camelcase_modelname}}ForConditionalGeneration(config).eval().to(torch_device) + if torch_device == "cuda": + model.half() + model.generate(input_ids, attention_mask=attention_mask) + model.generate(num_beams=4, do_sample=True, early_stopping=False, num_return_sequences=3) + + +def assert_tensors_close(a, b, atol=1e-12, prefix=""): + """If tensors have different shapes, different values or a and b are not both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if torch.allclose(a, b, atol=atol): + return True + raise + except Exception: + pct_different = (torch.gt((a - b).abs(), atol)).float().mean().item() + if a.numel() > 100: + msg = f"tensor values are {pct_different:.1%} percent different." + else: + msg = f"{a} != {b}" + if prefix: + msg = prefix + ": " + msg + raise AssertionError(msg) + + +def _long_tensor(tok_lst): + return torch.tensor(tok_lst, dtype=torch.long, device=torch_device) + + +TOLERANCE = 1e-4 + + +@require_torch +@require_sentencepiece +@require_tokenizers +@slow +class {{cookiecutter.camelcase_modelname}}ModelIntegrationTests(unittest.TestCase): + @cached_property + def default_tokenizer(self): + return {{cookiecutter.camelcase_modelname}}Tokenizer.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + + def test_inference_no_head(self): + model = {{cookiecutter.camelcase_modelname}}Model.from_pretrained('{{cookiecutter.checkpoint_identifier}}').to(torch_device) + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[2, 0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict)[0] + expected_shape = torch.Size((1, 11, 1024)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_inference_head(self): + model = {{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}').to(torch_device) + + # change to intended input + input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + decoder_input_ids = _long_tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + inputs_dict = prepare_{{cookiecutter.lowercase_modelname}}_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict)[0] + expected_shape = torch.Size((1, 11, model.config.vocab_size)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[0.7144, 0.8143, -1.2813], [0.7144, 0.8143, -1.2813], [-0.0467, 2.5911, -2.1845]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_seq_to_seq_generation(self): + hf = {{cookiecutter.camelcase_modelname}}ForConditionalGeneration.from_pretrained('{{cookiecutter.checkpoint_identifier}}').to(torch_device) + tok = {{cookiecutter.camelcase_modelname}}Tokenizer.from_pretrained('{{cookiecutter.checkpoint_identifier}}') + + batch_input = [ + # string 1, + # string 2, + # string 3, + # string 4, + ] + + # The below article tests that we don't add any hypotheses outside of the top n_beams + dct = tok.batch_encode_plus( + batch_input, + max_length=512, + padding="max_length", + truncation_strategy="only_first", + truncation=True, + return_tensors="pt", + ) + + hypotheses_batch = hf.generate( + input_ids=dct["input_ids"].to(torch_device), + attention_mask=dct["attention_mask"].to(torch_device), + num_beams=2, + ) + + EXPECTED = [ + # here expected 1, + # here expected 2, + # here expected 3, + # here expected 4, + ] + + generated = tok.batch_decode( + hypotheses_batch.tolist(), clean_up_tokenization_spaces=True, skip_special_tokens=True + ) + assert generated == EXPECTED + + +class {{cookiecutter.camelcase_modelname}}StandaloneDecoderModelTester: + def __init__( + self, + parent, + vocab_size=99, + batch_size=13, + d_model=16, + decoder_seq_length=7, + is_training=True, + is_decoder=True, + use_attention_mask=True, + use_cache=False, + use_labels=True, + decoder_start_token_id=2, + decoder_ffn_dim=32, + decoder_layers=4, + encoder_attention_heads=4, + decoder_attention_heads=4, + max_position_embeddings=30, + is_encoder_decoder=False, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.decoder_seq_length = decoder_seq_length + # For common tests + self.seq_length = self.decoder_seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_labels = use_labels + + self.vocab_size = vocab_size + self.d_model = d_model + self.hidden_size = d_model + self.num_hidden_layers = decoder_layers + self.decoder_layers = decoder_layers + self.decoder_ffn_dim = decoder_ffn_dim + self.encoder_attention_heads = encoder_attention_heads + self.decoder_attention_heads = decoder_attention_heads + self.num_attention_heads = decoder_attention_heads + self.eos_token_id = eos_token_id + self.bos_token_id = bos_token_id + self.pad_token_id = pad_token_id + self.decoder_start_token_id = decoder_start_token_id + self.use_cache = use_cache + self.max_position_embeddings = max_position_embeddings + self.is_encoder_decoder = is_encoder_decoder + + self.scope = None + self.decoder_key_length = decoder_seq_length + self.base_model_out_len = 2 + self.decoder_attention_idx = 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = ids_tensor([self.batch_size, self.decoder_seq_length], vocab_size=2) + + lm_labels = None + if self.use_labels: + lm_labels = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + config = {{cookiecutter.camelcase_modelname}}Config( + vocab_size=self.vocab_size, + d_model=self.d_model, + decoder_layers=self.decoder_layers, + decoder_ffn_dim=self.decoder_ffn_dim, + encoder_attention_heads=self.encoder_attention_heads, + decoder_attention_heads=self.decoder_attention_heads, + eos_token_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + use_cache=self.use_cache, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + max_position_embeddings=self.max_position_embeddings, + is_encoder_decoder=self.is_encoder_decoder, + ) + + return ( + config, + input_ids, + attention_mask, + lm_labels, + ) + + def create_and_check_decoder_model_past( + self, + config, + input_ids, + attention_mask, + lm_labels, + ): + config.use_cache = True + model = {{cookiecutter.camelcase_modelname}}Decoder(config=config).to(torch_device).eval() + # first forward pass + outputs = model(input_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids) + outputs_no_past = model(input_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + past_key_values = outputs["past_key_values"] + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + + output_from_no_past = model(next_input_ids)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, next_input_ids.shape[-1] - 1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + assert torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3) + + def create_and_check_decoder_model_attention_mask_past( + self, + config, + input_ids, + attention_mask, + lm_labels, + ): + model = {{cookiecutter.camelcase_modelname}}Decoder(config=config).to(torch_device).eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + + half_seq_length = input_ids.shape[-1] // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + past_key_values = model(input_ids, attention_mask=attn_mask, use_cache=True)["past_key_values"] + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, next_input_ids.shape[-1] - 1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + assert torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-2) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + attention_mask, + lm_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + } + return config, inputs_dict + + +@require_torch +class {{cookiecutter.camelcase_modelname}}StandaloneDecoderModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + all_model_classes = ({{cookiecutter.camelcase_modelname}}Decoder, {{cookiecutter.camelcase_modelname}}ForCausalLM) if is_torch_available() else () + all_generative_model_classes = ({{cookiecutter.camelcase_modelname}}ForCausalLM,) if is_torch_available() else () + test_pruning = False + is_encoder_decoder = False + + def setUp( + self, + ): + self.model_tester = {{cookiecutter.camelcase_modelname}}StandaloneDecoderModelTester(self, is_training=False) + self.config_tester = ConfigTester(self, config_class={{cookiecutter.camelcase_modelname}}Config) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_decoder_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past(*config_and_inputs) + + def test_decoder_model_attn_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_attention_mask_past(*config_and_inputs) + + def test_retain_grad_hidden_states_attentions(self): + # decoder cannot keep gradients + return +{% endif -%} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/to_replace_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/to_replace_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..273adca0ef230ea5092b4ed1eb6e7fc27bf6d7ea --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/to_replace_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,472 @@ +## Copyright 2022 The HuggingFace Team. All rights reserved. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +## This file is made so that specific statements may be copied inside existing files. This is useful to copy +## import statements in __init__.py, or to complete model lists in the AUTO files. +## +## It is to be used as such: +## Put '# To replace in: "FILE_PATH"' in order to indicate the contents will be copied in the file at path FILE_PATH +## Put '# Below: "STATEMENT"' in order to copy the contents below **the first occurence** of that line in the file at FILE_PATH +## Put '# Replace with:' followed by the lines containing the content to define the content +## End a statement with '# End.'. If starting a new statement without redefining the FILE_PATH, it will continue pasting +## content in that file. +## +## Put '## COMMENT' to comment on the file. + +# To replace in: "src/transformers/__init__.py" +# Below: " # PyTorch models structure" if generating PyTorch +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "{{cookiecutter.camelcase_modelname}}ForCausalLM", + "{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "{{cookiecutter.camelcase_modelname}}Layer", + "{{cookiecutter.camelcase_modelname}}Model", + "{{cookiecutter.camelcase_modelname}}PreTrainedModel", + "load_tf_weights_in_{{cookiecutter.lowercase_modelname}}", + ] + ) +{% else %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "{{cookiecutter.camelcase_modelname}}ForCausalLM", + "{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "{{cookiecutter.camelcase_modelname}}Model", + "{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] + ) +{% endif -%} +# End. + +# Below: " # TensorFlow models structure" if generating TensorFlow +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "TF_{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST", + "TF{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "TF{{cookiecutter.camelcase_modelname}}ForCausalLM", + "TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "TF{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "TF{{cookiecutter.camelcase_modelname}}Layer", + "TF{{cookiecutter.camelcase_modelname}}Model", + "TF{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] + ) +{% else %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "TF{{cookiecutter.camelcase_modelname}}Model", + "TF{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] + ) +{% endif -%} +# End. + +# Below: " # Flax models structure" if generating Flax +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM", + "Flax{{cookiecutter.camelcase_modelname}}ForCausalLM", + "Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice", + "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification", + "Flax{{cookiecutter.camelcase_modelname}}Layer", + "Flax{{cookiecutter.camelcase_modelname}}Model", + "Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] + ) +{% else %} + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].extend( + [ + "Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration", + "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering", + "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification", + "Flax{{cookiecutter.camelcase_modelname}}Model", + "Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel", + ] + ) +{% endif -%} +# End. + +# Below: " # Fast tokenizers structure" +# Replace with: + _import_structure["models.{{cookiecutter.lowercase_modelname}}"].append("{{cookiecutter.camelcase_modelname}}TokenizerFast") +# End. + +# Below: " # Models" +# Replace with: + "models.{{cookiecutter.lowercase_modelname}}": ["{{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP", "{{cookiecutter.camelcase_modelname}}Config", "{{cookiecutter.camelcase_modelname}}Tokenizer"], +# End. + +# To replace in: "src/transformers/__init__.py" +# Below: " # PyTorch model imports" if generating PyTorch +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + {{cookiecutter.camelcase_modelname}}ForMaskedLM, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForMultipleChoice, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}ForTokenClassification, + {{cookiecutter.camelcase_modelname}}Layer, + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}PreTrainedModel, + load_tf_weights_in_{{cookiecutter.lowercase_modelname}}, + ) +{% else %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + {{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + {{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + {{cookiecutter.camelcase_modelname}}ForCausalLM, + {{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + {{cookiecutter.camelcase_modelname}}ForSequenceClassification, + {{cookiecutter.camelcase_modelname}}Model, + {{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif -%} +# End. + +# Below: " # TensorFlow model imports" if generating TensorFlow +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + TF_{{cookiecutter.uppercase_modelname}}_PRETRAINED_MODEL_ARCHIVE_LIST, + TF{{cookiecutter.camelcase_modelname}}ForMaskedLM, + TF{{cookiecutter.camelcase_modelname}}ForCausalLM, + TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + TF{{cookiecutter.camelcase_modelname}}ForTokenClassification, + TF{{cookiecutter.camelcase_modelname}}Layer, + TF{{cookiecutter.camelcase_modelname}}Model, + TF{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% else %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + TF{{cookiecutter.camelcase_modelname}}Model, + TF{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif -%} +# End. + +# Below: " # Flax model imports" if generating Flax +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM, + Flax{{cookiecutter.camelcase_modelname}}ForCausalLM, + Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification, + Flax{{cookiecutter.camelcase_modelname}}Layer, + Flax{{cookiecutter.camelcase_modelname}}Model, + Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% else %} + from .models.{{cookiecutter.lowercase_modelname}} import ( + Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration, + Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering, + Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification, + Flax{{cookiecutter.camelcase_modelname}}Model, + Flax{{cookiecutter.camelcase_modelname}}PreTrainedModel, + ) +{% endif -%} +# End. + +# Below: " # Fast tokenizers imports" +# Replace with: + from .models.{{cookiecutter.lowercase_modelname}} import {{cookiecutter.camelcase_modelname}}TokenizerFast +# End. + +# Below: " from .models.albert import ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, AlbertConfig" +# Replace with: + from .models.{{cookiecutter.lowercase_modelname}} import {{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP, {{cookiecutter.camelcase_modelname}}Config, {{cookiecutter.camelcase_modelname}}Tokenizer +# End. + + + +# To replace in: "src/transformers/models/__init__.py" +# Below: "from . import (" +# Replace with: + {{cookiecutter.lowercase_modelname}}, +# End. + + +# To replace in: "src/transformers/models/auto/configuration_auto.py" +# Below: "# Add configs here" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}Config"), +# End. + +# Below: "# Add archive maps here" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.uppercase_modelname}}_PRETRAINED_CONFIG_ARCHIVE_MAP"), +# End. + +# Below: "# Add full (and cased) model names here" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}"), +# End. + + + +# To replace in: "src/transformers/models/auto/modeling_auto.py" if generating PyTorch +# Below: "# Base model mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}Model"), +# End. + +# Below: "# Model with LM heads mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + +# Below: "# Model for Causal LM mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForCausalLM"), +# End. + +# Below: "# Model for Masked LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Sequence Classification mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForSequenceClassification"), +# End. + +# Below: "# Model for Question Answering mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForQuestionAnswering"), +# End. + +# Below: "# Model for Token Classification mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForTokenClassification"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Multiple Choice mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForMultipleChoice"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Seq2Seq Causal LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + +# To replace in: "src/transformers/models/auto/modeling_tf_auto.py" if generating TensorFlow +# Below: "# Base model mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}Model"), +# End. + +# Below: "# Model with LM heads mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + +# Below: "# Model for Causal LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForCausalLM"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Masked LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Sequence Classification mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Question Answering mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Token Classification mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForTokenClassification"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Multiple Choice mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Seq2Seq Causal LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + +# To replace in: "src/transformers/models/auto/modeling_flax_auto.py" if generating Flax +# Below: "# Base model mapping" +# Replace with: + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}Model"), +# End. + +# Below: "# Model for Masked LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + +# Below: "# Model for Causal LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForCausalLM"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Masked LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Sequence Classification mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification"), +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification"), +{% endif -%} +# End. + +# Below: "# Model for Question Answering mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering"), +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering"), +{% endif -%} +# End. + +# Below: "# Model for Token Classification mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Multiple Choice mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice"), +{% else -%} +{% endif -%} +# End. + +# Below: "# Model for Seq2Seq Causal LM mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +{% else %} + ("{{cookiecutter.lowercase_modelname}}", "Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration"), +{% endif -%} +# End. + + + +# To replace in: "utils/check_repo.py" if generating PyTorch + +# Below: "models to ignore for model xxx mapping" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +{% else -%} + "{{cookiecutter.camelcase_modelname}}Encoder", + "{{cookiecutter.camelcase_modelname}}Decoder", + "{{cookiecutter.camelcase_modelname}}DecoderWrapper", +{% endif -%} +# End. + +# Below: "models to ignore for not tested" +# Replace with: +{% if cookiecutter.is_encoder_decoder_model == "False" -%} +{% else -%} + "{{cookiecutter.camelcase_modelname}}Encoder", # Building part of bigger (tested) model. + "{{cookiecutter.camelcase_modelname}}Decoder", # Building part of bigger (tested) model. + "{{cookiecutter.camelcase_modelname}}DecoderWrapper", # Building part of bigger (tested) model. +{% endif -%} +# End. diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_fast_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_fast_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..6e6c93698367feabaf050af25355e8386089bebc --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_fast_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,201 @@ +# coding=utf-8 +# Copyright 2022 {{cookiecutter.authors}} and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for {{cookiecutter.modelname}}.""" + +{%- if cookiecutter.tokenizer_type == "Based on BERT" %} +from ...utils import logging +from ..bert.tokenization_bert_fast import BertTokenizerFast +from .tokenization_{{cookiecutter.lowercase_modelname}} import {{cookiecutter.camelcase_modelname}}Tokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.txt", + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 512, +} + + +PRETRAINED_INIT_CONFIGURATION = { + "{{cookiecutter.checkpoint_identifier}}": {"do_lower_case": False}, +} + + +class {{cookiecutter.camelcase_modelname}}TokenizerFast(BertTokenizerFast): + r""" + Construct a "fast" {{cookiecutter.modelname}} tokenizer (backed by HuggingFace's *tokenizers* library). + + [`~{{cookiecutter.camelcase_modelname}}TokenizerFast`] is identical to [`BertTokenizerFast`] and runs + end-to-end tokenization: punctuation splitting and wordpiece. + + Refer to superclass [`BertTokenizerFast`] for usage examples and documentation concerning + parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + slow_tokenizer_class = {{cookiecutter.camelcase_modelname}}Tokenizer + +{%- elif cookiecutter.tokenizer_type == "Based on BART" %} +from ...utils import logging +from ..bart.tokenization_bart_fast import BartTokenizerFast +from .tokenization_{{cookiecutter.lowercase_modelname}} import {{cookiecutter.camelcase_modelname}}Tokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.json", + }, + "merges_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/merges.txt", + }, + "tokenizer_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 1024, +} + + +class {{cookiecutter.camelcase_modelname}}TokenizerFast(BartTokenizerFast): + r""" + Construct a "fast" {{cookiecutter.modelname}} tokenizer (backed by HuggingFace's *tokenizers* library). + + [`~{{cookiecutter.camelcase_modelname}}TokenizerFast`] is identical to [`BartTokenizerFast`] and runs + end-to-end tokenization: punctuation splitting and wordpiece. + + Refer to superclass [`BartTokenizerFast`] for usage examples and documentation concerning + parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + slow_tokenizer_class = {{cookiecutter.camelcase_modelname}}Tokenizer + +{%- elif cookiecutter.tokenizer_type == "Standalone" %} +from typing import List, Optional + +from tokenizers import ByteLevelBPETokenizer + +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging +from .tokenization_{{cookiecutter.lowercase_modelname}} import {{cookiecutter.camelcase_modelname}}Tokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.txt", + }, + "tokenizer_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/tokenizer.json", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 1024, +} + +class {{cookiecutter.camelcase_modelname}}TokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" {{cookiecutter.modelname}} tokenizer (backed by HuggingFace's *tokenizers* library). + + Args: + vocab_file (`str`): + Path to the vocabulary file. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + slow_tokenizer_class = {{cookiecutter.camelcase_modelname}}Tokenizer + + def __init__( + self, + vocab_file, + merges_file, + unk_token="<|endoftext|>", + bos_token="<|endoftext|>", + eos_token="<|endoftext|>", + add_prefix_space=False, + trim_offsets=True, + **kwargs + ): + super().__init__( + ByteLevelBPETokenizer( + vocab_file=vocab_file, + merges_file=merges_file, + add_prefix_space=add_prefix_space, + trim_offsets=trim_offsets, + ), + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + **kwargs, + ) + self.add_prefix_space = add_prefix_space + + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + output = [self.bos_token_id] + token_ids_0 + [self.eos_token_id] + if token_ids_1 is None: + return output + + return output + [self.eos_token_id] + token_ids_1 + [self.eos_token_id] + + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. + {{cookiecutter.modelname}} does not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + +{% endif %} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_{{cookiecutter.lowercase_modelname}}.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_{{cookiecutter.lowercase_modelname}}.py new file mode 100644 index 0000000000000000000000000000000000000000..a9c072f977d25f6c83e905bb26256808784a3484 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/tokenization_{{cookiecutter.lowercase_modelname}}.py @@ -0,0 +1,332 @@ +# coding=utf-8 +# Copyright 2022 {{cookiecutter.authors}} and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tokenization classes for {{cookiecutter.modelname}}.""" + +{%- if cookiecutter.tokenizer_type == "Based on BERT" %} +from ...utils import logging +from ..bert.tokenization_bert import BertTokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.txt", + } +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 512, +} + + +PRETRAINED_INIT_CONFIGURATION = { + "{{cookiecutter.checkpoint_identifier}}": {"do_lower_case": False}, +} + + +class {{cookiecutter.camelcase_modelname}}Tokenizer(BertTokenizer): + r""" + Construct a {{cookiecutter.modelname}} tokenizer. + + [`~{{cookiecutter.camelcase_modelname}}Tokenizer`] is identical to [`BertTokenizer`] and runs end-to-end + tokenization: punctuation splitting and wordpiece. + + Refer to superclass [`BertTokenizer`] for usage examples and documentation concerning + parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION + +{%- elif cookiecutter.tokenizer_type == "Based on BART" %} +from ...utils import logging +from ..bart.tokenization_bart import BartTokenizer + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.json", + }, + "merges_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/merges.txt", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 1024, +} + + +class {{cookiecutter.camelcase_modelname}}Tokenizer(BartTokenizer): + """ + Construct a {{cookiecutter.modelname}} tokenizer. + + [`~{{cookiecutter.camelcase_modelname}}Tokenizer`] is identical to [`BartTokenizer`] and runs end-to-end + tokenization: punctuation splitting and wordpiece. + + Refer to superclass [`BartTokenizer`] for usage examples and documentation concerning + parameters. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + +{%- elif cookiecutter.tokenizer_type == "Standalone" %} +from typing import List, Optional + +from tokenizers import ByteLevelBPETokenizer + +from ...tokenization_utils import AddedToken, PreTrainedTokenizer +from ...tokenization_utils_fast import PreTrainedTokenizerFast +from ...utils import logging + + +logger = logging.get_logger(__name__) + +VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"} + +PRETRAINED_VOCAB_FILES_MAP = { + "vocab_file": { + "{{cookiecutter.checkpoint_identifier}}": "https://huggingface.co/{{cookiecutter.checkpoint_identifier}}/resolve/main/vocab.txt", + }, +} + +PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = { + "{{cookiecutter.checkpoint_identifier}}": 1024, +} + +class {{cookiecutter.camelcase_modelname}}Tokenizer(PreTrainedTokenizer): + """ + Construct a {{cookiecutter.modelname}} tokenizer. Based on byte-level Byte-Pair-Encoding. + + Args: + vocab_file (`str`): + Path to the vocabulary file. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + unk_token="<|endoftext|>", + bos_token="<|endoftext|>", + eos_token="<|endoftext|>", + **kwargs + ): + bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token + eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token + unk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_token + super().__init__(bos_token=bos_token, eos_token=eos_token, unk_token=unk_token, **kwargs) + + """ Initialisation """ + + @property + def vocab_size(self): + """ Returns vocab size """ + + def get_vocab(self): + """ Returns vocab as a dict """ + + def _tokenize(self, text): + """ Returns a tokenized string. """ + + def _convert_token_to_id(self, token): + """ Converts a token (str) in an id using the vocab. """ + + def _convert_id_to_token(self, index): + """Converts an index (integer) in a token (str) using the vocab.""" + + def convert_tokens_to_string(self, tokens): + """ Converts a sequence of tokens (string) in a single string. """ + + def save_vocabulary(self, save_directory): + """ + Save the vocabulary and special tokens file to a directory. + + Args: + save_directory (`str`): + The directory in which to save the vocabulary. + + Returns: + `Tuple(str)`: Paths to the files saved. + """ + + def build_inputs_with_special_tokens( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Build model inputs from a sequence or a pair of sequence for sequence classification tasks + by concatenating and adding special tokens. + A {{cookiecutter.modelname}} sequence has the following format: + + - single sequence: ` X ` + - pair of sequences: ` A B ` + + Args: + token_ids_0 (`List[int]`): + List of IDs to which the special tokens will be added. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. + """ + if token_ids_1 is None: + return [self.cls_token_id] + token_ids_0 + [self.sep_token_id] + cls = [self.cls_token_id] + sep = [self.sep_token_id] + return cls + token_ids_0 + sep + sep + token_ids_1 + sep + + def get_special_tokens_mask( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False + ) -> List[int]: + """ + Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding + special tokens using the tokenizer `prepare_for_model` method. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + already_has_special_tokens (`bool`, *optional*, defaults to `False`): + Whether or not the token list is already formatted with special tokens for the model. + + Returns: + `List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token. + """ + if already_has_special_tokens: + return super().get_special_tokens_mask( + token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True + ) + + if token_ids_1 is None: + return [1] + ([0] * len(token_ids_0)) + [1] + return [1] + ([0] * len(token_ids_0)) + [1, 1] + ([0] * len(token_ids_1)) + [1] + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. + {{cookiecutter.modelname}} does not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + + def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs): + add_prefix_space = kwargs.pop("add_prefix_space", self.add_prefix_space) + if (is_split_into_words or add_prefix_space) and (len(text) > 0 and not text[0].isspace()): + text = " " + text + return (text, kwargs) + +class {{cookiecutter.camelcase_modelname}}TokenizerFast(PreTrainedTokenizerFast): + """ + Construct a "fast" {{cookiecutter.modelname}} tokenizer (backed by HuggingFace's *tokenizers* library). + + Args: + vocab_file (`str`): + Path to the vocabulary file. + """ + + vocab_files_names = VOCAB_FILES_NAMES + pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP + max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES + model_input_names = ["input_ids", "attention_mask"] + + def __init__( + self, + vocab_file, + merges_file, + unk_token="<|endoftext|>", + bos_token="<|endoftext|>", + eos_token="<|endoftext|>", + add_prefix_space=False, + trim_offsets=True, + **kwargs + ): + super().__init__( + ByteLevelBPETokenizer( + vocab_file=vocab_file, + merges_file=merges_file, + add_prefix_space=add_prefix_space, + trim_offsets=trim_offsets, + ), + bos_token=bos_token, + eos_token=eos_token, + unk_token=unk_token, + **kwargs, + ) + self.add_prefix_space = add_prefix_space + + def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): + output = [self.bos_token_id] + token_ids_0 + [self.eos_token_id] + if token_ids_1 is None: + return output + + return output + [self.eos_token_id] + token_ids_1 + [self.eos_token_id] + + + def create_token_type_ids_from_sequences( + self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None + ) -> List[int]: + """ + Create a mask from the two sequences passed to be used in a sequence-pair classification task. + {{cookiecutter.modelname}} does not make use of token type ids, therefore a list of zeros is returned. + + Args: + token_ids_0 (`List[int]`): + List of IDs. + token_ids_1 (`List[int]`, *optional*): + Optional second list of IDs for sequence pairs. + + Returns: + `List[int]`: List of zeros. + """ + sep = [self.sep_token_id] + cls = [self.cls_token_id] + + if token_ids_1 is None: + return len(cls + token_ids_0 + sep) * [0] + return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0] + +{% endif %} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/{{cookiecutter.lowercase_modelname}}.mdx b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/{{cookiecutter.lowercase_modelname}}.mdx new file mode 100644 index 0000000000000000000000000000000000000000..dcbac3638d496c171afa9a35dc76f514dd527d56 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter-template-{{cookiecutter.modelname}}/{{cookiecutter.lowercase_modelname}}.mdx @@ -0,0 +1,234 @@ + + +# {{cookiecutter.modelname}} + +## Overview + +The {{cookiecutter.modelname}} model was proposed in []() by . + +The abstract from the paper is the following: + +** + +Tips: + + + +This model was contributed by [INSERT YOUR HF USERNAME HERE](). The original code can be found [here](). + +## {{cookiecutter.camelcase_modelname}}Config + +[[autodoc]] {{cookiecutter.camelcase_modelname}}Config + + +## {{cookiecutter.camelcase_modelname}}Tokenizer + +[[autodoc]] {{cookiecutter.camelcase_modelname}}Tokenizer + - build_inputs_with_special_tokens + - get_special_tokens_mask + - create_token_type_ids_from_sequences + - save_vocabulary + + +## {{cookiecutter.camelcase_modelname}}TokenizerFast + +[[autodoc]] {{cookiecutter.camelcase_modelname}}TokenizerFast + + +{% if "PyTorch" in cookiecutter.generate_tensorflow_pytorch_and_flax -%} +## {{cookiecutter.camelcase_modelname}}Model + +[[autodoc]] {{cookiecutter.camelcase_modelname}}Model + - forward + +{% if cookiecutter.is_encoder_decoder_model == "False" %} +## {{cookiecutter.camelcase_modelname}}ForCausalLM + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForCausalLM + - forward + + +## {{cookiecutter.camelcase_modelname}}ForMaskedLM + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForMaskedLM + - forward + + +## {{cookiecutter.camelcase_modelname}}ForSequenceClassification + +[[autodoc]] transformers.{{cookiecutter.camelcase_modelname}}ForSequenceClassification + - forward + +## {{cookiecutter.camelcase_modelname}}ForMultipleChoice + +[[autodoc]] transformers.{{cookiecutter.camelcase_modelname}}ForMultipleChoice + - forward + + +## {{cookiecutter.camelcase_modelname}}ForTokenClassification + +[[autodoc]] transformers.{{cookiecutter.camelcase_modelname}}ForTokenClassification + - forward + + +## {{cookiecutter.camelcase_modelname}}ForQuestionAnswering + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForQuestionAnswering + - forward + +{%- else %} +## {{cookiecutter.camelcase_modelname}}ForConditionalGeneration + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForConditionalGeneration + - forward + + +## {{cookiecutter.camelcase_modelname}}ForSequenceClassification + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForSequenceClassification + - forward + + +## {{cookiecutter.camelcase_modelname}}ForQuestionAnswering + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForQuestionAnswering + - forward + + +## {{cookiecutter.camelcase_modelname}}ForCausalLM + +[[autodoc]] {{cookiecutter.camelcase_modelname}}ForCausalLM + - forward + + +{% endif -%} +{% endif -%} +{% if "TensorFlow" in cookiecutter.generate_tensorflow_pytorch_and_flax -%} + +## TF{{cookiecutter.camelcase_modelname}}Model + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}Model + - call + +{% if cookiecutter.is_encoder_decoder_model == "False" %} +## TF{{cookiecutter.camelcase_modelname}}ForMaskedLM + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForMaskedLM + - call + + +## TF{{cookiecutter.camelcase_modelname}}ForCausalLM + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForCausalLM + - call + + +## TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForSequenceClassification + - call + + +## TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForMultipleChoice + - call + + +## TF{{cookiecutter.camelcase_modelname}}ForTokenClassification + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForTokenClassification + - call + + +## TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + - call + + +{%- else %} +## TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration + +[[autodoc]] TF{{cookiecutter.camelcase_modelname}}ForConditionalGeneration + - call + + +{% endif -%} +{% endif -%} + +{% if "Flax" in cookiecutter.generate_tensorflow_pytorch_and_flax -%} + +## Flax{{cookiecutter.camelcase_modelname}}Model + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}Model + - call + +{% if cookiecutter.is_encoder_decoder_model == "False" %} +## Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForMaskedLM + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForCausalLM + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForCausalLM + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForMultipleChoice + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForTokenClassification + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + - call + + +{%- else %} +## Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForSequenceClassification + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForQuestionAnswering + - call + + +## Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration + +[[autodoc]] Flax{{cookiecutter.camelcase_modelname}}ForConditionalGeneration + - call + + +{% endif -%} +{% endif -%} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter.json new file mode 100644 index 0000000000000000000000000000000000000000..1fd9fda5b2f1be3a30ffa91f6de00bd2bfdc4474 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/cookiecutter.json @@ -0,0 +1,19 @@ +{ + "modelname": "BrandNewBERT", + "uppercase_modelname": "BRAND_NEW_BERT", + "lowercase_modelname": "brand_new_bert", + "camelcase_modelname": "BrandNewBert", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "brand-new-bert-base-cased", + "tokenizer_type": ["Based on BERT", "Based on BART", "Standalone"], + "generate_tensorflow_pytorch_and_flax": [ + "PyTorch, TensorFlow and Flax", + "PyTorch & TensorFlow", + "PyTorch & Flax", + "TensorFlow & Flax", + "PyTorch", + "TensorFlow", + "Flax" + ], + "is_encoder_decoder_model": ["True", "False"] +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/ADD_BIG_BIRD.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/ADD_BIG_BIRD.md new file mode 100644 index 0000000000000000000000000000000000000000..9c45c5b07f9da65cb6dfe8f007a9ff1bbc9d6c1b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/ADD_BIG_BIRD.md @@ -0,0 +1,1148 @@ +How to add BigBird to 🤗 Transformers? +===================================== + +Mentor: [Patrick](https://github.com/patrickvonplaten) + +Begin: 12.02.2020 + +Estimated End: 19.03.2020 + +Contributor: [Vasudev](https://github.com/vasudevgupta7) + +Adding a new model is often difficult and requires an in-depth knowledge +of the 🤗 Transformers library and ideally also of the model's original +repository. At Hugging Face, we are trying to empower the community more +and more to add models independently. + +The following sections explain in detail how to add BigBird +to Transformers. You will work closely with Patrick to +integrate BigBird into Transformers. By doing so, you will both gain a +theoretical and deep practical understanding of BigBird. +But more importantly, you will have made a major +open-source contribution to Transformers. Along the way, you will: + +- get insights into open-source best practices +- understand the design principles of one of the most popular NLP + libraries +- learn how to do efficiently test large NLP models +- learn how to integrate Python utilities like `black`, `ruff`, + `make fix-copies` into a library to always ensure clean and readable + code + +To start, let's try to get a general overview of the Transformers +library. + +General overview of 🤗 Transformers +---------------------------------- + +First, you should get a general overview of 🤗 Transformers. Transformers +is a very opinionated library, so there is a chance that +you don't agree with some of the library's philosophies or design +choices. From our experience, however, we found that the fundamental +design choices and philosophies of the library are crucial to +efficiently scale Transformers while keeping maintenance costs at a +reasonable level. + +A good first starting point to better understand the library is to read +the [documentation of our philosophy](https://huggingface.co/transformers/philosophy.html). +As a result of our way of working, there are some choices that we try to apply to all models: + +- Composition is generally favored over abstraction +- Duplicating code is not always bad if it strongly improves the + readability or accessibility of a model +- Model files are as self-contained as possible so that when you read + the code of a specific model, you ideally only have to look into the + respective `modeling_....py` file. + +In our opinion, the library's code is not just a means to provide a +product, *e.g.*, the ability to use BERT for inference, but also as the +very product that we want to improve. Hence, when adding a model, the +user is not only the person that will use your model, but also everybody +that will read, try to understand, and possibly tweak your code. + +With this in mind, let's go a bit deeper into the general library +design. + +### Overview of models + +To successfully add a model, it is important to understand the +interaction between your model and its config, +`PreTrainedModel`, and `PretrainedConfig`. For +exemplary purposes, we will call the PyTorch model to be added to 🤗 Transformers +`BrandNewBert`. + +Let's take a look: + +![image](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers_overview.png) + +As you can see, we do make use of inheritance in 🤗 Transformers, but we +keep the level of abstraction to an absolute minimum. There are never +more than two levels of abstraction for any model in the library. +`BrandNewBertModel` inherits from +`BrandNewBertPreTrainedModel` which in +turn inherits from `PreTrainedModel` and that's it. +As a general rule, we want to make sure +that a new model only depends on `PreTrainedModel`. The +important functionalities that are automatically provided to every new +model are +`PreTrainedModel.from_pretrained` and `PreTrainedModel.save_pretrained`, which are +used for serialization and deserialization. All +of the other important functionalities, such as +`BrandNewBertModel.forward` should be +completely defined in the new `modeling_brand_new_bert.py` module. Next, +we want to make sure that a model with a specific head layer, such as +`BrandNewBertForMaskedLM` does not inherit +from `BrandNewBertModel`, but rather uses +`BrandNewBertModel` as a component that +can be called in its forward pass to keep the level of abstraction low. +Every new model requires a configuration class, called +`BrandNewBertConfig`. This configuration +is always stored as an attribute in +`PreTrainedModel`, and +thus can be accessed via the `config` attribute for all classes +inheriting from `BrandNewBertPreTrainedModel` + +```python +# assuming that `brand_new_bert` belongs to the organization `brandy` +model = BrandNewBertModel.from_pretrained("brandy/brand_new_bert") +model.config # model has access to its config +``` + +Similar to the model, the configuration inherits basic serialization and +deserialization functionalities from +`PretrainedConfig`. Note +that the configuration and the model are always serialized into two +different formats - the model to a `pytorch_model.bin` file +and the configuration to a `config.json` file. Calling +`PreTrainedModel.save_pretrained` will automatically call +`PretrainedConfig.save_pretrained`, so that both model and configuration are saved. + +### Overview of tokenizers + +Not quite ready yet :-( This section will be added soon! + +Step-by-step recipe to add a model to 🤗 Transformers +---------------------------------------------------- + +Everyone has different preferences of how to port a model so it can be +very helpful for you to take a look at summaries of how other +contributors ported models to Hugging Face. Here is a list of community +blog posts on how to port a model: + +1. [Porting GPT2 + Model](https://medium.com/huggingface/from-tensorflow-to-pytorch-265f40ef2a28) + by [Thomas](https://huggingface.co/thomwolf) +2. [Porting WMT19 MT Model](https://huggingface.co/blog/porting-fsmt) + by [Stas](https://huggingface.co/stas) + +From experience, we can tell you that the most important things to keep +in mind when adding a model are: + +- Don't reinvent the wheel! Most parts of the code you will add for + the new 🤗 Transformers model already exist somewhere in 🤗 + Transformers. Take some time to find similar, already existing + models and tokenizers you can copy from. + [grep](https://www.gnu.org/software/grep/) and + [rg](https://github.com/BurntSushi/ripgrep) are your friends. Note + that it might very well happen that your model's tokenizer is based + on one model implementation, and your model's modeling code on + another one. *E.g.*, FSMT's modeling code is based on BART, while + FSMT's tokenizer code is based on XLM. +- It's more of an engineering challenge than a scientific challenge. + You should spend more time on creating an efficient debugging + environment than trying to understand all theoretical aspects of the + model in the paper. +- Ask for help when you're stuck! Models are the core component of 🤗 + Transformers so we, at Hugging Face, are more than happy to help + you at every step to add your model. Don't hesitate to ask if you + notice you are not making progress. + +In the following, we try to give you a general recipe that we found most +useful when porting a model to 🤗 Transformers. + +The following list is a summary of everything that has to be done to add +a model and can be used by you as a To-Do List: + +1. [ ] (Optional) Understood theoretical aspects + +2. [ ] Prepared transformers dev environment + +3. [ ] Set up debugging environment of the original repository + +4. [ ] Created script that successfully runs forward pass using + original repository and checkpoint + +5. [ ] Successfully opened a PR and added the model skeleton to Transformers + +6. [ ] Successfully converted original checkpoint to Transformers + checkpoint + +7. [ ] Successfully ran forward pass in Transformers that gives + identical output to original checkpoint + +8. [ ] Finished model tests in Transformers + +9. [ ] Successfully added Tokenizer in Transformers + +10. [ ] Run end-to-end integration tests + +11. [ ] Finished docs + +12. [ ] Uploaded model weights to the hub + +13. [ ] Submitted the pull request for review + +14. [ ] (Optional) Added a demo notebook + +To begin with, we usually recommend to start by getting a good +theoretical understanding of `BigBird`. However, if you prefer to +understand the theoretical aspects of the model *on-the-job*, then it is +totally fine to directly dive into the `BigBird`'s code-base. This +option might suit you better, if your engineering skills are better than +your theoretical skill, if you have trouble understanding +`BigBird`'s paper, or if you just enjoy programming much more than +reading scientific papers. + +### 1. (Optional) Theoretical aspects of BigBird + +You should take some time to read *BigBird's* paper, if such +descriptive work exists. There might be large sections of the paper that +are difficult to understand. If this is the case, this is fine - don't +worry! The goal is not to get a deep theoretical understanding of the +paper, but to extract the necessary information required to effectively +re-implement the model in 🤗 Transformers. That being said, you don't +have to spend too much time on the theoretical aspects, but rather focus +on the practical ones, namely: + +- What type of model is *BigBird*? BERT-like encoder-only + model? GPT2-like decoder-only model? BART-like encoder-decoder + model? Look at the `model_summary` if + you're not familiar with the differences between those. +- What are the applications of *BigBird*? Text + classification? Text generation? Seq2Seq tasks, *e.g.,* + summarization? +- What is the novel feature of the model making it different from + BERT/GPT-2/BART? +- Which of the already existing [🤗 Transformers + models](https://huggingface.co/transformers/#contents) is most + similar to *BigBird*? +- What type of tokenizer is used? A sentencepiece tokenizer? Word + piece tokenizer? Is it the same tokenizer as used for BERT or BART? + +After you feel like you have gotten a good overview of the architecture +of the model, you might want to write to Patrick with any +questions you might have. This might include questions regarding the +model's architecture, its attention layer, etc. We will be more than +happy to help you. + + +#### Additional resources + + Before diving into the code, here are some additional resources that might be worth taking a look at: + + - [Yannic Kilcher's paper summary](https://www.youtube.com/watch?v=WVPE62Gk3EM&ab_channel=YannicKilcher) + - [Yannic Kilcher's summary of Longformer](https://www.youtube.com/watch?v=_8KNb5iqblE&ab_channel=YannicKilcher) - Longformer and BigBird are **very** similar models. Since Longformer has already been ported to 🤗 Transformers, it is useful to understand the differences between the two models + - [Blog post](https://medium.com/dsc-msit/is-google-bigbird-gonna-be-the-new-leader-in-nlp-domain-8c95cecc30f8) - A relatively superficial blog post about BigBird. Might be a good starting point to understand BigBird + +#### Make sure you've understood the fundamental aspects of BigBird + +Alright, now you should be ready to take a closer look into the actual code of BigBird. +You should have understood the following aspects of BigBird by now: + +- BigBird provides a new attention layer for long-range sequence modelling that can be used + as a drop-in replacement for already existing architectures. This means that every transformer-based model architecture can replace its [Self-attention layer](https://towardsdatascience.com/illustrated-self-attention-2d627e33b20a) with BigBird's self-attention layer. +- BigBird's self-attention layer is composed of three mechanisms: block sparse (local) self-attention, global self-attention, random self-attention +- BigBird's block sparse (local) self-attention is different from Longformer's local self-attention. How so? Why does that matter? => Can be deployed on TPU much easier this way +- BigBird can be implemented for both an encoder-only model **and** + for an encoder-decoder model, which means that we can reuse lots of [code from RoBERTa](https://github.com/huggingface/transformers/blob/main/src/transformers/models/roberta/modeling_roberta.py) and [from PEGASUS](https://github.com/huggingface/transformers/blob/main/src/transformers/models/pegasus/modeling_pegasus.py) at a later stage. + + +If any of the mentioned aspects above are **not** clear to you, now is a great time to talk to Patrick. + +### 2. Next prepare your environment + +1. Fork the [repository](https://github.com/huggingface/transformers) + by clicking on the 'Fork' button on the repository's page. This + creates a copy of the code under your GitHub user account. + +2. Clone your `transformers` fork to your local disk, and add the base + repository as a remote: + + ```bash + git clone https://github.com/[your Github handle]/transformers.git + cd transformers + git remote add upstream https://github.com/huggingface/transformers.git + ``` + +3. Set up a development environment, for instance by running the + following command: + + ```bash + python -m venv .env + source .env/bin/activate + pip install -e ".[dev]" + ``` + +and return to the parent directory + +```bash +cd .. +``` + +4. We recommend adding the PyTorch version of *BigBird* to + Transformers. To install PyTorch, please follow the instructions [here](https://pytorch.org/get-started/locally/). + +**Note:** You don't need to have CUDA installed. Making the new model +work on CPU is sufficient. + +5. To port *BigBird*, you will also need access to its + original repository: + +```bash +git clone https://github.com/google-research/bigbird.git +cd big_bird +pip install -e . +``` + +Now you have set up a development environment to port *BigBird* +to 🤗 Transformers. + +### Run a pretrained checkpoint using the original repository + +**3. Set up debugging environment** + +At first, you will work on the original *BigBird* repository. +Often, the original implementation is very "researchy". Meaning that +documentation might be lacking and the code can be difficult to +understand. But this should be exactly your motivation to reimplement +*BigBird*. At Hugging Face, one of our main goals is to *make +people stand on the shoulders of giants* which translates here very well +into taking a working model and rewriting it to make it as **accessible, +user-friendly, and beautiful** as possible. This is the number-one +motivation to re-implement models into 🤗 Transformers - trying to make +complex new NLP technology accessible to **everybody**. + +You should start thereby by diving into the [original repository](https://github.com/google-research/bigbird). + +Successfully running the official pretrained model in the original +repository is often **the most difficult** step. From our experience, it +is very important to spend some time getting familiar with the original +code-base. You need to figure out the following: + +- Where to find the pretrained weights? +- How to load the pretrained weights into the corresponding model? +- How to run the tokenizer independently from the model? +- Trace one forward pass so that you know which classes and functions + are required for a simple forward pass. Usually, you only have to + reimplement those functions. +- Be able to locate the important components of the model: Where is + the model's class? Are there model sub-classes, *e.g.*, + EncoderModel, DecoderModel? Where is the self-attention layer? Are + there multiple different attention layers, *e.g.*, *self-attention*, + *cross-attention*...? +- How can you debug the model in the original environment of the repo? + Do you have to add `print` statements, can you work with + an interactive debugger like [ipdb](https://pypi.org/project/ipdb/), or should you use + an efficient IDE to debug the model, like PyCharm? + +It is very important that before you start the porting process, that you +can **efficiently** debug code in the original repository! Also, +remember that you are working with an open-source library, so do not +hesitate to open an issue, or even a pull request in the original +repository. The maintainers of this repository are most likely very +happy about someone looking into their code! + +At this point, it is really up to you which debugging environment and +strategy you prefer to use to debug the original model. We strongly +advise against setting up a costly GPU environment, but simply work on a +CPU both when starting to dive into the original repository and also +when starting to write the 🤗 Transformers implementation of the model. +Only at the very end, when the model has already been successfully +ported to 🤗 Transformers, one should verify that the model also works as +expected on GPU. + +In general, there are two possible debugging environments for running +the original model + +- [Jupyter notebooks](https://jupyter.org/) / [google colab](https://colab.research.google.com/notebooks/intro.ipynb) +- Local python scripts. + +Jupyter notebooks have the advantage that they allow for cell-by-cell +execution which can be helpful to better split logical components from +one another and to have faster debugging cycles as intermediate results +can be stored. Also, notebooks are often easier to share with other +contributors, which might be very helpful if you want to ask the Hugging +Face team for help. If you are familiar with Jupyter notebooks, we +strongly recommend you to work with them. + +The obvious disadvantage of Jupyter notebooks is that if you are not +used to working with them you will have to spend some time adjusting to +the new programming environment and that you might not be able to use +your known debugging tools anymore, like `ipdb`. + +**4. Successfully run forward pass** + +For each code-base, a good first step is always to load a **small** +pretrained checkpoint and to be able to reproduce a single forward pass +using a dummy integer vector of input IDs as an input. Such a script +could look something like this: + +```python +from bigbird.core import modeling +model = modeling.BertModel(bert_config) +from bigbird.core import utils + +params = utils.BigBirdConfig(vocab_size=32000, hidden_size=512, + num_hidden_layers=8, num_attention_heads=6, intermediate_size=1024) + +ckpt_path = 'gs://bigbird-transformer/pretrain/bigbr_base/model.ckpt-0' +ckpt_reader = tf.compat.v1.train.NewCheckpointReader(ckpt_path) +model.set_weights([ckpt_reader.get_tensor(v.name[:-2]) for v in tqdm(model.trainable_weights, position=0)]) + +input_ids = tf.constant([[31, 51, 99], [15, 5, 0]]) +_, pooled_output = model(input_ids=input_ids, token_type_ids=token_type_ids) +... + +``` + +Next, regarding the debugging strategy, there are generally a few from +which to choose from: + +- Decompose the original model into many small testable components and + run a forward pass on each of those for verification +- Decompose the original model only into the original *tokenizer* and + the original *model*, run a forward pass on those, and use + intermediate print statements or breakpoints for verification + +Again, it is up to you which strategy to choose. Often, one or the other +is advantageous depending on the original code base. + +If the original code-base allows you to decompose the model into smaller +sub-components, *e.g.*, if the original code-base can easily be run in +eager mode, it is usually worth the effort to do so. There are some +important advantages to taking the more difficult road in the beginning: + +- at a later stage when comparing the original model to the Hugging + Face implementation, you can verify automatically for each component + individually that the corresponding component of the 🤗 Transformers + implementation matches instead of relying on visual comparison via + print statements +- it can give you some rope to decompose the big problem of porting a + model into smaller problems of just porting individual components + and thus structure your work better +- separating the model into logical meaningful components will help + you to get a better overview of the model's design and thus to + better understand the model +- at a later stage those component-by-component tests help you to + ensure that no regression occurs as you continue changing your code + +[Lysandre's](https://gist.github.com/LysandreJik/db4c948f6b4483960de5cbac598ad4ed) +integration checks for ELECTRA gives a nice example of how this can be +done. + +However, if the original code-base is very complex or only allows +intermediate components to be run in a compiled mode, it might be too +time-consuming or even impossible to separate the model into smaller +testable sub-components. A good example is [T5's +MeshTensorFlow](https://github.com/tensorflow/mesh/tree/master/mesh_tensorflow) +library which is very complex and does not offer a simple way to +decompose the model into its sub-components. For such libraries, one +often relies on verifying print statements. + +No matter which strategy you choose, the recommended procedure is often +the same in that you should start to debug the starting layers first and +the ending layers last. + +It is recommended that you retrieve the output, either by print +statements or sub-component functions, of the following layers in the +following order: + +1. Retrieve the input IDs passed to the model +2. Retrieve the word embeddings +3. Retrieve the input of the first Transformer layer +4. Retrieve the output of the first Transformer layer +5. Retrieve the output of the following n - 1 Transformer layers +6. Retrieve the output of the whole BigBird Model + +Input IDs should thereby consists of an array of integers, *e.g.*, +`input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19]` + +The outputs of the following layers often consist of multi-dimensional +float arrays and can look like this: + +```bash +[[ + [-0.1465, -0.6501, 0.1993, ..., 0.1451, 0.3430, 0.6024], + [-0.4417, -0.5920, 0.3450, ..., -0.3062, 0.6182, 0.7132], + [-0.5009, -0.7122, 0.4548, ..., -0.3662, 0.6091, 0.7648], + ..., + [-0.5613, -0.6332, 0.4324, ..., -0.3792, 0.7372, 0.9288], + [-0.5416, -0.6345, 0.4180, ..., -0.3564, 0.6992, 0.9191], + [-0.5334, -0.6403, 0.4271, ..., -0.3339, 0.6533, 0.8694]]], +``` + +We expect that every model added to 🤗 Transformers passes a couple of +integration tests, meaning that the original model and the reimplemented +version in 🤗 Transformers have to give the exact same output up to a +precision of 0.001! Since it is normal that the exact same model written +in different libraries can give a slightly different output depending on +the library framework, we accept an error tolerance of 1e-3 (0.001). It +is not enough if the model gives nearly the same output, they have to be +the almost identical. Therefore, you will certainly compare the +intermediate outputs of the 🤗 Transformers version multiple times +against the intermediate outputs of the original implementation of +*BigBird* in which case an **efficient** debugging environment +of the original repository is absolutely important. Here is some advice +to make your debugging environment as efficient as possible. + +- Find the best way of debugging intermediate results. Is the original + repository written in PyTorch? Then you should probably take the + time to write a longer script that decomposes the original model + into smaller sub-components to retrieve intermediate values. Is the + original repository written in Tensorflow 1? Then you might have to + rely on TensorFlow print operations like + [tf.print](https://www.tensorflow.org/api_docs/python/tf/print) to + output intermediate values. Is the original repository written in + Jax? Then make sure that the model is **not jitted** when running + the forward pass, *e.g.*, check-out [this + link](https://github.com/google/jax/issues/196). +- Use the smallest pretrained checkpoint you can find. The smaller the + checkpoint, the faster your debug cycle becomes. It is not efficient + if your pretrained model is so big that your forward pass takes more + than 10 seconds. In case only very large checkpoints are available, + it might make more sense to create a dummy model in the new + environment with randomly initialized weights and save those weights + for comparison with the 🤗 Transformers version of your model +- Make sure you are using the easiest way of calling a forward pass in + the original repository. Ideally, you want to find the function in + the original repository that **only** calls a single forward pass, + *i.e.* that is often called `predict`, `evaluate`, `forward` or + `__call__`. You don't want to debug a function that calls `forward` + multiple times, *e.g.*, to generate text, like + `autoregressive_sample`, `generate`. +- Try to separate the tokenization from the model's + forward pass. If the original repository shows + examples where you have to input a string, then try to find out + where in the forward call the string input is changed to input ids + and start from this point. This might mean that you have to possibly + write a small script yourself or change the original code so that + you can directly input the ids instead of an input string. +- Make sure that the model in your debugging setup is **not** in + training mode, which often causes the model to yield random outputs + due to multiple dropout layers in the model. Make sure that the + forward pass in your debugging environment is **deterministic** so + that the dropout layers are not used. Or use + `transformers.utils.set_seed` if the old and new + implementations are in the same framework. + +#### (Important) More details on how to create a debugging environment for BigBird + +- BigBird has multiple pretrained checkpoints that should eventually all be ported to + 🤗 Transformers. The pretrained checkpoints can be found [here](https://console.cloud.google.com/storage/browser/bigbird-transformer/pretrain;tab=objects?prefix=&forceOnObjectsSortingFiltering=false). + Those checkpoints include both pretrained weights for encoder-only (BERT/RoBERTa) under the folder `bigbr_base` and encoder-decoder (PEGASUS) under the folder `bigbp_large`. + You should start by porting the `bigbr_base` model. The encoder-decoder model + can be ported afterward. + for an encoder-decoder architecture as well as an encoder-only architecture. +- BigBird was written in tf.compat meaning that a mixture of a TensorFlow 1 and + TensorFlow 2 API was used. +- The most important part of the BigBird code-base is [bigbird.bigbird.core](https://github.com/google-research/bigbird/tree/master/bigbird/core) which includes all logic necessary + to implement BigBird. +- The first goal should be to successfully run a forward pass using the RoBERTa checkpoint `bigbr_base/model.ckpt-0.data-00000-of-00001` and `bigbr_base/model.ckpt-0.index`. + + +### Port BigBird to 🤗 Transformers + +Next, you can finally start adding new code to 🤗 Transformers. Go into +the clone of your 🤗 Transformers' fork: + + cd transformers + +In the special case that you are adding a model whose architecture +exactly matches the model architecture of an existing model you only +have to add a conversion script as described in [this +section](#write-a-conversion-script). In this case, you can just re-use +the whole model architecture of the already existing model. + +Otherwise, let's start generating a new model with the amazing +Cookiecutter! + +**Use the Cookiecutter to automatically generate the model's code** + +To begin with head over to the [🤗 Transformers +templates](https://github.com/huggingface/transformers/tree/main/templates/adding_a_new_model) +to make use of our `cookiecutter` implementation to automatically +generate all the relevant files for your model. Again, we recommend only +adding the PyTorch version of the model at first. Make sure you follow +the instructions of the `README.md` on the [🤗 Transformers +templates](https://github.com/huggingface/transformers/tree/main/templates/adding_a_new_model) +carefully. +Since you will first implement the Encoder-only/RoBERTa-like version of BigBird you should +select the `is_encoder_decoder_model = False` option in the cookiecutter. Also, it is recommended +that you implement the model only in PyTorch in the beginning and select "Standalone" as the +tokenizer type for now. + +**Open a Pull Request on the main huggingface/transformers repo** + +Before starting to adapt the automatically generated code, now is the +time to open a "Work in progress (WIP)" pull request, *e.g.*, "\[WIP\] +Add *BigBird*", in 🤗 Transformers so that you and the Hugging +Face team can work side-by-side on integrating the model into 🤗 +Transformers. + +You should do the following: + +1. Create a branch with a descriptive name from your main branch + +``` + git checkout -b add_big_bird +``` + +2. Commit the automatically generated code: + +``` + git add . + git commit +``` + +3. Fetch and rebase to current main + +``` + git fetch upstream + git rebase upstream/main +``` + +4. Push the changes to your account using: + +``` + git push -u origin a-descriptive-name-for-my-changes +``` + +5. Once you are satisfied, go to the webpage of your fork on GitHub. + Click on "Pull request". Make sure to add the GitHub handle of Patrick + as one reviewer, so that the Hugging Face team gets notified for future changes. + +6. Change the PR into a draft by clicking on "Convert to draft" on the + right of the GitHub pull request web page. + +In the following, whenever you have done some progress, don't forget to +commit your work and push it to your account so that it shows in the +pull request. Additionally, you should make sure to update your work +with the current main from time to time by doing: + + git fetch upstream + git merge upstream/main + +In general, all questions you might have regarding the model or your +implementation should be asked in your PR and discussed/solved in the +PR. This way, Patrick will always be notified when you are +committing new code or if you have a question. It is often very helpful +to point Patrick to your added code so that the Hugging +Face team can efficiently understand your problem or question. + +To do so, you can go to the "Files changed" tab where you see all of +your changes, go to a line regarding which you want to ask a question, +and click on the "+" symbol to add a comment. Whenever a question or +problem has been solved, you can click on the "Resolve" button of the +created comment. + +In the same way, Patrick will open comments when reviewing +your code. We recommend asking most questions on GitHub on your PR. For +some very general questions that are not very useful for the public, +feel free to ping Patrick by Slack or email. + +**5. Adapt the generated models code for BigBird** + +At first, we will focus only on the model itself and not care about the +tokenizer. All the relevant code should be found in the generated files +`src/transformers/models/big_bird/modeling_big_bird.py` and +`src/transformers/models/big_bird/configuration_big_bird.py`. + +Now you can finally start coding :). The generated code in +`src/transformers/models/big_bird/modeling_big_bird.py` will +either have the same architecture as BERT if it's an encoder-only model +or BART if it's an encoder-decoder model. At this point, you should +remind yourself what you've learned in the beginning about the +theoretical aspects of the model: *How is the model different from BERT +or BART?*\". Implement those changes which often means to change the +*self-attention* layer, the order of the normalization layer, etc... +Again, it is often useful to look at the similar architecture of already +existing models in Transformers to get a better feeling of how your +model should be implemented. + +**Note** that at this point, you don't have to be very sure that your +code is fully correct or clean. Rather, it is advised to add a first +*unclean*, copy-pasted version of the original code to +`src/transformers/models/big_bird/modeling_big_bird.py` +until you feel like all the necessary code is added. From our +experience, it is much more efficient to quickly add a first version of +the required code and improve/correct the code iteratively with the +conversion script as described in the next section. The only thing that +has to work at this point is that you can instantiate the 🤗 Transformers +implementation of *BigBird*, *i.e.* the following command +should work: + +```python +from transformers import BigBirdModel, BigBirdConfig +model = BigBirdModel(BigBirdConfig()) +``` + +The above command will create a model according to the default +parameters as defined in `BigBirdConfig()` with random weights, +thus making sure that the `init()` methods of all components works. + +Note that for BigBird you have to change the attention layer. BigBird's attention +layer is quite complex as you can see [here](https://github.com/google-research/bigbird/blob/103a3345f94bf6364749b51189ed93024ca5ef26/bigbird/core/attention.py#L560). Don't +feel discouraged by this! In a first step you should simply make sure that +the layer `BigBirdAttention` has the correct weights as can be found in the +pretrained checkpoints. This means that you have to make sure that in the +`__init__(self, ...)` function of `BigBirdAttention`, all submodules include all +necessary `nn.Module` layers. Only at a later stage do we need to fully rewrite +the complex attention function. + +**6. Write a conversion script** + +Next, you should write a conversion script that lets you convert the +checkpoint you used to debug *BigBird* in the original +repository to a checkpoint compatible with your just created 🤗 +Transformers implementation of *BigBird*. It is not advised to +write the conversion script from scratch, but rather to look through +already existing conversion scripts in 🤗 Transformers for one that has +been used to convert a similar model that was written in the same +framework as *BigBird*. Usually, it is enough to copy an +already existing conversion script and slightly adapt it for your use +case. Don't hesitate to ask Patrick to point you to a +similar already existing conversion script for your model. + +- A good starting point to convert the original TF BigBird implementation to the PT Hugging Face implementation is probably BERT's conversion script + [here](https://github.com/huggingface/transformers/blob/7acfa95afb8194f8f9c1f4d2c6028224dbed35a2/src/transformers/models/bert/modeling_bert.py#L91) + +You can copy paste the conversion function into `modeling_big_bird.py` and then adapt it +to your needs. + +In the following, we'll quickly explain how PyTorch models store layer +weights and define layer names. In PyTorch, the name of a layer is +defined by the name of the class attribute you give the layer. Let's +define a dummy model in PyTorch, called `SimpleModel` as follows: + +```python +from torch import nn + +class SimpleModel(nn.Module): + def __init__(self): + super().__init__() + self.dense = nn.Linear(10, 10) + self.intermediate = nn.Linear(10, 10) + self.layer_norm = nn.LayerNorm(10) +``` + +Now we can create an instance of this model definition which will fill +all weights: `dense`, `intermediate`, `layer_norm` with random weights. +We can print the model to see its architecture + +```python +model = SimpleModel() + +print(model) +``` + +This will print out the following: + +```bash +SimpleModel( + (dense): Linear(in_features=10, out_features=10, bias=True) + (intermediate): Linear(in_features=10, out_features=10, bias=True) + (layer_norm): LayerNorm((10,), eps=1e-05, elementwise_affine=True) +) +``` + +We can see that the layer names are defined by the name of the class +attribute in PyTorch. You can print out the weight values of a specific +layer: + +```python +print(model.dense.weight.data) +``` + +to see that the weights were randomly initialized + +```bash +tensor([[-0.0818, 0.2207, -0.0749, -0.0030, 0.0045, -0.1569, -0.1598, 0.0212, + -0.2077, 0.2157], + [ 0.1044, 0.0201, 0.0990, 0.2482, 0.3116, 0.2509, 0.2866, -0.2190, + 0.2166, -0.0212], + [-0.2000, 0.1107, -0.1999, -0.3119, 0.1559, 0.0993, 0.1776, -0.1950, + -0.1023, -0.0447], + [-0.0888, -0.1092, 0.2281, 0.0336, 0.1817, -0.0115, 0.2096, 0.1415, + -0.1876, -0.2467], + [ 0.2208, -0.2352, -0.1426, -0.2636, -0.2889, -0.2061, -0.2849, -0.0465, + 0.2577, 0.0402], + [ 0.1502, 0.2465, 0.2566, 0.0693, 0.2352, -0.0530, 0.1859, -0.0604, + 0.2132, 0.1680], + [ 0.1733, -0.2407, -0.1721, 0.1484, 0.0358, -0.0633, -0.0721, -0.0090, + 0.2707, -0.2509], + [-0.1173, 0.1561, 0.2945, 0.0595, -0.1996, 0.2988, -0.0802, 0.0407, + 0.1829, -0.1568], + [-0.1164, -0.2228, -0.0403, 0.0428, 0.1339, 0.0047, 0.1967, 0.2923, + 0.0333, -0.0536], + [-0.1492, -0.1616, 0.1057, 0.1950, -0.2807, -0.2710, -0.1586, 0.0739, + 0.2220, 0.2358]]). +``` + +In the conversion script, you should fill those randomly initialized +weights with the exact weights of the corresponding layer in the +checkpoint. *E.g.*, + +```python +# retrieve matching layer weights, e.g. by +# recursive algorithm +layer_name = "dense" +pretrained_weight = array_of_dense_layer + +model_pointer = getattr(model, "dense") + +model_pointer.weight.data = torch.from_numpy(pretrained_weight) +``` + +While doing so, you must verify that each randomly initialized weight of +your PyTorch model and its corresponding pretrained checkpoint weight +exactly match in both **shape and name**. To do so, it is **necessary** +to add assert statements for the shape and print out the names of the +checkpoints weights. *E.g.*, you should add statements like: + +```python +assert ( + model_pointer.weight.shape == pretrained_weight.shape +), f"Pointer shape of random weight {model_pointer.shape} and array shape of checkpoint weight {pretrained_weight.shape} mismatched" +``` + +Besides, you should also print out the names of both weights to make +sure they match, *e.g.*, + +```python +logger.info(f"Initialize PyTorch weight {layer_name} from {pretrained_weight.name}") +``` + +If either the shape or the name doesn't match, you probably assigned +the wrong checkpoint weight to a randomly initialized layer of the 🤗 +Transformers implementation. + +An incorrect shape is most likely due to an incorrect setting of the +config parameters in `BigBirdConfig()` that do not exactly match +those that were used for the checkpoint you want to convert. However, it +could also be that PyTorch's implementation of a layer requires the +weight to be transposed beforehand. + +Finally, you should also check that **all** required weights are +initialized and print out all checkpoint weights that were not used for +initialization to make sure the model is correctly converted. It is +completely normal, that the conversion trials fail with either a wrong +shape statement or wrong name assignment. This is most likely because +either you used incorrect parameters in `BigBirdConfig()`, have a +wrong architecture in the 🤗 Transformers implementation, you have a bug +in the `init()` functions of one of the components of the 🤗 Transformers +implementation or you need to transpose one of the checkpoint weights. + +This step should be iterated with the previous step until all weights of +the checkpoint are correctly loaded in the Transformers model. Having +correctly loaded the checkpoint into the 🤗 Transformers implementation, +you can then save the model under a folder of your choice +`/path/to/converted/checkpoint/folder` that should then contain both a +`pytorch_model.bin` file and a `config.json` file: + +```python +model.save_pretrained("/path/to/converted/checkpoint/folder") +``` + +**7. Implement the forward pass** + +Having managed to correctly load the pretrained weights into the 🤗 +Transformers implementation, you should now make sure that the forward +pass is correctly implemented. In [Get familiar with the original +repository](#run-a-pretrained-checkpoint-using-the-original-repository), +you have already created a script that runs a forward pass of the model +using the original repository. Now you should write an analogous script +using the 🤗 Transformers implementation instead of the original one. It +should look as follows: + +[Here the model name might have to be adapted, *e.g.*, maybe BigBirdForConditionalGeneration instead of BigBirdModel] + +```python +model = BigBirdModel.from_pretrained("/path/to/converted/checkpoint/folder") +input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19] +output = model(input_ids).last_hidden_states +``` + +It is very likely that the 🤗 Transformers implementation and the +original model implementation don't give the exact same output the very +first time or that the forward pass throws an error. Don't be +disappointed - it's expected! First, you should make sure that the +forward pass doesn't throw any errors. It often happens that the wrong +dimensions are used leading to a `"Dimensionality mismatch"` +error or that the wrong data type object is used, *e.g.*, `torch.long` +instead of `torch.float32`. Don't hesitate to ask Patrick +for help, if you don't manage to solve certain errors. + +The final part to make sure the 🤗 Transformers implementation works +correctly is to ensure that the outputs are equivalent to a precision of +`1e-3`. First, you should ensure that the output shapes are identical, +*i.e.* `outputs.shape` should yield the same value for the script of the +🤗 Transformers implementation and the original implementation. Next, you +should make sure that the output values are identical as well. This one +of the most difficult parts of adding a new model. Common mistakes why +the outputs are not identical are: + +- Some layers were not added, *i.e.* an activation layer + was not added, or the residual connection was forgotten +- The word embedding matrix was not tied +- The wrong positional embeddings are used because the original + implementation uses on offset +- Dropout is applied during the forward pass. To fix this make sure + `model.training is False` and that no dropout layer is + falsely activated during the forward pass, *i.e.* pass + `self.training` to [PyTorch's functional + dropout](https://pytorch.org/docs/stable/nn.functional.html?highlight=dropout#torch.nn.functional.dropout) + +The best way to fix the problem is usually to look at the forward pass +of the original implementation and the 🤗 Transformers implementation +side-by-side and check if there are any differences. Ideally, you should +debug/print out intermediate outputs of both implementations of the +forward pass to find the exact position in the network where the 🤗 +Transformers implementation shows a different output than the original +implementation. First, make sure that the hard-coded `input_ids` in both +scripts are identical. Next, verify that the outputs of the first +transformation of the `input_ids` (usually the word embeddings) are +identical. And then work your way up to the very last layer of the +network. At some point, you will notice a difference between the two +implementations, which should point you to the bug in the 🤗 Transformers +implementation. From our experience, a simple and efficient way is to +add many print statements in both the original implementation and 🤗 +Transformers implementation, at the same positions in the network +respectively, and to successively remove print statements showing the +same values for intermediate presentions. + +When you're confident that both implementations yield the same output, +verifying the outputs with +`torch.allclose(original_output, output, atol=1e-3)`, you're done with +the most difficult part! Congratulations - the work left to be done +should be a cakewalk 😊. + +**8. Adding all necessary model tests** + +At this point, you have successfully added a new model. However, it is +very much possible that the model does not yet fully comply with the +required design. To make sure, the implementation is fully compatible +with 🤗 Transformers, all common tests should pass. The Cookiecutter +should have automatically added a test file for your model, probably +under the same `tests/test_modeling_big_bird.py`. Run this test +file to verify that all common tests pass: + +```python +pytest tests/test_modeling_big_bird.py +``` + +Having fixed all common tests, it is now crucial to ensure that all the +nice work you have done is well tested, so that + +- a) The community can easily understand your work by looking at + specific tests of *BigBird* + +- b) Future changes to your model will not break any important + feature of the model. + +At first, integration tests should be added. Those integration tests +essentially do the same as the debugging scripts you used earlier to +implement the model to 🤗 Transformers. A template of those model tests +is already added by the Cookiecutter, called +`BigBirdModelIntegrationTests` and only has to be filled out by +you. To ensure that those tests are passing, run + +```python +RUN_SLOW=1 pytest -sv tests/test_modeling_big_bird.py::BigBirdModelIntegrationTests +``` + +**Note**: In case you are using Windows, you should replace `RUN_SLOW=1` with +`SET RUN_SLOW=1` + +Second, all features that are special to *BigBird* should be +tested additionally in a separate test under +`BigBirdModelTester`/`BigBirdModelTest`. This part is often +forgotten but is extremely useful in two ways: + +- It helps to transfer the knowledge you have acquired during the + model addition to the community by showing how the special features + of *BigBird* should work. +- Future contributors can quickly test changes to the model by running + those special tests. + +BigBird has quite a complex attention layer, so it is very important +to add more tests verifying the all parts of BigBird's self-attention layer +works as expected. This means that there should be at least 3 additional tests: + +- 1. Verify that the sparse attention works correctly +- 2. Verify that the global attention works correctly +- 3. Verify that the random attention works correctly + +**9. Implement the tokenizer** + +Next, we should add the tokenizer of *BigBird*. Usually, the +tokenizer is equivalent or very similar to an already existing tokenizer +of 🤗 Transformers. + +In the case of BigBird you should be able to just rely on an already existing tokenizer. +If not mistaken, BigBird uses the same tokenizer that was used for `BertGenerationTokenizer`, +which is based on `sentencepiece`. So you should be able to just set the config parameter +`tokenizer_class` to `BertGenerationTokenizer` without having to implement any new tokenizer. + +It is very important to find/extract the original tokenizer file and to +manage to load this file into the 🤗 Transformers' implementation of the +tokenizer. + +For BigBird, the tokenizer (sentencepiece) files can be found [here](https://github.com/google-research/bigbird/blob/master/bigbird/vocab/gpt2.model), which you should be able to load +as easily as: + +```python +from transformers import BertGenerationTokenizer +tokenizer = BertGenerationTokenizer("/path/to/gpt2.model/file") +``` + +To ensure that the tokenizer works correctly, it is recommended to first +create a script in the original repository that inputs a string and +returns the `input_ids`. It could look similar to this (in pseudo-code): + +```bash +input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words." +model = BigBirdModel.load_pretrained_checkpoint("/path/to/checkpoint/") +input_ids = model.tokenize(input_str) +``` + +You might have to take a deeper look again into the original repository +to find the correct tokenizer function or you might even have to do +changes to your clone of the original repository to only output the +`input_ids`. Having written a functional tokenization script that uses +the original repository, an analogous script for 🤗 Transformers should +be created. It should look similar to this: + +```python +from transformers import BertGenerationTokenizer +input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words." + +tokenizer = BertGenerationTokenizer.from_pretrained("/path/big/bird/folder") + +input_ids = tokenizer(input_str).input_ids +``` + +When both `input_ids` yield the same values, as a final step a tokenizer +test file should also be added. + +Since BigBird is most likely fully based on `BertGenerationTokenizer`, +you should only add a couple of "slow" integration tests. However, in this +case you do **not** need to add any `BigBirdTokenizationTest`. + +**10. Run End-to-end integration tests** + +Having added the tokenizer, you should also add a couple of end-to-end +integration tests using both the model and the tokenizer to +`tests/test_modeling_big_bird.py` in 🤗 Transformers. Such a test +should show on a meaningful text-to-text sample that the 🤗 Transformers +implementation works as expected. A meaningful text-to-text sample can +include, *e.g.*, a source-to-target-translation pair, an +article-to-summary pair, a question-to-answer pair, etc... If none of +the ported checkpoints has been fine-tuned on a downstream task it is +enough to simply rely on the model tests. In a final step to ensure that +the model is fully functional, it is advised that you also run all tests +on GPU. It can happen that you forgot to add some `.to(self.device)` +statements to internal tensors of the model, which in such a test would +show in an error. In case you have no access to a GPU, the Hugging Face +team can take care of running those tests for you. + +**11. Add Docstring** + +Now, all the necessary functionality for *BigBird* is added - +you're almost done! The only thing left to add is a nice docstring and +a doc page. The Cookiecutter should have added a template file called +`docs/source/model_doc/big_bird.rst` that you should fill out. +Users of your model will usually first look at this page before using +your model. Hence, the documentation must be understandable and concise. +It is very useful for the community to add some *Tips* to show how the +model should be used. Don't hesitate to ping Patrick +regarding the docstrings. + +Next, make sure that the docstring added to +`src/transformers/models/big_bird/modeling_big_bird.py` is +correct and included all necessary inputs and outputs. It is always to +good to remind oneself that documentation should be treated at least as +carefully as the code in 🤗 Transformers since the documentation is +usually the first contact point of the community with the model. + +**Code refactor** + +Great, now you have added all the necessary code for *BigBird*. +At this point, you should correct some potential incorrect code style by +running: + +```bash +make style +``` + +and verify that your coding style passes the quality check: + +```bash +make quality +``` + +There are a couple of other very strict design tests in 🤗 Transformers +that might still be failing, which shows up in the tests of your pull +request. This is often because of some missing information in the +docstring or some incorrect naming. Patrick will surely +help you if you're stuck here. + +Lastly, it is always a good idea to refactor one's code after having +ensured that the code works correctly. With all tests passing, now it's +a good time to go over the added code again and do some refactoring. + +You have now finished the coding part, congratulation! 🎉 You are +Awesome! 😎 + +**12. Upload the models to the model hub** + +In this final part, you should convert and upload all checkpoints to the +model hub and add a model card for each uploaded model checkpoint. You +should work alongside Patrick here to decide on a fitting +name for each checkpoint and to get the required access rights to be +able to upload the model under the author's organization of +*BigBird*. + +It is worth spending some time to create fitting model cards for each +checkpoint. The model cards should highlight the specific +characteristics of this particular checkpoint, *e.g.*, On which dataset +was the checkpoint pretrained/fine-tuned on? On what down-stream task +should the model be used? And also include some code on how to correctly +use the model. + +**13. (Optional) Add notebook** + +It is very helpful to add a notebook that showcases in-detail how +*BigBird* can be used for inference and/or fine-tuned on a +downstream task. This is not mandatory to merge your PR, but very useful +for the community. + +**14. Submit your finished PR** + +You're done programming now and can move to the last step, which is +getting your PR merged into main. Usually, Patrick +should have helped you already at this point, but it is worth taking +some time to give your finished PR a nice description and eventually add +comments to your code, if you want to point out certain design choices +to your reviewer. + +### Share your work!! + +Now, it's time to get some credit from the community for your work! +Having completed a model addition is a major contribution to +Transformers and the whole NLP community. Your code and the ported +pre-trained models will certainly be used by hundreds and possibly even +thousands of developers and researchers. You should be proud of your +work and share your achievement with the community. + +**You have made another model that is super easy to access for everyone +in the community! 🤯** diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/README.md b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dd254209f007540e9607c83b887065e9ad46fe85 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/open_model_proposals/README.md @@ -0,0 +1,3 @@ +Currently the following model proposals are available: + +- [BigBird (Google)](./ADD_BIG_BIRD.md) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/encoder-bert-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/encoder-bert-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..dcc686c71210c9f08bc744d73dde94d39585dece --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/encoder-bert-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "Template", + "uppercase_modelname": "TEMPLATE", + "lowercase_modelname": "template", + "camelcase_modelname": "Template", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "brand-new-bert-base-cased", + "tokenizer_type": "Based on BERT", + "generate_tensorflow_pytorch_and_flax": "PyTorch, TensorFlow and Flax", + "is_encoder_decoder_model": "False" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-encoder-bert-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-encoder-bert-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..506ba974c730f52a41293c13e2ff126eed04b4de --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-encoder-bert-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "TemplateFLAX", + "uppercase_modelname": "TEMPLATE_FLAX", + "lowercase_modelname": "template_flax", + "camelcase_modelname": "TemplateFlax", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "brand-new-bert-base-cased", + "tokenizer_type": "Based on BERT", + "generate_tensorflow_pytorch_and_flax": "Flax", + "is_encoder_decoder_model": "False" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-seq-2-seq-bart-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-seq-2-seq-bart-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..a5ad69324e6fc896dd9975c32667b519c95612a8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/flax-seq-2-seq-bart-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "FlaxNewENCDEC", + "uppercase_modelname": "FLAX_NEW_ENC_DEC", + "lowercase_modelname": "flax_new_enc_dec_template", + "camelcase_modelname": "FlaxNewEncDec", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "new-flax-enc-dec-base", + "tokenizer_type": "Based on BART", + "generate_tensorflow_pytorch_and_flax": "Flax", + "is_encoder_decoder_model": "True" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-encoder-bert-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-encoder-bert-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..48a47e5dc4a4a2b5802b387d8f709f3bbed1c576 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-encoder-bert-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "TemplatePT", + "uppercase_modelname": "TEMPLATE_PT", + "lowercase_modelname": "template_pt", + "camelcase_modelname": "TemplatePt", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "brand-new-bert-base-cased", + "tokenizer_type": "Based on BERT", + "generate_tensorflow_pytorch_and_flax": "PyTorch", + "is_encoder_decoder_model": "False" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-seq-2-seq-bart-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-seq-2-seq-bart-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..2fb0fdf4e598f99c750b9d178e2aeff22c93a96c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/pt-seq-2-seq-bart-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "PTNewENCDEC", + "uppercase_modelname": "PT_NEW_ENC_DEC", + "lowercase_modelname": "pt_new_enc_dec_template", + "camelcase_modelname": "PtNewEncDec", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "pt-new-enc-dec-base", + "tokenizer_type": "Based on BART", + "generate_tensorflow_pytorch_and_flax": "PyTorch", + "is_encoder_decoder_model": "True" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/standalone.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/standalone.json new file mode 100644 index 0000000000000000000000000000000000000000..9b6b2a11829ea8f1dda96b5224bcb30f3b6ba26a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/standalone.json @@ -0,0 +1,11 @@ +{ + "modelname": "TemplateBI", + "uppercase_modelname": "TEMPLATE_BI", + "lowercase_modelname": "template_bi", + "camelcase_modelname": "TemplateBi", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "bi-brand-new-bert-base-cased", + "tokenizer_type": "Standalone", + "generate_tensorflow_pytorch_and_flax": "PyTorch, TensorFlow and Flax", + "is_encoder_decoder_model": "False" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-encoder-bert-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-encoder-bert-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..ea0178d4fa01fb2bc8ab4f0f6dcc6cd614d9336d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-encoder-bert-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "TemplateTF", + "uppercase_modelname": "TEMPLATE_TF", + "lowercase_modelname": "template_tf", + "camelcase_modelname": "TemplateTf", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "brand-new-bert-base-cased", + "tokenizer_type": "Based on BERT", + "generate_tensorflow_pytorch_and_flax": "TensorFlow", + "is_encoder_decoder_model": "False" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-seq-2-seq-bart-tokenizer.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-seq-2-seq-bart-tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..a1be4266b92a2b538a4c229dc838f9b93587da5a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/templates/adding_a_new_model/tests/tf-seq-2-seq-bart-tokenizer.json @@ -0,0 +1,11 @@ +{ + "modelname": "NewTFENCDEC", + "uppercase_modelname": "NEW_TF_ENC_DEC", + "lowercase_modelname": "new_tf_enc_dec_template", + "camelcase_modelname": "NewTFEncDec", + "authors": "The HuggingFace Team", + "checkpoint_identifier": "new-tf-enc-dec-base_template", + "tokenizer_type": "Based on BART", + "generate_tensorflow_pytorch_and_flax": "TensorFlow", + "is_encoder_decoder_model": "True" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark.py new file mode 100644 index 0000000000000000000000000000000000000000..e4444ec2c4de6a0e1186db9d1b4c43dc7d67b660 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark.py @@ -0,0 +1,264 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import tempfile +import unittest +from pathlib import Path + +from transformers import AutoConfig, is_torch_available +from transformers.testing_utils import require_torch, torch_device + + +if is_torch_available(): + from transformers import PyTorchBenchmark, PyTorchBenchmarkArguments + + +@require_torch +class BenchmarkTest(unittest.TestCase): + def check_results_dict_not_empty(self, results): + for model_result in results.values(): + for batch_size, sequence_length in zip(model_result["bs"], model_result["ss"]): + result = model_result["result"][batch_size][sequence_length] + self.assertIsNotNone(result) + + def test_inference_no_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_no_configs_only_pretrain(self): + MODEL_ID = "sgugger/tiny-distilbert-classification" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + only_pretrain_model=True, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_torchscript(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + torchscript=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + @unittest.skipIf(torch_device == "cpu", "Cant do half precision") + def test_inference_fp16(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + fp16=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_no_model_no_architectures(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + # set architectures equal to `None` + config.architectures = None + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_train_no_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=False, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + @unittest.skipIf(torch_device == "cpu", "Can't do half precision") + def test_train_no_configs_fp16(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=False, + sequence_lengths=[8], + batch_sizes=[1], + fp16=True, + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + def test_inference_with_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_encoder_decoder_with_configs(self): + MODEL_ID = "sshleifer/tinier_bart" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_train_with_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=False, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + def test_train_encoder_decoder_with_configs(self): + MODEL_ID = "sshleifer/tinier_bart" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + def test_save_csv_files(self): + MODEL_ID = "sshleifer/tiny-gpt2" + with tempfile.TemporaryDirectory() as tmp_dir: + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=True, + save_to_csv=True, + sequence_lengths=[8], + batch_sizes=[1], + inference_time_csv_file=os.path.join(tmp_dir, "inf_time.csv"), + train_memory_csv_file=os.path.join(tmp_dir, "train_mem.csv"), + inference_memory_csv_file=os.path.join(tmp_dir, "inf_mem.csv"), + train_time_csv_file=os.path.join(tmp_dir, "train_time.csv"), + env_info_csv_file=os.path.join(tmp_dir, "env.csv"), + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + benchmark.run() + self.assertTrue(Path(os.path.join(tmp_dir, "inf_time.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "train_time.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "inf_mem.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "train_mem.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "env.csv")).exists()) + + def test_trace_memory(self): + MODEL_ID = "sshleifer/tiny-gpt2" + + def _check_summary_is_not_empty(summary): + self.assertTrue(hasattr(summary, "sequential")) + self.assertTrue(hasattr(summary, "cumulative")) + self.assertTrue(hasattr(summary, "current")) + self.assertTrue(hasattr(summary, "total")) + + with tempfile.TemporaryDirectory() as tmp_dir: + benchmark_args = PyTorchBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + log_filename=os.path.join(tmp_dir, "log.txt"), + log_print=True, + trace_memory_line_by_line=True, + multi_process=False, + ) + benchmark = PyTorchBenchmark(benchmark_args) + result = benchmark.run() + _check_summary_is_not_empty(result.inference_summary) + _check_summary_is_not_empty(result.train_summary) + self.assertTrue(Path(os.path.join(tmp_dir, "log.txt")).exists()) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark_tf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark_tf.py new file mode 100644 index 0000000000000000000000000000000000000000..2cea8e4c68198d8e20baa3f69656099df507c13d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/benchmark/test_benchmark_tf.py @@ -0,0 +1,226 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import tempfile +import unittest +from pathlib import Path + +from transformers import AutoConfig, is_tf_available +from transformers.testing_utils import require_tf + + +if is_tf_available(): + import tensorflow as tf + + from transformers import TensorFlowBenchmark, TensorFlowBenchmarkArguments + + +@require_tf +class TFBenchmarkTest(unittest.TestCase): + def check_results_dict_not_empty(self, results): + for model_result in results.values(): + for batch_size, sequence_length in zip(model_result["bs"], model_result["ss"]): + result = model_result["result"][batch_size][sequence_length] + self.assertIsNotNone(result) + + def test_inference_no_configs_eager(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + eager_mode=True, + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_no_configs_only_pretrain(self): + MODEL_ID = "sgugger/tiny-distilbert-classification" + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + only_pretrain_model=True, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_no_configs_graph(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_with_configs_eager(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + eager_mode=True, + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args, [config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_inference_with_configs_graph(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args, [config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_train_no_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=False, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + def test_train_with_configs(self): + MODEL_ID = "sshleifer/tiny-gpt2" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=True, + inference=False, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args, [config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_train_result) + self.check_results_dict_not_empty(results.memory_train_result) + + def test_inference_encoder_decoder_with_configs(self): + MODEL_ID = "patrickvonplaten/t5-tiny-random" + config = AutoConfig.from_pretrained(MODEL_ID) + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args, configs=[config]) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + @unittest.skipIf(is_tf_available() and len(tf.config.list_physical_devices("GPU")) == 0, "Cannot do xla on CPU.") + def test_inference_no_configs_xla(self): + MODEL_ID = "sshleifer/tiny-gpt2" + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + training=False, + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + use_xla=True, + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + results = benchmark.run() + self.check_results_dict_not_empty(results.time_inference_result) + self.check_results_dict_not_empty(results.memory_inference_result) + + def test_save_csv_files(self): + MODEL_ID = "sshleifer/tiny-gpt2" + with tempfile.TemporaryDirectory() as tmp_dir: + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + inference=True, + save_to_csv=True, + sequence_lengths=[8], + batch_sizes=[1], + inference_time_csv_file=os.path.join(tmp_dir, "inf_time.csv"), + inference_memory_csv_file=os.path.join(tmp_dir, "inf_mem.csv"), + env_info_csv_file=os.path.join(tmp_dir, "env.csv"), + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + benchmark.run() + self.assertTrue(Path(os.path.join(tmp_dir, "inf_time.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "inf_mem.csv")).exists()) + self.assertTrue(Path(os.path.join(tmp_dir, "env.csv")).exists()) + + def test_trace_memory(self): + MODEL_ID = "sshleifer/tiny-gpt2" + + def _check_summary_is_not_empty(summary): + self.assertTrue(hasattr(summary, "sequential")) + self.assertTrue(hasattr(summary, "cumulative")) + self.assertTrue(hasattr(summary, "current")) + self.assertTrue(hasattr(summary, "total")) + + with tempfile.TemporaryDirectory() as tmp_dir: + benchmark_args = TensorFlowBenchmarkArguments( + models=[MODEL_ID], + inference=True, + sequence_lengths=[8], + batch_sizes=[1], + log_filename=os.path.join(tmp_dir, "log.txt"), + log_print=True, + trace_memory_line_by_line=True, + eager_mode=True, + multi_process=False, + ) + benchmark = TensorFlowBenchmark(benchmark_args) + result = benchmark.run() + _check_summary_is_not_empty(result.inference_summary) + self.assertTrue(Path(os.path.join(tmp_dir, "log.txt")).exists()) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/bettertransformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/bettertransformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/bettertransformer/test_integration.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/bettertransformer/test_integration.py new file mode 100644 index 0000000000000000000000000000000000000000..bfbb3050bdd6f1ce0ac7d310a55b4debd7281c00 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/bettertransformer/test_integration.py @@ -0,0 +1,86 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tempfile +import unittest + +from transformers import AutoModelForSeq2SeqLM, AutoTokenizer +from transformers.testing_utils import ( + is_torch_available, + require_optimum, + require_torch, + slow, +) + + +if is_torch_available(): + import torch + + +@require_torch +@require_optimum +@slow +class BetterTransformerIntegrationTest(unittest.TestCase): + # refer to the full test suite in Optimum library: + # https://github.com/huggingface/optimum/tree/main/tests/bettertransformer + + def test_transform_and_reverse(self): + r""" + Classic tests to simply check if the conversion has been successfull. + """ + model_id = "hf-internal-testing/tiny-random-t5" + tokenizer = AutoTokenizer.from_pretrained(model_id) + model = AutoModelForSeq2SeqLM.from_pretrained(model_id) + + inp = tokenizer("This is me", return_tensors="pt") + + model = model.to_bettertransformer() + + self.assertTrue(any("BetterTransformer" in mod.__class__.__name__ for _, mod in model.named_modules())) + + output = model.generate(**inp) + + model = model.reverse_bettertransformer() + + self.assertFalse(any("BetterTransformer" in mod.__class__.__name__ for _, mod in model.named_modules())) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + model_reloaded = AutoModelForSeq2SeqLM.from_pretrained(tmpdirname) + + self.assertFalse( + any("BetterTransformer" in mod.__class__.__name__ for _, mod in model_reloaded.named_modules()) + ) + + output_from_pretrained = model_reloaded.generate(**inp) + self.assertTrue(torch.allclose(output, output_from_pretrained)) + + def test_error_save_pretrained(self): + r""" + The save_pretrained method should raise a ValueError if the model is in BetterTransformer mode. + All should be good if the model is reversed. + """ + model_id = "hf-internal-testing/tiny-random-t5" + model = AutoModelForSeq2SeqLM.from_pretrained(model_id) + + model = model.to_bettertransformer() + + with tempfile.TemporaryDirectory() as tmpdirname: + with self.assertRaises(ValueError): + model.save_pretrained(tmpdirname) + + model = model.reverse_bettertransformer() + model.save_pretrained(tmpdirname) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero2.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero2.json new file mode 100644 index 0000000000000000000000000000000000000000..6f0a546e51614dd082d9b03d06a3376dd5fb2a11 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero2.json @@ -0,0 +1,54 @@ +{ + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + + "bf16": { + "enabled": "auto" + }, + + "optimizer": { + "type": "AdamW", + "params": { + "lr": "auto", + "betas": "auto", + "eps": "auto", + "weight_decay": "auto" + } + }, + + "scheduler": { + "type": "WarmupLR", + "params": { + "warmup_min_lr": "auto", + "warmup_max_lr": "auto", + "warmup_num_steps": "auto" + } + }, + + "zero_optimization": { + "stage": 2, + "offload_optimizer": { + "device": "cpu", + "pin_memory": true + }, + "allgather_partitions": true, + "allgather_bucket_size": 2e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 2e8, + "contiguous_gradients": true + }, + + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "steps_per_print": 2000, + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "wall_clock_breakdown": false +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero3.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero3.json new file mode 100644 index 0000000000000000000000000000000000000000..4d7a154c9b0d6f16e8819865dbb01f038c5d6618 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/ds_config_zero3.json @@ -0,0 +1,61 @@ +{ + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + + "bf16": { + "enabled": "auto" + }, + + "optimizer": { + "type": "AdamW", + "params": { + "lr": "auto", + "betas": "auto", + "eps": "auto", + "weight_decay": "auto" + } + }, + + "scheduler": { + "type": "WarmupLR", + "params": { + "warmup_min_lr": "auto", + "warmup_max_lr": "auto", + "warmup_num_steps": "auto" + } + }, + + "zero_optimization": { + "stage": 3, + "offload_optimizer": { + "device": "cpu", + "pin_memory": true + }, + "offload_param": { + "device": "cpu", + "pin_memory": true + }, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto", + "stage3_prefetch_bucket_size": "auto", + "stage3_param_persistence_threshold": "auto", + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "stage3_gather_16bit_weights_on_model_save": true + }, + + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "steps_per_print": 2000, + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "wall_clock_breakdown": false +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_deepspeed.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_deepspeed.py new file mode 100644 index 0000000000000000000000000000000000000000..446952ef7a0422232f0a402393db61a56c3e2d58 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_deepspeed.py @@ -0,0 +1,1163 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import dataclasses +import io +import itertools +import json +import os +import unittest +from copy import deepcopy +from functools import partial + +import datasets +from parameterized import parameterized + +import tests.trainer.test_trainer +from tests.trainer.test_trainer import TrainerIntegrationCommon # noqa +from transformers import AutoModel, TrainingArguments, is_torch_available, logging +from transformers.deepspeed import HfDeepSpeedConfig, is_deepspeed_available, unset_hf_deepspeed_config +from transformers.testing_utils import ( + CaptureLogger, + CaptureStd, + CaptureStderr, + LoggingLevel, + TestCasePlus, + execute_subprocess_async, + get_gpu_count, + mockenv_context, + require_deepspeed, + require_optuna, + require_torch_gpu, + require_torch_multi_gpu, + slow, +) +from transformers.trainer_utils import get_last_checkpoint, set_seed +from transformers.utils import WEIGHTS_NAME, is_torch_bf16_gpu_available + + +if is_torch_available(): + from tests.trainer.test_trainer import ( # noqa + RegressionModelConfig, + RegressionPreTrainedModel, + ) + + # hack to restore original logging level pre #21700 + get_regression_trainer = partial(tests.trainer.test_trainer.get_regression_trainer, log_level="info") + + +set_seed(42) + +# default torch.distributed port +DEFAULT_MASTER_PORT = "10999" + +T5_SMALL = "t5-small" +T5_TINY = "patrickvonplaten/t5-tiny-random" +GPT2_TINY = "sshleifer/tiny-gpt2" + + +def load_json(path): + with open(path) as f: + return json.load(f) + + +def get_master_port(real_launcher=False): + """ + When using a single gpu launcher emulation (i.e. not deepspeed or python -m torch.distributed) + the issue is that once the port is tied it can't be used anywhere else outside of this process, + since torch.dist doesn't free the port until the process exits. Therefore for the sake of being + able to run both emulated launcher and normal launcher tests we need 2 distinct ports. + + This function will give the right port in the right context. For real launcher it'll give the + base port, for emulated launcher it'll give the base port + 1. In both cases a string is + returned. + + Args: + `real_launcher`: whether a real launcher is going to be used, or the emulated one + + """ + + master_port_base = os.environ.get("DS_TEST_PORT", DEFAULT_MASTER_PORT) + if not real_launcher: + master_port_base = str(int(master_port_base) + 1) + return master_port_base + + +def require_deepspeed_aio(test_case): + """ + Decorator marking a test that requires deepspeed aio (nvme) + """ + if not is_deepspeed_available(): + return unittest.skip("test requires deepspeed")(test_case) + + import deepspeed + from deepspeed.ops.aio import AsyncIOBuilder + + if not deepspeed.ops.__compatible_ops__[AsyncIOBuilder.NAME]: + return unittest.skip("test requires deepspeed async-io")(test_case) + else: + return test_case + + +if is_deepspeed_available(): + from deepspeed.utils import logger as deepspeed_logger # noqa + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + from transformers.deepspeed import deepspeed_config, is_deepspeed_zero3_enabled # noqa + + +def get_launcher(distributed=False): + # 1. explicitly set --num_nodes=1 just in case these tests end up run on a multi-node setup + # - it won't be able to handle that + # 2. for now testing with just 2 gpus max (since some quality tests may give different + # results with mode gpus because we use very little data) + num_gpus = min(2, get_gpu_count()) if distributed else 1 + master_port = get_master_port(real_launcher=True) + return f"deepspeed --num_nodes 1 --num_gpus {num_gpus} --master_port {master_port}".split() + + +ZERO2 = "zero2" +ZERO3 = "zero3" + +FP16 = "fp16" +BF16 = "bf16" + +stages = [ZERO2, ZERO3] +if is_torch_bf16_gpu_available(): + dtypes = [FP16, BF16] +else: + dtypes = [FP16] + + +def parameterized_custom_name_func(func, param_num, param): + # customize the test name generator function as we want both params to appear in the sub-test + # name, as by default it shows only the first param + param_based_name = parameterized.to_safe_name("_".join(str(x) for x in param.args)) + return f"{func.__name__}_{param_based_name}" + + +# Cartesian-product of zero stages with models to test +params = list(itertools.product(stages, dtypes)) + + +@require_deepspeed +@require_torch_gpu +class CoreIntegrationDeepSpeed(TestCasePlus, TrainerIntegrationCommon): + """ + Testing non-Trainer DeepSpeed integration + """ + + def setUp(self): + super().setUp() + + master_port = get_master_port(real_launcher=False) + self.dist_env_1_gpu = { + "MASTER_ADDR": "localhost", + "MASTER_PORT": master_port, + "RANK": "0", + "LOCAL_RANK": "0", + "WORLD_SIZE": "1", + } + + def tearDown(self): + super().tearDown() + + # reset the ds config global so that tests state doesn't leak + unset_hf_deepspeed_config() + + def test_init_zero3_fp16(self): + # test that zero.Init() works correctly under zero3/fp16 + ds_config = { + "train_batch_size": 1, + "zero_optimization": { + "stage": 3, + }, + } + + dschf = HfDeepSpeedConfig(ds_config) + + self.assertTrue(dschf.is_zero3()) + self.assertTrue(is_deepspeed_zero3_enabled()) + + with LoggingLevel(logging.INFO): + with mockenv_context(**self.dist_env_1_gpu): + logger = logging.get_logger("transformers.modeling_utils") + with CaptureLogger(logger) as cl: + AutoModel.from_pretrained(T5_TINY) + self.assertIn("Detected DeepSpeed ZeRO-3", cl.out) + + # now remove zero optimization + del ds_config["zero_optimization"] + dschf = HfDeepSpeedConfig(ds_config) + + self.assertFalse(dschf.is_zero3()) + self.assertFalse(is_deepspeed_zero3_enabled()) + + with LoggingLevel(logging.INFO): + with mockenv_context(**self.dist_env_1_gpu): + logger = logging.get_logger("transformers.modeling_utils") + with CaptureLogger(logger) as cl: + AutoModel.from_pretrained(T5_TINY) + self.assertNotIn("Detected DeepSpeed ZeRO-3", cl.out) + + +class TrainerIntegrationDeepSpeedWithCustomConfig(TestCasePlus): + def setUp(self): + super().setUp() + + args = TrainingArguments(".") + self.n_epochs = args.num_train_epochs + self.batch_size = args.train_batch_size + + master_port = get_master_port(real_launcher=False) + self.dist_env_1_gpu = { + "MASTER_ADDR": "localhost", + "MASTER_PORT": master_port, + "RANK": "0", + "LOCAL_RANK": "0", + "WORLD_SIZE": "1", + } + + self.ds_config_file = { + "zero2": f"{self.test_file_dir_str}/ds_config_zero2.json", + "zero3": f"{self.test_file_dir_str}/ds_config_zero3.json", + } + + # use self.get_config_dict(stage) to use these to ensure the original is not modified + with io.open(self.ds_config_file[ZERO2], "r", encoding="utf-8") as f: + config_zero2 = json.load(f) + with io.open(self.ds_config_file[ZERO3], "r", encoding="utf-8") as f: + config_zero3 = json.load(f) + # The following setting slows things down, so don't enable it by default unless needed by a test. + # It's in the file as a demo for users since we want everything to work out of the box even if slower. + config_zero3["zero_optimization"]["stage3_gather_16bit_weights_on_model_save"] = False + + self.ds_config_dict = { + "zero2": config_zero2, + "zero3": config_zero3, + } + + def tearDown(self): + super().tearDown() + + # reset the ds config global so that tests state doesn't leak + unset_hf_deepspeed_config() + + def get_config_dict(self, stage): + # As some tests modify the dict, always make a copy + return deepcopy(self.ds_config_dict[stage]) + + +@require_deepspeed +@require_torch_gpu +class TrainerIntegrationDeepSpeed(TrainerIntegrationDeepSpeedWithCustomConfig, TrainerIntegrationCommon): + """ + + This class is for testing directly via get_regression_trainer + + It mixes in `TrainerIntegrationCommon` which already has a lot of helper validation methods + which we can re-use here. + + Important: this class' setup can only work with a single gpu because it runs within the current + pytest worker. For multi-gpu tests use TestDeepSpeedWithLauncher. + + Note: if any of the tests of this class get run there will be at least one gpu occupied by them + until this pytest worker exits. This is because the gpu memory allocated by the cuda-kernels + won't be released until this pytest worker exits. + + This may appear as some run-away tests if you watch `nvidia-smi` while other tests that fork new + processes are run. So there will be one or two "stale" processes reported in `nvidia-smi`. This + is not a bug. + """ + + # --- These tests are enough to run on one of zero stages --- # + + def test_hf_ds_config_mismatch(self): + ds_config = self.get_config_dict(ZERO2) + + # Purposefully configure these values to mismatch TrainingArguments values. + # This currently doesn't cover all keys (but it could) + per_device_train_batch_size = 2 + ds_config["train_micro_batch_size_per_gpu"] = per_device_train_batch_size + 2 + + ds_config["train_batch_size"] = 1000 + + gradient_accumulation_steps = 2 + ds_config["gradient_accumulation_steps"] = gradient_accumulation_steps + 2 + + max_grad_norm = 1.0 + ds_config["gradient_clipping"] = max_grad_norm + 0.1 + + adam_beta1, adam_beta2 = 0.9, 0.99 + ds_config["optimizer"]["params"]["betas"] = [adam_beta1 - 0.1, adam_beta2 - 0.1] + + fp16 = True + ds_config["fp16"]["enabled"] = not fp16 + + keys = [ + "per_device_train_batch_size", + "train_batch_size", + "gradient_accumulation_steps", + "max_grad_norm", + "betas", + "fp16", + ] + + with mockenv_context(**self.dist_env_1_gpu): + trainer = get_regression_trainer( + local_rank=0, + fp16=fp16, + deepspeed=ds_config, + per_device_train_batch_size=per_device_train_batch_size, + gradient_accumulation_steps=gradient_accumulation_steps, + max_grad_norm=max_grad_norm, + adam_beta1=adam_beta1, + adam_beta2=adam_beta2, + ) + with self.assertRaises(Exception) as context: + trainer.train() + + for key in keys: + self.assertTrue( + key in str(context.exception), + f"{key} is not in the exception message:\n{context.exception}", + ) + + # Test various combos + # 1. DS scheduler + DS optimizer: this is already tested by most other tests + # 2. HF scheduler + HF optimizer: + # 3. DS scheduler + HF optimizer: + # 4. HF scheduler + DS optimizer: + + def test_hf_scheduler_hf_optimizer(self): + a = 0 + with mockenv_context(**self.dist_env_1_gpu): + ds_config_zero2_dict = self.get_config_dict(ZERO2) + del ds_config_zero2_dict["optimizer"] # force default HF Trainer optimizer + del ds_config_zero2_dict["scheduler"] # force default HF Trainer scheduler + ds_config_zero2_dict["zero_optimization"]["offload_optimizer"]["device"] = "none" + ds_config_zero2_dict["fp16"]["initial_scale_power"] = 1 # force optimizer on the first step + trainer = get_regression_trainer(a=a, local_rank=0, fp16=True, deepspeed=ds_config_zero2_dict) + trainer.train() + new_a = trainer.model.a.item() + self.assertNotEqual(new_a, a) + + def test_ds_scheduler_hf_optimizer(self): + a = 0 + with mockenv_context(**self.dist_env_1_gpu): + ds_config_zero2_dict = self.get_config_dict(ZERO2) + del ds_config_zero2_dict["optimizer"] # force default HF Trainer optimizer + ds_config_zero2_dict["zero_optimization"]["offload_optimizer"]["device"] = "none" + ds_config_zero2_dict["fp16"]["initial_scale_power"] = 1 # force optimizer on the first step + trainer = get_regression_trainer(a=a, local_rank=0, fp16=True, deepspeed=ds_config_zero2_dict) + trainer.train() + new_a = trainer.model.a.item() + self.assertNotEqual(new_a, a) + + def test_hf_scheduler_ds_optimizer(self): + a = 0 + with mockenv_context(**self.dist_env_1_gpu): + ds_config_zero2_dict = self.get_config_dict(ZERO2) + del ds_config_zero2_dict["scheduler"] # force default HF Trainer scheduler + ds_config_zero2_dict["zero_optimization"]["offload_optimizer"]["device"] = "none" + ds_config_zero2_dict["fp16"]["initial_scale_power"] = 1 # force optimizer on the first step + trainer = get_regression_trainer(local_rank=0, fp16=True, deepspeed=ds_config_zero2_dict) + trainer.train() + new_a = trainer.model.a.item() + self.assertNotEqual(new_a, a) + + @require_deepspeed_aio + def test_stage3_nvme_offload(self): + with mockenv_context(**self.dist_env_1_gpu): + # this actually doesn't have to be on NVMe, any storage will do since this test only + # runs a simple check that we can use some directory as if it were NVMe + nvme_path = self.get_auto_remove_tmp_dir() + nvme_config = {"device": "nvme", "nvme_path": nvme_path} + ds_config_zero3_dict = self.get_config_dict(ZERO3) + ds_config_zero3_dict["zero_optimization"]["offload_optimizer"] = nvme_config + ds_config_zero3_dict["zero_optimization"]["offload_param"] = nvme_config + trainer = get_regression_trainer(local_rank=0, fp16=True, deepspeed=ds_config_zero3_dict) + with CaptureLogger(deepspeed_logger) as cl: + trainer.train() + self.assertIn("DeepSpeed info", cl.out, "expected DeepSpeed logger output but got none") + + @require_optuna + def test_hyperparameter_search(self): + with mockenv_context(**self.dist_env_1_gpu): + ds_config_zero3_dict = self.get_config_dict(ZERO3) + + # hyperparameter_search requires model_init() to recreate the model for each trial + def model_init(): + config = RegressionModelConfig(a=0, b=0, double_output=False) + model = RegressionPreTrainedModel(config) + return model + + trainer = get_regression_trainer( + local_rank=0, + fp16=True, + model_init=model_init, + deepspeed=ds_config_zero3_dict, + ) + + n_trials = 3 + with CaptureLogger(deepspeed_logger) as cl: + with CaptureStd() as cs: + trainer.hyperparameter_search(direction="maximize", n_trials=n_trials) + self.assertIn("DeepSpeed info", cl.out, "expected DeepSpeed logger output but got none") + self.assertIn(f"Trial {n_trials-1} finished with value", cs.err, "expected hyperparameter_search output") + self.assertIn("Best is trial", cs.err, "expected hyperparameter_search output") + + # --- These tests need to run on both zero stages --- # + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_hf_optimizer_with_offload(self, stage, dtype): + # non-DS optimizers can be used with ZERO-offload (as long as they have both CPU and GPU implementation (except LAMB)) + ds_config_dict = self.get_config_dict(stage) + del ds_config_dict["optimizer"] # force default HF Trainer optimizer + # force cpu offload + ds_config_dict["zero_optimization"]["offload_optimizer"]["device"] = "cpu" + ds_config_dict["zero_force_ds_cpu_optimizer"] = False # offload is not efficient w/o CPUAdam + with mockenv_context(**self.dist_env_1_gpu): + kwargs = {"local_rank": 0, "deepspeed": ds_config_dict} + kwargs[dtype] = True + trainer = get_regression_trainer(**kwargs) + with CaptureLogger(deepspeed_logger) as cl: + trainer.train() + self.assertIn("DeepSpeed info", cl.out, "expected DeepSpeed logger output but got none") + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_fake_notebook_no_launcher(self, stage, dtype): + # this setup emulates a notebook where a launcher needs to be emulated by hand + + # note that unittest resets sys.stdout each test, so `CaptureStd` will work here to capture + # DeepSpeed log if this test happens to run first in this pytest worker. But it will fail if + # it's run not as a first test as `sys.stdout` will no longer be the same. So we either have + # to reset `deepspeed_logger.handlers[0].setStream(sys.stdout)` or directly capture from the deepspeed_logger. + with mockenv_context(**self.dist_env_1_gpu): + kwargs = {"local_rank": 0, "deepspeed": self.get_config_dict(stage)} + kwargs[dtype] = True + trainer = get_regression_trainer(**kwargs) + + with CaptureLogger(deepspeed_logger) as cl: + trainer.train() + self.assertIn("DeepSpeed info", cl.out, "expected DeepSpeed logger output but got none") + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_early_get_last_lr(self, stage, dtype): + # with deepspeed's fp16 and dynamic loss scale enabled the optimizer/scheduler steps may + # not run for the first few dozen steps while loss scale is too large, and thus during + # that time `get_last_lr` will fail if called during that warm up stage, + # + # setting `logging_steps=1` forces an early `trainer._maybe_log_save_evaluate()` which calls + # `self.lr_scheduler.get_last_lr()` and originally it'd fail on the very first step. + with mockenv_context(**self.dist_env_1_gpu): + a = b = 0.0 + kwargs = { + "a": a, + "b": b, + "local_rank": 0, + "train_len": 8, + "deepspeed": self.get_config_dict(stage), + "per_device_train_batch_size": 8, + "logging_steps": 1, + } + kwargs[dtype] = True + trainer = get_regression_trainer(**kwargs) + + trainer.train() + post_train_a = trainer.model.a.item() + + # XXX: for some reason the following check fails with zero3/fp16 and any/bf16 - not a + # broken but a different qualitative outcome - as if optimizer did run + # oddly getting 1.0 for both a and b from 0.0 - there is a bug somewhere + # print(trainer.model.a.item()) + # print(trainer.model.b.item()) + # need to investigate at some point + if (stage == ZERO3 and dtype == FP16) or (dtype == BF16): + return + + # it's enough that train didn't fail for this test, but we must check that + # optimizer/scheduler didn't run (since if it did this test isn't testing the right thing) + self.assertEqual(post_train_a, a) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_gradient_accumulation(self, stage, dtype): + # this test measures that we get identical weights and similar loss with: + # 1. per_device_train_batch_size=8, gradient_accumulation_steps=1 + # 2. per_device_train_batch_size=4, gradient_accumulation_steps=2 + # since the 2nd should produce the effective batch of 1st, with the same results + # + # I can get an identical loss for a small train_len=32, plus the power of the initial + # dynamic loss scale value set to: + # "fp16.initial_scale_power": 1 + # plus having the same WarmupLR's warmup_min_lr == warmup_max_lr in the config file + # but for some reason going to train_len=64 the weights, weights start to mismatch with this setup. + # the culprit seems to be `initial_scale_power` - putting it back to its default 32 keeps the weights identical + + train_len = 64 + a = b = 0.0 + + kwargs = { + "a": a, + "b": b, + "local_rank": 0, + "train_len": train_len, + "deepspeed": self.get_config_dict(stage), + } + kwargs[dtype] = True + + with mockenv_context(**self.dist_env_1_gpu): + no_grad_accum_trainer = get_regression_trainer( + **kwargs, + per_device_train_batch_size=16, + gradient_accumulation_steps=1, + ) + no_grad_accum_result = no_grad_accum_trainer.train() + no_grad_accum_loss = no_grad_accum_result.training_loss + no_grad_accum_a = no_grad_accum_trainer.model.a.item() + no_grad_accum_b = no_grad_accum_trainer.model.b.item() + # make sure the optimizer kicked in - if it hasn't changed from the original value of a then make train_len bigger + self.assertNotEqual(no_grad_accum_a, a) + + with mockenv_context(**self.dist_env_1_gpu): + yes_grad_accum_trainer = get_regression_trainer( + **kwargs, + per_device_train_batch_size=4, + gradient_accumulation_steps=4, + ) + yes_grad_accum_result = yes_grad_accum_trainer.train() + yes_grad_accum_loss = yes_grad_accum_result.training_loss + yes_grad_accum_a = yes_grad_accum_trainer.model.a.item() + yes_grad_accum_b = yes_grad_accum_trainer.model.b.item() + self.assertNotEqual(yes_grad_accum_a, a) + + # training with half the batch size but accumulation steps as 2 should give the same + # weights, but sometimes get a slight difference still of 1e-6 + self.assertAlmostEqual(no_grad_accum_a, yes_grad_accum_a, places=5) + self.assertAlmostEqual(no_grad_accum_b, yes_grad_accum_b, places=5) + + # see the note above how to get identical loss on a small bs + self.assertAlmostEqual(no_grad_accum_loss, yes_grad_accum_loss, places=2) + + def check_saved_checkpoints_deepspeed(self, output_dir, freq, total, stage, dtype): + # adapted from TrainerIntegrationCommon.check_saved_checkpoints + + file_list = [WEIGHTS_NAME, "training_args.bin", "trainer_state.json", "config.json"] + + if stage == ZERO2: + ds_file_list = ["mp_rank_00_model_states.pt"] + elif stage == ZERO3: + ds_file_list = ["zero_pp_rank_0_mp_rank_00_model_states.pt"] + else: + raise ValueError(f"unknown stage {stage}") + + if dtype == "bf16": + ds_file_list.append("bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt") + + for step in range(freq, total, freq): + checkpoint = os.path.join(output_dir, f"checkpoint-{step}") + self.assertTrue(os.path.isdir(checkpoint), f"[{stage}] {checkpoint} dir is not found") + + # common files + for filename in file_list: + path = os.path.join(checkpoint, filename) + self.assertTrue(os.path.isfile(path), f"[{stage}] {path} is not found") + + # ds files + ds_path = os.path.join(checkpoint, f"global_step{step}") + for filename in ds_file_list: + # filename = os.path.join(path, filename) + # print(filename) + path = os.path.join(ds_path, filename) + self.assertTrue(os.path.isfile(path), f"[{stage}] {path} is not found") + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_save_checkpoints(self, stage, dtype): + # adapted from TrainerIntegrationTest.test_save_checkpoints + + freq = 5 + output_dir = self.get_auto_remove_tmp_dir() + ds_config_dict = self.get_config_dict(stage) + if dtype == FP16: + ds_config_dict["fp16"]["initial_scale_power"] = 1 # force optimizer on the first step + # XXX: + if stage == ZERO3: + ds_config_dict["zero_optimization"]["stage3_gather_16bit_weights_on_model_save"] = True + + # save checkpoints + with mockenv_context(**self.dist_env_1_gpu): + kwargs = { + "output_dir": output_dir, + "save_steps": freq, + "deepspeed": ds_config_dict, + } + kwargs[dtype] = True + trainer = get_regression_trainer(**kwargs) + trainer.train() + + total = int(self.n_epochs * 64 / self.batch_size) + self.check_saved_checkpoints_deepspeed(output_dir, freq, total, stage, dtype) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_can_resume_training_errors(self, stage, dtype): + with mockenv_context(**self.dist_env_1_gpu): + ds_config_dict = self.get_config_dict(stage) + output_dir = self.get_auto_remove_tmp_dir() + kwargs = {"output_dir": output_dir, "deepspeed": ds_config_dict} + kwargs[dtype] = True + trainer = get_regression_trainer(**kwargs) + + # 1. fail to find any checkpoint - due a fresh output_dir + with self.assertRaises(Exception) as context: + trainer.train(resume_from_checkpoint=True) + self.assertTrue( + "No valid checkpoint found in output directory" in str(context.exception), + f"got exception: {context.exception}", + ) + + # 2. fail to find a bogus checkpoint + with self.assertRaises(Exception) as context: + checkpoint = os.path.join(output_dir, "checkpoint-5") + trainer.train(resume_from_checkpoint=f"{checkpoint}-bogus") + self.assertTrue( + "Can't find a valid checkpoint at" in str(context.exception), f"got exception: {context.exception}" + ) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_can_resume_training_normal(self, stage, dtype): + # adapted from TrainerIntegrationTest.test_can_resume_training + # test normal resume for each stage separately, error-handling is tested in a different test + output_dir = self.get_auto_remove_tmp_dir("./xxx", after=False) + ds_config_dict = self.get_config_dict(stage) + if dtype == FP16: + ds_config_dict["fp16"]["initial_scale_power"] = 1 # force optimizer on the first step + # XXX: + if stage == ZERO3: + ds_config_dict["zero_optimization"]["stage3_gather_16bit_weights_on_model_save"] = True + + kwargs = { + "output_dir": output_dir, + "train_len": 128, + "save_steps": 5, + "learning_rate": 0.1, + "deepspeed": ds_config_dict, + } + kwargs[dtype] = True + + with mockenv_context(**self.dist_env_1_gpu): + trainer = get_regression_trainer(**kwargs) + trainer.train() + (a, b) = trainer.model.a.item(), trainer.model.b.item() + state = dataclasses.asdict(trainer.state) + + checkpoint = os.path.join(output_dir, "checkpoint-5") + + # Reinitialize trainer + trainer = get_regression_trainer(**kwargs) + + trainer.train(resume_from_checkpoint=checkpoint) + (a1, b1) = trainer.model.a.item(), trainer.model.b.item() + state1 = dataclasses.asdict(trainer.state) + self.assertEqual(a, a1) + self.assertEqual(b, b1) + self.check_trainer_state_are_the_same(state, state1) + + # Now check with a later checkpoint that it also works when we span over one epoch + checkpoint = os.path.join(output_dir, "checkpoint-15") + + # Reinitialize trainer and load model + trainer = get_regression_trainer(**kwargs) + + trainer.train(resume_from_checkpoint=checkpoint) + (a1, b1) = trainer.model.a.item(), trainer.model.b.item() + state1 = dataclasses.asdict(trainer.state) + self.assertEqual(a, a1) + self.assertEqual(b, b1) + self.check_trainer_state_are_the_same(state, state1) + + # Finally, should be able to resume with the same trainer/same deepspeed engine instance + # XXX: but currently this not possible due DS bug: https://github.com/microsoft/DeepSpeed/issues/1612 + # trainer.train(resume_from_checkpoint=checkpoint) + # a workaround needs to be used that re-creates the deepspeed engine + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_load_state_dict_from_zero_checkpoint(self, stage, dtype): + # test that we can load fp32 weights directly from the zero checkpoint into the current model + + output_dir = self.get_auto_remove_tmp_dir() # "./xxx", after=False, before=False) + + ds_config_dict = self.get_config_dict(stage) + + kwargs = { + "output_dir": output_dir, + "train_len": 4, + "per_device_train_batch_size": 4, + "num_train_epochs": 1, + "save_strategy": "steps", + "save_steps": 1, + "learning_rate": 0.1, + "deepspeed": ds_config_dict, + } + kwargs[dtype] = True + + with mockenv_context(**self.dist_env_1_gpu): + trainer = get_regression_trainer(**kwargs) + trainer.train() + (a, b) = trainer.model.a.item(), trainer.model.b.item() + state = dataclasses.asdict(trainer.state) + + checkpoint_dir = get_last_checkpoint(output_dir) + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + + (a1, b1) = model.a.item(), model.b.item() + state1 = dataclasses.asdict(trainer.state) + self.assertEqual(a, a1) + self.assertEqual(b, b1) + self.check_trainer_state_are_the_same(state, state1) + + def test_config_object(self): + # test that we can switch from zero2 to zero3 in the same process for example + # test is_zero, etc. + output_dir = self.get_auto_remove_tmp_dir() + kwargs = {"output_dir": output_dir, "train_len": 8, "fp16": True} + + ds_config_zero3_dict = self.get_config_dict(ZERO3) + ds_config_zero2_dict = self.get_config_dict(ZERO2) + + with mockenv_context(**self.dist_env_1_gpu): + trainer = get_regression_trainer(deepspeed=ds_config_zero3_dict, **kwargs) + self.assertTrue(is_deepspeed_zero3_enabled()) + + # test we can repeat that and with train this time + trainer = get_regression_trainer(deepspeed=ds_config_zero3_dict, **kwargs) + trainer.train() + self.assertTrue(is_deepspeed_zero3_enabled()) + + # test zero3 is disabled + trainer = get_regression_trainer(deepspeed=ds_config_zero2_dict, **kwargs) + self.assertFalse(is_deepspeed_zero3_enabled()) + + # check config obj + config = deepspeed_config() + self.assertTrue(bool(config), "Deepspeed config should be accessible") + + del trainer + # now weakref should gc the global and we shouldn't get anything here + config = deepspeed_config() + self.assertFalse(is_deepspeed_zero3_enabled()) + self.assertFalse(bool(config), "Deepspeed config should not be accessible") + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_load_best_model(self, stage, dtype): + # Test that forced deepspeed reinit doesn't break the model. the forced re-init after + # loading the best model in Trainer is there to workaround this bug in Deepspeed + # https://github.com/microsoft/DeepSpeed/issues/1612 + # + # The test is derived from a repro script submitted in this Issue: + # https://github.com/huggingface/transformers/issues/17114 + # + # One additional feature of this test is that we use a non-AdamW optimizer to test that + # deepspeed doesn't fallback to AdamW, which would prevent the optimizer states from loading + # correctly + + from transformers import T5ForConditionalGeneration, T5Tokenizer, Trainer # noqa + + output_dir = self.get_auto_remove_tmp_dir() # "./xxx", after=False, before=False) + + ds_config_dict = self.get_config_dict(stage) + del ds_config_dict["optimizer"] # will use HF Trainer optimizer + del ds_config_dict["scheduler"] # will use HF Trainer scheduler + ds_config_dict["zero_force_ds_cpu_optimizer"] = False # offload is not efficient w/o CPUAdam + # must use this setting to get the reload path exercised + ds_config_dict["zero_optimization"]["stage3_gather_16bit_weights_on_model_save"] = True + + with mockenv_context(**self.dist_env_1_gpu): + args_dict = { + "per_gpu_train_batch_size": 1, + "per_gpu_eval_batch_size": 1, + "gradient_accumulation_steps": 1, + "learning_rate": 1e-4, + "num_train_epochs": 1, + "do_train": True, + "do_eval": True, + "optim": "adafactor", + "evaluation_strategy": "steps", + "eval_steps": 1, + "save_strategy": "steps", + "save_steps": 1, + "load_best_model_at_end": True, + "max_steps": 1, + "deepspeed": ds_config_dict, + "report_to": "none", + } + + training_args = TrainingArguments(output_dir, **args_dict) + tokenizer = T5Tokenizer.from_pretrained(T5_TINY) + model = T5ForConditionalGeneration.from_pretrained(T5_TINY) + + def _add_eos_to_examples(example): + example["input_text"] = f"question: {example['question']} context: {example['context']}" + example["target_text"] = example["answers"]["text"][0] if len(example["answers"]["text"]) > 0 else "" + return example + + def _convert_to_features(example_batch): + input_encodings = tokenizer.batch_encode_plus( + example_batch["input_text"], pad_to_max_length=True, max_length=512, truncation=True + ) + target_encodings = tokenizer.batch_encode_plus( + example_batch["target_text"], pad_to_max_length=True, max_length=16, truncation=True + ) + + encodings = { + "input_ids": input_encodings["input_ids"], + "attention_mask": input_encodings["attention_mask"], + "labels": target_encodings["input_ids"], + } + + return encodings + + def get_dataset(): + data_file = str(self.tests_dir / "fixtures/tests_samples/SQUAD/sample.json") + data_files = {"train": data_file, "validation": data_file} + raw_datasets = datasets.load_dataset("json", data_files=data_files, field="data") + train_dataset = raw_datasets["train"].map(_add_eos_to_examples).map(_convert_to_features, batched=True) + valid_dataset = deepcopy(train_dataset) + return train_dataset, valid_dataset + + train_dataset, eval_dataset = get_dataset() + + trainer = Trainer( + model=model, + tokenizer=tokenizer, + args=training_args, + train_dataset=train_dataset, + eval_dataset=eval_dataset, + ) + trainer.train() # crash 1 was here + trainer.evaluate() # crash 2 was here + + +@slow +@require_deepspeed +@require_torch_gpu +class TestDeepSpeedWithLauncher(TestCasePlus): + """This class is for testing via an external script - can do multiple gpus""" + + # Tests to devise # + # + # 1. predict_with_generate on multigpu - need to figure out how to give input sequences so that + # the 2 gpus will generate prediction sequences that aren't of the same length - this is because + # we had to code a special feature to sync the gpus when the predicted sequences aren't of the + # same length. In general this will tested as a side-effect through a variety of other tests - + # it'll simply hang trying to synchronize with other gpus if this problem is encountered. So as + # long as we have a few full tests running on zero3 + predict_with_generate this should be + # mostly covered. + # + # but there are 5 variations on beam search in `generate`- with identical code branched with `if + # synced_gpus` + # + # 2. most tests should probably be run on both: zero2 and zero3 configs + # + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + @require_torch_multi_gpu + def test_basic_distributed(self, stage, dtype): + self.run_and_check(stage=stage, dtype=dtype, distributed=True) + + def test_do_eval_no_train(self): + # testing only zero3 since zero2 makes no sense with inference + self.run_and_check( + stage=ZERO3, + dtype=FP16, + eval_steps=1, + distributed=False, + do_train=False, + do_eval=True, + ) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_fp32_non_distributed(self, stage, dtype): + # real model needs too much GPU memory under stage2+fp32, so using tiny random model here - + # therefore no quality checks, just basic completion checks are done + self.run_and_check( + stage=stage, + dtype=dtype, + model_name=T5_TINY, + distributed=False, + do_train=True, + do_eval=True, + quality_checks=False, + fp32=True, + ) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + @require_torch_multi_gpu + def test_fp32_distributed(self, stage, dtype): + # real model needs too much GPU memory under stage2+fp32, so using tiny random model here - + # therefore no quality checks, just basic completion checks are done + self.run_and_check( + stage=stage, + dtype=dtype, + model_name=T5_TINY, + distributed=True, + do_train=True, + do_eval=True, + quality_checks=False, + fp32=True, + ) + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_resume_train_not_from_ds_checkpoint(self, stage, dtype): + # do normal training and then resume not from the deepspeed checkpoint but explicitly from + # the saved model dir + + do_train = True + do_eval = False + kwargs = { + "stage": stage, + "dtype": dtype, + "eval_steps": 1, + "distributed": True, + "do_train": do_train, + "do_eval": do_eval, + } + + # 1. normal training + output_dir = self.run_and_check(**kwargs) + + # 2. now resume explicitly from the saved weights, by passing --model_name_or_path output_dir + # - i.e. the same path the model was saved to in step 1 + output_dir = self.run_trainer(**kwargs, model_name=output_dir) + + self.do_checks(output_dir, do_train=do_train, do_eval=do_eval) + + @parameterized.expand(["bf16", "fp16", "fp32"]) + @require_torch_multi_gpu + def test_inference(self, dtype): + if dtype == "bf16" and not is_torch_bf16_gpu_available(): + self.skipTest("test requires bfloat16 hardware support") + + # this is just inference, so no optimizer should be loaded + # it only works for z3 (makes no sense with z1-z2) + fp32 = True if dtype == "fp32" else False + self.run_and_check( + stage=ZERO3, + dtype=FP16, + model_name=T5_TINY, + distributed=True, + do_train=False, + do_eval=True, + quality_checks=False, + fp32=fp32, + ) + + def do_checks(self, output_dir, do_train=True, do_eval=True, quality_checks=True): + if do_train: + train_metrics = load_json(os.path.join(output_dir, "train_results.json")) + self.assertIn("train_samples_per_second", train_metrics) + if quality_checks: + self.assertGreater(train_metrics["train_samples_per_second"], 0.5) + + if do_eval: + eval_metrics = load_json(os.path.join(output_dir, "eval_results.json")) + self.assertIn("eval_bleu", eval_metrics) + if quality_checks: + self.assertGreater(eval_metrics["eval_bleu"], 1) + + # XXX: need to do better validation beyond just that the run was successful + def run_and_check( + self, + stage, + dtype, + model_name: str = T5_SMALL, + eval_steps: int = 10, + distributed: bool = True, + do_train: bool = True, + do_eval: bool = True, + quality_checks: bool = True, + fp32: bool = False, + extra_args_str: str = None, + remove_args_str: str = None, + ): + # we are doing quality testing so using a small real model + output_dir = self.run_trainer( + stage=stage, + dtype=dtype, + model_name=model_name, + eval_steps=eval_steps, + num_train_epochs=1, + do_train=do_train, + do_eval=do_eval, + distributed=distributed, + fp32=fp32, + extra_args_str=extra_args_str, + remove_args_str=remove_args_str, + ) + + self.do_checks(output_dir, do_train=do_train, do_eval=do_eval, quality_checks=quality_checks) + + return output_dir + + def run_trainer( + self, + stage: str, + dtype: str, + model_name: str, + eval_steps: int = 10, + num_train_epochs: int = 1, + do_train: bool = False, + do_eval: bool = True, + distributed: bool = True, + fp32: bool = False, + extra_args_str: str = None, + remove_args_str: str = None, + ): + max_len = 32 + data_dir = self.test_file_dir / "../fixtures/tests_samples/wmt_en_ro" + output_dir = self.get_auto_remove_tmp_dir() + args = f""" + --model_name_or_path {model_name} + --train_file {data_dir}/train.json + --validation_file {data_dir}/val.json + --output_dir {output_dir} + --overwrite_output_dir + --max_source_length {max_len} + --max_target_length {max_len} + --val_max_target_length {max_len} + --warmup_steps 8 + --predict_with_generate + --save_steps 0 + --eval_steps {eval_steps} + --group_by_length + --label_smoothing_factor 0.1 + --source_lang en + --target_lang ro + --report_to none + """.split() + args.extend(["--source_prefix", '"translate English to Romanian: "']) + + if not fp32: + args.extend([f"--{dtype}"]) + + actions = 0 + if do_train: + actions += 1 + args.extend( + f""" + --do_train + --num_train_epochs {str(num_train_epochs)} + --max_train_samples 16 + --per_device_train_batch_size 2 + --learning_rate 3e-3 + """.split() + ) + + if do_eval: + actions += 1 + args.extend( + """ + --do_eval + --max_eval_samples 16 + --per_device_eval_batch_size 2 + """.split() + ) + + assert actions > 0, "need at least do_train or do_eval for the test to run" + + if extra_args_str is not None: + args.extend(extra_args_str.split()) + + # currently only works for bool args + if remove_args_str is not None: + remove_args = remove_args_str.split() + args = [x for x in args if x not in remove_args] + + ds_args = f"--deepspeed {self.test_file_dir_str}/ds_config_{stage}.json".split() + script = [f"{self.examples_dir_str}/pytorch/translation/run_translation.py"] + launcher = get_launcher(distributed) + + cmd = launcher + script + args + ds_args + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die + execute_subprocess_async(cmd, env=self.get_env()) + + return output_dir + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_clm(self, stage, dtype): + # this test exercises model.resize_token_embeddings() which requires param gathering outside + # of forward - it's not used by `run_translation.py`, but it is in `run_clm.py` + + data_dir = self.tests_dir / "fixtures" + output_dir = self.get_auto_remove_tmp_dir() + args = f""" + --model_name_or_path {GPT2_TINY} + --train_file {data_dir}/sample_text.txt + --validation_file {data_dir}/sample_text.txt + --output_dir {output_dir} + --overwrite_output_dir + --do_train + --do_eval + --max_train_samples 16 + --max_eval_samples 16 + --per_device_train_batch_size 2 + --per_device_eval_batch_size 2 + --num_train_epochs 1 + --warmup_steps 8 + --block_size 64 + --report_to none + """.split() + + args.extend([f"--{dtype}"]) + + ds_args = f"--deepspeed {self.test_file_dir_str}/ds_config_{stage}.json".split() + script = [f"{self.examples_dir_str}/pytorch/language-modeling/run_clm.py"] + launcher = get_launcher(distributed=True) + + cmd = launcher + script + args + ds_args + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die + execute_subprocess_async(cmd, env=self.get_env()) + + def test_clm_from_config_zero3_fp16(self): + # this test exercises AutoModel.from_config(config) - to ensure zero.Init is called + + data_dir = self.tests_dir / "fixtures" + output_dir = self.get_auto_remove_tmp_dir() + args = f""" + --model_type gpt2 + --tokenizer_name {GPT2_TINY} + --train_file {data_dir}/sample_text.txt + --validation_file {data_dir}/sample_text.txt + --output_dir {output_dir} + --overwrite_output_dir + --do_train + --max_train_samples 4 + --per_device_train_batch_size 2 + --num_train_epochs 1 + --warmup_steps 8 + --block_size 8 + --fp16 + --report_to none + """.split() + + ds_args = f"--deepspeed {self.test_file_dir_str}/ds_config_zero3.json".split() + script = [f"{self.examples_dir_str}/pytorch/language-modeling/run_clm.py"] + launcher = get_launcher(distributed=True) + + cmd = launcher + script + args + ds_args + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die + with CaptureStderr() as cs: + execute_subprocess_async(cmd, env=self.get_env()) + self.assertIn("Detected DeepSpeed ZeRO-3", cs.err) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_model_zoo.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_model_zoo.py new file mode 100644 index 0000000000000000000000000000000000000000..e51fe1e7cfcca26c556d6b4e7e3231d091c160f2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/test_model_zoo.py @@ -0,0 +1,367 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import itertools +import os +import subprocess +from os.path import dirname + +from parameterized import parameterized + +from tests.trainer.test_trainer import TrainerIntegrationCommon # noqa +from transformers import is_torch_available +from transformers.testing_utils import ( + TestCasePlus, + execute_subprocess_async, + get_gpu_count, + get_tests_dir, + require_deepspeed, + require_torch_gpu, + slow, +) +from transformers.trainer_utils import set_seed + + +if is_torch_available(): + from tests.trainer.test_trainer import ( # noqa + RegressionModelConfig, + RegressionPreTrainedModel, + get_regression_trainer, + ) + + +set_seed(42) + +FIXTURE_DIRECTORY = get_tests_dir("fixtures") +ROOT_DIRECTORY = os.path.join(dirname(get_tests_dir())) +DS_TESTS_DIRECTORY = dirname(os.path.abspath(__file__)) + +# default torch.distributed port +DEFAULT_MASTER_PORT = "10999" + +T5_SMALL = "t5-small" + +# *** Working Models *** +ALBERT_TINY = "hf-internal-testing/tiny-albert" +BART_TINY = "sshleifer/bart-tiny-random" +BERT_TINY = "hf-internal-testing/tiny-bert" +BIGBIRD_PEGASUS_TINY = "hf-internal-testing/tiny-random-bigbird_pegasus" +BIG_BIRD_TINY = "hf-internal-testing/tiny-random-big_bird" +BLENDERBOT_TINY = "hf-internal-testing/tiny-random-blenderbot" +BLOOM_TINY = "bigscience/bigscience-small-testing" +DEBERTA_TINY = "hf-internal-testing/tiny-random-deberta" +DEBERTA_V2_TINY = "hf-internal-testing/tiny-random-deberta-v2" +DISTILBERT_TINY = "sshleifer/tiny-distilbert-base-cased" +ELECTRA_TINY = "hf-internal-testing/tiny-electra" +FLAUBERT_TINY = "hf-internal-testing/tiny-random-flaubert" +FSMT_TINY = "stas/tiny-wmt19-en-de" +FUNNEL_TINY = "hf-internal-testing/tiny-random-funnel" +GPT2_TINY = "sshleifer/tiny-gpt2" +GPTJ_TINY = "hf-internal-testing/tiny-random-gptj" +GPT_NEO_TINY = "hf-internal-testing/tiny-random-gpt_neo" +LAYOUTLM_TINY = "hf-internal-testing/tiny-layoutlm" +LED_TINY = "hf-internal-testing/tiny-random-led" +LONGFORMER_TINY = "hf-internal-testing/tiny-random-longformer" +M2M_100_TINY = "stas/tiny-m2m_100" # hf tiny model is unsuitable +MARIAN_TINY = "sshleifer/tiny-marian-en-de" +MBART_TINY = "sshleifer/tiny-mbart" +MOBILEBERT_TINY = "hf-internal-testing/tiny-random-mobilebert" +MPNET_TINY = "hf-internal-testing/tiny-random-mpnet" +PEGASUS_TINY = "stas/pegasus-cnn_dailymail-tiny-random" +PROPHETNET_TINY = "hf-internal-testing/tiny-random-prophetnet" +ROBERTA_TINY = "sshleifer/tiny-distilroberta-base" +SQUEEZEBERT_TINY = "hf-internal-testing/tiny-random-squeezebert" +T5_TINY = "patrickvonplaten/t5-tiny-random" +T5_V1_TINY = "hf-internal-testing/tiny-random-t5-v1.1" +VIT_TINY = "hf-internal-testing/tiny-random-vit" +XLM_ROBERTA_TINY = "hf-internal-testing/tiny-xlm-roberta" +XLNET_TINY = "sshleifer/tiny-xlnet-base-cased" + + +# *** To Fix *** + + +# *** tiny model issues *** +# missing model files: +MT5_TINY = "hf-internal-testing/tiny-random-mt5" +CAMEMBERT_TINY = "hf-internal-testing/tiny-random-camembert" +OPENAI_GPT_TINY = "hf-internal-testing/tiny-random-openai-gpt" + +# missing tokenizer files +CONVBERT_TINY = "hf-internal-testing/tiny-random-convbert" +LAYOUTLMV2_TINY = "hf-internal-testing/tiny-random-layoutlmv2" +HUBERT_TINY = "hf-internal-testing/tiny-random-hubert" + +# issues with tokenizer +CTRL_TINY = "hf-internal-testing/tiny-random-ctrl" +TRANSFO_XL_TINY = "hf-internal-testing/tiny-random-transfo-xl" # same as ctrl + +# other issues with tiny models +IBERT_TINY = "hf-internal-testing/tiny-random-ibert" # multiple issues with either mlm/qa/clas +REFORMER_TINY = "hf-internal-testing/tiny-random-reformer" # multiple issues with either mlm/qa/clas + +# *** Lacking official examples to test with *** +# or not working with examples +DPR_TINY = "hf-internal-testing/tiny-random-dpr" +# - "dpr" examples/research_projects/rag-end2end-retriever/ +RAG_TINY = "hf-internal-testing/tiny-random-rag" +# - "rag" research_projects +LUKE_TINY = "" +# - "luke" Entities classes - no plan to make such example +LXMERT_TINY = "hf-internal-testing/tiny-random-lxmert" +# - "lxmert" doesn't work with run_qa.py +CLIP_TINY = "hf-internal-testing/tiny-random-clip" +# - "clip" nothing under pytorch examples - XXX: Suraj is working on adding some - check by end of Sep +SPEECH_TO_TEXT_TINY = "hf-internal-testing/tiny-random-speech_to_text" +# - "speech_to_text", nothing under pytorch examples + + +# *** Reactive mode *** +# models with low usage, unstable API, things about to change - do nothing about the following until someone runs into a problem +TAPAS_TINY = "hf-internal-testing/tiny-random-tapas" +# additional notes on tapas +# 1. "Table must be of type pd.DataFrame" failure + + +# TODO: new models to add: +# + + +def get_launcher(distributed=False): + # 1. explicitly set --num_nodes=1 just in case these tests end up run on a multi-node setup + # - it won't be able to handle that + # 2. for now testing with just 2 gpus max (since some quality tests may give different + # results with mode gpus because we use very little data) + num_gpus = min(2, get_gpu_count()) if distributed else 1 + master_port = os.environ.get("DS_TEST_PORT", DEFAULT_MASTER_PORT) + return f"deepspeed --num_nodes 1 --num_gpus {num_gpus} --master_port {master_port}".split() + + +def make_task_cmds(): + data_dir_samples = f"{FIXTURE_DIRECTORY}/tests_samples" + data_dir_wmt = f"{data_dir_samples}/wmt_en_ro" + data_dir_xsum = f"{data_dir_samples}/xsum" + args_main = """ + --do_train + --max_train_samples 4 + --per_device_train_batch_size 2 + --num_train_epochs 1 + --fp16 + --report_to none + --overwrite_output_dir + """.split() + + # try to cover as many models as possible once (it's enough to run on one task per model) + # but need a tiny model for each + # + # should have "{model_type.upper()}_TINY" corresponding vars defined, e.g., T5_TINY, etc. + tasks2models = { + "trans": [ + "bart", + "fsmt", + "m2m_100", + "marian", + "mbart", + "t5", + "t5_v1", + # "mt5", missing model files + ], + "sum": [ + "pegasus", + ], + "clm": [ + "big_bird", + "bigbird_pegasus", + "blenderbot", + "bloom", + "gpt2", + "gpt_neo", + "gptj", + "xlm-roberta", + "prophetnet", + # "camembert", missing model files + ], + "mlm": [ + "albert", + "deberta", + "deberta-v2", + "distilbert", + "electra", + "flaubert", + "funnel", + "layoutlm", + # "reformer", # multiple issues with either mlm/qa/clas + ], + "qa": [ + "led", + "longformer", + "mobilebert", + "mpnet", + "roberta", + "squeezebert", + # "convbert", # missing tokenizer files + # "layoutlmv2", missing model files + ], + "clas": [ + "bert", + "xlnet", + # "hubert", # missing tokenizer files + # "ibert", # multiple issues with either mlm/qa/clas + # "transfo-xl", # tokenizer issues as ctrl + # "ctrl", # tokenizer issues + # "openai-gpt", missing model files + # "tapas", multiple issues + ], + "img_clas": [ + "vit", + ], + } + + scripts_dir = f"{ROOT_DIRECTORY}/examples/pytorch" + + tasks = { + "trans": f""" + {scripts_dir}/translation/run_translation.py + --train_file {data_dir_wmt}/train.json + --source_lang en + --target_lang ro + """, + "sum": f""" + {scripts_dir}/summarization/run_summarization.py + --train_file {data_dir_xsum}/sample.json + --max_source_length 12 + --max_target_length 12 + --lang en + """, + "clm": f""" + {scripts_dir}/language-modeling/run_clm.py + --train_file {FIXTURE_DIRECTORY}/sample_text.txt + --block_size 8 + """, + "mlm": f""" + {scripts_dir}/language-modeling/run_mlm.py + --train_file {FIXTURE_DIRECTORY}/sample_text.txt + """, + "qa": f""" + {scripts_dir}/question-answering/run_qa.py + --train_file {data_dir_samples}/SQUAD/sample.json + """, + "clas": f""" + {scripts_dir}/text-classification/run_glue.py + --train_file {data_dir_samples}/MRPC/train.csv + --max_seq_length 12 + --task_name MRPC + """, + "img_clas": f""" + {scripts_dir}/image-classification/run_image_classification.py + --dataset_name hf-internal-testing/cats_vs_dogs_sample + --remove_unused_columns False + --max_steps 10 + --image_processor_name {DS_TESTS_DIRECTORY}/vit_feature_extractor.json + """, + } + + launcher = get_launcher(distributed=True) + + cmds = {} + for task, args in tasks.items(): + args = args.split() + for model in tasks2models[task]: + model_name = globals()[f"{model.upper().replace('-', '_')}_TINY"] + args_model = f"--model_name_or_path {model_name}".split() + cmds[f"{task}_{model}"] = launcher + args + args_model + args_main + + # # generation special case + # if task == "gen": + # launcher = f"deepspeed --num_nodes 1 --num_gpus 1".split() + # args_model += f"--model_type {model}".split() + # cmds[f"{task}_{model}"] = launcher + args + args_model + # else: + + return cmds + + +task_cmds = make_task_cmds() + +ZERO2 = "zero2" +ZERO3 = "zero3" + +stages = [ZERO2, ZERO3] + +# future preparation: +# for now test just fp16, as these tests are quite slow +# FP16 = "fp16" +# BF16 = "bf16" +# +# dtypes = [FP16] +# so just hardcoding --fp16 for now +# if is_torch_bf16_gpu_available(): +# dtypes += [BF16] + + +def parameterized_custom_name_func(func, param_num, param): + # customize the test name generator function as we want both params to appear in the sub-test + # name, as by default it shows only the first param + param_based_name = parameterized.to_safe_name("_".join(str(x) for x in param.args)) + return f"{func.__name__}_{param_based_name}" + + +# Cartesian-product of zero stages with models to test +params = list(itertools.product(stages, task_cmds.keys())) + + +@slow +@require_deepspeed +@require_torch_gpu +class TestDeepSpeedModelZoo(TestCasePlus): + """This class is for testing via an external script - can do multiple gpus""" + + def get_task_cmd(self, task, stage): + # return a ready to run train cmd + if task not in task_cmds: + raise ValueError(f"don't know of task {task}, have {task_cmds.keys()}") + + cmd = task_cmds[task] + args_ds = f"--deepspeed {self.test_file_dir_str}/ds_config_{stage}.json".split() + + output_dir = self.get_auto_remove_tmp_dir() + args_out = f"--output_dir {output_dir}".split() + + cmd += args_ds + args_out + + return cmd, output_dir + + @parameterized.expand(params, name_func=parameterized_custom_name_func) + def test_zero_to_fp32(self, stage, task): + # testing the ability to do a run followed by recovery of full fp32 weights + + cmd, output_dir = self.get_task_cmd(task, stage) + + # 1. generate the checkpoint + cmd += "--save_steps 1".split() + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] + cmd)); die + execute_subprocess_async(cmd, env=self.get_env()) + + # 2. test that the fp32 weights get reconsolidated + chkpt_dir = f"{output_dir}/checkpoint-1" + recovered_model_path = f"{chkpt_dir}/out.bin" + cmd = f"{chkpt_dir}/zero_to_fp32.py {chkpt_dir} {recovered_model_path}" + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die + subprocess.check_call(cmd, shell=True) + assert os.path.exists(recovered_model_path), f"{recovered_model_path} was not found" + + # possibly could also test that the resulting saved model is usable but given that we use + # random models we won't know if it's any good diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/vit_feature_extractor.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/vit_feature_extractor.json new file mode 100644 index 0000000000000000000000000000000000000000..bfe5a331249fa823a8189a1486209a19bfe870fc --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/deepspeed/vit_feature_extractor.json @@ -0,0 +1,4 @@ +{ + "feature_extractor_type": "ViTFeatureExtractor", + "size": 30 +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/extended/test_trainer_ext.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/extended/test_trainer_ext.py new file mode 100644 index 0000000000000000000000000000000000000000..7fd2fc9389ab251a1fcf48efb64d65a3a1abc9b2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/extended/test_trainer_ext.py @@ -0,0 +1,383 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import math +import os +import re +import sys +import unittest +from pathlib import Path +from typing import Tuple +from unittest.mock import patch + +from parameterized import parameterized + +from transformers.testing_utils import ( + CaptureStderr, + ExtendSysPath, + TestCasePlus, + execute_subprocess_async, + get_gpu_count, + get_torch_dist_unique_port, + require_apex, + require_bitsandbytes, + require_fairscale, + require_torch, + require_torch_gpu, + require_torch_multi_gpu, + require_torch_non_multi_gpu, + slow, +) +from transformers.trainer_callback import TrainerState +from transformers.trainer_utils import set_seed + + +bindir = os.path.abspath(os.path.dirname(__file__)) +with ExtendSysPath(f"{bindir}/../../examples/pytorch/translation"): + from run_translation import main # noqa + + +set_seed(42) +MARIAN_MODEL = "sshleifer/student_marian_en_ro_6_1" +MBART_TINY = "sshleifer/tiny-mbart" + + +@require_torch +class TestTrainerExt(TestCasePlus): + def run_seq2seq_quick( + self, + distributed=False, + extra_args_str=None, + predict_with_generate=True, + do_train=True, + do_eval=True, + do_predict=True, + ): + output_dir = self.run_trainer( + eval_steps=1, + max_len=12, + model_name=MBART_TINY, + num_train_epochs=1, + distributed=distributed, + extra_args_str=extra_args_str, + predict_with_generate=predict_with_generate, + do_train=do_train, + do_eval=do_eval, + do_predict=do_predict, + ) + logs = TrainerState.load_from_json(os.path.join(output_dir, "trainer_state.json")).log_history + + if not do_eval: + return + + eval_metrics = [log for log in logs if "eval_loss" in log.keys()] + + first_step_stats = eval_metrics[0] + if predict_with_generate: + assert "eval_bleu" in first_step_stats + + last_step_stats = eval_metrics[-1] + assert isinstance(last_step_stats["eval_bleu"], float) + assert not math.isnan(float(last_step_stats["eval_loss"])), "eval_loss must not be `nan`" + + @require_torch_non_multi_gpu + def test_run_seq2seq_no_dist(self): + self.run_seq2seq_quick() + + # verify that the trainer can handle non-distributed with n_gpu > 1 + @require_torch_multi_gpu + def test_run_seq2seq_dp(self): + self.run_seq2seq_quick(distributed=False) + + # verify that the trainer can handle distributed with n_gpu > 1 + @require_torch_multi_gpu + def test_run_seq2seq_ddp(self): + self.run_seq2seq_quick(distributed=True) + + # test --sharded_ddp w/o --fp16 + @unittest.skip("Requires an update of the env running those tests") + @require_torch_multi_gpu + @require_fairscale + def test_run_seq2seq_sharded_ddp(self): + self.run_seq2seq_quick(distributed=True, extra_args_str="--sharded_ddp simple") + + # test --sharded_ddp w/ --fp16 + @unittest.skip("Requires an update of the env running those tests") + @require_torch_multi_gpu + @require_fairscale + def test_run_seq2seq_sharded_ddp_fp16(self): + self.run_seq2seq_quick(distributed=True, extra_args_str="--sharded_ddp simple --fp16") + + # test --sharded_ddp zero_dp_2 w/o --fp16 + @unittest.skip("Requires an update of the env running those tests") + @require_torch_multi_gpu + @require_fairscale + def test_run_seq2seq_fully_sharded_ddp(self): + self.run_seq2seq_quick(distributed=True, extra_args_str="--sharded_ddp zero_dp_2", predict_with_generate=False) + + # test --sharded_ddp zero_dp_2 w/ --fp16 + @unittest.skip("Requires an update of the env running those tests") + @require_torch_multi_gpu + @require_fairscale + def test_run_seq2seq_fully_sharded_ddp_fp16(self): + self.run_seq2seq_quick( + distributed=True, extra_args_str="--sharded_ddp zero_dp_2 --fp16", predict_with_generate=False + ) + + @require_apex + @require_torch_gpu + def test_run_seq2seq_apex(self): + # XXX: apex breaks the trainer if it's run twice e.g. run_seq2seq.main() from the same + # program and it breaks other tests that run from the same pytest worker, therefore until this is + # sorted out it must be run only in an external program, that is distributed=True in this + # test and only under one or more gpus - if we want cpu will need to make a special test + # + # specifically to the problem traced it to self.optimizer.step() - if it's run 2nd time via + # 2nd main() call it botches the future eval. + # + self.run_seq2seq_quick(distributed=True, extra_args_str="--fp16 --fp16_backend=apex") + # test 2nd time - was getting eval_loss': nan' + # to reproduce the problem set distributed=False + self.run_seq2seq_quick(distributed=True, extra_args_str="--fp16 --fp16_backend=apex") + + @parameterized.expand(["base", "low", "high", "mixed"]) + @require_torch_multi_gpu + def test_trainer_log_level_replica(self, experiment_id): + # as each sub-test is slow-ish split into multiple sub-tests to avoid CI timeout + experiments = { + # test with the default log_level - should be info and thus log info once + "base": {"extra_args_str": "", "n_matches": 1}, + # test with low log_level and log_level_replica - should be noisy on all processes + # now the info string should appear twice on 2 processes + "low": {"extra_args_str": "--log_level debug --log_level_replica debug", "n_matches": 2}, + # test with high log_level and low log_level_replica + # now the info string should appear once only on the replica + "high": {"extra_args_str": "--log_level error --log_level_replica debug", "n_matches": 1}, + # test with high log_level and log_level_replica - should be quiet on all processes + "mixed": {"extra_args_str": "--log_level error --log_level_replica error", "n_matches": 0}, + } + + data = experiments[experiment_id] + kwargs = {"distributed": True, "predict_with_generate": False, "do_eval": False, "do_predict": False} + log_info_string = "Running training" + with CaptureStderr() as cl: + self.run_seq2seq_quick(**kwargs, extra_args_str=data["extra_args_str"]) + n_matches = len(re.findall(log_info_string, cl.err)) + self.assertEqual(n_matches, data["n_matches"]) + + @slow + def test_run_seq2seq(self): + output_dir = self.run_trainer( + eval_steps=2, + max_len=128, + model_name=MARIAN_MODEL, + learning_rate=3e-4, + num_train_epochs=10, + distributed=False, + ) + + # Check metrics + logs = TrainerState.load_from_json(os.path.join(output_dir, "trainer_state.json")).log_history + eval_metrics = [log for log in logs if "eval_loss" in log.keys()] + first_step_stats = eval_metrics[0] + last_step_stats = eval_metrics[-1] + + assert first_step_stats["eval_loss"] > last_step_stats["eval_loss"], "model learned nothing" + assert isinstance(last_step_stats["eval_bleu"], float) + + # test if do_predict saves generations and metrics + contents = os.listdir(output_dir) + contents = {os.path.basename(p) for p in contents} + assert "generated_predictions.txt" in contents + assert "predict_results.json" in contents + + @slow + @require_bitsandbytes + def test_run_seq2seq_bnb(self): + from transformers.training_args import OptimizerNames + + def train_and_return_metrics(optim: str) -> Tuple[int, float]: + extra_args = "--skip_memory_metrics 0" + + output_dir = self.run_trainer( + max_len=128, + model_name=MARIAN_MODEL, + learning_rate=3e-4, + num_train_epochs=1, + optim=optim, + distributed=True, # force run in a new process + extra_args_str=extra_args, + do_eval=False, + do_predict=False, + n_gpus_to_use=1, # to allow deterministic fixed memory usage + ) + + # Check metrics + logs = TrainerState.load_from_json(Path(output_dir, "trainer_state.json")).log_history + gpu_peak_mem_mb = int(logs[0]["train_mem_gpu_peaked_delta"] / 2**20) + gpu_alloc_mem_mb = int(logs[0]["train_mem_gpu_alloc_delta"] / 2**20) + + loss = logs[0]["train_loss"] + return gpu_peak_mem_mb, gpu_alloc_mem_mb, loss + + gpu_peak_mem_orig, gpu_alloc_mem_orig, loss_orig = train_and_return_metrics(OptimizerNames.ADAMW_TORCH.value) + gpu_peak_mem_bnb, gpu_alloc_mem_bnb, loss_bnb = train_and_return_metrics(OptimizerNames.ADAMW_BNB.value) + + gpu_alloc_mem_diff = gpu_alloc_mem_orig - gpu_alloc_mem_bnb + + gpu_total_mem_orig = gpu_peak_mem_orig + gpu_alloc_mem_orig + gpu_total_mem_bnb = gpu_peak_mem_bnb + gpu_alloc_mem_bnb + gpu_total_mem_diff = gpu_total_mem_orig - gpu_total_mem_bnb + + # sshleifer/student_marian_en_ro_6_1 has 54M parameter, 29M of which is `nn.Embedding` which + # doesn't get quantized and remains in fp32. Therefore we only have 25M parameters quantized + # in 2 bytes and the diff in optim memory usage is derived as so: + # + # - normal 25*8=~200MB (8 bytes per param) + # - bnb 25*2= ~50MB (2 bytes per param) + # + # Thus we should expect ~150MB total memory saved. + # + # Peak memory should be the same - the total should be different by about that same margin + # + # After leaving a small margin to accommodate for differences between gpus let's check + # that we have at least 120MB in savings + expected_savings = 120 + + # uncomment the following if this test starts failing - requires py38 for a new print feature + # gpu_peak_mem_diff = gpu_peak_mem_orig - gpu_peak_mem_bnb + # print(f"{gpu_alloc_mem_orig=}MB {gpu_peak_mem_orig=}MB {gpu_alloc_mem_orig+gpu_peak_mem_orig=}MB") + # print(f" {gpu_alloc_mem_bnb=}MB {gpu_peak_mem_bnb=}MB {gpu_alloc_mem_bnb+gpu_peak_mem_bnb=}MB") + # print(f"{gpu_alloc_mem_diff=}MB") + # print(f"{gpu_peak_mem_diff=}MB") + # print(f"{gpu_total_mem_orig=}MB, {gpu_total_mem_bnb=}MB") + # print(f"{gpu_total_mem_diff=}MB, {gpu_total_mem_diff=}MB") + + self.assertGreater( + gpu_alloc_mem_diff, + expected_savings, + "should use ~150MB less alloc gpu memory with BNB, compared to without it for this model but got" + f" a difference of {gpu_alloc_mem_diff}MB, with gpu_alloc_mem_orig={gpu_alloc_mem_orig}MB and" + f" gpu_alloc_mem_bnb={gpu_alloc_mem_bnb}MB", + ) + + self.assertGreater( + gpu_total_mem_diff, + expected_savings, + "should use ~150MB less total gpu memory with BNB, compared to without it for this model but got" + f" a difference of {gpu_total_mem_diff}MB, with gpu_total_mem_orig={gpu_total_mem_orig}MB and" + f" gpu_total_mem_bnb={gpu_total_mem_bnb}MB", + ) + + self.assertEqual( + loss_orig, loss_bnb, f"loss should be the same, but got loss_orig={loss_orig}, loss_bnb={loss_bnb}" + ) + + def run_trainer( + self, + max_len: int, + model_name: str, + num_train_epochs: int, + learning_rate: float = 3e-3, + optim: str = "adafactor", + distributed: bool = False, + extra_args_str: str = None, + eval_steps: int = 0, + predict_with_generate: bool = True, + do_train: bool = True, + do_eval: bool = True, + do_predict: bool = True, + n_gpus_to_use: int = None, + ): + data_dir = self.test_file_dir / "../fixtures/tests_samples/wmt_en_ro" + output_dir = self.get_auto_remove_tmp_dir() + args_train = f""" + --model_name_or_path {model_name} + --train_file {data_dir}/train.json + --validation_file {data_dir}/val.json + --test_file {data_dir}/test.json + --output_dir {output_dir} + --overwrite_output_dir + --max_train_samples 8 + --max_source_length {max_len} + --max_target_length {max_len} + --do_train + --num_train_epochs {str(num_train_epochs)} + --per_device_train_batch_size 4 + --learning_rate {learning_rate} + --warmup_steps 8 + --logging_steps 0 + --logging_strategy no + --save_steps {str(eval_steps)} + --group_by_length + --label_smoothing_factor 0.1 + --target_lang ro_RO + --source_lang en_XX + """.split() + + args_eval = f""" + --do_eval + --per_device_eval_batch_size 4 + --max_eval_samples 8 + --val_max_target_length {max_len} + --evaluation_strategy steps + --eval_steps {str(eval_steps)} + """.split() + + args_predict = """ + --do_predict + """.split() + + args = [] + if do_train: + args += args_train + + if do_eval: + args += args_eval + + if do_predict: + args += args_predict + + if predict_with_generate: + args += "--predict_with_generate".split() + + if do_train: + if optim == "adafactor": + args += "--adafactor".split() + else: + args += f"--optim {optim}".split() + + if extra_args_str is not None: + args += extra_args_str.split() + + if distributed: + if n_gpus_to_use is None: + n_gpus_to_use = get_gpu_count() + master_port = get_torch_dist_unique_port() + distributed_args = f""" + -m torch.distributed.run + --nproc_per_node={n_gpus_to_use} + --master_port={master_port} + {self.examples_dir_str}/pytorch/translation/run_translation.py + """.split() + cmd = [sys.executable] + distributed_args + args + # keep for quick debug + # print(" ".join([f"\nPYTHONPATH={self.src_dir_str}"] +cmd)); die + execute_subprocess_async(cmd, env=self.get_env()) + else: + testargs = ["run_translation.py"] + args + with patch.object(sys, "argv", testargs): + main() + + return output_dir diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/add_distilbert_like_config.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/add_distilbert_like_config.json new file mode 100644 index 0000000000000000000000000000000000000000..812d2a635ddeeb4cc1da8ed7317a9739a6e9f160 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/add_distilbert_like_config.json @@ -0,0 +1,19 @@ +{ + "add_copied_from": true, + "old_model_type": "distilbert", + "new_model_patterns": { + "model_name": "BERT New", + "checkpoint": "huggingface/bert-new-base", + "model_type": "bert-new", + "model_lower_cased": "bert_new", + "model_camel_cased": "BertNew", + "model_upper_cased": "BERT_NEW", + "config_class": "BertNewConfig", + "tokenizer_class": "DistilBertTokenizer" + }, + "frameworks": [ + "pt", + "tf", + "flax" + ] +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy-config.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy-config.json new file mode 100644 index 0000000000000000000000000000000000000000..e388bdf71151db7c014ae6e0174dd07c1a6acbee --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy-config.json @@ -0,0 +1,3 @@ +{ + "model_type": "roberta" +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy_feature_extractor_config.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy_feature_extractor_config.json new file mode 100644 index 0000000000000000000000000000000000000000..674ef8a0b200d57b1ac38da7b4acecfa288a7ac8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/dummy_feature_extractor_config.json @@ -0,0 +1,4 @@ +{ + "feature_extractor_type": "Wav2Vec2FeatureExtractor", + "processor_class": "Wav2Vec2Processor" +} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/empty.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/empty.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/input.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/input.txt new file mode 100644 index 0000000000000000000000000000000000000000..d1e3f410d07833e4c5c233ffd54f8d2b54ebb7cf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/input.txt @@ -0,0 +1 @@ +Who was Jim Henson ? ||| Jim Henson was a puppeteer diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/merges.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/merges.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7c5738baaf4304ef4692f6fe8ad887b9517d047 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/merges.txt @@ -0,0 +1,5 @@ +#version: 0.2 +Ġ l +Ġl o +Ġlo w +e r diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/preprocessor_config.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/preprocessor_config.json new file mode 100644 index 0000000000000000000000000000000000000000..29cd5bc5f3b4dd6794c63dcc60dc86d1a7821ef6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/preprocessor_config.json @@ -0,0 +1,4 @@ +{ + "feature_extractor_type": "Wav2Vec2FeatureExtractor", + "processor_class": "Wav2Vec2Processor" +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text.txt new file mode 100644 index 0000000000000000000000000000000000000000..a42812060c576bae870eb29b1ac083fda0d239d3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text.txt @@ -0,0 +1,33 @@ +This text is included to make sure Unicode is handled properly: 力加勝北区ᴵᴺᵀᵃছজটডণত +Text should be one-sentence-per-line, with empty lines between documents. +This sample text is public domain and was randomly selected from Project Guttenberg. + +The rain had only ceased with the gray streaks of morning at Blazing Star, and the settlement awoke to a moral sense of cleanliness, and the finding of forgotten knives, tin cups, and smaller camp utensils, where the heavy showers had washed away the debris and dust heaps before the cabin doors. +Indeed, it was recorded in Blazing Star that a fortunate early riser had once picked up on the highway a solid chunk of gold quartz which the rain had freed from its incumbering soil, and washed into immediate and glittering popularity. +Possibly this may have been the reason why early risers in that locality, during the rainy season, adopted a thoughtful habit of body, and seldom lifted their eyes to the rifted or india-ink washed skies above them. +"Cass" Beard had risen early that morning, but not with a view to discovery. +A leak in his cabin roof,--quite consistent with his careless, improvident habits,--had roused him at 4 A. M., with a flooded "bunk" and wet blankets. +The chips from his wood pile refused to kindle a fire to dry his bed-clothes, and he had recourse to a more provident neighbor's to supply the deficiency. +This was nearly opposite. +Mr. Cassius crossed the highway, and stopped suddenly. +Something glittered in the nearest red pool before him. +Gold, surely! +But, wonderful to relate, not an irregular, shapeless fragment of crude ore, fresh from Nature's crucible, but a bit of jeweler's handicraft in the form of a plain gold ring. +Looking at it more attentively, he saw that it bore the inscription, "May to Cass." +Like most of his fellow gold-seekers, Cass was superstitious. + +The fountain of classic wisdom, Hypatia herself. +As the ancient sage--the name is unimportant to a monk--pumped water nightly that he might study by day, so I, the guardian of cloaks and parasols, at the sacred doors of her lecture-room, imbibe celestial knowledge. +From my youth I felt in me a soul above the matter-entangled herd. +She revealed to me the glorious fact, that I am a spark of Divinity itself. +A fallen star, I am, sir!' continued he, pensively, stroking his lean stomach--'a fallen star!--fallen, if the dignity of philosophy will allow of the simile, among the hogs of the lower world--indeed, even into the hog-bucket itself. Well, after all, I will show you the way to the Archbishop's. +There is a philosophic pleasure in opening one's treasures to the modest young. +Perhaps you will assist me by carrying this basket of fruit?' And the little man jumped up, put his basket on Philammon's head, and trotted off up a neighbouring street. +Philammon followed, half contemptuous, half wondering at what this philosophy might be, which could feed the self-conceit of anything so abject as his ragged little apish guide; +but the novel roar and whirl of the street, the perpetual stream of busy faces, the line of curricles, palanquins, laden asses, camels, elephants, which met and passed him, and squeezed him up steps and into doorways, as they threaded their way through the great Moon-gate into the ample street beyond, drove everything from his mind but wondering curiosity, and a vague, helpless dread of that great living wilderness, more terrible than any dead wilderness of sand which he had left behind. +Already he longed for the repose, the silence of the Laura--for faces which knew him and smiled upon him; but it was too late to turn back now. +His guide held on for more than a mile up the great main street, crossed in the centre of the city, at right angles, by one equally magnificent, at each end of which, miles away, appeared, dim and distant over the heads of the living stream of passengers, the yellow sand-hills of the desert; +while at the end of the vista in front of them gleamed the blue harbour, through a network of countless masts. +At last they reached the quay at the opposite end of the street; +and there burst on Philammon's astonished eyes a vast semicircle of blue sea, ringed with palaces and towers. +He stopped involuntarily; and his little guide stopped also, and looked askance at the young monk, to watch the effect which that grand panorama should produce on him. diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text_no_unicode.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text_no_unicode.txt new file mode 100644 index 0000000000000000000000000000000000000000..74646661c7c121a31af30def84a4d724a4b2d41f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/sample_text_no_unicode.txt @@ -0,0 +1,32 @@ +Text should be one-sentence-per-line, with empty lines between documents. +This sample text is public domain and was randomly selected from Project Guttenberg. + +The rain had only ceased with the gray streaks of morning at Blazing Star, and the settlement awoke to a moral sense of cleanliness, and the finding of forgotten knives, tin cups, and smaller camp utensils, where the heavy showers had washed away the debris and dust heaps before the cabin doors. +Indeed, it was recorded in Blazing Star that a fortunate early riser had once picked up on the highway a solid chunk of gold quartz which the rain had freed from its incumbering soil, and washed into immediate and glittering popularity. +Possibly this may have been the reason why early risers in that locality, during the rainy season, adopted a thoughtful habit of body, and seldom lifted their eyes to the rifted or india-ink washed skies above them. +"Cass" Beard had risen early that morning, but not with a view to discovery. +A leak in his cabin roof,--quite consistent with his careless, improvident habits,--had roused him at 4 A. M., with a flooded "bunk" and wet blankets. +The chips from his wood pile refused to kindle a fire to dry his bed-clothes, and he had recourse to a more provident neighbor's to supply the deficiency. +This was nearly opposite. +Mr. Cassius crossed the highway, and stopped suddenly. +Something glittered in the nearest red pool before him. +Gold, surely! +But, wonderful to relate, not an irregular, shapeless fragment of crude ore, fresh from Nature's crucible, but a bit of jeweler's handicraft in the form of a plain gold ring. +Looking at it more attentively, he saw that it bore the inscription, "May to Cass." +Like most of his fellow gold-seekers, Cass was superstitious. + +The fountain of classic wisdom, Hypatia herself. +As the ancient sage--the name is unimportant to a monk--pumped water nightly that he might study by day, so I, the guardian of cloaks and parasols, at the sacred doors of her lecture-room, imbibe celestial knowledge. +From my youth I felt in me a soul above the matter-entangled herd. +She revealed to me the glorious fact, that I am a spark of Divinity itself. +A fallen star, I am, sir!' continued he, pensively, stroking his lean stomach--'a fallen star!--fallen, if the dignity of philosophy will allow of the simile, among the hogs of the lower world--indeed, even into the hog-bucket itself. Well, after all, I will show you the way to the Archbishop's. +There is a philosophic pleasure in opening one's treasures to the modest young. +Perhaps you will assist me by carrying this basket of fruit?' And the little man jumped up, put his basket on Philammon's head, and trotted off up a neighbouring street. +Philammon followed, half contemptuous, half wondering at what this philosophy might be, which could feed the self-conceit of anything so abject as his ragged little apish guide; +but the novel roar and whirl of the street, the perpetual stream of busy faces, the line of curricles, palanquins, laden asses, camels, elephants, which met and passed him, and squeezed him up steps and into doorways, as they threaded their way through the great Moon-gate into the ample street beyond, drove everything from his mind but wondering curiosity, and a vague, helpless dread of that great living wilderness, more terrible than any dead wilderness of sand which he had left behind. +Already he longed for the repose, the silence of the Laura--for faces which knew him and smiled upon him; but it was too late to turn back now. +His guide held on for more than a mile up the great main street, crossed in the centre of the city, at right angles, by one equally magnificent, at each end of which, miles away, appeared, dim and distant over the heads of the living stream of passengers, the yellow sand-hills of the desert; +while at the end of the vista in front of them gleamed the blue harbour, through a network of countless masts. +At last they reached the quay at the opposite end of the street; +and there burst on Philammon's astonished eyes a vast semicircle of blue sea, ringed with palaces and towers. +He stopped involuntarily; and his little guide stopped also, and looked askance at the young monk, to watch the effect which that grand panorama should produce on him. diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/test_entity_vocab.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/test_entity_vocab.json new file mode 100644 index 0000000000000000000000000000000000000000..d5a63935979e7b0b0ae181e0c36b9b9e715315ac --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/test_entity_vocab.json @@ -0,0 +1 @@ +{"[MASK]": 0, "[UNK]": 1, "[PAD]": 2, "DUMMY": 3, "DUMMY2": 4, "[MASK2]": 5} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/.gitignore b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1d7141c43dcf8f422e18fe3c13eb8f9e0bb9a964 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/.gitignore @@ -0,0 +1,6 @@ +cache* +temp* +!*.txt +!*.tsv +!*.json +!.gitignore \ No newline at end of file diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/000000039769.png b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/000000039769.png new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_annotations.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_annotations.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_panoptic/000000039769.png b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_panoptic/000000039769.png new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/dev.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/dev.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/labels.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/labels.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/train.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/GermEval/train.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/dev.csv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/dev.csv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/dev.tsv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/dev.tsv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/train.csv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/train.csv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/train.tsv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/MRPC/train.tsv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/SQUAD/sample.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/SQUAD/sample.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/STS-B/dev.tsv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/STS-B/dev.tsv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/STS-B/train.tsv b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/STS-B/train.tsv new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/conll/sample.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/conll/sample.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/swag/sample.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/swag/sample.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wiki_text/wiki_00 b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wiki_text/wiki_00 new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt16/sample.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt16/sample.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/test.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/test.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/train.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/train.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/val.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/wmt_en_ro/val.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/xsum/sample.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/tests_samples/xsum/sample.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.json b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.json new file mode 100644 index 0000000000000000000000000000000000000000..c5d99b8ae9d4d6d94d91af3e7e2515f61c8ce7d9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.json @@ -0,0 +1 @@ +{"l": 0, "o": 1, "w": 2, "e": 3, "r": 4, "s": 5, "t": 6, "i": 7, "d": 8, "n": 9, "Ġ": 10, "Ġl": 11, "Ġn": 12, "Ġlo": 13, "Ġlow": 14, "er": 15, "Ġlowest": 16, "Ġnewer": 17, "Ġwider": 18, "": 19, "<|endoftext|>": 20} diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.txt b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad9f94bc6876d33f79e8dd7bbc19c2dab700f1df --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/fixtures/vocab.txt @@ -0,0 +1,10 @@ +[PAD] +[SEP] +[MASK] +[CLS] +[unused3] +[unused4] +[unused5] +[unused6] +[unused7] +[unused8] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_constraints.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_constraints.py new file mode 100644 index 0000000000000000000000000000000000000000..ae8a0c41eb950cb331ce3875219a26c562963df7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_constraints.py @@ -0,0 +1,115 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import is_torch_available +from transformers.testing_utils import require_torch + + +if is_torch_available(): + import torch + + from transformers.generation import DisjunctiveConstraint + + +@require_torch +class ConstraintTest(unittest.TestCase): + def test_input_types(self): + # For consistency across different places the DisjunctiveConstraint is called, + # dc.token_ids is a list of integers. It is also initialized only by integers. + + cset = [[1, 2, 4], [1, 2, 3, 4]] + dc = DisjunctiveConstraint(cset) + self.assertTrue(isinstance(dc.token_ids, list)) + + with self.assertRaises(ValueError): + DisjunctiveConstraint(torch.LongTensor([[1, 2, 4], [1, 2, 3]])) + + with self.assertRaises(ValueError): + DisjunctiveConstraint([torch.LongTensor([1, 2, 4]), torch.LongTensor([1, 2, 3, 4, 5])]) + + def test_check_illegal_input(self): + # We can't have constraints that are complete subsets of another. This leads to a preverse + # interpretation of "constraint fulfillment": does generating [1,2,3] fulfill the constraint? + # It would mean that it generated [1,2] which fulfills it, but it's in the middle of potentially + # fulfilling [1,2,3,4]. If we believe that [1,2,3] does fulfill the constraint, then the algorithm + # will necessarily never reach [1,2,3,4], giving users a false sense of control (better to just not allow it). + cset = [[1, 2], [1, 2, 3, 4]] + + with self.assertRaises(ValueError): + DisjunctiveConstraint(cset) # fails here + + def test_example_progression(self): + cset = [[1, 2, 3], [1, 2, 4]] + + dc = DisjunctiveConstraint(cset) + + stepped, completed, reset = dc.update(1) + desired = stepped is True and completed is False and reset is False + self.assertTrue(desired) + self.assertTrue(not dc.completed) + self.assertTrue(dc.current_seq == [1]) + + stepped, completed, reset = dc.update(2) + desired = stepped is True and completed is False and reset is False + self.assertTrue(desired) + self.assertTrue(not dc.completed) + self.assertTrue(dc.current_seq == [1, 2]) + + stepped, completed, reset = dc.update(3) + desired = stepped is True and completed is True and reset is False + self.assertTrue(desired) + self.assertTrue(dc.completed) # Completed! + self.assertTrue(dc.current_seq == [1, 2, 3]) + + def test_example_progression_unequal_three_mid_and_reset(self): + cset = [[1, 2, 3], [1, 2, 4, 5], [1, 2, 5]] + + dc = DisjunctiveConstraint(cset) + + stepped, completed, reset = dc.update(1) + self.assertTrue(not dc.completed) + self.assertTrue(dc.current_seq == [1]) + + stepped, completed, reset = dc.update(2) + self.assertTrue(not dc.completed) + self.assertTrue(dc.current_seq == [1, 2]) + + stepped, completed, reset = dc.update(4) + self.assertTrue(not dc.completed) + self.assertTrue(dc.current_seq == [1, 2, 4]) + + stepped, completed, reset = dc.update(5) + self.assertTrue(dc.completed) # Completed! + self.assertTrue(dc.current_seq == [1, 2, 4, 5]) + + dc.reset() + + stepped, completed, reset = dc.update(1) + self.assertTrue(not dc.completed) + self.assertTrue(dc.remaining() == 3) + self.assertTrue(dc.current_seq == [1]) + + stepped, completed, reset = dc.update(2) + self.assertTrue(not dc.completed) + self.assertTrue(dc.remaining() == 2) + self.assertTrue(dc.current_seq == [1, 2]) + + stepped, completed, reset = dc.update(5) + self.assertTrue(dc.completed) # Completed! + self.assertTrue(dc.remaining() == 0) + self.assertTrue(dc.current_seq == [1, 2, 5]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_search.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_search.py new file mode 100644 index 0000000000000000000000000000000000000000..47d3b4b38a7b5a22e3edf28847607e0d4f44e8bf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_beam_search.py @@ -0,0 +1,577 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import is_torch_available +from transformers.testing_utils import require_torch, torch_device + +from ..test_modeling_common import floats_tensor, ids_tensor + + +if is_torch_available(): + import torch + + from transformers.generation import ( + BeamHypotheses, + BeamSearchScorer, + ConstrainedBeamSearchScorer, + DisjunctiveConstraint, + PhrasalConstraint, + ) + + +class BeamSearchTester: + def __init__( + self, + parent, + batch_size=3, + sequence_length=10, + vocab_size=99, + pad_token_id=0, + max_length=20, + num_beams=4, + length_penalty=2.0, + do_early_stopping=True, + num_beam_hyps_to_keep=2, + ): + self.parent = parent + self.batch_size = batch_size + self.sequence_length = sequence_length + self.vocab_size = vocab_size + self.pad_token_id = pad_token_id + self.max_length = max_length + self.num_beams = num_beams + self.length_penalty = length_penalty + self.do_early_stopping = do_early_stopping + self.num_beam_hyps_to_keep = num_beam_hyps_to_keep + + # cannot be randomly generated + self.eos_token_id = vocab_size + 1 + + def prepare_beam_scorer(self, **kwargs): + return BeamSearchScorer( + batch_size=kwargs.get("batch_size", self.batch_size), + num_beams=kwargs.get("num_beams", self.num_beams), + device=torch_device, + length_penalty=kwargs.get("length_penalty", self.length_penalty), + do_early_stopping=kwargs.get("do_early_stopping", self.do_early_stopping), + num_beam_hyps_to_keep=kwargs.get("num_beam_hyps_to_keep", self.num_beam_hyps_to_keep), + ) + + def prepare_inputs(self): + input_ids = ids_tensor((self.batch_size * self.num_beams, self.sequence_length), self.vocab_size) + next_tokens = ids_tensor((self.batch_size, 2 * self.num_beams), self.vocab_size).to(torch_device) + next_indices = ids_tensor((self.batch_size, 2 * self.num_beams), self.num_beams).to(torch_device) + next_scores, _ = (-floats_tensor((self.batch_size, 2 * self.num_beams)).to(torch_device)).sort(descending=True) + return (input_ids, next_tokens, next_indices, next_scores) + + def check_beam_hypotheses(self, input_ids, *args): + # check that correct number of beam hypotheses is set in beam scorer + beam_scorer = self.prepare_beam_scorer(do_early_stopping=True) + beam_hyp = beam_scorer._beam_hyps[0] + + self.parent.assertEqual(len(beam_scorer._beam_hyps), self.batch_size) + + # check correct type + self.parent.assertTrue(isinstance(beam_hyp, BeamHypotheses)) + + # check that num_beams is correctly set + self.parent.assertEqual(beam_hyp.num_beams, self.num_beams) + + # check for early stopping deactivated + for beam_idx in range(self.num_beams): + beam_hyp.add(input_ids[beam_idx], -10.0) + + # if early stopping True -> score does not matter + self.parent.assertTrue(beam_hyp.is_done(-10.0, 5)) + + # re-init + beam_scorer = self.prepare_beam_scorer(do_early_stopping=False) + beam_hyp = beam_scorer._beam_hyps[0] + + # add `num_beams + 1` beams to change `worst_score` + for beam_idx in range(self.num_beams + 1): + beam_hyp.add(input_ids[beam_idx], -10.0 + float(beam_idx)) + + # -10.0 is removed => -9.0 is worst score + self.parent.assertAlmostEqual(beam_hyp.worst_score, -9.0 / (self.sequence_length**beam_hyp.length_penalty)) + + # -5.0 is better than worst score => should not be finished + self.parent.assertFalse(beam_hyp.is_done(-5.0, self.sequence_length)) + + # -20.0 is worse than worst score => should be finished + self.parent.assertTrue(beam_hyp.is_done(-20.0, self.sequence_length)) + + def check_beam_scorer_update(self, input_ids, next_tokens, next_indices, next_scores): + # check too many eos tokens + beam_scorer = self.prepare_beam_scorer() + + tokens = next_tokens.clone() + tokens[0, :] = self.eos_token_id + + with self.parent.assertRaises(ValueError): + beam_scorer.process(input_ids, next_scores, tokens, next_indices, eos_token_id=self.eos_token_id) + + # check all batches are done + beam_scorer = self.prepare_beam_scorer() + + tokens = next_tokens.clone() + tokens[:, : self.num_beams] = self.eos_token_id + beam_indices = torch.zeros_like(input_ids) + torch.arange(input_ids.shape[-1], device=input_ids.device) + beam_indices = tuple(tuple(b) for b in beam_indices) + beam_scorer.process( + input_ids, next_scores, tokens, next_indices, eos_token_id=self.eos_token_id, beam_indices=beam_indices + ) + # beam scorer should be done + self.parent.assertTrue(beam_scorer.is_done) + + # check + beam_scorer = self.prepare_beam_scorer() + + tokens = next_tokens.clone() + tokens[:, 1] = self.eos_token_id + beam_outputs = beam_scorer.process( + input_ids, next_scores, tokens, next_indices, eos_token_id=self.eos_token_id, beam_indices=beam_indices + ) + output_scores = beam_outputs["next_beam_scores"] + output_tokens = beam_outputs["next_beam_tokens"] + output_indices = beam_outputs["next_beam_indices"] + + def cut_expected_tensor(tensor): + return torch.cat([tensor[:, :1], tensor[:, 2 : self.num_beams + 1]], dim=1).flatten() + + # check all outptus + # cut out id of eos token and take best `num_beams` outputs + expected_output_tokens = cut_expected_tensor(tokens) + expected_output_scores = cut_expected_tensor(next_scores) + + # add num_beams * batch_idx + offset = torch.div( + torch.arange(self.num_beams * self.batch_size, device=torch_device), self.num_beams, rounding_mode="floor" + ) + expected_output_indices = cut_expected_tensor(next_indices) + offset * self.num_beams + + self.parent.assertListEqual(expected_output_tokens.tolist(), output_tokens.tolist()) + self.parent.assertListEqual(expected_output_indices.tolist(), output_indices.tolist()) + self.parent.assertTrue(torch.allclose(expected_output_scores, output_scores, atol=1e-3)) + + # make sure ids of eos token are correctly saved in beam_hyps of beam scorer + expected_beam_indices = list(range(10)) + for batch_idx in range(self.batch_size): + correct_idx = batch_idx * self.num_beams + next_indices[batch_idx, 1] + self.parent.assertListEqual( + input_ids[correct_idx].tolist(), beam_scorer._beam_hyps[batch_idx].beams[0][1].tolist() + ) + self.parent.assertListEqual( + expected_beam_indices + [correct_idx], + torch.tensor(beam_scorer._beam_hyps[batch_idx].beams[0][2]).tolist(), + ) + + def check_beam_scores_finalize(self, input_ids, next_tokens, next_indices, next_scores): + # max_length should be only one more than current input_ids to check that eos is correctly appended + max_length = self.sequence_length + 1 + beam_scorer = self.prepare_beam_scorer(num_beam_hyps_to_keep=1, length_penalty=1.0, do_early_stopping=False) + + # update beams and append to input_ids + tokens = next_tokens.clone() + # first batch, first output has to finish with eos token id since scores are correctly sorted + tokens[0, 0] = self.eos_token_id + # make sure corresponding score is as good as possible to surely be picked first + next_scores[0, 0] = 0.0 + beam_outputs = beam_scorer.process( + input_ids, next_scores, tokens, next_indices, eos_token_id=self.eos_token_id + ) + output_scores = beam_outputs["next_beam_scores"] + output_tokens = beam_outputs["next_beam_tokens"] + output_indices = beam_outputs["next_beam_indices"] + + input_ids = torch.cat([input_ids[output_indices, :], output_tokens.unsqueeze(-1)], dim=-1) + + # finalize + beam_indices = torch.zeros_like(input_ids) + torch.arange(input_ids.shape[-1], device=input_ids.device) + beam_indices = tuple(tuple(b) for b in beam_indices) + sequence_output = beam_scorer.finalize( + input_ids, + output_scores, + output_tokens, + output_indices, + pad_token_id=self.pad_token_id, + eos_token_id=self.eos_token_id, + max_length=max_length, + beam_indices=beam_indices, + ) + + sequences = sequence_output["sequences"] + sequence_scores = sequence_output["sequence_scores"] + + # since `num_beam_hyps_to_keep` = 1 => only return `batch_size` x `max_length` + self.parent.assertListEqual(list(sequences.shape), [self.batch_size, max_length]) + self.parent.assertListEqual(list(sequence_scores.shape), [self.batch_size]) + + # check sequence_scores + self.parent.assertFalse((sequence_scores > 0).any().item()) + + # first batch has to finish with eos_token + self.parent.assertEqual(sequences[0, -1].item(), self.eos_token_id) + + # other batches cannot finish with eos token + self.parent.assertNotEqual(sequences[1, -1].item(), self.eos_token_id) + self.parent.assertNotEqual(sequences[2, -1].item(), self.eos_token_id) + + # now test that if `num_beam_hyps_to_keep` is 3 => all beams are returned + beam_scorer.num_beam_hyps_to_keep = self.num_beams + sequence_output = beam_scorer.finalize( + input_ids, + output_scores, + output_tokens, + output_indices, + pad_token_id=self.pad_token_id, + eos_token_id=self.eos_token_id, + max_length=max_length, + beam_indices=beam_indices, + ) + sequences = sequence_output["sequences"] + sequence_scores = sequence_output["sequence_scores"] + + self.parent.assertListEqual(list(sequences.shape), [self.num_beams * self.batch_size, max_length]) + self.parent.assertListEqual(list(sequence_scores.shape), [self.num_beams * self.batch_size]) + + +class ConstrainedBeamSearchTester: + def __init__( + self, + parent, + constraints=None, + batch_size=3, + sequence_length=10, + vocab_size=99, + pad_token_id=0, + max_length=20, + num_beams=4, + length_penalty=2.0, + do_early_stopping=True, + num_beam_hyps_to_keep=2, + ): + self.parent = parent + self.batch_size = batch_size + self.sequence_length = sequence_length + self.vocab_size = vocab_size + self.pad_token_id = pad_token_id + self.max_length = max_length + self.num_beams = num_beams + self.length_penalty = length_penalty + self.do_early_stopping = do_early_stopping + self.num_beam_hyps_to_keep = num_beam_hyps_to_keep + + if constraints is None: + force_tokens = torch.randint(10, 50, (1, 2))[0].tolist() + disjunctive_tokens = torch.randint(10, 50, (2, 2)).tolist() + + constraints = [PhrasalConstraint(force_tokens), DisjunctiveConstraint(disjunctive_tokens)] + self.constraints = constraints + # cannot be randomly generated + self.eos_token_id = vocab_size + 1 + + def prepare_constrained_beam_scorer(self, **kwargs): + return ConstrainedBeamSearchScorer( + constraints=kwargs.get("constraints", self.constraints), + batch_size=kwargs.get("batch_size", self.batch_size), + num_beams=kwargs.get("num_beams", self.num_beams), + device=torch_device, + length_penalty=kwargs.get("length_penalty", self.length_penalty), + do_early_stopping=kwargs.get("do_early_stopping", self.do_early_stopping), + num_beam_hyps_to_keep=kwargs.get("num_beam_hyps_to_keep", self.num_beam_hyps_to_keep), + ) + + def prepare_inputs(self): + input_ids = ids_tensor((self.batch_size * self.num_beams, self.sequence_length), self.vocab_size) + next_tokens = ids_tensor((self.batch_size, 2 * self.num_beams), self.vocab_size).to(torch_device) + next_indices = ids_tensor((self.batch_size, 2 * self.num_beams), self.num_beams).to(torch_device) + next_scores, _ = (-floats_tensor((self.batch_size, 2 * self.num_beams)).to(torch_device)).sort(descending=True) + scores_for_all_vocab, _ = ( + -floats_tensor((self.batch_size * self.num_beams, self.vocab_size)).to(torch_device) + ).sort(descending=True) + return (input_ids, next_tokens, next_indices, next_scores, scores_for_all_vocab) + + def check_beam_hypotheses(self, input_ids, *args): + # check that correct number of beam hypotheses is set in beam scorer + constrained_beam_scorer = self.prepare_constrained_beam_scorer(do_early_stopping=True) + beam_hyp = constrained_beam_scorer._beam_hyps[0] + + self.parent.assertEqual(len(constrained_beam_scorer._beam_hyps), self.batch_size) + + # check correct type + self.parent.assertTrue(isinstance(beam_hyp, BeamHypotheses)) + + # check that num_beams is correctly set + self.parent.assertEqual(beam_hyp.num_beams, self.num_beams) + + # check for early stopping deactivated + for beam_idx in range(self.num_beams): + beam_hyp.add(input_ids[beam_idx], -10.0) + + # if early stopping True -> score does not matter + self.parent.assertTrue(beam_hyp.is_done(-10.0, 5)) + + # re-init + constrained_beam_scorer = self.prepare_constrained_beam_scorer(do_early_stopping=False) + beam_hyp = constrained_beam_scorer._beam_hyps[0] + + # add `num_beams + 1` beams to change `worst_score` + for beam_idx in range(self.num_beams + 1): + beam_hyp.add(input_ids[beam_idx], -10.0 + float(beam_idx)) + + # -10.0 is removed => -9.0 is worst score + self.parent.assertAlmostEqual(beam_hyp.worst_score, -9.0 / (self.sequence_length**beam_hyp.length_penalty)) + + # -5.0 is better than worst score => should not be finished + self.parent.assertFalse(beam_hyp.is_done(-5.0, self.sequence_length)) + + # -20.0 is worse than worst score => should be finished + self.parent.assertTrue(beam_hyp.is_done(-20.0, self.sequence_length)) + + def check_constrained_beam_scorer_update( + self, input_ids, next_tokens, next_indices, next_scores, scores_for_all_vocab + ): + # check too many eos tokens + constrained_beam_scorer = self.prepare_constrained_beam_scorer() + stacked_token_ids = [] + for constraint in self.constraints: + token_ids = constraint.token_ids + token_ids = token_ids[0] if isinstance(token_ids[0], list) else token_ids + stacked_token_ids = stacked_token_ids + token_ids + + fulfilling_sequence = torch.LongTensor(stacked_token_ids) + fulfill_len = fulfilling_sequence.size(0) + input_ids[:, :fulfill_len] = fulfilling_sequence + + tokens = next_tokens.clone() + tokens[0, :] = self.eos_token_id + + with self.parent.assertRaises(ValueError): + constrained_beam_scorer.process( + input_ids, next_scores, tokens, next_indices, scores_for_all_vocab, eos_token_id=self.eos_token_id + ) + + # check all batches are done + constrained_beam_scorer = self.prepare_constrained_beam_scorer() + + tokens = next_tokens.clone() + tokens[:, : self.num_beams] = self.eos_token_id + constrained_beam_scorer.process( + input_ids, next_scores, tokens, next_indices, scores_for_all_vocab, eos_token_id=self.eos_token_id + ) + # beam scorer should be done + self.parent.assertTrue(constrained_beam_scorer.is_done) + + # check + constrained_beam_scorer = self.prepare_constrained_beam_scorer() + + tokens = next_tokens.clone() + tokens[:, 1] = self.eos_token_id + beam_outputs = constrained_beam_scorer.process( + input_ids, next_scores, tokens, next_indices, scores_for_all_vocab, eos_token_id=self.eos_token_id + ) + output_scores = beam_outputs["next_beam_scores"] + output_tokens = beam_outputs["next_beam_tokens"] + output_indices = beam_outputs["next_beam_indices"] + + def cut_expected_tensor(tensor): + return torch.cat([tensor[:, :1], tensor[:, 2 : self.num_beams + 1]], dim=1).flatten() + + # check all outptus + # cut out id of eos token and take best `num_beams` outputs + expected_output_tokens = cut_expected_tensor(tokens) + expected_output_scores = cut_expected_tensor(next_scores) + + # add num_beams * batch_idx + offset = torch.div( + torch.arange(self.num_beams * self.batch_size, device=torch_device), self.num_beams, rounding_mode="floor" + ) + expected_output_indices = cut_expected_tensor(next_indices) + offset * self.num_beams + + self.parent.assertListEqual(expected_output_tokens.tolist(), output_tokens.tolist()) + self.parent.assertListEqual(expected_output_indices.tolist(), output_indices.tolist()) + self.parent.assertTrue(torch.allclose(expected_output_scores, output_scores, atol=1e-3)) + + # make sure ids of eos token are correctly saved in beam_hyps of beam scorer + for batch_idx in range(self.batch_size): + correct_idx = batch_idx * self.num_beams + next_indices[batch_idx, 1] + self.parent.assertListEqual( + input_ids[correct_idx].tolist(), constrained_beam_scorer._beam_hyps[batch_idx].beams[0][1].tolist() + ) + + def check_constrained_beam_scorer_finalize( + self, input_ids, next_tokens, next_indices, next_scores, scores_for_all_vocab + ): + # max_length should be only one more than current input_ids to check that eos is correctly appended + max_length = self.sequence_length + 1 + + # for testing finalize, we do want to have fulfilled constraints + stacked_token_ids = [] + for constraint in self.constraints: + token_ids = constraint.token_ids + token_ids = token_ids[0] if isinstance(token_ids[0], list) else token_ids + stacked_token_ids = stacked_token_ids + token_ids + + fulfilling_sequence = torch.LongTensor(stacked_token_ids) + + fulfill_len = fulfilling_sequence.size(0) + input_ids[:, :fulfill_len] = fulfilling_sequence + + constrained_beam_scorer = self.prepare_constrained_beam_scorer( + num_beam_hyps_to_keep=1, length_penalty=1.0, do_early_stopping=False + ) + + constraints = constrained_beam_scorer.constraints + # update beams and append to input_ids + tokens = next_tokens.clone() + # first batch, first output has to finish with eos token id since scores are correctly sorted + tokens[0, 0] = self.eos_token_id + # make sure corresponding score is as good as possible to surely be picked first + next_scores[0, 0] = 0.0 + + beam_outputs = constrained_beam_scorer.process( + input_ids, next_scores, tokens, next_indices, scores_for_all_vocab, eos_token_id=self.eos_token_id + ) + output_scores = beam_outputs["next_beam_scores"] + output_tokens = beam_outputs["next_beam_tokens"] + output_indices = beam_outputs["next_beam_indices"] + input_ids = torch.cat([input_ids[output_indices, :], output_tokens.unsqueeze(-1)], dim=-1) + + # finalize + sequence_output = constrained_beam_scorer.finalize( + input_ids, + output_scores, + output_tokens, + output_indices, + pad_token_id=self.pad_token_id, + eos_token_id=self.eos_token_id, + max_length=max_length, + ) + + sequences = sequence_output["sequences"] + sequence_scores = sequence_output["sequence_scores"] + + # since `num_beam_hyps_to_keep` = 1 => only return `batch_size` x `max_length` + self.parent.assertListEqual(list(sequences.shape), [self.batch_size, max_length]) + self.parent.assertListEqual(list(sequence_scores.shape), [self.batch_size]) + + # check sequence_scores + self.parent.assertFalse((sequence_scores > 0).any().item()) + + # first batch has to finish with eos_token + self.parent.assertEqual(sequences[0, -1].item(), self.eos_token_id) + + # other batches cannot finish with eos token + self.parent.assertNotEqual(sequences[1, -1].item(), self.eos_token_id) + self.parent.assertNotEqual(sequences[2, -1].item(), self.eos_token_id) + + # test that the constraint is indeed fulfilled + for output, constraint in [(s, c) for s in sequences for c in constraints]: + forced_token_ids = constraint.token_ids + if isinstance(forced_token_ids[0], list): + # disjunctive case + flag = False + for token_ids in forced_token_ids: + if self._check_sequence_inside_sequence(output, token_ids): + flag = True + break + self.parent.assertEqual(flag, True) + else: + self.parent.assertEqual(self._check_sequence_inside_sequence(output, forced_token_ids), True) + + # now test that if `num_beam_hyps_to_keep` is 3 => all beams are returned + + # constrained_beam_scorer.num_beam_hyps_to_keep = self.num_beams + constrained_beam_scorer = self.prepare_constrained_beam_scorer( + num_beam_hyps_to_keep=self.num_beams, length_penalty=1.0, do_early_stopping=False + ) + + sequence_output = constrained_beam_scorer.finalize( + input_ids, + output_scores, + output_tokens, + output_indices, + pad_token_id=self.pad_token_id, + eos_token_id=self.eos_token_id, + max_length=max_length, + ) + sequences = sequence_output["sequences"] + sequence_scores = sequence_output["sequence_scores"] + + self.parent.assertListEqual(list(sequences.shape), [self.num_beams * self.batch_size, max_length]) + self.parent.assertListEqual(list(sequence_scores.shape), [self.num_beams * self.batch_size]) + + def _check_sequence_inside_sequence(self, tensor_1, tensor_2): + # check if tensor_1 inside tensor_2 or tensor_2 inside tensor_1. + # set to same device. we don't care what device. + + if not isinstance(tensor_1, list): + tensor_1 = tensor_1.cpu().tolist() + if not isinstance(tensor_2, list): + tensor_2 = tensor_2.cpu().tolist() + + in_order = len(tensor_1) <= len(tensor_2) + longer = tensor_2 if in_order else tensor_1 + shorter = tensor_1 if in_order else tensor_2 + + flag = False + chunk_size = len(shorter) + for chunk_idx in range(len(longer) - chunk_size + 1): + subseq = longer[chunk_idx : chunk_idx + chunk_size] + if subseq == shorter: + flag = True + break + + return flag + + +@require_torch +class BeamSearchTest(unittest.TestCase): + def setUp(self): + self.beam_search_tester = BeamSearchTester(self) + + def test_beam_hypotheses(self): + inputs = self.beam_search_tester.prepare_inputs() + self.beam_search_tester.check_beam_hypotheses(*inputs) + + def test_beam_scorer_update(self): + inputs = self.beam_search_tester.prepare_inputs() + self.beam_search_tester.check_beam_scorer_update(*inputs) + + def test_beam_scorer_finalize(self): + inputs = self.beam_search_tester.prepare_inputs() + self.beam_search_tester.check_beam_scores_finalize(*inputs) + + +@require_torch +class ConstrainedBeamSearchTest(unittest.TestCase): + def setUp(self): + self.constrained_beam_search_tester = ConstrainedBeamSearchTester(self) + + def test_constrained_beam_hypotheses(self): + inputs = self.constrained_beam_search_tester.prepare_inputs() + self.constrained_beam_search_tester.check_beam_hypotheses(*inputs) + + def test_constrained_beam_scorer_update(self): + inputs = self.constrained_beam_search_tester.prepare_inputs() + self.constrained_beam_search_tester.check_constrained_beam_scorer_update(*inputs) + + def test_constrained_beam_scorer_finalize(self): + inputs = self.constrained_beam_search_tester.prepare_inputs() + self.constrained_beam_search_tester.check_constrained_beam_scorer_finalize(*inputs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_configuration_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_configuration_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..a12b35968283c74f731b1682c67e82ab2812cc2f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_configuration_utils.py @@ -0,0 +1,168 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import tempfile +import unittest + +from huggingface_hub import HfFolder, delete_repo +from parameterized import parameterized +from requests.exceptions import HTTPError + +from transformers import AutoConfig, GenerationConfig +from transformers.testing_utils import TOKEN, USER, is_staging_test + + +class GenerationConfigTest(unittest.TestCase): + @parameterized.expand([(None,), ("foo.json",)]) + def test_save_load_config(self, config_name): + config = GenerationConfig( + do_sample=True, + temperature=0.7, + length_penalty=1.0, + bad_words_ids=[[1, 2, 3], [4, 5]], + ) + with tempfile.TemporaryDirectory() as tmp_dir: + config.save_pretrained(tmp_dir, config_name=config_name) + loaded_config = GenerationConfig.from_pretrained(tmp_dir, config_name=config_name) + + # Checks parameters that were specified + self.assertEqual(loaded_config.do_sample, True) + self.assertEqual(loaded_config.temperature, 0.7) + self.assertEqual(loaded_config.length_penalty, 1.0) + self.assertEqual(loaded_config.bad_words_ids, [[1, 2, 3], [4, 5]]) + + # Checks parameters that were not specified (defaults) + self.assertEqual(loaded_config.top_k, 50) + self.assertEqual(loaded_config.max_length, 20) + self.assertEqual(loaded_config.max_time, None) + + def test_from_model_config(self): + model_config = AutoConfig.from_pretrained("gpt2") + generation_config_from_model = GenerationConfig.from_model_config(model_config) + default_generation_config = GenerationConfig() + + # The generation config has loaded a few non-default parameters from the model config + self.assertNotEqual(generation_config_from_model, default_generation_config) + + # One of those parameters is eos_token_id -- check if it matches + self.assertNotEqual(generation_config_from_model.eos_token_id, default_generation_config.eos_token_id) + self.assertEqual(generation_config_from_model.eos_token_id, model_config.eos_token_id) + + def test_update(self): + generation_config = GenerationConfig() + update_kwargs = { + "max_new_tokens": 1024, + "foo": "bar", + } + update_kwargs_copy = copy.deepcopy(update_kwargs) + unused_kwargs = generation_config.update(**update_kwargs) + + # update_kwargs was not modified (no side effects) + self.assertEqual(update_kwargs, update_kwargs_copy) + + # update_kwargs was used to update the config on valid attributes + self.assertEqual(generation_config.max_new_tokens, 1024) + + # `.update()` returns a dictionary of unused kwargs + self.assertEqual(unused_kwargs, {"foo": "bar"}) + + def test_initialize_new_kwargs(self): + generation_config = GenerationConfig() + generation_config.foo = "bar" + + with tempfile.TemporaryDirectory("test-generation-config") as tmp_dir: + generation_config.save_pretrained(tmp_dir) + + new_config = GenerationConfig.from_pretrained(tmp_dir) + # update_kwargs was used to update the config on valid attributes + self.assertEqual(new_config.foo, "bar") + + generation_config = GenerationConfig.from_model_config(new_config) + assert not hasattr(generation_config, "foo") # no new kwargs should be initialized if from config + + +@is_staging_test +class ConfigPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-generation-config") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-generation-config-org") + except HTTPError: + pass + + def test_push_to_hub(self): + config = GenerationConfig( + do_sample=True, + temperature=0.7, + length_penalty=1.0, + ) + config.push_to_hub("test-generation-config", use_auth_token=self._token) + + new_config = GenerationConfig.from_pretrained(f"{USER}/test-generation-config") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="test-generation-config") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + config.save_pretrained( + tmp_dir, repo_id="test-generation-config", push_to_hub=True, use_auth_token=self._token + ) + + new_config = GenerationConfig.from_pretrained(f"{USER}/test-generation-config") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + def test_push_to_hub_in_organization(self): + config = GenerationConfig( + do_sample=True, + temperature=0.7, + length_penalty=1.0, + ) + config.push_to_hub("valid_org/test-generation-config-org", use_auth_token=self._token) + + new_config = GenerationConfig.from_pretrained("valid_org/test-generation-config-org") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-generation-config-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + config.save_pretrained( + tmp_dir, repo_id="valid_org/test-generation-config-org", push_to_hub=True, use_auth_token=self._token + ) + + new_config = GenerationConfig.from_pretrained("valid_org/test-generation-config-org") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_flax_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_flax_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..647482b88cd83f0cecf02f52c4046bc42f7bdd7e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_flax_utils.py @@ -0,0 +1,310 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random +import unittest + +import numpy as np + +import transformers +from transformers import is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax + + +if is_flax_available(): + import os + + import jax.numpy as jnp + from jax import jit + + from transformers import AutoTokenizer, FlaxAutoModelForCausalLM + from transformers.modeling_flax_pytorch_utils import load_flax_weights_in_pytorch_model + + os.environ["XLA_PYTHON_CLIENT_MEM_FRACTION"] = "0.12" # assumed parallelism: 8 + + +if is_torch_available(): + import torch + + +def ids_tensor(shape, vocab_size, rng=None): + """Creates a random int32 tensor of the shape within the vocab size.""" + if rng is None: + rng = random.Random() + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.randint(0, vocab_size - 1)) + + output = np.array(values, dtype=jnp.int32).reshape(shape) + + return output + + +def random_attention_mask(shape, rng=None): + attn_mask = ids_tensor(shape, vocab_size=2, rng=rng) + # make sure that at least one token is attended to for each batch + attn_mask[:, -1] = 1 + return attn_mask + + +@require_flax +class FlaxGenerationTesterMixin: + model_tester = None + all_generative_model_classes = () + + def _get_input_ids_and_config(self): + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + + # cut to half length & take max batch_size 3 + max_batch_size = 2 + sequence_length = inputs["input_ids"].shape[-1] // 2 + input_ids = inputs["input_ids"][:max_batch_size, :sequence_length] + + attention_mask = jnp.ones_like(input_ids) + attention_mask = attention_mask[:max_batch_size, :sequence_length] + + # generate max 5 tokens + max_length = input_ids.shape[-1] + 5 + if config.eos_token_id is not None and config.pad_token_id is None: + # hack to allow generate for models such as GPT2 as is done in `generate()` + config.pad_token_id = config.eos_token_id + return config, input_ids, attention_mask, max_length + + @is_pt_flax_cross_test + def test_greedy_generate_pt_fx(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = False + config.max_length = max_length + config.decoder_start_token_id = 0 + + for model_class in self.all_generative_model_classes: + flax_model = model_class(config) + + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, flax_model.params) + + flax_generation_outputs = flax_model.generate(input_ids).sequences + pt_generation_outputs = pt_model.generate(torch.tensor(input_ids, dtype=torch.long)) + + if flax_generation_outputs.shape[-1] > pt_generation_outputs.shape[-1]: + flax_generation_outputs = flax_generation_outputs[:, : pt_generation_outputs.shape[-1]] + + self.assertListEqual(pt_generation_outputs.numpy().tolist(), flax_generation_outputs.tolist()) + + def test_greedy_generate(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = False + config.max_length = max_length + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_sample_generate(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = True + config.max_length = max_length + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_beam_search_generate(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = False + config.max_length = max_length + config.num_beams = 2 + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_beam_search_generate_num_return_sequences(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = False + config.max_length = max_length + config.num_beams = 2 + config.num_return_sequences = 2 + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[0], input_ids.shape[0] * config.num_return_sequences) + + def test_sample_generate_logits_warper(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.do_sample = True + config.max_length = max_length + config.temperature = 0.8 + config.top_k = 10 + config.top_p = 0.3 + config.min_length = 1 + config.forced_bos_token_id = 8 + config.forced_eos_token_id = 9 + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_greedy_generate_logits_warper(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.max_length = max_length + config.min_length = 1 + config.forced_bos_token_id = 8 + config.forced_eos_token_id = 9 + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_beam_search_generate_logits_warper(self): + config, input_ids, _, max_length = self._get_input_ids_and_config() + config.max_length = max_length + config.num_beams = 2 + config.min_length = 1 + config.forced_bos_token_id = 8 + config.forced_eos_token_id = 9 + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_greedy_generate_attn_mask(self): + config, input_ids, attention_mask, max_length = self._get_input_ids_and_config() + + # pad attention mask on the left + attention_mask = attention_mask.at[(0, 0)].set(0) + + config.do_sample = False + config.max_length = max_length + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids, attention_mask=attention_mask).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids, attention_mask=attention_mask).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_sample_generate_attn_mask(self): + config, input_ids, attention_mask, max_length = self._get_input_ids_and_config() + + # pad attention mask on the left + attention_mask = attention_mask.at[(0, 0)].set(0) + + config.do_sample = True + config.max_length = max_length + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids, attention_mask=attention_mask).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids, attention_mask=attention_mask).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + def test_beam_search_generate_attn_mask(self): + config, input_ids, attention_mask, max_length = self._get_input_ids_and_config() + + # pad attention mask on the left + attention_mask = attention_mask.at[(0, 0)].set(0) + + config.num_beams = 2 + config.max_length = max_length + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + generation_outputs = model.generate(input_ids, attention_mask=attention_mask).sequences + self.assertEqual(generation_outputs.shape[-1], max_length) + + jit_generate = jit(model.generate) + jit_generation_outputs = jit_generate(input_ids, attention_mask=attention_mask).sequences + + self.assertListEqual(generation_outputs.tolist(), jit_generation_outputs.tolist()) + + +@require_flax +class FlaxGenerationIntegrationTests(unittest.TestCase): + def test_validate_generation_inputs(self): + tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-bert") + model = FlaxAutoModelForCausalLM.from_pretrained("hf-internal-testing/tiny-bert-flax-only") + + encoder_input_str = "Hello world" + input_ids = tokenizer(encoder_input_str, return_tensors="np").input_ids + + # typos are quickly detected (the correct argument is `do_sample`) + with self.assertRaisesRegex(ValueError, "do_samples"): + model.generate(input_ids, do_samples=True) + + # arbitrary arguments that will not be used anywhere are also not accepted + with self.assertRaisesRegex(ValueError, "foo"): + fake_model_kwargs = {"foo": "bar"} + model.generate(input_ids, **fake_model_kwargs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_logits_process.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_logits_process.py new file mode 100644 index 0000000000000000000000000000000000000000..85ebf780f7dc17cff8747f1b9c968783b0b27ed6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_logits_process.py @@ -0,0 +1,720 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from typing import List, Union + +from parameterized import parameterized + +from transformers import is_torch_available +from transformers.testing_utils import require_torch, torch_device + +from ..test_modeling_common import ids_tensor + + +if is_torch_available(): + import torch + from torch import nn + + from transformers.generation import ( + EncoderNoRepeatNGramLogitsProcessor, + EncoderRepetitionPenaltyLogitsProcessor, + EpsilonLogitsWarper, + EtaLogitsWarper, + ExponentialDecayLengthPenalty, + ForcedBOSTokenLogitsProcessor, + ForcedEOSTokenLogitsProcessor, + HammingDiversityLogitsProcessor, + InfNanRemoveLogitsProcessor, + LogitNormalization, + LogitsProcessorList, + MinLengthLogitsProcessor, + MinNewTokensLengthLogitsProcessor, + NoBadWordsLogitsProcessor, + NoRepeatNGramLogitsProcessor, + PrefixConstrainedLogitsProcessor, + RepetitionPenaltyLogitsProcessor, + TemperatureLogitsWarper, + TopKLogitsWarper, + TopPLogitsWarper, + TypicalLogitsWarper, + ) + + +@require_torch +class LogitsProcessorTest(unittest.TestCase): + def _get_uniform_logits(self, batch_size: int, length: int): + scores = torch.ones((batch_size, length), device=torch_device, dtype=torch.float) / length + return scores + + def test_min_length_dist_processor(self): + vocab_size = 20 + batch_size = 4 + eos_token_id = 0 + + min_dist_processor = MinLengthLogitsProcessor(min_length=10, eos_token_id=eos_token_id) + + # check that min length is applied at length 5 + input_ids = ids_tensor((batch_size, 5), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = min_dist_processor(input_ids, scores) + self.assertListEqual(scores_before_min_length[:, eos_token_id].tolist(), 4 * [-float("inf")]) + + # check that min length is not applied anymore at length 15 + input_ids = ids_tensor((batch_size, 15), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = min_dist_processor(input_ids, scores) + self.assertFalse(torch.isinf(scores_before_min_length).any()) + + @parameterized.expand([(0,), ([0, 18],)]) + def test_new_min_length_dist_processor(self, eos_token_id: Union[int, List[int]]): + vocab_size = 20 + batch_size = 4 + + # check that first input is skipped (min new length applying) + input_ids = ids_tensor((batch_size, 5), vocab_size=20) + new_min_dist_processor = MinNewTokensLengthLogitsProcessor( + prompt_length_to_skip=input_ids.shape[-1], min_new_tokens=3, eos_token_id=eos_token_id + ) + + expected_eos_scores_before_min_length = batch_size * [-float("inf")] + if isinstance(eos_token_id, list): + expected_eos_scores_before_min_length *= len(eos_token_id) + + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertListEqual( + scores_before_min_length[:, eos_token_id].flatten().tolist(), expected_eos_scores_before_min_length + ) + + # check that, for skipping, now prompt length is 5, after that we expect first 5 tokens will be skipped + self.assertTrue(new_min_dist_processor.prompt_length_to_skip == 5) + + # check that min length is applied at length 2 + input_ids = ids_tensor((batch_size, 2), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertListEqual( + scores_before_min_length[:, eos_token_id].flatten().tolist(), expected_eos_scores_before_min_length + ) + + # check that min new length is applied at length 6 (because it has only 1 new token) + input_ids = ids_tensor((batch_size, 6), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertListEqual( + scores_before_min_length[:, eos_token_id].flatten().tolist(), expected_eos_scores_before_min_length + ) + + # check that min new length is applied at length 7 (because it has only 2 new tokens) + input_ids = ids_tensor((batch_size, 7), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertListEqual( + scores_before_min_length[:, eos_token_id].flatten().tolist(), expected_eos_scores_before_min_length + ) + + # check that min new length is not applied anymore at length 8 + input_ids = ids_tensor((batch_size, 8), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertFalse(torch.isinf(scores_before_min_length).any()) + + # check that min new length is not applied anymore at length 15 + input_ids = ids_tensor((batch_size, 15), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_min_length = new_min_dist_processor(input_ids, scores) + self.assertFalse(torch.isinf(scores_before_min_length).any()) + + def test_temperature_dist_warper(self): + input_ids = None + length = 20 + + scores = self._get_uniform_logits(batch_size=2, length=length) + + # tweak scores to not be uniform anymore + scores[1, 5] = (1 / length) + 0.1 # peak, 1st batch + scores[1, 10] = (1 / length) - 0.4 # valley, 1st batch + + # compute softmax + probs = nn.functional.softmax(scores, dim=-1) + + temp_dist_warper_sharper = TemperatureLogitsWarper(temperature=0.5) + temp_dist_warper_smoother = TemperatureLogitsWarper(temperature=1.3) + + warped_prob_sharp = nn.functional.softmax(temp_dist_warper_sharper(input_ids, scores.clone()), dim=-1) + warped_prob_smooth = nn.functional.softmax(temp_dist_warper_smoother(input_ids, scores.clone()), dim=-1) + + # uniform distribution stays uniform + self.assertTrue(torch.allclose(probs[0, :], warped_prob_sharp[0, :], atol=1e-3)) + self.assertTrue(torch.allclose(probs[0, :], warped_prob_smooth[0, :], atol=1e-3)) + + # sharp peaks get higher, valleys get lower + self.assertLess(probs[1, :].max(), warped_prob_sharp[1, :].max()) + self.assertGreater(probs[1, :].min(), warped_prob_sharp[1, :].min()) + + # smooth peaks get lower, valleys get higher + self.assertGreater(probs[1, :].max(), warped_prob_smooth[1, :].max()) + self.assertLess(probs[1, :].min(), warped_prob_smooth[1, :].min()) + + def test_repetition_penalty_dist_process(self): + input_ids = torch.tensor([[0, 1], [5, 0]], device=torch_device, dtype=torch.long) + vocab_size = 10 + + scores = self._get_uniform_logits(batch_size=2, length=vocab_size) + + # give values special values + scores[0, 0] = -(1 / vocab_size) + scores[1, 5] = 4 / vocab_size + + rep_penalty_proc = RepetitionPenaltyLogitsProcessor(penalty=2.0) + + scores = rep_penalty_proc(input_ids, scores.clone()) + + # check that values were correctly changed + self.assertAlmostEqual(scores[0, 0].item(), -(1 / vocab_size) * 2) + self.assertAlmostEqual(scores[0, 1].item(), (1 / vocab_size) / 2) + + self.assertAlmostEqual(scores[1, 0].item(), (1 / vocab_size) / 2) + self.assertAlmostEqual(scores[1, 5].item(), (4 / vocab_size) / 2) + + def test_encoder_repetition_penalty_dist_process(self): + input_ids = torch.tensor([[0, 1], [5, 0]], device=torch_device, dtype=torch.long) + vocab_size = 10 + + scores = self._get_uniform_logits(batch_size=2, length=vocab_size) + + # give values special values + scores[0, 0] = -(1 / vocab_size) + scores[1, 5] = 4 / vocab_size + + rep_penalty_proc = EncoderRepetitionPenaltyLogitsProcessor(penalty=2.0, encoder_input_ids=input_ids) + + scores = rep_penalty_proc(input_ids, scores.clone()) + + # check that values were correctly changed + self.assertAlmostEqual(scores[0, 0].item(), -(1 / vocab_size) / 2) + self.assertAlmostEqual(scores[0, 1].item(), (1 / vocab_size) * 2) + + self.assertAlmostEqual(scores[1, 0].item(), (1 / vocab_size) * 2) + self.assertAlmostEqual(scores[1, 5].item(), (4 / vocab_size) * 2) + + # check that values not in the encoder ids were NOT changed + self.assertAlmostEqual(scores[0, 2].item(), (1 / vocab_size)) + self.assertAlmostEqual(scores[1, 2].item(), (1 / vocab_size)) + + def test_top_k_dist_warper(self): + input_ids = None + vocab_size = 10 + batch_size = 2 + + # create ramp distribution + ramp_logits = ( + torch.arange(vocab_size, device=torch_device, dtype=torch.float).unsqueeze(0).repeat(batch_size, 1) + ) + ramp_logits[1:, : vocab_size // 2] = ramp_logits[1:, : vocab_size // 2] + vocab_size + + top_k_warp = TopKLogitsWarper(3) + + scores = top_k_warp(input_ids, ramp_logits) + + # check that correct tokens are filtered + self.assertListEqual(torch.isinf(scores[0]).tolist(), 7 * [True] + 3 * [False]) + self.assertListEqual(torch.isinf(scores[1]).tolist(), 2 * [True] + 3 * [False] + 5 * [True]) + + # check special cases + length = 5 + + logits = self._get_uniform_logits(batch_size=batch_size, length=length) + top_k_warp_safety_check = TopKLogitsWarper(top_k=1, filter_value=0.0, min_tokens_to_keep=3) + + scores = top_k_warp_safety_check(input_ids, logits) + # uniform dist is not changed + self.assertListEqual((scores == 0.0).to(torch.long).sum(dim=-1).tolist(), [0, 0]) + + ramp_logits = torch.arange(length, device=torch_device, dtype=torch.float).unsqueeze(0).repeat(batch_size, 1) + scores = top_k_warp_safety_check(input_ids, ramp_logits) + + # min_tokens overwrites k: 3 tokens are kept => 2 tokens are nullified + self.assertListEqual((scores == 0.0).to(torch.long).sum(dim=-1).tolist(), [2, 2]) + + def test_top_p_dist_warper(self): + input_ids = None + vocab_size = 10 + batch_size = 2 + + # create distribution and take log (inverse to Softmax as taken in TopPLogitsWarper) + dist = torch.log( + torch.tensor([[0.3, 0.1, 0.1, 0.5], [0.15, 0.3, 0.3, 0.25]], device=torch_device, dtype=torch.float) + ) + + top_p_warp = TopPLogitsWarper(0.8) + filtered_dist = torch.exp(top_p_warp(input_ids, dist)) + + # dist should be filtered to keep min num values so that sum is >= top_p + # exp (-inf) => 0 + EXPECTED_FILTERED_DIST = torch.tensor( + [[0.3, 0.0, 0.0, 0.5], [0.0, 0.3, 0.3, 0.25]], device=torch_device, dtype=torch.float + ) + self.assertTrue(torch.allclose(filtered_dist, EXPECTED_FILTERED_DIST, atol=1e-3)) + + # check edge cases with negative and extreme logits + ramp_logits = torch.arange(vocab_size, device=torch_device, dtype=torch.float).unsqueeze(0).repeat( + batch_size, 1 + ) - (vocab_size // 2) + + # make ramp_logits more extreme + ramp_logits[1] = ramp_logits[1] * 100.0 + + # make sure at least 2 tokens are kept + top_p_warp = TopPLogitsWarper(0.9, min_tokens_to_keep=2, filter_value=0.0) + filtered_dist = top_p_warp(input_ids, ramp_logits) + + # first batch should keep three tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. + self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [3, 2]) + + def test_typical_dist_warper(self): + input_ids = None + vocab_size = 10 + batch_size = 2 + + # create distribution and take log (inverse to Softmax as taken in TopPLogitsWarper) + dist = torch.log( + torch.tensor([[0.97, 0.01, 0.01, 0.01], [0.4, 0.2, 0.2, 0.2]], device=torch_device, dtype=torch.float) + ) + + typical_warp = TypicalLogitsWarper(0.5) + filtered_dist = torch.exp(typical_warp(input_ids, dist)) + + # dist should be filtered to keep min num values so that sum is >= 0.7 + # exp (-inf) => 0 + EXPECTED_FILTERED_DIST = torch.tensor( + [[0.97, 0.0, 0.0, 0.0], [0.0, 0.2, 0.2, 0.2]], device=torch_device, dtype=torch.float + ) + self.assertTrue(torch.allclose(filtered_dist, EXPECTED_FILTERED_DIST, atol=1e-3)) + + # check special cases + length = 5 + + logits = self._get_uniform_logits(batch_size=batch_size, length=length) + typical_warp_safety_check = TypicalLogitsWarper(mass=0.5, filter_value=0.0, min_tokens_to_keep=3) + + scores = typical_warp_safety_check(input_ids, logits) + # uniform dist is not changed + self.assertListEqual((scores == 0.0).to(torch.long).sum(dim=-1).tolist(), [0, 0]) + + # check edge cases with negative and extreme logits + ramp_logits = torch.arange(vocab_size, device=torch_device, dtype=torch.float).unsqueeze(0).repeat( + batch_size, 1 + ) - (vocab_size // 2) + + # make ramp_logits more extreme + ramp_logits[1] = ramp_logits[1] * 100.0 + + # make sure at least 2 tokens are kept + typical_warp = TypicalLogitsWarper(0.7, min_tokens_to_keep=2, filter_value=0.0) + filtered_dist = typical_warp(input_ids, ramp_logits) + + # first batch should keep two tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. + self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [2, 2]) + + def test_epsilon_dist_warper(self): + input_ids = None + vocab_size = 10 + batch_size = 2 + + # create distribution and take log (inverse to Softmax as taken in TopPLogitsWarper) + dist = torch.log( + torch.tensor( + [[0.87, 0.099, 0.001, 0.03], [0.4, 0.299, 0.101, 0.2]], device=torch_device, dtype=torch.float + ) + ) + + epsilon_warp = EpsilonLogitsWarper(0.1) + filtered_dist = torch.exp(epsilon_warp(input_ids, dist)) + + # dist should be filtered to only keep values with proba >= 0.1 + # exp (-inf) => 0 + EXPECTED_FILTERED_DIST = torch.tensor( + [[0.87, 0, 0, 0], [0.4, 0.299, 0.101, 0.2]], device=torch_device, dtype=torch.float + ) + self.assertTrue(torch.allclose(filtered_dist, EXPECTED_FILTERED_DIST, atol=1e-3)) + + # check edge cases with negative and extreme logits + ramp_logits = torch.arange(vocab_size, device=torch_device, dtype=torch.float).unsqueeze(0).repeat( + batch_size, 1 + ) - (vocab_size // 2) + + # make ramp_logits more extreme + ramp_logits[1] = ramp_logits[1] * 100.0 + + # make sure at least 2 tokens are kept + epsilon_warp = EpsilonLogitsWarper(5e-2, min_tokens_to_keep=2, filter_value=0.0) + filtered_dist = epsilon_warp(input_ids, ramp_logits) + + # first batch should keep 3 tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. + self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [3, 2]) + + def test_eta_dist_warper(self): + input_ids = None + vocab_size = 10 + batch_size = 2 + + # create distribution and take log (inverse to Softmax as taken in TopPLogitsWarper) + dist = torch.log( + torch.tensor([[0.0, 0.1, 0.8, 0.1], [0.01, 0.04, 0.9, 0.05]], device=torch_device, dtype=torch.float) + ) + + eta_warp = EtaLogitsWarper(0.0625) + filtered_dist = torch.exp(eta_warp(input_ids, dist)) + + # dist should be filtered to only keep values with proba >= min(0.0625, sqrt(0.0625) * e^-H(p)) + # min(0.0625, 0.1320) is the cutoff for the first row and min(0.0625, 0.1644) is for the second + # where H is the entropy function and p is the probability vector. + # exp (-inf) => 0 + EXPECTED_FILTERED_DIST = torch.tensor( + [[0.0, 0.1, 0.8, 0.1], [0.0, 0.0, 0.9, 0.0]], device=torch_device, dtype=torch.float + ) + self.assertTrue(torch.allclose(filtered_dist, EXPECTED_FILTERED_DIST, atol=1e-3)) + + # check edge cases with negative and extreme logits + ramp_logits = torch.arange(vocab_size, device=torch_device, dtype=torch.float).unsqueeze(0).repeat( + batch_size, 1 + ) - (vocab_size // 2) + + # make ramp_logits more extreme + ramp_logits[1] = ramp_logits[1] * 100.0 + + # make sure at least 2 tokens are kept + eta_warp = EtaLogitsWarper(0.1, min_tokens_to_keep=2, filter_value=0.0) + filtered_dist = eta_warp(input_ids, ramp_logits) + + # first batch should keep 2 tokens, second batch would keep only 1, but due to `min_tokens_to_keep=2` keeps 2. + self.assertListEqual((filtered_dist != 0.0).to(torch.long).sum(dim=-1).tolist(), [2, 2]) + + def test_no_repeat_ngram_dist_processor(self): + vocab_size = 3 + batch_size = 2 + + input_ids = torch.tensor([[1, 1, 2, 1], [0, 1, 0, 1]], device=torch_device, dtype=torch.long) + scores = self._get_uniform_logits(batch_size, vocab_size) + + no_repeat_proc_2_gram = NoRepeatNGramLogitsProcessor(2) + no_repeat_proc_3_gram = NoRepeatNGramLogitsProcessor(3) + + filtered_scores_2_gram = no_repeat_proc_2_gram(input_ids, scores.clone()) + filtered_scores_3_gram = no_repeat_proc_3_gram(input_ids, scores.clone()) + + # 2-gram would forbid 2nd and 3rd token (1,2) at 1st batch and 1st token (0) at 2nd batch + self.assertListEqual(torch.isinf(filtered_scores_2_gram).tolist(), [[False, True, True], [True, False, False]]) + + # 3-gram would forbid no token at 1st batch and 1st token (0) at 2nd batch + self.assertListEqual( + torch.isinf(filtered_scores_3_gram).tolist(), [[False, False, False], [True, False, False]] + ) + + def test_encoder_no_repeat_ngram_dist_processor(self): + vocab_size = 3 + num_beams = 2 + batch_size = 1 + + encoder_input_ids = torch.tensor([1, 2, 1, 1], device=torch_device, dtype=torch.long) + + input_ids = torch.tensor([[1, 2, 1], [8, 0, 2]], device=torch_device, dtype=torch.long) + scores = self._get_uniform_logits(batch_size * num_beams, vocab_size) + + no_repeat_proc_2_gram = EncoderNoRepeatNGramLogitsProcessor(2, encoder_input_ids=encoder_input_ids) + no_repeat_proc_3_gram = EncoderNoRepeatNGramLogitsProcessor(3, encoder_input_ids=encoder_input_ids) + + filtered_scores_2_gram = no_repeat_proc_2_gram(input_ids, scores.clone()) + filtered_scores_3_gram = no_repeat_proc_3_gram(input_ids, scores.clone()) + + # 2-gram would forbid 1st and 2nd token at 1st beam and 1st token (0) at 2nd beam + self.assertListEqual(torch.isinf(filtered_scores_2_gram).tolist(), [[False, True, True], [False, True, False]]) + + # 3-gram would forbid 1st token at 1st beam and no token at 2nd beam + self.assertListEqual( + torch.isinf(filtered_scores_3_gram).tolist(), [[False, True, False], [False, False, False]] + ) + + # Batched input + vocab_size = 3 + num_beams = 2 + batch_size = 2 + encoder_input_ids = torch.tensor([[1, 2, 1, 1], [0, 0, 2, 1]], device=torch_device, dtype=torch.long) + + input_ids = torch.tensor([[1, 2, 1], [1, 0, 2], [0, 0, 0], [0, 2, 2]], device=torch_device, dtype=torch.long) + scores = self._get_uniform_logits(batch_size * num_beams, vocab_size) + + no_repeat_proc_2_gram = EncoderNoRepeatNGramLogitsProcessor(2, encoder_input_ids=encoder_input_ids) + no_repeat_proc_3_gram = EncoderNoRepeatNGramLogitsProcessor(3, encoder_input_ids=encoder_input_ids) + + filtered_scores_2_gram = no_repeat_proc_2_gram(input_ids, scores.clone()) + filtered_scores_3_gram = no_repeat_proc_3_gram(input_ids, scores.clone()) + + # 2gram + # Batch 1 + # - Beam 1: tokens (1, 2) forbidden + # - Beam 2: tokens (1) forbidden + # Batch 2 + # - Beam 1: tokens (0, 2) forbidden + # - Beam 2: tokens (1) forbidden + self.assertListEqual( + torch.isinf(filtered_scores_2_gram).tolist(), + [[False, True, True], [False, True, False], [True, False, True], [False, True, False]], + ) + + # Batch 1 + # - Beam 1: tokens (1) forbidden + # - Beam 2: tokens () forbidden + # Batch 2 + # - Beam 1: tokens (2) forbidden + # - Beam 2: tokens () forbidden + self.assertListEqual( + torch.isinf(filtered_scores_3_gram).tolist(), + [[False, True, False], [False, False, False], [False, False, True], [False, False, False]], + ) + + def test_no_bad_words_dist_processor(self): + vocab_size = 5 + batch_size = 2 + eos_token_id = 4 + + input_ids = torch.tensor([[0, 1, 3, 1], [0, 1, 0, 1]], device=torch_device, dtype=torch.long) + bad_word_tokens = [[1], [4], [1, 0], [0, 1, 2], [1, 3, 1, 3]] + scores = self._get_uniform_logits(batch_size, vocab_size) + + no_bad_words_dist_proc = NoBadWordsLogitsProcessor(bad_words_ids=bad_word_tokens, eos_token_id=eos_token_id) + + filtered_scores = no_bad_words_dist_proc(input_ids, scores.clone()) + + # batch 1: 1st, 2nd, and 4th (0, 1, 3) token are forbidden + # batch 2: 1st, 2nd, and 3rd (0, 1, 2) token are forbidden + # Note that 5th element cannot be forbidden as it is EOS token + self.assertListEqual( + torch.isinf(filtered_scores).tolist(), [[True, True, False, True, False], [True, True, True, False, False]] + ) + + # check edge case + no_bad_words_dist_proc = NoBadWordsLogitsProcessor(bad_words_ids=[[4]], eos_token_id=eos_token_id) + filtered_scores = no_bad_words_dist_proc(input_ids, scores.clone()) + self.assertTrue(torch.allclose(scores, filtered_scores, atol=1e-3)) + + def test_processor_list(self): + batch_size = 4 + sequence_length = 10 + vocab_size = 15 + eos_token_id = 0 + + # dummy input_ids and scores + input_ids = ids_tensor((batch_size, sequence_length), vocab_size) + input_ids_comp = input_ids.clone() + + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_comp = scores.clone() + + # instantiate all dist processors + min_dist_proc = MinLengthLogitsProcessor(min_length=10, eos_token_id=eos_token_id) + temp_dist_warp = TemperatureLogitsWarper(temperature=0.5) + rep_penalty_proc = RepetitionPenaltyLogitsProcessor(penalty=2.0) + top_k_warp = TopKLogitsWarper(3) + top_p_warp = TopPLogitsWarper(0.8) + no_repeat_proc = NoRepeatNGramLogitsProcessor(2) + no_bad_words_dist_proc = NoBadWordsLogitsProcessor(bad_words_ids=[[1]], eos_token_id=eos_token_id) + + # no processor list + scores = min_dist_proc(input_ids, scores) + scores = temp_dist_warp(input_ids, scores) + scores = rep_penalty_proc(input_ids, scores) + scores = top_k_warp(input_ids, scores) + scores = top_p_warp(input_ids, scores) + scores = no_repeat_proc(input_ids, scores) + scores = no_bad_words_dist_proc(input_ids, scores) + + # with processor list + processor = LogitsProcessorList( + [ + min_dist_proc, + temp_dist_warp, + rep_penalty_proc, + top_k_warp, + top_p_warp, + no_repeat_proc, + no_bad_words_dist_proc, + ] + ) + scores_comp = processor(input_ids, scores_comp) + + # scores should be equal + self.assertTrue(torch.allclose(scores, scores_comp, atol=1e-3)) + + # input_ids should never be changed + self.assertListEqual(input_ids.tolist(), input_ids_comp.tolist()) + + def test_prefix_constrained_logits_processor(self): + vocab_size = 5 + batch_size = 2 + + input_ids = torch.tensor([[0, 1, 3, 1], [0, 1, 0, 1]], device=torch_device, dtype=torch.long) + scores = self._get_uniform_logits(batch_size, vocab_size) + + def prefix_allowed_tokens_fn(batch_id, inputs_ids): + return [[0, 1], [2, 3]][batch_id] + + prefix_constrained_logits_proc = PrefixConstrainedLogitsProcessor(prefix_allowed_tokens_fn, 1) + + filtered_scores = prefix_constrained_logits_proc(input_ids, scores.clone()) + + # batch 1: 1st, 2nd (0, 1) token are allowed + # batch 2: 3rd, 4th (2, 3) token are allowed + self.assertListEqual( + torch.isinf(filtered_scores).tolist(), [[False, False, True, True, True], [True, True, False, False, True]] + ) + + def test_hamming_diversity(self): + vocab_size = 4 + num_beams = 2 + num_beam_groups = 2 + + scores = self._get_uniform_logits(num_beams, vocab_size) + # batch_idx = 0 -> index batch_idx * num_beam_groups -> idx = 0 * 2 = 0 -> penalises tokens 1 + # batch_idx = 1 -> index batch_idx * num_beam_groups -> idx = 1 * 2 = 2 -> penalises tokens 1 + current_tokens = torch.tensor([0, 3, 1, 2], device=torch_device, dtype=torch.long) + + diversity_logits_processor = HammingDiversityLogitsProcessor( + diversity_penalty=1.0, num_beams=num_beams, num_beam_groups=num_beam_groups + ) + + processed_scores = diversity_logits_processor(None, scores, current_tokens, 1) + + self.assertTrue( + torch.allclose( + processed_scores[0], torch.tensor([-0.7500, 0.2500, 0.2500, 0.2500], device=torch_device), atol=1e-3 + ) + ) + self.assertTrue( + torch.allclose( + processed_scores[1], torch.tensor([0.2500, -0.7500, 0.2500, 0.2500], device=torch_device), atol=1e-3 + ) + ) + + def test_forced_bos_token_logits_processor(self): + vocab_size = 20 + batch_size = 4 + bos_token_id = 0 + + logits_processor = ForcedBOSTokenLogitsProcessor(bos_token_id=bos_token_id) + + # check that all scores are -inf except the bos_token_id score + input_ids = ids_tensor((batch_size, 1), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores = logits_processor(input_ids, scores) + self.assertTrue(torch.isneginf(scores[:, bos_token_id + 1 :]).all()) + self.assertListEqual(scores[:, bos_token_id].tolist(), 4 * [0]) # score for bos_token_id shold be zero + + # check that bos_token_id is not forced if current length is greater than 1 + input_ids = ids_tensor((batch_size, 4), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores = logits_processor(input_ids, scores) + self.assertFalse(torch.isinf(scores).any()) + + def test_forced_eos_token_logits_processor(self): + vocab_size = 20 + batch_size = 4 + eos_token_id = 0 + max_length = 5 + + logits_processor = ForcedEOSTokenLogitsProcessor(max_length=max_length, eos_token_id=eos_token_id) + + # check that all scores are -inf except the eos_token_id when max_length-1 is reached + input_ids = ids_tensor((batch_size, 4), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores = logits_processor(input_ids, scores) + self.assertTrue(torch.isneginf(scores[:, eos_token_id + 1 :]).all()) + self.assertListEqual(scores[:, eos_token_id].tolist(), 4 * [0]) # score for eos_token_id should be zero + + # check that eos_token_id is not forced if max_length-1 is not reached + input_ids = ids_tensor((batch_size, 3), vocab_size=20) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores = logits_processor(input_ids, scores) + self.assertFalse(torch.isinf(scores).any()) + + def test_remove_nan_inf_logits_processor(self): + scores = torch.tensor( + [[0.0, 0.7, 0.8, float("nan")], [0.1, float("inf"), 0.3, float("-inf")]], device=torch_device + ) + input_ids = ids_tensor((2, 4), vocab_size=20) + + logits_processor = InfNanRemoveLogitsProcessor() + + scores = logits_processor(input_ids, scores) + + self.assertTrue( + torch.allclose( + scores, + torch.tensor( + [[0.0, 0.7, 0.8, 0.0], [0.1, torch.finfo(scores.dtype).max, 0.3, float("-inf")]], + device=torch_device, + ), + atol=1e-6, + ) + ) + + def test_exponential_decay_length_penalty(self): + vocab_size = 20 + batch_size = 4 + eos_token_id = 0 + + penalty_start = 5 + penalty_factor = 1.1 + + input_ids = ids_tensor((batch_size, 2), vocab_size=vocab_size) + input_ids_seq_length = input_ids.shape[-1] + + length_decay_processor = ExponentialDecayLengthPenalty( + exponential_decay_length_penalty=(penalty_start, penalty_factor), + eos_token_id=eos_token_id, + input_ids_seq_length=input_ids_seq_length, + ) + + # check that penalty is not applied before start + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_before_start = length_decay_processor(input_ids, scores) + self.assertListEqual(scores_before_start[:, eos_token_id].tolist(), scores[:, eos_token_id].tolist()) + + # check that penalty is applied after start + input_ids = ids_tensor((batch_size, 20), vocab_size=vocab_size) + scores = self._get_uniform_logits(batch_size, vocab_size) + scores_after_start = length_decay_processor(input_ids, scores) + self.assertTrue( + torch.gt( + scores_after_start[penalty_start + 1 :, eos_token_id], scores[penalty_start + 1 :, eos_token_id] + ).all() + ) + + def test_normalization(self): + input_ids = None + + scores = torch.tensor( + [[-23.18, -29.96, -43.54, 47.77], [-33.58, -26.87, -32.96, 22.51]], device=torch_device, dtype=torch.float + ) + + logit_normalization = LogitNormalization() + normalized_scores = logit_normalization(input_ids, scores).exp() + + ones = torch.ones(scores.shape[0], device=torch_device, dtype=torch.float) + self.assertTrue(normalized_scores.sum(dim=-1).allclose(ones)) + + self.assertTrue(normalized_scores.allclose(scores.softmax(dim=-1))) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_stopping_criteria.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_stopping_criteria.py new file mode 100644 index 0000000000000000000000000000000000000000..dfc5308359ffb319d85ff77a3de9b17170a6e65b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_stopping_criteria.py @@ -0,0 +1,109 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +import unittest + +from transformers import is_torch_available +from transformers.testing_utils import require_torch, torch_device + +from ..test_modeling_common import ids_tensor + + +if is_torch_available(): + import torch + + from transformers.generation import ( + MaxLengthCriteria, + MaxNewTokensCriteria, + MaxTimeCriteria, + StoppingCriteriaList, + validate_stopping_criteria, + ) + + +@require_torch +class StoppingCriteriaTestCase(unittest.TestCase): + def _get_tensors(self, length): + batch_size = 3 + vocab_size = 250 + + input_ids = ids_tensor((batch_size, length), vocab_size) + scores = torch.ones((batch_size, length), device=torch_device, dtype=torch.float) / length + return input_ids, scores + + def test_list_criteria(self): + input_ids, scores = self._get_tensors(5) + + criteria = StoppingCriteriaList( + [ + MaxLengthCriteria(max_length=10), + MaxTimeCriteria(max_time=0.1), + ] + ) + + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(9) + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(10) + self.assertTrue(criteria(input_ids, scores)) + + def test_max_length_criteria(self): + criteria = MaxLengthCriteria(max_length=10) + + input_ids, scores = self._get_tensors(5) + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(9) + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(10) + self.assertTrue(criteria(input_ids, scores)) + + def test_max_new_tokens_criteria(self): + criteria = MaxNewTokensCriteria(start_length=5, max_new_tokens=5) + + input_ids, scores = self._get_tensors(5) + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(9) + self.assertFalse(criteria(input_ids, scores)) + + input_ids, scores = self._get_tensors(10) + self.assertTrue(criteria(input_ids, scores)) + + criteria_list = StoppingCriteriaList([criteria]) + self.assertEqual(criteria_list.max_length, 10) + + def test_max_time_criteria(self): + input_ids, scores = self._get_tensors(5) + + criteria = MaxTimeCriteria(max_time=0.1) + self.assertFalse(criteria(input_ids, scores)) + + criteria = MaxTimeCriteria(max_time=0.1, initial_timestamp=time.time() - 0.2) + self.assertTrue(criteria(input_ids, scores)) + + def test_validate_stopping_criteria(self): + validate_stopping_criteria(StoppingCriteriaList([MaxLengthCriteria(10)]), 10) + + with self.assertWarns(UserWarning): + validate_stopping_criteria(StoppingCriteriaList([MaxLengthCriteria(10)]), 11) + + stopping_criteria = validate_stopping_criteria(StoppingCriteriaList(), 11) + + self.assertEqual(len(stopping_criteria), 1) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_tf_utils.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_tf_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..6fdad1ef6365310008bc2a2e810edcec961a5d18 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/generation/test_tf_utils.py @@ -0,0 +1,339 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import tempfile +import unittest + +import numpy as np +from huggingface_hub import hf_hub_download + +from transformers import is_tensorflow_text_available, is_tf_available +from transformers.testing_utils import require_tensorflow_text, require_tf, slow + +from ..test_modeling_tf_common import floats_tensor +from .test_framework_agnostic import GenerationIntegrationTestsMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + AutoTokenizer, + TFAutoModelForCausalLM, + TFAutoModelForSeq2SeqLM, + TFAutoModelForSpeechSeq2Seq, + TFAutoModelForVision2Seq, + TFBartForConditionalGeneration, + TFLogitsProcessorList, + TFMinLengthLogitsProcessor, + tf_top_k_top_p_filtering, + ) + +if is_tensorflow_text_available(): + import tensorflow_text as text + + +@require_tf +class UtilsFunctionsTest(unittest.TestCase): + # tests whether the top_k_top_p_filtering function behaves as expected + def test_top_k_top_p_filtering(self): + logits = tf.convert_to_tensor( + [ + [ + 8.2220991, # 3rd highest value; idx. 0 + -0.5620044, + 5.23229752, + 4.0386393, + -6.8798378, + -0.54785802, + -3.2012153, + 2.92777176, + 1.88171953, + 7.35341276, # 5th highest value; idx. 9 + 8.43207833, # 2nd highest value; idx. 10 + -9.85711836, + -5.96209236, + -1.13039161, + -7.1115294, + -0.8369633, + -5.3186408, + 7.06427407, + 0.81369344, + -0.82023817, + -5.9179796, + 0.58813443, + -6.99778438, + 4.71551189, + -0.18771637, + 7.44020759, # 4th highest value; idx. 25 + 9.38450987, # 1st highest value; idx. 26 + 2.12662941, + -9.32562038, + 2.35652522, + ], # cummulative prob of 5 highest values <= 0.6 + [ + 0.58425518, + 4.53139238, + -5.57510464, + -6.28030699, + -7.19529503, + -4.02122551, + 1.39337037, + -6.06707057, + 1.59480517, + -9.643119, + 0.03907799, + 0.67231762, + -8.88206726, + 6.27115922, # 4th highest value; idx. 13 + 2.28520723, + 4.82767506, + 4.30421368, + 8.8275313, # 2nd highest value; idx. 17 + 5.44029958, # 5th highest value; idx. 18 + -4.4735794, + 7.38579536, # 3rd highest value; idx. 20 + -2.91051663, + 2.61946077, + -2.5674762, + -9.48959302, + -4.02922645, + -1.35416918, + 9.67702323, # 1st highest value; idx. 27 + -5.89478553, + 1.85370467, + ], # cummulative prob of 5 highest values <= 0.6 + ], + dtype=tf.float32, + ) + + non_inf_expected_idx = tf.convert_to_tensor( + [[0, 0], [0, 9], [0, 10], [0, 25], [0, 26], [1, 13], [1, 17], [1, 18], [1, 20], [1, 27]], + dtype=tf.int32, + ) # expected non filtered idx as noted above + + non_inf_expected_output = tf.convert_to_tensor( + [8.222099, 7.3534126, 8.432078, 7.4402075, 9.38451, 6.271159, 8.827531, 5.4402995, 7.3857956, 9.677023], + dtype=tf.float32, + ) # expected non filtered values as noted above + + output = tf_top_k_top_p_filtering(logits, top_k=10, top_p=0.6, min_tokens_to_keep=4) + + non_inf_output = output[output != -float("inf")] + non_inf_idx = tf.cast( + tf.where(tf.not_equal(output, tf.constant(-float("inf"), dtype=tf.float32))), + dtype=tf.int32, + ) + + tf.debugging.assert_near(non_inf_output, non_inf_expected_output, rtol=1e-12) + tf.debugging.assert_equal(non_inf_idx, non_inf_expected_idx) + + +@require_tf +class TFGenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMixin): + # setting framework_dependent_parameters needs to be gated, just like its contents' imports + if is_tf_available(): + framework_dependent_parameters = { + "AutoModelForCausalLM": TFAutoModelForCausalLM, + "AutoModelForSpeechSeq2Seq": TFAutoModelForSpeechSeq2Seq, + "AutoModelForSeq2SeqLM": TFAutoModelForSeq2SeqLM, + "AutoModelForVision2Seq": TFAutoModelForVision2Seq, + "LogitsProcessorList": TFLogitsProcessorList, + "MinLengthLogitsProcessor": TFMinLengthLogitsProcessor, + "create_tensor_fn": tf.convert_to_tensor, + "floats_tensor": floats_tensor, + "return_tensors": "tf", + } + + @slow + def test_generate_tf_function_export_fixed_input_length(self): + # TF-only test: tf.saved_model export + test_model = TFAutoModelForCausalLM.from_pretrained("hf-internal-testing/tiny-random-gpt2") + input_length = 2 + max_new_tokens = 2 + + class DummyModel(tf.Module): + def __init__(self, model): + super(DummyModel, self).__init__() + self.model = model + + @tf.function( + input_signature=( + tf.TensorSpec((None, input_length), tf.int32, name="input_ids"), + tf.TensorSpec((None, input_length), tf.int32, name="attention_mask"), + ), + jit_compile=True, + ) + def serving(self, input_ids, attention_mask): + outputs = self.model.generate( + input_ids=input_ids, + attention_mask=attention_mask, + max_new_tokens=max_new_tokens, + return_dict_in_generate=True, + ) + return {"sequences": outputs["sequences"]} + + dummy_input_ids = [[2, 0], [102, 103]] + dummy_attention_masks = [[1, 0], [1, 1]] + dummy_model = DummyModel(model=test_model) + with tempfile.TemporaryDirectory() as tmp_dir: + tf.saved_model.save(dummy_model, tmp_dir, signatures={"serving_default": dummy_model.serving}) + serving_func = tf.saved_model.load(tmp_dir).signatures["serving_default"] + for batch_size in range(1, len(dummy_input_ids) + 1): + inputs = { + "input_ids": tf.constant(dummy_input_ids[:batch_size]), + "attention_mask": tf.constant(dummy_attention_masks[:batch_size]), + } + tf_func_outputs = serving_func(**inputs)["sequences"] + tf_model_outputs = test_model.generate(**inputs, max_new_tokens=max_new_tokens) + tf.debugging.assert_equal(tf_func_outputs, tf_model_outputs) + + @slow + def test_generate_tf_function_export_fixed_batch_size(self): + # TF-only test: tf.saved_model export + test_model = TFAutoModelForCausalLM.from_pretrained("hf-internal-testing/tiny-random-gpt2") + batch_size = 1 + max_new_tokens = 2 + + class DummyModel(tf.Module): + def __init__(self, model): + super(DummyModel, self).__init__() + self.model = model + + @tf.function( + input_signature=( + tf.TensorSpec((batch_size, None), tf.int32, name="input_ids"), + tf.TensorSpec((batch_size, None), tf.int32, name="attention_mask"), + ), + jit_compile=True, + ) + def serving(self, input_ids, attention_mask): + outputs = self.model.generate( + input_ids=input_ids, + attention_mask=attention_mask, + max_new_tokens=max_new_tokens, + return_dict_in_generate=True, + ) + return {"sequences": outputs["sequences"]} + + dummy_input_ids = [[2], [102, 103]] + dummy_attention_masks = [[1], [1, 1]] + dummy_model = DummyModel(model=test_model) + with tempfile.TemporaryDirectory() as tmp_dir: + tf.saved_model.save(dummy_model, tmp_dir, signatures={"serving_default": dummy_model.serving}) + serving_func = tf.saved_model.load(tmp_dir).signatures["serving_default"] + for input_row in range(len(dummy_input_ids)): + inputs = { + "input_ids": tf.constant([dummy_input_ids[input_row]]), + "attention_mask": tf.constant([dummy_attention_masks[input_row]]), + } + tf_func_outputs = serving_func(**inputs)["sequences"] + tf_model_outputs = test_model.generate(**inputs, max_new_tokens=max_new_tokens) + tf.debugging.assert_equal(tf_func_outputs, tf_model_outputs) + + @slow + @require_tensorflow_text + def test_generate_tf_function_export_with_tf_tokenizer(self): + # TF-only test: tf.saved_model export + with tempfile.TemporaryDirectory() as tmp_dir: + # file needed to load the TF tokenizer + hf_hub_download(repo_id="google/flan-t5-small", filename="spiece.model", local_dir=tmp_dir) + + class CompleteSentenceTransformer(tf.keras.layers.Layer): + def __init__(self): + super().__init__() + self.tokenizer = text.SentencepieceTokenizer( + model=tf.io.gfile.GFile(os.path.join(tmp_dir, "spiece.model"), "rb").read() + ) + self.model = TFAutoModelForSeq2SeqLM.from_pretrained("hf-internal-testing/tiny-random-t5") + + def call(self, inputs, *args, **kwargs): + tokens = self.tokenizer.tokenize(inputs) + input_ids, attention_mask = text.pad_model_inputs( + tokens, max_seq_length=64, pad_value=self.model.config.pad_token_id + ) + outputs = self.model.generate(input_ids=input_ids, attention_mask=attention_mask) + return self.tokenizer.detokenize(outputs) + + complete_model = CompleteSentenceTransformer() + inputs = tf.keras.layers.Input(shape=(1,), dtype=tf.string, name="inputs") + outputs = complete_model(inputs) + keras_model = tf.keras.Model(inputs, outputs) + keras_model.save(tmp_dir) + + def test_eos_token_id_int_and_list_top_k_top_sampling(self): + # Has PT equivalent: this test relies on random sampling + generation_kwargs = { + "do_sample": True, + "num_beams": 1, + "top_p": 0.7, + "top_k": 10, + "temperature": 0.7, + } + expectation = 14 + + tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-random-gpt2") + text = """Hello, my dog is cute and""" + tokens = tokenizer(text, return_tensors="tf") + model = TFAutoModelForCausalLM.from_pretrained("hf-internal-testing/tiny-random-gpt2") + + eos_token_id = 638 + # forces the generation to happen on CPU, to avoid GPU-related quirks + with tf.device(":/CPU:0"): + tf.random.set_seed(0) + generated_tokens = model.generate(**tokens, eos_token_id=eos_token_id, **generation_kwargs) + self.assertTrue(expectation == len(generated_tokens[0])) + + eos_token_id = [638, 198] + with tf.device(":/CPU:0"): + tf.random.set_seed(0) + generated_tokens = model.generate(**tokens, eos_token_id=eos_token_id, **generation_kwargs) + self.assertTrue(expectation == len(generated_tokens[0])) + + def test_model_kwarg_encoder_signature_filtering(self): + # Has PT equivalent: ample use of framework-specific code + bart_tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-random-bart") + article = """Hugging Face is a technology company based in New York and Paris.""" + input_ids = bart_tokenizer(article, return_tensors="tf").input_ids + bart_model = TFBartForConditionalGeneration.from_pretrained("hf-internal-testing/tiny-random-bart") + output = bart_model.generate(input_ids).numpy() + + # Let's create a fake model that has a different signature. In particular, this fake model accepts "foo" as an + # argument. Because "foo" is not in the encoder signature and doesn't start with "decoder_", it will be part of + # the encoder kwargs prior to signature filtering, which would lead to an exception. But filtering kicks in and + # saves the day. + class FakeBart(TFBartForConditionalGeneration): + def call(self, input_ids, foo=None, **kwargs): + return super().call(input_ids, **kwargs) + + bart_model = FakeBart.from_pretrained("hf-internal-testing/tiny-random-bart") + fake_output = bart_model.generate(input_ids, foo="bar").numpy() + self.assertTrue(np.array_equal(output, fake_output)) + + # Encoder signature filtering only kicks in if it doesn't accept wildcard kwargs. The following test will fail + # because it doesn't do signature filtering. + class FakeEncoder(bart_model.model.encoder.__class__): + def call(self, input_ids, **kwargs): + return super().call(input_ids, **kwargs) + + fake_encoder = FakeEncoder(bart_model.config, bart_model.model.shared) + bart_model.model.encoder = fake_encoder + + # Normal generation still works (the output will be different because the encoder weights are different) + fake_output = bart_model.generate(input_ids).numpy() + with self.assertRaises(ValueError): + # FakeEncoder.call() accepts **kwargs -> no filtering -> value error due to unexpected input "foo" + bart_model.generate(input_ids, foo="bar") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/mixed_int8/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/mixed_int8/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/mixed_int8/test_mixed_int8.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/mixed_int8/test_mixed_int8.py new file mode 100644 index 0000000000000000000000000000000000000000..1628e08155d67e30900a1b6ad675e086348658a9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/mixed_int8/test_mixed_int8.py @@ -0,0 +1,689 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a clone of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import gc +import tempfile +import unittest + +from packaging import version + +from transformers import ( + AutoConfig, + AutoModel, + AutoModelForCausalLM, + AutoModelForSeq2SeqLM, + AutoModelForSequenceClassification, + AutoTokenizer, + BitsAndBytesConfig, + pipeline, +) +from transformers.testing_utils import ( + is_torch_available, + require_accelerate, + require_bitsandbytes, + require_torch, + require_torch_gpu, + require_torch_multi_gpu, + slow, +) +from transformers.utils.versions import importlib_metadata + + +if is_torch_available(): + import torch + import torch.nn as nn + + class LoRALayer(nn.Module): + """Wraps a linear layer with LoRA-like adapter - Used for testing purposes only""" + + def __init__(self, module: nn.Module, rank: int): + super().__init__() + self.module = module + self.adapter = nn.Sequential( + nn.Linear(module.in_features, rank, bias=False), + nn.Linear(rank, module.out_features, bias=False), + ) + small_std = (2.0 / (5 * min(module.in_features, module.out_features))) ** 0.5 + nn.init.normal_(self.adapter[0].weight, std=small_std) + nn.init.zeros_(self.adapter[1].weight) + self.adapter.to(module.weight.device) + + def forward(self, input, *args, **kwargs): + return self.module(input, *args, **kwargs) + self.adapter(input) + + +@require_bitsandbytes +@require_accelerate +@require_torch +@require_torch_gpu +@slow +class BaseMixedInt8Test(unittest.TestCase): + # We keep the constants inside the init function and model loading inside setUp function + + # We need to test on relatively large models (aka >1b parameters otherwise the quantiztion may not work as expected) + # Therefore here we use only bloom-1b3 to test our module + model_name = "bigscience/bloom-1b7" + + # Constant values + EXPECTED_RELATIVE_DIFFERENCE = ( + 1.540025 # This was obtained on a Quadro RTX 8000 so the number might slightly change + ) + + input_text = "Hello my name is" + EXPECTED_OUTPUT = "Hello my name is John.\nI am a friend of the family.\n" + MAX_NEW_TOKENS = 10 + + def setUp(self): + # Models and tokenizer + self.tokenizer = AutoTokenizer.from_pretrained(self.model_name) + + +class MixedInt8Test(BaseMixedInt8Test): + def setUp(self): + super().setUp() + + # Models and tokenizer + self.model_fp16 = AutoModelForCausalLM.from_pretrained( + self.model_name, torch_dtype=torch.float16, device_map="auto" + ) + self.model_8bit = AutoModelForCausalLM.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + + def tearDown(self): + r""" + TearDown function needs to be called at the end of each test to free the GPU memory and cache, also to + avoid unexpected behaviors. Please see: https://discuss.pytorch.org/t/how-can-we-release-gpu-memory-cache/14530/27 + """ + del self.model_fp16 + del self.model_8bit + + gc.collect() + torch.cuda.empty_cache() + + def test_memory_footprint(self): + r""" + A simple test to check if the model conversion has been done correctly by checking on the + memory footprint of the converted model and the class type of the linear layers of the converted models + """ + from bitsandbytes.nn import Int8Params + + mem_fp16 = self.model_fp16.get_memory_footprint() + mem_8bit = self.model_8bit.get_memory_footprint() + + self.assertAlmostEqual(mem_fp16 / mem_8bit, self.EXPECTED_RELATIVE_DIFFERENCE) + self.assertTrue(self.model_8bit.transformer.h[0].mlp.dense_4h_to_h.weight.__class__ == Int8Params) + + def test_generate_quality(self): + r""" + Test the generation quality of the quantized model and see that we are matching the expected output. + Given that we are operating on small numbers + the testing model is relatively small, we might not get + the same output across GPUs. So we'll generate few tokens (5-10) and check their output. + """ + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + output_sequences = self.model_8bit.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + self.assertEqual(self.tokenizer.decode(output_sequences[0], skip_special_tokens=True), self.EXPECTED_OUTPUT) + + def test_generate_quality_config(self): + r""" + Test that loading the model with the config is equivalent + """ + bnb_config = BitsAndBytesConfig() + + model_8bit_from_config = AutoModelForCausalLM.from_pretrained( + self.model_name, quantization_config=bnb_config, device_map="auto" + ) + + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + output_sequences = model_8bit_from_config.generate( + input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10 + ) + + self.assertEqual(self.tokenizer.decode(output_sequences[0], skip_special_tokens=True), self.EXPECTED_OUTPUT) + + def test_warns_save_pretrained(self): + r""" + Test whether trying to save a model after converting it in 8-bit will throw a warning. + """ + with self.assertWarns(UserWarning), tempfile.TemporaryDirectory() as tmpdirname: + self.model_8bit.save_pretrained(tmpdirname) + + def test_raise_if_config_and_load_in_8bit(self): + r""" + Test that loading the model with the config and `load_in_8bit` raises an error + """ + bnb_config = BitsAndBytesConfig() + + with self.assertRaises(ValueError): + _ = AutoModelForCausalLM.from_pretrained( + self.model_name, + quantization_config=bnb_config, + load_in_8bit=True, + device_map="auto", + llm_int8_enable_fp32_cpu_offload=True, + ) + + def test_device_and_dtype_assignment(self): + r""" + Test whether trying to cast (or assigning a device to) a model after converting it in 8-bit will throw an error. + Checks also if other models are casted correctly. + """ + with self.assertRaises(ValueError): + # Tries with `str` + self.model_8bit.to("cpu") + + with self.assertRaises(ValueError): + # Tries with a `dtype`` + self.model_8bit.to(torch.float16) + + with self.assertRaises(ValueError): + # Tries with a `device` + self.model_8bit.to(torch.device("cuda:0")) + + with self.assertRaises(ValueError): + # Tries with a `device` + self.model_8bit.float() + + with self.assertRaises(ValueError): + # Tries with a `device` + self.model_8bit.half() + + # Test if we did not break anything + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + + self.model_fp16 = self.model_fp16.to(torch.float32) + _ = self.model_fp16.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + # Check this does not throw an error + _ = self.model_fp16.to("cpu") + + # Check this does not throw an error + _ = self.model_fp16.half() + + # Check this does not throw an error + _ = self.model_fp16.float() + + def test_fp32_int8_conversion(self): + r""" + Test whether it is possible to mix both `int8` and `fp32` weights when using `keep_in_fp32_modules` correctly. + """ + model = AutoModelForSeq2SeqLM.from_pretrained("t5-small", load_in_8bit=True, device_map="auto") + self.assertTrue(model.decoder.block[0].layer[2].DenseReluDense.wo.weight.dtype == torch.float32) + + def test_int8_serialization(self): + r""" + Test whether it is possible to serialize a model in 8-bit. + """ + from bitsandbytes.nn import Int8Params + + with tempfile.TemporaryDirectory() as tmpdirname: + self.model_8bit.save_pretrained(tmpdirname) + + # check that the file `quantization_config` is present + config = AutoConfig.from_pretrained(tmpdirname) + self.assertTrue(hasattr(config, "quantization_config")) + + model_from_saved = AutoModelForCausalLM.from_pretrained(tmpdirname, load_in_8bit=True, device_map="auto") + + self.assertTrue(model_from_saved.transformer.h[0].mlp.dense_4h_to_h.weight.__class__ == Int8Params) + self.assertTrue(hasattr(model_from_saved.transformer.h[0].mlp.dense_4h_to_h.weight, "SCB")) + + # generate + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + output_sequences = model_from_saved.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + self.assertEqual( + self.tokenizer.decode(output_sequences[0], skip_special_tokens=True), self.EXPECTED_OUTPUT + ) + + def test_int8_serialization_sharded(self): + r""" + Test whether it is possible to serialize a model in 8-bit - sharded version. + """ + from bitsandbytes.nn import Int8Params + + with tempfile.TemporaryDirectory() as tmpdirname: + self.model_8bit.save_pretrained(tmpdirname, max_shard_size="200MB") + + # check that the file `quantization_config` is present + config = AutoConfig.from_pretrained(tmpdirname) + self.assertTrue(hasattr(config, "quantization_config")) + + model_from_saved = AutoModelForCausalLM.from_pretrained(tmpdirname) + + self.assertTrue(model_from_saved.transformer.h[0].mlp.dense_4h_to_h.weight.__class__ == Int8Params) + self.assertTrue(hasattr(model_from_saved.transformer.h[0].mlp.dense_4h_to_h.weight, "SCB")) + + # generate + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + output_sequences = model_from_saved.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + self.assertEqual( + self.tokenizer.decode(output_sequences[0], skip_special_tokens=True), self.EXPECTED_OUTPUT + ) + + def test_int8_from_pretrained(self): + r""" + Test whether loading a 8bit model from the Hub works as expected + """ + from bitsandbytes.nn import Int8Params + + model_id = "ybelkada/bloom-1b7-8bit" + + model = AutoModelForCausalLM.from_pretrained(model_id) + + self.assertTrue(model.transformer.h[0].mlp.dense_4h_to_h.weight.__class__ == Int8Params) + self.assertTrue(hasattr(model.transformer.h[0].mlp.dense_4h_to_h.weight, "SCB")) + + # generate + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + output_sequences = model.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + self.assertEqual(self.tokenizer.decode(output_sequences[0], skip_special_tokens=True), self.EXPECTED_OUTPUT) + + +@require_bitsandbytes +@require_accelerate +@require_torch +@require_torch_gpu +@slow +class MixedInt8T5Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.model_name = "t5-small" + cls.dense_act_model_name = "google/flan-t5-small" # flan-t5 uses dense-act instead of dense-relu-dense + cls.tokenizer = AutoTokenizer.from_pretrained(cls.model_name) + cls.input_text = "Translate in German: Hello, my dog is cute" + + def tearDown(self): + r""" + TearDown function needs to be called at the end of each test to free the GPU memory and cache, also to + avoid unexpected behaviors. Please see: https://discuss.pytorch.org/t/how-can-we-release-gpu-memory-cache/14530/27 + """ + gc.collect() + torch.cuda.empty_cache() + + def test_inference_without_keep_in_fp32(self): + r""" + Test whether it is possible to mix both `int8` and `fp32` weights when using `keep_in_fp32_modules` correctly. + `flan-t5-small` uses `T5DenseGatedActDense` whereas `t5-small` uses `T5DenseReluDense`. We need to test + both cases. + """ + from transformers import T5ForConditionalGeneration + + T5ForConditionalGeneration._keep_in_fp32_modules = None + + # test with `t5-small` + model = T5ForConditionalGeneration.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + # test with `flan-t5-small` + model = T5ForConditionalGeneration.from_pretrained( + self.dense_act_model_name, load_in_8bit=True, device_map="auto" + ) + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + def test_inference_with_keep_in_fp32(self): + r""" + Test whether it is possible to mix both `int8` and `fp32` weights when using `keep_in_fp32_modules` correctly. + `flan-t5-small` uses `T5DenseGatedActDense` whereas `t5-small` uses `T5DenseReluDense`. We need to test + both cases. + """ + import bitsandbytes as bnb + + from transformers import T5ForConditionalGeneration + + # test with `t5-small` + model = T5ForConditionalGeneration.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + + # there was a bug with decoders - this test checks that it is fixed + self.assertTrue(isinstance(model.decoder.block[0].layer[0].SelfAttention.q, bnb.nn.Linear8bitLt)) + + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + # test with `flan-t5-small` + model = T5ForConditionalGeneration.from_pretrained( + self.dense_act_model_name, load_in_8bit=True, device_map="auto" + ) + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + def test_inference_with_keep_in_fp32_serialized(self): + r""" + Test whether it is possible to mix both `int8` and `fp32` weights when using `keep_in_fp32_modules` correctly on + a serialized model. + `flan-t5-small` uses `T5DenseGatedActDense` whereas `t5-small` uses `T5DenseReluDense`. We need to test + both cases. + """ + import bitsandbytes as bnb + + from transformers import T5ForConditionalGeneration + + # test with `t5-small` + model = T5ForConditionalGeneration.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir) + + model = T5ForConditionalGeneration.from_pretrained(tmp_dir) + + # there was a bug with decoders - this test checks that it is fixed + self.assertTrue(isinstance(model.decoder.block[0].layer[0].SelfAttention.q, bnb.nn.Linear8bitLt)) + + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + # test with `flan-t5-small` + model = T5ForConditionalGeneration.from_pretrained( + self.dense_act_model_name, load_in_8bit=True, device_map="auto" + ) + encoded_input = self.tokenizer(self.input_text, return_tensors="pt").to(0) + _ = model.generate(**encoded_input) + + +class MixedInt8ModelClassesTest(BaseMixedInt8Test): + def setUp(self): + super().setUp() + # model_name + self.model_name = "bigscience/bloom-560m" + self.seq_to_seq_name = "t5-small" + + # Different types of model + + self.base_model = AutoModel.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + # Sequence classification model + self.sequence_model = AutoModelForSequenceClassification.from_pretrained( + self.model_name, load_in_8bit=True, device_map="auto" + ) + # CausalLM model + self.model_8bit = AutoModelForCausalLM.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + # Seq2seq model + self.seq_to_seq_model = AutoModelForSeq2SeqLM.from_pretrained( + self.seq_to_seq_name, load_in_8bit=True, device_map="auto" + ) + + def tearDown(self): + r""" + TearDown function needs to be called at the end of each test to free the GPU memory and cache, also to + avoid unexpected behaviors. Please see: https://discuss.pytorch.org/t/how-can-we-release-gpu-memory-cache/14530/27 + """ + del self.base_model + del self.sequence_model + del self.model_8bit + del self.seq_to_seq_model + + gc.collect() + torch.cuda.empty_cache() + + def test_correct_head_class(self): + r""" + A simple test to check if the last modules for some classes (AutoModelForCausalLM or SequenceClassification) + are kept in their native class. + """ + from bitsandbytes.nn import Int8Params + + # last param of a base model should be a linear8bit module + self.assertTrue(self.base_model.h[-1].mlp.dense_4h_to_h.weight.__class__ == Int8Params) + + # Other heads should be nn.Parameter + self.assertTrue(self.model_8bit.lm_head.weight.__class__ == torch.nn.Parameter) + self.assertTrue(self.sequence_model.score.weight.__class__ == torch.nn.Parameter) + self.assertTrue(self.seq_to_seq_model.lm_head.weight.__class__ == torch.nn.Parameter) + + +class MixedInt8TestPipeline(BaseMixedInt8Test): + def setUp(self): + super().setUp() + + def tearDown(self): + r""" + TearDown function needs to be called at the end of each test to free the GPU memory and cache, also to + avoid unexpected behaviors. Please see: https://discuss.pytorch.org/t/how-can-we-release-gpu-memory-cache/14530/27 + """ + del self.pipe + + gc.collect() + torch.cuda.empty_cache() + + def test_pipeline(self): + r""" + The aim of this test is to verify that the mixed int8 is compatible with `pipeline` from transformers. Since + we used pipline for inference speed benchmarking we want to make sure that this feature does not break anything + on pipline. + """ + # self._clear_cuda_cache() + self.pipe = pipeline( + "text-generation", + model=self.model_name, + model_kwargs={"device_map": "auto", "load_in_8bit": True}, + max_new_tokens=self.MAX_NEW_TOKENS, + ) + + # Real second forward pass + pipeline_output = self.pipe(self.input_text) + self.assertEqual(pipeline_output[0]["generated_text"], self.EXPECTED_OUTPUT) + + +@require_torch_multi_gpu +class MixedInt8TestMultiGpu(BaseMixedInt8Test): + def setUp(self): + super().setUp() + + def test_multi_gpu_loading(self): + r""" + This tests that the model has been loaded and can be used correctly on a multi-GPU setup. + Let's just try to load a model on 2 GPUs and see if it works. The model we test has ~2GB of total, 3GB should suffice + """ + + model_parallel = AutoModelForCausalLM.from_pretrained( + self.model_name, load_in_8bit=True, device_map="balanced" + ) + + # Check correct device map + self.assertEqual(set(model_parallel.hf_device_map.values()), {0, 1}) + + # Check that inference pass works on the model + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + + # Second real batch + output_parallel = model_parallel.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + self.assertEqual(self.tokenizer.decode(output_parallel[0], skip_special_tokens=True), self.EXPECTED_OUTPUT) + + +@require_torch_multi_gpu +class MixedInt8TestCpuGpu(BaseMixedInt8Test): + def setUp(self): + super().setUp() + + def check_inference_correctness(self, model): + # Check that inference pass works on the model + encoded_input = self.tokenizer(self.input_text, return_tensors="pt") + + # Check the exactness of the results + output_parallel = model.generate(input_ids=encoded_input["input_ids"].to(0), max_new_tokens=10) + + # Get the generation + output_text = self.tokenizer.decode(output_parallel[0], skip_special_tokens=True) + self.assertEqual(output_text, self.EXPECTED_OUTPUT) + + def test_cpu_gpu_loading_random_device_map(self): + r""" + A test to check is dispatching a model on cpu & gpu works correctly using a random `device_map`. + """ + device_map = { + "transformer.word_embeddings": 0, + "transformer.word_embeddings_layernorm": 0, + "lm_head": 0, + "transformer.h.0": "cpu", + "transformer.h.1": "cpu", + "transformer.h.2": 0, + "transformer.h.3": 0, + "transformer.h.4": 0, + "transformer.h.5": 0, + "transformer.h.6": 0, + "transformer.h.7": 0, + "transformer.h.8": 0, + "transformer.h.9": 1, + "transformer.h.10": 0, + "transformer.h.11": 1, + "transformer.h.12": 0, + "transformer.h.13": 0, + "transformer.h.14": 1, + "transformer.h.15": 0, + "transformer.h.16": 0, + "transformer.h.17": 1, + "transformer.h.18": 1, + "transformer.h.19": 0, + "transformer.h.20": 1, + "transformer.h.21": 1, + "transformer.h.22": 0, + "transformer.h.23": 0, + "transformer.ln_f": 1, + } + + bnb_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True) + + model_8bit = AutoModelForCausalLM.from_pretrained( + self.model_name, + device_map=device_map, + quantization_config=bnb_config, + ) + + # Check that the model has been correctly set on device 0, 1, and `cpu`. + self.assertEqual(set(model_8bit.hf_device_map.values()), {0, 1, "cpu"}) + + self.check_inference_correctness(model_8bit) + + def test_cpu_gpu_loading_custom_device_map(self): + r""" + A test to check is dispatching a model on cpu & gpu works correctly using a custom `device_map`. + This time the device map is more organized than the test above and uses the abstraction + `transformer.h` to encapsulate all the decoder layers. + """ + device_map = { + "transformer.word_embeddings": "cpu", + "transformer.word_embeddings_layernorm": "cpu", + "lm_head": "cpu", + "transformer.h": 0, + "transformer.ln_f": 1, + } + bnb_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True) + + # Load model + model_8bit = AutoModelForCausalLM.from_pretrained( + self.model_name, + device_map=device_map, + quantization_config=bnb_config, + ) + + # Check that the model has been correctly set on device 0, 1, and `cpu`. + self.assertEqual(set(model_8bit.hf_device_map.values()), {0, 1, "cpu"}) + + self.check_inference_correctness(model_8bit) + + def test_cpu_gpu_disk_loading_custom_device_map(self): + r""" + A test to check is dispatching a model on cpu & gpu works correctly using a custom `device_map`. + This time we also add `disk` on the device_map. + """ + device_map = { + "transformer.word_embeddings": 0, + "transformer.word_embeddings_layernorm": "cpu", + "lm_head": 0, + "transformer.h": 1, + "transformer.ln_f": "disk", + } + bnb_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True) + with tempfile.TemporaryDirectory() as tmpdirname: + # Load model + model_8bit = AutoModelForCausalLM.from_pretrained( + self.model_name, + device_map=device_map, + quantization_config=bnb_config, + offload_folder=tmpdirname, + ) + + # Check that the model has been correctly set on device 0, 1, and `cpu`. + self.assertEqual(set(model_8bit.hf_device_map.values()), {0, 1, "cpu", "disk"}) + + self.check_inference_correctness(model_8bit) + + def test_cpu_gpu_disk_loading_custom_device_map_kwargs(self): + r""" + A test to check is dispatching a model on cpu & gpu works correctly using a custom `device_map`. + This time we also add `disk` on the device_map - using the kwargs directly instead of the quantization config + """ + device_map = { + "transformer.word_embeddings": 0, + "transformer.word_embeddings_layernorm": "cpu", + "lm_head": 0, + "transformer.h": 1, + "transformer.ln_f": "disk", + } + with tempfile.TemporaryDirectory() as tmpdirname: + # Load model + model_8bit = AutoModelForCausalLM.from_pretrained( + self.model_name, + device_map=device_map, + llm_int8_enable_fp32_cpu_offload=True, + offload_folder=tmpdirname, + ) + + # Check that the model has been correctly set on device 0, 1, and `cpu`. + self.assertEqual(set(model_8bit.hf_device_map.values()), {0, 1, "cpu", "disk"}) + + self.check_inference_correctness(model_8bit) + + +class MixedInt8TestTraining(BaseMixedInt8Test): + def setUp(self): + self.model_name = "facebook/opt-350m" + super().setUp() + + def test_training(self): + if version.parse(importlib_metadata.version("bitsandbytes")) < version.parse("0.37.0"): + return + + # Step 1: freeze all parameters + model = AutoModelForCausalLM.from_pretrained(self.model_name, load_in_8bit=True, device_map="auto") + + for param in model.parameters(): + param.requires_grad = False # freeze the model - train adapters later + if param.ndim == 1: + # cast the small parameters (e.g. layernorm) to fp32 for stability + param.data = param.data.to(torch.float32) + + # Step 2: add adapters + for _, module in model.named_modules(): + if "OPTAttention" in repr(type(module)): + module.q_proj = LoRALayer(module.q_proj, rank=16) + module.k_proj = LoRALayer(module.k_proj, rank=16) + module.v_proj = LoRALayer(module.v_proj, rank=16) + + # Step 3: dummy batch + batch = self.tokenizer("Test batch ", return_tensors="pt").to(0) + + # Step 4: Check if the gradient is not None + with torch.cuda.amp.autocast(): + out = model.forward(**batch) + out.logits.norm().backward() + + for module in model.modules(): + if isinstance(module, LoRALayer): + self.assertTrue(module.adapter[1].weight.grad is not None) + self.assertTrue(module.adapter[1].weight.grad.norm().item() > 0) + elif isinstance(module, nn.Embedding): + self.assertTrue(module.weight.grad is None) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/albert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/albert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/albert/test_modeling_albert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/albert/test_modeling_albert.py new file mode 100644 index 0000000000000000000000000000000000000000..96fa5596a21d15a90c0c92f5b520f552d7b7eb2a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/albert/test_modeling_albert.py @@ -0,0 +1,344 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import AlbertConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_PRETRAINING_MAPPING, + AlbertForMaskedLM, + AlbertForMultipleChoice, + AlbertForPreTraining, + AlbertForQuestionAnswering, + AlbertForSequenceClassification, + AlbertForTokenClassification, + AlbertModel, + ) + from transformers.models.albert.modeling_albert import ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST + + +class AlbertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + embedding_size=16, + hidden_size=36, + num_hidden_layers=6, + num_hidden_groups=6, + num_attention_heads=6, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.embedding_size = embedding_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_hidden_groups = num_hidden_groups + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return AlbertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + num_hidden_groups=self.num_hidden_groups, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = AlbertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_pretraining( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = AlbertForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + sentence_order_label=sequence_labels, + ) + self.parent.assertEqual(result.prediction_logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + self.parent.assertEqual(result.sop_logits.shape, (self.batch_size, config.num_labels)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = AlbertForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = AlbertForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = AlbertForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = AlbertForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = AlbertForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class AlbertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + AlbertModel, + AlbertForPreTraining, + AlbertForMaskedLM, + AlbertForMultipleChoice, + AlbertForSequenceClassification, + AlbertForTokenClassification, + AlbertForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": AlbertModel, + "fill-mask": AlbertForMaskedLM, + "question-answering": AlbertForQuestionAnswering, + "text-classification": AlbertForSequenceClassification, + "token-classification": AlbertForTokenClassification, + "zero-shot": AlbertForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + inputs_dict["sentence_order_label"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = AlbertModelTester(self) + self.config_tester = ConfigTester(self, config_class=AlbertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ALBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = AlbertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class AlbertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = AlbertModel.from_pretrained("albert-base-v2") + input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) + attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + with torch.no_grad(): + output = model(input_ids, attention_mask=attention_mask)[0] + expected_shape = torch.Size((1, 11, 768)) + self.assertEqual(output.shape, expected_shape) + expected_slice = torch.tensor( + [[[-0.6513, 1.5035, -0.2766], [-0.6515, 1.5046, -0.2780], [-0.6512, 1.5049, -0.2784]]] + ) + + self.assertTrue(torch.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/align/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/align/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/altclip/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/altclip/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bloom/test_modeling_bloom.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bloom/test_modeling_bloom.py new file mode 100644 index 0000000000000000000000000000000000000000..617998cc61b30440d1bc0fce15da17191c38b1cf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bloom/test_modeling_bloom.py @@ -0,0 +1,807 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import math +import unittest + +from transformers import BloomConfig, is_torch_available +from transformers.testing_utils import require_torch, require_torch_gpu, slow, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + BLOOM_PRETRAINED_MODEL_ARCHIVE_LIST, + BloomForCausalLM, + BloomForQuestionAnswering, + BloomForSequenceClassification, + BloomForTokenClassification, + BloomModel, + BloomTokenizerFast, + ) + from transformers.pytorch_utils import is_torch_greater_or_equal_than_1_10 +else: + is_torch_greater_or_equal_than_1_10 = False + + +@require_torch +class BloomModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=False, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_dropout_prob = attention_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def get_large_model_config(self): + return BloomConfig.from_pretrained("bigscience/bloom") + + def prepare_config_and_inputs(self, gradient_checkpointing=False): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config(gradient_checkpointing=gradient_checkpointing) + + return (config, input_ids, input_mask, sequence_labels) + + def get_config(self, gradient_checkpointing=False, slow_but_exact=True): + return BloomConfig( + vocab_size=self.vocab_size, + seq_length=self.seq_length, + hidden_size=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + hidden_dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + num_labels=self.num_labels, + gradient_checkpointing=gradient_checkpointing, + slow_but_exact=slow_but_exact, + dtype="float32", + ) + + def create_and_check_bloom_model(self, config, input_ids, input_mask, *args): + model = BloomModel(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_bloom_model_past(self, config, input_ids, input_mask, *args): + model = BloomModel(config=config) + + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, attention_mask=torch.ones_like(input_ids), use_cache=True) + outputs_use_cache_conf = model(input_ids, attention_mask=torch.ones_like(input_ids)) + outputs_no_past = model(input_ids, use_cache=False, attention_mask=torch.ones_like(input_ids)) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + past = outputs["past_key_values"] + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + + output_from_no_past = model(next_input_ids)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_bloom_model_attention_mask_past(self, config, input_ids, input_mask, *args): + model = BloomModel(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_bloom_model_past_large_inputs(self, config, input_ids, input_mask, *args): + model = BloomModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past)[ + "last_hidden_state" + ] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, *args): + model = BloomForCausalLM(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_sequence_classification_model(self, config, input_ids, input_mask, *args): + config.num_labels = self.num_labels + model = BloomForSequenceClassification(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_token_classification_model(self, config, input_ids, input_mask, *args): + model = BloomForTokenClassification(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_question_answering_model(self, config, input_ids, input_mask, *args): + model = BloomForQuestionAnswering(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, *args, gradient_checkpointing=False + ): + model = BloomForCausalLM(config) + model.to(torch_device) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + + result = model(input_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def create_and_check_bloom_weight_initialization(self, config, *args): + model = BloomModel(config) + model_std = model.config.initializer_range / math.sqrt(2 * model.config.n_layer) + for key in model.state_dict().keys(): + if "c_proj" in key and "weight" in key: + self.parent.assertLessEqual(abs(torch.std(model.state_dict()[key]) - model_std), 0.001) + self.parent.assertLessEqual(abs(torch.mean(model.state_dict()[key]) - 0.0), 0.01) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + config, input_ids, input_mask, sequence_labels = config_and_inputs + + inputs_dict = {"input_ids": input_ids} + + return config, inputs_dict + + +@require_torch +class BloomModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + BloomModel, + BloomForCausalLM, + BloomForSequenceClassification, + BloomForTokenClassification, + BloomForQuestionAnswering, + ) + if is_torch_available() + else () + ) + + all_generative_model_classes = (BloomForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": BloomModel, + "question-answering": BloomForQuestionAnswering, + "text-classification": BloomForSequenceClassification, + "text-generation": BloomForCausalLM, + "token-classification": BloomForTokenClassification, + "zero-shot": BloomForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + test_missing_keys = False + test_pruning = False + test_torchscript = True # torch.autograd functions seems to be not supported + + def setUp(self): + self.model_tester = BloomModelTester(self) + self.config_tester = ConfigTester(self, config_class=BloomConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_bloom_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_bloom_model(*config_and_inputs) + + def test_bloom_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_bloom_model_past(*config_and_inputs) + + def test_bloom_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_bloom_model_attention_mask_past(*config_and_inputs) + + def test_bloom_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_bloom_model_past_large_inputs(*config_and_inputs) + + def test_bloom_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_bloom_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_sequence_classification_model(*config_and_inputs) + + def test_bloom_token_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_token_classification_model(*config_and_inputs) + + def test_bloom_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + def test_bloom_weight_initialization(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_bloom_weight_initialization(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in BLOOM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = BloomModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + @require_torch_gpu + def test_simple_generation(self): + # This test is a bit flaky. For some GPU architectures, pytorch sets by default allow_fp16_reduced_precision_reduction = True and some operations + # do not give the same results under this configuration, especially torch.baddmm and torch.bmm. https://pytorch.org/docs/stable/notes/numerical_accuracy.html#fp16-on-mi200 + # As we leave the default value (True) for allow_fp16_reduced_precision_reduction , the tests failed when running in half-precision with smaller models (560m) + # Please see: https://pytorch.org/docs/stable/notes/cuda.html#reduced-precision-reduction-in-fp16-gemms + # This discrepancy is observed only when using small models and seems to be stable for larger models. + # Our conclusion is that these operations are flaky for small inputs but seems to be stable for larger inputs (for the functions `baddmm` and `bmm`), and therefore for larger models. + + # Here is a summary of an ablation study of our observations + # EXPECTED_OUTPUT = "I enjoy walking with my cute dog, and I love to watch the kids play. I am a very active person, and I am a very good listener. I am a very good person, and I am a very good person. I am a" + # 560m + allow_fp16_reduced_precision_reduction = False + torch.bmm ==> PASS + # 560m + allow_fp16_reduced_precision_reduction = False + torch.baddm ==> PASS + # 560m + allow_fp16_reduced_precision_reduction = True + torch.baddm ==> PASS + # 560m + allow_fp16_reduced_precision_reduction = True + torch.bmm ==> FAIL + + # EXPECTED_OUTPUT = "I enjoy walking with my cute dog, but I also enjoy hiking, biking, and swimming. I love to cook and bake. I love to cook and bake. I love to cook and bake. I love to cook and bake. I love" + # >=1b1 + allow_fp16_reduced_precision_reduction = True + torch.baddm ==> PASS (for use_cache=True and use_cache=False) + # >=1b1 + allow_fp16_reduced_precision_reduction = True + torch.bmm ==> PASS + # >=1b1 + allow_fp16_reduced_precision_reduction = False + torch.bmm ==> PASS + + path_560m = "bigscience/bloom-560m" + model = BloomForCausalLM.from_pretrained(path_560m, use_cache=True, revision="gs555750").cuda() + model = model.eval() + tokenizer = BloomTokenizerFast.from_pretrained(path_560m) + + input_sentence = "I enjoy walking with my cute dog" + # This output has been obtained using fp32 model on the huggingface DGX workstation - NVIDIA A100 GPU + EXPECTED_OUTPUT = ( + "I enjoy walking with my cute dog, and I love to watch the kids play with the kids. I am a very " + "active person, and I enjoy working out, and I am a very active person. I am a very active person, and I" + ) + + input_ids = tokenizer.encode(input_sentence, return_tensors="pt") + greedy_output = model.generate(input_ids.cuda(), max_length=50) + + self.assertEqual(tokenizer.decode(greedy_output[0], skip_special_tokens=True), EXPECTED_OUTPUT) + + @slow + @require_torch_gpu + def test_batch_generation(self): + path_560m = "bigscience/bloom-560m" + model = BloomForCausalLM.from_pretrained(path_560m, use_cache=True, revision="gs555750").cuda() + model = model.eval() + tokenizer = BloomTokenizerFast.from_pretrained(path_560m, padding_side="left") + + input_sentence = ["I enjoy walking with my cute dog", "I enjoy walking with my cute dog"] + + input_ids = tokenizer.batch_encode_plus(input_sentence, return_tensors="pt", padding=True) + greedy_output = model.generate( + input_ids["input_ids"].cuda(), attention_mask=input_ids["attention_mask"], max_length=50, do_sample=False + ) + + self.assertEqual( + tokenizer.decode(greedy_output[0], skip_special_tokens=True), + tokenizer.decode(greedy_output[1], skip_special_tokens=True), + ) + + @slow + @require_torch_gpu + def test_batch_generation_padd(self): + path_560m = "bigscience/bloom-560m" + model = BloomForCausalLM.from_pretrained(path_560m, use_cache=True, revision="gs555750").cuda() + model = model.eval() + tokenizer = BloomTokenizerFast.from_pretrained(path_560m, padding_side="left") + + input_sentence = ["I enjoy walking with my cute dog", "Hello my name is"] + input_sentence_without_pad = "Hello my name is" + + input_ids = tokenizer.batch_encode_plus(input_sentence, return_tensors="pt", padding=True) + input_ids_without_pad = tokenizer.encode(input_sentence_without_pad, return_tensors="pt") + + greedy_output = model.generate( + input_ids["input_ids"].cuda(), attention_mask=input_ids["attention_mask"], max_length=50, do_sample=False + ) + greedy_output_without_pad = model.generate(input_ids_without_pad.cuda(), max_length=50, do_sample=False) + + # test token values + self.assertEqual(greedy_output[-1, 3:].tolist(), greedy_output_without_pad[0, :-3].tolist()) + + # test reconstructions + self.assertEqual( + tokenizer.decode(greedy_output[-1, 3:], skip_special_tokens=True), + tokenizer.decode(greedy_output_without_pad[0, :-3], skip_special_tokens=True), + ) + + +@require_torch +class BloomEmbeddingTest(unittest.TestCase): + """ + The goal here is to compare the embeddings generated by the model trained + using Megatron-LM with the one from the transformers library, with a small GPT2-like model + to ensure that the conversion from Megatron-LM to transformers has been done successfully. + The script compares the logits of the embedding layer and the transformer layers. + + WARNING: It is expected that these logits will not have exactly the same statistics when running + the code on CPU or GPU. For more info, please visit: + - https://github.com/pytorch/pytorch/issues/76052#issuecomment-1103193548 + - https://discuss.pytorch.org/t/reproducibility-issue-between-intel-and-amd-cpus/144779/9 + + + You need to install tokenizers following this readme: + - https://huggingface.co/bigscience-catalogue-data-dev/byte-level-bpe-tokenizer-no-norm-250k-whitespace-and-eos-regex-alpha-v3-dedup-lines-articles + + Tokenizer used during training: + - https://huggingface.co/bigscience-catalogue-data-dev/byte-level-bpe-tokenizer-no-norm-250k-whitespace-and-eos-regex-alpha-v3-dedup-lines-articles + + # TODO change the script (or just add skip) when building the env with tokenizers 0.12.0 + """ + + def setUp(self): + super().setUp() + self.path_bigscience_model = "bigscience/bigscience-small-testing" + + @unittest.skipIf( + not is_torch_greater_or_equal_than_1_10, + "Test failed with torch < 1.10 (`LayerNormKernelImpl` not implemented for `BFloat16`)", + ) + @require_torch + def test_embeddings(self): + # The config in this checkpoint has `bfloat16` as `torch_dtype` -> model in `bfloat16` + model = BloomForCausalLM.from_pretrained(self.path_bigscience_model, torch_dtype="auto") + model.eval() + + EMBEDDINGS_DS_BEFORE_LN_BF_16_MEAN = { + 3478: 0.0002307891845703125, + 368: -0.000568389892578125, + 109586: -0.0003910064697265625, + 35433: -0.000194549560546875, + 2: 0.0004138946533203125, + 77: 0.000659942626953125, + 132619: -0.00031280517578125, + 2175: 0.000457763671875, + 23714: 0.000263214111328125, + 73173: -0.000286102294921875, + 144252: 0.00052642822265625, + } + EMBEDDINGS_DS_BEFORE_LN_BF_16_MIN = { + 3478: -0.00921630859375, + 368: -0.010009765625, + 109586: -0.01031494140625, + 35433: -0.01177978515625, + 2: -0.0074462890625, + 77: -0.00848388671875, + 132619: -0.009521484375, + 2175: -0.0074462890625, + 23714: -0.0145263671875, + 73173: -0.007415771484375, + 144252: -0.01007080078125, + } + EMBEDDINGS_DS_BEFORE_LN_BF_16_MAX = { + 3478: 0.0128173828125, + 368: 0.01214599609375, + 109586: 0.0111083984375, + 35433: 0.01019287109375, + 2: 0.0157470703125, + 77: 0.0174560546875, + 132619: 0.0078125, + 2175: 0.0113525390625, + 23714: 0.0146484375, + 73173: 0.01116943359375, + 144252: 0.01141357421875, + } + EMBEDDINGS_DS_BEFORE_LN_BF_16_SUM = {"value": 0.08203125} + + EMBEDDINGS_DS_BEFORE_LN_F_16_MEAN = { + 132619: -0.00031256675720214844, + 3478: 0.00023090839385986328, + 368: -0.0005702972412109375, + 109586: -0.00039124488830566406, + 35433: -0.000194549560546875, + 2: 0.0004146099090576172, + 2175: 0.0004572868347167969, + 23714: 0.00026416778564453125, + 73173: -0.0002865791320800781, + 144252: 0.0005254745483398438, + 77: 0.0006618499755859375, + } + EMBEDDINGS_DS_BEFORE_LN_F_16_MIN = { + 3478: -0.00921630859375, + 368: -0.010009765625, + 109586: -0.01031494140625, + 35433: -0.01177978515625, + 2: -0.0074462890625, + 77: -0.00848388671875, + 132619: -0.009521484375, + 2175: -0.0074462890625, + 23714: -0.0145263671875, + 73173: -0.007415771484375, + 144252: -0.01007080078125, + } + EMBEDDINGS_DS_BEFORE_LN_F_16_MAX = { + 3478: 0.0128173828125, + 368: 0.01214599609375, + 109586: 0.0111083984375, + 35433: 0.01019287109375, + 2: 0.0157470703125, + 77: 0.0174560546875, + 132619: 0.0078125, + 2175: 0.0113525390625, + 23714: 0.0146484375, + 73173: 0.01116943359375, + 144252: 0.01141357421875, + } + EMBEDDINGS_DS_BEFORE_LN_F_16_SUM = {"value": 0.0821533203125} + + EMBEDDINGS_DS_BEFORE_LN_F_32_MEAN = { + 132619: -0.00031267106533050537, + 3478: 0.00023087859153747559, + 368: -0.0005701072514057159, + 109586: -0.0003911703824996948, + 35433: -0.0001944899559020996, + 2: 0.0004146844148635864, + 2175: 0.00045740045607089996, + 23714: 0.0002641640603542328, + 73173: -0.0002864748239517212, + 144252: 0.0005256589502096176, + 77: 0.0006617321632802486, + } + EMBEDDINGS_DS_BEFORE_LN_F_32_MIN = { + 3478: -0.00921630859375, + 368: -0.010009765625, + 109586: -0.01031494140625, + 35433: -0.01177978515625, + 2: -0.0074462890625, + 77: -0.00848388671875, + 132619: -0.009521484375, + 2175: -0.0074462890625, + 23714: -0.0145263671875, + 73173: -0.007415771484375, + 144252: -0.01007080078125, + } + EMBEDDINGS_DS_BEFORE_LN_F_32_MAX = { + 3478: 0.0128173828125, + 368: 0.01214599609375, + 109586: 0.0111083984375, + 35433: 0.01019287109375, + 2: 0.0157470703125, + 77: 0.0174560546875, + 132619: 0.0078125, + 2175: 0.0113525390625, + 23714: 0.0146484375, + 73173: 0.01116943359375, + 144252: 0.01141357421875, + } + EMBEDDINGS_DS_BEFORE_LN_F_32_SUM = {"value": 0.08217757940292358} + + TEST_EMBEDDINGS = { + "torch.bfloat16": { + "mean": EMBEDDINGS_DS_BEFORE_LN_BF_16_MEAN, + "max": EMBEDDINGS_DS_BEFORE_LN_BF_16_MAX, + "min": EMBEDDINGS_DS_BEFORE_LN_BF_16_MIN, + "sum": EMBEDDINGS_DS_BEFORE_LN_BF_16_SUM, + }, + "torch.float32": { + "mean": EMBEDDINGS_DS_BEFORE_LN_F_32_MEAN, + "max": EMBEDDINGS_DS_BEFORE_LN_F_32_MAX, + "min": EMBEDDINGS_DS_BEFORE_LN_F_32_MIN, + "sum": EMBEDDINGS_DS_BEFORE_LN_F_32_SUM, + }, + "torch.float": { + "mean": EMBEDDINGS_DS_BEFORE_LN_F_32_MEAN, + "max": EMBEDDINGS_DS_BEFORE_LN_F_32_MAX, + "min": EMBEDDINGS_DS_BEFORE_LN_F_32_MIN, + "sum": EMBEDDINGS_DS_BEFORE_LN_F_32_SUM, + }, + "torch.float16": { + "mean": EMBEDDINGS_DS_BEFORE_LN_F_16_MEAN, + "max": EMBEDDINGS_DS_BEFORE_LN_F_16_MAX, + "min": EMBEDDINGS_DS_BEFORE_LN_F_16_MIN, + "sum": EMBEDDINGS_DS_BEFORE_LN_F_16_SUM, + }, + } + + # fmt: off + EXAMPLE_IDS = [3478, 368, 109586, 35433, 2, 77, 132619, 3478, 368, 109586, 35433, 2, 2175, 23714, 73173, 144252, 2, 77, 132619, 3478] + # fmt: on + + EMBEDDINGS_DS_AFTER_LN_MEAN = { + 3478: -6.580352783203125e-05, + 368: 0.0001316070556640625, + 109586: -0.00030517578125, + 35433: 4.00543212890625e-05, + 2: -7.2479248046875e-05, + 77: -8.96453857421875e-05, + 132619: 0.0001583099365234375, + 2175: 2.1219253540039062e-05, + 23714: -0.000247955322265625, + 73173: -0.00021839141845703125, + 144252: -0.0001430511474609375, + } + EMBEDDINGS_DS_AFTER_LN_MIN = { + 3478: -1.6953125, + 368: -1.6875, + 109586: -1.6875, + 35433: -2.125, + 2: -1.390625, + 77: -1.5390625, + 132619: -1.875, + 2175: -1.4609375, + 23714: -2.296875, + 73173: -1.3515625, + 144252: -1.78125, + } + EMBEDDINGS_DS_AFTER_LN_MAX = { + 3478: 2.265625, + 368: 2.28125, + 109586: 1.953125, + 35433: 1.90625, + 2: 2.703125, + 77: 2.828125, + 132619: 1.65625, + 2175: 2.015625, + 23714: 2.234375, + 73173: 2.171875, + 144252: 1.828125, + } + + EMBEDDINGS_DS_AFTER_LN = { + "mean": EMBEDDINGS_DS_AFTER_LN_MEAN, + "min": EMBEDDINGS_DS_AFTER_LN_MIN, + "max": EMBEDDINGS_DS_AFTER_LN_MAX, + } + + tensor_ids = torch.LongTensor([EXAMPLE_IDS]) + with torch.no_grad(): + embeddings = model.transformer.word_embeddings(tensor_ids) + embeddings_ln = model.transformer.word_embeddings_layernorm(embeddings) # + # first check the embeddings before LN + output_dict = {"min": {}, "max": {}, "mean": {}, "sum": {"value": embeddings.sum().item()}} + for i, idx in enumerate(EXAMPLE_IDS): + output_dict["min"][idx] = embeddings.min(dim=-1).values[0][i].item() + output_dict["max"][idx] = embeddings.max(dim=-1).values[0][i].item() + output_dict["mean"][idx] = embeddings.mean(dim=-1)[0][i].item() + + for key in TEST_EMBEDDINGS[str(model.dtype)].keys(): + self.assertDictEqual(TEST_EMBEDDINGS[str(model.dtype)][key], output_dict[key]) + + output_dict_norm = {"min": {}, "max": {}, "mean": {}} + for i, idx in enumerate(EXAMPLE_IDS): + output_dict_norm["min"][idx] = embeddings_ln.min(dim=-1).values[0][i].item() + output_dict_norm["max"][idx] = embeddings_ln.max(dim=-1).values[0][i].item() + output_dict_norm["mean"][idx] = embeddings_ln.mean(dim=-1)[0][i].item() + + # This test does not pass when places = 2 + for i, key in enumerate(output_dict_norm.keys()): + for j, idx in enumerate(output_dict[key].keys()): + self.assertAlmostEqual(EMBEDDINGS_DS_AFTER_LN[key][idx], output_dict_norm[key][idx], places=1) + + @require_torch + def test_hidden_states_transformers(self): + cuda_available = torch.cuda.is_available() + model = BloomModel.from_pretrained(self.path_bigscience_model, use_cache=False, torch_dtype="auto").to( + torch_device + ) + model.eval() + + # fmt: off + EXAMPLE_IDS = [3478, 368, 109586, 35433, 2, 77, 132619, 3478, 368, 109586, 35433, 2, 2175, 23714, 73173, 144252, 2, 77, 132619, 3478] + # fmt: on + + MEAN_VALUE_LAST_LM = -4.3392181396484375e-05 + MIN_MAX_DICT = {"min": -2.0625, "max": 2.75} + tensor_ids = torch.LongTensor([EXAMPLE_IDS]) + + with torch.no_grad(): + logits = model(tensor_ids.to(torch_device)) + output_dict = { + "min": logits.last_hidden_state.min(dim=-1).values[0][0].item(), + "max": logits.last_hidden_state.max(dim=-1).values[0][0].item(), + } + + if cuda_available: + self.assertAlmostEqual(MEAN_VALUE_LAST_LM, logits.last_hidden_state.mean().item(), places=4) + else: + self.assertAlmostEqual(MEAN_VALUE_LAST_LM, logits.last_hidden_state.mean().item(), places=3) + + self.assertDictEqual(MIN_MAX_DICT, output_dict) + + @require_torch + def test_logits(self): + cuda_available = torch.cuda.is_available() + model = BloomForCausalLM.from_pretrained(self.path_bigscience_model, use_cache=False, torch_dtype="auto").to( + torch_device + ) # load in bf16 + model.eval() + + # fmt: off + EXAMPLE_IDS = [3478, 368, 109586, 35433, 2, 77, 132619, 3478, 368, 109586, 35433, 2, 2175, 23714, 73173, 144252, 2, 77, 132619, 3478] + # fmt: on + + MEAN_LOGITS_GPU_1 = -1.823902130126953e-05 + MEAN_LOGITS_GPU_2 = 1.9431114196777344e-05 + + tensor_ids = torch.LongTensor([EXAMPLE_IDS]).to(torch_device) + with torch.no_grad(): + output = model(tensor_ids).logits + + output_gpu_1, output_gpu_2 = output.split(125440, dim=-1) + if cuda_available: + self.assertAlmostEqual(output_gpu_1.mean().item(), MEAN_LOGITS_GPU_1, places=6) + self.assertAlmostEqual(output_gpu_2.mean().item(), MEAN_LOGITS_GPU_2, places=6) + else: + self.assertAlmostEqual(output_gpu_1.mean().item(), MEAN_LOGITS_GPU_1, places=6) # 1e-06 precision!! + self.assertAlmostEqual(output_gpu_2.mean().item(), MEAN_LOGITS_GPU_2, places=6) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bort/test_modeling_bort.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bort/test_modeling_bort.py new file mode 100644 index 0000000000000000000000000000000000000000..79ca940801074981d90cfdce8780f14ad3c4304e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bort/test_modeling_bort.py @@ -0,0 +1,51 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device + + +if is_torch_available(): + import torch + + from transformers import AutoModel + + +@require_torch +@require_sentencepiece +@require_tokenizers +class BortIntegrationTest(unittest.TestCase): + @slow + def test_output_embeds_base_model(self): + model = AutoModel.from_pretrained("amazon/bort") + model.to(torch_device) + + input_ids = torch.tensor( + [[0, 18077, 4082, 7804, 8606, 6195, 2457, 3321, 11, 10489, 16, 269, 2579, 328, 2]], + device=torch_device, + dtype=torch.long, + ) # Schloß Nymphenburg in Munich is really nice! + output = model(input_ids)["last_hidden_state"] + expected_shape = torch.Size((1, 15, 1024)) + self.assertEqual(output.shape, expected_shape) + # compare the actual values for a slice. + expected_slice = torch.tensor( + [[[-0.0349, 0.0436, -1.8654], [-0.6964, 0.0835, -1.7393], [-0.9819, 0.2956, -0.2868]]], + device=torch_device, + dtype=torch.float, + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bridgetower/test_modeling_bridgetower.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bridgetower/test_modeling_bridgetower.py new file mode 100644 index 0000000000000000000000000000000000000000..1a4d34d3967f98226f965b7c9474abd829705c20 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/bridgetower/test_modeling_bridgetower.py @@ -0,0 +1,656 @@ +# coding=utf-8 +# Copyright 2023 The Intel Labs Team Authors, The Microsoft Research Team Authors and HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch BridgeTower model. """ + +import tempfile +import unittest + +import numpy as np + +from transformers import ( + BridgeTowerConfig, + BridgeTowerTextConfig, + BridgeTowerVisionConfig, + is_torch_available, + is_vision_available, +) +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + BridgeTowerForContrastiveLearning, + BridgeTowerForImageAndTextRetrieval, + BridgeTowerForMaskedLM, + BridgeTowerModel, + ) + from transformers.models.bridgetower.modeling_bridgetower import BRIDGETOWER_PRETRAINED_MODEL_ARCHIVE_LIST + from transformers.pytorch_utils import is_torch_greater_or_equal_than_1_10 +else: + is_torch_greater_or_equal_than_1_10 = False + +if is_vision_available(): + from PIL import Image + + from transformers import BridgeTowerProcessor + + +class BridgeTowerTextModelTester: + def __init__( + self, + parent, + hidden_act="gelu", + hidden_size=128, + initializer_factor=1, + layer_norm_eps=1e-05, + num_attention_heads=4, + num_hidden_layers=2, + intermediate_size=256, + tie_word_embeddings=False, + output_hidden_states=False, + ): + self.parent = parent + self.hidden_act = hidden_act + self.hidden_size = hidden_size + self.initializer_factor = initializer_factor + self.layer_norm_eps = layer_norm_eps + self.num_attention_heads = num_attention_heads + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.tie_word_embeddings = tie_word_embeddings + self.vocab_size = 99 + self.seq_length = 4 + self.batch_size = 1 + self.is_training = False + self.output_hidden_states = output_hidden_states + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = self.get_config() + + return config, input_ids, attention_mask + + def get_config(self): + return BridgeTowerTextConfig( + hidden_act=self.hidden_act, + hidden_size=self.hidden_size, + initializer_factor=self.initializer_factor, + layer_norm_eps=self.layer_norm_eps, + num_attention_heads=self.num_attention_heads, + num_hidden_layers=self.num_hidden_layers, + intermediate_size=self.intermediate_size, + tie_word_embeddings=self.tie_word_embeddings, + output_hidden_states=self.output_hidden_states, + ) + + +class BridgeTowerImageModelTester: + def __init__( + self, + parent, + hidden_size=128, + initializer_factor=1, + layer_norm_eps=1e-05, + num_hidden_layers=2, + init_layernorm_from_vision_encoder=False, + output_hidden_states=False, + image_size=64, + ): + self.parent = parent + self.hidden_size = hidden_size + self.initializer_factor = initializer_factor + self.layer_norm_eps = layer_norm_eps + self.num_hidden_layers = num_hidden_layers + self.init_layernorm_from_vision_encoder = init_layernorm_from_vision_encoder + self.num_channels = 3 + self.num_image_features = 17 + self.batch_size = 1 + self.image_size = image_size + self.is_training = False + self.output_hidden_states = output_hidden_states + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + pixel_mask = random_attention_mask([self.batch_size, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values, pixel_mask + + def get_config(self): + return BridgeTowerVisionConfig( + hidden_size=self.hidden_size, + initializer_factor=self.initializer_factor, + layer_norm_eps=self.layer_norm_eps, + num_hidden_layers=self.num_hidden_layers, + init_layernorm_from_vision_encoder=self.init_layernorm_from_vision_encoder, + num_channels=self.num_channels, + num_image_features=self.num_image_features, + batch_size=self.batch_size, + image_size=self.image_size, + is_training=self.is_training, + output_hidden_states=self.output_hidden_states, + ) + + +class BridgeTowerModelTester: + def __init__( + self, + parent, + text_kwargs=None, + vision_kwargs=None, + share_cross_modal_transformer_layers=True, + share_link_tower_layers=False, + link_tower_type="add", + init_layernorm_from_vision_encoder=False, + contrastive_hidden_size=512, + logit_scale_init_value=2.6592, + hidden_size=128, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=256, + ): + if text_kwargs is None: + text_kwargs = {} + if vision_kwargs is None: + vision_kwargs = {} + + self.parent = parent + self.text_model_tester = BridgeTowerTextModelTester(parent, **text_kwargs) + self.vision_model_tester = BridgeTowerImageModelTester(parent, **vision_kwargs) + + self.share_cross_modal_transformer_layers = share_cross_modal_transformer_layers + self.share_link_tower_layers = share_link_tower_layers + self.link_tower_type = link_tower_type + self.init_layernorm_from_vision_encoder = init_layernorm_from_vision_encoder + self.contrastive_hidden_size = contrastive_hidden_size + self.logit_scale_init_value = logit_scale_init_value + + self.batch_size = 1 + self.expected_num_hidden_layers = 8 + self.is_training = False + + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values, pixel_mask = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return (config, input_ids, attention_mask, pixel_values, pixel_mask) + + def get_config(self): + return BridgeTowerConfig.from_text_vision_configs( + text_config=self.text_model_tester.get_config(), + vision_config=self.vision_model_tester.get_config(), + share_cross_modal_transformer_layers=self.share_cross_modal_transformer_layers, + share_link_tower_layers=self.share_link_tower_layers, + link_tower_type=self.link_tower_type, + init_layernorm_from_vision_encoder=self.init_layernorm_from_vision_encoder, + contrastive_hidden_size=self.contrastive_hidden_size, + logit_scale_init_value=self.logit_scale_init_value, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + ) + + def create_and_check_model( + self, + config, + input_ids, + attention_mask, + pixel_values, + pixel_mask, + ): + model = BridgeTowerModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values) + self.parent.assertEqual( + result["text_features"].shape, + (self.batch_size, self.text_model_tester.seq_length, self.text_model_tester.hidden_size), + ) + self.parent.assertEqual( + result["image_features"].shape, + (self.batch_size, self.vision_model_tester.num_image_features, self.vision_model_tester.hidden_size), + ) + self.parent.assertEqual( + result["pooler_output"].shape, + (self.batch_size, self.text_model_tester.hidden_size + self.vision_model_tester.hidden_size), + ) + + def create_and_check_for_image_and_text_retrieval( + self, + config, + input_ids, + attention_mask, + pixel_values, + pixel_mask, + ): + bridgetower_itm_output_last_dimension = 2 + + model = BridgeTowerForImageAndTextRetrieval(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, bridgetower_itm_output_last_dimension)) + + def create_and_check_for_masked_language_modeling( + self, + config, + input_ids, + attention_mask, + pixel_values, + pixel_mask, + ): + model = BridgeTowerForMaskedLM(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(input_ids, attention_mask=attention_mask, pixel_values=pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.text_model_tester.seq_length, 50265)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + (config, input_ids, attention_mask, pixel_values, pixel_mask) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "pixel_mask": pixel_mask, + } + return config, inputs_dict + + +@require_torch +@unittest.skipIf(not is_torch_greater_or_equal_than_1_10, "BridgeTower is only available in torch v1.10+") +class BridgeTowerModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + BridgeTowerModel, + BridgeTowerForImageAndTextRetrieval, + BridgeTowerForMaskedLM, + BridgeTowerForContrastiveLearning, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = {"feature-extraction": BridgeTowerModel} if is_torch_available() else {} + + is_training = False + test_headmasking = False + test_pruning = False + test_torchscript = False + test_resize_embeddings = False + has_attentions = False + + @unittest.skip(reason="Does not work on the tiny model as we keep hitting edge cases.") + def test_cpu_offload(self): + pass + + @unittest.skip(reason="Does not work on the tiny model as we keep hitting edge cases.") + def test_disk_offload(self): + pass + + @unittest.skip(reason="Does not work on the tiny model as we keep hitting edge cases.") + def test_model_parallelism(self): + pass + + # function to extract meaningful tensor from output per different model_class + def extract_output(self, outputs, model_class): + return outputs["pooler_output"] if model_class == "BridgeTowerModel" else outputs["logits"] + + def setUp(self): + self.model_tester = BridgeTowerModelTester(self) + self.config_tester = ConfigTester(self, config_class=BridgeTowerConfig, hidden_size=37, vocab_size=99) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_and_text_retrieval(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_and_text_retrieval(*config_and_inputs) + + def test_for_masked_language_modeling(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_language_modeling(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in BRIDGETOWER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = BridgeTowerModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_save_load_fast_init_from_base(self): + # Override as it is a slow test on this model + super().test_save_load_fast_init_from_base() + + # Override as extracting meaningful tensor from output is different for BridgeTower + def test_save_load(self): + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**input_dict) + + out_2 = self.extract_output(outputs, model_class.__name__) + out_2 = out_2.cpu().numpy() + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model = model_class.from_pretrained(tmpdirname) + model.to(torch_device) + with torch.no_grad(): + after_outputs = model(**input_dict) + + # Make sure we don't have nans + out_1 = self.extract_output(after_outputs, model_class.__name__) + out_1 = out_1.cpu().numpy() + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + # Override this as `hidden states output` is different for BridgeTower + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states_text, hidden_states_vision, hidden_states_cross = ( + outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + ) + + expected_num_layers = self.model_tester.expected_num_hidden_layers + self.assertEqual( + sum((len(hidden_states_text), len(hidden_states_vision), len(hidden_states_cross))), + expected_num_layers, + ) + + seq_length = self.model_tester.text_model_tester.seq_length + num_image_features = self.model_tester.vision_model_tester.num_image_features + + self.assertListEqual( + list(hidden_states_text[0].shape[-2:]), + [seq_length, self.model_tester.text_model_tester.hidden_size], + ) + self.assertListEqual( + list(hidden_states_vision[0].shape), + [num_image_features, 1, self.model_tester.vision_model_tester.hidden_size], + ) + self.assertListEqual( + list(hidden_states_cross[0][0].shape[-2:]), + [seq_length, self.model_tester.text_model_tester.hidden_size], + ) + self.assertListEqual( + list(hidden_states_cross[0][1].shape[-2:]), + [num_image_features, self.model_tester.vision_model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + check_hidden_states_output(inputs_dict, config, model_class) + + # Override as `hidden states output` is different for BridgeTower + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0][0] + hidden_states.retain_grad() + + if self.has_attentions: + attentions = outputs.attentions[0][0] + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + + if self.has_attentions: + self.assertIsNotNone(attentions.grad) + + # override as the `logit_scale` parameter initilization is different for BRIDGE TOWER + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + if name == "logit_scale": + self.assertAlmostEqual( + param.data.item(), + config.logit_scale_init_value, + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + @unittest.skip(reason="""Bridge Tower does not have input/output embeddings. So this test is not applicable.""") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="""Bridge Tower does not have input/output embeddings. Thus this test is not applicable.""") + def test_inputs_embeds(self): + pass + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +@unittest.skipIf(not is_torch_greater_or_equal_than_1_10, "BridgeTower is only available in torch v1.10+") +class BridgeTowerModelIntegrationTest(unittest.TestCase): + @cached_property + def default_processor(self): + return ( + BridgeTowerProcessor.from_pretrained("BridgeTower/bridgetower-base-itm-mlm") + if is_vision_available() + else None + ) + + @slow + def test_image_and_text_retrieval(self): + model = BridgeTowerForImageAndTextRetrieval.from_pretrained("BridgeTower/bridgetower-base-itm-mlm").to( + torch_device + ) + model.eval() + processor = self.default_processor + image = prepare_img() + text = "a bunch of cats laying on a tower." + inputs = processor(image, text, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size([1, 2]) + self.assertEqual(outputs.logits.shape, expected_shape) + self.assertTrue(outputs.logits[0, 1].item() > outputs.logits[0, 0].item()) + + # verify loss + inputs["labels"] = torch.ones(1, dtype=torch.long, device=torch_device) + inputs = inputs.to(torch_device) + with torch.no_grad(): + outputs = model(**inputs) + self.assertAlmostEqual(outputs.loss.item(), 0.5108, places=4) + + @slow + def test_masked_language_modeling(self): + model = BridgeTowerForMaskedLM.from_pretrained("BridgeTower/bridgetower-base-itm-mlm").to(torch_device) + model.eval() + processor = self.default_processor + image = prepare_img() + text = "a bunch of laying on a tower." + inputs = processor(image, text, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size([1, 11, 50265]) + self.assertEqual(outputs.logits.shape, expected_shape) + + # verify predicted word + predicted_id = outputs.logits.argmax(dim=-1).squeeze(0).tolist()[4] + self.assertTrue(processor.decode([predicted_id]) == " cats") + + # verify loss + inputs["labels"] = inputs["input_ids"].clone() + inputs = inputs.to(torch_device) + with torch.no_grad(): + outputs = model(**inputs) + self.assertAlmostEqual(outputs.loss.item(), 5.7373, places=4) + + @slow + def test_constrastive_learning(self): + model = BridgeTowerForContrastiveLearning.from_pretrained("BridgeTower/bridgetower-large-itm-mlm-itc").to( + torch_device + ) + model.eval() + processor = BridgeTowerProcessor.from_pretrained("BridgeTower/bridgetower-large-itm-mlm-itc") + image = prepare_img() + text = "a bunch of cats laying on a tower." + inputs = processor(image, text, padding=True, return_tensors="pt").to(torch_device) + with torch.no_grad(): + outputs = model(**inputs, output_hidden_states=True, return_loss=True) + + # verify the logits + expected_shape = torch.Size([1, 3, 512]) + self.assertEqual(outputs.logits.shape, expected_shape) + + +@slow +@require_torch +@unittest.skipIf(not is_torch_greater_or_equal_than_1_10, "BridgeTower is only available in torch v1.10+") +class BridgeTowerModelTrainingTest(unittest.TestCase): + all_training_supported_model_classes = ( + (BridgeTowerForImageAndTextRetrieval, BridgeTowerForMaskedLM, BridgeTowerForContrastiveLearning) + if is_torch_available() + else () + ) + + def setUp(self): + self.model_tester = BridgeTowerModelTester(self) + self.config_tester = ConfigTester(self, config_class=BridgeTowerConfig, hidden_size=37, vocab_size=99) + + def _prepare_inputs_for_training(self, model_class): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if model_class == BridgeTowerForMaskedLM: + inputs_dict["labels"] = inputs_dict["input_ids"] + elif model_class == BridgeTowerForImageAndTextRetrieval: + inputs_dict["labels"] = ids_tensor([1], 2) + elif model_class == BridgeTowerForContrastiveLearning: + inputs_dict["return_loss"] = True + return config, inputs_dict + + def _get_non_used_layer_names(self, model_class): + non_used_layer_names = ["text_model.pooler"] + if model_class == BridgeTowerForMaskedLM: + non_used_layer_names = non_used_layer_names + [ + "cross_modal_image_layers.5", + "cross_modal_image_pooler", + "cross_modal_text_pooler", + ] + return non_used_layer_names + + def _is_layer_used(self, model_class, layer_name): + non_used_layer_names = self._get_non_used_layer_names(model_class) + for non_used_layer_name in non_used_layer_names: + if non_used_layer_name in layer_name: + return False + return True + + def test_training(self): + for model_class in self.all_training_supported_model_classes: + config, inputs_dict = self._prepare_inputs_for_training(model_class) + model = model_class(config) + model.to(torch_device) + model.train() + + loss = model(**inputs_dict).loss + loss.backward() + + # verify the gradients of used layers' weight are not None + for name, param in model.named_parameters(): + if self._is_layer_used(model_class, name): + self.assertIsNotNone(param.grad, f"Gradients should not be None - got {param.grad} for {name}") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/camembert/test_tokenization_camembert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/camembert/test_tokenization_camembert.py new file mode 100644 index 0000000000000000000000000000000000000000..6acabc7bf25dd7883cc08dac1f53297cc421c441 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/camembert/test_tokenization_camembert.py @@ -0,0 +1,129 @@ +# coding=utf-8 +# Copyright 2018 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import CamembertTokenizer, CamembertTokenizerFast +from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow +from transformers.utils import is_torch_available + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") +SAMPLE_BPE_VOCAB = get_tests_dir("fixtures/test_sentencepiece_bpe.model") + +FRAMEWORK = "pt" if is_torch_available() else "tf" + + +@require_sentencepiece +@require_tokenizers +class CamembertTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = CamembertTokenizer + rust_tokenizer_class = CamembertTokenizerFast + test_rust_tokenizer = True + test_sentencepiece = True + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = CamembertTokenizer(SAMPLE_VOCAB) + tokenizer.save_pretrained(self.tmpdirname) + + def test_convert_token_and_id(self): + """Test ``_convert_token_to_id`` and ``_convert_id_to_token``.""" + token = "" + token_id = 1 + + self.assertEqual(self.get_tokenizer()._convert_token_to_id(token), token_id) + self.assertEqual(self.get_tokenizer()._convert_id_to_token(token_id), token) + + def test_get_vocab(self): + vocab_keys = list(self.get_tokenizer().get_vocab().keys()) + + self.assertEqual(vocab_keys[0], "NOTUSED") + self.assertEqual(vocab_keys[1], "") + self.assertEqual(vocab_keys[-1], "") + self.assertEqual(len(vocab_keys), 1_004) + + def test_vocab_size(self): + self.assertEqual(self.get_tokenizer().vocab_size, 1_005) + + def test_rust_and_python_bpe_tokenizers(self): + tokenizer = CamembertTokenizer(SAMPLE_BPE_VOCAB) + tokenizer.save_pretrained(self.tmpdirname) + rust_tokenizer = CamembertTokenizerFast.from_pretrained(self.tmpdirname) + + sequence = "I was born in 92000, and this is falsé." + + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + # tokens are not the same for `rust` than for `slow`. + # Because spm gives back raw token instead of `unk` in EncodeAsPieces + # tokens = tokenizer.tokenize(sequence) + tokens = tokenizer.convert_ids_to_tokens(ids) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence = "I was born in 92000, and this is falsé." + + tokens = tokenizer.tokenize(sequence) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + rust_tokenizer = self.get_rust_tokenizer() + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + @slow + def test_tokenizer_integration(self): + # fmt: off + expected_encoding = {'input_ids': [[5, 54, 7196, 297, 30, 23, 776, 18, 11, 3215, 3705, 8252, 22, 3164, 1181, 2116, 29, 16, 813, 25, 791, 3314, 20, 3446, 38, 27575, 120, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [5, 468, 17, 11, 9088, 20, 1517, 8, 22804, 18818, 10, 38, 629, 607, 607, 142, 19, 7196, 867, 56, 10326, 24, 2267, 20, 416, 5072, 15612, 233, 734, 7, 2399, 27, 16, 3015, 1649, 7, 24, 20, 4338, 2399, 27, 13, 3400, 14, 13, 6189, 8, 930, 9, 6]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]} # noqa: E501 + # fmt: on + + # camembert is a french model. So we also use french texts. + sequences = [ + "Le transformeur est un modèle d'apprentissage profond introduit en 2017, " + "utilisé principalement dans le domaine du traitement automatique des langues (TAL).", + "À l'instar des réseaux de neurones récurrents (RNN), les transformeurs sont conçus " + "pour gérer des données séquentielles, telles que le langage naturel, pour des tâches " + "telles que la traduction et la synthèse de texte.", + ] + + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="camembert-base", + revision="3a0641d9a1aeb7e848a74299e7e4c4bca216b4cf", + sequences=sequences, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/canine/test_modeling_canine.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/canine/test_modeling_canine.py new file mode 100644 index 0000000000000000000000000000000000000000..d612a02bf47c673d3208aa31442e7a0e8a41a059 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/canine/test_modeling_canine.py @@ -0,0 +1,549 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CANINE model. """ + + +import unittest +from typing import List, Tuple + +from transformers import CanineConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, global_rng, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + CanineForMultipleChoice, + CanineForQuestionAnswering, + CanineForSequenceClassification, + CanineForTokenClassification, + CanineModel, + ) + from transformers.models.canine.modeling_canine import CANINE_PRETRAINED_MODEL_ARCHIVE_LIST + + +class CanineModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + # let's use a vocab size that's way bigger than BERT's one + vocab_size=100000, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor(input_ids.shape, self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return CanineConfig( + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = CanineModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = CanineForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = CanineForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = CanineForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = CanineForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class CanineModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + CanineModel, + CanineForMultipleChoice, + CanineForQuestionAnswering, + CanineForSequenceClassification, + CanineForTokenClassification, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": CanineModel, + "question-answering": CanineForQuestionAnswering, + "text-classification": CanineForSequenceClassification, + "token-classification": CanineForTokenClassification, + "zero-shot": CanineForSequenceClassification, + } + if is_torch_available() + else {} + ) + + test_mismatched_shapes = False + test_resize_embeddings = False + test_pruning = False + + def setUp(self): + self.model_tester = CanineModelTester(self) + # we set has_text_modality to False as the config has no vocab_size attribute + self.config_tester = ConfigTester(self, config_class=CanineConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + # expected_num_layers equals num_hidden_layers of the deep encoder + 1, + 2 for the first shallow encoder, + 2 + # for the final shallow encoder + expected_num_layers = self.model_tester.num_hidden_layers + 1 + 2 + 2 + self.assertEqual(len(hidden_states), expected_num_layers) + + seq_length = self.model_tester.seq_length + for i in range(expected_num_layers): + if (i < 2) or ((expected_num_layers - i) < 3): + # the expected length of the hidden_states of the first and final shallow encoders + # is equal to the seq_length + self.assertListEqual( + list(hidden_states[i].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + else: + # the expected length of the hidden_states of the deep encoder need to be updated + # for CANINE since the seq length is downsampled + self.assertListEqual( + list(hidden_states[i].shape[-2:]), + [seq_length // config.downsampling_rate, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + # we add + 2 due to the 2 shallow encoders + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers + 2) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + # we add + 2 due to the 2 shallow encoders + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers + 2) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_len, seq_len], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers + 2) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_len, seq_len], + ) + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def set_nan_tensor_to_zero(t): + t[t != t] = 0 + return t + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + with torch.no_grad(): + tuple_output = model(**tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(**dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + torch.allclose( + set_nan_tensor_to_zero(tuple_object), set_nan_tensor_to_zero(dict_object), atol=1e-5 + ), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {torch.max(torch.abs(tuple_object - dict_object))}. Tuple has `nan`:" + f" {torch.isnan(tuple_object).any()} and `inf`: {torch.isinf(tuple_object)}. Dict has" + f" `nan`: {torch.isnan(dict_object).any()} and `inf`: {torch.isinf(dict_object)}." + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + print(model_class) + model = model_class(config) + model.to(torch_device) + model.eval() + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence( + model, tuple_inputs, dict_inputs, {"output_hidden_states": True, "output_attentions": True} + ) + + def test_headmasking(self): + if not self.test_head_masking: + return + + global_rng.seed(42) + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + global_rng.seed() + + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + # Prepare head_mask + # Set require_grad after having prepared the tensor to avoid error (leaf variable has been moved into the graph interior) + head_mask = torch.ones( + self.model_tester.num_hidden_layers, + self.model_tester.num_attention_heads, + device=torch_device, + ) + head_mask[0, 0] = 0 + head_mask[-1, :-1] = 0 + head_mask.requires_grad_(requires_grad=True) + inputs = self._prepare_for_class(inputs_dict, model_class).copy() + inputs["head_mask"] = head_mask + + outputs = model(**inputs, return_dict=True) + + # Test that we can get a gradient back for importance score computation + output = sum(t.sum() for t in outputs[0]) + output = output.sum() + output.backward() + multihead_outputs = head_mask.grad + + self.assertIsNotNone(multihead_outputs) + self.assertEqual(len(multihead_outputs), self.model_tester.num_hidden_layers) + + def check_attentions_validity(attentions): + # Remove Nan + for t in attentions: + self.assertLess( + torch.sum(torch.isnan(t)), t.numel() / 4 + ) # Check we don't have more than 25% nans (arbitrary) + attentions = [ + t.masked_fill(torch.isnan(t), 0.0) for t in attentions + ] # remove them (the test is less complete) + + self.assertAlmostEqual(attentions[1][..., 0, :, :].flatten().sum().item(), 0.0) + self.assertNotEqual(attentions[1][..., -1, :, :].flatten().sum().item(), 0.0) + self.assertAlmostEqual(attentions[-2][..., -2, :, :].flatten().sum().item(), 0.0) + self.assertNotEqual(attentions[-2][..., -1, :, :].flatten().sum().item(), 0.0) + + check_attentions_validity(outputs.attentions) + + @unittest.skip("CANINE does not have a get_input_embeddings() method.") + def test_inputs_embeds(self): + # ViT does not use inputs_embeds + pass + + @unittest.skip("CANINE does not have a get_input_embeddings() method.") + def test_model_common_attributes(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CANINE_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CanineModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class CanineModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head(self): + model = CanineModel.from_pretrained("google/canine-s") + # this one corresponds to the first example of the TydiQA dev set (in Swahili) + # fmt: off + input_ids = [57344, 57349, 85, 107, 117, 98, 119, 97, 32, 119, 97, 32, 82, 105, 106, 105, 108, 105, 32, 75, 97, 110, 116, 111, 114, 105, 32, 110, 105, 32, 107, 105, 97, 115, 105, 32, 103, 97, 110, 105, 63, 57345, 57350, 32, 82, 105, 106, 105, 108, 105, 32, 75, 97, 110, 116, 111, 114, 105, 32, 44, 32, 82, 105, 106, 105, 108, 105, 32, 75, 97, 110, 116, 97, 114, 117, 115, 105, 32, 97, 117, 32, 105, 110, 103, 46, 32, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 40, 112, 105, 97, 58, 32, 84, 111, 108, 105, 109, 97, 110, 32, 97, 117, 32, 82, 105, 103, 105, 108, 32, 75, 101, 110, 116, 97, 117, 114, 117, 115, 41, 32, 110, 105, 32, 110, 121, 111, 116, 97, 32, 105, 110, 97, 121, 111, 110, 103, 39, 97, 97, 32, 115, 97, 110, 97, 32, 107, 97, 116, 105, 107, 97, 32, 97, 110, 103, 97, 32, 121, 97, 32, 107, 117, 115, 105, 110, 105, 32, 107, 119, 101, 110, 121, 101, 32, 107, 117, 110, 100, 105, 110, 121, 111, 116, 97, 32, 121, 97, 32, 75, 97, 110, 116, 97, 114, 117, 115, 105, 32, 40, 112, 105, 97, 58, 32, 105, 110, 103, 46, 32, 67, 101, 110, 116, 97, 117, 114, 117, 115, 41, 46, 32, 78, 105, 32, 110, 121, 111, 116, 97, 32, 121, 97, 32, 107, 117, 110, 103, 97, 97, 32, 115, 97, 110, 97, 32, 121, 97, 32, 110, 110, 101, 32, 97, 110, 103, 97, 110, 105, 32, 108, 97, 107, 105, 110, 105, 32, 104, 97, 105, 111, 110, 101, 107, 97, 110, 105, 32, 107, 119, 101, 110, 121, 101, 32, 110, 117, 115, 117, 100, 117, 110, 105, 97, 32, 121, 97, 32, 107, 97, 115, 107, 97, 122, 105, 110, 105, 46, 32, 57351, 32, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 110, 105, 32, 110, 121, 111, 116, 97, 32, 121, 97, 32, 112, 101, 107, 101, 101, 32, 107, 119, 97, 32, 115, 97, 98, 97, 98, 117, 32, 110, 105, 32, 110, 121, 111, 116, 97, 32, 121, 101, 116, 117, 32, 106, 105, 114, 97, 110, 105, 32, 107, 97, 116, 105, 107, 97, 32, 97, 110, 103, 97, 32, 105, 110, 97, 32, 117, 109, 98, 97, 108, 105, 32, 119, 97, 32, 109, 105, 97, 107, 97, 32, 121, 97, 32, 110, 117, 114, 117, 32, 52, 46, 50, 46, 32, 73, 110, 97, 111, 110, 101, 107, 97, 110, 97, 32, 97, 110, 103, 97, 110, 105, 32, 107, 97, 114, 105, 98, 117, 32, 110, 97, 32, 107, 117, 110, 100, 105, 110, 121, 111, 116, 97, 32, 121, 97, 32, 83, 97, 108, 105, 98, 117, 32, 40, 67, 114, 117, 120, 41, 46, 32, 57352, 32, 82, 105, 106, 105, 108, 105, 32, 75, 97, 110, 116, 97, 114, 117, 115, 105, 32, 40, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 41, 32, 105, 110, 97, 111, 110, 101, 107, 97, 110, 97, 32, 107, 97, 109, 97, 32, 110, 121, 111, 116, 97, 32, 109, 111, 106, 97, 32, 108, 97, 107, 105, 110, 105, 32, 107, 119, 97, 32, 100, 97, 114, 117, 98, 105, 110, 105, 32, 107, 117, 98, 119, 97, 32, 105, 110, 97, 111, 110, 101, 107, 97, 110, 97, 32, 107, 117, 119, 97, 32, 109, 102, 117, 109, 111, 32, 119, 97, 32, 110, 121, 111, 116, 97, 32, 116, 97, 116, 117, 32, 122, 105, 110, 97, 122, 111, 107, 97, 97, 32, 107, 97, 114, 105, 98, 117, 32, 110, 97, 32, 107, 117, 115, 104, 105, 107, 97, 109, 97, 110, 97, 32, 107, 97, 116, 105, 32, 121, 97, 111, 46, 32, 78, 121, 111, 116, 97, 32, 109, 97, 112, 97, 99, 104, 97, 32, 122, 97, 32, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 65, 32, 110, 97, 32, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 66, 32, 122, 105, 107, 111, 32, 109, 105, 97, 107, 97, 32, 121, 97, 32, 110, 117, 114, 117, 32, 52, 46, 51, 54, 32, 107, 117, 116, 111, 107, 97, 32, 107, 119, 101, 116, 117, 32, 110, 97, 32, 110, 121, 111, 116, 97, 32, 121, 97, 32, 116, 97, 116, 117, 32, 65, 108, 112, 104, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 67, 32, 97, 117, 32, 80, 114, 111, 120, 105, 109, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 105, 110, 97, 32, 117, 109, 98, 97, 108, 105, 32, 119, 97, 32, 109, 105, 97, 107, 97, 32, 121, 97, 32, 110, 117, 114, 117, 32, 52, 46, 50, 50, 46, 32, 57353, 32, 80, 114, 111, 120, 105, 109, 97, 32, 67, 101, 110, 116, 97, 117, 114, 105, 32, 40, 121, 97, 97, 110, 105, 32, 110, 121, 111, 116, 97, 32, 121, 97, 32, 75, 97, 110, 116, 97, 114, 117, 115, 105, 32, 105, 108, 105, 121, 111, 32, 107, 97, 114, 105, 98, 117, 32, 122, 97, 105, 100, 105, 32, 110, 97, 115, 105, 41, 32, 105, 109, 101, 103, 117, 110, 100, 117, 108, 105, 119, 97, 32, 107, 117, 119, 97, 32, 110, 97, 32, 115, 97, 121, 97, 114, 105, 32, 109, 111, 106, 97, 46, 32, 86, 105, 112, 105, 109, 111, 32, 118, 105, 110, 97, 118, 121, 111, 112, 97, 116, 105, 107, 97, 110, 97, 32, 104, 97, 100, 105, 32, 115, 97, 115, 97, 32, 122, 105, 110, 97, 111, 110, 121, 101, 115, 104, 97, 32, 117, 119, 101, 122, 101, 107, 97, 110, 111, 32, 109, 107, 117, 98, 119, 97, 32, 121, 97, 32, 107, 119, 97, 109, 98, 97, 32, 115, 97, 121, 97, 114, 105, 32, 104, 105, 105, 32, 110, 105, 32, 121, 97, 32, 109, 119, 97, 109, 98, 97, 32, 40, 107, 97, 109, 97, 32, 100, 117, 110, 105, 97, 32, 121, 101, 116, 117, 44, 32, 77, 105, 114, 105, 104, 105, 32, 97, 117, 32, 90, 117, 104, 117, 114, 97, 41, 32, 110, 97, 32, 105, 110, 97, 119, 101, 122, 97, 32, 107, 117, 119, 97, 32, 110, 97, 32, 97, 110, 103, 97, 104, 101, 119, 97, 44, 32, 116, 101, 110, 97, 32, 107, 97, 116, 105, 107, 97, 32, 117, 112, 101, 111, 32, 119, 97, 32, 106, 111, 116, 111, 32, 117, 110, 97, 111, 114, 117, 104, 117, 115, 117, 32, 107, 117, 119, 101, 112, 111, 32, 107, 119, 97, 32, 117, 104, 97, 105, 46, 32, 91, 49, 93, 57345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + attention_mask = [1 if x != 0 else 0 for x in input_ids] + token_type_ids = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + # fmt: on + input_ids = torch.tensor([input_ids]) + attention_mask = torch.tensor([attention_mask]) + token_type_ids = torch.tensor([token_type_ids]) + outputs = model(input_ids, attention_mask, token_type_ids) + + # verify sequence output + expected_shape = torch.Size((1, 2048, 768)) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor( + [ + [-0.161433131, 0.395568609, 0.0407391489], + [-0.108025983, 0.362060368, -0.544592619], + [-0.141537309, 0.180541009, 0.076907], + ] + ) + + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-2)) + + # verify pooled output + expected_shape = torch.Size((1, 768)) + self.assertEqual(outputs.pooler_output.shape, expected_shape) + + expected_slice = torch.tensor([-0.884311497, -0.529064834, 0.723164916]) + + self.assertTrue(torch.allclose(outputs.pooler_output[0, :3], expected_slice, atol=1e-2)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_image_processing_chinese_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_image_processing_chinese_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..90b0ffbcd6c59387c6da696dde596349c96dfe55 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_image_processing_chinese_clip.py @@ -0,0 +1,303 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import ChineseCLIPImageProcessor + + +class ChineseCLIPImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_center_crop=True, + crop_size=None, + do_normalize=True, + image_mean=[0.48145466, 0.4578275, 0.40821073], + image_std=[0.26862954, 0.26130258, 0.27577711], + do_convert_rgb=True, + ): + size = size if size is not None else {"height": 224, "width": 224} + crop_size = crop_size if crop_size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_convert_rgb = do_convert_rgb + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_center_crop": self.do_center_crop, + "crop_size": self.crop_size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_convert_rgb": self.do_convert_rgb, + } + + def prepare_inputs(self, equal_resolution=False, numpify=False, torchify=False): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + assert not (numpify and torchify), "You cannot specify both numpy and PyTorch tensors at the same time" + + if equal_resolution: + image_inputs = [] + for i in range(self.batch_size): + image_inputs.append( + np.random.randint( + 255, size=(self.num_channels, self.max_resolution, self.max_resolution), dtype=np.uint8 + ) + ) + else: + image_inputs = [] + for i in range(self.batch_size): + width, height = np.random.choice(np.arange(self.min_resolution, self.max_resolution), 2) + image_inputs.append(np.random.randint(255, size=(self.num_channels, width, height), dtype=np.uint8)) + + if not numpify and not torchify: + # PIL expects the channel dimension as last dimension + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + if torchify: + image_inputs = [torch.from_numpy(x) for x in image_inputs] + + return image_inputs + + +@require_torch +@require_vision +class ChineseCLIPImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ChineseCLIPImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = ChineseCLIPImageProcessingTester(self, do_center_crop=True) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_center_crop")) + self.assertTrue(hasattr(image_processing, "center_crop")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_convert_rgb")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 224, "width": 224}) + self.assertEqual(image_processor.crop_size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42, crop_size=84) + self.assertEqual(image_processor.size, {"shortest_edge": 42}) + self.assertEqual(image_processor.crop_size, {"height": 84, "width": 84}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = self.image_processor_tester.prepare_inputs(equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = self.image_processor_tester.prepare_inputs(equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = self.image_processor_tester.prepare_inputs(equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + +@require_torch +@require_vision +class ChineseCLIPImageProcessingTestFourChannels(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ChineseCLIPImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = ChineseCLIPImageProcessingTester(self, num_channels=4, do_center_crop=True) + self.expected_encoded_image_num_channels = 3 + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_center_crop")) + self.assertTrue(hasattr(image_processing, "center_crop")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_convert_rgb")) + + def test_batch_feature(self): + pass + + def test_call_pil_four_channels(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = self.image_processor_tester.prepare_inputs(equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.expected_encoded_image_num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.expected_encoded_image_num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_modeling_chinese_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_modeling_chinese_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..57f532da8635157d45560242791e8947fbf7c941 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_modeling_chinese_clip.py @@ -0,0 +1,703 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Chinese-CLIP model. """ + +import inspect +import os +import tempfile +import unittest + +import numpy as np +import requests + +from transformers import ChineseCLIPConfig, ChineseCLIPTextConfig, ChineseCLIPVisionConfig +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + MODEL_FOR_PRETRAINING_MAPPING, + ChineseCLIPModel, + ChineseCLIPTextModel, + ChineseCLIPVisionModel, + ) + from transformers.models.chinese_clip.modeling_chinese_clip import CHINESE_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import ChineseCLIPProcessor + + +class ChineseCLIPTextModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + """ + Returns a tiny configuration by default. + """ + return ChineseCLIPTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ChineseCLIPTextModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = ChineseCLIPTextModel(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +class ChineseCLIPVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + projection_dim=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + # in ViT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return ChineseCLIPVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = ChineseCLIPVisionModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class ChineseCLIPTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (ChineseCLIPTextModel,) if is_torch_available() else () + fx_compatible = False + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + inputs_dict["next_sentence_label"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = ChineseCLIPTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=ChineseCLIPTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_as_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + @slow + def test_model_from_pretrained(self): + for model_name in CHINESE_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ChineseCLIPTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="ChineseCLIPTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="ChineseCLIPTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + +@require_torch +class ChineseCLIPVisionModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as CHINESE_CLIP does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (ChineseCLIPVisionModel,) if is_torch_available() else () + fx_compatible = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = ChineseCLIPVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=ChineseCLIPVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="CHINESE_CLIP does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="ChineseCLIPVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="ChineseCLIPVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CHINESE_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ChineseCLIPVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class ChineseCLIPModelTester: + def __init__(self, parent, text_kwargs=None, vision_kwargs=None, is_training=True): + if text_kwargs is None: + text_kwargs = {} + if vision_kwargs is None: + vision_kwargs = {} + + self.parent = parent + self.text_model_tester = ChineseCLIPTextModelTester(parent, **text_kwargs) + self.vision_model_tester = ChineseCLIPVisionModelTester(parent, **vision_kwargs) + self.is_training = is_training + + def prepare_config_and_inputs(self): + ( + config, + input_ids, + token_type_ids, + attention_mask, + _, + __, + ___, + ) = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, token_type_ids, attention_mask, pixel_values + + def get_config(self): + return ChineseCLIPConfig.from_text_vision_configs( + self.text_model_tester.get_config(), self.vision_model_tester.get_config(), projection_dim=64 + ) + + def create_and_check_model(self, config, input_ids, token_type_ids, attention_mask, pixel_values): + model = ChineseCLIPModel(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, pixel_values, attention_mask, token_type_ids) + self.parent.assertEqual( + result.logits_per_image.shape, (self.vision_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, token_type_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "return_loss": True, + } + return config, inputs_dict + + +@require_torch +class ChineseCLIPModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (ChineseCLIPModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": ChineseCLIPModel} if is_torch_available() else {} + fx_compatible = False + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def setUp(self): + text_kwargs = {"use_labels": False, "batch_size": 12} + vision_kwargs = {"batch_size": 12} + self.model_tester = ChineseCLIPModelTester(self, text_kwargs, vision_kwargs) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="Hidden_states is tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="Inputs_embeds is tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Retain_grad is tested in individual model tests") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip(reason="ChineseCLIPModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + # override as the `logit_scale` parameter initilization is different for CHINESE_CLIP + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for sub_config_key in ("vision_config", "text_config"): + sub_config = getattr(configs_no_init, sub_config_key, {}) + setattr(configs_no_init, sub_config_key, _config_zero_init(sub_config)) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if name == "logit_scale": + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + pixel_values = inputs_dict["pixel_values"] # CHINESE_CLIP needs pixel_values + traced_model = torch.jit.trace(model, (input_ids, pixel_values)) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + non_persistent_buffers = {} + for key in loaded_model_state_dict.keys(): + if key not in model_state_dict.keys(): + non_persistent_buffers[key] = loaded_model_state_dict[key] + + loaded_model_state_dict = { + key: value for key, value in loaded_model_state_dict.items() if key not in non_persistent_buffers + } + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + @slow + def test_model_from_pretrained(self): + for model_name in CHINESE_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ChineseCLIPModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of Pikachu +def prepare_img(): + url = "https://clip-cn-beijing.oss-cn-beijing.aliyuncs.com/pokemon.jpeg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@require_vision +@require_torch +class ChineseCLIPModelIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "OFA-Sys/chinese-clip-vit-base-patch16" + model = ChineseCLIPModel.from_pretrained(model_name).to(torch_device) + processor = ChineseCLIPProcessor.from_pretrained(model_name) + + image = prepare_img() + inputs = processor(text=["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"], images=image, padding=True, return_tensors="pt").to( + torch_device + ) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + self.assertEqual( + outputs.logits_per_image.shape, + torch.Size((inputs.pixel_values.shape[0], inputs.input_ids.shape[0])), + ) + self.assertEqual( + outputs.logits_per_text.shape, + torch.Size((inputs.input_ids.shape[0], inputs.pixel_values.shape[0])), + ) + + probs = outputs.logits_per_image.softmax(dim=1) + expected_probs = torch.tensor([[1.2686e-03, 5.4499e-02, 6.7968e-04, 9.4355e-01]], device=torch_device) + + self.assertTrue(torch.allclose(probs, expected_probs, atol=5e-3)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_processor_chinese_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_processor_chinese_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..969b4d8992c71c3c01170be1699186a6f0333c19 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/chinese_clip/test_processor_chinese_clip.py @@ -0,0 +1,213 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import BertTokenizer, BertTokenizerFast +from transformers.models.bert.tokenization_bert import VOCAB_FILES_NAMES +from transformers.testing_utils import require_vision +from transformers.utils import FEATURE_EXTRACTOR_NAME, is_vision_available + + +if is_vision_available(): + from PIL import Image + + from transformers import ChineseCLIPImageProcessor, ChineseCLIPProcessor + + +@require_vision +class ChineseCLIPProcessorTest(unittest.TestCase): + def setUp(self): + self.tmpdirname = tempfile.mkdtemp() + + vocab_tokens = [ + "[UNK]", + "[CLS]", + "[SEP]", + "[PAD]", + "[MASK]", + "的", + "价", + "格", + "是", + "15", + "便", + "alex", + "##andra", + ",", + "。", + "-", + "t", + "shirt", + ] + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + image_processor_map = { + "do_resize": True, + "size": {"height": 224, "width": 224}, + "do_center_crop": True, + "crop_size": {"height": 18, "width": 18}, + "do_normalize": True, + "image_mean": [0.48145466, 0.4578275, 0.40821073], + "image_std": [0.26862954, 0.26130258, 0.27577711], + "do_convert_rgb": True, + } + self.image_processor_file = os.path.join(self.tmpdirname, FEATURE_EXTRACTOR_NAME) + with open(self.image_processor_file, "w", encoding="utf-8") as fp: + json.dump(image_processor_map, fp) + + def get_tokenizer(self, **kwargs): + return BertTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + return BertTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_image_processor(self, **kwargs): + return ChineseCLIPImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + tokenizer_slow = self.get_tokenizer() + tokenizer_fast = self.get_rust_tokenizer() + image_processor = self.get_image_processor() + + processor_slow = ChineseCLIPProcessor(tokenizer=tokenizer_slow, image_processor=image_processor) + processor_slow.save_pretrained(self.tmpdirname) + processor_slow = ChineseCLIPProcessor.from_pretrained(self.tmpdirname, use_fast=False) + + processor_fast = ChineseCLIPProcessor(tokenizer=tokenizer_fast, image_processor=image_processor) + processor_fast.save_pretrained(self.tmpdirname) + processor_fast = ChineseCLIPProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor_slow.tokenizer.get_vocab(), tokenizer_slow.get_vocab()) + self.assertEqual(processor_fast.tokenizer.get_vocab(), tokenizer_fast.get_vocab()) + self.assertEqual(tokenizer_slow.get_vocab(), tokenizer_fast.get_vocab()) + self.assertIsInstance(processor_slow.tokenizer, BertTokenizer) + self.assertIsInstance(processor_fast.tokenizer, BertTokenizerFast) + + self.assertEqual(processor_slow.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertEqual(processor_fast.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor_slow.image_processor, ChineseCLIPImageProcessor) + self.assertIsInstance(processor_fast.image_processor, ChineseCLIPImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = ChineseCLIPProcessor(tokenizer=self.get_tokenizer(), image_processor=self.get_image_processor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(cls_token="(CLS)", sep_token="(SEP)") + image_processor_add_kwargs = self.get_image_processor(do_normalize=False) + + processor = ChineseCLIPProcessor.from_pretrained( + self.tmpdirname, cls_token="(CLS)", sep_token="(SEP)", do_normalize=False + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, BertTokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, ChineseCLIPImageProcessor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = ChineseCLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + + input_feat_extract = image_processor(image_input, return_tensors="np") + input_processor = processor(images=image_input, return_tensors="np") + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = ChineseCLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "Alexandra,T-shirt的价格是15便士。" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = ChineseCLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "Alexandra,T-shirt的价格是15便士。" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), ["input_ids", "token_type_ids", "attention_mask", "pixel_values"]) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_tokenizer_decode(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = ChineseCLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = ChineseCLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "Alexandra,T-shirt的价格是15便士。" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_feature_extraction_clap.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_feature_extraction_clap.py new file mode 100644 index 0000000000000000000000000000000000000000..733dd66681c4733a015dadfba9f9a89dd090a9cd --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_feature_extraction_clap.py @@ -0,0 +1,538 @@ +# coding=utf-8 +# Copyright 2023 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import itertools +import random +import unittest + +import numpy as np + +from transformers import ClapFeatureExtractor +from transformers.testing_utils import require_torch, require_torchaudio +from transformers.trainer_utils import set_seed +from transformers.utils.import_utils import is_torch_available + +from ...test_sequence_feature_extraction_common import SequenceFeatureExtractionTestMixin + + +if is_torch_available(): + import torch + +global_rng = random.Random() + + +# Copied from tests.models.whisper.test_feature_extraction_whisper.floats_list +def floats_list(shape, scale=1.0, rng=None, name=None): + """Creates a random float32 tensor""" + if rng is None: + rng = global_rng + + values = [] + for batch_idx in range(shape[0]): + values.append([]) + for _ in range(shape[1]): + values[-1].append(rng.random() * scale) + + return values + + +@require_torch +@require_torchaudio +# Copied from tests.models.whisper.test_feature_extraction_whisper.WhisperFeatureExtractionTester with Whisper->Clap +class ClapFeatureExtractionTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + min_seq_length=400, + max_seq_length=2000, + feature_size=10, + hop_length=160, + chunk_length=8, + padding_value=0.0, + sampling_rate=4_000, + return_attention_mask=False, + do_normalize=True, + ): + self.parent = parent + self.batch_size = batch_size + self.min_seq_length = min_seq_length + self.max_seq_length = max_seq_length + self.seq_length_diff = (self.max_seq_length - self.min_seq_length) // (self.batch_size - 1) + self.padding_value = padding_value + self.sampling_rate = sampling_rate + self.return_attention_mask = return_attention_mask + self.do_normalize = do_normalize + self.feature_size = feature_size + self.chunk_length = chunk_length + self.hop_length = hop_length + + def prepare_feat_extract_dict(self): + return { + "feature_size": self.feature_size, + "hop_length": self.hop_length, + "chunk_length": self.chunk_length, + "padding_value": self.padding_value, + "sampling_rate": self.sampling_rate, + "return_attention_mask": self.return_attention_mask, + "do_normalize": self.do_normalize, + } + + def prepare_inputs_for_common(self, equal_length=False, numpify=False): + def _flatten(list_of_lists): + return list(itertools.chain(*list_of_lists)) + + if equal_length: + speech_inputs = [floats_list((self.max_seq_length, self.feature_size)) for _ in range(self.batch_size)] + else: + # make sure that inputs increase in size + speech_inputs = [ + floats_list((x, self.feature_size)) + for x in range(self.min_seq_length, self.max_seq_length, self.seq_length_diff) + ] + if numpify: + speech_inputs = [np.asarray(x) for x in speech_inputs] + return speech_inputs + + +@require_torch +@require_torchaudio +# Copied from tests.models.whisper.test_feature_extraction_whisper.WhisperFeatureExtractionTest with Whisper->Clap +class ClapFeatureExtractionTest(SequenceFeatureExtractionTestMixin, unittest.TestCase): + feature_extraction_class = ClapFeatureExtractor + + def setUp(self): + self.feat_extract_tester = ClapFeatureExtractionTester(self) + + def test_call(self): + # Tests that all call wrap to encode_plus and batch_encode_plus + feature_extractor = self.feature_extraction_class(**self.feat_extract_tester.prepare_feat_extract_dict()) + # create three inputs of length 800, 1000, and 1200 + speech_inputs = [floats_list((1, x))[0] for x in range(800, 1400, 200)] + np_speech_inputs = [np.asarray(speech_input) for speech_input in speech_inputs] + + # Test feature size + input_features = feature_extractor(np_speech_inputs, padding="max_length", return_tensors="np").input_features + self.assertTrue(input_features.ndim == 4) + + # Test not batched input + encoded_sequences_1 = feature_extractor(speech_inputs[0], return_tensors="np").input_features + encoded_sequences_2 = feature_extractor(np_speech_inputs[0], return_tensors="np").input_features + self.assertTrue(np.allclose(encoded_sequences_1, encoded_sequences_2, atol=1e-3)) + + # Test batched + encoded_sequences_1 = feature_extractor(speech_inputs, return_tensors="np").input_features + encoded_sequences_2 = feature_extractor(np_speech_inputs, return_tensors="np").input_features + for enc_seq_1, enc_seq_2 in zip(encoded_sequences_1, encoded_sequences_2): + self.assertTrue(np.allclose(enc_seq_1, enc_seq_2, atol=1e-3)) + + def test_double_precision_pad(self): + import torch + + feature_extractor = self.feature_extraction_class(**self.feat_extract_tester.prepare_feat_extract_dict()) + np_speech_inputs = np.random.rand(100, 32).astype(np.float64) + py_speech_inputs = np_speech_inputs.tolist() + + for inputs in [py_speech_inputs, np_speech_inputs]: + np_processed = feature_extractor.pad([{"input_features": inputs}], return_tensors="np") + self.assertTrue(np_processed.input_features.dtype == np.float32) + pt_processed = feature_extractor.pad([{"input_features": inputs}], return_tensors="pt") + self.assertTrue(pt_processed.input_features.dtype == torch.float32) + + def _load_datasamples(self, num_samples): + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + # automatic decoding with librispeech + speech_samples = ds.sort("id").select(range(num_samples))[:num_samples]["audio"] + + return [x["array"] for x in speech_samples] + + def test_integration_fusion_short_input(self): + # fmt: off + EXPECTED_INPUT_FEATURES = torch.tensor( + [ + [ + # "repeat" + [ + -20.1049, -19.9764, -20.0731, -19.5055, -27.5018, -22.5761, -26.6071, + -29.0091, -26.4659, -26.4236, -28.8808, -31.9190, -32.4848, -34.1186, + -34.0340, -32.8803, -30.9895, -37.6238, -38.0347, -40.6263, -36.3496, + -42.2533, -32.9132, -27.7068, -29.3704, -30.3208, -22.5972, -27.1494, + -30.1975, -31.1005, -29.9372, -27.1917, -25.9806, -30.3489, -33.2380, + -31.9062, -36.5498, -32.8721, -30.5629, -27.4674, -22.2232, -22.5653, + -16.3868, -17.2713, -25.9738, -30.6256, -34.3766, -31.1292, -27.8950, + -27.0588, -25.6206, -23.0712, -26.6050, -28.0112, -32.6847, -34.3396, + -34.9738, -35.8463, -39.2324, -37.1188, -33.3705, -28.9230, -28.9112, + -28.6578 + ], + [ + -36.7233, -30.0587, -24.8431, -18.4611, -16.8149, -23.9319, -32.8580, + -34.2264, -27.4332, -26.8027, -29.2721, -33.9033, -39.3403, -35.3232, + -26.8076, -28.6460, -35.2780, -36.0738, -35.4996, -37.7631, -39.5056, + -34.7112, -36.8741, -34.1066, -32.9474, -33.6604, -27.9937, -30.9594, + -26.2928, -32.0485, -29.2151, -29.2917, -32.7308, -29.6542, -31.1454, + -37.0088, -32.3388, -37.3086, -31.1024, -27.2889, -19.6788, -21.1488, + -19.5144, -14.8889, -21.2006, -24.7488, -27.7940, -31.1058, -27.5068, + -21.5737, -22.3780, -21.5151, -26.3086, -30.9223, -33.5043, -32.0307, + -37.3806, -41.6188, -45.6650, -40.5131, -32.5023, -26.7385, -26.3709, + -26.7761 + ] + ], + [ + # "repeatpad" + [ + -25.7496, -24.9339, -24.1357, -23.1271, -23.7853, -26.1264, -29.1456, + -33.2060, -37.8179, -42.4833, -41.9386, -41.2164, -42.3566, -44.2575, + -40.0217, -36.6794, -36.6974, -38.7819, -42.0880, -45.5560, -39.9368, + -36.3219, -35.5981, -36.6434, -35.1851, -33.0684, -30.0437, -30.2010, + -34.3476, -42.1373, -38.8039, -37.3355, -40.4576, -41.0485, -40.6377, + -38.2275, -42.7481, -34.6084, -34.7048, -29.5149, -26.3935, -26.8952, + -34.1336, -26.2904, -28.2571, -32.5642, -36.7240, -35.5334, -38.2451, + -34.8177, -28.9754, -25.1096, -27.9768, -32.3184, -37.0269, -40.5136, + -40.8061, -36.4948, -40.3767, -38.9671, -38.3552, -34.1250, -30.9035, + -31.6112 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ], + [ + # None, same as "repeatpad" + [ + -25.7496, -24.9339, -24.1357, -23.1271, -23.7853, -26.1264, -29.1456, + -33.2060, -37.8179, -42.4833, -41.9386, -41.2164, -42.3566, -44.2575, + -40.0217, -36.6794, -36.6974, -38.7819, -42.0880, -45.5560, -39.9368, + -36.3219, -35.5981, -36.6434, -35.1851, -33.0684, -30.0437, -30.2010, + -34.3476, -42.1373, -38.8039, -37.3355, -40.4576, -41.0485, -40.6377, + -38.2275, -42.7481, -34.6084, -34.7048, -29.5149, -26.3935, -26.8952, + -34.1336, -26.2904, -28.2571, -32.5642, -36.7240, -35.5334, -38.2451, + -34.8177, -28.9754, -25.1096, -27.9768, -32.3184, -37.0269, -40.5136, + -40.8061, -36.4948, -40.3767, -38.9671, -38.3552, -34.1250, -30.9035, + -31.6112 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ], + [ + # "pad" + [ + -58.5260, -58.1155, -57.8623, -57.5059, -57.9178, -58.7171, -59.2343, + -59.9833, -60.9764, -62.0722, -63.5723, -65.7111, -67.5153, -68.7088, + -69.8325, -70.2987, -70.1548, -70.6233, -71.5702, -72.5159, -72.3821, + -70.1817, -67.0315, -64.1387, -62.2202, -61.0717, -60.4951, -61.6005, + -63.7358, -67.1400, -67.6185, -65.5635, -64.3593, -63.7138, -63.6209, + -66.4950, -72.6284, -63.3961, -56.8334, -52.7319, -50.6310, -51.3728, + -53.5619, -51.9190, -50.9708, -52.8684, -55.8073, -58.8227, -60.6991, + -57.0547, -52.7611, -51.4388, -54.4892, -60.8950, -66.1024, -72.4352, + -67.8538, -65.1463, -68.7588, -72.3080, -68.4864, -60.4688, -57.1516, + -60.9460 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ] + ] + ) + # fmt: on + MEL_BIN = [[976, 977], [976, 977], [976, 977], [196, 197]] + input_speech = self._load_datasamples(1) + feature_extractor = ClapFeatureExtractor() + for padding, EXPECTED_VALUES, idx_in_mel in zip( + ["repeat", "repeatpad", None, "pad"], EXPECTED_INPUT_FEATURES, MEL_BIN + ): + input_features = feature_extractor(input_speech, return_tensors="pt", padding=padding).input_features + self.assertEqual(input_features.shape, (1, 4, 1001, 64)) + + self.assertTrue(torch.allclose(input_features[0, 0, idx_in_mel[0]], EXPECTED_VALUES[0], atol=1e-4)) + self.assertTrue(torch.allclose(input_features[0, 0, idx_in_mel[1]], EXPECTED_VALUES[1], atol=1e-4)) + + self.assertTrue(torch.all(input_features[0, 0] == input_features[0, 1])) + self.assertTrue(torch.all(input_features[0, 0] == input_features[0, 2])) + self.assertTrue(torch.all(input_features[0, 0] == input_features[0, 3])) + + def test_integration_rand_trunc_short_input(self): + # fmt: off + EXPECTED_INPUT_FEATURES = torch.tensor( + [ + [ + # "repeat" + [ + -35.0483, -35.7865, -38.2884, -40.0220, -42.5349, -44.9489, -43.2228, + -44.6499, -47.6253, -49.6983, -50.2127, -52.5483, -52.2223, -51.9157, + -49.4082, -51.2024, -57.0476, -56.2803, -58.1618, -60.7474, -55.0389, + -60.9514, -59.3080, -50.4419, -47.8172, -48.7570, -55.2552, -44.5036, + -44.1148, -50.8218, -51.0968, -52.9408, -51.1037, -48.9789, -47.5897, + -52.0915, -55.4216, -54.1529, -58.0149, -58.0866, -52.7798, -52.6154, + -45.9144, -46.2008, -40.7603, -41.1703, -50.2250, -55.4112, -59.4818, + -54.5795, -53.5552, -51.3668, -49.8358, -50.3186, -54.0452, -57.6030, + -61.1589, -61.6415, -63.2756, -66.5890, -62.8543, -58.0665, -56.7203, + -56.7632 + ], + [ + -47.1320, -37.9961, -34.0076, -36.7109, -47.9057, -48.4924, -43.8371, + -44.9728, -48.1689, -52.9141, -57.6077, -52.8520, -44.8502, -45.6764, + -51.8389, -56.4284, -54.6972, -53.4889, -55.6077, -58.7149, -60.3760, + -54.0136, -56.0730, -55.9870, -54.4017, -53.1094, -53.5640, -50.3064, + -49.9520, -49.3239, -48.1668, -53.4852, -50.4561, -50.8688, -55.1970, + -51.5538, -53.0260, -59.6933, -54.8183, -59.5895, -55.9589, -50.3761, + -44.1282, -44.1463, -43.8540, -39.1168, -45.3893, -49.5542, -53.1505, + -55.2870, -50.3921, -46.8511, -47.4444, -49.5633, -56.0034, -59.0815, + -59.0018, -63.7589, -69.5745, -71.5789, -64.0498, -56.0558, -54.3475, + -54.7004 + ] + ], + [ + # "repeatpad" + [ + -40.3184, -39.7186, -39.8807, -41.6508, -45.3613, -50.4785, -57.0297, + -60.4944, -59.1642, -58.9495, -60.4661, -62.5300, -58.4759, -55.2865, + -54.8973, -56.0780, -57.5482, -59.6557, -64.3309, -65.0330, -59.4941, + -56.8552, -55.0519, -55.9817, -56.9739, -55.2827, -54.5312, -51.4141, + -50.4289, -51.9131, -57.5821, -63.9979, -59.9180, -58.9489, -62.3247, + -62.6975, -63.7948, -60.5250, -64.6107, -58.7905, -57.0229, -54.3084, + -49.8445, -50.4459, -57.0172, -50.6425, -52.5992, -57.4207, -61.6358, + -60.6540, -63.1968, -57.4360, -52.3263, -51.7695, -57.1946, -62.9610, + -66.7359, -67.0335, -63.7440, -68.1775, -66.3798, -62.8650, -59.8972, + -59.3139 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ], + [ + # None, same as "repeatpad" + [ + -40.3184, -39.7186, -39.8807, -41.6508, -45.3613, -50.4785, -57.0297, + -60.4944, -59.1642, -58.9495, -60.4661, -62.5300, -58.4759, -55.2865, + -54.8973, -56.0780, -57.5482, -59.6557, -64.3309, -65.0330, -59.4941, + -56.8552, -55.0519, -55.9817, -56.9739, -55.2827, -54.5312, -51.4141, + -50.4289, -51.9131, -57.5821, -63.9979, -59.9180, -58.9489, -62.3247, + -62.6975, -63.7948, -60.5250, -64.6107, -58.7905, -57.0229, -54.3084, + -49.8445, -50.4459, -57.0172, -50.6425, -52.5992, -57.4207, -61.6358, + -60.6540, -63.1968, -57.4360, -52.3263, -51.7695, -57.1946, -62.9610, + -66.7359, -67.0335, -63.7440, -68.1775, -66.3798, -62.8650, -59.8972, + -59.3139 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ], + [ + # "pad" + [ + -73.3190, -73.6349, -74.1451, -74.8539, -75.7476, -76.5438, -78.5540, + -80.1339, -81.8911, -83.7560, -85.5387, -86.7466, -88.2072, -88.6090, + -88.8243, -89.0784, -89.4364, -89.8179, -91.3146, -92.2833, -91.7221, + -90.9440, -88.1315, -86.2425, -84.2281, -82.4893, -81.5993, -81.1328, + -81.5759, -83.1068, -85.6525, -88.9520, -88.9187, -87.2703, -86.3052, + -85.7188, -85.8802, -87.9996, -95.0464, -88.0133, -80.8561, -76.5597, + -74.2816, -74.8109, -77.3615, -76.0719, -75.3426, -77.6428, -80.9663, + -84.5275, -84.9907, -80.5205, -77.2851, -78.6259, -84.7740, -91.4535, + -98.1894, -94.3872, -92.3735, -97.6807, -98.1501, -91.4344, -85.2842, + -88.4338 + ], + [ + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100., -100., -100., -100., -100., -100., -100., + -100., -100., -100., -100. + ] + ] + ] + ) + # fmt: on + MEL_BIN = [[976, 977], [976, 977], [976, 977], [196, 197]] + input_speech = self._load_datasamples(1) + feature_extractor = ClapFeatureExtractor() + for padding, EXPECTED_VALUES, idx_in_mel in zip( + ["repeat", "repeatpad", None, "pad"], EXPECTED_INPUT_FEATURES, MEL_BIN + ): + input_features = feature_extractor( + input_speech, return_tensors="pt", truncation="rand_trunc", padding=padding + ).input_features + self.assertEqual(input_features.shape, (1, 1, 1001, 64)) + self.assertTrue(torch.allclose(input_features[0, 0, idx_in_mel[0]], EXPECTED_VALUES[0], atol=1e-4)) + self.assertTrue(torch.allclose(input_features[0, 0, idx_in_mel[1]], EXPECTED_VALUES[1], atol=1e-4)) + + def test_integration_fusion_long_input(self): + # fmt: off + EXPECTED_INPUT_FEATURES = torch.tensor( + [ + [ + -11.1830, -10.1894, -8.6051, -4.8578, -1.3268, -8.4606, -14.5453, + -9.2017, 0.5781, 16.2129, 14.8289, 3.6326, -3.8794, -6.5544, + -2.4408, 1.9531, 6.0967, 1.7590, -7.6730, -6.1571, 2.0052, + 16.6694, 20.6447, 21.2145, 13.4972, 15.9043, 16.8987, 4.1766, + 11.9428, 21.2372, 12.3016, 4.8604, 6.7241, 1.8543, 4.9235, + 5.3188, -0.9897, -1.2416, -6.5864, 2.9529, 2.9274, 6.4753, + 10.2300, 11.2127, 3.4042, -1.0055, -6.0475, -6.7524, -3.9801, + -1.4434, 0.4740, -0.1584, -4.5457, -8.5746, -8.8428, -13.1475, + -9.6079, -8.5798, -4.1143, -3.7966, -7.1651, -6.1517, -8.0258, + -12.1486 + ], + [ + -10.2017, -7.9924, -5.9517, -3.9372, -1.9735, -4.3130, 16.1647, + 25.0592, 23.5532, 14.4974, -7.0778, -10.2262, 6.4782, 20.3454, + 19.4269, 1.7976, -16.5070, 4.9380, 12.3390, 6.9285, -13.6325, + -8.5298, 1.0839, -5.9629, -8.4812, 3.1331, -2.0963, -16.6046, + -14.0070, -17.5707, -13.2080, -17.2168, -17.7770, -12.1111, -18.6184, + -17.1897, -13.9801, -12.0426, -23.5400, -25.6823, -23.5813, -18.7847, + -20.5473, -25.6458, -19.7585, -27.6007, -28.9276, -24.8948, -25.4458, + -22.2807, -19.6613, -19.2669, -15.7813, -19.6821, -24.3439, -22.2598, + -28.2631, -30.1017, -32.7646, -33.6525, -27.5639, -22.0548, -27.8054, + -29.6947 + ], + [ + -9.2078, -7.2963, -6.2095, -7.9959, -2.9280, -11.1843, -6.1490, + 5.0733, 19.2957, 21.4578, 14.6803, -3.3153, -6.3334, -2.3542, + 6.9509, 15.2965, 14.6620, 5.2075, -0.0873, 1.1919, 18.1986, + 20.8470, 10.8035, 2.2516, 7.6905, 7.7427, -1.2543, -5.0018, + 0.9809, -2.1584, -5.4580, -5.4760, -11.8888, -9.0605, -8.4638, + -9.9897, -0.0540, -5.1629, 0.0483, -4.1504, -4.8140, -7.8236, + -9.0622, -10.1742, -8.9597, -11.5380, -16.5603, -17.1858, -17.5032, + -20.9326, -23.9543, -25.2602, -25.3429, -27.4536, -26.8859, -22.7852, + -25.8288, -24.8399, -23.8893, -24.2096, -26.5415, -23.7281, -25.6851, + -22.3629 + ], + [ + 1.3448, 2.9883, 4.0366, -0.8019, -10.4191, -10.0883, -4.3812, + 0.8136, 2.1579, 0.0832, 1.0949, -0.9759, -5.5319, -4.6009, + -6.5452, -14.9155, -20.1584, -9.3611, -2.4271, 1.4031, 4.9910, + 8.6916, 8.6785, 10.1973, 9.9029, 5.3840, 7.5336, 5.2803, + 2.8144, -0.3138, 2.2216, 5.7328, 7.5574, 7.7402, 1.0681, + 3.1049, 7.0742, 6.5588, 7.3712, 5.7881, 8.6874, 8.7725, + 2.8133, -4.5809, -6.1317, -5.1719, -5.0192, -9.0977, -10.9391, + -6.0769, 1.6016, -0.8965, -7.2252, -7.8632, -11.4468, -11.7446, + -10.7447, -7.0601, -2.7748, -4.1798, -2.8433, -3.1352, 0.8097, + 6.4212 + ] + ] + ) + # fmt: on + MEL_BIN = 963 + input_speech = torch.cat([torch.tensor(x) for x in self._load_datasamples(5)]) + feature_extractor = ClapFeatureExtractor() + for padding, EXPECTED_VALUES, block_idx in zip( + ["repeat", "repeatpad", None, "pad"], EXPECTED_INPUT_FEATURES, [1, 2, 0, 3] + ): + set_seed(987654321) + input_features = feature_extractor(input_speech, return_tensors="pt", padding=padding).input_features + self.assertEqual(input_features.shape, (1, 4, 1001, 64)) + self.assertTrue(torch.allclose(input_features[0, block_idx, MEL_BIN], EXPECTED_VALUES, atol=1e-3)) + + def test_integration_rand_trunc_long_input(self): + # fmt: off + EXPECTED_INPUT_FEATURES = torch.tensor( + [ + [ + -35.4022, -32.7555, -31.2004, -32.7764, -42.5770, -41.6339, -43.1630, + -44.5080, -44.3029, -48.9628, -39.5022, -39.2105, -43.1350, -43.2195, + -48.4894, -52.2344, -57.6891, -52.2228, -45.5155, -44.2893, -43.4697, + -46.6702, -43.7490, -40.4819, -42.7275, -46.3434, -46.8412, -41.2003, + -43.1681, -46.2948, -46.1925, -47.8333, -45.6812, -44.9182, -41.7786, + -43.3809, -44.3199, -42.8814, -45.4771, -46.7114, -46.9746, -42.7090, + -41.6057, -38.3965, -40.1980, -41.0263, -34.1256, -28.3289, -29.0201, + -30.4453, -29.5561, -30.1734, -25.9406, -19.0897, -15.8452, -20.1351, + -23.6515, -23.1194, -17.1845, -19.4399, -23.6527, -22.8768, -20.7279, + -22.7864 + ], + [ + -35.7719, -27.2566, -23.6964, -27.5521, 0.2510, 7.4391, 1.3917, + -13.3417, -28.1758, -17.0856, -5.7723, -0.8000, -7.8832, -15.5548, + -30.5935, -24.7571, -13.7009, -10.3432, -21.2464, -24.8118, -19.4080, + -14.9779, -11.7991, -18.4485, -20.1982, -17.3652, -20.6328, -28.2967, + -25.7819, -21.8962, -28.5083, -29.5719, -30.2120, -35.7033, -31.8218, + -34.0408, -37.7744, -33.9653, -31.3009, -30.9063, -28.6153, -32.2202, + -28.5456, -28.8579, -32.5170, -37.9152, -43.0052, -46.4849, -44.0786, + -39.1933, -33.2757, -31.6313, -42.6386, -52.3679, -53.5785, -55.6444, + -47.0050, -47.6459, -56.6361, -60.6781, -61.5244, -55.8272, -60.4832, + -58.1897 + ], + [ + -38.2686, -36.6285, -32.5835, -35.1693, -37.7938, -37.4035, -35.3132, + -35.6083, -36.3609, -40.9472, -36.7846, -36.1544, -38.9076, -39.3618, + -35.4953, -34.2809, -39.9466, -39.7433, -34.8347, -37.5674, -41.5689, + -38.9161, -34.3947, -30.2924, -30.4841, -34.5831, -28.9261, -24.8849, + -31.2324, -27.1622, -27.2107, -25.9385, -30.1691, -30.9223, -23.9495, + -25.6047, -26.7119, -28.5523, -27.7481, -32.8427, -35.4650, -31.0399, + -31.2073, -30.5163, -22.9819, -20.8892, -19.2510, -24.7905, -28.9426, + -28.1998, -26.7386, -25.0140, -27.9223, -32.9913, -33.1864, -34.9742, + -38.5995, -39.6990, -29.3203, -22.4697, -25.6415, -33.5608, -33.0945, + -27.1716 + ], + [ + -33.2015, -28.7741, -21.9457, -23.4888, -32.1072, -8.6307, 3.2724, + 5.9157, -0.9221, -30.1814, -31.0015, -27.4508, -27.0477, -9.5342, + 0.3221, 0.6511, -7.1596, -25.9707, -32.8924, -32.2300, -13.8974, + -0.4895, 0.9168, -10.7663, -27.1176, -35.0829, -11.6859, -4.8855, + -11.8898, -26.6167, -5.6192, -3.8443, -19.7947, -14.4101, -8.6236, + -21.2458, -21.0801, -17.9136, -24.4663, -18.6333, -24.8085, -15.5854, + -15.4344, -11.5046, -22.3625, -27.3387, -32.4353, -30.9670, -31.3789, + -35.4044, -34.4591, -25.2433, -28.0773, -33.8736, -33.0224, -33.3155, + -38.5302, -39.2741, -36.6395, -34.7729, -32.4483, -42.4001, -49.2857, + -39.1682 + ] + ] + ) + # fmt: on + MEL_BIN = 963 + SEEDS = [987654321, 1234, 666, 5555] + input_speech = torch.cat([torch.tensor(x) for x in self._load_datasamples(5)]) + feature_extractor = ClapFeatureExtractor() + for padding, EXPECTED_VALUES, seed in zip( + ["repeat", "repeatpad", None, "pad"], EXPECTED_INPUT_FEATURES, SEEDS + ): + set_seed(seed) + input_features = feature_extractor( + input_speech, return_tensors="pt", truncation="rand_trunc", padding=padding + ).input_features + self.assertEqual(input_features.shape, (1, 1, 1001, 64)) + self.assertTrue(torch.allclose(input_features[0, 0, MEL_BIN], EXPECTED_VALUES, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_modeling_clap.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_modeling_clap.py new file mode 100644 index 0000000000000000000000000000000000000000..56a7dfdcfce0a1ce834c82ff0f172197ab06471c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_modeling_clap.py @@ -0,0 +1,719 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CLAP model. """ + + +import inspect +import os +import tempfile +import unittest + +import numpy as np +from datasets import load_dataset + +from transformers import ClapAudioConfig, ClapConfig, ClapProcessor, ClapTextConfig +from transformers.testing_utils import require_torch, slow, torch_device +from transformers.utils import is_torch_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + ClapAudioModel, + ClapAudioModelWithProjection, + ClapModel, + ClapTextModel, + ClapTextModelWithProjection, + ) + from transformers.models.clap.modeling_clap import CLAP_PRETRAINED_MODEL_ARCHIVE_LIST + + +class ClapAudioModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=60, + num_mel_bins=16, + window_size=4, + spec_size=64, + patch_size=2, + patch_stride=2, + seq_length=16, + freq_ratio=2, + num_channels=3, + is_training=True, + hidden_size=256, + patch_embeds_hidden_size=32, + projection_dim=32, + num_hidden_layers=4, + num_heads=[2, 2, 2, 2], + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_mel_bins = num_mel_bins + self.window_size = window_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_heads = num_heads + self.num_attention_heads = num_heads[0] + self.seq_length = seq_length + self.spec_size = spec_size + self.freq_ratio = freq_ratio + self.patch_stride = patch_stride + self.patch_embeds_hidden_size = patch_embeds_hidden_size + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + input_features = floats_tensor([self.batch_size, 1, self.hidden_size, self.num_mel_bins]) + config = self.get_config() + + return config, input_features + + def get_config(self): + return ClapAudioConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_mel_bins=self.num_mel_bins, + window_size=self.window_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + patch_stride=self.patch_stride, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + spec_size=self.spec_size, + freq_ratio=self.freq_ratio, + patch_embeds_hidden_size=self.patch_embeds_hidden_size, + ) + + def create_and_check_model(self, config, input_features): + model = ClapAudioModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_features) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_with_projection(self, config, input_features): + model = ClapAudioModelWithProjection(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_features) + self.parent.assertEqual(result.audio_embeds.shape, (self.batch_size, self.projection_dim)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_features = config_and_inputs + inputs_dict = {"input_features": input_features} + return config, inputs_dict + + +@require_torch +class ClapAudioModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as CLAP does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (ClapAudioModel, ClapAudioModelWithProjection) if is_torch_available() else () + fx_compatible = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = ClapAudioModelTester(self) + self.config_tester = ConfigTester(self, config_class=ClapAudioConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="ClapAudioModel does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.patch_embeds_hidden_size, self.model_tester.patch_embeds_hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + @unittest.skip(reason="ClapAudioModel does not output any loss term in the forward pass") + def test_retain_grad_hidden_states_attentions(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_features"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_with_projection(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_projection(*config_and_inputs) + + @unittest.skip(reason="ClapAudioModel does not output any loss term in the forward pass") + def test_training(self): + pass + + @unittest.skip(reason="ClapAudioModel does not output any loss term in the forward pass") + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="ClapAudioModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="ClapAudioModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLAP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ClapAudioModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_model_with_projection_from_pretrained(self): + for model_name in CLAP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ClapAudioModelWithProjection.from_pretrained(model_name) + self.assertIsNotNone(model) + self.assertTrue(hasattr(model, "audio_projection")) + + +class ClapTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + projection_dim=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + projection_hidden_act="relu", + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + self.projection_hidden_act = projection_hidden_act + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return ClapTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + projection_hidden_act=self.projection_hidden_act, + ) + + def create_and_check_model(self, config, input_ids, input_mask): + model = ClapTextModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_with_projection(self, config, input_ids, input_mask): + model = ClapTextModelWithProjection(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.text_embeds.shape, (self.batch_size, self.projection_dim)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class ClapTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (ClapTextModel, ClapTextModelWithProjection) if is_torch_available() else () + fx_compatible = False + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = ClapTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=ClapTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_with_projection(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_projection(*config_and_inputs) + + @unittest.skip(reason="ClapTextModel does not output any loss term in the forward pass") + def test_training(self): + pass + + @unittest.skip(reason="ClapTextModel does not output any loss term in the forward pass") + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="ClapTextModel does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="ClapTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="ClapTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLAP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ClapTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_model_with_projection_from_pretrained(self): + for model_name in CLAP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ClapTextModelWithProjection.from_pretrained(model_name) + self.assertIsNotNone(model) + self.assertTrue(hasattr(model, "text_projection")) + + +class ClapModelTester: + def __init__(self, parent, text_kwargs=None, audio_kwargs=None, is_training=True): + if text_kwargs is None: + text_kwargs = {} + if audio_kwargs is None: + audio_kwargs = {} + + self.parent = parent + self.text_model_tester = ClapTextModelTester(parent, **text_kwargs) + self.audio_model_tester = ClapAudioModelTester(parent, **audio_kwargs) + self.is_training = is_training + + def prepare_config_and_inputs(self): + _, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + _, input_features = self.audio_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, attention_mask, input_features + + def get_config(self): + return ClapConfig.from_text_audio_configs( + self.text_model_tester.get_config(), self.audio_model_tester.get_config(), projection_dim=64 + ) + + def create_and_check_model(self, config, input_ids, attention_mask, input_features): + model = ClapModel(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, input_features, attention_mask) + self.parent.assertEqual( + result.logits_per_audio.shape, (self.audio_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.audio_model_tester.batch_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, input_features = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "input_features": input_features, + "return_loss": True, + } + return config, inputs_dict + + +@require_torch +class ClapModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (ClapModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": ClapModel} if is_torch_available() else {} + fx_compatible = False + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def setUp(self): + self.model_tester = ClapModelTester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="Hidden_states is tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="Inputs_embeds is tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Retain_grad is tested in individual model tests") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip(reason="ClapModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + # override as the `logit_scale` parameter initilization is different for CLAP + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if name == "logit_scale": + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + input_features = inputs_dict["input_features"] # CLAP needs input_features + traced_model = torch.jit.trace(model, (input_ids, input_features)) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_load_audio_text_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Save ClapConfig and check if we can load ClapAudioConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + audio_config = ClapAudioConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.audio_config.to_dict(), audio_config.to_dict()) + + # Save ClapConfig and check if we can load ClapTextConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + text_config = ClapTextConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.text_config.to_dict(), text_config.to_dict()) + + @slow + def test_model_from_pretrained(self): + for model_name in CLAP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ClapModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@slow +@require_torch +class ClapModelIntegrationTest(unittest.TestCase): + paddings = ["repeatpad", "repeat", "pad"] + + def test_integration_unfused(self): + EXPECTED_MEANS_UNFUSED = { + "repeatpad": 0.0024, + "pad": 0.0020, + "repeat": 0.0023, + } + + librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + audio_sample = librispeech_dummy[-1] + + model_id = "laion/clap-htsat-unfused" + + model = ClapModel.from_pretrained(model_id).to(torch_device) + processor = ClapProcessor.from_pretrained(model_id) + + for padding in self.paddings: + inputs = processor(audios=audio_sample["audio"]["array"], return_tensors="pt", padding=padding).to( + torch_device + ) + + audio_embed = model.get_audio_features(**inputs) + expected_mean = EXPECTED_MEANS_UNFUSED[padding] + + self.assertTrue( + torch.allclose(audio_embed.cpu().mean(), torch.tensor([expected_mean]), atol=1e-3, rtol=1e-3) + ) + + def test_integration_fused(self): + EXPECTED_MEANS_FUSED = { + "repeatpad": 0.00069, + "repeat": 0.00196, + "pad": -0.000379, + } + + librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + audio_sample = librispeech_dummy[-1] + + model_id = "laion/clap-htsat-fused" + + model = ClapModel.from_pretrained(model_id).to(torch_device) + processor = ClapProcessor.from_pretrained(model_id) + + for padding in self.paddings: + inputs = processor( + audios=audio_sample["audio"]["array"], return_tensors="pt", padding=padding, truncation="fusion" + ).to(torch_device) + + audio_embed = model.get_audio_features(**inputs) + expected_mean = EXPECTED_MEANS_FUSED[padding] + + self.assertTrue( + torch.allclose(audio_embed.cpu().mean(), torch.tensor([expected_mean]), atol=1e-3, rtol=1e-3) + ) + + def test_batched_fused(self): + EXPECTED_MEANS_FUSED = { + "repeatpad": 0.0010, + "repeat": 0.0020, + "pad": 0.0006, + } + + librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + audio_samples = [sample["array"] for sample in librispeech_dummy[0:4]["audio"]] + + model_id = "laion/clap-htsat-fused" + + model = ClapModel.from_pretrained(model_id).to(torch_device) + processor = ClapProcessor.from_pretrained(model_id) + + for padding in self.paddings: + inputs = processor(audios=audio_samples, return_tensors="pt", padding=padding, truncation="fusion").to( + torch_device + ) + + audio_embed = model.get_audio_features(**inputs) + expected_mean = EXPECTED_MEANS_FUSED[padding] + + self.assertTrue( + torch.allclose(audio_embed.cpu().mean(), torch.tensor([expected_mean]), atol=1e-3, rtol=1e-3) + ) + + def test_batched_unfused(self): + EXPECTED_MEANS_FUSED = { + "repeatpad": 0.0016, + "repeat": 0.0019, + "pad": 0.0019, + } + + librispeech_dummy = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + audio_samples = [sample["array"] for sample in librispeech_dummy[0:4]["audio"]] + + model_id = "laion/clap-htsat-unfused" + + model = ClapModel.from_pretrained(model_id).to(torch_device) + processor = ClapProcessor.from_pretrained(model_id) + + for padding in self.paddings: + inputs = processor(audios=audio_samples, return_tensors="pt", padding=padding).to(torch_device) + + audio_embed = model.get_audio_features(**inputs) + expected_mean = EXPECTED_MEANS_FUSED[padding] + + self.assertTrue( + torch.allclose(audio_embed.cpu().mean(), torch.tensor([expected_mean]), atol=1e-3, rtol=1e-3) + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_processor_clap.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_processor_clap.py new file mode 100644 index 0000000000000000000000000000000000000000..49e9972ea02e22a0661ab0d8ef71cc1cfe29b291 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clap/test_processor_clap.py @@ -0,0 +1,125 @@ +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import shutil +import tempfile +import unittest + +from transformers import ClapFeatureExtractor, ClapProcessor, RobertaTokenizer, RobertaTokenizerFast +from transformers.testing_utils import require_sentencepiece, require_torchaudio + +from .test_feature_extraction_clap import floats_list + + +@require_torchaudio +@require_sentencepiece +class ClapProcessorTest(unittest.TestCase): + def setUp(self): + self.checkpoint = "laion/clap-htsat-unfused" + self.tmpdirname = tempfile.mkdtemp() + + def get_tokenizer(self, **kwargs): + return RobertaTokenizer.from_pretrained(self.checkpoint, **kwargs) + + def get_feature_extractor(self, **kwargs): + return ClapFeatureExtractor.from_pretrained(self.checkpoint, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def test_save_load_pretrained_default(self): + tokenizer = self.get_tokenizer() + feature_extractor = self.get_feature_extractor() + + processor = ClapProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + processor.save_pretrained(self.tmpdirname) + processor = ClapProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertIsInstance(processor.tokenizer, RobertaTokenizerFast) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor.to_json_string()) + self.assertIsInstance(processor.feature_extractor, ClapFeatureExtractor) + + def test_save_load_pretrained_additional_features(self): + processor = ClapProcessor(tokenizer=self.get_tokenizer(), feature_extractor=self.get_feature_extractor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + feature_extractor_add_kwargs = self.get_feature_extractor(do_normalize=False, padding_value=1.0) + + processor = ClapProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_normalize=False, padding_value=1.0 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, RobertaTokenizerFast) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.feature_extractor, ClapFeatureExtractor) + + def test_feature_extractor(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = ClapProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + raw_speech = floats_list((3, 1000)) + + input_feat_extract = feature_extractor(raw_speech, return_tensors="np") + input_processor = processor(audios=raw_speech, return_tensors="np") + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = ClapProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + input_str = "This is a test string" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_tokenizer_decode(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = ClapProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) + + def test_model_input_names(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = ClapProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + self.assertListEqual( + processor.model_input_names[2:], + feature_extractor.model_input_names, + msg="`processor` and `feature_extractor` model input names do not match", + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..d16241ab2f22a05771dcc9ed5c0cd4c30dcac9d8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_clip.py @@ -0,0 +1,737 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CLIP model. """ + + +import inspect +import os +import tempfile +import unittest + +import numpy as np +import requests + +import transformers +from transformers import CLIPConfig, CLIPTextConfig, CLIPVisionConfig +from transformers.testing_utils import ( + is_flax_available, + is_pt_flax_cross_test, + require_torch, + require_vision, + slow, + torch_device, +) +from transformers.utils import is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + CLIPModel, + CLIPTextModel, + CLIPTextModelWithProjection, + CLIPVisionModel, + CLIPVisionModelWithProjection, + ) + from transformers.models.clip.modeling_clip import CLIP_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import CLIPProcessor + + +if is_flax_available(): + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + + +class CLIPVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + projection_dim=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + # in ViT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return CLIPVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = CLIPVisionModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_with_projection(self, config, pixel_values): + model = CLIPVisionModelWithProjection(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + self.parent.assertEqual(result.image_embeds.shape, (self.batch_size, self.projection_dim)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class CLIPVisionModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as CLIP does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (CLIPVisionModel, CLIPVisionModelWithProjection) if is_torch_available() else () + fx_compatible = True + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = CLIPVisionModelTester(self) + self.config_tester = ConfigTester(self, config_class=CLIPVisionConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="CLIP does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_with_projection(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_projection(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="CLIPVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="CLIPVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_model_with_projection_from_pretrained(self): + for model_name in CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPVisionModelWithProjection.from_pretrained(model_name) + self.assertIsNotNone(model) + self.assertTrue(hasattr(model, "visual_projection")) + + +class CLIPTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + projection_dim=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return CLIPTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask): + model = CLIPTextModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_with_projection(self, config, input_ids, input_mask): + model = CLIPTextModelWithProjection(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.text_embeds.shape, (self.batch_size, self.projection_dim)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class CLIPTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (CLIPTextModel, CLIPTextModelWithProjection) if is_torch_available() else () + fx_compatible = True + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = CLIPTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=CLIPTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_with_projection(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_projection(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="CLIP does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="CLIPTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="CLIPTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_model_with_projection_from_pretrained(self): + for model_name in CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPTextModelWithProjection.from_pretrained(model_name) + self.assertIsNotNone(model) + self.assertTrue(hasattr(model, "text_projection")) + + +class CLIPModelTester: + def __init__(self, parent, text_kwargs=None, vision_kwargs=None, is_training=True): + if text_kwargs is None: + text_kwargs = {} + if vision_kwargs is None: + vision_kwargs = {} + + self.parent = parent + self.text_model_tester = CLIPTextModelTester(parent, **text_kwargs) + self.vision_model_tester = CLIPVisionModelTester(parent, **vision_kwargs) + self.is_training = is_training + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, attention_mask, pixel_values + + def get_config(self): + return CLIPConfig.from_text_vision_configs( + self.text_model_tester.get_config(), self.vision_model_tester.get_config(), projection_dim=64 + ) + + def create_and_check_model(self, config, input_ids, attention_mask, pixel_values): + model = CLIPModel(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, pixel_values, attention_mask) + self.parent.assertEqual( + result.logits_per_image.shape, (self.vision_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "return_loss": True, + } + return config, inputs_dict + + +@require_torch +class CLIPModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (CLIPModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": CLIPModel} if is_torch_available() else {} + fx_compatible = True + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def setUp(self): + self.model_tester = CLIPModelTester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="Hidden_states is tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="Inputs_embeds is tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Retain_grad is tested in individual model tests") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip(reason="CLIPModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + # override as the `logit_scale` parameter initilization is different for CLIP + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if name == "logit_scale": + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + pixel_values = inputs_dict["pixel_values"] # CLIP needs pixel_values + traced_model = torch.jit.trace(model, (input_ids, pixel_values)) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_load_vision_text_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Save CLIPConfig and check if we can load CLIPVisionConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + vision_config = CLIPVisionConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.vision_config.to_dict(), vision_config.to_dict()) + + # Save CLIPConfig and check if we can load CLIPTextConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + text_config = CLIPTextConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.text_config.to_dict(), text_config.to_dict()) + + # overwrite from common since FlaxCLIPModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # load PyTorch class + pt_model = model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + return + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + # convert inputs to Flax + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + fx_outputs = fx_model(**fx_inputs).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = fx_model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**fx_inputs).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output_loaded, pt_output.numpy(), 4e-2) + + # overwrite from common since FlaxCLIPModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # load corresponding PyTorch class + pt_model = model_class(config).eval() + + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + # no flax model exists for this class + return + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + + fx_outputs = fx_model(**fx_inputs).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs_loaded[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + @slow + def test_model_from_pretrained(self): + for model_name in CLIP_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@require_vision +@require_torch +class CLIPModelIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "openai/clip-vit-base-patch32" + model = CLIPModel.from_pretrained(model_name).to(torch_device) + processor = CLIPProcessor.from_pretrained(model_name) + + image = prepare_img() + inputs = processor( + text=["a photo of a cat", "a photo of a dog"], images=image, padding=True, return_tensors="pt" + ).to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + self.assertEqual( + outputs.logits_per_image.shape, + torch.Size((inputs.pixel_values.shape[0], inputs.input_ids.shape[0])), + ) + self.assertEqual( + outputs.logits_per_text.shape, + torch.Size((inputs.input_ids.shape[0], inputs.pixel_values.shape[0])), + ) + + expected_logits = torch.tensor([[24.5701, 19.3049]], device=torch_device) + + self.assertTrue(torch.allclose(outputs.logits_per_image, expected_logits, atol=1e-3)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_flax_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_flax_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..7d63fa9edf17740ba18e04cc69b8fc749e48bdd9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_modeling_flax_clip.py @@ -0,0 +1,588 @@ +import inspect +import tempfile +import unittest + +import numpy as np + +import transformers +from transformers import CLIPConfig, CLIPTextConfig, CLIPVisionConfig, is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax, slow + +from ...test_modeling_flax_common import FlaxModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask + + +if is_flax_available(): + import jax + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + from transformers.models.clip.modeling_flax_clip import FlaxCLIPModel, FlaxCLIPTextModel, FlaxCLIPVisionModel + +if is_torch_available(): + import torch + + +class FlaxCLIPVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = CLIPVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + return config, pixel_values + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_flax +class FlaxCLIPVisionModelTest(FlaxModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as CLIP does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (FlaxCLIPVisionModel,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxCLIPVisionModelTester(self) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.__call__) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_jit_compilation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + @jax.jit + def model_jitted(pixel_values, **kwargs): + return model(pixel_values=pixel_values, **kwargs).to_tuple() + + with self.subTest("JIT Enabled"): + jitted_outputs = model_jitted(**prepared_inputs_dict) + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = model_jitted(**prepared_inputs_dict) + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + hidden_states = outputs.hidden_states + + self.assertEqual(len(hidden_states), self.model_tester.num_hidden_layers + 1) + + # CLIP has a different seq_length + image_size = (self.model_tester.image_size, self.model_tester.image_size) + patch_size = (self.model_tester.patch_size, self.model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_length = num_patches + 1 + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + # in CLIP, the seq_len equals the number of patches + 1 (we add 1 for the [CLS] token) + image_size = (self.model_tester.image_size, self.model_tester.image_size) + patch_size = (self.model_tester.patch_size, self.model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_length = num_patches + 1 + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, seq_length], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, seq_length], + ) + + # FlaxCLIPVisionModel does not have any base model + def test_save_load_from_base(self): + pass + + # FlaxCLIPVisionModel does not have any base model + def test_save_load_to_base(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_from_base_pt(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_to_base_pt(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_bf16_to_base_pt(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("openai/clip-vit-base-patch32", from_pt=True) + outputs = model(np.ones((1, 3, 224, 224))) + self.assertIsNotNone(outputs) + + +class FlaxCLIPTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = CLIPTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + return config, input_ids, input_mask + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_flax +class FlaxCLIPTextModelTest(FlaxModelTesterMixin, unittest.TestCase): + all_model_classes = (FlaxCLIPTextModel,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxCLIPTextModelTester(self) + + # FlaxCLIPTextModel does not have any base model + def test_save_load_from_base(self): + pass + + # FlaxCLIPVisionModel does not have any base model + def test_save_load_to_base(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_from_base_pt(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_to_base_pt(self): + pass + + # FlaxCLIPVisionModel does not have any base model + @is_pt_flax_cross_test + def test_save_load_bf16_to_base_pt(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("openai/clip-vit-base-patch32", from_pt=True) + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) + + +class FlaxCLIPModelTester: + def __init__(self, parent, is_training=True): + self.parent = parent + self.text_model_tester = FlaxCLIPTextModelTester(parent) + self.vision_model_tester = FlaxCLIPVisionModelTester(parent) + self.is_training = is_training + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = CLIPConfig.from_text_vision_configs(text_config, vision_config, projection_dim=64) + + return config, input_ids, attention_mask, pixel_values + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + } + return config, inputs_dict + + +@require_flax +class FlaxCLIPModelTest(FlaxModelTesterMixin, unittest.TestCase): + all_model_classes = (FlaxCLIPModel,) if is_flax_available() else () + test_attention_outputs = False + + def setUp(self): + self.model_tester = FlaxCLIPModelTester(self) + + # hidden_states are tested in individual model tests + def test_hidden_states_output(self): + pass + + def test_jit_compilation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + @jax.jit + def model_jitted(input_ids, pixel_values, **kwargs): + return model(input_ids=input_ids, pixel_values=pixel_values, **kwargs).to_tuple() + + with self.subTest("JIT Enabled"): + jitted_outputs = model_jitted(**prepared_inputs_dict) + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = model_jitted(**prepared_inputs_dict) + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs[:4], outputs[:4]): + self.assertEqual(jitted_output.shape, output.shape) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.__call__) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_ids", "pixel_values", "attention_mask", "position_ids"] + self.assertListEqual(arg_names[:4], expected_arg_names) + + def test_get_image_features(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + model = FlaxCLIPModel(config) + + @jax.jit + def model_jitted(pixel_values): + return model.get_image_features(pixel_values=pixel_values) + + with self.subTest("JIT Enabled"): + jitted_output = model_jitted(inputs_dict["pixel_values"]) + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + output = model_jitted(inputs_dict["pixel_values"]) + + self.assertEqual(jitted_output.shape, output.shape) + self.assertTrue(np.allclose(jitted_output, output, atol=1e-3)) + + def test_get_text_features(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + model = FlaxCLIPModel(config) + + @jax.jit + def model_jitted(input_ids, attention_mask, **kwargs): + return model.get_text_features(input_ids=input_ids, attention_mask=attention_mask) + + with self.subTest("JIT Enabled"): + jitted_output = model_jitted(**inputs_dict) + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + output = model_jitted(**inputs_dict) + + self.assertEqual(jitted_output.shape, output.shape) + self.assertTrue(np.allclose(jitted_output, output, atol=1e-3)) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("openai/clip-vit-base-patch32", from_pt=True) + outputs = model(input_ids=np.ones((1, 1)), pixel_values=np.ones((1, 3, 224, 224))) + self.assertIsNotNone(outputs) + + # overwrite from common since FlaxCLIPModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**prepared_inputs_dict).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output_loaded, pt_output.numpy(), 4e-2) + + # overwrite from common since FlaxCLIPModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = pt_model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs_loaded[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + # overwrite from common since FlaxCLIPModel returns nested output + # which is not supported in the common test + def test_from_pretrained_save_pretrained(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class.__name__ != "FlaxBertModel": + continue + + with self.subTest(model_class.__name__): + model = model_class(config) + + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + outputs = model(**prepared_inputs_dict).to_tuple() + + # verify that normal save_pretrained works as expected + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model_loaded = model_class.from_pretrained(tmpdirname) + + outputs_loaded = model_loaded(**prepared_inputs_dict).to_tuple()[:4] + for output_loaded, output in zip(outputs_loaded, outputs): + self.assert_almost_equals(output_loaded, output, 1e-3) + + # verify that save_pretrained for distributed training + # with `params=params` works as expected + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, params=model.params) + model_loaded = model_class.from_pretrained(tmpdirname) + + outputs_loaded = model_loaded(**prepared_inputs_dict).to_tuple()[:4] + for output_loaded, output in zip(outputs_loaded, outputs): + self.assert_almost_equals(output_loaded, output, 1e-3) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_processor_clip.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_processor_clip.py new file mode 100644 index 0000000000000000000000000000000000000000..59e1f135462b66c2594c3318c955d68416f28e08 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clip/test_processor_clip.py @@ -0,0 +1,202 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import CLIPTokenizer, CLIPTokenizerFast +from transformers.models.clip.tokenization_clip import VOCAB_FILES_NAMES +from transformers.testing_utils import require_vision +from transformers.utils import IMAGE_PROCESSOR_NAME, is_vision_available + + +if is_vision_available(): + from PIL import Image + + from transformers import CLIPImageProcessor, CLIPProcessor + + +@require_vision +class CLIPProcessorTest(unittest.TestCase): + def setUp(self): + self.tmpdirname = tempfile.mkdtemp() + + # fmt: off + vocab = ["l", "o", "w", "e", "r", "s", "t", "i", "d", "n", "lo", "l", "w", "r", "t", "low", "er", "lowest", "newer", "wider", "", "<|startoftext|>", "<|endoftext|>"] + # fmt: on + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "l o", "lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + image_processor_map = { + "do_resize": True, + "size": 20, + "do_center_crop": True, + "crop_size": 18, + "do_normalize": True, + "image_mean": [0.48145466, 0.4578275, 0.40821073], + "image_std": [0.26862954, 0.26130258, 0.27577711], + } + self.image_processor_file = os.path.join(self.tmpdirname, IMAGE_PROCESSOR_NAME) + with open(self.image_processor_file, "w", encoding="utf-8") as fp: + json.dump(image_processor_map, fp) + + def get_tokenizer(self, **kwargs): + return CLIPTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + return CLIPTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_image_processor(self, **kwargs): + return CLIPImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + tokenizer_slow = self.get_tokenizer() + tokenizer_fast = self.get_rust_tokenizer() + image_processor = self.get_image_processor() + + processor_slow = CLIPProcessor(tokenizer=tokenizer_slow, image_processor=image_processor) + processor_slow.save_pretrained(self.tmpdirname) + processor_slow = CLIPProcessor.from_pretrained(self.tmpdirname, use_fast=False) + + processor_fast = CLIPProcessor(tokenizer=tokenizer_fast, image_processor=image_processor) + processor_fast.save_pretrained(self.tmpdirname) + processor_fast = CLIPProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor_slow.tokenizer.get_vocab(), tokenizer_slow.get_vocab()) + self.assertEqual(processor_fast.tokenizer.get_vocab(), tokenizer_fast.get_vocab()) + self.assertEqual(tokenizer_slow.get_vocab(), tokenizer_fast.get_vocab()) + self.assertIsInstance(processor_slow.tokenizer, CLIPTokenizer) + self.assertIsInstance(processor_fast.tokenizer, CLIPTokenizerFast) + + self.assertEqual(processor_slow.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertEqual(processor_fast.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor_slow.image_processor, CLIPImageProcessor) + self.assertIsInstance(processor_fast.image_processor, CLIPImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = CLIPProcessor(tokenizer=self.get_tokenizer(), image_processor=self.get_image_processor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_normalize=False, padding_value=1.0) + + processor = CLIPProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_normalize=False, padding_value=1.0 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, CLIPTokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, CLIPImageProcessor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + + input_image_proc = image_processor(image_input, return_tensors="np") + input_processor = processor(images=image_input, return_tensors="np") + + for key in input_image_proc.keys(): + self.assertAlmostEqual(input_image_proc[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), ["input_ids", "attention_mask", "pixel_values"]) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_tokenizer_decode(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_modeling_clipseg.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_modeling_clipseg.py new file mode 100644 index 0000000000000000000000000000000000000000..b54861d8d8d045a1545073a5a6aa1205856d2d03 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_modeling_clipseg.py @@ -0,0 +1,741 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CLIPSeg model. """ + + +import inspect +import os +import tempfile +import unittest + +import numpy as np +import requests + +import transformers +from transformers import MODEL_MAPPING, CLIPSegConfig, CLIPSegProcessor, CLIPSegTextConfig, CLIPSegVisionConfig +from transformers.models.auto import get_values +from transformers.testing_utils import ( + is_flax_available, + is_pt_flax_cross_test, + require_torch, + require_vision, + slow, + torch_device, +) +from transformers.utils import is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import CLIPSegForImageSegmentation, CLIPSegModel, CLIPSegTextModel, CLIPSegVisionModel + from transformers.models.clipseg.modeling_clipseg import CLIPSEG_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + +if is_flax_available(): + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + + +class CLIPSegVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + # in ViT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return CLIPSegVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = CLIPSegVisionModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class CLIPSegVisionModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as CLIPSeg does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (CLIPSegVisionModel,) if is_torch_available() else () + fx_compatible = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = CLIPSegVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=CLIPSegVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="CLIPSeg does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="CLIPSegVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="CLIPSegVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLIPSEG_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPSegVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class CLIPSegTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return CLIPSegTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask): + model = CLIPSegTextModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class CLIPSegTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (CLIPSegTextModel,) if is_torch_available() else () + fx_compatible = False + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = CLIPSegTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=CLIPSegTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="CLIPSeg does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="CLIPSegTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="CLIPSegTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in CLIPSEG_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPSegTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class CLIPSegModelTester: + def __init__(self, parent, text_kwargs=None, vision_kwargs=None, is_training=True): + if text_kwargs is None: + text_kwargs = {} + if vision_kwargs is None: + vision_kwargs = {} + + self.parent = parent + self.text_model_tester = CLIPSegTextModelTester(parent, **text_kwargs) + self.vision_model_tester = CLIPSegVisionModelTester(parent, **vision_kwargs) + self.is_training = is_training + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, attention_mask, pixel_values + + def get_config(self): + return CLIPSegConfig.from_text_vision_configs( + self.text_model_tester.get_config(), + self.vision_model_tester.get_config(), + projection_dim=64, + reduce_dim=32, + extract_layers=[1, 2, 3], + ) + + def create_and_check_model(self, config, input_ids, attention_mask, pixel_values): + model = CLIPSegModel(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, pixel_values, attention_mask) + self.parent.assertEqual( + result.logits_per_image.shape, (self.vision_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) + ) + + def create_and_check_model_for_image_segmentation(self, config, input_ids, attention_maks, pixel_values): + model = CLIPSegForImageSegmentation(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, pixel_values) + self.parent.assertEqual( + result.logits.shape, + ( + self.vision_model_tester.batch_size, + self.vision_model_tester.image_size, + self.vision_model_tester.image_size, + ), + ) + self.parent.assertEqual( + result.conditional_embeddings.shape, (self.text_model_tester.batch_size, config.projection_dim) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + } + return config, inputs_dict + + +@require_torch +class CLIPSegModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (CLIPSegModel, CLIPSegForImageSegmentation) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": CLIPSegModel} if is_torch_available() else {} + fx_compatible = False + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + # CLIPSegForImageSegmentation requires special treatment + if return_labels: + if model_class.__name__ == "CLIPSegForImageSegmentation": + batch_size, _, height, width = inputs_dict["pixel_values"].shape + inputs_dict["labels"] = torch.zeros( + [batch_size, height, width], device=torch_device, dtype=torch.float + ) + + return inputs_dict + + def setUp(self): + self.model_tester = CLIPSegModelTester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_for_image_segmentation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_for_image_segmentation(*config_and_inputs) + + @unittest.skip(reason="Hidden_states is tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="Inputs_embeds is tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Retain_grad is tested in individual model tests") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip(reason="CLIPSegModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + # override as the some parameters require custom initialization + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if "logit_scale" in name: + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + elif "film" in name or "transposed_conv" in name or "reduce" in name: + # those parameters use PyTorch' default nn.Linear initialization scheme + pass + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + pixel_values = inputs_dict["pixel_values"] # CLIPSeg needs pixel_values + traced_model = torch.jit.trace(model, (input_ids, pixel_values)) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_load_vision_text_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Save CLIPSegConfig and check if we can load CLIPSegVisionConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + vision_config = CLIPSegVisionConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.vision_config.to_dict(), vision_config.to_dict()) + + # Save CLIPSegConfig and check if we can load CLIPSegTextConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + text_config = CLIPSegTextConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.text_config.to_dict(), text_config.to_dict()) + + # overwrite from common since FlaxCLIPSegModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # load PyTorch class + pt_model = model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + return + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + # convert inputs to Flax + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + fx_outputs = fx_model(**fx_inputs).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = fx_model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**fx_inputs).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output_loaded, pt_output.numpy(), 4e-2) + + # overwrite from common since FlaxCLIPSegModel returns nested output + # which is not supported in the common test + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # load corresponding PyTorch class + pt_model = model_class(config).eval() + + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + # no flax model exists for this class + return + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + + fx_outputs = fx_model(**fx_inputs).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs[:4], pt_outputs_loaded[:4]): + self.assert_almost_equals(fx_output, pt_output.numpy(), 4e-2) + + def test_training(self): + if not self.model_tester.is_training: + return + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + if model_class in get_values(MODEL_MAPPING): + continue + + print("Model class:", model_class) + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + for k, v in inputs.items(): + print(k, v.shape) + loss = model(**inputs).loss + loss.backward() + + @slow + def test_model_from_pretrained(self): + for model_name in CLIPSEG_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CLIPSegModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + image = Image.open(requests.get(url, stream=True).raw) + return image + + +@require_vision +@require_torch +class CLIPSegModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_image_segmentation(self): + model_name = "CIDAS/clipseg-rd64-refined" + processor = CLIPSegProcessor.from_pretrained(model_name) + model = CLIPSegForImageSegmentation.from_pretrained(model_name).to(torch_device) + + image = prepare_img() + texts = ["a cat", "a remote", "a blanket"] + inputs = processor(text=texts, images=[image] * len(texts), padding=True, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the predicted masks + self.assertEqual( + outputs.logits.shape, + torch.Size((3, 352, 352)), + ) + expected_masks_slice = torch.tensor( + [[-7.4613, -7.4785, -7.3628], [-7.3268, -7.0899, -7.1333], [-6.9838, -6.7900, -6.8913]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_masks_slice, atol=1e-3)) + + # verify conditional and pooled output + expected_conditional = torch.tensor([0.5601, -0.0314, 0.1980]).to(torch_device) + expected_pooled_output = torch.tensor([0.5036, -0.2681, -0.2644]).to(torch_device) + self.assertTrue(torch.allclose(outputs.conditional_embeddings[0, :3], expected_conditional, atol=1e-3)) + self.assertTrue(torch.allclose(outputs.pooled_output[0, :3], expected_pooled_output, atol=1e-3)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_processor_clipseg.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_processor_clipseg.py new file mode 100644 index 0000000000000000000000000000000000000000..2bc82dd022cb681b7024785f33009a41081be8cb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/clipseg/test_processor_clipseg.py @@ -0,0 +1,205 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import CLIPTokenizer, CLIPTokenizerFast +from transformers.models.clip.tokenization_clip import VOCAB_FILES_NAMES +from transformers.testing_utils import require_vision +from transformers.utils import IMAGE_PROCESSOR_NAME, is_vision_available + + +if is_vision_available(): + from PIL import Image + + from transformers import CLIPSegProcessor, ViTImageProcessor + + +@require_vision +class CLIPSegProcessorTest(unittest.TestCase): + def setUp(self): + self.tmpdirname = tempfile.mkdtemp() + + # fmt: off + vocab = ["l", "o", "w", "e", "r", "s", "t", "i", "d", "n", "lo", "l", "w", "r", "t", "low", "er", "lowest", "newer", "wider", "", "<|startoftext|>", "<|endoftext|>"] + # fmt: on + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "l o", "lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + image_processor_map = { + "do_resize": True, + "size": 20, + "do_center_crop": True, + "crop_size": 18, + "do_normalize": True, + "image_mean": [0.48145466, 0.4578275, 0.40821073], + "image_std": [0.26862954, 0.26130258, 0.27577711], + } + self.image_processor_file = os.path.join(self.tmpdirname, IMAGE_PROCESSOR_NAME) + with open(self.image_processor_file, "w", encoding="utf-8") as fp: + json.dump(image_processor_map, fp) + + def get_tokenizer(self, **kwargs): + return CLIPTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + return CLIPTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_image_processor(self, **kwargs): + return ViTImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True.""" + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + tokenizer_slow = self.get_tokenizer() + tokenizer_fast = self.get_rust_tokenizer() + image_processor = self.get_image_processor() + + processor_slow = CLIPSegProcessor(tokenizer=tokenizer_slow, image_processor=image_processor) + processor_slow.save_pretrained(self.tmpdirname) + processor_slow = CLIPSegProcessor.from_pretrained(self.tmpdirname, use_fast=False) + + processor_fast = CLIPSegProcessor(tokenizer=tokenizer_fast, image_processor=image_processor) + processor_fast.save_pretrained(self.tmpdirname) + processor_fast = CLIPSegProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor_slow.tokenizer.get_vocab(), tokenizer_slow.get_vocab()) + self.assertEqual(processor_fast.tokenizer.get_vocab(), tokenizer_fast.get_vocab()) + self.assertEqual(tokenizer_slow.get_vocab(), tokenizer_fast.get_vocab()) + self.assertIsInstance(processor_slow.tokenizer, CLIPTokenizer) + self.assertIsInstance(processor_fast.tokenizer, CLIPTokenizerFast) + + self.assertEqual(processor_slow.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertEqual(processor_fast.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor_slow.image_processor, ViTImageProcessor) + self.assertIsInstance(processor_fast.image_processor, ViTImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = CLIPSegProcessor(tokenizer=self.get_tokenizer(), image_processor=self.get_image_processor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_normalize=False, padding_value=1.0) + + processor = CLIPSegProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_normalize=False, padding_value=1.0 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, CLIPTokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, ViTImageProcessor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPSegProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + + input_feat_extract = image_processor(image_input, return_tensors="np") + input_processor = processor(images=image_input, return_tensors="np") + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPSegProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_processor_text(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPSegProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), ["input_ids", "attention_mask", "pixel_values"]) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_processor_visual_prompt(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPSegProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + visual_prompt_input = self.prepare_image_inputs() + + inputs = processor(images=image_input, visual_prompt=visual_prompt_input) + + self.assertListEqual(list(inputs.keys()), ["pixel_values", "conditional_pixel_values"]) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_tokenizer_decode(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = CLIPSegProcessor(tokenizer=tokenizer, image_processor=image_processor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_modeling_codegen.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_modeling_codegen.py new file mode 100644 index 0000000000000000000000000000000000000000..fdf2d891929583bf75f6d83bc4aec17792ca2b9a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_modeling_codegen.py @@ -0,0 +1,567 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import datetime +import unittest + +from transformers import CodeGenConfig, is_torch_available +from transformers.file_utils import cached_property +from transformers.testing_utils import is_flaky, 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 CODEGEN_PRETRAINED_MODEL_ARCHIVE_LIST, AutoTokenizer, CodeGenForCausalLM, CodeGenModel + + +class CodeGenModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=256, + hidden_size=32, + rotary_dim=4, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.rotary_dim = rotary_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def get_large_model_config(self): + return CodeGenConfig.from_pretrained("Salesforce/codegen-2B-mono") + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config(self): + return CodeGenConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + rotary_dim=self.rotary_dim, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_codegen_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = CodeGenModel(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_codegen_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = CodeGenModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_codegen_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = CodeGenModel(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_codegen_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = CodeGenModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = CodeGenForCausalLM(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False + ): + model = CodeGenForCausalLM(config) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + model.to(torch_device) + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "head_mask": head_mask} + + return config, inputs_dict + + +@require_torch +class CodeGenModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (CodeGenModel, CodeGenForCausalLM) if is_torch_available() else () + all_generative_model_classes = (CodeGenForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": CodeGenModel, "text-generation": CodeGenForCausalLM} if is_torch_available() else {} + ) + fx_compatible = False + test_pruning = False + test_missing_keys = False + test_model_parallel = False + test_head_masking = False + + # special case for DoubleHeads model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + return inputs_dict + + def setUp(self): + self.model_tester = CodeGenModelTester(self) + self.config_tester = ConfigTester(self, config_class=CodeGenConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_codegen_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_codegen_model(*config_and_inputs) + + def test_codegen_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_codegen_model_past(*config_and_inputs) + + def test_codegen_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_codegen_model_attention_mask_past(*config_and_inputs) + + def test_codegen_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_codegen_model_past_large_inputs(*config_and_inputs) + + def test_codegen_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_codegen_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + @slow + def test_batch_generation(self): + tokenizer = AutoTokenizer.from_pretrained("Salesforce/codegen-350M-mono") + model = CodeGenForCausalLM.from_pretrained("Salesforce/codegen-350M-mono") + model.to(torch_device) + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = ["def hellow_world():", "def greet(name):"] + + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item() + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + 'def hellow_world():\n print("Hello World")\n\nhellow_world()', + 'def greet(name):\n print(f"Hello {name}")\n\ng', + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_model_from_pretrained(self): + for model_name in CODEGEN_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CodeGenModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class CodeGenModelLanguageGenerationTest(unittest.TestCase): + @cached_property + def cached_tokenizer(self): + return AutoTokenizer.from_pretrained("Salesforce/codegen-350M-mono") + + @cached_property + def cached_model(self): + return CodeGenForCausalLM.from_pretrained("Salesforce/codegen-350M-mono") + + @slow + def test_lm_generate_codegen(self): + tokenizer = self.cached_tokenizer + for checkpointing in [True, False]: + model = self.cached_model + + if checkpointing: + model.gradient_checkpointing_enable() + else: + model.gradient_checkpointing_disable() + model.to(torch_device) + + inputs = tokenizer("def hello_world():", return_tensors="pt").to(torch_device) + expected_output = 'def hello_world():\n print("Hello World")\n\nhello_world()\n\n' + + output_ids = model.generate(**inputs, do_sample=False) + output_str = tokenizer.batch_decode(output_ids)[0] + + self.assertEqual(output_str, expected_output) + + @slow + def test_codegen_sample(self): + tokenizer = self.cached_tokenizer + model = self.cached_model + model.to(torch_device) + + torch.manual_seed(0) + if torch_device == "cuda": + torch.cuda.manual_seed(0) + + tokenized = tokenizer("def hello_world():", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + output_ids = model.generate(input_ids, do_sample=True) + output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True) + + token_type_ids = tokenized.token_type_ids.to(torch_device) + output_seq = model.generate(input_ids=input_ids, do_sample=True, num_return_sequences=5) + output_seq_tt = model.generate( + input_ids=input_ids, token_type_ids=token_type_ids, do_sample=True, num_return_sequences=5 + ) + output_seq_strs = tokenizer.batch_decode(output_seq, skip_special_tokens=True) + output_seq_tt_strs = tokenizer.batch_decode(output_seq_tt, skip_special_tokens=True) + + if torch_device == "cuda": + EXPECTED_OUTPUT_STR = 'def hello_world():\n print("Hello World")\n return True\n\nresult =' + else: + EXPECTED_OUTPUT_STR = "def hello_world():\r\n print('Hello, World.')\r\n\r\n\r" + + self.assertEqual(output_str, EXPECTED_OUTPUT_STR) + self.assertTrue( + all([output_seq_strs[idx] != output_seq_tt_strs[idx] for idx in range(len(output_seq_tt_strs))]) + ) # token_type_ids should change output + + @is_flaky(max_attempts=3, description="measure of timing is somehow flaky.") + @slow + def test_codegen_sample_max_time(self): + tokenizer = self.cached_tokenizer + model = self.cached_model + model.to(torch_device) + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + + MAX_TIME = 0.05 + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=2 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=2 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=2 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=2 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=None, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=2 * MAX_TIME)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_tokenization_codegen.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_tokenization_codegen.py new file mode 100644 index 0000000000000000000000000000000000000000..ec7c11dcef9d8087a8d767275165abd6a978f480 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/codegen/test_tokenization_codegen.py @@ -0,0 +1,264 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import re +import unittest + +from transformers import CodeGenTokenizer, CodeGenTokenizerFast +from transformers.models.codegen.tokenization_codegen import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class CodeGenTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = CodeGenTokenizer + rust_tokenizer_class = CodeGenTokenizerFast + test_rust_tokenizer = True + from_pretrained_kwargs = {"add_prefix_space": True} + test_seq2seq = False + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + "<|endoftext|>", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return CodeGenTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return CodeGenTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = CodeGenTokenizer(self.vocab_file, self.merges_file, **self.special_tokens_map) + text = "lower newer" + bpe_tokens = ["\u0120low", "er", "\u0120", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text, add_prefix_space=True) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [14, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer(add_prefix_space=True) + + sequence = "lower newer" + + # Testing tokenization + tokens = tokenizer.tokenize(sequence, add_prefix_space=True) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + # Testing conversion to ids without special tokens + ids = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=True) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + # Testing conversion to ids with special tokens + rust_tokenizer = self.get_rust_tokenizer(add_prefix_space=True) + ids = tokenizer.encode(sequence, add_prefix_space=True) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + # Testing the unknown token + input_tokens = tokens + [rust_tokenizer.unk_token] + input_bpe_tokens = [14, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(rust_tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_pretokenized_inputs(self, *args, **kwargs): + # It's very difficult to mix/test pretokenization with byte-level + # And get both CodeGen and Roberta to work at the same time (mostly an issue of adding a space before the string) + pass + + def test_padding(self, max_length=15): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Simple input + s = "This is a simple input" + s2 = ["This is a simple input 1", "This is a simple input 2"] + p = ("This is a simple input", "This is a pair") + p2 = [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ] + + # Simple input tests + self.assertRaises(ValueError, tokenizer_r.encode, s, max_length=max_length, padding="max_length") + + # Simple input + self.assertRaises(ValueError, tokenizer_r.encode_plus, s, max_length=max_length, padding="max_length") + + # Simple input + self.assertRaises( + ValueError, + tokenizer_r.batch_encode_plus, + s2, + max_length=max_length, + padding="max_length", + ) + + # Pair input + self.assertRaises(ValueError, tokenizer_r.encode, p, max_length=max_length, padding="max_length") + + # Pair input + self.assertRaises(ValueError, tokenizer_r.encode_plus, p, max_length=max_length, padding="max_length") + + # Pair input + self.assertRaises( + ValueError, + tokenizer_r.batch_encode_plus, + p2, + max_length=max_length, + padding="max_length", + ) + + def test_padding_if_pad_token_set_slow(self): + tokenizer = CodeGenTokenizer.from_pretrained(self.tmpdirname, pad_token="") + + # Simple input + s = "This is a simple input" + s2 = ["This is a simple input looooooooong", "This is a simple input"] + p = ("This is a simple input", "This is a pair") + p2 = [ + ("This is a simple input loooooong", "This is a simple input"), + ("This is a simple pair loooooong", "This is a simple pair"), + ] + + pad_token_id = tokenizer.pad_token_id + + out_s = tokenizer(s, padding="max_length", max_length=30, return_tensors="np") + out_s2 = tokenizer(s2, padding=True, truncate=True, return_tensors="np") + out_p = tokenizer(*p, padding="max_length", max_length=60, return_tensors="np") + out_p2 = tokenizer(p2, padding=True, truncate=True, return_tensors="np") + + # s + # test single string max_length padding + self.assertEqual(out_s["input_ids"].shape[-1], 30) + self.assertTrue(pad_token_id in out_s["input_ids"]) + self.assertTrue(0 in out_s["attention_mask"]) + + # s2 + # test automatic padding + self.assertEqual(out_s2["input_ids"].shape[-1], 33) + # long slice doesn't have padding + self.assertFalse(pad_token_id in out_s2["input_ids"][0]) + self.assertFalse(0 in out_s2["attention_mask"][0]) + # short slice does have padding + self.assertTrue(pad_token_id in out_s2["input_ids"][1]) + self.assertTrue(0 in out_s2["attention_mask"][1]) + + # p + # test single pair max_length padding + self.assertEqual(out_p["input_ids"].shape[-1], 60) + self.assertTrue(pad_token_id in out_p["input_ids"]) + self.assertTrue(0 in out_p["attention_mask"]) + + # p2 + # test automatic padding pair + self.assertEqual(out_p2["input_ids"].shape[-1], 52) + # long slice pair doesn't have padding + self.assertFalse(pad_token_id in out_p2["input_ids"][0]) + self.assertFalse(0 in out_p2["attention_mask"][0]) + # short slice pair does have padding + self.assertTrue(pad_token_id in out_p2["input_ids"][1]) + self.assertTrue(0 in out_p2["attention_mask"][1]) + + def test_add_bos_token_slow(self): + bos_token = "$$$" + tokenizer = CodeGenTokenizer.from_pretrained(self.tmpdirname, bos_token=bos_token, add_bos_token=True) + + s = "This is a simple input" + s2 = ["This is a simple input 1", "This is a simple input 2"] + + bos_token_id = tokenizer.bos_token_id + + out_s = tokenizer(s) + out_s2 = tokenizer(s2) + + self.assertEqual(out_s.input_ids[0], bos_token_id) + self.assertTrue(all(o[0] == bos_token_id for o in out_s2.input_ids)) + + decode_s = tokenizer.decode(out_s.input_ids) + decode_s2 = tokenizer.batch_decode(out_s2.input_ids) + + self.assertEqual(decode_s.split()[0], bos_token) + self.assertTrue(all(d.split()[0] == bos_token for d in decode_s2)) + + @slow + def test_truncation(self): + tokenizer = CodeGenTokenizer.from_pretrained("Salesforce/codegen-350M-mono") + + text = "\nif len_a > len_b:\n result = a\nelse:\n result = b\n\n\n\n#" + expected_trucated_text = "\nif len_a > len_b: result = a\nelse: result = b" + + input_ids = tokenizer.encode(text) + truncation_pattern = ["^#", re.escape("<|endoftext|>"), "^'''", '^"""', "\n\n\n"] + decoded_text = tokenizer.decode(input_ids, truncate_before_pattern=truncation_pattern) + self.assertEqual(decoded_text, expected_trucated_text) + + # tokenizer has no padding token + def test_padding_different_model_input_name(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_image_processing_conditional_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_image_processing_conditional_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..ba77431467b830134f6ae212c8ea7bfd256ce1a3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_image_processing_conditional_detr.py @@ -0,0 +1,358 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import pathlib +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision, slow +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import ConditionalDetrImageProcessor + + +class ConditionalDetrImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + do_rescale=True, + rescale_factor=1 / 255, + do_pad=True, + ): + # by setting size["longest_edge"] > max_resolution we're effectively not testing this :p + size = size if size is not None else {"shortest_edge": 18, "longest_edge": 1333} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_pad = do_pad + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_rescale": self.do_rescale, + "rescale_factor": self.rescale_factor, + "do_pad": self.do_pad, + } + + def get_expected_values(self, image_inputs, batched=False): + """ + This function computes the expected height and width when providing images to ConditionalDetrImageProcessor, + assuming do_resize is set to True with a scalar size. + """ + if not batched: + image = image_inputs[0] + if isinstance(image, Image.Image): + w, h = image.size + else: + h, w = image.shape[1], image.shape[2] + if w < h: + expected_height = int(self.size["shortest_edge"] * h / w) + expected_width = self.size["shortest_edge"] + elif w > h: + expected_height = self.size["shortest_edge"] + expected_width = int(self.size["shortest_edge"] * w / h) + else: + expected_height = self.size["shortest_edge"] + expected_width = self.size["shortest_edge"] + + else: + expected_values = [] + for image in image_inputs: + expected_height, expected_width = self.get_expected_values([image]) + expected_values.append((expected_height, expected_width)) + expected_height = max(expected_values, key=lambda item: item[0])[0] + expected_width = max(expected_values, key=lambda item: item[1])[1] + + return expected_height, expected_width + + +@require_torch +@require_vision +class ConditionalDetrImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ConditionalDetrImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = ConditionalDetrImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 18, "longest_edge": 1333}) + self.assertEqual(image_processor.do_pad, True) + + image_processor = self.image_processing_class.from_dict( + self.image_processor_dict, size=42, max_size=84, pad_and_return_pixel_mask=False + ) + self.assertEqual(image_processor.size, {"shortest_edge": 42, "longest_edge": 84}) + self.assertEqual(image_processor.do_pad, False) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_equivalence_pad_and_create_pixel_mask(self): + # Initialize image_processings + image_processing_1 = self.image_processing_class(**self.image_processor_dict) + image_processing_2 = self.image_processing_class(do_resize=False, do_normalize=False, do_rescale=False) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test whether the method "pad_and_return_pixel_mask" and calling the image processor return the same tensors + encoded_images_with_method = image_processing_1.pad_and_create_pixel_mask(image_inputs, return_tensors="pt") + encoded_images = image_processing_2(image_inputs, return_tensors="pt") + + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_values"], encoded_images["pixel_values"], atol=1e-4) + ) + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_mask"], encoded_images["pixel_mask"], atol=1e-4) + ) + + @slow + def test_call_pytorch_with_coco_detection_annotations(self): + # prepare image and target + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"image_id": 39769, "annotations": target} + + # encode them + image_processing = ConditionalDetrImageProcessor.from_pretrained("microsoft/conditional-detr-resnet-50") + encoding = image_processing(images=image, annotations=target, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([5887.9600, 11250.2061, 489353.8438, 837122.7500, 147967.5156, 165732.3438]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.5503, 0.2765, 0.0604, 0.2215]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([75, 75, 63, 65, 17, 17]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) + + @slow + def test_call_pytorch_with_coco_panoptic_annotations(self): + # prepare image, target and masks_path + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"file_name": "000000039769.png", "image_id": 39769, "segments_info": target} + + masks_path = pathlib.Path("./tests/fixtures/tests_samples/COCO/coco_panoptic") + + # encode them + image_processing = ConditionalDetrImageProcessor(format="coco_panoptic") + encoding = image_processing(images=image, annotations=target, masks_path=masks_path, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([147979.6875, 165527.0469, 484638.5938, 11292.9375, 5879.6562, 7634.1147]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.2625, 0.5437, 0.4688, 0.8625]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([17, 17, 63, 75, 75, 93]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify masks + expected_masks_sum = 822873 + self.assertEqual(encoding["labels"][0]["masks"].sum().item(), expected_masks_sum) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_modeling_conditional_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_modeling_conditional_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..11a548df923934d0fc1f277244902260f71d6338 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/conditional_detr/test_modeling_conditional_detr.py @@ -0,0 +1,560 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Conditional DETR model. """ + + +import inspect +import math +import unittest + +from transformers import ConditionalDetrConfig, is_timm_available, is_vision_available +from transformers.testing_utils import require_timm, require_vision, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_timm_available(): + import torch + + from transformers import ( + ConditionalDetrForObjectDetection, + ConditionalDetrForSegmentation, + ConditionalDetrModel, + ResNetConfig, + ) + + +if is_vision_available(): + from PIL import Image + + from transformers import ConditionalDetrFeatureExtractor + + +class ConditionalDetrModelTester: + def __init__( + self, + parent, + batch_size=8, + is_training=True, + use_labels=True, + hidden_size=256, + num_hidden_layers=2, + num_attention_heads=8, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + num_queries=12, + num_channels=3, + min_size=200, + max_size=200, + n_targets=8, + num_labels=91, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.num_queries = num_queries + self.num_channels = num_channels + self.min_size = min_size + self.max_size = max_size + self.n_targets = n_targets + self.num_labels = num_labels + + # we also set the expected seq length for both encoder and decoder + self.encoder_seq_length = math.ceil(self.min_size / 32) * math.ceil(self.max_size / 32) + self.decoder_seq_length = self.num_queries + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.min_size, self.max_size]) + + pixel_mask = torch.ones([self.batch_size, self.min_size, self.max_size], device=torch_device) + + labels = None + if self.use_labels: + # labels is a list of Dict (each Dict being the labels for a given example in the batch) + labels = [] + for i in range(self.batch_size): + target = {} + target["class_labels"] = torch.randint( + high=self.num_labels, size=(self.n_targets,), device=torch_device + ) + target["boxes"] = torch.rand(self.n_targets, 4, device=torch_device) + target["masks"] = torch.rand(self.n_targets, self.min_size, self.max_size, device=torch_device) + labels.append(target) + + config = self.get_config() + return config, pixel_values, pixel_mask, labels + + def get_config(self): + return ConditionalDetrConfig( + 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, + num_queries=self.num_queries, + num_labels=self.num_labels, + ) + + def prepare_config_and_inputs_for_common(self): + config, pixel_values, pixel_mask, labels = self.prepare_config_and_inputs() + inputs_dict = {"pixel_values": pixel_values, "pixel_mask": pixel_mask} + return config, inputs_dict + + def create_and_check_conditional_detr_model(self, config, pixel_values, pixel_mask, labels): + model = ConditionalDetrModel(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.decoder_seq_length, self.hidden_size) + ) + + def create_and_check_conditional_detr_object_detection_head_model(self, config, pixel_values, pixel_mask, labels): + model = ConditionalDetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + def create_and_check_no_timm_backbone(self, config, pixel_values, pixel_mask, labels): + config.use_timm_backbone = False + config.backbone_config = ResNetConfig() + model = ConditionalDetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + +@require_timm +class ConditionalDetrModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + ConditionalDetrModel, + ConditionalDetrForObjectDetection, + ConditionalDetrForSegmentation, + ) + if is_timm_available() + else () + ) + pipeline_model_mapping = ( + {"feature-extraction": ConditionalDetrModel, "object-detection": ConditionalDetrForObjectDetection} + if is_timm_available() + else {} + ) + is_encoder_decoder = True + test_torchscript = False + test_pruning = False + test_head_masking = False + test_missing_keys = False + + # special case for head models + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ in ["ConditionalDetrForObjectDetection", "ConditionalDetrForSegmentation"]: + labels = [] + for i in range(self.model_tester.batch_size): + target = {} + target["class_labels"] = torch.ones( + size=(self.model_tester.n_targets,), device=torch_device, dtype=torch.long + ) + target["boxes"] = torch.ones( + self.model_tester.n_targets, 4, device=torch_device, dtype=torch.float + ) + target["masks"] = torch.ones( + self.model_tester.n_targets, + self.model_tester.min_size, + self.model_tester.max_size, + device=torch_device, + dtype=torch.float, + ) + labels.append(target) + inputs_dict["labels"] = labels + + return inputs_dict + + def setUp(self): + self.model_tester = ConditionalDetrModelTester(self) + self.config_tester = ConfigTester(self, config_class=ConditionalDetrConfig, has_text_modality=False) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_conditional_detr_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_conditional_detr_model(*config_and_inputs) + + def test_conditional_detr_object_detection_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_conditional_detr_object_detection_head_model(*config_and_inputs) + + def test_conditional_detr_no_timm_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_no_timm_backbone(*config_and_inputs) + + # TODO: check if this works again for PyTorch 2.x.y + @unittest.skip(reason="Got `CUDA error: misaligned address` with PyTorch 2.0.0.") + def test_multi_gpu_data_parallel_forward(self): + pass + + @unittest.skip(reason="Conditional DETR does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Conditional DETR does not have a get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="Conditional DETR is not a generative model") + def test_generate_without_input_ids(self): + pass + + @unittest.skip(reason="Conditional DETR does not use token embeddings") + def test_resize_tokens_embeddings(self): + pass + + @slow + def test_model_outputs_equivalence(self): + # TODO Niels: fix me! + pass + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + decoder_seq_length = self.model_tester.decoder_seq_length + encoder_seq_length = self.model_tester.encoder_seq_length + decoder_key_length = self.model_tester.decoder_seq_length + encoder_key_length = self.model_tester.encoder_seq_length + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 6 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Object Detection model returns pred_logits and pred_boxes + if model_class.__name__ == "ConditionalDetrForObjectDetection": + correct_outlen += 1 + # Panoptic Segmentation model returns pred_logits, pred_boxes, pred_masks + if model_class.__name__ == "ConditionalDetrForSegmentation": + correct_outlen += 2 + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + def test_retain_grad_hidden_states_attentions(self): + # removed retain_grad and grad on decoder_hidden_states, as queries don't require grad + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_attentions = outputs.encoder_attentions[0] + encoder_hidden_states.retain_grad() + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = ["pixel_values", "pixel_mask"] + expected_arg_names.extend( + ["head_mask", "decoder_head_mask", "encoder_outputs"] + if "head_mask" and "decoder_head_mask" in arg_names + else [] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["pixel_values", "pixel_mask"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_different_timm_backbone(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # let's pick a random timm backbone + config.backbone = "tf_mobilenetv3_small_075" + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if model_class.__name__ == "ConditionalDetrForObjectDetection": + expected_shape = ( + self.model_tester.batch_size, + self.model_tester.num_queries, + self.model_tester.num_labels, + ) + self.assertEqual(outputs.logits.shape, expected_shape) + + self.assertTrue(outputs) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + configs_no_init.init_xavier_std = 1e9 + + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + if "bbox_attention" in name and "bias" not in name: + self.assertLess( + 100000, + abs(param.data.max().item()), + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +TOLERANCE = 1e-4 + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_timm +@require_vision +@slow +class ConditionalDetrModelIntegrationTests(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + ConditionalDetrFeatureExtractor.from_pretrained("microsoft/conditional-detr-resnet-50") + if is_vision_available() + else None + ) + + def test_inference_no_head(self): + model = ConditionalDetrModel.from_pretrained("microsoft/conditional-detr-resnet-50").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**encoding) + + expected_shape = torch.Size((1, 300, 256)) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + expected_slice = torch.tensor( + [[0.4222, 0.7471, 0.8760], [0.6395, -0.2729, 0.7127], [-0.3090, 0.7642, 0.9529]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) + + def test_inference_object_detection_head(self): + model = ConditionalDetrForObjectDetection.from_pretrained("microsoft/conditional-detr-resnet-50").to( + torch_device + ) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + pixel_values = encoding["pixel_values"].to(torch_device) + pixel_mask = encoding["pixel_mask"].to(torch_device) + + with torch.no_grad(): + outputs = model(pixel_values, pixel_mask) + + # verify logits + box predictions + expected_shape_logits = torch.Size((1, model.config.num_queries, model.config.num_labels)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + expected_slice_logits = torch.tensor( + [[-10.4372, -5.7558, -8.6764], [-10.5410, -5.8704, -8.0590], [-10.6827, -6.3469, -8.3923]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_slice_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, model.config.num_queries, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + expected_slice_boxes = torch.tensor( + [[0.7733, 0.6576, 0.4496], [0.5171, 0.1184, 0.9094], [0.8846, 0.5647, 0.2486]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_slice_boxes, atol=1e-4)) + + # verify postprocessing + results = feature_extractor.post_process_object_detection( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + expected_scores = torch.tensor([0.8330, 0.8313, 0.8039, 0.6829, 0.5355]).to(torch_device) + expected_labels = [75, 17, 17, 75, 63] + expected_slice_boxes = torch.tensor([38.3089, 72.1022, 177.6293, 118.4512]).to(torch_device) + + self.assertEqual(len(results["scores"]), 5) + self.assertTrue(torch.allclose(results["scores"], expected_scores, atol=1e-4)) + self.assertSequenceEqual(results["labels"].tolist(), expected_labels) + self.assertTrue(torch.allclose(results["boxes"][0, :], expected_slice_boxes)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_convbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_convbert.py new file mode 100644 index 0000000000000000000000000000000000000000..dc1550acc2018392b78a5eef9b5236ee74a7a70e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_convbert.py @@ -0,0 +1,484 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ConvBERT model. """ +import os +import tempfile +import unittest + +from transformers import ConvBertConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_torch_gpu, slow, torch_device + +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 ( + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + ConvBertForMaskedLM, + ConvBertForMultipleChoice, + ConvBertForQuestionAnswering, + ConvBertForSequenceClassification, + ConvBertForTokenClassification, + ConvBertModel, + ) + from transformers.models.convbert.modeling_convbert import CONVBERT_PRETRAINED_MODEL_ARCHIVE_LIST + + +class ConvBertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return ConvBertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ConvBertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ConvBertForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ConvBertForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ConvBertForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ConvBertForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = ConvBertForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class ConvBertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + ConvBertModel, + ConvBertForMaskedLM, + ConvBertForMultipleChoice, + ConvBertForQuestionAnswering, + ConvBertForSequenceClassification, + ConvBertForTokenClassification, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": ConvBertModel, + "fill-mask": ConvBertForMaskedLM, + "question-answering": ConvBertForQuestionAnswering, + "text-classification": ConvBertForSequenceClassification, + "token-classification": ConvBertForTokenClassification, + "zero-shot": ConvBertForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = ConvBertModelTester(self) + self.config_tester = ConfigTester(self, config_class=ConvBertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in CONVBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ConvBertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + if chunk_length is not None: + self.assertListEqual( + list(attentions[0].shape[-4:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, chunk_length, encoder_key_length], + ) + else: + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Question Answering model returns start_logits and end_logits + if model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + if chunk_length is not None: + self.assertListEqual( + list(self_attentions[0].shape[-4:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, chunk_length, encoder_key_length], + ) + else: + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length], + ) + + @slow + @require_torch_gpu + def test_torchscript_device_change(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # ConvBertForMultipleChoice behaves incorrectly in JIT environments. + if model_class == ConvBertForMultipleChoice: + return + + config.torchscript = True + model = model_class(config=config) + + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + traced_model = torch.jit.trace( + model, (inputs_dict["input_ids"].to("cpu"), inputs_dict["attention_mask"].to("cpu")) + ) + + with tempfile.TemporaryDirectory() as tmp: + torch.jit.save(traced_model, os.path.join(tmp, "traced_model.pt")) + loaded = torch.jit.load(os.path.join(tmp, "traced_model.pt"), map_location=torch_device) + loaded(inputs_dict["input_ids"].to(torch_device), inputs_dict["attention_mask"].to(torch_device)) + + def test_model_for_input_embeds(self): + batch_size = 2 + seq_length = 10 + inputs_embeds = torch.rand([batch_size, seq_length, 768], device=torch_device) + config = self.model_tester.get_config() + model = ConvBertModel(config=config) + model.to(torch_device) + model.eval() + result = model(inputs_embeds=inputs_embeds) + self.assertEqual(result.last_hidden_state.shape, (batch_size, seq_length, config.hidden_size)) + + def test_reducing_attention_heads(self): + config, *inputs_dict = self.model_tester.prepare_config_and_inputs() + config.head_ratio = 4 + self.model_tester.create_and_check_for_masked_lm(config, *inputs_dict) + + +@require_torch +class ConvBertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head(self): + model = ConvBertModel.from_pretrained("YituTech/conv-bert-base") + input_ids = torch.tensor([[1, 2, 3, 4, 5, 6]]) + with torch.no_grad(): + output = model(input_ids)[0] + + expected_shape = torch.Size((1, 6, 768)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[[-0.0864, -0.4898, -0.3677], [0.1434, -0.2952, -0.7640], [-0.0112, -0.4432, -0.5432]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_tf_convbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_tf_convbert.py new file mode 100644 index 0000000000000000000000000000000000000000..0c259110e71626bc0045db14f6ef2cb6c98f73cf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convbert/test_modeling_tf_convbert.py @@ -0,0 +1,422 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import tempfile +import unittest + +from transformers import ConvBertConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFConvBertForMaskedLM, + TFConvBertForMultipleChoice, + TFConvBertForQuestionAnswering, + TFConvBertForSequenceClassification, + TFConvBertForTokenClassification, + TFConvBertModel, + ) + + +class TFConvBertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 384 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.embedding_size = 128 + self.head_ratio = 2 + self.conv_kernel_size = 9 + self.num_groups = 1 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = ConvBertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + return_dict=True, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFConvBertModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFConvBertForMaskedLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFConvBertForSequenceClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = TFConvBertForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFConvBertForTokenClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFConvBertForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFConvBertModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFConvBertModel, + TFConvBertForMaskedLM, + TFConvBertForQuestionAnswering, + TFConvBertForSequenceClassification, + TFConvBertForTokenClassification, + TFConvBertForMultipleChoice, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFConvBertModel, + "fill-mask": TFConvBertForMaskedLM, + "question-answering": TFConvBertForQuestionAnswering, + "text-classification": TFConvBertForSequenceClassification, + "token-classification": TFConvBertForTokenClassification, + "zero-shot": TFConvBertForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFConvBertModelTester(self) + self.config_tester = ConfigTester(self, config_class=ConvBertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_saved_model_creation_extended(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + if hasattr(config, "use_cache"): + config.use_cache = True + + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", self.model_tester.seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + + for model_class in self.all_model_classes: + class_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + num_out = len(model(class_inputs_dict)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=True) + saved_model_dir = os.path.join(tmpdirname, "saved_model", "1") + model = tf.keras.models.load_model(saved_model_dir) + outputs = model(class_inputs_dict) + + if self.is_encoder_decoder: + output_hidden_states = outputs["encoder_hidden_states"] + output_attentions = outputs["encoder_attentions"] + else: + output_hidden_states = outputs["hidden_states"] + output_attentions = outputs["attentions"] + + self.assertEqual(len(outputs), num_out) + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + self.assertEqual(len(output_hidden_states), expected_num_layers) + self.assertListEqual( + list(output_hidden_states[0].shape[-2:]), + [self.model_tester.seq_length, self.model_tester.hidden_size], + ) + + self.assertEqual(len(output_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(output_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length], + ) + + @slow + def test_model_from_pretrained(self): + model = TFConvBertModel.from_pretrained("YituTech/conv-bert-base") + self.assertIsNotNone(model) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", self.model_tester.seq_length) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", self.model_tester.seq_length) + decoder_key_length = getattr(self.model_tester, "key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + + def check_decoder_attentions_output(outputs): + out_len = len(outputs) + self.assertEqual(out_len % 2, 0) + decoder_attentions = outputs.decoder_attentions + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads / 2, decoder_seq_length, decoder_key_length], + ) + + def check_encoder_attentions_output(outputs): + attentions = [ + t.numpy() for t in (outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions) + ] + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads / 2, encoder_seq_length, encoder_key_length], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + out_len = len(outputs) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + if self.is_encoder_decoder: + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_decoder_attentions_output(outputs) + + # Check that output attentions can also be changed via the config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + self.assertEqual(out_len + (2 if self.is_encoder_decoder else 1), len(outputs)) + self.assertEqual(model.config.output_hidden_states, True) + check_encoder_attentions_output(outputs) + + +@require_tf +class TFConvBertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TFConvBertModel.from_pretrained("YituTech/conv-bert-base") + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + expected_shape = [1, 6, 768] + self.assertEqual(output.shape, expected_shape) + + expected_slice = tf.constant( + [ + [ + [-0.03475493, -0.4686034, -0.30638832], + [0.22637248, -0.26988646, -0.7423424], + [0.10324868, -0.45013508, -0.58280784], + ] + ] + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_image_processing_convnext.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_image_processing_convnext.py new file mode 100644 index 0000000000000000000000000000000000000000..ced0765c3528666c8c5038612d5d20164e474ecb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_image_processing_convnext.py @@ -0,0 +1,202 @@ +# coding=utf-8 +# Copyright 2022s HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import ConvNextImageProcessor + + +class ConvNextImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + crop_pct=0.875, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"shortest_edge": 20} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.crop_pct = crop_pct + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "size": self.size, + "crop_pct": self.crop_pct, + } + + +@require_torch +@require_vision +class ConvNextImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ConvNextImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = ConvNextImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "crop_pct")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 20}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"shortest_edge": 42}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["shortest_edge"], + self.image_processor_tester.size["shortest_edge"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_convnext.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_convnext.py new file mode 100644 index 0000000000000000000000000000000000000000..16d57d7e9646dbb56ee6c5d7572875f9fd690b4d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_convnext.py @@ -0,0 +1,320 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ConvNext model. """ + + +import inspect +import unittest + +from transformers import ConvNextConfig +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_backbone_common import BackboneTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ConvNextBackbone, ConvNextForImageClassification, ConvNextModel + from transformers.models.convnext.modeling_convnext import CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoFeatureExtractor + + +class ConvNextModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + num_channels=3, + num_stages=4, + hidden_sizes=[10, 20, 30, 40], + depths=[2, 2, 3, 2], + is_training=True, + use_labels=True, + intermediate_size=37, + hidden_act="gelu", + num_labels=10, + initializer_range=0.02, + out_features=["stage2", "stage3", "stage4"], + out_indices=[2, 3, 4], + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.num_stages = num_stages + self.hidden_sizes = hidden_sizes + self.depths = depths + self.is_training = is_training + self.use_labels = use_labels + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_labels = num_labels + self.initializer_range = initializer_range + self.out_features = out_features + self.out_indices = out_indices + self.scope = scope + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return ConvNextConfig( + num_channels=self.num_channels, + hidden_sizes=self.hidden_sizes, + depths=self.depths, + num_stages=self.num_stages, + hidden_act=self.hidden_act, + is_decoder=False, + initializer_range=self.initializer_range, + out_features=self.out_features, + out_indices=self.out_indices, + num_labels=self.num_labels, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = ConvNextModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + # expected last hidden states: B, C, H // 32, W // 32 + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32), + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + model = ConvNextForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_backbone(self, config, pixel_values, labels): + model = ConvNextBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify hidden states + self.parent.assertEqual(len(result.feature_maps), len(config.out_features)) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.hidden_sizes[1], 4, 4]) + + # verify channels + self.parent.assertEqual(len(model.channels), len(config.out_features)) + self.parent.assertListEqual(model.channels, config.hidden_sizes[1:]) + + # verify backbone works with out_features=None + config.out_features = None + model = ConvNextBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify feature maps + self.parent.assertEqual(len(result.feature_maps), 1) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.hidden_sizes[-1], 1, 1]) + + # verify channels + self.parent.assertEqual(len(model.channels), 1) + self.parent.assertListEqual(model.channels, [config.hidden_sizes[-1]]) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class ConvNextModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as ConvNext does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + ( + ConvNextModel, + ConvNextForImageClassification, + ConvNextBackbone, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + {"feature-extraction": ConvNextModel, "image-classification": ConvNextForImageClassification} + if is_torch_available() + else {} + ) + + fx_compatible = True + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = ConvNextModelTester(self) + self.config_tester = ConfigTester(self, config_class=ConvNextConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + @unittest.skip(reason="ConvNext does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="ConvNext does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="ConvNext does not use feedforward chunking") + def test_feed_forward_chunking(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_backbone(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_stages = self.model_tester.num_stages + self.assertEqual(len(hidden_states), expected_num_stages + 1) + + # ConvNext's feature maps are of shape (batch_size, num_channels, height, width) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.image_size // 4, self.model_tester.image_size // 4], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ConvNextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class ConvNextModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return AutoFeatureExtractor.from_pretrained("facebook/convnext-tiny-224") if is_vision_available() else None + + @slow + def test_inference_image_classification_head(self): + model = ConvNextForImageClassification.from_pretrained("facebook/convnext-tiny-224").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([-0.0260, -0.4739, 0.1911]).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) + + +@require_torch +class ConvNextBackboneTest(unittest.TestCase, BackboneTesterMixin): + all_model_classes = (ConvNextBackbone,) if is_torch_available() else () + config_class = ConvNextConfig + + has_attentions = False + + def setUp(self): + self.model_tester = ConvNextModelTester(self) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_tf_convnext.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_tf_convnext.py new file mode 100644 index 0000000000000000000000000000000000000000..72981c09d65e450e19b526ad4bf14126f7766ef1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnext/test_modeling_tf_convnext.py @@ -0,0 +1,301 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the TensorFlow ConvNext model. """ + +import inspect +import unittest +from typing import List, Tuple + +from transformers import ConvNextConfig +from transformers.testing_utils import require_tf, require_vision, slow +from transformers.utils import cached_property, is_tf_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import TFConvNextForImageClassification, TFConvNextModel + + +if is_vision_available(): + from PIL import Image + + from transformers import ConvNextFeatureExtractor + + +class TFConvNextModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + num_channels=3, + num_stages=4, + hidden_sizes=[10, 20, 30, 40], + depths=[2, 2, 3, 2], + is_training=True, + use_labels=True, + intermediate_size=37, + hidden_act="gelu", + type_sequence_label_size=10, + initializer_range=0.02, + num_labels=3, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.num_stages = num_stages + self.hidden_sizes = hidden_sizes + self.depths = depths + self.is_training = is_training + self.use_labels = use_labels + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return ConvNextConfig( + num_channels=self.num_channels, + hidden_sizes=self.hidden_sizes, + depths=self.depths, + num_stages=self.num_stages, + hidden_act=self.hidden_act, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = TFConvNextModel(config=config) + result = model(pixel_values, training=False) + # expected last hidden states: B, C, H // 32, W // 32 + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32), + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.type_sequence_label_size + model = TFConvNextForImageClassification(config) + result = model(pixel_values, labels=labels, training=False) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_tf +class TFConvNextModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as ConvNext does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (TFConvNextModel, TFConvNextForImageClassification) if is_tf_available() else () + pipeline_model_mapping = ( + {"feature-extraction": TFConvNextModel, "image-classification": TFConvNextForImageClassification} + if is_tf_available() + else {} + ) + + test_pruning = False + test_onnx = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = TFConvNextModelTester(self) + self.config_tester = ConfigTester( + self, + config_class=ConvNextConfig, + has_text_modality=False, + hidden_size=37, + ) + + @unittest.skip(reason="ConvNext does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) == 0, + reason="TF does not support backprop for grouped convolutions on CPU.", + ) + def test_keras_fit(self): + super().test_keras_fit() + + @unittest.skip(reason="ConvNext does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) == 0, + reason="TF does not support backprop for grouped convolutions on CPU.", + ) + def test_dataset_conversion(self): + super().test_dataset_conversion() + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_stages = self.model_tester.num_stages + self.assertEqual(len(hidden_states), expected_num_stages + 1) + + # ConvNext's feature maps are of shape (batch_size, num_channels, height, width) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.image_size // 4, self.model_tester.image_size // 4], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + # Since ConvNext does not have any attention we need to rewrite this test. + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + tuple_output = model(tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + all(tf.equal(tuple_object, dict_object)), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {tf.math.reduce_max(tf.abs(tuple_object - dict_object))}" + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + model = model_class(config) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + model = TFConvNextModel.from_pretrained("facebook/convnext-tiny-224") + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_tf +@require_vision +class TFConvNextModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + ConvNextFeatureExtractor.from_pretrained("facebook/convnext-tiny-224") if is_vision_available() else None + ) + + @slow + def test_inference_image_classification_head(self): + model = TFConvNextForImageClassification.from_pretrained("facebook/convnext-tiny-224") + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="tf") + + # forward pass + outputs = model(**inputs) + + # verify the logits + expected_shape = tf.TensorShape((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = tf.constant([-0.0260, -0.4739, 0.1911]) + + tf.debugging.assert_near(outputs.logits[0, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnextv2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnextv2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnextv2/test_modeling_convnextv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnextv2/test_modeling_convnextv2.py new file mode 100644 index 0000000000000000000000000000000000000000..85ce5b1813bb5e86dcfa7a81dab06e795f3ee00b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/convnextv2/test_modeling_convnextv2.py @@ -0,0 +1,357 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ConvNextV2 model. """ + + +import inspect +import unittest + +from transformers import ConvNextV2Config +from transformers.models.auto import get_values +from transformers.models.auto.modeling_auto import MODEL_FOR_BACKBONE_MAPPING_NAMES, MODEL_MAPPING_NAMES +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ConvNextV2Backbone, ConvNextV2ForImageClassification, ConvNextV2Model + from transformers.models.convnextv2.modeling_convnextv2 import CONVNEXTV2_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoImageProcessor + + +class ConvNextV2ModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + num_channels=3, + num_stages=4, + hidden_sizes=[10, 20, 30, 40], + depths=[2, 2, 3, 2], + is_training=True, + use_labels=True, + intermediate_size=37, + hidden_act="gelu", + num_labels=10, + initializer_range=0.02, + out_features=["stage2", "stage3", "stage4"], + out_indices=[2, 3, 4], + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.num_stages = num_stages + self.hidden_sizes = hidden_sizes + self.depths = depths + self.is_training = is_training + self.use_labels = use_labels + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.num_labels = num_labels + self.initializer_range = initializer_range + self.out_features = out_features + self.out_indices = out_indices + self.scope = scope + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return ConvNextV2Config( + num_channels=self.num_channels, + hidden_sizes=self.hidden_sizes, + depths=self.depths, + num_stages=self.num_stages, + hidden_act=self.hidden_act, + is_decoder=False, + initializer_range=self.initializer_range, + out_features=self.out_features, + out_indices=self.out_indices, + num_labels=self.num_labels, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = ConvNextV2Model(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + # expected last hidden states: B, C, H // 32, W // 32 + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32), + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + model = ConvNextV2ForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_backbone(self, config, pixel_values, labels): + model = ConvNextV2Backbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify hidden states + self.parent.assertEqual(len(result.feature_maps), len(config.out_features)) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.hidden_sizes[1], 4, 4]) + + # verify channels + self.parent.assertEqual(len(model.channels), len(config.out_features)) + self.parent.assertListEqual(model.channels, config.hidden_sizes[1:]) + + # verify backbone works with out_features=None + config.out_features = None + model = ConvNextV2Backbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify feature maps + self.parent.assertEqual(len(result.feature_maps), 1) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.hidden_sizes[-1], 1, 1]) + + # verify channels + self.parent.assertEqual(len(model.channels), 1) + self.parent.assertListEqual(model.channels, [config.hidden_sizes[-1]]) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + def prepare_config_and_inputs_with_labels(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values, "labels": labels} + return config, inputs_dict + + +@require_torch +class ConvNextV2ModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as ConvNextV2 does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + ( + ConvNextV2Model, + ConvNextV2ForImageClassification, + ConvNextV2Backbone, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + {"feature-extraction": ConvNextV2Model, "image-classification": ConvNextV2ForImageClassification} + if is_torch_available() + else {} + ) + + fx_compatible = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = ConvNextV2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=ConvNextV2Config, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + @unittest.skip(reason="ConvNextV2 does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="ConvNextV2 does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="ConvNextV2 does not use feedforward chunking") + def test_feed_forward_chunking(self): + pass + + def test_training(self): + if not self.model_tester.is_training: + return + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_with_labels() + config.return_dict = True + + if model_class.__name__ in [ + *get_values(MODEL_MAPPING_NAMES), + *get_values(MODEL_FOR_BACKBONE_MAPPING_NAMES), + ]: + continue + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + if not self.model_tester.is_training: + return + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_with_labels() + config.use_cache = False + config.return_dict = True + + if ( + model_class.__name__ + in [*get_values(MODEL_MAPPING_NAMES), *get_values(MODEL_FOR_BACKBONE_MAPPING_NAMES)] + or not model_class.supports_gradient_checkpointing + ): + continue + + model = model_class(config) + model.to(torch_device) + model.gradient_checkpointing_enable() + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_stages = self.model_tester.num_stages + self.assertEqual(len(hidden_states), expected_num_stages + 1) + + # ConvNextV2's feature maps are of shape (batch_size, num_channels, height, width) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.image_size // 4, self.model_tester.image_size // 4], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in CONVNEXTV2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ConvNextV2Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class ConvNextV2ModelIntegrationTest(unittest.TestCase): + @cached_property + def default_image_processor(self): + return AutoImageProcessor.from_pretrained("facebook/convnextv2-tiny-1k-224") if is_vision_available() else None + + @slow + def test_inference_image_classification_head(self): + model = ConvNextV2ForImageClassification.from_pretrained("facebook/convnextv2-tiny-1k-224").to(torch_device) + + preprocessor = self.default_image_processor + image = prepare_img() + inputs = preprocessor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([-0.3083, -0.3040, -0.4344]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpm/test_tokenization_cpm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpm/test_tokenization_cpm.py new file mode 100644 index 0000000000000000000000000000000000000000..fa69a6aaa7dcb612428596bbb79cd6ab13086f88 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpm/test_tokenization_cpm.py @@ -0,0 +1,45 @@ +# coding=utf-8 +# Copyright 2018 HuggingFace Inc. team. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from transformers.models.cpm.tokenization_cpm import CpmTokenizer +from transformers.testing_utils import custom_tokenizers + +from ..xlnet.test_modeling_xlnet import XLNetModelTest + + +@custom_tokenizers +class CpmTokenizationTest(XLNetModelTest): + # There is no `CpmModel` + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + return True + + def test_pre_tokenization(self): + tokenizer = CpmTokenizer.from_pretrained("TsinghuaAI/CPM-Generate") + text = "Hugging Face大法好,谁用谁知道。" + normalized_text = "Hugging Face大法好,谁用谁知道。" + bpe_tokens = "▁Hu gg ing ▁ ▂ ▁F ace ▁大法 ▁好 ▁ , ▁谁 ▁用 ▁谁 ▁知 道 ▁ 。".split() + + tokens = tokenizer.tokenize(text) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + + input_bpe_tokens = [13789, 13283, 1421, 8, 10, 1164, 13608, 16528, 63, 8, 9, 440, 108, 440, 121, 90, 8, 12, 0] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + reconstructed_text = tokenizer.decode(input_bpe_tokens) + self.assertEqual(reconstructed_text, normalized_text) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_modeling_cpmant.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_modeling_cpmant.py new file mode 100644 index 0000000000000000000000000000000000000000..61cd0ec17e2d83b706022f45d6afa9bf9ca6ddf7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_modeling_cpmant.py @@ -0,0 +1,233 @@ +# coding=utf-8 +# Copyright 2022 The OpenBMB Team and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CPMAnt model. """ + +import unittest + +from transformers.testing_utils import is_torch_available, require_torch, tooslow + +from ...generation.test_utils import torch_device +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor + + +if is_torch_available(): + import torch + + from transformers import ( + CpmAntConfig, + CpmAntForCausalLM, + CpmAntModel, + CpmAntTokenizer, + ) + + +@require_torch +class CpmAntModelTester: + def __init__( + self, + parent, + batch_size=2, + seq_length=8, + is_training=True, + use_token_type_ids=False, + use_input_mask=False, + use_labels=False, + use_mc_token_ids=False, + vocab_size=99, + hidden_size=32, + num_hidden_layers=3, + num_attention_heads=4, + intermediate_size=37, + num_buckets=32, + max_distance=128, + prompt_length=8, + prompt_types=8, + segment_types=8, + init_std=1.0, + return_dict=True, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.num_buckets = num_buckets + self.max_distance = max_distance + self.prompt_length = prompt_length + self.prompt_types = prompt_types + self.segment_types = segment_types + self.init_std = init_std + self.return_dict = return_dict + + def prepare_config_and_inputs(self): + input_ids = {} + input_ids["input_ids"] = ids_tensor([self.batch_size, self.seq_length], self.vocab_size).type(torch.int32) + input_ids["use_cache"] = False + + config = self.get_config() + + return (config, input_ids) + + def get_config(self): + return CpmAntConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + dim_ff=self.intermediate_size, + position_bias_num_buckets=self.num_buckets, + position_bias_max_distance=self.max_distance, + prompt_types=self.prompt_types, + prompt_length=self.prompt_length, + segment_types=self.segment_types, + use_cache=True, + init_std=self.init_std, + return_dict=self.return_dict, + ) + + def create_and_check_cpmant_model(self, config, input_ids, *args): + model = CpmAntModel(config=config) + model.to(torch_device) + model.eval() + + hidden_states = model(**input_ids).last_hidden_state + + self.parent.assertEqual(hidden_states.shape, (self.batch_size, self.seq_length, config.hidden_size)) + + def create_and_check_lm_head_model(self, config, input_ids, *args): + model = CpmAntForCausalLM(config) + model.to(torch_device) + input_ids["input_ids"] = input_ids["input_ids"].to(torch_device) + model.eval() + + model_output = model(**input_ids) + self.parent.assertEqual( + model_output.logits.shape, + (self.batch_size, self.seq_length, config.vocab_size + config.prompt_types * config.prompt_length), + ) + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + +@require_torch +class CpmAntModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (CpmAntModel, CpmAntForCausalLM) if is_torch_available() else () + + test_pruning = False + test_missing_keys = False + test_mismatched_shapes = False + test_head_masking = False + test_resize_embeddings = False + + def setUp(self): + self.model_tester = CpmAntModelTester(self) + self.config_tester = ConfigTester(self, config_class=CpmAntConfig) + + def test_config(self): + self.config_tester.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def test_inputs_embeds(self): + unittest.skip("CPMAnt doesn't support input_embeds.")(self.test_inputs_embeds) + + def test_retain_grad_hidden_states_attentions(self): + unittest.skip( + "CPMAnt doesn't support retain grad in hidden_states or attentions, because prompt management will peel off the output.hidden_states from graph.\ + So is attentions. We strongly recommand you use loss to tune model." + )(self.test_retain_grad_hidden_states_attentions) + + def test_cpmant_model(self): + config, inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_cpmant_model(config, inputs) + + def test_cpmant_lm_head_model(self): + config, inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(config, inputs) + + +@require_torch +class CpmAntModelIntegrationTest(unittest.TestCase): + @tooslow + def test_inference_masked_lm(self): + texts = "今天天气真好!" + model_path = "openbmb/cpm-ant-10b" + model = CpmAntModel.from_pretrained(model_path) + tokenizer = CpmAntTokenizer.from_pretrained(model_path) + inputs = tokenizer(texts, return_tensors="pt") + hidden_states = model(**inputs).last_hidden_state + + expected_slice = torch.tensor( + [[[6.1708, 5.9244, 1.0835], [6.5207, 6.2893, -11.3324], [-1.0107, -0.0576, -5.9577]]], + ) + self.assertTrue(torch.allclose(hidden_states[:, :3, :3], expected_slice, atol=1e-2)) + + +@require_torch +class CpmAntForCausalLMlIntegrationTest(unittest.TestCase): + @tooslow + def test_inference_casual(self): + texts = "今天天气真好!" + model_path = "openbmb/cpm-ant-10b" + model = CpmAntForCausalLM.from_pretrained(model_path) + tokenizer = CpmAntTokenizer.from_pretrained(model_path) + inputs = tokenizer(texts, return_tensors="pt") + hidden_states = model(**inputs).logits + + expected_slice = torch.tensor( + [[[-6.4267, -6.4083, -6.3958], [-5.8802, -5.9447, -5.7811], [-5.3896, -5.4820, -5.4295]]], + ) + self.assertTrue(torch.allclose(hidden_states[:, :3, :3], expected_slice, atol=1e-2)) + + @tooslow + def test_simple_generation(self): + model_path = "openbmb/cpm-ant-10b" + model = CpmAntForCausalLM.from_pretrained(model_path) + tokenizer = CpmAntTokenizer.from_pretrained(model_path) + texts = "今天天气不错," + expected_output = "今天天气不错,阳光明媚,我和妈妈一起去超市买东西。\n在超市里,我看到了一个很好玩的玩具,它的名字叫“机器人”。它有一个圆圆的脑袋,两只圆圆的眼睛,还有一个圆圆的" + model_inputs = tokenizer(texts, return_tensors="pt") + token_ids = model.generate(**model_inputs) + output_texts = tokenizer.batch_decode(token_ids) + self.assertEqual(expected_output, output_texts) + + @tooslow + def test_batch_generation(self): + model_path = "openbmb/cpm-ant-10b" + model = CpmAntForCausalLM.from_pretrained(model_path) + tokenizer = CpmAntTokenizer.from_pretrained(model_path) + texts = ["今天天气不错,", "新年快乐,万事如意!"] + expected_output = [ + "今天天气不错,阳光明媚,我和妈妈一起去超市买东西。\n在超市里,我看到了一个很好玩的玩具,它的名字叫“机器人”。它有一个圆圆的脑袋,两只圆圆的眼睛,还有一个圆圆的", + "新年快乐,万事如意!在这辞旧迎新的美好时刻,我谨代表《农村新技术》杂志社全体同仁,向一直以来关心、支持《农村新技术》杂志发展的各级领导、各界朋友和广大读者致以最诚挚的", + ] + model_inputs = tokenizer(texts, return_tensors="pt", padding=True) + token_ids = model.generate(**model_inputs) + output_texts = tokenizer.batch_decode(token_ids) + self.assertEqual(expected_output, output_texts) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_tokenization_cpmant.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_tokenization_cpmant.py new file mode 100644 index 0000000000000000000000000000000000000000..f5d0ef32450bcc66598e94d0ff378c955f928c68 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cpmant/test_tokenization_cpmant.py @@ -0,0 +1,69 @@ +# coding=utf-8 +# Copyright 2022 The OpenBMB Team and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest + +from transformers.models.cpmant.tokenization_cpmant import VOCAB_FILES_NAMES, CpmAntTokenizer +from transformers.testing_utils import require_jieba, tooslow + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_jieba +class CPMAntTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = CpmAntTokenizer + test_rust_tokenizer = False + + def setUp(self): + super().setUp() + + vocab_tokens = [ + "", + "", + "", + "", + "", + "", + "", + "", + "我", + "是", + "C", + "P", + "M", + "A", + "n", + "t", + ] + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + @tooslow + def test_pre_tokenization(self): + tokenizer = CpmAntTokenizer.from_pretrained("openbmb/cpm-ant-10b") + texts = "今天天气真好!" + jieba_tokens = ["今天", "天气", "真", "好", "!"] + tokens = tokenizer.tokenize(texts) + self.assertListEqual(tokens, jieba_tokens) + normalized_text = "今天天气真好!" + input_tokens = [tokenizer.bos_token] + tokens + + input_jieba_tokens = [6, 9802, 14962, 2082, 831, 244] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_jieba_tokens) + + reconstructed_text = tokenizer.decode(input_jieba_tokens) + self.assertEqual(reconstructed_text, normalized_text) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_ctrl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_ctrl.py new file mode 100644 index 0000000000000000000000000000000000000000..87d719853ad7d7d1919248372e32e652a7617394 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_ctrl.py @@ -0,0 +1,292 @@ +# coding=utf-8 +# Copyright 2018 Salesforce and HuggingFace Inc. team. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import gc +import unittest + +from transformers import CTRLConfig, 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, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + CTRL_PRETRAINED_MODEL_ARCHIVE_LIST, + CTRLForSequenceClassification, + CTRLLMHeadModel, + CTRLModel, + ) + + +class CTRLModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.pad_token_id = self.vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config(self): + return CTRLConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + # intermediate_size=self.intermediate_size, + # hidden_act=self.hidden_act, + # hidden_dropout_prob=self.hidden_dropout_prob, + # attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + # type_vocab_size=self.type_vocab_size, + # initializer_range=self.initializer_range, + pad_token_id=self.pad_token_id, + ) + + def create_and_check_ctrl_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = CTRLModel(config=config) + model.to(torch_device) + model.eval() + + model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = CTRLLMHeadModel(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "head_mask": head_mask} + + return config, inputs_dict + + def create_and_check_ctrl_for_sequence_classification(self, config, input_ids, head_mask, token_type_ids, *args): + config.num_labels = self.num_labels + model = CTRLForSequenceClassification(config) + model.to(torch_device) + model.eval() + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + result = model(input_ids, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + +@require_torch +class CTRLModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (CTRLModel, CTRLLMHeadModel, CTRLForSequenceClassification) if is_torch_available() else () + all_generative_model_classes = (CTRLLMHeadModel,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": CTRLModel, + "text-classification": CTRLForSequenceClassification, + "text-generation": CTRLLMHeadModel, + "zero-shot": CTRLForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_pruning = True + test_resize_embeddings = False + test_head_masking = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "ZeroShotClassificationPipelineTests": + # Get `tokenizer does not have a padding token` error for both fast/slow tokenizers. + # `CTRLConfig` was never used in pipeline tests, either because of a missing checkpoint or because a tiny + # config could not be created. + return True + + return False + + def setUp(self): + self.model_tester = CTRLModelTester(self) + self.config_tester = ConfigTester(self, config_class=CTRLConfig, n_embd=37) + + def tearDown(self): + super().tearDown() + # clean-up as much as possible GPU memory occupied by PyTorch + gc.collect() + torch.cuda.empty_cache() + + def test_config(self): + self.config_tester.run_common_tests() + + def test_ctrl_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_ctrl_model(*config_and_inputs) + + def test_ctrl_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in CTRL_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CTRLModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class CTRLModelLanguageGenerationTest(unittest.TestCase): + def tearDown(self): + super().tearDown() + # clean-up as much as possible GPU memory occupied by PyTorch + gc.collect() + torch.cuda.empty_cache() + + @slow + def test_lm_generate_ctrl(self): + model = CTRLLMHeadModel.from_pretrained("ctrl") + model.to(torch_device) + input_ids = torch.tensor( + [[11859, 0, 1611, 8]], dtype=torch.long, device=torch_device + ) # Legal the president is + expected_output_ids = [ + 11859, + 0, + 1611, + 8, + 5, + 150, + 26449, + 2, + 19, + 348, + 469, + 3, + 2595, + 48, + 20740, + 246533, + 246533, + 19, + 30, + 5, + ] # Legal the president is a good guy and I don't want to lose my job. \n \n I have a + + output_ids = model.generate(input_ids, do_sample=False) + self.assertListEqual(output_ids[0].tolist(), expected_output_ids) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_tf_ctrl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_tf_ctrl.py new file mode 100644 index 0000000000000000000000000000000000000000..c71c96bc9da98237d1cb78ab6e0292d1a2a1d89f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_modeling_tf_ctrl.py @@ -0,0 +1,283 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import CTRLConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.ctrl.modeling_tf_ctrl import ( + TF_CTRL_PRETRAINED_MODEL_ARCHIVE_LIST, + TFCTRLForSequenceClassification, + TFCTRLLMHeadModel, + TFCTRLModel, + ) + + +class TFCTRLModelTester(object): + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_token_type_ids = True + self.use_input_mask = True + self.use_labels = True + self.use_mc_token_ids = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + self.pad_token_id = self.vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = CTRLConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + # intermediate_size=self.intermediate_size, + # hidden_act=self.hidden_act, + # hidden_dropout_prob=self.hidden_dropout_prob, + # attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + # type_vocab_size=self.type_vocab_size, + # initializer_range=self.initializer_range, + pad_token_id=self.pad_token_id, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def create_and_check_ctrl_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFCTRLModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, None, input_mask] # None is the input for 'past' + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_ctrl_lm_head(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFCTRLLMHeadModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_ctrl_for_sequence_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + config.num_labels = self.num_labels + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + inputs = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "labels": sequence_labels, + } + model = TFCTRLForSequenceClassification(config) + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFCTRLModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFCTRLModel, TFCTRLLMHeadModel, TFCTRLForSequenceClassification) if is_tf_available() else () + all_generative_model_classes = (TFCTRLLMHeadModel,) if is_tf_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": TFCTRLModel, + "text-classification": TFCTRLForSequenceClassification, + "text-generation": TFCTRLLMHeadModel, + "zero-shot": TFCTRLForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "ZeroShotClassificationPipelineTests": + # Get `tokenizer does not have a padding token` error for both fast/slow tokenizers. + # `CTRLConfig` was never used in pipeline tests, either because of a missing checkpoint or because a tiny + # config could not be created. + return True + + return False + + def setUp(self): + self.model_tester = TFCTRLModelTester(self) + self.config_tester = ConfigTester(self, config_class=CTRLConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_ctrl_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_ctrl_model(*config_and_inputs) + + def test_ctrl_lm_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_ctrl_lm_head(*config_and_inputs) + + def test_ctrl_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_ctrl_for_sequence_classification(*config_and_inputs) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + list_lm_models = [TFCTRLLMHeadModel] + list_other_models_with_output_ebd = [TFCTRLForSequenceClassification] + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in list_lm_models: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + elif model_class in list_other_models_with_output_ebd: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert name is None + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + @slow + def test_model_from_pretrained(self): + for model_name in TF_CTRL_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFCTRLModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_tf +class TFCTRLModelLanguageGenerationTest(unittest.TestCase): + @slow + def test_lm_generate_ctrl(self): + model = TFCTRLLMHeadModel.from_pretrained("ctrl") + input_ids = tf.convert_to_tensor([[11859, 0, 1611, 8]], dtype=tf.int32) # Legal the president is + expected_output_ids = [ + 11859, + 0, + 1611, + 8, + 5, + 150, + 26449, + 2, + 19, + 348, + 469, + 3, + 2595, + 48, + 20740, + 246533, + 246533, + 19, + 30, + 5, + ] # Legal the president is a good guy and I don't want to lose my job. \n \n I have a + + output_ids = model.generate(input_ids, do_sample=False) + self.assertListEqual(output_ids[0].numpy().tolist(), expected_output_ids) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_tokenization_ctrl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_tokenization_ctrl.py new file mode 100644 index 0000000000000000000000000000000000000000..02c3459f9e04615785494332865939891e1edb8b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ctrl/test_tokenization_ctrl.py @@ -0,0 +1,65 @@ +# coding=utf-8 +# Copyright 2018 Salesforce and HuggingFace Inc. team. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers.models.ctrl.tokenization_ctrl import VOCAB_FILES_NAMES, CTRLTokenizer + +from ...test_tokenization_common import TokenizerTesterMixin + + +class CTRLTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = CTRLTokenizer + test_rust_tokenizer = False + test_seq2seq = False + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = ["adapt", "re@@", "a@@", "apt", "c@@", "t", ""] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "a p", "ap t", "r e", "a d", "ad apt", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return CTRLTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "adapt react readapt apt" + output_text = "adapt react readapt apt" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = CTRLTokenizer(self.vocab_file, self.merges_file, **self.special_tokens_map) + text = "adapt react readapt apt" + bpe_tokens = "adapt re@@ a@@ c@@ t re@@ adapt apt".split() + tokens = tokenizer.tokenize(text) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + + input_bpe_tokens = [0, 1, 2, 4, 5, 1, 0, 3, 6] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_cvt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_cvt.py new file mode 100644 index 0000000000000000000000000000000000000000..35ecf5021728d5a5abe971272136cca21de7cf3e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_cvt.py @@ -0,0 +1,288 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch CvT model. """ + + +import inspect +import unittest +from math import floor + +from transformers import CvtConfig +from transformers.file_utils import cached_property, is_torch_available, is_vision_available +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import CvtForImageClassification, CvtModel + from transformers.models.cvt.modeling_cvt import CVT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoFeatureExtractor + + +class CvtConfigTester(ConfigTester): + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + self.parent.assertTrue(hasattr(config, "embed_dim")) + self.parent.assertTrue(hasattr(config, "num_heads")) + + +class CvtModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=64, + num_channels=3, + embed_dim=[16, 48, 96], + num_heads=[1, 3, 6], + depth=[1, 2, 10], + patch_sizes=[7, 3, 3], + patch_stride=[4, 2, 2], + patch_padding=[2, 1, 1], + stride_kv=[2, 2, 2], + cls_token=[False, False, True], + attention_drop_rate=[0.0, 0.0, 0.0], + initializer_range=0.02, + layer_norm_eps=1e-12, + is_training=True, + use_labels=True, + num_labels=2, # Check + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_sizes = patch_sizes + self.patch_stride = patch_stride + self.patch_padding = patch_padding + self.is_training = is_training + self.use_labels = use_labels + self.num_labels = num_labels + self.num_channels = num_channels + self.embed_dim = embed_dim + self.num_heads = num_heads + self.stride_kv = stride_kv + self.depth = depth + self.cls_token = cls_token + self.attention_drop_rate = attention_drop_rate + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return CvtConfig( + image_size=self.image_size, + num_labels=self.num_labels, + num_channels=self.num_channels, + embed_dim=self.embed_dim, + num_heads=self.num_heads, + patch_sizes=self.patch_sizes, + patch_padding=self.patch_padding, + patch_stride=self.patch_stride, + stride_kv=self.stride_kv, + depth=self.depth, + cls_token=self.cls_token, + attention_drop_rate=self.attention_drop_rate, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = CvtModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + image_size = (self.image_size, self.image_size) + height, width = image_size[0], image_size[1] + for i in range(len(self.depth)): + height = floor(((height + 2 * self.patch_padding[i] - self.patch_sizes[i]) / self.patch_stride[i]) + 1) + width = floor(((width + 2 * self.patch_padding[i] - self.patch_sizes[i]) / self.patch_stride[i]) + 1) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.embed_dim[-1], height, width)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = CvtForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class CvtModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as Cvt does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (CvtModel, CvtForImageClassification) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": CvtModel, "image-classification": CvtForImageClassification} + if is_torch_available() + else {} + ) + + test_pruning = False + test_torchscript = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = CvtModelTester(self) + self.config_tester = ConfigTester(self, config_class=CvtConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + @unittest.skip(reason="Cvt does not output attentions") + def test_attention_outputs(self): + pass + + @unittest.skip(reason="Cvt does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Cvt does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = len(self.model_tester.depth) + self.assertEqual(len(hidden_states), expected_num_layers) + + # verify the first hidden states (first block) + self.assertListEqual( + list(hidden_states[0].shape[-3:]), + [ + self.model_tester.embed_dim[0], + self.model_tester.image_size // 4, + self.model_tester.image_size // 4, + ], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in CVT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = CvtModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class CvtModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return AutoFeatureExtractor.from_pretrained(CVT_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + + @slow + def test_inference_image_classification_head(self): + model = CvtForImageClassification.from_pretrained(CVT_PRETRAINED_MODEL_ARCHIVE_LIST[0]).to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([0.9285, 0.9015, -0.3150]).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_tf_cvt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_tf_cvt.py new file mode 100644 index 0000000000000000000000000000000000000000..484bd295d17291dae5b0e16ef251881703674ab1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/cvt/test_modeling_tf_cvt.py @@ -0,0 +1,283 @@ +""" Testing suite for the Tensorflow CvT model. """ + + +import inspect +import unittest +from math import floor + +import numpy as np + +from transformers import CvtConfig +from transformers.testing_utils import require_tf, require_vision, slow +from transformers.utils import cached_property, is_tf_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import TFCvtForImageClassification, TFCvtModel + from transformers.models.cvt.modeling_tf_cvt import TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoFeatureExtractor + + +class TFCvtConfigTester(ConfigTester): + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + self.parent.assertTrue(hasattr(config, "embed_dim")) + self.parent.assertTrue(hasattr(config, "num_heads")) + + +class TFCvtModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=64, + num_channels=3, + embed_dim=[16, 48, 96], + num_heads=[1, 3, 6], + depth=[1, 2, 10], + patch_sizes=[7, 3, 3], + patch_stride=[4, 2, 2], + patch_padding=[2, 1, 1], + stride_kv=[2, 2, 2], + cls_token=[False, False, True], + attention_drop_rate=[0.0, 0.0, 0.0], + initializer_range=0.02, + layer_norm_eps=1e-12, + is_training=True, + use_labels=True, + num_labels=2, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_sizes = patch_sizes + self.patch_stride = patch_stride + self.patch_padding = patch_padding + self.is_training = is_training + self.use_labels = use_labels + self.num_labels = num_labels + self.num_channels = num_channels + self.embed_dim = embed_dim + self.num_heads = num_heads + self.stride_kv = stride_kv + self.depth = depth + self.cls_token = cls_token + self.attention_drop_rate = attention_drop_rate + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + # create a random int32 tensor of given shape + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return CvtConfig( + image_size=self.image_size, + num_labels=self.num_labels, + num_channels=self.num_channels, + embed_dim=self.embed_dim, + num_heads=self.num_heads, + patch_sizes=self.patch_sizes, + patch_padding=self.patch_padding, + patch_stride=self.patch_stride, + stride_kv=self.stride_kv, + depth=self.depth, + cls_token=self.cls_token, + attention_drop_rate=self.attention_drop_rate, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = TFCvtModel(config=config) + result = model(pixel_values, training=False) + image_size = (self.image_size, self.image_size) + height, width = image_size[0], image_size[1] + for i in range(len(self.depth)): + height = floor(((height + 2 * self.patch_padding[i] - self.patch_sizes[i]) / self.patch_stride[i]) + 1) + width = floor(((width + 2 * self.patch_padding[i] - self.patch_sizes[i]) / self.patch_stride[i]) + 1) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.embed_dim[-1], height, width)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = TFCvtForImageClassification(config) + result = model(pixel_values, labels=labels, training=False) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_tf +class TFCvtModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as Cvt + does not use input_ids, inputs_embeds, attention_mask and seq_length. + """ + + all_model_classes = (TFCvtModel, TFCvtForImageClassification) if is_tf_available() else () + pipeline_model_mapping = ( + {"feature-extraction": TFCvtModel, "image-classification": TFCvtForImageClassification} + if is_tf_available() + else {} + ) + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + test_onnx = False + + def setUp(self): + self.model_tester = TFCvtModelTester(self) + self.config_tester = TFCvtConfigTester(self, config_class=CvtConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + @unittest.skip(reason="Cvt does not output attentions") + def test_attention_outputs(self): + pass + + @unittest.skip(reason="Cvt does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Cvt does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) == 0, + reason="TF does not support backprop for grouped convolutions on CPU.", + ) + def test_dataset_conversion(self): + super().test_dataset_conversion() + + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) == 0, + reason="TF does not support backprop for grouped convolutions on CPU.", + ) + def test_keras_fit(self): + super().test_keras_fit() + + def test_keras_fit_mixed_precision(self): + policy = tf.keras.mixed_precision.Policy("mixed_float16") + tf.keras.mixed_precision.set_global_policy(policy) + super().test_keras_fit() + tf.keras.mixed_precision.set_global_policy("float32") + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + hidden_states = outputs.hidden_states + + expected_num_layers = len(self.model_tester.depth) + self.assertEqual(len(hidden_states), expected_num_layers) + + # verify the first hidden states (first block) + self.assertListEqual( + list(hidden_states[0].shape[-3:]), + [ + self.model_tester.embed_dim[0], + self.model_tester.image_size // 4, + self.model_tester.image_size // 4, + ], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFCvtModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_tf +@require_vision +class TFCvtModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return AutoFeatureExtractor.from_pretrained(TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + + @slow + def test_inference_image_classification_head(self): + model = TFCvtForImageClassification.from_pretrained(TF_CVT_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="tf") + + # forward pass + outputs = model(**inputs) + + # verify the logits + expected_shape = tf.TensorShape((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = tf.constant([0.9285, 0.9015, -0.3150]) + self.assertTrue(np.allclose(outputs.logits[0, :3].numpy(), expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_audio.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_audio.py new file mode 100644 index 0000000000000000000000000000000000000000..74450f50c8b5d6bc999ba543719cfe4afbab1476 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_audio.py @@ -0,0 +1,753 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Data2VecAudio model. """ + +import math +import unittest + +import numpy as np +from datasets import load_dataset + +from tests.test_modeling_common import floats_tensor, ids_tensor, random_attention_mask +from transformers import Data2VecAudioConfig, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_soundfile, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + Data2VecAudioForAudioFrameClassification, + Data2VecAudioForCTC, + Data2VecAudioForSequenceClassification, + Data2VecAudioForXVector, + Data2VecAudioModel, + Wav2Vec2Processor, + ) + from transformers.models.data2vec.modeling_data2vec_audio import _compute_mask_indices + + +class Data2VecAudioModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=1024, # speech is longer + is_training=False, + hidden_size=16, + feat_extract_dropout=0.0, + feat_extract_activation="gelu", + conv_dim=(32, 32, 32), + conv_stride=(4, 4, 4), + conv_kernel=(8, 8, 8), + conv_bias=False, + num_conv_pos_embeddings=16, + num_conv_pos_embedding_groups=2, + num_hidden_layers=4, + num_attention_heads=2, + hidden_dropout_prob=0.1, + intermediate_size=20, + layer_norm_eps=1e-5, + hidden_act="gelu", + initializer_range=0.02, + mask_time_prob=0.5, + mask_time_length=2, + vocab_size=32, + num_adapter_layers=1, + adapter_stride=2, + tdnn_dim=(32, 32), + tdnn_kernel=(5, 3), + tdnn_dilation=(1, 2), + xvector_output_dim=32, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.hidden_size = hidden_size + self.feat_extract_dropout = feat_extract_dropout + self.feat_extract_activation = feat_extract_activation + self.conv_dim = conv_dim + self.conv_stride = conv_stride + self.conv_kernel = conv_kernel + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_dropout_prob = hidden_dropout_prob + self.intermediate_size = intermediate_size + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.num_adapter_layers = num_adapter_layers + self.adapter_stride = adapter_stride + self.mask_time_prob = mask_time_prob + self.mask_time_length = mask_time_length + self.scope = scope + self.tdnn_dim = tdnn_dim + self.tdnn_kernel = tdnn_kernel + self.tdnn_dilation = tdnn_dilation + self.xvector_output_dim = xvector_output_dim + + output_seq_length = self.seq_length + for kernel, stride in zip(self.conv_kernel, self.conv_stride): + output_seq_length = (output_seq_length - (kernel - 1)) / stride + self.output_seq_length = int(math.ceil(output_seq_length)) + self.encoder_seq_length = self.output_seq_length + + self.adapter_output_seq_length = (self.output_seq_length - 1) // adapter_stride + 1 + + def prepare_config_and_inputs(self): + input_values = floats_tensor([self.batch_size, self.seq_length], scale=1.0) + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = self.get_config() + + return config, input_values, attention_mask + + def get_config(self): + return Data2VecAudioConfig( + hidden_size=self.hidden_size, + feat_extract_dropout=self.feat_extract_dropout, + feat_extract_activation=self.feat_extract_activation, + conv_dim=self.conv_dim, + conv_stride=self.conv_stride, + conv_kernel=self.conv_kernel, + conv_bias=self.conv_bias, + mask_time_prob=self.mask_time_prob, + mask_time_length=self.mask_time_length, + num_conv_pos_embeddings=self.num_conv_pos_embeddings, + num_conv_pos_embedding_groups=self.num_conv_pos_embedding_groups, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + hidden_dropout_prob=self.hidden_dropout_prob, + intermediate_size=self.intermediate_size, + layer_norm_eps=self.layer_norm_eps, + hidden_act=self.hidden_act, + initializer_range=self.initializer_range, + vocab_size=self.vocab_size, + num_adapter_layers=self.num_adapter_layers, + adapter_stride=self.adapter_stride, + tdnn_dim=self.tdnn_dim, + tdnn_kernel=self.tdnn_kernel, + tdnn_dilation=self.tdnn_dilation, + xvector_output_dim=self.xvector_output_dim, + ) + + def create_and_check_model(self, config, input_values, attention_mask): + model = Data2VecAudioModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_values, attention_mask=attention_mask) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.output_seq_length, self.hidden_size) + ) + + def create_and_check_model_with_adapter(self, config, input_values, attention_mask): + config.add_adapter = True + model = Data2VecAudioModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_values, attention_mask=attention_mask) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.adapter_output_seq_length, self.hidden_size) + ) + + def create_and_check_model_with_adapter_proj_dim(self, config, input_values, attention_mask): + config.add_adapter = True + config.output_hidden_size = 8 + model = Data2VecAudioModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_values, attention_mask=attention_mask) + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, self.adapter_output_seq_length, config.output_hidden_size), + ) + + def create_and_check_batch_inference(self, config, input_values, *args): + # test does not pass for models making use of `group_norm` + # check: https://github.com/pytorch/fairseq/issues/3227 + model = Data2VecAudioModel(config=config) + model.to(torch_device) + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.bool) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0.0 + + batch_outputs = model(input_values, attention_mask=attention_mask).last_hidden_state + + for i in range(input_values.shape[0]): + input_slice = input_values[i : i + 1, : input_lengths[i]] + output = model(input_slice).last_hidden_state + + batch_output = batch_outputs[i : i + 1, : output.shape[1]] + self.parent.assertTrue(torch.allclose(output, batch_output, atol=1e-3)) + + def check_ctc_loss(self, config, input_values, *args): + model = Data2VecAudioForCTC(config=config) + model.to(torch_device) + + # make sure that dropout is disabled + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.long) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], min(max_length_labels) - 1), model.config.vocab_size) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0 + + model.config.ctc_loss_reduction = "sum" + sum_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + + model.config.ctc_loss_reduction = "mean" + mean_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + + self.parent.assertTrue(isinstance(sum_loss, float)) + self.parent.assertTrue(isinstance(mean_loss, float)) + + def check_seq_classifier_loss(self, config, input_values, *args): + model = Data2VecAudioForSequenceClassification(config=config) + model.to(torch_device) + + # make sure that dropout is disabled + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.long) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + labels = ids_tensor((input_values.shape[0], 1), len(model.config.id2label)) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0 + + masked_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + unmasked_loss = model(input_values, labels=labels).loss.item() + + self.parent.assertTrue(isinstance(masked_loss, float)) + self.parent.assertTrue(isinstance(unmasked_loss, float)) + self.parent.assertTrue(masked_loss != unmasked_loss) + + def check_ctc_training(self, config, input_values, *args): + config.ctc_zero_infinity = True + model = Data2VecAudioForCTC(config=config) + model.to(torch_device) + model.train() + + # freeze feature encoder + model.freeze_feature_encoder() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], max(max_length_labels) - 2), model.config.vocab_size) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + + if max_length_labels[i] < labels.shape[-1]: + # it's important that we make sure that target lenghts are at least + # one shorter than logit lenghts to prevent -inf + labels[i, max_length_labels[i] - 1 :] = -100 + + loss = model(input_values, labels=labels).loss + self.parent.assertFalse(torch.isinf(loss).item()) + + loss.backward() + + def check_seq_classifier_training(self, config, input_values, *args): + config.ctc_zero_infinity = True + model = Data2VecAudioForSequenceClassification(config=config) + model.to(torch_device) + model.train() + + # freeze everything but the classification head + model.freeze_base_model() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + labels = ids_tensor((input_values.shape[0], 1), len(model.config.id2label)) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + + loss = model(input_values, labels=labels).loss + self.parent.assertFalse(torch.isinf(loss).item()) + + loss.backward() + + def check_xvector_training(self, config, input_values, *args): + config.ctc_zero_infinity = True + model = Data2VecAudioForXVector(config=config) + model.to(torch_device) + model.train() + + # freeze everything but the classification head + model.freeze_base_model() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + labels = ids_tensor((input_values.shape[0], 1), len(model.config.id2label)) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + + loss = model(input_values, labels=labels).loss + self.parent.assertFalse(torch.isinf(loss).item()) + + loss.backward() + + def check_labels_out_of_vocab(self, config, input_values, *args): + model = Data2VecAudioForCTC(config) + model.to(torch_device) + model.train() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], max(max_length_labels) - 2), model.config.vocab_size + 100) + + with self.parent.assertRaises(ValueError): + model(input_values, labels=labels) + + def prepare_config_and_inputs_for_common(self): + config, input_values, attention_mask = self.prepare_config_and_inputs() + inputs_dict = {"input_values": input_values, "attention_mask": attention_mask} + return config, inputs_dict + + +@require_torch +class Data2VecAudioModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + Data2VecAudioForCTC, + Data2VecAudioModel, + Data2VecAudioForSequenceClassification, + Data2VecAudioForAudioFrameClassification, + Data2VecAudioForXVector, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "audio-classification": Data2VecAudioForSequenceClassification, + "automatic-speech-recognition": Data2VecAudioForCTC, + "feature-extraction": Data2VecAudioModel, + } + if is_torch_available() + else {} + ) + test_pruning = False + test_headmasking = False + + def setUp(self): + self.model_tester = Data2VecAudioModelTester(self) + self.config_tester = ConfigTester(self, config_class=Data2VecAudioConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_with_adapter(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_adapter(*config_and_inputs) + + def test_model_with_adapter_proj_dim(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_adapter_proj_dim(*config_and_inputs) + + def test_ctc_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_loss(*config_and_inputs) + + def test_seq_classifier_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_loss(*config_and_inputs) + + def test_ctc_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_training(*config_and_inputs) + + def test_seq_classifier_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_training(*config_and_inputs) + + def test_xvector_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_xvector_training(*config_and_inputs) + + def test_labels_out_of_vocab(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_labels_out_of_vocab(*config_and_inputs) + + # Data2VecAudio has no inputs_embeds + def test_inputs_embeds(self): + pass + + # `input_ids` is renamed to `input_values` + def test_forward_signature(self): + pass + + # Data2VecAudio cannot resize token embeddings + # since it has no tokens embeddings + def test_resize_tokens_embeddings(self): + pass + + # Data2VecAudio has no inputs_embeds + # and thus the `get_input_embeddings` fn + # is not implemented + def test_model_common_attributes(self): + pass + + @is_pt_flax_cross_test + # non-robust architecture does not exist in Flax + def test_equivalence_flax_to_pt(self): + pass + + @is_pt_flax_cross_test + # non-robust architecture does not exist in Flax + def test_equivalence_pt_to_flax(self): + pass + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + # set layer drop to 0 + model.config.layerdrop = 0.0 + + input_values = inputs_dict["input_values"] + + input_lengths = torch.tensor( + [input_values.shape[1] for _ in range(input_values.shape[0])], dtype=torch.long, device=torch_device + ) + output_lengths = model._get_feat_extract_output_lengths(input_lengths) + + labels = ids_tensor((input_values.shape[0], output_lengths[0] - 2), self.model_tester.vocab_size) + inputs_dict["attention_mask"] = torch.ones_like(inputs_dict["attention_mask"]) + inputs_dict["labels"] = labels + + outputs = model(**inputs_dict) + + output = outputs[0] + + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0] + attentions = outputs.attentions[0] + + hidden_states.retain_grad() + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + self.assertIsNotNone(attentions.grad) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + uniform_init_parms = [ + "conv.weight", + "masked_spec_embed", + "codevectors", + "quantizer.weight_proj.weight", + "project_hid.weight", + "project_hid.bias", + "project_q.weight", + "project_q.bias", + "feature_projection.projection.weight", + "feature_projection.projection.bias", + "objective.weight", + ] + if param.requires_grad: + if any([x in name for x in uniform_init_parms]): + self.assertTrue( + -1.0 <= ((param.data.mean() * 1e9).round() / 1e9).item() <= 1.0, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + # overwrite from test_modeling_common + def _mock_init_weights(self, module): + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(3) + if hasattr(module, "weight_g") and module.weight_g is not None: + module.weight_g.data.fill_(3) + if hasattr(module, "weight_v") and module.weight_v is not None: + module.weight_v.data.fill_(3) + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.fill_(3) + if hasattr(module, "codevectors") and module.codevectors is not None: + module.codevectors.data.fill_(3) + if hasattr(module, "masked_spec_embed") and module.masked_spec_embed is not None: + module.masked_spec_embed.data.fill_(3) + + def test_mask_feature_prob_ctc(self): + model = Data2VecAudioForCTC.from_pretrained( + "hf-internal-testing/tiny-random-data2vec-seq-class", mask_feature_prob=0.2, mask_feature_length=2 + ) + model.to(torch_device).train() + processor = Wav2Vec2Processor.from_pretrained( + "hf-internal-testing/tiny-random-wav2vec2", return_attention_mask=True + ) + + batch_duration_in_seconds = [1, 3, 2, 6] + input_features = [np.random.random(16_000 * s) for s in batch_duration_in_seconds] + + batch = processor( + input_features, padding=True, sampling_rate=processor.feature_extractor.sampling_rate, return_tensors="pt" + ) + + logits = model( + input_values=batch["input_values"].to(torch_device), + attention_mask=batch["attention_mask"].to(torch_device), + ).logits + + self.assertEqual(logits.shape, (4, 1498, 32)) + + def test_mask_time_prob_ctc(self): + model = Data2VecAudioForCTC.from_pretrained( + "facebook/data2vec-audio-base-960h", mask_time_prob=0.2, mask_time_length=2 + ) + model.to(torch_device).train() + processor = Wav2Vec2Processor.from_pretrained( + "hf-internal-testing/tiny-random-wav2vec2", return_attention_mask=True + ) + + batch_duration_in_seconds = [1, 3, 2, 6] + input_features = [np.random.random(16_000 * s) for s in batch_duration_in_seconds] + + batch = processor( + input_features, padding=True, sampling_rate=processor.feature_extractor.sampling_rate, return_tensors="pt" + ) + + logits = model( + input_values=batch["input_values"].to(torch_device), + attention_mask=batch["attention_mask"].to(torch_device), + ).logits + + self.assertEqual(logits.shape, (4, 299, 32)) + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + @slow + def test_model_from_pretrained(self): + model = Data2VecAudioModel.from_pretrained("facebook/data2vec-audio-base") + self.assertIsNotNone(model) + + +@require_torch +class Data2VecAudioUtilsTest(unittest.TestCase): + def test_compute_mask_indices(self): + batch_size = 4 + sequence_length = 60 + mask_prob = 0.5 + mask_length = 1 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + mask = torch.from_numpy(mask).to(torch_device) + + self.assertListEqual(mask.sum(axis=-1).tolist(), [mask_prob * sequence_length for _ in range(batch_size)]) + + def test_compute_mask_indices_low_prob(self): + # with these settings num_masked_spans=0.5, which means probabilistic rounding + # ensures that in 5 out of 10 method calls, num_masked_spans=0, and in + # the other 5 out of 10, cases num_masked_spans=1 + n_trials = 100 + batch_size = 4 + sequence_length = 100 + mask_prob = 0.05 + mask_length = 10 + + count_dimensions_masked = 0 + count_dimensions_not_masked = 0 + + for _ in range(n_trials): + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + mask = torch.from_numpy(mask).to(torch_device) + + num_masks = torch.sum(mask).item() + + if num_masks > 0: + count_dimensions_masked += 1 + else: + count_dimensions_not_masked += 1 + + # as we test for at least 10 masked dimension and at least + # 10 non-masked dimension, this test could fail with probability: + # P(100 coin flips, at most 9 heads) = 1.66e-18 + self.assertGreater(count_dimensions_masked, int(n_trials * 0.1)) + self.assertGreater(count_dimensions_not_masked, int(n_trials * 0.1)) + + def test_compute_mask_indices_overlap(self): + batch_size = 4 + sequence_length = 80 + mask_prob = 0.5 + mask_length = 4 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + mask = torch.from_numpy(mask).to(torch_device) + + # because of overlap mask don't have to add up exactly to `mask_prob * sequence_length`, but have to be smaller or equal + for batch_sum in mask.sum(axis=-1): + self.assertTrue(int(batch_sum) <= mask_prob * sequence_length) + + def test_compute_mask_indices_attn_mask_overlap(self): + batch_size = 4 + sequence_length = 80 + mask_prob = 0.5 + mask_length = 4 + + attention_mask = torch.ones((batch_size, sequence_length), dtype=torch.long, device=torch_device) + attention_mask[:2, sequence_length // 2 :] = 0 + + mask = _compute_mask_indices( + (batch_size, sequence_length), mask_prob, mask_length, attention_mask=attention_mask + ) + mask = torch.from_numpy(mask).to(torch_device) + + for batch_sum in mask.sum(axis=-1): + self.assertTrue(int(batch_sum) <= mask_prob * sequence_length) + + self.assertTrue(mask[:2, sequence_length // 2 :].sum() == 0) + + def test_compute_mask_indices_short_audio(self): + batch_size = 4 + sequence_length = 100 + mask_prob = 0.05 + mask_length = 10 + + attention_mask = torch.ones((batch_size, sequence_length), dtype=torch.long, device=torch_device) + # force one example to be heavily padded + attention_mask[0, 5:] = 0 + + mask = _compute_mask_indices( + (batch_size, sequence_length), mask_prob, mask_length, attention_mask=attention_mask, min_masks=2 + ) + + # make sure that non-padded examples cannot be padded + self.assertFalse(mask[0][attention_mask[0].to(torch.bool).cpu()].any()) + + +@require_torch +@require_soundfile +@slow +class Data2VecAudioModelIntegrationTest(unittest.TestCase): + def _load_datasamples(self, num_samples): + ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + # automatic decoding with librispeech + speech_samples = ds.sort("id").filter( + lambda x: x["id"] in [f"1272-141231-000{i}" for i in range(num_samples)] + )[:num_samples]["audio"] + + return [x["array"] for x in speech_samples] + + def _load_superb(self, task, num_samples): + ds = load_dataset("anton-l/superb_dummy", task, split="test") + + return ds[:num_samples] + + def test_inference_ctc_normal(self): + model = Data2VecAudioForCTC.from_pretrained("facebook/data2vec-audio-base-960h") + model.to(torch_device) + processor = Wav2Vec2Processor.from_pretrained("hf-internal-testing/tiny-random-wav2vec2", do_lower_case=True) + input_speech = self._load_datasamples(1) + + input_values = processor(input_speech, return_tensors="pt").input_values.to(torch_device) + + with torch.no_grad(): + logits = model(input_values).logits + + predicted_ids = torch.argmax(logits, dim=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = ["a man said to the universe sir i exist"] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) + + def test_inference_ctc_batched(self): + model = Data2VecAudioForCTC.from_pretrained("facebook/data2vec-audio-base-960h").to(torch_device) + processor = Wav2Vec2Processor.from_pretrained("hf-internal-testing/tiny-random-wav2vec2", do_lower_case=True) + + input_speech = self._load_datasamples(4) + + inputs = processor(input_speech, return_tensors="pt", padding=True) + + input_values = inputs.input_values.to(torch_device) + + with torch.no_grad(): + logits = model(input_values).logits + + predicted_ids = torch.argmax(logits, dim=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = [ + "a man said to the universe sir i exist", + "sweat covered brion's body trickling into the tight loin cloth that was the only garment he wore", + "the cut on his chest still dripping blood the ache of his overstrained eyes even the soaring arena around" + " him with thousands of spectators were trivialities not worth thinking about", + "his instant of panic was followed by a small sharp blow high on his chest", + ] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_text.py new file mode 100644 index 0000000000000000000000000000000000000000..a45c9b6a8b41dfc5ebd712414ef6bece19e013ba --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_text.py @@ -0,0 +1,546 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Data2VecAudio model. """ + +import unittest + +from tests.test_modeling_common import floats_tensor, ids_tensor, random_attention_mask +from transformers import Data2VecTextConfig, is_torch_available +from transformers.testing_utils import TestCasePlus, require_torch, slow, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + Data2VecTextForCausalLM, + Data2VecTextForMaskedLM, + Data2VecTextForMultipleChoice, + Data2VecTextForQuestionAnswering, + Data2VecTextForSequenceClassification, + Data2VecTextForTokenClassification, + Data2VecTextModel, + ) + from transformers.models.data2vec.modeling_data2vec_text import ( + DATA2VEC_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST, + Data2VecTextForTextEmbeddings, + create_position_ids_from_input_ids, + ) + + +class Data2VecTextModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return Data2VecTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Data2VecTextModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = Data2VecTextModel(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_causal_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + model = Data2VecTextForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.is_decoder = True + config.add_cross_attention = True + model = Data2VecTextForCausalLM(config=config).to(torch_device).eval() + + # make sure that ids don't start with pad token + mask = input_ids.ne(config.pad_token_id).long() + input_ids = input_ids * mask + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + + # make sure that ids don't start with pad token + mask = next_tokens.ne(config.pad_token_id).long() + next_tokens = next_tokens * mask + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + )["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Data2VecTextForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = Data2VecTextForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = Data2VecTextForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = Data2VecTextForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class Data2VecTextModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + Data2VecTextForCausalLM, + Data2VecTextForMaskedLM, + Data2VecTextModel, + Data2VecTextForSequenceClassification, + Data2VecTextForTokenClassification, + Data2VecTextForMultipleChoice, + Data2VecTextForQuestionAnswering, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (Data2VecTextForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": Data2VecTextModel, + "fill-mask": Data2VecTextForMaskedLM, + "question-answering": Data2VecTextForQuestionAnswering, + "text-classification": Data2VecTextForSequenceClassification, + "text-generation": Data2VecTextForCausalLM, + "token-classification": Data2VecTextForTokenClassification, + "zero-shot": Data2VecTextForSequenceClassification, + } + if is_torch_available() + else {} + ) + + def setUp(self): + self.model_tester = Data2VecTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=Data2VecTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_as_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def test_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + config_and_inputs[0].position_embedding_type = "relative_key" + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DATA2VEC_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = Data2VecTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_create_position_ids_respects_padding_index(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is Data2VecTextForTextEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + model = Data2VecTextForTextEmbeddings(config=config) + + input_ids = torch.as_tensor([[12, 31, 13, model.padding_idx]]) + expected_positions = torch.as_tensor( + [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] + ) + + position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + def test_create_position_ids_from_inputs_embeds(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is Data2VecTextForTextEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + embeddings = Data2VecTextForTextEmbeddings(config=config) + + inputs_embeds = torch.empty(2, 4, 30) + expected_single_positions = [ + 0 + embeddings.padding_idx + 1, + 1 + embeddings.padding_idx + 1, + 2 + embeddings.padding_idx + 1, + 3 + embeddings.padding_idx + 1, + ] + expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + +@require_torch +class Data2VecTextModelIntegrationTest(TestCasePlus): + @slow + def test_inference_masked_lm(self): + model = Data2VecTextForMaskedLM.from_pretrained("facebook/data2vec-text-base") + + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + with torch.no_grad(): + output = model(input_ids)[0] + expected_shape = torch.Size((1, 11, 50265)) + self.assertEqual(output.shape, expected_shape) + # compare the actual values for a slice. + expected_slice = torch.tensor([[[0.2328, 0.0000, 1.1710], [2.2525, 0.0000, 1.9937], [2.1280, 0.0000, 1.8691]]]) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) + + @slow + def test_inference_no_head(self): + model = Data2VecTextModel.from_pretrained("facebook/data2vec-text-base") + + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + with torch.no_grad(): + output = model(input_ids)[0] + # compare the actual values for a slice. + expected_slice = torch.tensor( + [[[0.1998, -0.0379, 0.0024], [-0.0971, -0.2214, -0.1798], [-0.0789, -0.2400, -0.1898]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_vision.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_vision.py new file mode 100644 index 0000000000000000000000000000000000000000..b4c391fea17e64ed5d5e4654a4d7f1d504235e23 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_data2vec_vision.py @@ -0,0 +1,361 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Data2VecVision model. """ + + +import inspect +import unittest + +from transformers import Data2VecVisionConfig +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_torch_multi_gpu, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + MODEL_MAPPING, + Data2VecVisionForImageClassification, + Data2VecVisionForSemanticSegmentation, + Data2VecVisionModel, + ) + from transformers.models.data2vec.modeling_data2vec_vision import DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import BeitFeatureExtractor + + +class Data2VecVisionModelTester: + def __init__( + self, + parent, + vocab_size=100, + batch_size=13, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=4, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + type_sequence_label_size=10, + initializer_range=0.02, + num_labels=3, + scope=None, + out_indices=[0, 1, 2, 3], + ): + self.parent = parent + self.vocab_size = 100 + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.scope = scope + self.out_indices = out_indices + self.num_labels = num_labels + + # in BeiT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + pixel_labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + pixel_labels = ids_tensor([self.batch_size, self.image_size, self.image_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels, pixel_labels + + def get_config(self): + return Data2VecVisionConfig( + vocab_size=self.vocab_size, + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + out_indices=self.out_indices, + ) + + def create_and_check_model(self, config, pixel_values, labels, pixel_labels): + model = Data2VecVisionModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + num_patches = (self.image_size // self.patch_size) ** 2 + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels, pixel_labels): + config.num_labels = self.type_sequence_label_size + model = Data2VecVisionForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def create_and_check_for_image_segmentation(self, config, pixel_values, labels, pixel_labels): + config.num_labels = self.num_labels + model = Data2VecVisionForSemanticSegmentation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2) + ) + result = model(pixel_values, labels=pixel_labels) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels, pixel_labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class Data2VecVisionModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as Data2VecVision does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + (Data2VecVisionModel, Data2VecVisionForImageClassification, Data2VecVisionForSemanticSegmentation) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": Data2VecVisionModel, + "image-classification": Data2VecVisionForImageClassification, + "image-segmentation": Data2VecVisionForSemanticSegmentation, + } + if is_torch_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = Data2VecVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=Data2VecVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_inputs_embeds(self): + # Data2VecVision does not use inputs_embeds + pass + + @require_torch_multi_gpu + @unittest.skip( + reason="Data2VecVision has some layers using `add_module` which doesn't work well with `nn.DataParallel`" + ) + def test_multi_gpu_data_parallel_forward(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_segmentation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_segmentation(*config_and_inputs) + + def test_training(self): + if not self.model_tester.is_training: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class in [*get_values(MODEL_MAPPING)]: + continue + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if not self.model_tester.is_training: + return + + config.use_cache = False + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class in [*get_values(MODEL_MAPPING)] or not model_class.supports_gradient_checkpointing: + continue + # TODO: remove the following 3 lines once we have a MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING + # this can then be incorporated into _prepare_for_class in test_modeling_common.py + elif model_class.__name__ == "Data2VecVisionForSemanticSegmentation": + batch_size, num_channels, height, width = inputs_dict["pixel_values"].shape + inputs_dict["labels"] = torch.zeros( + [self.model_tester.batch_size, height, width], device=torch_device + ).long() + model = model_class(config) + model.gradient_checkpointing_enable() + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + # we skip lambda parameters as these require special initial values + # determined by config.layer_scale_init_value + if "lambda" in name: + continue + if param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def check_pt_tf_outputs(self, tf_outputs, pt_outputs, model_class, tol=2e-4, name="outputs", attributes=None): + # We override with a slightly higher tol value, as semseg models tend to diverge a bit more + super().check_pt_tf_outputs(tf_outputs, pt_outputs, model_class, tol, name, attributes) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = Data2VecVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class Data2VecVisionModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + BeitFeatureExtractor.from_pretrained("facebook/data2vec-vision-base-ft1k") + if is_vision_available() + else None + ) + + @slow + def test_inference_image_classification_head_imagenet_1k(self): + model = Data2VecVisionForImageClassification.from_pretrained("facebook/data2vec-vision-base-ft1k").to( + torch_device + ) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + logits = outputs.logits + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(logits.shape, expected_shape) + + expected_slice = torch.tensor([0.3277, -0.1395, 0.0911]).to(torch_device) + + self.assertTrue(torch.allclose(logits[0, :3], expected_slice, atol=1e-4)) + + expected_top2 = [model.config.label2id[i] for i in ["remote control, remote", "tabby, tabby cat"]] + self.assertEqual(logits[0].topk(2).indices.cpu().tolist(), expected_top2) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_tf_data2vec_vision.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_tf_data2vec_vision.py new file mode 100644 index 0000000000000000000000000000000000000000..dfa890d25a9e9000ce79bb0fedaf8d3e07c8dd4a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/data2vec/test_modeling_tf_data2vec_vision.py @@ -0,0 +1,501 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the TensorFlow Data2VecVision model. """ + +import collections.abc +import inspect +import unittest + +import numpy as np + +from transformers import Data2VecVisionConfig +from transformers.file_utils import cached_property, is_tf_available, is_vision_available +from transformers.testing_utils import require_tf, require_vision, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFData2VecVisionForImageClassification, + TFData2VecVisionForSemanticSegmentation, + TFData2VecVisionModel, + ) + from transformers.models.data2vec.modeling_tf_data2vec_vision import ( + TF_DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST, + ) + +if is_vision_available(): + from PIL import Image + + from transformers import BeitFeatureExtractor + + +class TFData2VecVisionModelTester: + def __init__( + self, + parent, + vocab_size=100, + batch_size=13, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=4, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + type_sequence_label_size=10, + initializer_range=0.02, + num_labels=3, + scope=None, + out_indices=[0, 1, 2, 3], + ): + self.parent = parent + self.vocab_size = 100 + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.scope = scope + self.out_indices = out_indices + self.num_labels = num_labels + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + pixel_labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + pixel_labels = ids_tensor([self.batch_size, self.image_size, self.image_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels, pixel_labels + + def get_config(self): + return Data2VecVisionConfig( + vocab_size=self.vocab_size, + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + out_indices=self.out_indices, + ) + + def create_and_check_model(self, config, pixel_values, labels, pixel_labels): + model = TFData2VecVisionModel(config=config) + result = model(pixel_values, training=False) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = ( + self.image_size + if isinstance(self.image_size, collections.abc.Iterable) + else (self.image_size, self.image_size) + ) + patch_size = ( + self.patch_size + if isinstance(self.image_size, collections.abc.Iterable) + else (self.patch_size, self.patch_size) + ) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels, pixel_labels): + config.num_labels = self.type_sequence_label_size + model = TFData2VecVisionForImageClassification(config) + + result = model(pixel_values, labels=labels, training=False) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def create_and_check_for_image_segmentation(self, config, pixel_values, labels, pixel_labels): + config.num_labels = self.num_labels + model = TFData2VecVisionForSemanticSegmentation(config) + result = model(pixel_values, training=False) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2) + ) + result = model(pixel_values, labels=pixel_labels) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels, pixel_labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + def prepare_config_and_inputs_for_keras_fit(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, _, _ = config_and_inputs + inputs_dict = {"pixel_values": pixel_values, "labels": tf.zeros((self.batch_size))} + return config, inputs_dict + + +@require_tf +class TFData2VecVisionModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as Data2VecVision does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + (TFData2VecVisionModel, TFData2VecVisionForImageClassification, TFData2VecVisionForSemanticSegmentation) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + {"feature-extraction": TFData2VecVisionModel, "image-classification": TFData2VecVisionForImageClassification} + if is_tf_available() + else {} + ) + + test_pruning = False + test_onnx = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = TFData2VecVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=Data2VecVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="Data2VecVision does not use inputs_embeds") + def test_inputs_embeds(self): + # Data2VecVision does not use inputs_embeds + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (tf.keras.layers.Layer)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, tf.keras.layers.Layer)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_segmentation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_segmentation(*config_and_inputs) + + @unittest.skip("Test was written for TF 1.x and isn't really relevant here") + def test_compile_tf_model(self): + pass + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + # in Data2VecVision, the seq_len equals the number of patches + 1 (we add 1 for the [CLS] token) + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + patch_size = ( + self.model_tester.patch_size + if isinstance(self.model_tester.patch_size, collections.abc.Iterable) + else (self.model_tester.patch_size, self.model_tester.patch_size) + ) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_len = num_patches + 1 + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + + self.assertEqual(out_len + 1, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # Data2VecVision has a different seq_length + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + patch_size = ( + self.model_tester.patch_size + if isinstance(self.model_tester.patch_size, collections.abc.Iterable) + else (self.model_tester.patch_size, self.model_tester.patch_size) + ) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_length = num_patches + 1 + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + # Overriding this method since the base method won't be compatible with Data2VecVision. + def test_keras_fit(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # Since `TFData2VecVisionModel` cannot operate with the default `fit()` method. + if model_class.__name__ != "TFData2VecVisionModel": + model = model_class(config) + if getattr(model, "hf_compute_loss", None): + # Test that model correctly compute the loss with kwargs + _, prepared_for_class = self.model_tester.prepare_config_and_inputs_for_keras_fit() + + label_names = {"labels"} + self.assertGreater(len(label_names), 0, msg="No matching label names found!") + labels = {key: val for key, val in prepared_for_class.items() if key in label_names} + inputs_minus_labels = { + key: val for key, val in prepared_for_class.items() if key not in label_names + } + self.assertGreater(len(inputs_minus_labels), 0) + model.compile(optimizer=tf.keras.optimizers.SGD(0.0), run_eagerly=True) + + # Make sure the model fits without crashing regardless of where we pass the labels + history1 = model.fit( + prepared_for_class, + validation_data=prepared_for_class, + steps_per_epoch=1, + validation_steps=1, + shuffle=False, + ) + val_loss1 = history1.history["val_loss"][0] + history2 = model.fit( + inputs_minus_labels, + labels, + validation_data=(inputs_minus_labels, labels), + steps_per_epoch=1, + validation_steps=1, + shuffle=False, + ) + val_loss2 = history2.history["val_loss"][0] + self.assertTrue(np.allclose(val_loss1, val_loss2, atol=1e-2, rtol=1e-3)) + + def check_pt_tf_outputs(self, tf_outputs, pt_outputs, model_class, tol=2e-4, name="outputs", attributes=None): + # We override with a slightly higher tol value, as semseg models tend to diverge a bit more + super().check_pt_tf_outputs(tf_outputs, pt_outputs, model_class, tol, name, attributes) + + # Overriding this method since the base method won't be compatible with Data2VecVision. + def test_loss_computation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # Since `TFData2VecVisionModel` won't have labels against which we + # could compute loss. + if model_class.__name__ != "TFData2VecVisionModel": + model = model_class(config) + if getattr(model, "hf_compute_loss", None): + # The number of elements in the loss should be the same as the number of elements in the label + _, prepared_for_class = self.model_tester.prepare_config_and_inputs_for_keras_fit() + added_label = prepared_for_class[ + sorted(prepared_for_class.keys() - inputs_dict.keys(), reverse=True)[0] + ] + loss_size = tf.size(added_label) + + # Test that model correctly compute the loss with kwargs + possible_input_names = {"input_ids", "pixel_values", "input_features"} + input_name = possible_input_names.intersection(set(prepared_for_class)).pop() + model_input = prepared_for_class.pop(input_name) + + loss = model(model_input, **prepared_for_class)[0] + self.assertEqual(loss.shape, [loss_size]) + + # Test that model correctly compute the loss with a dict + _, prepared_for_class = self.model_tester.prepare_config_and_inputs_for_keras_fit() + loss = model(**prepared_for_class)[0] + self.assertEqual(loss.shape, [loss_size]) + + # Test that model correctly compute the loss with a tuple + label_keys = prepared_for_class.keys() - inputs_dict.keys() + signature = inspect.signature(model.call).parameters + signature_names = list(signature.keys()) + + # Create a dictionary holding the location of the tensors in the tuple + tuple_index_mapping = {0: input_name} + for label_key in label_keys: + label_key_index = signature_names.index(label_key) + tuple_index_mapping[label_key_index] = label_key + sorted_tuple_index_mapping = sorted(tuple_index_mapping.items()) + # Initialize a list with their default values, update the values and convert to a tuple + list_input = [] + + for name in signature_names: + if name != "kwargs": + list_input.append(signature[name].default) + + for index, value in sorted_tuple_index_mapping: + list_input[index] = prepared_for_class[value] + + tuple_input = tuple(list_input) + + # Send to model + loss = model(tuple_input[:-1])[0] + + self.assertEqual(loss.shape, [loss_size]) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFData2VecVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_tf +@require_vision +class TFData2VecVisionModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + BeitFeatureExtractor.from_pretrained("facebook/data2vec-vision-base-ft1k") + if is_vision_available() + else None + ) + + @slow + def test_inference_image_classification_head_imagenet_1k(self): + model = TFData2VecVisionForImageClassification.from_pretrained("facebook/data2vec-vision-base-ft1k") + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="tf") + + # forward pass + outputs = model(**inputs) + logits = outputs.logits + + # verify the logits + expected_shape = tf.convert_to_tensor([1, 1000]) + self.assertEqual(logits.shape, expected_shape) + + expected_slice = tf.convert_to_tensor([0.3277, -0.1395, 0.0911]) + + tf.debugging.assert_near(logits[0, :3], expected_slice, atol=1e-4) + + expected_top2 = [model.config.label2id[i] for i in ["remote control, remote", "tabby, tabby cat"]] + self.assertEqual(tf.nn.top_k(outputs.logits[0], 2).indices.numpy().tolist(), expected_top2) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..7daff3b522e7b95da5715f4e2cd8b4dc58bd95c9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_deberta.py @@ -0,0 +1,302 @@ +# coding=utf-8 +# Copyright 2018 Microsoft Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from transformers import DebertaConfig, is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + DebertaForMaskedLM, + DebertaForQuestionAnswering, + DebertaForSequenceClassification, + DebertaForTokenClassification, + DebertaModel, + ) + from transformers.models.deberta.modeling_deberta import DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST + + +class DebertaModelTester(object): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + relative_attention=False, + position_biased_input=True, + pos_att_type="None", + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.relative_attention = relative_attention + self.position_biased_input = position_biased_input + self.pos_att_type = pos_att_type + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return DebertaConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + relative_attention=self.relative_attention, + position_biased_input=self.position_biased_input, + pos_att_type=self.pos_att_type, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def check_loss_output(self, result): + self.parent.assertListEqual(list(result.loss.size()), []) + + def create_and_check_deberta_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaModel(config=config) + model.to(torch_device) + model.eval() + sequence_output = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids)[0] + sequence_output = model(input_ids, token_type_ids=token_type_ids)[0] + sequence_output = model(input_ids)[0] + + self.parent.assertListEqual(list(sequence_output.size()), [self.batch_size, self.seq_length, self.hidden_size]) + + def create_and_check_deberta_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_deberta_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DebertaForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertListEqual(list(result.logits.size()), [self.batch_size, self.num_labels]) + self.check_loss_output(result) + + def create_and_check_deberta_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DebertaForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_deberta_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class DebertaModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DebertaModel, + DebertaForMaskedLM, + DebertaForSequenceClassification, + DebertaForTokenClassification, + DebertaForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": DebertaModel, + "fill-mask": DebertaForMaskedLM, + "question-answering": DebertaForQuestionAnswering, + "text-classification": DebertaForSequenceClassification, + "token-classification": DebertaForTokenClassification, + "zero-shot": DebertaForSequenceClassification, + } + if is_torch_available() + else {} + ) + + fx_compatible = True + test_torchscript = False + test_pruning = False + test_head_masking = False + is_encoder_decoder = False + + def setUp(self): + self.model_tester = DebertaModelTester(self) + self.config_tester = ConfigTester(self, config_class=DebertaConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_deberta_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_sequence_classification(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_question_answering(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DebertaModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class DebertaModelIntegrationTest(unittest.TestCase): + @unittest.skip(reason="Model not available yet") + def test_inference_masked_lm(self): + pass + + @slow + def test_inference_no_head(self): + model = DebertaModel.from_pretrained("microsoft/deberta-base") + + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + with torch.no_grad(): + output = model(input_ids, attention_mask=attention_mask)[0] + # compare the actual values for a slice. + expected_slice = torch.tensor( + [[[-0.5986, -0.8055, -0.8462], [1.4484, -0.9348, -0.8059], [0.3123, 0.0032, -1.4131]]] + ) + self.assertTrue(torch.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4), f"{output[:, 1:4, 1:4]}") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_tf_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_tf_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..424d9e0b2b4100a09051f6f00efd171ede36123d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_modeling_tf_deberta.py @@ -0,0 +1,294 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import DebertaConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFDebertaForMaskedLM, + TFDebertaForQuestionAnswering, + TFDebertaForSequenceClassification, + TFDebertaForTokenClassification, + TFDebertaModel, + ) + + +class TFDebertaModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.relative_attention = False + self.max_relative_positions = -1 + self.position_biased_input = True + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + + config = DebertaConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + relative_attention=self.relative_attention, + max_relative_positions=self.max_relative_positions, + position_biased_input=self.position_biased_input, + initializer_range=self.initializer_range, + return_dict=True, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaForMaskedLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDebertaForSequenceClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDebertaForTokenClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFDebertaModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFDebertaModel, + TFDebertaForMaskedLM, + TFDebertaForQuestionAnswering, + TFDebertaForSequenceClassification, + TFDebertaForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFDebertaModel, + "fill-mask": TFDebertaForMaskedLM, + "question-answering": TFDebertaForQuestionAnswering, + "text-classification": TFDebertaForSequenceClassification, + "token-classification": TFDebertaForTokenClassification, + "zero-shot": TFDebertaForSequenceClassification, + } + if is_tf_available() + else {} + ) + + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFDebertaModelTester(self) + self.config_tester = ConfigTester(self, config_class=DebertaConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + model = TFDebertaModel.from_pretrained("kamalkraj/deberta-base") + self.assertIsNotNone(model) + + +@require_tf +class TFDeBERTaModelIntegrationTest(unittest.TestCase): + @unittest.skip(reason="Model not available yet") + def test_inference_masked_lm(self): + pass + + @slow + def test_inference_no_head(self): + model = TFDebertaModel.from_pretrained("kamalkraj/deberta-base") + input_ids = tf.constant([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + attention_mask = tf.constant([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + output = model(input_ids, attention_mask=attention_mask)[0] + + expected_slice = tf.constant( + [ + [ + [-0.59855896, -0.80552566, -0.8462135], + [1.4484025, -0.93483794, -0.80593085], + [0.3122741, 0.00316059, -1.4131377], + ] + ] + ) + tf.debugging.assert_near(output[:, 1:4, 1:4], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_tokenization_deberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_tokenization_deberta.py new file mode 100644 index 0000000000000000000000000000000000000000..81d7bd95bd8081225209bceca63c202e40bf383f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta/test_tokenization_deberta.py @@ -0,0 +1,167 @@ +# coding=utf-8 +# Copyright 2019 Hugging Face inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers import DebertaTokenizer, DebertaTokenizerFast +from transformers.models.deberta.tokenization_deberta import VOCAB_FILES_NAMES +from transformers.testing_utils import slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +class DebertaTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = DebertaTokenizer + test_rust_tokenizer = True + rust_tokenizer_class = DebertaTokenizerFast + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "[UNK]", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": "[UNK]"} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.get_tokenizer() + text = "lower newer" + bpe_tokens = ["l", "o", "w", "er", "\u0120", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [0, 1, 2, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_token_type_ids(self): + tokenizer = self.get_tokenizer() + tokd = tokenizer("Hello", "World") + expected_token_type_ids = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1] + self.assertListEqual(tokd["token_type_ids"], expected_token_type_ids) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("microsoft/deberta-base") + + text = tokenizer.encode("sequence builders", add_special_tokens=False) + text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False) + + encoded_text_from_decode = tokenizer.encode( + "sequence builders", add_special_tokens=True, add_prefix_space=False + ) + encoded_pair_from_decode = tokenizer.encode( + "sequence builders", "multi-sequence build", add_special_tokens=True, add_prefix_space=False + ) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == encoded_text_from_decode + assert encoded_pair == encoded_pair_from_decode + + @slow + def test_tokenizer_integration(self): + tokenizer_classes = [self.tokenizer_class] + if self.test_rust_tokenizer: + tokenizer_classes.append(self.rust_tokenizer_class) + + for tokenizer_class in tokenizer_classes: + tokenizer = tokenizer_class.from_pretrained("microsoft/deberta-base") + + sequences = [ + "ALBERT: A Lite BERT for Self-supervised Learning of Language Representations", + "ALBERT incorporates two parameter reduction techniques", + "The first one is a factorized embedding parameterization. By decomposing the large vocabulary" + " embedding matrix into two small matrices, we separate the size of the hidden layers from the size of" + " vocabulary embedding.", + ] + + encoding = tokenizer(sequences, padding=True) + decoded_sequences = [tokenizer.decode(seq, skip_special_tokens=True) for seq in encoding["input_ids"]] + + # fmt: off + expected_encoding = { + 'input_ids': [ + [1, 2118, 11126, 565, 35, 83, 25191, 163, 18854, 13, 12156, 12, 16101, 25376, 13807, 9, 22205, 27893, 1635, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 2118, 11126, 565, 24536, 80, 43797, 4878, 7373, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 133, 78, 65, 16, 10, 3724, 1538, 33183, 11303, 43797, 1938, 4, 870, 24165, 29105, 5, 739, 32644, 33183, 11303, 36173, 88, 80, 650, 7821, 45940, 6, 52, 2559, 5, 1836, 9, 5, 7397, 13171, 31, 5, 1836, 9, 32644, 33183, 11303, 4, 2] + ], + 'token_type_ids': [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ], + 'attention_mask': [ + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + ] + } + # fmt: on + + expected_decoded_sequence = [ + "ALBERT: A Lite BERT for Self-supervised Learning of Language Representations", + "ALBERT incorporates two parameter reduction techniques", + "The first one is a factorized embedding parameterization. By decomposing the large vocabulary" + " embedding matrix into two small matrices, we separate the size of the hidden layers from the size of" + " vocabulary embedding.", + ] + + self.assertDictEqual(encoding.data, expected_encoding) + + for expected, decoded in zip(expected_decoded_sequence, decoded_sequences): + self.assertEqual(expected, decoded) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..548c9617b8dad4d11958a20a18f5af83081a3da7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_deberta_v2.py @@ -0,0 +1,320 @@ +# coding=utf-8 +# Copyright 2018 Microsoft Authors and the HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from transformers import DebertaV2Config, is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + DebertaV2ForMaskedLM, + DebertaV2ForMultipleChoice, + DebertaV2ForQuestionAnswering, + DebertaV2ForSequenceClassification, + DebertaV2ForTokenClassification, + DebertaV2Model, + ) + from transformers.models.deberta_v2.modeling_deberta_v2 import DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST + + +class DebertaV2ModelTester(object): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + relative_attention=False, + position_biased_input=True, + pos_att_type="None", + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.relative_attention = relative_attention + self.position_biased_input = position_biased_input + self.pos_att_type = pos_att_type + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return DebertaV2Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + relative_attention=self.relative_attention, + position_biased_input=self.position_biased_input, + pos_att_type=self.pos_att_type, + ) + + def check_loss_output(self, result): + self.parent.assertListEqual(list(result.loss.size()), []) + + def create_and_check_deberta_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaV2Model(config=config) + model.to(torch_device) + model.eval() + sequence_output = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids)[0] + sequence_output = model(input_ids, token_type_ids=token_type_ids)[0] + sequence_output = model(input_ids)[0] + + self.parent.assertListEqual(list(sequence_output.size()), [self.batch_size, self.seq_length, self.hidden_size]) + + def create_and_check_deberta_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaV2ForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_deberta_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DebertaV2ForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertListEqual(list(result.logits.size()), [self.batch_size, self.num_labels]) + self.check_loss_output(result) + + def create_and_check_deberta_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DebertaV2ForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_deberta_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaV2ForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_deberta_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DebertaV2ForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class DebertaV2ModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DebertaV2Model, + DebertaV2ForMaskedLM, + DebertaV2ForSequenceClassification, + DebertaV2ForTokenClassification, + DebertaV2ForQuestionAnswering, + DebertaV2ForMultipleChoice, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": DebertaV2Model, + "fill-mask": DebertaV2ForMaskedLM, + "question-answering": DebertaV2ForQuestionAnswering, + "text-classification": DebertaV2ForSequenceClassification, + "token-classification": DebertaV2ForTokenClassification, + "zero-shot": DebertaV2ForSequenceClassification, + } + if is_torch_available() + else {} + ) + + fx_compatible = True + test_torchscript = False + test_pruning = False + test_head_masking = False + is_encoder_decoder = False + + def setUp(self): + self.model_tester = DebertaV2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=DebertaV2Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_deberta_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_sequence_classification(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_question_answering(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deberta_for_multiple_choice(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DEBERTA_V2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DebertaV2Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class DebertaV2ModelIntegrationTest(unittest.TestCase): + @unittest.skip(reason="Model not available yet") + def test_inference_masked_lm(self): + pass + + @slow + def test_inference_no_head(self): + model = DebertaV2Model.from_pretrained("microsoft/deberta-v2-xlarge") + + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + with torch.no_grad(): + output = model(input_ids, attention_mask=attention_mask)[0] + # compare the actual values for a slice. + expected_slice = torch.tensor( + [[[0.2356, 0.1948, 0.0369], [-0.1063, 0.3586, -0.5152], [-0.6399, -0.0259, -0.2525]]] + ) + self.assertTrue(torch.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4), f"{output[:, 1:4, 1:4]}") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_tf_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_tf_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..60391635eedfadfeb968c5ded58a90d4a64e7cbf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_modeling_tf_deberta_v2.py @@ -0,0 +1,290 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import DebertaV2Config, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFDebertaV2ForMaskedLM, + TFDebertaV2ForQuestionAnswering, + TFDebertaV2ForSequenceClassification, + TFDebertaV2ForTokenClassification, + TFDebertaV2Model, + ) + + +class TFDebertaV2ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + relative_attention=False, + position_biased_input=True, + pos_att_type="None", + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.relative_attention = relative_attention + self.position_biased_input = position_biased_input + self.pos_att_type = pos_att_type + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + + config = DebertaV2Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + relative_attention=self.relative_attention, + position_biased_input=self.position_biased_input, + initializer_range=self.initializer_range, + return_dict=True, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaV2Model(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaV2ForMaskedLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDebertaV2ForSequenceClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDebertaV2ForTokenClassification(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDebertaV2ForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFDebertaModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFDebertaV2Model, + TFDebertaV2ForMaskedLM, + TFDebertaV2ForQuestionAnswering, + TFDebertaV2ForSequenceClassification, + TFDebertaV2ForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFDebertaV2Model, + "fill-mask": TFDebertaV2ForMaskedLM, + "question-answering": TFDebertaV2ForQuestionAnswering, + "text-classification": TFDebertaV2ForSequenceClassification, + "token-classification": TFDebertaV2ForTokenClassification, + "zero-shot": TFDebertaV2ForSequenceClassification, + } + if is_tf_available() + else {} + ) + + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFDebertaV2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=DebertaV2Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + model = TFDebertaV2Model.from_pretrained("kamalkraj/deberta-v2-xlarge") + self.assertIsNotNone(model) + + +@require_tf +class TFDeBERTaV2ModelIntegrationTest(unittest.TestCase): + @unittest.skip(reason="Model not available yet") + def test_inference_masked_lm(self): + pass + + @slow + def test_inference_no_head(self): + model = TFDebertaV2Model.from_pretrained("kamalkraj/deberta-v2-xlarge") + input_ids = tf.constant([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + attention_mask = tf.constant([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + output = model(input_ids, attention_mask=attention_mask)[0] + + expected_slice = tf.constant( + [[[0.2356, 0.1948, 0.0369], [-0.1063, 0.3586, -0.5152], [-0.6399, -0.0259, -0.2525]]] + ) + tf.debugging.assert_near(output[:, 1:4, 1:4], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_tokenization_deberta_v2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_tokenization_deberta_v2.py new file mode 100644 index 0000000000000000000000000000000000000000..961cd82f548c3cc97371b2830effbcd0e87e7100 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deberta_v2/test_tokenization_deberta_v2.py @@ -0,0 +1,255 @@ +# coding=utf-8 +# Copyright 2019 Hugging Face inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import DebertaV2Tokenizer, DebertaV2TokenizerFast +from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/spiece.model") + + +@require_sentencepiece +@require_tokenizers +class DebertaV2TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = DebertaV2Tokenizer + rust_tokenizer_class = DebertaV2TokenizerFast + test_sentencepiece = True + test_sentencepiece_ignore_case = True + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, unk_token="") + tokenizer.save_pretrained(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_text = "this is a test" + output_text = "this is a test" + return input_text, output_text + + def test_convert_token_and_id(self): + """Test ``_convert_token_to_id`` and ``_convert_id_to_token``.""" + token = "" + token_id = 0 + + self.assertEqual(self.get_tokenizer()._convert_token_to_id(token), token_id) + self.assertEqual(self.get_tokenizer()._convert_id_to_token(token_id), token) + + def test_get_vocab(self): + vocab_keys = list(self.get_tokenizer().get_vocab().keys()) + self.assertEqual(vocab_keys[0], "") + self.assertEqual(vocab_keys[1], "") + self.assertEqual(vocab_keys[-1], "[PAD]") + self.assertEqual(len(vocab_keys), 30_001) + + def test_vocab_size(self): + self.assertEqual(self.get_tokenizer().vocab_size, 30_000) + + def test_do_lower_case(self): + # fmt: off + sequence = " \tHeLLo!how \n Are yoU? " + tokens_target = ["▁hello", "!", "how", "▁are", "▁you", "?"] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, do_lower_case=True) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, do_lower_case=True) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(rust_tokens, tokens_target) + + @unittest.skip("There is an inconsistency between slow and fast tokenizer due to a bug in the fast one.") + def test_sentencepiece_tokenize_and_convert_tokens_to_string(self): + pass + + @unittest.skip("There is an inconsistency between slow and fast tokenizer due to a bug in the fast one.") + def test_sentencepiece_tokenize_and_decode(self): + pass + + def test_split_by_punct(self): + # fmt: off + sequence = "I was born in 92000, and this is falsé." + tokens_target = ["▁", "", "▁was", "▁born", "▁in", "▁9", "2000", "▁", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", "▁", ".", ] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, split_by_punct=True) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, split_by_punct=True) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(rust_tokens, tokens_target) + + def test_do_lower_case_split_by_punct(self): + # fmt: off + sequence = "I was born in 92000, and this is falsé." + tokens_target = ["▁i", "▁was", "▁born", "▁in", "▁9", "2000", "▁", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", "▁", ".", ] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, do_lower_case=True, split_by_punct=True) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, do_lower_case=True, split_by_punct=True) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + self.assertListEqual(rust_tokens, tokens_target) + + def test_do_lower_case_split_by_punct_false(self): + # fmt: off + sequence = "I was born in 92000, and this is falsé." + tokens_target = ["▁i", "▁was", "▁born", "▁in", "▁9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", ".", ] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, do_lower_case=True, split_by_punct=False) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, do_lower_case=True, split_by_punct=False) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(rust_tokens, tokens_target) + + def test_do_lower_case_false_split_by_punct(self): + # fmt: off + sequence = "I was born in 92000, and this is falsé." + tokens_target = ["▁", "", "▁was", "▁born", "▁in", "▁9", "2000", "▁", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", "▁", ".", ] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, do_lower_case=False, split_by_punct=True) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, do_lower_case=False, split_by_punct=True) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(rust_tokens, tokens_target) + + def test_do_lower_case_false_split_by_punct_false(self): + # fmt: off + sequence = " \tHeLLo!how \n Are yoU? " + tokens_target = ["▁", "", "e", "", "o", "!", "how", "▁", "", "re", "▁yo", "", "?"] + # fmt: on + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, do_lower_case=False, split_by_punct=False) + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(tokens, tokens_target) + + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, do_lower_case=False, split_by_punct=False) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + + self.assertListEqual(rust_tokens, tokens_target) + + def test_rust_and_python_full_tokenizers(self): + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence = "I was born in 92000, and this is falsé." + + tokens = tokenizer.convert_ids_to_tokens(tokenizer.encode(sequence, add_special_tokens=False)) + rust_tokens = rust_tokenizer.convert_ids_to_tokens(rust_tokenizer.encode(sequence, add_special_tokens=False)) + self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + rust_tokenizer = self.get_rust_tokenizer() + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + def test_full_tokenizer(self): + sequence = "This is a test" + ids_target = [13, 1, 4398, 25, 21, 1289] + tokens_target = ["▁", "T", "his", "▁is", "▁a", "▁test"] + back_tokens_target = ["▁", "", "his", "▁is", "▁a", "▁test"] + + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB, keep_accents=True) + rust_tokenizer = DebertaV2TokenizerFast(SAMPLE_VOCAB, keep_accents=True) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, ids_target) + tokens = tokenizer.tokenize(sequence) + self.assertListEqual(tokens, tokens_target) + back_tokens = tokenizer.convert_ids_to_tokens(ids) + self.assertListEqual(back_tokens, back_tokens_target) + + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(rust_ids, ids_target) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(rust_tokens, tokens_target) + rust_back_tokens = rust_tokenizer.convert_ids_to_tokens(rust_ids) + self.assertListEqual(rust_back_tokens, back_tokens_target) + + # fmt: off + sequence = "I was born in 92000, and this is falsé." + ids_target = [13, 1, 23, 386, 19, 561, 3050, 15, 17, 48, 25, 8256, 18, 1, 9] + tokens_target = ["▁", "I", "▁was", "▁born", "▁in", "▁9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "é", ".", ] + back_tokens_target = ["▁", "", "▁was", "▁born", "▁in", "▁9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", ".", ] + # fmt: on + + ids = tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, ids_target) + tokens = tokenizer.tokenize(sequence) + self.assertListEqual(tokens, tokens_target) + back_tokens = tokenizer.convert_ids_to_tokens(ids) + self.assertListEqual(back_tokens, back_tokens_target) + + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(rust_ids, ids_target) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(rust_tokens, tokens_target) + rust_back_tokens = rust_tokenizer.convert_ids_to_tokens(rust_ids) + self.assertListEqual(rust_back_tokens, back_tokens_target) + + def test_sequence_builders(self): + tokenizer = DebertaV2Tokenizer(SAMPLE_VOCAB) + + text = tokenizer.encode("sequence builders") + text_2 = tokenizer.encode("multi-sequence build") + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + self.assertEqual([tokenizer.cls_token_id] + text + [tokenizer.sep_token_id], encoded_sentence) + self.assertEqual( + [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + text_2 + [tokenizer.sep_token_id], + encoded_pair, + ) + + @slow + def test_tokenizer_integration(self): + # fmt: off + expected_encoding = {'input_ids': [[1, 39867, 36, 19390, 486, 27, 35052, 81436, 18, 60685, 1225, 7, 35052, 81436, 18, 9367, 16899, 18, 15937, 53, 594, 773, 18, 16287, 30465, 36, 15937, 6, 41139, 38, 36979, 60763, 191, 6, 34132, 99, 6, 50538, 390, 43230, 6, 34132, 2779, 20850, 14, 699, 1072, 1194, 36, 382, 10901, 53, 7, 699, 1072, 2084, 36, 20422, 630, 53, 19, 105, 3049, 1896, 1053, 16899, 1506, 11, 37978, 4243, 7, 1237, 31869, 200, 16566, 654, 6, 35052, 81436, 7, 55630, 13593, 4, 2], [1, 26, 15011, 13, 667, 8, 1053, 18, 23611, 1237, 72356, 12820, 34, 104134, 1209, 35, 13313, 6627, 21, 202, 347, 7, 164, 2399, 11, 46, 4485, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 5, 1232, 2864, 15785, 14951, 105, 5, 8581, 1250, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E501 + # fmt: on + + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="microsoft/deberta-v2-xlarge", + revision="ad6e42c1532ddf3a15c39246b63f5559d558b670", + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/decision_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/decision_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/decision_transformer/test_modeling_decision_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/decision_transformer/test_modeling_decision_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..d99521b2f19eb192386159ae341e50f370628fa8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/decision_transformer/test_modeling_decision_transformer.py @@ -0,0 +1,252 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DecisionTransformer model. """ + + +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 DecisionTransformerModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + act_dim=6, + state_dim=17, + hidden_size=23, + max_length=11, + is_training=True, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.act_dim = act_dim + self.state_dim = state_dim + self.hidden_size = hidden_size + self.max_length = max_length + self.is_training = is_training + + def prepare_config_and_inputs(self): + states = floats_tensor((self.batch_size, self.seq_length, self.state_dim)) + actions = floats_tensor((self.batch_size, self.seq_length, self.act_dim)) + rewards = floats_tensor((self.batch_size, self.seq_length, 1)) + returns_to_go = floats_tensor((self.batch_size, self.seq_length, 1)) + timesteps = ids_tensor((self.batch_size, self.seq_length), vocab_size=1000) + attention_mask = random_attention_mask((self.batch_size, self.seq_length)) + + config = self.get_config() + + return ( + config, + states, + actions, + rewards, + returns_to_go, + timesteps, + attention_mask, + ) + + def get_config(self): + 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 create_and_check_model( + self, + config, + states, + actions, + rewards, + returns_to_go, + timesteps, + attention_mask, + ): + model = DecisionTransformerModel(config=config) + model.to(torch_device) + model.eval() + result = model(states, actions, rewards, returns_to_go, timesteps, attention_mask) + + 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 prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + states, + actions, + rewards, + returns_to_go, + timesteps, + attention_mask, + ) = config_and_inputs + inputs_dict = { + "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 DecisionTransformerModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (DecisionTransformerModel,) if is_torch_available() else () + all_generative_model_classes = () + pipeline_model_mapping = {"feature-extraction": DecisionTransformerModel} if is_torch_available() else {} + + # Ignoring of a failing test from GenerationTesterMixin, as the model does not use inputs_ids + test_generate_without_input_ids = False + + # Ignoring of a failing tests from ModelTesterMixin, as the model does not implement these features + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + test_attention_outputs = False + test_hidden_states_output = False + test_inputs_embeds = False + test_model_common_attributes = False + test_gradient_checkpointing = False + test_torchscript = False + + def setUp(self): + self.model_tester = DecisionTransformerModelTester(self) + self.config_tester = ConfigTester(self, config_class=DecisionTransformerConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DecisionTransformerModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = [ + "states", + "actions", + "rewards", + "returns_to_go", + "timesteps", + "attention_mask", + ] + + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + + +@require_torch +class DecisionTransformerModelIntegrationTest(unittest.TestCase): + @slow + def test_autoregressive_prediction(self): + """ + An integration test that performs autoregressive prediction of state, action and return + from a sequence of state, actions and returns. Test is performed over two timesteps. + + """ + + NUM_STEPS = 2 # number of steps of autoregressive prediction we will perform + TARGET_RETURN = 10 # defined by the RL environment, may be normalized + model = DecisionTransformerModel.from_pretrained("edbeeching/decision-transformer-gym-hopper-expert") + model = model.to(torch_device) + config = model.config + torch.manual_seed(0) + state = torch.randn(1, 1, config.state_dim).to(device=torch_device, dtype=torch.float32) # env.reset() + + expected_outputs = torch.tensor( + [[0.242793, -0.28693074, 0.8742613], [0.67815274, -0.08101085, -0.12952147]], device=torch_device + ) + + returns_to_go = torch.tensor(TARGET_RETURN, device=torch_device, dtype=torch.float32).reshape(1, 1, 1) + states = state + actions = torch.zeros(1, 0, config.act_dim, device=torch_device, dtype=torch.float32) + rewards = torch.zeros(1, 0, device=torch_device, dtype=torch.float32) + timesteps = torch.tensor(0, device=torch_device, dtype=torch.long).reshape(1, 1) + + for step in range(NUM_STEPS): + actions = torch.cat([actions, torch.zeros(1, 1, config.act_dim, device=torch_device)], dim=1) + rewards = torch.cat([rewards, torch.zeros(1, 1, device=torch_device)], dim=1) + + attention_mask = torch.ones(1, states.shape[1]).to(dtype=torch.long, device=states.device) + + with torch.no_grad(): + _, action_pred, _ = model( + states=states, + actions=actions, + rewards=rewards, + returns_to_go=returns_to_go, + timesteps=timesteps, + attention_mask=attention_mask, + return_dict=False, + ) + + self.assertEqual(action_pred.shape, actions.shape) + self.assertTrue(torch.allclose(action_pred[0, -1], expected_outputs[step], atol=1e-4)) + state, reward, _, _ = ( # env.step(action) + torch.randn(1, 1, config.state_dim).to(device=torch_device, dtype=torch.float32), + 1.0, + False, + {}, + ) + + actions[-1] = action_pred[0, -1] + states = torch.cat([states, state], dim=1) + pred_return = returns_to_go[0, -1] - reward + returns_to_go = torch.cat([returns_to_go, pred_return.reshape(1, 1, 1)], dim=1) + timesteps = torch.cat( + [timesteps, torch.ones((1, 1), device=torch_device, dtype=torch.long) * (step + 1)], dim=1 + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_image_processing_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_image_processing_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..c0d927b9c980d42cc566c51ce3147f5927e37bf0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_image_processing_deformable_detr.py @@ -0,0 +1,361 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import pathlib +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision, slow +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DeformableDetrImageProcessor + + +class DeformableDetrImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + do_rescale=True, + rescale_factor=1 / 255, + do_pad=True, + ): + # by setting size["longest_edge"] > max_resolution we're effectively not testing this :p + size = size if size is not None else {"shortest_edge": 18, "longest_edge": 1333} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_pad = do_pad + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_rescale": self.do_rescale, + "rescale_factor": self.rescale_factor, + "do_pad": self.do_pad, + } + + def get_expected_values(self, image_inputs, batched=False): + """ + This function computes the expected height and width when providing images to DeformableDetrImageProcessor, + assuming do_resize is set to True with a scalar size. + """ + if not batched: + image = image_inputs[0] + if isinstance(image, Image.Image): + w, h = image.size + else: + h, w = image.shape[1], image.shape[2] + if w < h: + expected_height = int(self.size["shortest_edge"] * h / w) + expected_width = self.size["shortest_edge"] + elif w > h: + expected_height = self.size["shortest_edge"] + expected_width = int(self.size["shortest_edge"] * w / h) + else: + expected_height = self.size["shortest_edge"] + expected_width = self.size["shortest_edge"] + + else: + expected_values = [] + for image in image_inputs: + expected_height, expected_width = self.get_expected_values([image]) + expected_values.append((expected_height, expected_width)) + expected_height = max(expected_values, key=lambda item: item[0])[0] + expected_width = max(expected_values, key=lambda item: item[1])[1] + + return expected_height, expected_width + + +@require_torch +@require_vision +class DeformableDetrImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DeformableDetrImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = DeformableDetrImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + self.assertTrue(hasattr(image_processing, "do_pad")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 18, "longest_edge": 1333}) + self.assertEqual(image_processor.do_pad, True) + + image_processor = self.image_processing_class.from_dict( + self.image_processor_dict, size=42, max_size=84, pad_and_return_pixel_mask=False + ) + self.assertEqual(image_processor.size, {"shortest_edge": 42, "longest_edge": 84}) + self.assertEqual(image_processor.do_pad, False) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_equivalence_pad_and_create_pixel_mask(self): + # Initialize image_processings + image_processing_1 = self.image_processing_class(**self.image_processor_dict) + image_processing_2 = self.image_processing_class(do_resize=False, do_normalize=False, do_rescale=False) + + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test whether the method "pad_and_return_pixel_mask" and calling the image processor return the same tensors + encoded_images_with_method = image_processing_1.pad_and_create_pixel_mask(image_inputs, return_tensors="pt") + encoded_images = image_processing_2(image_inputs, return_tensors="pt") + + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_values"], encoded_images["pixel_values"], atol=1e-4) + ) + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_mask"], encoded_images["pixel_mask"], atol=1e-4) + ) + + @slow + def test_call_pytorch_with_coco_detection_annotations(self): + # prepare image and target + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"image_id": 39769, "annotations": target} + + # encode them + image_processing = DeformableDetrImageProcessor() + encoding = image_processing(images=image, annotations=target, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([5887.9600, 11250.2061, 489353.8438, 837122.7500, 147967.5156, 165732.3438]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.5503, 0.2765, 0.0604, 0.2215]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([75, 75, 63, 65, 17, 17]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) + + @slow + def test_call_pytorch_with_coco_panoptic_annotations(self): + # prepare image, target and masks_path + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"file_name": "000000039769.png", "image_id": 39769, "segments_info": target} + + masks_path = pathlib.Path("./tests/fixtures/tests_samples/COCO/coco_panoptic") + + # encode them + image_processing = DeformableDetrImageProcessor(format="coco_panoptic") + encoding = image_processing(images=image, annotations=target, masks_path=masks_path, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([147979.6875, 165527.0469, 484638.5938, 11292.9375, 5879.6562, 7634.1147]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.2625, 0.5437, 0.4688, 0.8625]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([17, 17, 63, 75, 75, 93]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify masks + expected_masks_sum = 822873 + self.assertEqual(encoding["labels"][0]["masks"].sum().item(), expected_masks_sum) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_modeling_deformable_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_modeling_deformable_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..3c7c2f640a5911d0522712130eca5be6b2e59a28 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deformable_detr/test_modeling_deformable_detr.py @@ -0,0 +1,667 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Deformable DETR model. """ + + +import inspect +import math +import unittest +from typing import Dict, List, Tuple + +from transformers import DeformableDetrConfig, is_timm_available, is_vision_available +from transformers.file_utils import cached_property +from transformers.testing_utils import require_timm, require_torch_gpu, require_vision, slow, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_timm_available(): + import torch + + from transformers import DeformableDetrForObjectDetection, DeformableDetrModel, ResNetConfig + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoFeatureExtractor + + +class DeformableDetrModelTester: + def __init__( + self, + parent, + batch_size=8, + is_training=True, + use_labels=True, + hidden_size=256, + num_hidden_layers=2, + num_attention_heads=8, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + num_queries=12, + num_channels=3, + image_size=196, + n_targets=8, + num_labels=91, + num_feature_levels=4, + encoder_n_points=2, + decoder_n_points=6, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.num_queries = num_queries + self.num_channels = num_channels + self.image_size = image_size + self.n_targets = n_targets + self.num_labels = num_labels + self.num_feature_levels = num_feature_levels + self.encoder_n_points = encoder_n_points + self.decoder_n_points = decoder_n_points + + # we also set the expected seq length for both encoder and decoder + self.encoder_seq_length = ( + math.ceil(self.image_size / 8) ** 2 + + math.ceil(self.image_size / 16) ** 2 + + math.ceil(self.image_size / 32) ** 2 + + math.ceil(self.image_size / 64) ** 2 + ) + self.decoder_seq_length = self.num_queries + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + pixel_mask = torch.ones([self.batch_size, self.image_size, self.image_size], device=torch_device) + + labels = None + if self.use_labels: + # labels is a list of Dict (each Dict being the labels for a given example in the batch) + labels = [] + for i in range(self.batch_size): + target = {} + target["class_labels"] = torch.randint( + high=self.num_labels, size=(self.n_targets,), device=torch_device + ) + target["boxes"] = torch.rand(self.n_targets, 4, device=torch_device) + target["masks"] = torch.rand(self.n_targets, self.image_size, self.image_size, device=torch_device) + labels.append(target) + + config = self.get_config() + return config, pixel_values, pixel_mask, labels + + def get_config(self): + return DeformableDetrConfig( + 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, + num_queries=self.num_queries, + num_labels=self.num_labels, + num_feature_levels=self.num_feature_levels, + encoder_n_points=self.encoder_n_points, + decoder_n_points=self.decoder_n_points, + ) + + def prepare_config_and_inputs_for_common(self): + config, pixel_values, pixel_mask, labels = self.prepare_config_and_inputs() + inputs_dict = {"pixel_values": pixel_values, "pixel_mask": pixel_mask} + return config, inputs_dict + + def create_and_check_deformable_detr_model(self, config, pixel_values, pixel_mask, labels): + model = DeformableDetrModel(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.num_queries, self.hidden_size)) + + def create_and_check_deformable_detr_object_detection_head_model(self, config, pixel_values, pixel_mask, labels): + model = DeformableDetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + def create_and_check_no_timm_backbone(self, config, pixel_values, pixel_mask, labels): + config.use_timm_backbone = False + config.backbone_config = ResNetConfig() + model = DeformableDetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + +@require_timm +class DeformableDetrModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (DeformableDetrModel, DeformableDetrForObjectDetection) if is_timm_available() else () + pipeline_model_mapping = ( + {"feature-extraction": DeformableDetrModel, "object-detection": DeformableDetrForObjectDetection} + if is_timm_available() + else {} + ) + is_encoder_decoder = True + test_torchscript = False + test_pruning = False + test_head_masking = False + test_missing_keys = False + + # special case for head models + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "DeformableDetrForObjectDetection": + labels = [] + for i in range(self.model_tester.batch_size): + target = {} + target["class_labels"] = torch.ones( + size=(self.model_tester.n_targets,), device=torch_device, dtype=torch.long + ) + target["boxes"] = torch.ones( + self.model_tester.n_targets, 4, device=torch_device, dtype=torch.float + ) + target["masks"] = torch.ones( + self.model_tester.n_targets, + self.model_tester.image_size, + self.model_tester.image_size, + device=torch_device, + dtype=torch.float, + ) + labels.append(target) + inputs_dict["labels"] = labels + + return inputs_dict + + def setUp(self): + self.model_tester = DeformableDetrModelTester(self) + self.config_tester = ConfigTester(self, config_class=DeformableDetrConfig, has_text_modality=False) + + def test_config(self): + # we don't test common_properties and arguments_init as these don't apply for Deformable DETR + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + + def test_deformable_detr_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deformable_detr_model(*config_and_inputs) + + def test_deformable_detr_object_detection_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deformable_detr_object_detection_head_model(*config_and_inputs) + + def test_deformable_detr_no_timm_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_no_timm_backbone(*config_and_inputs) + + @unittest.skip(reason="Deformable DETR does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Deformable DETR does not have a get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="Deformable DETR is not a generative model") + def test_generate_without_input_ids(self): + pass + + @unittest.skip(reason="Deformable DETR does not use token embeddings") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.encoder_n_points, + ], + ) + out_len = len(outputs) + + correct_outlen = 8 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Object Detection model returns pred_logits and pred_boxes + if model_class.__name__ == "DeformableDetrForObjectDetection": + correct_outlen += 2 + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, self.model_tester.num_queries, self.model_tester.num_queries], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.decoder_n_points, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.encoder_n_points, + ], + ) + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def set_nan_tensor_to_zero(t): + t[t != t] = 0 + return t + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + with torch.no_grad(): + tuple_output = model(**tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(**dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif isinstance(tuple_object, Dict): + for tuple_iterable_value, dict_iterable_value in zip( + tuple_object.values(), dict_object.values() + ): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + torch.allclose( + set_nan_tensor_to_zero(tuple_object), set_nan_tensor_to_zero(dict_object), atol=1e-5 + ), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {torch.max(torch.abs(tuple_object - dict_object))}. Tuple has `nan`:" + f" {torch.isnan(tuple_object).any()} and `inf`: {torch.isinf(tuple_object)}. Dict has" + f" `nan`: {torch.isnan(dict_object).any()} and `inf`: {torch.isinf(dict_object)}." + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + print("Model class:", model_class) + model = model_class(config) + model.to(torch_device) + model.eval() + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence( + model, tuple_inputs, dict_inputs, {"output_hidden_states": True, "output_attentions": True} + ) + + def test_retain_grad_hidden_states_attentions(self): + # removed retain_grad and grad on decoder_hidden_states, as queries don't require grad + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + # we take the second output since last_hidden_state is the second item + output = outputs[1] + + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_attentions = outputs.encoder_attentions[0] + encoder_hidden_states.retain_grad() + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = ["pixel_values", "pixel_mask"] + expected_arg_names.extend( + ["head_mask", "decoder_head_mask", "encoder_outputs"] + if "head_mask" and "decoder_head_mask" in arg_names + else [] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["pixel_values", "pixel_mask"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_different_timm_backbone(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # let's pick a random timm backbone + config.backbone = "tf_mobilenetv3_small_075" + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if model_class.__name__ == "DeformableDetrForObjectDetection": + expected_shape = ( + self.model_tester.batch_size, + self.model_tester.num_queries, + self.model_tester.num_labels, + ) + self.assertEqual(outputs.logits.shape, expected_shape) + + self.assertTrue(outputs) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + print("Model class:", model_class) + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + if param.requires_grad: + if ( + "level_embed" in name + or "sampling_offsets.bias" in name + or "value_proj" in name + or "output_proj" in name + or "reference_points" in name + ): + continue + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +TOLERANCE = 1e-4 + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_timm +@require_vision +@slow +class DeformableDetrModelIntegrationTests(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return AutoFeatureExtractor.from_pretrained("SenseTime/deformable-detr") if is_vision_available() else None + + def test_inference_object_detection_head(self): + model = DeformableDetrForObjectDetection.from_pretrained("SenseTime/deformable-detr").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + pixel_values = encoding["pixel_values"].to(torch_device) + pixel_mask = encoding["pixel_mask"].to(torch_device) + + with torch.no_grad(): + outputs = model(pixel_values, pixel_mask) + + expected_shape_logits = torch.Size((1, model.config.num_queries, model.config.num_labels)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + + expected_logits = torch.tensor( + [[-9.6645, -4.3449, -5.8705], [-9.7035, -3.8504, -5.0724], [-10.5634, -5.3379, -7.5116]] + ).to(torch_device) + expected_boxes = torch.tensor( + [[0.8693, 0.2289, 0.2492], [0.3150, 0.5489, 0.5845], [0.5563, 0.7580, 0.8518]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, model.config.num_queries, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes, atol=1e-4)) + + # verify postprocessing + results = feature_extractor.post_process_object_detection( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + expected_scores = torch.tensor([0.7999, 0.7894, 0.6331, 0.4720, 0.4382]).to(torch_device) + expected_labels = [17, 17, 75, 75, 63] + expected_slice_boxes = torch.tensor([16.5028, 52.8390, 318.2544, 470.7841]).to(torch_device) + + self.assertEqual(len(results["scores"]), 5) + self.assertTrue(torch.allclose(results["scores"], expected_scores, atol=1e-4)) + self.assertSequenceEqual(results["labels"].tolist(), expected_labels) + self.assertTrue(torch.allclose(results["boxes"][0, :], expected_slice_boxes)) + + def test_inference_object_detection_head_with_box_refine_two_stage(self): + model = DeformableDetrForObjectDetection.from_pretrained( + "SenseTime/deformable-detr-with-box-refine-two-stage" + ).to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + pixel_values = encoding["pixel_values"].to(torch_device) + pixel_mask = encoding["pixel_mask"].to(torch_device) + + with torch.no_grad(): + outputs = model(pixel_values, pixel_mask) + + expected_shape_logits = torch.Size((1, model.config.num_queries, model.config.num_labels)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + + expected_logits = torch.tensor( + [[-6.7108, -4.3213, -6.3777], [-8.9014, -6.1799, -6.7240], [-6.9315, -4.4735, -6.2298]] + ).to(torch_device) + expected_boxes = torch.tensor( + [[0.2583, 0.5499, 0.4683], [0.7652, 0.9068, 0.4882], [0.5490, 0.2763, 0.0564]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, model.config.num_queries, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes, atol=1e-4)) + + @require_torch_gpu + def test_inference_object_detection_head_equivalence_cpu_gpu(self): + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt") + pixel_values = encoding["pixel_values"] + pixel_mask = encoding["pixel_mask"] + + # 1. run model on CPU + model = DeformableDetrForObjectDetection.from_pretrained("SenseTime/deformable-detr-single-scale") + + with torch.no_grad(): + cpu_outputs = model(pixel_values, pixel_mask) + + # 2. run model on GPU + model.to("cuda") + + with torch.no_grad(): + gpu_outputs = model(pixel_values.to("cuda"), pixel_mask.to("cuda")) + + # 3. assert equivalence + for key in cpu_outputs.keys(): + assert torch.allclose(cpu_outputs[key], gpu_outputs[key].cpu(), atol=1e-4) + + expected_logits = torch.tensor( + [[-9.9051, -4.2541, -6.4852], [-9.6947, -4.0854, -6.8033], [-10.0665, -5.8470, -7.7003]] + ) + assert torch.allclose(cpu_outputs.logits[0, :3, :3], expected_logits, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_image_processing_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_image_processing_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..4103fc8fb25d5ebeac0bca3bd7484e1b729e3e5b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_image_processing_deit.py @@ -0,0 +1,211 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DeiTImageProcessor + + +class DeiTImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_center_crop=True, + crop_size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"height": 20, "width": 20} + crop_size = crop_size if crop_size is not None else {"height": 18, "width": 18} + + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_center_crop": self.do_center_crop, + "crop_size": self.crop_size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + } + + +@require_torch +@require_vision +class DeiTImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DeiTImageProcessor if is_vision_available() else None + test_cast_dtype = True + + def setUp(self): + self.image_processor_tester = DeiTImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_center_crop")) + self.assertTrue(hasattr(image_processing, "center_crop")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 20, "width": 20}) + self.assertEqual(image_processor.crop_size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42, crop_size=84) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + self.assertEqual(image_processor.crop_size, {"height": 84, "width": 84}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..1564b23aa65959625437813bfda1ba8294c7a52b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_deit.py @@ -0,0 +1,431 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DeiT model. """ + + +import inspect +import unittest +import warnings + +from transformers import DeiTConfig +from transformers.models.auto import get_values +from transformers.testing_utils import ( + require_accelerate, + require_torch, + require_torch_gpu, + require_vision, + slow, + torch_device, +) +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + MODEL_MAPPING, + DeiTForImageClassification, + DeiTForImageClassificationWithTeacher, + DeiTForMaskedImageModeling, + DeiTModel, + ) + from transformers.models.deit.modeling_deit import DEIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import DeiTFeatureExtractor + + +class DeiTModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + type_sequence_label_size=10, + initializer_range=0.02, + num_labels=3, + scope=None, + encoder_stride=2, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.scope = scope + self.encoder_stride = encoder_stride + + # in DeiT, the seq length equals the number of patches + 2 (we add 2 for the [CLS] and distilation tokens) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 2 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return DeiTConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + encoder_stride=self.encoder_stride, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = DeiTModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_image_modeling(self, config, pixel_values, labels): + model = DeiTForMaskedImageModeling(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual( + result.reconstruction.shape, (self.batch_size, self.num_channels, self.image_size, self.image_size) + ) + + # test greyscale images + config.num_channels = 1 + model = DeiTForMaskedImageModeling(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.reconstruction.shape, (self.batch_size, 1, self.image_size, self.image_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.type_sequence_label_size + model = DeiTForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + # test greyscale images + config.num_channels = 1 + model = DeiTForImageClassification(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + pixel_values, + labels, + ) = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class DeiTModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as DeiT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + ( + DeiTModel, + DeiTForImageClassification, + DeiTForImageClassificationWithTeacher, + DeiTForMaskedImageModeling, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": DeiTModel, + "image-classification": (DeiTForImageClassification, DeiTForImageClassificationWithTeacher), + } + if is_torch_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = DeiTModelTester(self) + self.config_tester = ConfigTester(self, config_class=DeiTConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="DeiT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_image_modeling(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_image_modeling(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + # special case for DeiTForImageClassificationWithTeacher model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "DeiTForImageClassificationWithTeacher": + del inputs_dict["labels"] + + return inputs_dict + + def test_training(self): + if not self.model_tester.is_training: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + # DeiTForImageClassificationWithTeacher supports inference-only + if ( + model_class in get_values(MODEL_MAPPING) + or model_class.__name__ == "DeiTForImageClassificationWithTeacher" + ): + continue + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if not self.model_tester.is_training: + return + + config.use_cache = False + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class in get_values(MODEL_MAPPING) or not model_class.supports_gradient_checkpointing: + continue + # DeiTForImageClassificationWithTeacher supports inference-only + if model_class.__name__ == "DeiTForImageClassificationWithTeacher": + continue + model = model_class(config) + model.gradient_checkpointing_enable() + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_problem_types(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + problem_types = [ + {"title": "multi_label_classification", "num_labels": 2, "dtype": torch.float}, + {"title": "single_label_classification", "num_labels": 1, "dtype": torch.long}, + {"title": "regression", "num_labels": 1, "dtype": torch.float}, + ] + + for model_class in self.all_model_classes: + if ( + model_class + not in [ + *get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING), + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING), + ] + or model_class.__name__ == "DeiTForImageClassificationWithTeacher" + ): + continue + + for problem_type in problem_types: + with self.subTest(msg=f"Testing {model_class} with {problem_type['title']}"): + config.problem_type = problem_type["title"] + config.num_labels = problem_type["num_labels"] + + model = model_class(config) + model.to(torch_device) + model.train() + + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + + if problem_type["num_labels"] > 1: + inputs["labels"] = inputs["labels"].unsqueeze(1).repeat(1, problem_type["num_labels"]) + + inputs["labels"] = inputs["labels"].to(problem_type["dtype"]) + + # This tests that we do not trigger the warning form PyTorch "Using a target size that is different + # to the input size. This will likely lead to incorrect results due to broadcasting. Please ensure + # they have the same size." which is a symptom something in wrong for the regression problem. + # See https://github.com/huggingface/transformers/issues/11780 + with warnings.catch_warnings(record=True) as warning_list: + loss = model(**inputs).loss + for w in warning_list: + if "Using a target size that is different to the input size" in str(w.message): + raise ValueError( + f"Something is going wrong in the regression problem: intercepted {w.message}" + ) + + loss.backward() + + @slow + def test_model_from_pretrained(self): + for model_name in DEIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DeiTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class DeiTModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + DeiTFeatureExtractor.from_pretrained("facebook/deit-base-distilled-patch16-224") + if is_vision_available() + else None + ) + + @slow + def test_inference_image_classification_head(self): + model = DeiTForImageClassificationWithTeacher.from_pretrained("facebook/deit-base-distilled-patch16-224").to( + torch_device + ) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([-1.0266, 0.1912, -1.2861]).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) + + @slow + @require_accelerate + @require_torch_gpu + def test_inference_fp16(self): + r""" + A small test to make sure that inference work in half precision without any problem. + """ + model = DeiTModel.from_pretrained( + "facebook/deit-base-distilled-patch16-224", torch_dtype=torch.float16, device_map="auto" + ) + feature_extractor = self.default_feature_extractor + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt") + pixel_values = inputs.pixel_values.to(torch_device) + + # forward pass to make sure inference works in fp16 + with torch.no_grad(): + _ = model(pixel_values) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_tf_deit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_tf_deit.py new file mode 100644 index 0000000000000000000000000000000000000000..223d164d4aaf3ffcf29388b3a6964d012168065c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deit/test_modeling_tf_deit.py @@ -0,0 +1,291 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the TensorFlow DeiT model. """ + + +import inspect +import unittest + +import numpy as np + +from transformers import DeiTConfig +from transformers.testing_utils import require_tf, require_vision, slow +from transformers.utils import cached_property, is_tf_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFDeiTForImageClassification, + TFDeiTForImageClassificationWithTeacher, + TFDeiTForMaskedImageModeling, + TFDeiTModel, + ) + from transformers.models.deit.modeling_tf_deit import TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import DeiTFeatureExtractor + + +class TFDeiTModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + type_sequence_label_size=10, + initializer_range=0.02, + num_labels=3, + scope=None, + encoder_stride=2, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.scope = scope + self.encoder_stride = encoder_stride + + # in DeiT, the seq length equals the number of patches + 2 (we add 2 for the [CLS] and distilation tokens) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 2 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return DeiTConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + encoder_stride=self.encoder_stride, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = TFDeiTModel(config=config) + result = model(pixel_values) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_image_modeling(self, config, pixel_values, labels): + model = TFDeiTForMaskedImageModeling(config=config) + result = model(pixel_values) + self.parent.assertEqual( + result.reconstruction.shape, (self.batch_size, self.num_channels, self.image_size, self.image_size) + ) + + # test greyscale images + config.num_channels = 1 + model = TFDeiTForMaskedImageModeling(config) + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.reconstruction.shape, (self.batch_size, 1, self.image_size, self.image_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.type_sequence_label_size + model = TFDeiTForImageClassification(config) + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + # test greyscale images + config.num_channels = 1 + model = TFDeiTForImageClassification(config) + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_tf +class TFDeiTModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_tf_common.py, as DeiT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + ( + TFDeiTModel, + TFDeiTForImageClassification, + TFDeiTForImageClassificationWithTeacher, + TFDeiTForMaskedImageModeling, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFDeiTModel, + "image-classification": (TFDeiTForImageClassification, TFDeiTForImageClassificationWithTeacher), + } + if is_tf_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFDeiTModelTester(self) + self.config_tester = ConfigTester(self, config_class=DeiTConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="DeiT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (tf.keras.layers.Layer)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, tf.keras.layers.Dense)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_image_modeling(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_image_modeling(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + # special case for DeiTForImageClassificationWithTeacher model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "DeiTForImageClassificationWithTeacher": + del inputs_dict["labels"] + + return inputs_dict + + @slow + def test_model_from_pretrained(self): + for model_name in TF_DEIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFDeiTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_tf +@require_vision +class DeiTModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + DeiTFeatureExtractor.from_pretrained("facebook/deit-base-distilled-patch16-224") + if is_vision_available() + else None + ) + + @slow + def test_inference_image_classification_head(self): + model = TFDeiTForImageClassificationWithTeacher.from_pretrained("facebook/deit-base-distilled-patch16-224") + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="tf") + + # forward pass + outputs = model(**inputs) + + # verify the logits + expected_shape = tf.TensorShape((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = tf.constant([-1.0266, 0.1912, -1.2861]) + + self.assertTrue(np.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_image_processing_deta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_image_processing_deta.py new file mode 100644 index 0000000000000000000000000000000000000000..e6e98476657746a14991bb3eeed28b7a3246f7bd --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_image_processing_deta.py @@ -0,0 +1,355 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import pathlib +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision, slow +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DetaImageProcessor + + +class DetaImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + do_rescale=True, + rescale_factor=1 / 255, + do_pad=True, + ): + # by setting size["longest_edge"] > max_resolution we're effectively not testing this :p + size = size if size is not None else {"shortest_edge": 18, "longest_edge": 1333} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_pad = do_pad + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_rescale": self.do_rescale, + "rescale_factor": self.rescale_factor, + "do_pad": self.do_pad, + } + + def get_expected_values(self, image_inputs, batched=False): + """ + This function computes the expected height and width when providing images to DetaImageProcessor, + assuming do_resize is set to True with a scalar size. + """ + if not batched: + image = image_inputs[0] + if isinstance(image, Image.Image): + w, h = image.size + else: + h, w = image.shape[1], image.shape[2] + if w < h: + expected_height = int(self.size["shortest_edge"] * h / w) + expected_width = self.size["shortest_edge"] + elif w > h: + expected_height = self.size["shortest_edge"] + expected_width = int(self.size["shortest_edge"] * w / h) + else: + expected_height = self.size["shortest_edge"] + expected_width = self.size["shortest_edge"] + + else: + expected_values = [] + for image in image_inputs: + expected_height, expected_width = self.get_expected_values([image]) + expected_values.append((expected_height, expected_width)) + expected_height = max(expected_values, key=lambda item: item[0])[0] + expected_width = max(expected_values, key=lambda item: item[1])[1] + + return expected_height, expected_width + + +@require_torch +@require_vision +class DetaImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DetaImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = DetaImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + self.assertTrue(hasattr(image_processing, "do_pad")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 18, "longest_edge": 1333}) + self.assertEqual(image_processor.do_pad, True) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_equivalence_pad_and_create_pixel_mask(self): + # Initialize image_processings + image_processing_1 = self.image_processing_class(**self.image_processor_dict) + image_processing_2 = self.image_processing_class(do_resize=False, do_normalize=False, do_rescale=False) + + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test whether the method "pad_and_return_pixel_mask" and calling the image processor return the same tensors + encoded_images_with_method = image_processing_1.pad_and_create_pixel_mask(image_inputs, return_tensors="pt") + encoded_images = image_processing_2(image_inputs, return_tensors="pt") + + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_values"], encoded_images["pixel_values"], atol=1e-4) + ) + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_mask"], encoded_images["pixel_mask"], atol=1e-4) + ) + + @slow + def test_call_pytorch_with_coco_detection_annotations(self): + # prepare image and target + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"image_id": 39769, "annotations": target} + + # encode them + image_processing = DetaImageProcessor() + encoding = image_processing(images=image, annotations=target, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([5887.9600, 11250.2061, 489353.8438, 837122.7500, 147967.5156, 165732.3438]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.5503, 0.2765, 0.0604, 0.2215]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([75, 75, 63, 65, 17, 17]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) + + @slow + def test_call_pytorch_with_coco_panoptic_annotations(self): + # prepare image, target and masks_path + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"file_name": "000000039769.png", "image_id": 39769, "segments_info": target} + + masks_path = pathlib.Path("./tests/fixtures/tests_samples/COCO/coco_panoptic") + + # encode them + image_processing = DetaImageProcessor(format="coco_panoptic") + encoding = image_processing(images=image, annotations=target, masks_path=masks_path, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([147979.6875, 165527.0469, 484638.5938, 11292.9375, 5879.6562, 7634.1147]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.2625, 0.5437, 0.4688, 0.8625]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([17, 17, 63, 75, 75, 93]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify masks + expected_masks_sum = 822873 + self.assertEqual(encoding["labels"][0]["masks"].sum().item(), expected_masks_sum) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_modeling_deta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_modeling_deta.py new file mode 100644 index 0000000000000000000000000000000000000000..b1d54a87def4798a3f123b95634195d247e4b6d3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/deta/test_modeling_deta.py @@ -0,0 +1,547 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DETA model. """ + + +import inspect +import math +import unittest + +from transformers import DetaConfig, is_torch_available, is_torchvision_available, is_vision_available +from transformers.file_utils import cached_property +from transformers.testing_utils import require_torchvision, require_vision, slow, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + +if is_torchvision_available(): + from transformers import DetaForObjectDetection, DetaModel + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoImageProcessor + + +class DetaModelTester: + def __init__( + self, + parent, + batch_size=8, + is_training=True, + use_labels=True, + hidden_size=256, + num_hidden_layers=2, + num_attention_heads=8, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + num_queries=12, + num_channels=3, + image_size=196, + n_targets=8, + num_labels=91, + num_feature_levels=4, + encoder_n_points=2, + decoder_n_points=6, + two_stage=False, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.num_queries = num_queries + self.num_channels = num_channels + self.image_size = image_size + self.n_targets = n_targets + self.num_labels = num_labels + self.num_feature_levels = num_feature_levels + self.encoder_n_points = encoder_n_points + self.decoder_n_points = decoder_n_points + self.two_stage = two_stage + + # we also set the expected seq length for both encoder and decoder + self.encoder_seq_length = ( + math.ceil(self.image_size / 8) ** 2 + + math.ceil(self.image_size / 16) ** 2 + + math.ceil(self.image_size / 32) ** 2 + + math.ceil(self.image_size / 64) ** 2 + ) + self.decoder_seq_length = self.num_queries + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + pixel_mask = torch.ones([self.batch_size, self.image_size, self.image_size], device=torch_device) + + labels = None + if self.use_labels: + # labels is a list of Dict (each Dict being the labels for a given example in the batch) + labels = [] + for i in range(self.batch_size): + target = {} + target["class_labels"] = torch.randint( + high=self.num_labels, size=(self.n_targets,), device=torch_device + ) + target["boxes"] = torch.rand(self.n_targets, 4, device=torch_device) + target["masks"] = torch.rand(self.n_targets, self.image_size, self.image_size, device=torch_device) + labels.append(target) + + config = self.get_config() + return config, pixel_values, pixel_mask, labels + + def get_config(self): + return DetaConfig( + 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, + num_queries=self.num_queries, + num_labels=self.num_labels, + num_feature_levels=self.num_feature_levels, + encoder_n_points=self.encoder_n_points, + decoder_n_points=self.decoder_n_points, + two_stage=self.two_stage, + ) + + def prepare_config_and_inputs_for_common(self): + config, pixel_values, pixel_mask, labels = self.prepare_config_and_inputs() + inputs_dict = {"pixel_values": pixel_values, "pixel_mask": pixel_mask} + return config, inputs_dict + + def create_and_check_deta_model(self, config, pixel_values, pixel_mask, labels): + model = DetaModel(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.num_queries, self.hidden_size)) + + def create_and_check_deta_object_detection_head_model(self, config, pixel_values, pixel_mask, labels): + model = DetaForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + +@require_torchvision +class DetaModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (DetaModel, DetaForObjectDetection) if is_torchvision_available() else () + pipeline_model_mapping = ( + {"feature-extraction": DetaModel, "object-detection": DetaForObjectDetection} + if is_torchvision_available() + else {} + ) + is_encoder_decoder = True + test_torchscript = False + test_pruning = False + test_head_masking = False + test_missing_keys = False + + # TODO: Fix the failed tests when this model gets more usage + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "ObjectDetectionPipelineTests": + return True + + return False + + @unittest.skip("Skip for now. PR #22437 causes some loading issue. See (not merged) #22656 for some discussions.") + def test_can_use_safetensors(self): + super().test_can_use_safetensors() + + # special case for head models + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "DetaForObjectDetection": + labels = [] + for i in range(self.model_tester.batch_size): + target = {} + target["class_labels"] = torch.ones( + size=(self.model_tester.n_targets,), device=torch_device, dtype=torch.long + ) + target["boxes"] = torch.ones( + self.model_tester.n_targets, 4, device=torch_device, dtype=torch.float + ) + target["masks"] = torch.ones( + self.model_tester.n_targets, + self.model_tester.image_size, + self.model_tester.image_size, + device=torch_device, + dtype=torch.float, + ) + labels.append(target) + inputs_dict["labels"] = labels + + return inputs_dict + + def setUp(self): + self.model_tester = DetaModelTester(self) + self.config_tester = ConfigTester(self, config_class=DetaConfig, has_text_modality=False) + + def test_config(self): + # we don't test common_properties and arguments_init as these don't apply for DETA + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + + def test_deta_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deta_model(*config_and_inputs) + + def test_deta_object_detection_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_deta_object_detection_head_model(*config_and_inputs) + + @unittest.skip(reason="DETA does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="DETA does not have a get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="DETA is not a generative model") + def test_generate_without_input_ids(self): + pass + + @unittest.skip(reason="DETA does not use token embeddings") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.encoder_n_points, + ], + ) + out_len = len(outputs) + + correct_outlen = 8 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Object Detection model returns pred_logits and pred_boxes + if model_class.__name__ == "DetaForObjectDetection": + correct_outlen += 2 + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, self.model_tester.num_queries, self.model_tester.num_queries], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.decoder_n_points, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + self.model_tester.num_feature_levels, + self.model_tester.encoder_n_points, + ], + ) + + # removed retain_grad and grad on decoder_hidden_states, as queries don't require grad + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + # we take the second output since last_hidden_state is the second item + output = outputs[1] + + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_attentions = outputs.encoder_attentions[0] + encoder_hidden_states.retain_grad() + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = ["pixel_values", "pixel_mask"] + expected_arg_names.extend( + ["head_mask", "decoder_head_mask", "encoder_outputs"] + if "head_mask" and "decoder_head_mask" in arg_names + else [] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["pixel_values", "pixel_mask"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + @unittest.skip(reason="Model doesn't use tied weights") + def test_tied_model_weights_key_ignore(self): + pass + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + # Skip the check for the backbone + for name, module in model.named_modules(): + if module.__class__.__name__ == "DetaBackboneWithPositionalEncodings": + backbone_params = [f"{name}.{key}" for key in module.state_dict().keys()] + break + + for name, param in model.named_parameters(): + if param.requires_grad: + if ( + "level_embed" in name + or "sampling_offsets.bias" in name + or "value_proj" in name + or "output_proj" in name + or "reference_points" in name + or name in backbone_params + ): + continue + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +TOLERANCE = 1e-4 + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torchvision +@require_vision +@slow +class DetaModelIntegrationTests(unittest.TestCase): + @cached_property + def default_image_processor(self): + return AutoImageProcessor.from_pretrained("jozhang97/deta-resnet-50") if is_vision_available() else None + + def test_inference_object_detection_head(self): + model = DetaForObjectDetection.from_pretrained("jozhang97/deta-resnet-50").to(torch_device) + + image_processor = self.default_image_processor + image = prepare_img() + inputs = image_processor(images=image, return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**inputs) + + expected_shape_logits = torch.Size((1, 300, model.config.num_labels)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + + expected_logits = torch.tensor( + [[-7.3978, -2.5406, -4.1668], [-8.2684, -3.9933, -3.8096], [-7.0515, -3.7973, -5.8516]] + ).to(torch_device) + expected_boxes = torch.tensor( + [[0.5043, 0.4973, 0.9998], [0.2542, 0.5489, 0.4748], [0.5490, 0.2765, 0.0570]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, 300, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes, atol=1e-4)) + + # verify postprocessing + results = image_processor.post_process_object_detection( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + expected_scores = torch.tensor([0.6392, 0.6276, 0.5546, 0.5260, 0.4706], device=torch_device) + expected_labels = [75, 17, 17, 75, 63] + expected_slice_boxes = torch.tensor([40.5866, 73.2107, 176.1421, 117.1751], device=torch_device) + + self.assertTrue(torch.allclose(results["scores"], expected_scores, atol=1e-4)) + self.assertSequenceEqual(results["labels"].tolist(), expected_labels) + self.assertTrue(torch.allclose(results["boxes"][0, :], expected_slice_boxes)) + + def test_inference_object_detection_head_swin_backbone(self): + model = DetaForObjectDetection.from_pretrained("jozhang97/deta-swin-large").to(torch_device) + + image_processor = self.default_image_processor + image = prepare_img() + inputs = image_processor(images=image, return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**inputs) + + expected_shape_logits = torch.Size((1, 300, model.config.num_labels)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + + expected_logits = torch.tensor( + [[-7.6308, -2.8485, -5.3737], [-7.2037, -4.5505, -4.8027], [-7.2943, -4.2611, -4.6617]] + ).to(torch_device) + expected_boxes = torch.tensor( + [[0.4987, 0.4969, 0.9999], [0.2549, 0.5498, 0.4805], [0.5498, 0.2757, 0.0569]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, 300, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_boxes, atol=1e-4)) + + # verify postprocessing + results = image_processor.post_process_object_detection( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + expected_scores = torch.tensor([0.6831, 0.6826, 0.5684, 0.5464, 0.4392], device=torch_device) + expected_labels = [17, 17, 75, 75, 63] + expected_slice_boxes = torch.tensor([345.8478, 23.6754, 639.8562, 372.8265], device=torch_device) + + self.assertTrue(torch.allclose(results["scores"], expected_scores, atol=1e-4)) + self.assertSequenceEqual(results["labels"].tolist(), expected_labels) + self.assertTrue(torch.allclose(results["boxes"][0, :], expected_slice_boxes)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_image_processing_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_image_processing_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..d6354de43dbe29cfc478ab28b10ecb301ccc9633 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_image_processing_detr.py @@ -0,0 +1,361 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import pathlib +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision, slow +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DetrImageProcessor + + +class DetrImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_rescale=True, + rescale_factor=1 / 255, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + do_pad=True, + ): + # by setting size["longest_edge"] > max_resolution we're effectively not testing this :p + size = size if size is not None else {"shortest_edge": 18, "longest_edge": 1333} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_pad = do_pad + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_rescale": self.do_rescale, + "rescale_factor": self.rescale_factor, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_pad": self.do_pad, + } + + def get_expected_values(self, image_inputs, batched=False): + """ + This function computes the expected height and width when providing images to DetrImageProcessor, + assuming do_resize is set to True with a scalar size. + """ + if not batched: + image = image_inputs[0] + if isinstance(image, Image.Image): + w, h = image.size + else: + h, w = image.shape[1], image.shape[2] + if w < h: + expected_height = int(self.size["shortest_edge"] * h / w) + expected_width = self.size["shortest_edge"] + elif w > h: + expected_height = self.size["shortest_edge"] + expected_width = int(self.size["shortest_edge"] * w / h) + else: + expected_height = self.size["shortest_edge"] + expected_width = self.size["shortest_edge"] + + else: + expected_values = [] + for image in image_inputs: + expected_height, expected_width = self.get_expected_values([image]) + expected_values.append((expected_height, expected_width)) + expected_height = max(expected_values, key=lambda item: item[0])[0] + expected_width = max(expected_values, key=lambda item: item[1])[1] + + return expected_height, expected_width + + +@require_torch +@require_vision +class DetrImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DetrImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = DetrImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + self.assertTrue(hasattr(image_processing, "rescale_factor")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_pad")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 18, "longest_edge": 1333}) + self.assertEqual(image_processor.do_pad, True) + + image_processor = self.image_processing_class.from_dict( + self.image_processor_dict, size=42, max_size=84, pad_and_return_pixel_mask=False + ) + self.assertEqual(image_processor.size, {"shortest_edge": 42, "longest_edge": 84}) + self.assertEqual(image_processor.do_pad, False) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs) + + self.assertEqual( + encoded_images.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_values(image_inputs, batched=True) + + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def test_equivalence_pad_and_create_pixel_mask(self): + # Initialize image_processings + image_processing_1 = self.image_processing_class(**self.image_processor_dict) + image_processing_2 = self.image_processing_class(do_resize=False, do_normalize=False, do_rescale=False) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test whether the method "pad_and_return_pixel_mask" and calling the image processor return the same tensors + encoded_images_with_method = image_processing_1.pad_and_create_pixel_mask(image_inputs, return_tensors="pt") + encoded_images = image_processing_2(image_inputs, return_tensors="pt") + + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_values"], encoded_images["pixel_values"], atol=1e-4) + ) + self.assertTrue( + torch.allclose(encoded_images_with_method["pixel_mask"], encoded_images["pixel_mask"], atol=1e-4) + ) + + @slow + def test_call_pytorch_with_coco_detection_annotations(self): + # prepare image and target + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"image_id": 39769, "annotations": target} + + # encode them + image_processing = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50") + encoding = image_processing(images=image, annotations=target, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([5887.9600, 11250.2061, 489353.8438, 837122.7500, 147967.5156, 165732.3438]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.5503, 0.2765, 0.0604, 0.2215]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([75, 75, 63, 65, 17, 17]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) + + @slow + def test_call_pytorch_with_coco_panoptic_annotations(self): + # prepare image, target and masks_path + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + with open("./tests/fixtures/tests_samples/COCO/coco_panoptic_annotations.txt", "r") as f: + target = json.loads(f.read()) + + target = {"file_name": "000000039769.png", "image_id": 39769, "segments_info": target} + + masks_path = pathlib.Path("./tests/fixtures/tests_samples/COCO/coco_panoptic") + + # encode them + image_processing = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50-panoptic") + encoding = image_processing(images=image, annotations=target, masks_path=masks_path, return_tensors="pt") + + # verify pixel values + expected_shape = torch.Size([1, 3, 800, 1066]) + self.assertEqual(encoding["pixel_values"].shape, expected_shape) + + expected_slice = torch.tensor([0.2796, 0.3138, 0.3481]) + self.assertTrue(torch.allclose(encoding["pixel_values"][0, 0, 0, :3], expected_slice, atol=1e-4)) + + # verify area + expected_area = torch.tensor([147979.6875, 165527.0469, 484638.5938, 11292.9375, 5879.6562, 7634.1147]) + self.assertTrue(torch.allclose(encoding["labels"][0]["area"], expected_area)) + # verify boxes + expected_boxes_shape = torch.Size([6, 4]) + self.assertEqual(encoding["labels"][0]["boxes"].shape, expected_boxes_shape) + expected_boxes_slice = torch.tensor([0.2625, 0.5437, 0.4688, 0.8625]) + self.assertTrue(torch.allclose(encoding["labels"][0]["boxes"][0], expected_boxes_slice, atol=1e-3)) + # verify image_id + expected_image_id = torch.tensor([39769]) + self.assertTrue(torch.allclose(encoding["labels"][0]["image_id"], expected_image_id)) + # verify is_crowd + expected_is_crowd = torch.tensor([0, 0, 0, 0, 0, 0]) + self.assertTrue(torch.allclose(encoding["labels"][0]["iscrowd"], expected_is_crowd)) + # verify class_labels + expected_class_labels = torch.tensor([17, 17, 63, 75, 75, 93]) + self.assertTrue(torch.allclose(encoding["labels"][0]["class_labels"], expected_class_labels)) + # verify masks + expected_masks_sum = 822873 + self.assertEqual(encoding["labels"][0]["masks"].sum().item(), expected_masks_sum) + # verify orig_size + expected_orig_size = torch.tensor([480, 640]) + self.assertTrue(torch.allclose(encoding["labels"][0]["orig_size"], expected_orig_size)) + # verify size + expected_size = torch.tensor([800, 1066]) + self.assertTrue(torch.allclose(encoding["labels"][0]["size"], expected_size)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_modeling_detr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_modeling_detr.py new file mode 100644 index 0000000000000000000000000000000000000000..31d3db444ca0fbcab430fe603d75741c435f79fe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/detr/test_modeling_detr.py @@ -0,0 +1,658 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DETR model. """ + + +import inspect +import math +import unittest + +from transformers import DetrConfig, is_timm_available, is_vision_available +from transformers.testing_utils import require_timm, require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_timm_available(): + import torch + + from transformers import DetrForObjectDetection, DetrForSegmentation, DetrModel, ResNetConfig + + +if is_vision_available(): + from PIL import Image + + from transformers import DetrFeatureExtractor + + +class DetrModelTester: + def __init__( + self, + parent, + batch_size=8, + is_training=True, + use_labels=True, + hidden_size=256, + num_hidden_layers=2, + num_attention_heads=8, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + num_queries=12, + num_channels=3, + min_size=200, + max_size=200, + n_targets=8, + num_labels=91, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.num_queries = num_queries + self.num_channels = num_channels + self.min_size = min_size + self.max_size = max_size + self.n_targets = n_targets + self.num_labels = num_labels + + # we also set the expected seq length for both encoder and decoder + self.encoder_seq_length = math.ceil(self.min_size / 32) * math.ceil(self.max_size / 32) + self.decoder_seq_length = self.num_queries + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.min_size, self.max_size]) + + pixel_mask = torch.ones([self.batch_size, self.min_size, self.max_size], device=torch_device) + + labels = None + if self.use_labels: + # labels is a list of Dict (each Dict being the labels for a given example in the batch) + labels = [] + for i in range(self.batch_size): + target = {} + target["class_labels"] = torch.randint( + high=self.num_labels, size=(self.n_targets,), device=torch_device + ) + target["boxes"] = torch.rand(self.n_targets, 4, device=torch_device) + target["masks"] = torch.rand(self.n_targets, self.min_size, self.max_size, device=torch_device) + labels.append(target) + + config = self.get_config() + return config, pixel_values, pixel_mask, labels + + def get_config(self): + return DetrConfig( + 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, + num_queries=self.num_queries, + num_labels=self.num_labels, + ) + + def prepare_config_and_inputs_for_common(self): + config, pixel_values, pixel_mask, labels = self.prepare_config_and_inputs() + inputs_dict = {"pixel_values": pixel_values, "pixel_mask": pixel_mask} + return config, inputs_dict + + def create_and_check_detr_model(self, config, pixel_values, pixel_mask, labels): + model = DetrModel(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.decoder_seq_length, self.hidden_size) + ) + + def create_and_check_detr_object_detection_head_model(self, config, pixel_values, pixel_mask, labels): + model = DetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels + 1)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels + 1)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + def create_and_check_no_timm_backbone(self, config, pixel_values, pixel_mask, labels): + config.use_timm_backbone = False + config.backbone_config = ResNetConfig() + model = DetrForObjectDetection(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels + 1)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask, labels=labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_queries, self.num_labels + 1)) + self.parent.assertEqual(result.pred_boxes.shape, (self.batch_size, self.num_queries, 4)) + + +@require_timm +class DetrModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DetrModel, + DetrForObjectDetection, + DetrForSegmentation, + ) + if is_timm_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": DetrModel, + "image-segmentation": DetrForSegmentation, + "object-detection": DetrForObjectDetection, + } + if is_timm_available() + else {} + ) + is_encoder_decoder = True + test_torchscript = False + test_pruning = False + test_head_masking = False + test_missing_keys = False + + # special case for head models + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ in ["DetrForObjectDetection", "DetrForSegmentation"]: + labels = [] + for i in range(self.model_tester.batch_size): + target = {} + target["class_labels"] = torch.ones( + size=(self.model_tester.n_targets,), device=torch_device, dtype=torch.long + ) + target["boxes"] = torch.ones( + self.model_tester.n_targets, 4, device=torch_device, dtype=torch.float + ) + target["masks"] = torch.ones( + self.model_tester.n_targets, + self.model_tester.min_size, + self.model_tester.max_size, + device=torch_device, + dtype=torch.float, + ) + labels.append(target) + inputs_dict["labels"] = labels + + return inputs_dict + + def setUp(self): + self.model_tester = DetrModelTester(self) + self.config_tester = ConfigTester(self, config_class=DetrConfig, has_text_modality=False) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_detr_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_detr_model(*config_and_inputs) + + def test_detr_object_detection_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_detr_object_detection_head_model(*config_and_inputs) + + def test_detr_no_timm_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_no_timm_backbone(*config_and_inputs) + + # TODO: check if this works again for PyTorch 2.x.y + @unittest.skip(reason="Got `CUDA error: misaligned address` with PyTorch 2.0.0.") + def test_multi_gpu_data_parallel_forward(self): + pass + + @unittest.skip(reason="DETR does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="DETR does not have a get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="DETR is not a generative model") + def test_generate_without_input_ids(self): + pass + + @unittest.skip(reason="DETR does not use token embeddings") + def test_resize_tokens_embeddings(self): + pass + + @slow + def test_model_outputs_equivalence(self): + # TODO Niels: fix me! + pass + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + decoder_seq_length = self.model_tester.decoder_seq_length + encoder_seq_length = self.model_tester.encoder_seq_length + decoder_key_length = self.model_tester.decoder_seq_length + encoder_key_length = self.model_tester.encoder_seq_length + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Object Detection model returns pred_logits and pred_boxes + if model_class.__name__ == "DetrForObjectDetection": + correct_outlen += 2 + # Panoptic Segmentation model returns pred_logits, pred_boxes, pred_masks + if model_class.__name__ == "DetrForSegmentation": + correct_outlen += 3 + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + def test_retain_grad_hidden_states_attentions(self): + # removed retain_grad and grad on decoder_hidden_states, as queries don't require grad + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_attentions = outputs.encoder_attentions[0] + encoder_hidden_states.retain_grad() + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = ["pixel_values", "pixel_mask"] + expected_arg_names.extend( + ["head_mask", "decoder_head_mask", "encoder_outputs"] + if "head_mask" and "decoder_head_mask" in arg_names + else [] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["pixel_values", "pixel_mask"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_different_timm_backbone(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # let's pick a random timm backbone + config.backbone = "tf_mobilenetv3_small_075" + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if model_class.__name__ == "DetrForObjectDetection": + expected_shape = ( + self.model_tester.batch_size, + self.model_tester.num_queries, + self.model_tester.num_labels + 1, + ) + self.assertEqual(outputs.logits.shape, expected_shape) + + self.assertTrue(outputs) + + def test_greyscale_images(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # use greyscale pixel values + inputs_dict["pixel_values"] = floats_tensor( + [self.model_tester.batch_size, 1, self.model_tester.min_size, self.model_tester.max_size] + ) + + # let's set num_channels to 1 + config.num_channels = 1 + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + self.assertTrue(outputs) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + configs_no_init.init_xavier_std = 1e9 + + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + if "bbox_attention" in name and "bias" not in name: + self.assertLess( + 100000, + abs(param.data.max().item()), + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +TOLERANCE = 1e-4 + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_timm +@require_vision +@slow +class DetrModelIntegrationTestsTimmBackbone(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return DetrFeatureExtractor.from_pretrained("facebook/detr-resnet-50") if is_vision_available() else None + + def test_inference_no_head(self): + model = DetrModel.from_pretrained("facebook/detr-resnet-50").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**encoding) + + expected_shape = torch.Size((1, 100, 256)) + assert outputs.last_hidden_state.shape == expected_shape + expected_slice = torch.tensor( + [[0.0616, -0.5146, -0.4032], [-0.7629, -0.4934, -1.7153], [-0.4768, -0.6403, -0.7826]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) + + def test_inference_object_detection_head(self): + model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + pixel_values = encoding["pixel_values"].to(torch_device) + pixel_mask = encoding["pixel_mask"].to(torch_device) + + with torch.no_grad(): + outputs = model(pixel_values, pixel_mask) + + # verify outputs + expected_shape_logits = torch.Size((1, model.config.num_queries, model.config.num_labels + 1)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + expected_slice_logits = torch.tensor( + [[-19.1194, -0.0893, -11.0154], [-17.3640, -1.8035, -14.0219], [-20.0461, -0.5837, -11.1060]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_slice_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, model.config.num_queries, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + expected_slice_boxes = torch.tensor( + [[0.4433, 0.5302, 0.8853], [0.5494, 0.2517, 0.0529], [0.4998, 0.5360, 0.9956]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_slice_boxes, atol=1e-4)) + + # verify postprocessing + results = feature_extractor.post_process_object_detection( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + expected_scores = torch.tensor([0.9982, 0.9960, 0.9955, 0.9988, 0.9987]).to(torch_device) + expected_labels = [75, 75, 63, 17, 17] + expected_slice_boxes = torch.tensor([40.1633, 70.8115, 175.5471, 117.9841]).to(torch_device) + + self.assertEqual(len(results["scores"]), 5) + self.assertTrue(torch.allclose(results["scores"], expected_scores, atol=1e-4)) + self.assertSequenceEqual(results["labels"].tolist(), expected_labels) + self.assertTrue(torch.allclose(results["boxes"][0, :], expected_slice_boxes)) + + def test_inference_panoptic_segmentation_head(self): + model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50-panoptic").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + pixel_values = encoding["pixel_values"].to(torch_device) + pixel_mask = encoding["pixel_mask"].to(torch_device) + + with torch.no_grad(): + outputs = model(pixel_values, pixel_mask) + + # verify outputs + expected_shape_logits = torch.Size((1, model.config.num_queries, model.config.num_labels + 1)) + self.assertEqual(outputs.logits.shape, expected_shape_logits) + expected_slice_logits = torch.tensor( + [[-18.1565, -1.7568, -13.5029], [-16.8888, -1.4138, -14.1028], [-17.5709, -2.5080, -11.8654]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_slice_logits, atol=1e-4)) + + expected_shape_boxes = torch.Size((1, model.config.num_queries, 4)) + self.assertEqual(outputs.pred_boxes.shape, expected_shape_boxes) + expected_slice_boxes = torch.tensor( + [[0.5344, 0.1789, 0.9285], [0.4420, 0.0572, 0.0875], [0.6630, 0.6887, 0.1017]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.pred_boxes[0, :3, :3], expected_slice_boxes, atol=1e-4)) + + expected_shape_masks = torch.Size((1, model.config.num_queries, 200, 267)) + self.assertEqual(outputs.pred_masks.shape, expected_shape_masks) + expected_slice_masks = torch.tensor( + [[-7.7558, -10.8788, -11.9797], [-11.8881, -16.4329, -17.7451], [-14.7316, -19.7383, -20.3004]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.pred_masks[0, 0, :3, :3], expected_slice_masks, atol=1e-3)) + + # verify postprocessing + results = feature_extractor.post_process_panoptic_segmentation( + outputs, threshold=0.3, target_sizes=[image.size[::-1]] + )[0] + + expected_shape = torch.Size([480, 640]) + expected_slice_segmentation = torch.tensor([[4, 4, 4], [4, 4, 4], [4, 4, 4]], dtype=torch.int32).to( + torch_device + ) + expected_number_of_segments = 5 + expected_first_segment = {"id": 1, "label_id": 17, "was_fused": False, "score": 0.994096} + + number_of_unique_segments = len(torch.unique(results["segmentation"])) + self.assertTrue( + number_of_unique_segments, expected_number_of_segments + 1 + ) # we add 1 for the background class + self.assertTrue(results["segmentation"].shape, expected_shape) + self.assertTrue(torch.allclose(results["segmentation"][:3, :3], expected_slice_segmentation, atol=1e-4)) + self.assertTrue(len(results["segments_info"]), expected_number_of_segments) + self.assertDictEqual(results["segments_info"][0], expected_first_segment) + + +@require_vision +@require_torch +@slow +class DetrModelIntegrationTests(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + DetrFeatureExtractor.from_pretrained("facebook/detr-resnet-50", revision="no_timm") + if is_vision_available() + else None + ) + + def test_inference_no_head(self): + model = DetrModel.from_pretrained("facebook/detr-resnet-50", revision="no_timm").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + encoding = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**encoding) + + expected_shape = torch.Size((1, 100, 256)) + assert outputs.last_hidden_state.shape == expected_shape + expected_slice = torch.tensor( + [[0.0616, -0.5146, -0.4032], [-0.7629, -0.4934, -1.7153], [-0.4768, -0.6403, -0.7826]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dinat/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dinat/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dinat/test_modeling_dinat.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dinat/test_modeling_dinat.py new file mode 100644 index 0000000000000000000000000000000000000000..c08abf3d121d40fb5f1ea39cddc81b3c450c913b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dinat/test_modeling_dinat.py @@ -0,0 +1,399 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Dinat model. """ + +import collections +import inspect +import unittest + +from transformers import DinatConfig +from transformers.testing_utils import require_natten, require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_backbone_common import BackboneTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import DinatBackbone, DinatForImageClassification, DinatModel + from transformers.models.dinat.modeling_dinat import DINAT_PRETRAINED_MODEL_ARCHIVE_LIST + +if is_vision_available(): + from PIL import Image + + from transformers import AutoImageProcessor + + +class DinatModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=64, + patch_size=4, + num_channels=3, + embed_dim=16, + depths=[1, 2, 1], + num_heads=[2, 4, 8], + kernel_size=3, + dilations=[[3], [1, 2], [1]], + mlp_ratio=2.0, + qkv_bias=True, + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + drop_path_rate=0.1, + hidden_act="gelu", + patch_norm=True, + initializer_range=0.02, + layer_norm_eps=1e-5, + is_training=True, + scope=None, + use_labels=True, + num_labels=10, + out_features=["stage1", "stage2"], + out_indices=[1, 2], + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.embed_dim = embed_dim + self.depths = depths + self.num_heads = num_heads + self.kernel_size = kernel_size + self.dilations = dilations + self.mlp_ratio = mlp_ratio + self.qkv_bias = qkv_bias + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.drop_path_rate = drop_path_rate + self.hidden_act = hidden_act + self.patch_norm = patch_norm + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.is_training = is_training + self.scope = scope + self.use_labels = use_labels + self.num_labels = num_labels + self.out_features = out_features + self.out_indices = out_indices + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return DinatConfig( + num_labels=self.num_labels, + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + embed_dim=self.embed_dim, + depths=self.depths, + num_heads=self.num_heads, + kernel_size=self.kernel_size, + dilations=self.dilations, + mlp_ratio=self.mlp_ratio, + qkv_bias=self.qkv_bias, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + drop_path_rate=self.drop_path_rate, + hidden_act=self.hidden_act, + patch_norm=self.patch_norm, + layer_norm_eps=self.layer_norm_eps, + initializer_range=self.initializer_range, + out_features=self.out_features, + out_indices=self.out_indices, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = DinatModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + expected_height = expected_width = (config.image_size // config.patch_size) // (2 ** (len(config.depths) - 1)) + expected_dim = int(config.embed_dim * 2 ** (len(config.depths) - 1)) + + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, expected_height, expected_width, expected_dim) + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + model = DinatForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + # test greyscale images + config.num_channels = 1 + model = DinatForImageClassification(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_backbone(self, config, pixel_values, labels): + model = DinatBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify hidden states + self.parent.assertEqual(len(result.feature_maps), len(config.out_features)) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, model.channels[0], 16, 16]) + + # verify channels + self.parent.assertEqual(len(model.channels), len(config.out_features)) + + # verify backbone works with out_features=None + config.out_features = None + model = DinatBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify feature maps + self.parent.assertEqual(len(result.feature_maps), 1) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, model.channels[-1], 4, 4]) + + # verify channels + self.parent.assertEqual(len(model.channels), 1) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_natten +@require_torch +class DinatModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DinatModel, + DinatForImageClassification, + DinatBackbone, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + {"feature-extraction": DinatModel, "image-classification": DinatForImageClassification} + if is_torch_available() + else {} + ) + fx_compatible = False + + test_torchscript = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = DinatModelTester(self) + self.config_tester = ConfigTester(self, config_class=DinatConfig, embed_dim=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + def test_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_backbone(*config_and_inputs) + + @unittest.skip(reason="Dinat does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Dinat does not use feedforward chunking") + def test_feed_forward_chunking(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_attention_outputs(self): + self.skipTest("Dinat's attention operation is handled entirely by NATTEN.") + + def check_hidden_states_output(self, inputs_dict, config, model_class, image_size): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", len(self.model_tester.depths) + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # Dinat has a different seq_length + patch_size = ( + config.patch_size + if isinstance(config.patch_size, collections.abc.Iterable) + else (config.patch_size, config.patch_size) + ) + + height = image_size[0] // patch_size[0] + width = image_size[1] // patch_size[1] + + self.assertListEqual( + list(hidden_states[0].shape[-3:]), + [height, width, self.model_tester.embed_dim], + ) + + if model_class.__name__ != "DinatBackbone": + reshaped_hidden_states = outputs.reshaped_hidden_states + self.assertEqual(len(reshaped_hidden_states), expected_num_layers) + + batch_size, num_channels, height, width = reshaped_hidden_states[0].shape + reshaped_hidden_states = ( + reshaped_hidden_states[0].view(batch_size, num_channels, height, width).permute(0, 2, 3, 1) + ) + self.assertListEqual( + list(reshaped_hidden_states.shape[-3:]), + [height, width, self.model_tester.embed_dim], + ) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + @slow + def test_model_from_pretrained(self): + for model_name in DINAT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DinatModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if "embeddings" not in name and param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +@require_natten +@require_vision +@require_torch +class DinatModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return AutoImageProcessor.from_pretrained("shi-labs/dinat-mini-in1k-224") if is_vision_available() else None + + @slow + def test_inference_image_classification_head(self): + model = DinatForImageClassification.from_pretrained("shi-labs/dinat-mini-in1k-224").to(torch_device) + feature_extractor = self.default_feature_extractor + + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + expected_slice = torch.tensor([-0.1545, -0.7667, 0.4642]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) + + +@require_torch +@require_natten +class DinatBackboneTest(unittest.TestCase, BackboneTesterMixin): + all_model_classes = (DinatBackbone,) if is_torch_available() else () + config_class = DinatConfig + + def setUp(self): + self.model_tester = DinatModelTester(self) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..9d17a1c4415d481b379273372e23c465c549bb01 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_distilbert.py @@ -0,0 +1,304 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import tempfile +import unittest + +from transformers import DistilBertConfig, is_torch_available +from transformers.testing_utils import require_torch, require_torch_gpu, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + DistilBertForMaskedLM, + DistilBertForMultipleChoice, + DistilBertForQuestionAnswering, + DistilBertForSequenceClassification, + DistilBertForTokenClassification, + DistilBertModel, + ) + + +class DistilBertModelTester(object): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return DistilBertConfig( + vocab_size=self.vocab_size, + dim=self.hidden_size, + n_layers=self.num_hidden_layers, + n_heads=self.num_attention_heads, + hidden_dim=self.intermediate_size, + hidden_act=self.hidden_act, + dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + def create_and_check_distilbert_model( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DistilBertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_distilbert_for_masked_lm( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DistilBertForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_distilbert_for_question_answering( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DistilBertForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, attention_mask=input_mask, start_positions=sequence_labels, end_positions=sequence_labels + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_distilbert_for_sequence_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DistilBertForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_distilbert_for_token_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = DistilBertForTokenClassification(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_distilbert_for_multiple_choice( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = DistilBertForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + (config, input_ids, input_mask, sequence_labels, token_labels, choice_labels) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class DistilBertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DistilBertModel, + DistilBertForMaskedLM, + DistilBertForMultipleChoice, + DistilBertForQuestionAnswering, + DistilBertForSequenceClassification, + DistilBertForTokenClassification, + ) + if is_torch_available() + else None + ) + pipeline_model_mapping = ( + { + "feature-extraction": DistilBertModel, + "fill-mask": DistilBertForMaskedLM, + "question-answering": DistilBertForQuestionAnswering, + "text-classification": DistilBertForSequenceClassification, + "token-classification": DistilBertForTokenClassification, + "zero-shot": DistilBertForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + test_pruning = True + test_resize_embeddings = True + test_resize_position_embeddings = True + + def setUp(self): + self.model_tester = DistilBertModelTester(self) + self.config_tester = ConfigTester(self, config_class=DistilBertConfig, dim=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_distilbert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_multiple_choice(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DistilBertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + @require_torch_gpu + def test_torchscript_device_change(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # BertForMultipleChoice behaves incorrectly in JIT environments. + if model_class == DistilBertForMultipleChoice: + return + + config.torchscript = True + model = model_class(config=config) + + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + traced_model = torch.jit.trace( + model, (inputs_dict["input_ids"].to("cpu"), inputs_dict["attention_mask"].to("cpu")) + ) + + with tempfile.TemporaryDirectory() as tmp: + torch.jit.save(traced_model, os.path.join(tmp, "traced_model.pt")) + loaded = torch.jit.load(os.path.join(tmp, "traced_model.pt"), map_location=torch_device) + loaded(inputs_dict["input_ids"].to(torch_device), inputs_dict["attention_mask"].to(torch_device)) + + +@require_torch +class DistilBertModelIntergrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = DistilBertModel.from_pretrained("distilbert-base-uncased") + input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) + attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + with torch.no_grad(): + output = model(input_ids, attention_mask=attention_mask)[0] + expected_shape = torch.Size((1, 11, 768)) + self.assertEqual(output.shape, expected_shape) + expected_slice = torch.tensor( + [[[-0.1639, 0.3299, 0.1648], [-0.1746, 0.3289, 0.1710], [-0.1884, 0.3357, 0.1810]]] + ) + + self.assertTrue(torch.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_flax_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_flax_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..f4481a6e4a077ac10f94636d6dcd8556d4a8b53a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_flax_distilbert.py @@ -0,0 +1,152 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +import numpy as np + +from transformers import DistilBertConfig, is_flax_available +from transformers.testing_utils import require_flax, slow + +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask + + +if is_flax_available(): + import jax.numpy as jnp + + from transformers.models.distilbert.modeling_flax_distilbert import ( + FlaxDistilBertForMaskedLM, + FlaxDistilBertForMultipleChoice, + FlaxDistilBertForQuestionAnswering, + FlaxDistilBertForSequenceClassification, + FlaxDistilBertForTokenClassification, + FlaxDistilBertModel, + ) + + +class FlaxDistilBertModelTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_attention_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_choices=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_choices = num_choices + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = DistilBertConfig( + vocab_size=self.vocab_size, + dim=self.hidden_size, + n_layers=self.num_hidden_layers, + n_heads=self.num_attention_heads, + hidden_dim=self.intermediate_size, + hidden_act=self.hidden_act, + dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + tie_weights_=True, + ) + + return config, input_ids, attention_mask + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": attention_mask} + return config, inputs_dict + + +@require_flax +class FlaxDistilBertModelTest(FlaxModelTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + FlaxDistilBertModel, + FlaxDistilBertForMaskedLM, + FlaxDistilBertForMultipleChoice, + FlaxDistilBertForQuestionAnswering, + FlaxDistilBertForSequenceClassification, + FlaxDistilBertForTokenClassification, + FlaxDistilBertForQuestionAnswering, + ) + if is_flax_available() + else () + ) + + def setUp(self): + self.model_tester = FlaxDistilBertModelTester(self) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("distilbert-base-uncased") + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) + + +@require_flax +class FlaxDistilBertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = FlaxDistilBertModel.from_pretrained("distilbert-base-uncased") + input_ids = np.array([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) + attention_mask = np.array([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + output = model(input_ids, attention_mask=attention_mask)[0] + expected_shape = (1, 11, 768) + self.assertEqual(output.shape, expected_shape) + expected_slice = np.array([[[-0.1639, 0.3299, 0.1648], [-0.1746, 0.3289, 0.1710], [-0.1884, 0.3357, 0.1810]]]) + + self.assertTrue(jnp.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_tf_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_tf_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..1f4f3c2b4697167a6c48c9d39fcca0882b4dee85 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_modeling_tf_distilbert.py @@ -0,0 +1,259 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import DistilBertConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.distilbert.modeling_tf_distilbert import ( + TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + TFDistilBertForMaskedLM, + TFDistilBertForMultipleChoice, + TFDistilBertForQuestionAnswering, + TFDistilBertForSequenceClassification, + TFDistilBertForTokenClassification, + TFDistilBertModel, + ) + + +class TFDistilBertModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = False + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = DistilBertConfig( + vocab_size=self.vocab_size, + dim=self.hidden_size, + n_layers=self.num_hidden_layers, + n_heads=self.num_attention_heads, + hidden_dim=self.intermediate_size, + hidden_act=self.hidden_act, + dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_distilbert_model( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDistilBertModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + + result = model(inputs) + + inputs = [input_ids, input_mask] + + result = model(inputs) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_distilbert_for_masked_lm( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDistilBertForMaskedLM(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_distilbert_for_question_answering( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDistilBertForQuestionAnswering(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + } + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_distilbert_for_sequence_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDistilBertForSequenceClassification(config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_distilbert_for_multiple_choice( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = TFDistilBertForMultipleChoice(config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_distilbert_for_token_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFDistilBertForTokenClassification(config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + (config, input_ids, input_mask, sequence_labels, token_labels, choice_labels) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFDistilBertModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFDistilBertModel, + TFDistilBertForMaskedLM, + TFDistilBertForQuestionAnswering, + TFDistilBertForSequenceClassification, + TFDistilBertForTokenClassification, + TFDistilBertForMultipleChoice, + ) + if is_tf_available() + else None + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFDistilBertModel, + "fill-mask": TFDistilBertForMaskedLM, + "question-answering": TFDistilBertForQuestionAnswering, + "text-classification": TFDistilBertForSequenceClassification, + "token-classification": TFDistilBertForTokenClassification, + "zero-shot": TFDistilBertForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFDistilBertModelTester(self) + self.config_tester = ConfigTester(self, config_class=DistilBertConfig, dim=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_distilbert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_sequence_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_multiple_choice(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_distilbert_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in list(TF_DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]): + model = TFDistilBertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_tf +class TFDistilBertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TFDistilBertModel.from_pretrained("distilbert-base-uncased") + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + expected_shape = [1, 6, 768] + self.assertEqual(output.shape, expected_shape) + + expected_slice = tf.constant( + [ + [ + [0.19261885, -0.13732955, 0.4119799], + [0.22150156, -0.07422661, 0.39037204], + [0.22756018, -0.0896414, 0.3701467], + ] + ] + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_tokenization_distilbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_tokenization_distilbert.py new file mode 100644 index 0000000000000000000000000000000000000000..09422395720988bceb4a5963a4820c4ce319420e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/distilbert/test_tokenization_distilbert.py @@ -0,0 +1,42 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from transformers import DistilBertTokenizer, DistilBertTokenizerFast +from transformers.testing_utils import require_tokenizers, slow + +from ..bert.test_tokenization_bert import BertTokenizationTest + + +@require_tokenizers +class DistilBertTokenizationTest(BertTokenizationTest): + tokenizer_class = DistilBertTokenizer + rust_tokenizer_class = DistilBertTokenizerFast + test_rust_tokenizer = True + + @slow + def test_sequence_builders(self): + tokenizer = DistilBertTokenizer.from_pretrained("distilbert-base-uncased") + + text = tokenizer.encode("sequence builders", add_special_tokens=False) + text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + assert encoded_pair == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + text_2 + [ + tokenizer.sep_token_id + ] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dit/test_modeling_dit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dit/test_modeling_dit.py new file mode 100644 index 0000000000000000000000000000000000000000..e7e1474f17cbb80562b19a37c993063690f21f79 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dit/test_modeling_dit.py @@ -0,0 +1,61 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import is_torch_available, is_vision_available +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + + +if is_torch_available(): + import torch + + from transformers import AutoModelForImageClassification + +if is_vision_available(): + from transformers import AutoFeatureExtractor + + +@require_torch +@require_vision +class DiTIntegrationTest(unittest.TestCase): + @slow + def test_for_image_classification(self): + feature_extractor = AutoFeatureExtractor.from_pretrained("microsoft/dit-base-finetuned-rvlcdip") + model = AutoModelForImageClassification.from_pretrained("microsoft/dit-base-finetuned-rvlcdip") + model.to(torch_device) + + from datasets import load_dataset + + dataset = load_dataset("nielsr/rvlcdip-demo") + + image = dataset["train"][0]["image"].convert("RGB") + + inputs = feature_extractor(image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + logits = outputs.logits + + expected_shape = torch.Size((1, 16)) + self.assertEqual(logits.shape, expected_shape) + + expected_slice = torch.tensor( + [-0.4158, -0.4092, -0.4347], + device=torch_device, + dtype=torch.float, + ) + self.assertTrue(torch.allclose(logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_image_processing_donut.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_image_processing_donut.py new file mode 100644 index 0000000000000000000000000000000000000000..bd992626494aa6ef4673178b2ebce0e87f4e0e1c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_image_processing_donut.py @@ -0,0 +1,216 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import is_flaky, require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DonutImageProcessor + + +class DonutImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_thumbnail=True, + do_align_axis=False, + do_pad=True, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size if size is not None else {"height": 18, "width": 20} + self.do_thumbnail = do_thumbnail + self.do_align_axis = do_align_axis + self.do_pad = do_pad + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size": self.size, + "do_thumbnail": self.do_thumbnail, + "do_align_long_axis": self.do_align_axis, + "do_pad": self.do_pad, + "do_normalize": self.do_normalize, + "image_mean": self.image_mean, + "image_std": self.image_std, + } + + +@require_torch +@require_vision +class DonutImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DonutImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = DonutImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_thumbnail")) + self.assertTrue(hasattr(image_processing, "do_align_long_axis")) + self.assertTrue(hasattr(image_processing, "do_pad")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 20}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + # Previous config had dimensions in (width, height) order + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=(42, 84)) + self.assertEqual(image_processor.size, {"height": 84, "width": 42}) + + def test_batch_feature(self): + pass + + @is_flaky() + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + @is_flaky() + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + @is_flaky() + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_modeling_donut_swin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_modeling_donut_swin.py new file mode 100644 index 0000000000000000000000000000000000000000..2a0d9f5e17cbdb013bfcd995797effac296ae045 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_modeling_donut_swin.py @@ -0,0 +1,366 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Donut Swin model. """ + +import collections +import inspect +import unittest + +from transformers import DonutSwinConfig +from transformers.testing_utils import require_torch, slow, torch_device +from transformers.utils import is_torch_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import DonutSwinModel + from transformers.models.donut.modeling_donut_swin import DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST + + +class DonutSwinModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + patch_size=2, + num_channels=3, + embed_dim=16, + depths=[1, 2, 1], + num_heads=[2, 2, 4], + window_size=2, + mlp_ratio=2.0, + qkv_bias=True, + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + drop_path_rate=0.1, + hidden_act="gelu", + use_absolute_embeddings=False, + patch_norm=True, + initializer_range=0.02, + layer_norm_eps=1e-5, + is_training=True, + scope=None, + use_labels=True, + type_sequence_label_size=10, + encoder_stride=8, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.embed_dim = embed_dim + self.depths = depths + self.num_heads = num_heads + self.window_size = window_size + self.mlp_ratio = mlp_ratio + self.qkv_bias = qkv_bias + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.drop_path_rate = drop_path_rate + self.hidden_act = hidden_act + self.use_absolute_embeddings = use_absolute_embeddings + self.patch_norm = patch_norm + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.is_training = is_training + self.scope = scope + self.use_labels = use_labels + self.type_sequence_label_size = type_sequence_label_size + self.encoder_stride = encoder_stride + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return DonutSwinConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + embed_dim=self.embed_dim, + depths=self.depths, + num_heads=self.num_heads, + window_size=self.window_size, + mlp_ratio=self.mlp_ratio, + qkv_bias=self.qkv_bias, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + drop_path_rate=self.drop_path_rate, + hidden_act=self.hidden_act, + use_absolute_embeddings=self.use_absolute_embeddings, + path_norm=self.patch_norm, + layer_norm_eps=self.layer_norm_eps, + initializer_range=self.initializer_range, + encoder_stride=self.encoder_stride, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = DonutSwinModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + expected_seq_len = ((config.image_size // config.patch_size) ** 2) // (4 ** (len(config.depths) - 1)) + expected_dim = int(config.embed_dim * 2 ** (len(config.depths) - 1)) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, expected_seq_len, expected_dim)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + pixel_values, + labels, + ) = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class DonutSwinModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (DonutSwinModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": DonutSwinModel} if is_torch_available() else {} + fx_compatible = True + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = DonutSwinModelTester(self) + self.config_tester = ConfigTester(self, config_class=DonutSwinConfig, embed_dim=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_inputs_embeds(self): + # DonutSwin does not use inputs_embeds + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + expected_num_attentions = len(self.model_tester.depths) + self.assertEqual(len(attentions), expected_num_attentions) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + window_size_squared = config.window_size**2 + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), expected_num_attentions) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_heads[0], window_size_squared, window_size_squared], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + else: + # also another +1 for reshaped_hidden_states + added_hidden_states = 2 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), expected_num_attentions) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_heads[0], window_size_squared, window_size_squared], + ) + + def check_hidden_states_output(self, inputs_dict, config, model_class, image_size): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", len(self.model_tester.depths) + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # DonutSwin has a different seq_length + patch_size = ( + config.patch_size + if isinstance(config.patch_size, collections.abc.Iterable) + else (config.patch_size, config.patch_size) + ) + + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [num_patches, self.model_tester.embed_dim], + ) + + reshaped_hidden_states = outputs.reshaped_hidden_states + self.assertEqual(len(reshaped_hidden_states), expected_num_layers) + + batch_size, num_channels, height, width = reshaped_hidden_states[0].shape + reshaped_hidden_states = ( + reshaped_hidden_states[0].view(batch_size, num_channels, height * width).permute(0, 2, 1) + ) + self.assertListEqual( + list(reshaped_hidden_states.shape[-2:]), + [num_patches, self.model_tester.embed_dim], + ) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + def test_hidden_states_output_with_padding(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.patch_size = 3 + + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + patch_size = ( + config.patch_size + if isinstance(config.patch_size, collections.abc.Iterable) + else (config.patch_size, config.patch_size) + ) + + padded_height = image_size[0] + patch_size[0] - (image_size[0] % patch_size[0]) + padded_width = image_size[1] + patch_size[1] - (image_size[1] % patch_size[1]) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + self.check_hidden_states_output(inputs_dict, config, model_class, (padded_height, padded_width)) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + self.check_hidden_states_output(inputs_dict, config, model_class, (padded_height, padded_width)) + + @slow + def test_model_from_pretrained(self): + for model_name in DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DonutSwinModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if "embeddings" not in name and param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_processing_donut.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_processing_donut.py new file mode 100644 index 0000000000000000000000000000000000000000..cad0e37bc5195313d59ca5b361888b5e93c10dfa --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/donut/test_processing_donut.py @@ -0,0 +1,48 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import DonutProcessor + + +DONUT_PRETRAINED_MODEL_NAME = "naver-clova-ix/donut-base" + + +class DonutProcessorTest(unittest.TestCase): + def setUp(self): + self.processor = DonutProcessor.from_pretrained(DONUT_PRETRAINED_MODEL_NAME) + + def test_token2json(self): + expected_json = { + "name": "John Doe", + "age": "99", + "city": "Atlanta", + "state": "GA", + "zip": "30301", + "phone": "123-4567", + "nicknames": [{"nickname": "Johnny"}, {"nickname": "JD"}], + } + + sequence = ( + "John Doe99Atlanta" + "GA30301123-4567" + "Johnny" + "JD" + ) + actual_json = self.processor.token2json(sequence) + + self.assertDictEqual(actual_json, expected_json) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..cd4f430dedf750ab36a713f16f1569aceebf8c16 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_dpr.py @@ -0,0 +1,312 @@ +# coding=utf-8 +# Copyright 2020 Huggingface +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +from transformers import DPRConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import DPRContextEncoder, DPRQuestionEncoder, DPRReader, DPRReaderTokenizer + from transformers.models.dpr.modeling_dpr import ( + DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST, + ) + + +class DPRModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=False, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + projection_dim=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.projection_dim = projection_dim + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return DPRConfig( + projection_dim=self.projection_dim, + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + def create_and_check_context_encoder( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DPRContextEncoder(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.projection_dim or self.hidden_size)) + + def create_and_check_question_encoder( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DPRQuestionEncoder(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.projection_dim or self.hidden_size)) + + def create_and_check_reader( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = DPRReader(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + ) + + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.relevance_logits.shape, (self.batch_size,)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids} + return config, inputs_dict + + +@require_torch +class DPRModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + DPRContextEncoder, + DPRQuestionEncoder, + DPRReader, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = {"feature-extraction": DPRQuestionEncoder} if is_torch_available() else {} + + test_resize_embeddings = False + test_missing_keys = False # why? + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = DPRModelTester(self) + self.config_tester = ConfigTester(self, config_class=DPRConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_context_encoder_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_context_encoder(*config_and_inputs) + + def test_question_encoder_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_question_encoder(*config_and_inputs) + + def test_reader_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_reader(*config_and_inputs) + + def test_init_changed_config(self): + config = self.model_tester.prepare_config_and_inputs()[0] + + model = DPRQuestionEncoder(config=config) + model.to(torch_device) + model.eval() + + with tempfile.TemporaryDirectory() as tmp_dirname: + model.save_pretrained(tmp_dirname) + model = DPRQuestionEncoder.from_pretrained(tmp_dirname, projection_dim=512) + + self.assertIsNotNone(model) + + @slow + def test_model_from_pretrained(self): + for model_name in DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DPRContextEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DPRContextEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DPRQuestionEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DPRReader.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class DPRModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head(self): + model = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base", return_dict=False) + model.to(torch_device) + + input_ids = torch.tensor( + [[101, 7592, 1010, 2003, 2026, 3899, 10140, 1029, 102]], dtype=torch.long, device=torch_device + ) # [CLS] hello, is my dog cute? [SEP] + output = model(input_ids)[0] # embedding shape = (1, 768) + # compare the actual values for a slice. + expected_slice = torch.tensor( + [ + [ + 0.03236253, + 0.12753335, + 0.16818509, + 0.00279786, + 0.3896933, + 0.24264945, + 0.2178971, + -0.02335227, + -0.08481959, + -0.14324117, + ] + ], + dtype=torch.float, + device=torch_device, + ) + self.assertTrue(torch.allclose(output[:, :10], expected_slice, atol=1e-4)) + + @slow + def test_reader_inference(self): + tokenizer = DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base") + model = DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base") + model.to(torch_device) + + encoded_inputs = tokenizer( + questions="What is love ?", + titles="Haddaway", + texts="What Is Love is a song recorded by the artist Haddaway", + padding=True, + return_tensors="pt", + ) + encoded_inputs.to(torch_device) + + outputs = model(**encoded_inputs) + + # compare the actual values for a slice. + expected_start_logits = torch.tensor( + [[-10.3005, -10.7765, -11.4872, -11.6841, -11.9312, -10.3002, -9.8544, -11.7378, -12.0821, -10.2975]], + dtype=torch.float, + device=torch_device, + ) + + expected_end_logits = torch.tensor( + [[-11.0684, -11.7041, -11.5397, -10.3465, -10.8791, -6.8443, -11.9959, -11.0364, -10.0096, -6.8405]], + dtype=torch.float, + device=torch_device, + ) + self.assertTrue(torch.allclose(outputs.start_logits[:, :10], expected_start_logits, atol=1e-4)) + self.assertTrue(torch.allclose(outputs.end_logits[:, :10], expected_end_logits, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_tf_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_tf_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..64dea041b53f38469b2f99d2d25fb54c0f60dbba --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_modeling_tf_dpr.py @@ -0,0 +1,258 @@ +# coding=utf-8 +# Copyright 2020 Huggingface +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import numpy + import tensorflow as tf + + from transformers import ( + TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST, + TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST, + BertConfig, + DPRConfig, + TFDPRContextEncoder, + TFDPRQuestionEncoder, + TFDPRReader, + ) + + +class TFDPRModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + projection_dim=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.projection_dim = projection_dim + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + # follow test_modeling_tf_ctrl.py + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = BertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + config = DPRConfig(projection_dim=self.projection_dim, **config.to_dict()) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_dpr_context_encoder( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDPRContextEncoder(config=config) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.projection_dim or self.hidden_size)) + + def create_and_check_dpr_question_encoder( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDPRQuestionEncoder(config=config) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.projection_dim or self.hidden_size)) + + def create_and_check_dpr_reader( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFDPRReader(config=config) + result = model(input_ids, attention_mask=input_mask) + + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.relevance_logits.shape, (self.batch_size,)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids} + return config, inputs_dict + + +@require_tf +class TFDPRModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFDPRContextEncoder, + TFDPRQuestionEncoder, + TFDPRReader, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = {"feature-extraction": TFDPRQuestionEncoder} if is_tf_available() else {} + + test_resize_embeddings = False + test_missing_keys = False + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFDPRModelTester(self) + self.config_tester = ConfigTester(self, config_class=DPRConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_dpr_context_encoder_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_dpr_context_encoder(*config_and_inputs) + + def test_dpr_question_encoder_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_dpr_question_encoder(*config_and_inputs) + + def test_dpr_reader_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_dpr_reader(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFDPRContextEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFDPRContextEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFDPRQuestionEncoder.from_pretrained(model_name) + self.assertIsNotNone(model) + + for model_name in TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFDPRReader.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_tf +class TFDPRModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head(self): + model = TFDPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base") + + input_ids = tf.constant( + [[101, 7592, 1010, 2003, 2026, 3899, 10140, 1029, 102]] + ) # [CLS] hello, is my dog cute? [SEP] + output = model(input_ids)[0] # embedding shape = (1, 768) + # compare the actual values for a slice. + expected_slice = tf.constant( + [ + [ + 0.03236253, + 0.12753335, + 0.16818509, + 0.00279786, + 0.3896933, + 0.24264945, + 0.2178971, + -0.02335227, + -0.08481959, + -0.14324117, + ] + ] + ) + self.assertTrue(numpy.allclose(output[:, :10].numpy(), expected_slice.numpy(), atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_tokenization_dpr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_tokenization_dpr.py new file mode 100644 index 0000000000000000000000000000000000000000..db41052d4cd0e2f0459373261612c222d78273b6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpr/test_tokenization_dpr.py @@ -0,0 +1,85 @@ +# coding=utf-8 +# Copyright 2020 Huggingface +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from transformers import ( + DPRContextEncoderTokenizer, + DPRContextEncoderTokenizerFast, + DPRQuestionEncoderTokenizer, + DPRQuestionEncoderTokenizerFast, + DPRReaderOutput, + DPRReaderTokenizer, + DPRReaderTokenizerFast, +) +from transformers.testing_utils import require_tokenizers, slow +from transformers.tokenization_utils_base import BatchEncoding + +from ..bert.test_tokenization_bert import BertTokenizationTest + + +@require_tokenizers +class DPRContextEncoderTokenizationTest(BertTokenizationTest): + tokenizer_class = DPRContextEncoderTokenizer + rust_tokenizer_class = DPRContextEncoderTokenizerFast + test_rust_tokenizer = True + + +@require_tokenizers +class DPRQuestionEncoderTokenizationTest(BertTokenizationTest): + tokenizer_class = DPRQuestionEncoderTokenizer + rust_tokenizer_class = DPRQuestionEncoderTokenizerFast + test_rust_tokenizer = True + + +@require_tokenizers +class DPRReaderTokenizationTest(BertTokenizationTest): + tokenizer_class = DPRReaderTokenizer + rust_tokenizer_class = DPRReaderTokenizerFast + test_rust_tokenizer = True + + @slow + def test_decode_best_spans(self): + tokenizer = self.tokenizer_class.from_pretrained("bert-base-uncased") + + text_1 = tokenizer.encode("question sequence", add_special_tokens=False) + text_2 = tokenizer.encode("title sequence", add_special_tokens=False) + text_3 = tokenizer.encode("text sequence " * 4, add_special_tokens=False) + input_ids = [[101] + text_1 + [102] + text_2 + [102] + text_3] + reader_input = BatchEncoding({"input_ids": input_ids}) + + start_logits = [[0] * len(input_ids[0])] + end_logits = [[0] * len(input_ids[0])] + relevance_logits = [0] + reader_output = DPRReaderOutput(start_logits, end_logits, relevance_logits) + + start_index, end_index = 8, 9 + start_logits[0][start_index] = 10 + end_logits[0][end_index] = 10 + predicted_spans = tokenizer.decode_best_spans(reader_input, reader_output) + self.assertEqual(predicted_spans[0].start_index, start_index) + self.assertEqual(predicted_spans[0].end_index, end_index) + self.assertEqual(predicted_spans[0].doc_id, 0) + + @slow + def test_call(self): + tokenizer = self.tokenizer_class.from_pretrained("bert-base-uncased") + + text_1 = tokenizer.encode("question sequence", add_special_tokens=False) + text_2 = tokenizer.encode("title sequence", add_special_tokens=False) + text_3 = tokenizer.encode("text sequence", add_special_tokens=False) + expected_input_ids = [101] + text_1 + [102] + text_2 + [102] + text_3 + encoded_input = tokenizer(questions=["question sequence"], titles=["title sequence"], texts=["text sequence"]) + self.assertIn("input_ids", encoded_input) + self.assertIn("attention_mask", encoded_input) + self.assertListEqual(encoded_input["input_ids"][0], expected_input_ids) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_image_processing_dpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_image_processing_dpt.py new file mode 100644 index 0000000000000000000000000000000000000000..4cde4cbe73f03abb166151b8ecaa808b12741034 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_image_processing_dpt.py @@ -0,0 +1,195 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.file_utils import is_torch_available, is_vision_available +from transformers.testing_utils import require_torch, require_vision + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import DPTImageProcessor + + +class DPTImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "size": self.size, + } + + +@require_torch +@require_vision +class DPTImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = DPTImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = DPTImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt.py new file mode 100644 index 0000000000000000000000000000000000000000..76790ee795026e1dcc830a3ddf2b51d92636745d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt.py @@ -0,0 +1,357 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DPT model. """ + + +import inspect +import unittest + +from transformers import DPTConfig +from transformers.file_utils import is_torch_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import MODEL_MAPPING, DPTForDepthEstimation, DPTForSemanticSegmentation, DPTModel + from transformers.models.dpt.modeling_dpt import DPT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import DPTFeatureExtractor + + +class DPTModelTester: + def __init__( + self, + parent, + batch_size=2, + image_size=32, + patch_size=16, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=4, + backbone_out_indices=[0, 1, 2, 3], + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + initializer_range=0.02, + num_labels=3, + is_hybrid=False, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.backbone_out_indices = backbone_out_indices + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.num_labels = num_labels + self.scope = scope + self.is_hybrid = is_hybrid + # sequence length of DPT = num_patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size, self.image_size, self.image_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return DPTConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + backbone_out_indices=self.backbone_out_indices, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + is_hybrid=self.is_hybrid, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = DPTModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_depth_estimation(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = DPTForDepthEstimation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.predicted_depth.shape, (self.batch_size, self.image_size, self.image_size)) + + def create_and_check_for_semantic_segmentation(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = DPTForSemanticSegmentation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size, self.image_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class DPTModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as DPT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (DPTModel, DPTForDepthEstimation, DPTForSemanticSegmentation) if is_torch_available() else () + pipeline_model_mapping = ( + { + "depth-estimation": DPTForDepthEstimation, + "feature-extraction": DPTModel, + "image-segmentation": DPTForSemanticSegmentation, + } + if is_torch_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = DPTModelTester(self) + self.config_tester = ConfigTester(self, config_class=DPTConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="DPT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_depth_estimation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_depth_estimation(*config_and_inputs) + + def test_for_semantic_segmentation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_semantic_segmentation(*config_and_inputs) + + def test_training(self): + for model_class in self.all_model_classes: + if model_class.__name__ == "DPTForDepthEstimation": + continue + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + if model_class in get_values(MODEL_MAPPING): + continue + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + for model_class in self.all_model_classes: + if model_class.__name__ == "DPTForDepthEstimation": + continue + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.use_cache = False + config.return_dict = True + + if model_class in get_values(MODEL_MAPPING) or not model_class.supports_gradient_checkpointing: + continue + model = model_class(config) + model.to(torch_device) + model.gradient_checkpointing_enable() + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + # Skip the check for the backbone + backbone_params = [] + for name, module in model.named_modules(): + if module.__class__.__name__ == "DPTViTHybridEmbeddings": + backbone_params = [f"{name}.{key}" for key in module.state_dict().keys()] + break + + for name, param in model.named_parameters(): + if param.requires_grad: + if name in backbone_params: + continue + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + @slow + def test_model_from_pretrained(self): + for model_name in DPT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = DPTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +@slow +class DPTModelIntegrationTest(unittest.TestCase): + def test_inference_depth_estimation(self): + feature_extractor = DPTFeatureExtractor.from_pretrained("Intel/dpt-large") + model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large").to(torch_device) + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + predicted_depth = outputs.predicted_depth + + # verify the predicted depth + expected_shape = torch.Size((1, 384, 384)) + self.assertEqual(predicted_depth.shape, expected_shape) + + expected_slice = torch.tensor( + [[6.3199, 6.3629, 6.4148], [6.3850, 6.3615, 6.4166], [6.3519, 6.3176, 6.3575]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.predicted_depth[0, :3, :3], expected_slice, atol=1e-4)) + + def test_inference_semantic_segmentation(self): + feature_extractor = DPTFeatureExtractor.from_pretrained("Intel/dpt-large-ade") + model = DPTForSemanticSegmentation.from_pretrained("Intel/dpt-large-ade").to(torch_device) + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 150, 480, 480)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor( + [[4.0480, 4.2420, 4.4360], [4.3124, 4.5693, 4.8261], [4.5768, 4.8965, 5.2163]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, 0, :3, :3], expected_slice, atol=1e-4)) + + def test_post_processing_semantic_segmentation(self): + feature_extractor = DPTFeatureExtractor.from_pretrained("Intel/dpt-large-ade") + model = DPTForSemanticSegmentation.from_pretrained("Intel/dpt-large-ade").to(torch_device) + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + outputs.logits = outputs.logits.detach().cpu() + + segmentation = feature_extractor.post_process_semantic_segmentation(outputs=outputs, target_sizes=[(500, 300)]) + expected_shape = torch.Size((500, 300)) + self.assertEqual(segmentation[0].shape, expected_shape) + + segmentation = feature_extractor.post_process_semantic_segmentation(outputs=outputs) + expected_shape = torch.Size((480, 480)) + self.assertEqual(segmentation[0].shape, expected_shape) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt_hybrid.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt_hybrid.py new file mode 100644 index 0000000000000000000000000000000000000000..6d4a75c80da12049589344302269ade4c03408cf --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/dpt/test_modeling_dpt_hybrid.py @@ -0,0 +1,336 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch DPT model. """ + + +import inspect +import unittest + +from transformers import DPTConfig +from transformers.file_utils import is_torch_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import MODEL_MAPPING, DPTForDepthEstimation, DPTForSemanticSegmentation, DPTModel + from transformers.models.dpt.modeling_dpt import DPT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import DPTFeatureExtractor + + +class DPTModelTester: + def __init__( + self, + parent, + batch_size=2, + image_size=32, + patch_size=16, + num_channels=3, + is_training=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=4, + backbone_out_indices=[0, 1, 2, 3], + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + initializer_range=0.02, + num_labels=3, + backbone_featmap_shape=[1, 384, 24, 24], + is_hybrid=True, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.backbone_out_indices = backbone_out_indices + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.num_labels = num_labels + self.backbone_featmap_shape = backbone_featmap_shape + self.scope = scope + self.is_hybrid = is_hybrid + # sequence length of DPT = num_patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size, self.image_size, self.image_size], self.num_labels) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + backbone_config = { + "global_padding": "same", + "layer_type": "bottleneck", + "depths": [3, 4, 9], + "out_features": ["stage1", "stage2", "stage3"], + "embedding_dynamic_padding": True, + "hidden_sizes": [96, 192, 384, 768], + "num_groups": 2, + } + + return DPTConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + backbone_out_indices=self.backbone_out_indices, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + is_hybrid=self.is_hybrid, + backbone_config=backbone_config, + backbone_featmap_shape=self.backbone_featmap_shape, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = DPTModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_depth_estimation(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = DPTForDepthEstimation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.predicted_depth.shape, (self.batch_size, self.image_size, self.image_size)) + + def create_and_check_for_semantic_segmentation(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = DPTForSemanticSegmentation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_labels, self.image_size, self.image_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class DPTModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as DPT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (DPTModel, DPTForDepthEstimation, DPTForSemanticSegmentation) if is_torch_available() else () + pipeline_model_mapping = ( + { + "depth-estimation": DPTForDepthEstimation, + "feature-extraction": DPTModel, + "image-segmentation": DPTForSemanticSegmentation, + } + if is_torch_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = DPTModelTester(self) + self.config_tester = ConfigTester(self, config_class=DPTConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="DPT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_depth_estimation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_depth_estimation(*config_and_inputs) + + def test_for_semantic_segmentation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_semantic_segmentation(*config_and_inputs) + + def test_training(self): + for model_class in self.all_model_classes: + if model_class.__name__ == "DPTForDepthEstimation": + continue + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + if model_class in get_values(MODEL_MAPPING): + continue + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + for model_class in self.all_model_classes: + if model_class.__name__ == "DPTForDepthEstimation": + continue + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.use_cache = False + config.return_dict = True + + if model_class in get_values(MODEL_MAPPING) or not model_class.supports_gradient_checkpointing: + continue + model = model_class(config) + model.to(torch_device) + model.gradient_checkpointing_enable() + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + # Skip the check for the backbone + backbone_params = [] + for name, module in model.named_modules(): + if module.__class__.__name__ == "DPTViTHybridEmbeddings": + backbone_params = [f"{name}.{key}" for key in module.state_dict().keys()] + break + + for name, param in model.named_parameters(): + if param.requires_grad: + if name in backbone_params: + continue + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + @slow + def test_model_from_pretrained(self): + for model_name in DPT_PRETRAINED_MODEL_ARCHIVE_LIST[1:]: + model = DPTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_raise_readout_type(self): + # We do this test only for DPTForDepthEstimation since it is the only model that uses readout_type + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + config.readout_type = "add" + with self.assertRaises(ValueError): + _ = DPTForDepthEstimation(config) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +@slow +class DPTModelIntegrationTest(unittest.TestCase): + def test_inference_depth_estimation(self): + feature_extractor = DPTFeatureExtractor.from_pretrained("Intel/dpt-hybrid-midas") + model = DPTForDepthEstimation.from_pretrained("Intel/dpt-hybrid-midas").to(torch_device) + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + predicted_depth = outputs.predicted_depth + + # verify the predicted depth + expected_shape = torch.Size((1, 384, 384)) + self.assertEqual(predicted_depth.shape, expected_shape) + + expected_slice = torch.tensor( + [[[5.6437, 5.6146, 5.6511], [5.4371, 5.5649, 5.5958], [5.5215, 5.5184, 5.5293]]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.predicted_depth[:3, :3, :3] / 100, expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_image_processing_efficientformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_image_processing_efficientformer.py new file mode 100644 index 0000000000000000000000000000000000000000..ff2fcafd4b7b6042cb3360a63ab676f3bed40d5c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_image_processing_efficientformer.py @@ -0,0 +1,191 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import ViTImageProcessor + + +class EfficientFormerImageProcessorTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=13, + num_channels=3, + image_size=224, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "size": self.size, + } + + +@require_torch +@require_vision +class EfficientFormerImageProcessorTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ViTImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_proc_tester = EfficientFormerImageProcessorTester(self) + + @property + def image_processor_dict(self): + return self.image_proc_tester.prepare_image_processor_dict() + + def test_image_proc_properties(self): + image_processor = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processor, "image_mean")) + self.assertTrue(hasattr(image_processor, "image_std")) + self.assertTrue(hasattr(image_processor, "do_normalize")) + self.assertTrue(hasattr(image_processor, "do_resize")) + self.assertTrue(hasattr(image_processor, "size")) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processor + image_processor = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_proc_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processor(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processor(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_proc_tester.batch_size, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processor + image_processor = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_proc_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processor(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processor(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_proc_tester.batch_size, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processor + image_processor = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_proc_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processor(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processor(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_proc_tester.batch_size, + self.image_proc_tester.num_channels, + self.image_proc_tester.size["height"], + self.image_proc_tester.size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_modeling_efficientformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_modeling_efficientformer.py new file mode 100644 index 0000000000000000000000000000000000000000..f3e88b1d2959809105fd4ffa2796bbe463ba9348 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientformer/test_modeling_efficientformer.py @@ -0,0 +1,477 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch EfficientFormer model. """ + + +import inspect +import unittest +import warnings + +from transformers import EfficientFormerConfig +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + MODEL_MAPPING, + EfficientFormerForImageClassification, + EfficientFormerForImageClassificationWithTeacher, + EfficientFormerModel, + ) + from transformers.models.efficientformer.modeling_efficientformer import ( + EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST, + ) + + +if is_vision_available(): + from PIL import Image + + from transformers import EfficientFormerImageProcessor + + +class EfficientFormerModelTester: + def __init__( + self, + parent, + batch_size: int = 13, + image_size: int = 224, + patch_size: int = 2, + embed_dim: int = 48, # last embed dim of stem + num_channels: int = 3, + is_training: bool = True, + use_labels: bool = True, + hidden_size: int = 448, + num_hidden_layers: int = 7, # For the l1 + num_attention_heads: int = 8, + intermediate_size: int = 37, + hidden_act: str = "gelu", + hidden_dropout_prob: float = 0.1, + attention_probs_dropout_prob: float = 0.1, + type_sequence_label_size: int = 10, + initializer_range: float = 0.02, + encoder_stride: int = 2, + num_attention_outputs: int = 1, # For l1 + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.encoder_stride = encoder_stride + self.num_attention_outputs = num_attention_outputs + self.embed_dim = embed_dim + self.seq_length = embed_dim + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return EfficientFormerConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + is_decoder=False, + initializer_range=self.initializer_range, + encoder_stride=self.encoder_stride, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = EfficientFormerModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.type_sequence_label_size + model = EfficientFormerForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + # test greyscale images + config.num_channels = 1 + model = EfficientFormerForImageClassification(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + pixel_values, + labels, + ) = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class EfficientFormerModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as EfficientFormer does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + ( + EfficientFormerModel, + EfficientFormerForImageClassificationWithTeacher, + EfficientFormerForImageClassification, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": EfficientFormerModel, + "image-classification": ( + EfficientFormerForImageClassification, + EfficientFormerForImageClassificationWithTeacher, + ), + } + if is_torch_available() + else {} + ) + fx_compatible = False + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = EfficientFormerModelTester(self) + self.config_tester = ConfigTester( + self, config_class=EfficientFormerConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="EfficientFormer does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="EfficientFormer does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + if hasattr(self.model_tester, "encoder_seq_length"): + seq_length = self.model_tester.encoder_seq_length + if hasattr(self.model_tester, "chunk_length") and self.model_tester.chunk_length > 1: + seq_length = seq_length * self.model_tester.chunk_length + else: + seq_length = self.model_tester.seq_length + + self.assertListEqual( + list(hidden_states[-1].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + if config.is_encoder_decoder: + hidden_states = outputs.decoder_hidden_states + + self.assertIsInstance(hidden_states, (list, tuple)) + self.assertEqual(len(hidden_states), expected_num_layers) + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + + self.assertListEqual( + list(hidden_states[-1].shape[-2:]), + [decoder_seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher": + del inputs_dict["labels"] + + return inputs_dict + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="EfficientFormer does not implement masked image modeling yet") + def test_for_masked_image_modeling(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_image_modeling(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + # special case for EfficientFormerForImageClassificationWithTeacher model + def test_training(self): + if not self.model_tester.is_training: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + # EfficientFormerForImageClassificationWithTeacher supports inference-only + if ( + model_class in get_values(MODEL_MAPPING) + or model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher" + ): + continue + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_problem_types(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + problem_types = [ + {"title": "multi_label_classification", "num_labels": 2, "dtype": torch.float}, + {"title": "single_label_classification", "num_labels": 1, "dtype": torch.long}, + {"title": "regression", "num_labels": 1, "dtype": torch.float}, + ] + + for model_class in self.all_model_classes: + if ( + model_class + not in [ + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING), + ] + or model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher" + ): + continue + + for problem_type in problem_types: + with self.subTest(msg=f"Testing {model_class} with {problem_type['title']}"): + config.problem_type = problem_type["title"] + config.num_labels = problem_type["num_labels"] + + model = model_class(config) + model.to(torch_device) + model.train() + + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + + if problem_type["num_labels"] > 1: + inputs["labels"] = inputs["labels"].unsqueeze(1).repeat(1, problem_type["num_labels"]) + + inputs["labels"] = inputs["labels"].to(problem_type["dtype"]) + + # This tests that we do not trigger the warning form PyTorch "Using a target size that is different + # to the input size. This will likely lead to incorrect results due to broadcasting. Please ensure + # they have the same size." which is a symptom something in wrong for the regression problem. + # See https://github.com/huggingface/transformers/issues/11780 + with warnings.catch_warnings(record=True) as warning_list: + loss = model(**inputs).loss + for w in warning_list: + if "Using a target size that is different to the input size" in str(w.message): + raise ValueError( + f"Something is going wrong in the regression problem: intercepted {w.message}" + ) + + loss.backward() + + @slow + def test_model_from_pretrained(self): + for model_name in EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = EfficientFormerModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_attention_outputs) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_attention_outputs) + + if chunk_length is not None: + self.assertListEqual( + list(attentions[0].shape[-4:]), + [self.model_tester.num_attention_heads, encoder_seq_length, chunk_length, encoder_key_length], + ) + else: + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class EfficientFormerModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ( + EfficientFormerImageProcessor.from_pretrained("snap-research/efficientformer-l1-300") + if is_vision_available() + else None + ) + + @slow + def test_inference_image_classification_head(self): + model = EfficientFormerForImageClassification.from_pretrained("snap-research/efficientformer-l1-300").to( + torch_device + ) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = (1, 1000) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([-0.0555, 0.4825, -0.0852]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0][:3], expected_slice, atol=1e-4)) + + @slow + def test_inference_image_classification_head_with_teacher(self): + model = EfficientFormerForImageClassificationWithTeacher.from_pretrained( + "snap-research/efficientformer-l1-300" + ).to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = (1, 1000) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([-0.1312, 0.4353, -1.0499]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0][:3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_image_processing_efficientnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_image_processing_efficientnet.py new file mode 100644 index 0000000000000000000000000000000000000000..8e4fad3b084035c3c83e76f5a9c04adc5df3eae0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_image_processing_efficientnet.py @@ -0,0 +1,195 @@ +# coding=utf-8 +# Copyright 2023 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import EfficientNetImageProcessor + + +class EfficientNetImageProcessorTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=13, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "size": self.size, + } + + +@require_torch +@require_vision +class EfficientNetImageProcessorTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = EfficientNetImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = EfficientNetImageProcessorTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_modeling_efficientnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_modeling_efficientnet.py new file mode 100644 index 0000000000000000000000000000000000000000..11babddac2edbf62c00e3a21df9be7dc913fbbf0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/efficientnet/test_modeling_efficientnet.py @@ -0,0 +1,269 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch EfficientNet model. """ + + +import inspect +import unittest + +from transformers import EfficientNetConfig +from transformers.testing_utils import is_pipeline_test, require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import EfficientNetForImageClassification, EfficientNetModel + from transformers.models.efficientnet.modeling_efficientnet import EFFICIENTNET_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoImageProcessor + + +class EfficientNetModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + num_channels=3, + kernel_sizes=[3, 3, 5], + in_channels=[32, 16, 24], + out_channels=[16, 24, 40], + strides=[1, 1, 2], + num_block_repeats=[1, 1, 2], + expand_ratios=[1, 6, 6], + is_training=True, + use_labels=True, + intermediate_size=37, + hidden_act="gelu", + num_labels=10, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.kernel_sizes = kernel_sizes + self.in_channels = in_channels + self.out_channels = out_channels + self.strides = strides + self.num_block_repeats = num_block_repeats + self.expand_ratios = expand_ratios + self.is_training = is_training + self.hidden_act = hidden_act + self.num_labels = num_labels + self.use_labels = use_labels + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return EfficientNetConfig( + num_channels=self.num_channels, + kernel_sizes=self.kernel_sizes, + in_channels=self.in_channels, + out_channels=self.out_channels, + strides=self.strides, + num_block_repeats=self.num_block_repeats, + expand_ratios=self.expand_ratios, + hidden_act=self.hidden_act, + num_labels=self.num_labels, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = EfficientNetModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + # expected last hidden states: B, C, H // 4, W // 4 + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, config.hidden_dim, self.image_size // 4, self.image_size // 4), + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + model = EfficientNetForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class EfficientNetModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as EfficientNet does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (EfficientNetModel, EfficientNetForImageClassification) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": EfficientNetModel, "image-classification": EfficientNetForImageClassification} + if is_torch_available() + else {} + ) + + fx_compatible = False + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = EfficientNetModelTester(self) + self.config_tester = ConfigTester( + self, config_class=EfficientNetConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + @unittest.skip(reason="EfficientNet does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="EfficientNet does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="EfficientNet does not use feedforward chunking") + def test_feed_forward_chunking(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + num_blocks = sum(config.num_block_repeats) * 4 + self.assertEqual(len(hidden_states), num_blocks) + + # EfficientNet's feature maps are of shape (batch_size, num_channels, height, width) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.image_size // 2, self.model_tester.image_size // 2], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in EFFICIENTNET_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = EfficientNetModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @is_pipeline_test + @require_vision + @slow + def test_pipeline_image_classification(self): + super().test_pipeline_image_classification() + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class EfficientNetModelIntegrationTest(unittest.TestCase): + @cached_property + def default_image_processor(self): + return AutoImageProcessor.from_pretrained("google/efficientnet-b7") if is_vision_available() else None + + @slow + def test_inference_image_classification_head(self): + model = EfficientNetForImageClassification.from_pretrained("google/efficientnet-b7").to(torch_device) + + image_processor = self.default_image_processor + image = prepare_img() + inputs = image_processor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([0.0001, 0.0002, 0.0002]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_electra.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_electra.py new file mode 100644 index 0000000000000000000000000000000000000000..550bc1448707e3b51ac5cbfe6e8be39fcdb51d99 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_electra.py @@ -0,0 +1,489 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import ElectraConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, slow, torch_device + +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 ( + MODEL_FOR_PRETRAINING_MAPPING, + ElectraForCausalLM, + ElectraForMaskedLM, + ElectraForMultipleChoice, + ElectraForPreTraining, + ElectraForQuestionAnswering, + ElectraForSequenceClassification, + ElectraForTokenClassification, + ElectraModel, + ) + from transformers.models.electra.modeling_electra import ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST + + +class ElectraModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + fake_token_labels = ids_tensor([self.batch_size, self.seq_length], 1) + + config = self.get_config() + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ) + + def get_config(self): + return ElectraConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + _, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_electra_model( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = ElectraModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_electra_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = ElectraModel(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_electra_for_masked_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = ElectraForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_electra_for_causal_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + model = ElectraForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_electra_for_token_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = ElectraForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_electra_for_pretraining( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = ElectraForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=fake_token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_electra_for_sequence_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = ElectraForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_electra_for_question_answering( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = ElectraForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_electra_for_multiple_choice( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_choices = self.num_choices + model = ElectraForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class ElectraModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + ElectraModel, + ElectraForPreTraining, + ElectraForMaskedLM, + ElectraForCausalLM, + ElectraForMultipleChoice, + ElectraForTokenClassification, + ElectraForSequenceClassification, + ElectraForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": ElectraModel, + "fill-mask": ElectraForMaskedLM, + "question-answering": ElectraForQuestionAnswering, + "text-classification": ElectraForSequenceClassification, + "text-generation": ElectraForCausalLM, + "token-classification": ElectraForTokenClassification, + "zero-shot": ElectraForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = ElectraModelTester(self) + self.config_tester = ConfigTester(self, config_class=ElectraConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_electra_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_model(*config_and_inputs) + + def test_electra_model_as_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_electra_model_as_decoder(*config_and_inputs) + + def test_electra_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_electra_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_token_classification(*config_and_inputs) + + def test_for_pre_training(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_pretraining(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_sequence_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_question_answering(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_electra_for_multiple_choice(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ElectraModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_electra_for_causal_lm(*config_and_inputs) + + +@require_torch +class ElectraModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = ElectraModel.from_pretrained("google/electra-small-discriminator") + input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) + attention_mask = torch.tensor([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) + output = model(input_ids, attention_mask=attention_mask)[0] + expected_shape = torch.Size((1, 11, 256)) + self.assertEqual(output.shape, expected_shape) + expected_slice = torch.tensor( + [[[0.4471, 0.6821, -0.3265], [0.4627, 0.5255, -0.3668], [0.4532, 0.3313, -0.4344]]] + ) + + self.assertTrue(torch.allclose(output[:, 1:4, 1:4], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_flax_electra.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_flax_electra.py new file mode 100644 index 0000000000000000000000000000000000000000..0dda4e38fddaf7d21cb648b079c56ee79d6582f8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_flax_electra.py @@ -0,0 +1,136 @@ +import unittest + +import numpy as np + +from transformers import ElectraConfig, is_flax_available +from transformers.testing_utils import require_flax, slow + +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask + + +if is_flax_available(): + from transformers.models.electra.modeling_flax_electra import ( + FlaxElectraForCausalLM, + FlaxElectraForMaskedLM, + FlaxElectraForMultipleChoice, + FlaxElectraForPreTraining, + FlaxElectraForQuestionAnswering, + FlaxElectraForSequenceClassification, + FlaxElectraForTokenClassification, + FlaxElectraModel, + ) + + +class FlaxElectraModelTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_attention_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + embedding_size=24, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_choices=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.embedding_size = embedding_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_choices = num_choices + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + config = ElectraConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + embedding_size=self.embedding_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + return config, input_ids, token_type_ids, attention_mask + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, token_type_ids, attention_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": attention_mask} + return config, inputs_dict + + +@require_flax +class FlaxElectraModelTest(FlaxModelTesterMixin, unittest.TestCase): + test_head_masking = True + + all_model_classes = ( + ( + FlaxElectraModel, + FlaxElectraForCausalLM, + FlaxElectraForMaskedLM, + FlaxElectraForPreTraining, + FlaxElectraForTokenClassification, + FlaxElectraForQuestionAnswering, + FlaxElectraForMultipleChoice, + FlaxElectraForSequenceClassification, + ) + if is_flax_available() + else () + ) + + def setUp(self): + self.model_tester = FlaxElectraModelTester(self) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + if model_class_name == FlaxElectraForMaskedLM: + model = model_class_name.from_pretrained("google/electra-small-generator") + else: + model = model_class_name.from_pretrained("google/electra-small-discriminator") + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_tf_electra.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_tf_electra.py new file mode 100644 index 0000000000000000000000000000000000000000..ae092e8a17dc5e4250ffb81b4ccfb2dbea16444e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/electra/test_modeling_tf_electra.py @@ -0,0 +1,614 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import ElectraConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.electra.modeling_tf_electra import ( + TFElectraForMaskedLM, + TFElectraForMultipleChoice, + TFElectraForPreTraining, + TFElectraForQuestionAnswering, + TFElectraForSequenceClassification, + TFElectraForTokenClassification, + TFElectraModel, + ) + + +class TFElectraModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + self.embedding_size = 128 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = ElectraConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFElectraModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_causal_lm_base_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.is_decoder = True + + model = TFElectraModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TFElectraModel(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + "encoder_hidden_states": encoder_hidden_states, + "encoder_attention_mask": encoder_attention_mask, + } + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs, token_type_ids=token_type_ids, encoder_hidden_states=encoder_hidden_states) + + # Also check the case where encoder outputs are not passed + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_causal_lm_base_model_past( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TFElectraModel(config=config) + + # first forward pass + outputs = model(input_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids) + outputs_no_past = model(input_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and attn_mask + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + + output_from_no_past = model(next_input_ids, output_hidden_states=True).hidden_states[0] + output_from_past = model( + next_tokens, past_key_values=past_key_values, output_hidden_states=True + ).hidden_states[0] + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_causal_lm_base_model_past_with_attn_mask( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TFElectraModel(config=config) + + # create attention mask + half_seq_length = self.seq_length // 2 + attn_mask_begin = tf.ones((self.batch_size, half_seq_length), dtype=tf.int32) + attn_mask_end = tf.zeros((self.batch_size, self.seq_length - half_seq_length), dtype=tf.int32) + attn_mask = tf.concat([attn_mask_begin, attn_mask_end], axis=1) + + # first forward pass + outputs = model(input_ids, attention_mask=attn_mask, use_cache=True) + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + past_key_values = outputs.past_key_values + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).numpy() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, self.seq_length), config.vocab_size) + vector_condition = tf.range(self.seq_length) == (self.seq_length - random_seq_idx_to_change) + condition = tf.transpose( + tf.broadcast_to(tf.expand_dims(vector_condition, -1), (self.seq_length, self.batch_size)) + ) + input_ids = tf.where(condition, random_other_next_tokens, input_ids) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + attn_mask = tf.concat( + [attn_mask, tf.ones((attn_mask.shape[0], 1), dtype=tf.int32)], + axis=1, + ) + + output_from_no_past = model( + next_input_ids, + attention_mask=attn_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, past_key_values=past_key_values, attention_mask=attn_mask, output_hidden_states=True + ).hidden_states[0] + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_causal_lm_base_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.is_decoder = True + + model = TFElectraModel(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, use_cache=True) + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + ).hidden_states[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TFElectraModel(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + encoder_hidden_states = encoder_hidden_states[:1, :, :] + encoder_attention_mask = encoder_attention_mask[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + ).hidden_states[0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + ).hidden_states[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFElectraForMaskedLM(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_pretraining( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFElectraForPreTraining(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFElectraForSequenceClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = TFElectraForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFElectraForQuestionAnswering(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFElectraForTokenClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFElectraModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFElectraModel, + TFElectraForMaskedLM, + TFElectraForPreTraining, + TFElectraForTokenClassification, + TFElectraForMultipleChoice, + TFElectraForSequenceClassification, + TFElectraForQuestionAnswering, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFElectraModel, + "fill-mask": TFElectraForMaskedLM, + "question-answering": TFElectraForQuestionAnswering, + "text-classification": TFElectraForSequenceClassification, + "token-classification": TFElectraForTokenClassification, + "zero-shot": TFElectraForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFElectraModelTester(self) + self.config_tester = ConfigTester(self, config_class=ElectraConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + """Test the base model""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_causal_lm_base_model(self): + """Test the base model of the causal LM model + + is_deocder=True, no cross_attention, no encoder outputs + """ + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_base_model(*config_and_inputs) + + def test_model_as_decoder(self): + """Test the base model as a decoder (of an encoder-decoder architecture) + + is_deocder=True + cross_attention + pass encoder outputs + """ + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_causal_lm_base_model_past(self): + """Test causal LM base model with `past_key_values`""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_base_model_past(*config_and_inputs) + + def test_causal_lm_base_model_past_with_attn_mask(self): + """Test the causal LM base model with `past_key_values` and `attention_mask`""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_base_model_past_with_attn_mask(*config_and_inputs) + + def test_causal_lm_base_model_past_with_large_inputs(self): + """Test the causal LM base model with `past_key_values` and a longer decoder sequence length""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_causal_lm_base_model_past_large_inputs(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs(self): + """Similar to `test_causal_lm_base_model_past_with_large_inputs` but with cross-attention""" + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + # for model_name in TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + for model_name in ["google/electra-small-discriminator"]: + model = TFElectraModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_tf +class TFElectraModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TFElectraForPreTraining.from_pretrained("lysandre/tiny-electra-random") + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + expected_shape = [1, 6] + self.assertEqual(output.shape, expected_shape) + + print(output[:, :3]) + + expected_slice = tf.constant([[-0.24651965, 0.8835437, 1.823782]]) + tf.debugging.assert_near(output[:, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..c476744057e89dd4c14696b0ac040c8bcb86b029 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_encoder_decoder.py @@ -0,0 +1,1113 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +from transformers import is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_modeling_common import ids_tensor +from ..bart.test_modeling_bart import BartStandaloneDecoderModelTester +from ..bert.test_modeling_bert import BertModelTester +from ..bert_generation.test_modeling_bert_generation import BertGenerationEncoderTester +from ..gpt2.test_modeling_gpt2 import GPT2ModelTester +from ..prophetnet.test_modeling_prophetnet import ProphetNetStandaloneDecoderModelTester +from ..roberta.test_modeling_roberta import RobertaModelTester + + +if is_torch_available(): + import numpy as np + import torch + + from transformers import ( + AutoConfig, + AutoTokenizer, + BartForCausalLM, + BertGenerationDecoder, + BertGenerationEncoder, + BertLMHeadModel, + BertModel, + BertTokenizer, + EncoderDecoderConfig, + EncoderDecoderModel, + GPT2LMHeadModel, + ProphetNetForCausalLM, + RobertaForCausalLM, + RobertaModel, + ) + from transformers.modeling_outputs import BaseModelOutput + + +@require_torch +class EncoderDecoderMixin: + def get_encoder_decoder_model(self, config, decoder_config): + raise NotImplementedError + + def prepare_config_and_inputs(self): + raise NotImplementedError + + def get_pretrained_model(self): + raise NotImplementedError + + def check_encoder_decoder_model_from_pretrained_configs( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + self.assertTrue(encoder_decoder_config.decoder.is_decoder) + + enc_dec_model = EncoderDecoderModel(encoder_decoder_config) + enc_dec_model.to(torch_device) + enc_dec_model.eval() + + self.assertTrue(enc_dec_model.config.is_encoder_decoder) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + self.assertTrue(enc_dec_model.config.decoder.is_decoder) + self.assertTrue(enc_dec_model.config.decoder.add_cross_attention) + self.assertTrue(enc_dec_model.config.is_encoder_decoder) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + encoder_outputs = BaseModelOutput(last_hidden_state=encoder_hidden_states) + outputs_encoder_decoder = enc_dec_model( + encoder_outputs=encoder_outputs, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + # Test passing encoder_outputs as tuple. + encoder_outputs = (encoder_hidden_states,) + outputs_encoder_decoder = enc_dec_model( + encoder_outputs=encoder_outputs, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model_from_pretrained_using_model_paths( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + with tempfile.TemporaryDirectory() as encoder_tmp_dirname, tempfile.TemporaryDirectory() as decoder_tmp_dirname: + encoder_model.save_pretrained(encoder_tmp_dirname) + decoder_model.save_pretrained(decoder_tmp_dirname) + model_kwargs = {"encoder_hidden_dropout_prob": 0.0} + + # BartConfig has no hidden_dropout_prob. + if not hasattr(decoder_config, "hidden_dropout_prob"): + model_kwargs["decoder_activation_function"] = "gelu" + else: + model_kwargs["decoder_hidden_dropout_prob"] = 0.0 + + enc_dec_model = EncoderDecoderModel.from_encoder_decoder_pretrained( + encoder_tmp_dirname, decoder_tmp_dirname, **model_kwargs + ) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + return_dict=True, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model_from_pretrained( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + return_dict, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model, "return_dict": return_dict} + enc_dec_model = EncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + return_dict=True, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_save_and_load( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.to(torch_device) + enc_dec_model.eval() + with torch.no_grad(): + outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_2 = outputs[0].cpu().numpy() + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmpdirname: + enc_dec_model.save_pretrained(tmpdirname) + enc_dec_model = EncoderDecoderModel.from_pretrained(tmpdirname) + enc_dec_model.to(torch_device) + + after_outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_1 = after_outputs[0].cpu().numpy() + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + def check_save_and_load_encoder_decoder_model( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.to(torch_device) + enc_dec_model.eval() + with torch.no_grad(): + outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_2 = outputs[0].cpu().numpy() + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as encoder_tmp_dirname, tempfile.TemporaryDirectory() as decoder_tmp_dirname: + enc_dec_model.encoder.save_pretrained(encoder_tmp_dirname) + enc_dec_model.decoder.save_pretrained(decoder_tmp_dirname) + enc_dec_model = EncoderDecoderModel.from_encoder_decoder_pretrained( + encoder_pretrained_model_name_or_path=encoder_tmp_dirname, + decoder_pretrained_model_name_or_path=decoder_tmp_dirname, + ) + enc_dec_model.to(torch_device) + + after_outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_1 = after_outputs[0].cpu().numpy() + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + def check_encoder_decoder_model_labels( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + labels, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + labels=labels, + ) + + loss = outputs_encoder_decoder["loss"] + # check that backprop works + loss.backward() + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def _check_output_with_attentions( + self, outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ): + encoder_attentions = outputs_encoder_decoder["encoder_attentions"] + self.assertEqual(len(encoder_attentions), config.num_hidden_layers) + + self.assertEqual( + encoder_attentions[0].shape[-3:], (config.num_attention_heads, input_ids.shape[-1], input_ids.shape[-1]) + ) + + decoder_attentions = outputs_encoder_decoder["decoder_attentions"] + num_decoder_layers = ( + decoder_config.num_decoder_layers + if hasattr(decoder_config, "num_decoder_layers") + else decoder_config.num_hidden_layers + ) + self.assertEqual(len(decoder_attentions), num_decoder_layers) + + self.assertEqual( + decoder_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, decoder_input_ids.shape[-1], decoder_input_ids.shape[-1]), + ) + + cross_attentions = outputs_encoder_decoder["cross_attentions"] + self.assertEqual(len(cross_attentions), num_decoder_layers) + + cross_attention_input_seq_len = decoder_input_ids.shape[-1] * ( + 1 + (decoder_config.ngram if hasattr(decoder_config, "ngram") else 0) + ) + self.assertEqual( + cross_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, cross_attention_input_seq_len, input_ids.shape[-1]), + ) + + def check_encoder_decoder_model_output_attentions( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + labels, + **kwargs, + ): + # make the decoder inputs a different shape from the encoder inputs to harden the test + decoder_input_ids = decoder_input_ids[:, :-1] + decoder_attention_mask = decoder_attention_mask[:, :-1] + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + output_attentions=True, + ) + self._check_output_with_attentions( + outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ) + + def check_encoder_decoder_model_output_attentions_from_config( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + labels, + **kwargs, + ): + # Similar to `check_encoder_decoder_model_output_attentions`, but with `output_attentions` triggered from the + # config file. Contrarily to most models, changing the model's config won't work -- the defaults are loaded + # from the inner models' configurations. + + decoder_input_ids = decoder_input_ids[:, :-1] + decoder_attention_mask = decoder_attention_mask[:, :-1] + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.config.output_attentions = True # model config -> won't work + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + self.assertTrue( + all( + key not in outputs_encoder_decoder + for key in ["encoder_attentions", "decoder_attentions", "cross_attentions"] + ) + ) + + config.output_attentions = True # inner model config -> will work + decoder_config.output_attentions = True + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.to(torch_device) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + self._check_output_with_attentions( + outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ) + + def check_encoder_decoder_model_generate(self, input_ids, config, decoder_config, **kwargs): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + + # Generate until max length + if hasattr(enc_dec_model.config, "eos_token_id"): + enc_dec_model.config.eos_token_id = None + if hasattr(enc_dec_model.config, "decoder") and hasattr(enc_dec_model.config.decoder, "eos_token_id"): + enc_dec_model.config.decoder.eos_token_id = None + enc_dec_model.to(torch_device) + + # Bert does not have a bos token id, so use pad_token_id instead + generated_output = enc_dec_model.generate( + input_ids, decoder_start_token_id=enc_dec_model.config.decoder.pad_token_id + ) + self.assertEqual(generated_output.shape, (input_ids.shape[0],) + (decoder_config.max_length,)) + + def create_and_check_encoder_decoder_shared_weights( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + labels, + **kwargs, + ): + torch.manual_seed(0) + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + model.to(torch_device) + model.eval() + # load state dict copies weights but does not tie them + decoder_state_dict = model.decoder._modules[model.decoder.base_model_prefix].state_dict() + model.encoder.load_state_dict(decoder_state_dict, strict=False) + + torch.manual_seed(0) + tied_encoder_model, tied_decoder_model = self.get_encoder_decoder_model(config, decoder_config) + config = EncoderDecoderConfig.from_encoder_decoder_configs( + tied_encoder_model.config, tied_decoder_model.config, tie_encoder_decoder=True + ) + tied_model = EncoderDecoderModel(encoder=tied_encoder_model, decoder=tied_decoder_model, config=config) + tied_model.to(torch_device) + tied_model.eval() + + model_result = model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + tied_model_result = tied_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + # check that models has less parameters + self.assertLess(sum(p.numel() for p in tied_model.parameters()), sum(p.numel() for p in model.parameters())) + random_slice_idx = ids_tensor((1,), model_result[0].shape[-1]).item() + + # check that outputs are equal + self.assertTrue( + torch.allclose( + model_result[0][0, :, random_slice_idx], tied_model_result[0][0, :, random_slice_idx], atol=1e-4 + ) + ) + + # check that outputs after saving and loading are equal + with tempfile.TemporaryDirectory() as tmpdirname: + tied_model.save_pretrained(tmpdirname) + tied_model = EncoderDecoderModel.from_pretrained(tmpdirname) + tied_model.to(torch_device) + tied_model.eval() + + # check that models has less parameters + self.assertLess( + sum(p.numel() for p in tied_model.parameters()), sum(p.numel() for p in model.parameters()) + ) + random_slice_idx = ids_tensor((1,), model_result[0].shape[-1]).item() + + tied_model_result = tied_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + # check that outputs are equal + self.assertTrue( + torch.allclose( + model_result[0][0, :, random_slice_idx], tied_model_result[0][0, :, random_slice_idx], atol=1e-4 + ) + ) + + def test_encoder_decoder_model(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model(**input_ids_dict) + + def test_encoder_decoder_model_from_pretrained_configs(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained_configs(**input_ids_dict) + + def test_encoder_decoder_model_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=False) + + def test_encoder_decoder_model_from_pretrained_return_dict(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=True) + + def test_encoder_decoder_model_from_pretrained_using_model_paths(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained_using_model_paths(**input_ids_dict, return_dict=False) + + def test_save_and_load_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_save_and_load(**input_ids_dict) + + def test_save_and_load_from_encoder_decoder_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_save_and_load_encoder_decoder_model(**input_ids_dict) + + def test_encoder_decoder_model_labels(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_labels(**input_ids_dict) + + def test_encoder_decoder_model_output_attentions(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_output_attentions(**input_ids_dict) + + def test_encoder_decoder_model_output_attentions_from_config(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_output_attentions_from_config(**input_ids_dict) + + def test_encoder_decoder_model_generate(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_generate(**input_ids_dict) + + def test_encoder_decoder_model_shared_weights(self): + input_ids_dict = self.prepare_config_and_inputs() + self.create_and_check_encoder_decoder_shared_weights(**input_ids_dict) + + def test_training_gradient_checkpointing(self): + inputs_dict = self.prepare_config_and_inputs() + encoder_model, decoder_model = self.get_encoder_decoder_model( + inputs_dict["config"], inputs_dict["decoder_config"] + ) + + model = EncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + model.to(torch_device) + model.gradient_checkpointing_enable() + model.train() + + model.config.decoder_start_token_id = 0 + model.config.pad_token_id = 0 + + model_inputs = { + "input_ids": inputs_dict["input_ids"], + "attention_mask": inputs_dict["attention_mask"], + "labels": inputs_dict["labels"], + "decoder_input_ids": inputs_dict["decoder_input_ids"], + } + model_inputs = {k: v.to(torch_device) for k, v in model_inputs.items()} + + loss = model(**model_inputs).loss + loss.backward() + + @slow + def test_real_model_save_load_from_pretrained(self): + model_2 = self.get_pretrained_model() + model_2.to(torch_device) + input_ids = ids_tensor([13, 5], model_2.config.encoder.vocab_size) + decoder_input_ids = ids_tensor([13, 1], model_2.config.encoder.vocab_size) + attention_mask = ids_tensor([13, 5], vocab_size=2) + with torch.no_grad(): + outputs = model_2( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_2 = outputs[0].cpu().numpy() + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmp_dirname: + model_2.save_pretrained(tmp_dirname) + model_1 = EncoderDecoderModel.from_pretrained(tmp_dirname) + model_1.to(torch_device) + + after_outputs = model_1( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_1 = after_outputs[0].cpu().numpy() + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + +@require_torch +class BertEncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "bert-base-cased") + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = BertModel(config) + decoder_model = BertLMHeadModel(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester = BertModelTester(self) + encoder_config_and_inputs = model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_token_type_ids, + decoder_input_mask, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + def test_relative_position_embeds(self): + config_and_inputs = self.prepare_config_and_inputs() + + encoder_config = config_and_inputs["config"] + decoder_config = config_and_inputs["decoder_config"] + + encoder_config.position_embedding_type = "relative_key_query" + decoder_config.position_embedding_type = "relative_key_query" + + config = EncoderDecoderConfig.from_encoder_decoder_configs(encoder_config, decoder_config) + model = EncoderDecoderModel(config).eval().to(torch_device) + + logits = model( + input_ids=config_and_inputs["input_ids"], decoder_input_ids=config_and_inputs["decoder_input_ids"] + ).logits + + self.assertTrue(logits.shape, (13, 7)) + + @slow + def test_bert2bert_summarization(self): + model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") + model.to(torch_device) + tokenizer = BertTokenizer.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") + + ARTICLE_SIGMA = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David Boren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 1856, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confederate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking full membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on the fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more involved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members allegedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a fraternity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloyd's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing incidents.""" + + ARTICLE_AMERICA = """(CNN) -- The 2013 America's Cup will be faster than ever after organizers announced that wingsail catamarans will be the vessels of choice. The race has historically been between yachts with a single hull, however the 34th edition of the contest will be between multi-hull vessels with wings rather than traditional sails. This means the boats will travel faster through the water, with top speeds in excess of 30 knots, almost three times as fast as in the past. The Golden Gate Yacht Club, hosts of the 2013 race and holders of the cup, have also announced a new, shorter race format for the competition. In an attempt to boost interest in one of sailing's showpiece events an annual World Series will also take place, starting in 2011, resulting a world champion team being crowned. In addition, a youth America's Cup will also be introduced, set to begin in 2012. In a statement on the International Sailing Federation (ISAF) website, the CEO of 2010's winning syndicate BMW ORACLE Racing Russell Coutts explained the reasons behind the changes. "We believe this new format and new boat will put the America's Cup back at the pinnacle of our sport," said Coutts. "These changes will give equal opportunity to competitors and long-term economic stability to all teams and all commercial partners. We promised fairness and innovation and this is what we've delivered." The statement also explained how, in addition to generating interest in the contest, the new annual America's Cup World Series will provide increased commercial revenue for the teams and their sponsors. The venue for the 2013 contest is not due to be announced until the end of the year, with San Francisco, Valencia and a location near Rome believed to be under consideration. Vincenzo Onorato, President of the 2013 challengers Mascalzone Latino, supported the changes: "I think that we need to acknowledge that the Defender has kept its word. The America's Cup is going to have fair rules and a truly independent management of the racing.""" + + EXPECTED_SUMMARY_SIGMA = """sae was founded in 1856, five years before the civil war. the fraternity has had to work hard to change recently. the university of oklahoma president says the university's affiliation with the fraternity is permanently done. the sae has had a string of members in recent months.""" + + EXPECTED_SUMMARY_AMERICA = """the 2013 america's cup will be faster than ever. the 34th edition of the competition will be held in 2011. the 2013 race will be between multi - hull vessels with wings rather than traditional sails. the new america'' cup will provide increased commercial revenue. the event will also be expanded to a youth america'cup.""" + + input_dict = tokenizer( + [ARTICLE_SIGMA, ARTICLE_AMERICA], + padding="max_length", + pad_to_max_length=True, + max_length=512, + return_tensors="pt", + ) + output_ids = model.generate( + input_dict["input_ids"].to(torch_device), attention_mask=input_dict["attention_mask"].to(torch_device) + ) + summary = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_SIGMA, EXPECTED_SUMMARY_AMERICA]) + + +@require_torch +class BertGenerationEncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained( + "google/bert_for_seq_generation_L-24_bbc_encoder", "google/bert_for_seq_generation_L-24_bbc_encoder" + ) + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = BertGenerationEncoder(config) + decoder_model = BertGenerationDecoder(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester = BertGenerationEncoderTester(self) + encoder_config_and_inputs = model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + input_mask, + token_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_input_mask, + decoder_token_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_token_labels": decoder_token_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + @slow + def test_roberta2roberta_summarization(self): + model = EncoderDecoderModel.from_pretrained("google/roberta2roberta_L-24_bbc") + model.to(torch_device) + tokenizer = AutoTokenizer.from_pretrained("google/roberta2roberta_L-24_bbc") + + ARTICLE_PS3 = """The problem is affecting people using the older versions of the PlayStation 3, called the "Fat" model.The problem isn't affecting the newer PS3 Slim systems that have been on sale since September last year.Sony have also said they are aiming to have the problem fixed shortly but is advising some users to avoid using their console for the time being."We hope to resolve this problem within the next 24 hours," a statement reads. "In the meantime, if you have a model other than the new slim PS3, we advise that you do not use your PS3 system, as doing so may result in errors in some functionality, such as recording obtained trophies, and not being able to restore certain data."We believe we have identified that this problem is being caused by a bug in the clock functionality incorporated in the system."The PlayStation Network is used by millions of people around the world.It allows users to play their friends at games like Fifa over the internet and also do things like download software or visit online stores.""" + + ARTICLE_TOSHIBA = """An independent panel appointed by Toshiba found institutional accounting irregularities, the firm said in a statement to investors. Toshiba said it "takes the situation it has caused very seriously" and that it "deeply apologised" to shareholders. The overstatement was roughly triple an initial Toshiba estimate. The probe could lead to a restatement of earnings, a board overhaul and potential action by regulators. "Within Toshiba, there was a corporate culture in which one could not go against the wishes of superiors," the report said. "Therefore, when top management presented 'challenges', division presidents, line managers and employees below them continually carried out inappropriate accounting practices to meet targets in line with the wishes of their superiors." The improper accounting practices stretched back to 2008.""" + + EXPECTED_SUMMARY_PS3 = """Sony has said that a bug in its PlayStation 3 console is preventing them from using the machine as a computer.""" + + EXPECTED_SUMMARY_TOSHIBA = """Japanese electronics giant Toshiba overstated its annual earnings by more than a third last year, according to a report.""" + + input_dict = tokenizer( + [ARTICLE_PS3, ARTICLE_TOSHIBA], max_length=512, padding="max_length", return_tensors="pt" + ) + output_ids = model.generate( + input_dict["input_ids"].to(torch_device), attention_mask=input_dict["attention_mask"].to(torch_device) + ) + summary = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_PS3, EXPECTED_SUMMARY_TOSHIBA]) + + +@require_torch +class RoBertaEncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = RobertaModel(config) + decoder_model = RobertaForCausalLM(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester = RobertaModelTester(self) + encoder_config_and_inputs = model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_token_type_ids, + decoder_input_mask, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained("roberta-base", "roberta-base") + + +@require_torch +class GPT2EncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = BertModel(config) + decoder_model = GPT2LMHeadModel(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = BertModelTester(self, batch_size=13) + model_tester_decoder = GPT2ModelTester(self, batch_size=13) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_input_mask, + decoder_head_mask, + decoder_token_type_ids, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "gpt2") + + def test_encoder_decoder_model_shared_weights(self): + pass + + @slow + def test_bert2gpt2_summarization(self): + model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16") + + model.to(torch_device) + tokenizer_in = AutoTokenizer.from_pretrained("bert-base-cased") + tokenizer_out = AutoTokenizer.from_pretrained("gpt2") + + ARTICLE_STUDENTS = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David Boren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 1856, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confederate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking full membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on the fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more involved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members allegedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a fraternity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloyd's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing incidents.""" + + EXPECTED_SUMMARY_STUDENTS = """SAS Alpha Epsilon suspended the students, but university president says it's permanent.\nThe fraternity has had to deal with a string of student deaths since 2010.\nSAS has more than 200,000 members, many of whom are students.\nA student died while being forced into excessive alcohol consumption.""" + + input_dict = tokenizer_in(ARTICLE_STUDENTS, return_tensors="pt") + output_ids = model.generate(input_dict["input_ids"].to(torch_device)) + summary = tokenizer_out.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_STUDENTS]) + + +@require_torch +class ProphetNetEncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = BertModel(config) + decoder_model = ProphetNetForCausalLM(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = BertModelTester(self, batch_size=13) + model_tester_decoder = ProphetNetStandaloneDecoderModelTester( + self, batch_size=13, hidden_size=32, max_position_embeddings=512 + ) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + lm_labels, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "encoder_hidden_states": encoder_hidden_states, + "labels": lm_labels, + } + + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained( + "bert-large-uncased", "microsoft/prophetnet-large-uncased" + ) + + def test_encoder_decoder_model_shared_weights(self): + pass + + +@require_torch +class BartEncoderDecoderModelTest(EncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = BertModel(config) + decoder_model = BartForCausalLM(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = BertModelTester(self, batch_size=13) + model_tester_decoder = BartStandaloneDecoderModelTester( + self, batch_size=13, d_model=32, max_position_embeddings=512 + ) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + lm_labels, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "encoder_hidden_states": encoder_hidden_states, + "labels": lm_labels, + } + + def get_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained("bert-large-uncased", "facebook/bart-large") + + def test_encoder_decoder_model_shared_weights(self): + pass + + +@require_torch +class EncoderDecoderModelTest(unittest.TestCase): + def get_from_encoderdecoder_pretrained_model(self): + return EncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-uncased", "bert-base-uncased") + + def get_decoder_config(self): + config = AutoConfig.from_pretrained("bert-base-uncased") + config.is_decoder = True + config.add_cross_attention = True + return config + + def get_encoderdecoder_model(self): + return EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") + + def get_encoder_decoder_models(self): + encoder_model = BertModel.from_pretrained("bert-base-uncased") + decoder_model = BertLMHeadModel.from_pretrained("bert-base-uncased", config=self.get_decoder_config()) + return {"encoder": encoder_model, "decoder": decoder_model} + + def _check_configuration_tie(self, model): + assert id(model.decoder.config) == id(model.config.decoder) + assert id(model.encoder.config) == id(model.config.encoder) + + @slow + def test_configuration_tie(self): + model = self.get_from_encoderdecoder_pretrained_model() + self._check_configuration_tie(model) + + model = EncoderDecoderModel(**self.get_encoder_decoder_models()) + self._check_configuration_tie(model) + + model = self.get_encoderdecoder_model() + self._check_configuration_tie(model) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_flax_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_flax_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..362a5f74a1b6adc7c25216d4a24a53c44b329463 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_flax_encoder_decoder.py @@ -0,0 +1,596 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +import numpy as np + +from transformers import is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax, slow, torch_device + +from ...test_modeling_flax_common import ids_tensor +from ..bart.test_modeling_flax_bart import FlaxBartStandaloneDecoderModelTester +from ..bert.test_modeling_flax_bert import FlaxBertModelTester +from ..gpt2.test_modeling_flax_gpt2 import FlaxGPT2ModelTester + + +if is_flax_available(): + from transformers import ( + AutoTokenizer, + EncoderDecoderConfig, + FlaxBartForCausalLM, + FlaxBertForCausalLM, + FlaxBertModel, + FlaxEncoderDecoderModel, + FlaxGPT2LMHeadModel, + ) + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + +if is_torch_available(): + import torch + + from transformers import EncoderDecoderModel + + +@require_flax +class FlaxEncoderDecoderMixin: + def get_encoder_decoder_model(self, config, decoder_config): + raise NotImplementedError + + def prepare_config_and_inputs(self): + raise NotImplementedError + + def get_pretrained_model(self): + raise NotImplementedError + + def check_encoder_decoder_model_from_pretrained_configs( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + self.assertTrue(encoder_decoder_config.decoder.is_decoder) + + enc_dec_model = FlaxEncoderDecoderModel(encoder_decoder_config) + + self.assertTrue(enc_dec_model.config.is_encoder_decoder) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model_from_pretrained( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + return_dict, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model, "return_dict": return_dict} + enc_dec_model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + return_dict=True, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_save_and_load( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model} + enc_dec_model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + + outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_2 = np.array(outputs[0]) + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmpdirname: + enc_dec_model.save_pretrained(tmpdirname) + FlaxEncoderDecoderModel.from_pretrained(tmpdirname) + + after_outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + out_1 = np.array(after_outputs[0]) + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + def check_encoder_decoder_model_from_encoder_decoder_pretrained( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + # assert that model attributes match those of configs + self.assertEqual(config.use_cache, encoder_model.config.use_cache) + self.assertEqual(decoder_config.use_cache, decoder_model.config.use_cache) + + with tempfile.TemporaryDirectory() as enc_tmpdir: + with tempfile.TemporaryDirectory() as dec_tmpdir: + encoder_model.save_pretrained(enc_tmpdir) + decoder_model.save_pretrained(dec_tmpdir) + # load a model from pretrained encoder and decoder checkpoints, setting one encoder and one decoder kwarg opposite to that specified in their respective configs + enc_dec_model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained( + encoder_pretrained_model_name_or_path=enc_tmpdir, + decoder_pretrained_model_name_or_path=dec_tmpdir, + encoder_use_cache=not config.use_cache, + decoder_use_cache=not decoder_config.use_cache, + ) + + # assert that setting encoder and decoder kwargs opposite to those in the configs has correctly been applied + self.assertNotEqual(config.use_cache, enc_dec_model.config.encoder.use_cache) + self.assertNotEqual(decoder_config.use_cache, enc_dec_model.config.decoder.use_cache) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + attention_mask=attention_mask, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + output_hidden_states=True, + return_dict=True, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + + def check_encoder_decoder_model_output_attentions( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + # make the decoder inputs a different shape from the encoder inputs to harden the test + decoder_input_ids = decoder_input_ids[:, :-1] + decoder_attention_mask = decoder_attention_mask[:, :-1] + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model} + enc_dec_model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + output_attentions=True, + ) + + encoder_attentions = outputs_encoder_decoder["encoder_attentions"] + self.assertEqual(len(encoder_attentions), config.num_hidden_layers) + + self.assertEqual( + encoder_attentions[0].shape[-3:], (config.num_attention_heads, input_ids.shape[-1], input_ids.shape[-1]) + ) + + decoder_attentions = outputs_encoder_decoder["decoder_attentions"] + num_decoder_layers = ( + decoder_config.num_decoder_layers + if hasattr(decoder_config, "num_decoder_layers") + else decoder_config.num_hidden_layers + ) + self.assertEqual(len(decoder_attentions), num_decoder_layers) + + self.assertEqual( + decoder_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, decoder_input_ids.shape[-1], decoder_input_ids.shape[-1]), + ) + + cross_attentions = outputs_encoder_decoder["cross_attentions"] + self.assertEqual(len(cross_attentions), num_decoder_layers) + + cross_attention_input_seq_len = decoder_input_ids.shape[-1] * ( + 1 + (decoder_config.ngram if hasattr(decoder_config, "ngram") else 0) + ) + self.assertEqual( + cross_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, cross_attention_input_seq_len, input_ids.shape[-1]), + ) + + def check_encoder_decoder_model_generate(self, input_ids, config, decoder_config, **kwargs): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model} + enc_dec_model = FlaxEncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + + pad_token_id = enc_dec_model.config.decoder.pad_token_id + eos_token_id = enc_dec_model.config.decoder.eos_token_id + decoder_start_token_id = enc_dec_model.config.decoder.decoder_start_token_id + + # Copied from generation.utils (GPT2 doesn't have `pad_token_id`) + if pad_token_id is None and eos_token_id is not None: + pad_token_id = eos_token_id + if decoder_start_token_id is None: + decoder_start_token_id = enc_dec_model.config.decoder.bos_token_id + + # Bert does not have a bos token id, so use pad_token_id instead + # Copied from `test_modeling_encoder_decoder.py` + if decoder_start_token_id is None: + decoder_start_token_id = pad_token_id + + generated_output = enc_dec_model.generate( + input_ids, + pad_token_id=pad_token_id, + eos_token_id=eos_token_id, + decoder_start_token_id=decoder_start_token_id, + ) + generated_sequences = generated_output.sequences + self.assertEqual(generated_sequences.shape, (input_ids.shape[0],) + (decoder_config.max_length,)) + + def check_pt_flax_equivalence(self, pt_model, fx_model, inputs_dict): + pt_model.to(torch_device) + pt_model.eval() + + # prepare inputs + flax_inputs = inputs_dict + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in flax_inputs.items()} + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output, pt_output.numpy(), 1e-5) + + # PT -> Flax + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = FlaxEncoderDecoderModel.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output_loaded, pt_output in zip(fx_outputs_loaded, pt_outputs): + self.assert_almost_equals(fx_output_loaded, pt_output.numpy(), 1e-5) + + # Flax -> PT + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = EncoderDecoderModel.from_pretrained(tmpdirname, from_flax=True) + + pt_model_loaded.to(torch_device) + pt_model_loaded.eval() + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual(len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output_loaded in zip(fx_outputs, pt_outputs_loaded): + self.assert_almost_equals(fx_output, pt_output_loaded.numpy(), 1e-5) + + def check_equivalence_pt_to_flax(self, config, decoder_config, inputs_dict): + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + + pt_model = EncoderDecoderModel(encoder_decoder_config) + fx_model = FlaxEncoderDecoderModel(encoder_decoder_config) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + self.check_pt_flax_equivalence(pt_model, fx_model, inputs_dict) + + def check_equivalence_flax_to_pt(self, config, decoder_config, inputs_dict): + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + + pt_model = EncoderDecoderModel(encoder_decoder_config) + fx_model = FlaxEncoderDecoderModel(encoder_decoder_config) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + self.check_pt_flax_equivalence(pt_model, fx_model, inputs_dict) + + def test_encoder_decoder_model_from_pretrained_configs(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained_configs(**input_ids_dict) + + def test_encoder_decoder_model_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=False) + + def test_encoder_decoder_model_from_pretrained_return_dict(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=True) + + def test_save_and_load_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_save_and_load(**input_ids_dict) + + def test_encoder_decoder_model_from_encoder_decoder_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_encoder_decoder_pretrained(**input_ids_dict) + + def test_encoder_decoder_model_output_attentions(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_output_attentions(**input_ids_dict) + + def test_encoder_decoder_model_generate(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_generate(**input_ids_dict) + + def assert_almost_equals(self, a: np.ndarray, b: np.ndarray, tol: float): + diff = np.abs((a - b)).max() + self.assertLessEqual(diff, tol, f"Difference between torch and flax is {diff} (>= {tol}).") + + @is_pt_flax_cross_test + def test_pt_flax_equivalence(self): + config_inputs_dict = self.prepare_config_and_inputs() + config = config_inputs_dict.pop("config") + decoder_config = config_inputs_dict.pop("decoder_config") + + inputs_dict = config_inputs_dict + # `encoder_hidden_states` is not used in model call/forward + del inputs_dict["encoder_hidden_states"] + + # Avoid the case where a sequence has no place to attend (after combined with the causal attention mask) + batch_size = inputs_dict["decoder_attention_mask"].shape[0] + inputs_dict["decoder_attention_mask"] = np.concatenate( + [np.ones(shape=(batch_size, 1)), inputs_dict["decoder_attention_mask"][:, 1:]], axis=1 + ) + + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + decoder_config.use_cache = False + + self.assertTrue(decoder_config.cross_attention_hidden_size is None) + + # check without `enc_to_dec_proj` projection + decoder_config.hidden_size = config.hidden_size + self.assertTrue(config.hidden_size == decoder_config.hidden_size) + self.check_equivalence_pt_to_flax(config, decoder_config, inputs_dict) + self.check_equivalence_flax_to_pt(config, decoder_config, inputs_dict) + + # check `enc_to_dec_proj` work as expected + decoder_config.hidden_size = decoder_config.hidden_size * 2 + self.assertTrue(config.hidden_size != decoder_config.hidden_size) + self.check_equivalence_pt_to_flax(config, decoder_config, inputs_dict) + self.check_equivalence_flax_to_pt(config, decoder_config, inputs_dict) + + @slow + def test_real_model_save_load_from_pretrained(self): + model_2 = self.get_pretrained_model() + input_ids = ids_tensor([13, 5], model_2.config.encoder.vocab_size) + decoder_input_ids = ids_tensor([13, 1], model_2.config.encoder.vocab_size) + attention_mask = ids_tensor([13, 5], vocab_size=2) + + outputs = model_2( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_2 = np.array(outputs[0]) + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmp_dirname: + model_2.save_pretrained(tmp_dirname) + model_1 = FlaxEncoderDecoderModel.from_pretrained(tmp_dirname) + + after_outputs = model_1( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_1 = np.array(after_outputs[0]) + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + +@require_flax +class FlaxGPT2EncoderDecoderModelTest(FlaxEncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = FlaxBertModel(config) + decoder_model = FlaxGPT2LMHeadModel(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = FlaxBertModelTester(self, batch_size=13) + model_tester_decoder = FlaxGPT2ModelTester(self, batch_size=13) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + (config, input_ids, token_type_ids, attention_mask) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "encoder_hidden_states": encoder_hidden_states, + } + + def get_pretrained_model(self): + return FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "gpt2") + + @slow + def test_bert2gpt2_summarization(self): + tokenizer_in = AutoTokenizer.from_pretrained("bert-base-cased") + tokenizer_out = AutoTokenizer.from_pretrained("gpt2") + + model = FlaxEncoderDecoderModel.from_pretrained( + "patrickvonplaten/bert2gpt2-cnn_dailymail-fp16", pad_token_id=tokenizer_out.eos_token_id + ) + + ARTICLE_STUDENTS = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David Boren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 1856, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confederate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking full membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on the fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more involved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members allegedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a fraternity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloyd's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing incidents.""" + + EXPECTED_SUMMARY_STUDENTS = """SAE's national chapter suspended the students, but university president says it's permanent.\nSAE's national chapter has had to work hard to change recently.\nSAE's chapter has more than 200,000 members.\nSAE's chapter has been criticized for its hazing of new recruits.""" + + input_dict = tokenizer_in(ARTICLE_STUDENTS, return_tensors="np") + output_ids = model.generate(input_dict["input_ids"]).sequences + summary = tokenizer_out.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_STUDENTS]) + + +@require_flax +class FlaxBartEncoderDecoderModelTest(FlaxEncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = FlaxBertModel(config) + decoder_model = FlaxBartForCausalLM(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = FlaxBertModelTester(self, batch_size=13) + model_tester_decoder = FlaxBartStandaloneDecoderModelTester(self, batch_size=13) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + (config, input_ids, token_type_ids, attention_mask) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "encoder_hidden_states": encoder_hidden_states, + } + + def get_pretrained_model(self): + return FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "facebook/bart-base") + + +@require_flax +class FlaxBertEncoderDecoderModelTest(FlaxEncoderDecoderMixin, unittest.TestCase): + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = FlaxBertModel(config) + decoder_model = FlaxBertForCausalLM(decoder_config) + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + model_tester_encoder = FlaxBertModelTester(self, batch_size=13) + model_tester_decoder = FlaxBertModelTester(self, batch_size=13) + encoder_config_and_inputs = model_tester_encoder.prepare_config_and_inputs() + decoder_config_and_inputs = model_tester_decoder.prepare_config_and_inputs_for_decoder() + (config, input_ids, token_type_ids, attention_mask) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + return { + "config": config, + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "encoder_hidden_states": encoder_hidden_states, + } + + def get_pretrained_model(self): + return FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "bert-base-cased") + + +@require_flax +class FlaxEncoderDecoderModelTest(unittest.TestCase): + def get_from_encoderdecoder_pretrained_model(self): + return FlaxEncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "gpt2") + + def _check_configuration_tie(self, model): + module = model.module.bind(model.params) + + assert id(module.decoder.config) == id(model.config.decoder) + assert id(module.encoder.config) == id(model.config.encoder) + + @slow + def test_configuration_tie(self): + model = self.get_from_encoderdecoder_pretrained_model() + self._check_configuration_tie(model) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_tf_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_tf_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..76ebd687f77edf2e90181729648ed95a54ed7b2c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/encoder_decoder/test_modeling_tf_encoder_decoder.py @@ -0,0 +1,1216 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import os +import tempfile +import unittest + +import numpy as np + +from transformers import is_tf_available, is_torch_available +from transformers.testing_utils import is_pt_tf_cross_test, require_tf, require_torch, slow, torch_device +from transformers.utils.generic import ModelOutput + +from ...test_modeling_tf_common import ids_tensor +from ..bert.test_modeling_tf_bert import TFBertModelTester +from ..gpt2.test_modeling_tf_gpt2 import TFGPT2ModelTester +from ..rembert.test_modeling_tf_rembert import TFRemBertModelTester +from ..roberta.test_modeling_tf_roberta import TFRobertaModelTester + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + AutoConfig, + AutoTokenizer, + EncoderDecoderConfig, + TFAutoModel, + TFAutoModelForCausalLM, + TFBertLMHeadModel, + TFBertModel, + TFEncoderDecoderModel, + TFGPT2LMHeadModel, + TFRemBertForCausalLM, + TFRemBertModel, + TFRobertaForCausalLM, + TFRobertaModel, + ) + from transformers.modeling_tf_outputs import TFBaseModelOutput + +if is_torch_available(): + import torch + + from transformers import BertLMHeadModel, BertModel, EncoderDecoderModel + + +@require_tf +class TFEncoderDecoderMixin: + def get_encoder_decoder_model(self, config, decoder_config): + raise NotImplementedError + + def prepare_config_and_inputs(self): + raise NotImplementedError + + def get_pretrained_model(self): + raise NotImplementedError + + def check_encoder_decoder_model_from_pretrained_configs( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + self.assertTrue(encoder_decoder_config.decoder.is_decoder) + + enc_dec_model = TFEncoderDecoderModel(encoder_decoder_config) + + self.assertTrue(enc_dec_model.config.is_encoder_decoder) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + self.assertTrue(enc_dec_model.config.decoder.is_decoder) + self.assertTrue(enc_dec_model.config.decoder.add_cross_attention) + self.assertTrue(enc_dec_model.config.is_encoder_decoder) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + encoder_outputs = TFBaseModelOutput(last_hidden_state=encoder_hidden_states) + outputs_encoder_decoder = enc_dec_model( + input_ids=None, + encoder_outputs=encoder_outputs, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_encoder_decoder_model_from_pretrained( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + return_dict, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + kwargs = {"encoder_model": encoder_model, "decoder_model": decoder_model, "return_dict": return_dict} + enc_dec_model = TFEncoderDecoderModel.from_encoder_decoder_pretrained(**kwargs) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + return_dict=True, + kwargs=kwargs, + ) + + self.assertEqual( + outputs_encoder_decoder["logits"].shape, (decoder_input_ids.shape + (decoder_config.vocab_size,)) + ) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def check_save_and_load( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + + outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + out_2 = np.array(outputs[0]) + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmpdirname: + enc_dec_model.save_pretrained(tmpdirname) + enc_dec_model = TFEncoderDecoderModel.from_pretrained(tmpdirname) + + after_outputs = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + out_1 = np.array(after_outputs[0]) + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + def check_encoder_decoder_model_labels( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + labels, + **kwargs, + ): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + labels=labels, + kwargs=kwargs, + ) + + # Make sure `loss` exist + self.assertIn("loss", outputs_encoder_decoder) + + batch_size, seq_len = decoder_input_ids.shape + expected_shape = (batch_size, seq_len, decoder_config.vocab_size) + self.assertEqual(outputs_encoder_decoder["logits"].shape, expected_shape) + self.assertEqual( + outputs_encoder_decoder["encoder_last_hidden_state"].shape, (input_ids.shape + (config.hidden_size,)) + ) + + def _check_output_with_attentions( + self, outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ): + encoder_attentions = outputs_encoder_decoder["encoder_attentions"] + self.assertEqual(len(encoder_attentions), config.num_hidden_layers) + + self.assertEqual( + encoder_attentions[0].shape[-3:], (config.num_attention_heads, input_ids.shape[-1], input_ids.shape[-1]) + ) + + decoder_attentions = outputs_encoder_decoder["decoder_attentions"] + num_decoder_layers = ( + decoder_config.num_decoder_layers + if hasattr(decoder_config, "num_decoder_layers") + else decoder_config.num_hidden_layers + ) + self.assertEqual(len(decoder_attentions), num_decoder_layers) + + self.assertEqual( + decoder_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, decoder_input_ids.shape[-1], decoder_input_ids.shape[-1]), + ) + + cross_attentions = outputs_encoder_decoder["cross_attentions"] + self.assertEqual(len(cross_attentions), num_decoder_layers) + + cross_attention_input_seq_len = decoder_input_ids.shape[-1] * ( + 1 + (decoder_config.ngram if hasattr(decoder_config, "ngram") else 0) + ) + self.assertEqual( + cross_attentions[0].shape[-3:], + (decoder_config.num_attention_heads, cross_attention_input_seq_len, input_ids.shape[-1]), + ) + + def check_encoder_decoder_model_output_attentions( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + # make the decoder inputs a different shape from the encoder inputs to harden the test + decoder_input_ids = decoder_input_ids[:, :-1] + decoder_attention_mask = decoder_attention_mask[:, :-1] + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + output_attentions=True, + kwargs=kwargs, + ) + self._check_output_with_attentions( + outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ) + + def check_encoder_decoder_model_output_attentions_from_config( + self, + config, + input_ids, + attention_mask, + encoder_hidden_states, + decoder_config, + decoder_input_ids, + decoder_attention_mask, + **kwargs, + ): + # Similar to `check_encoder_decoder_model_output_attentions`, but with `output_attentions` triggered from the + # config file. Contrarily to most models, changing the model's config won't work -- the defaults are loaded + # from the inner models' configurations. + + decoder_input_ids = decoder_input_ids[:, :-1] + decoder_attention_mask = decoder_attention_mask[:, :-1] + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + enc_dec_model.config.output_attentions = True # model config -> won't work + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + self.assertTrue( + all( + key not in outputs_encoder_decoder + for key in ["encoder_attentions", "decoder_attentions", "cross_attentions"] + ) + ) + + config.output_attentions = True # inner model config -> will work + decoder_config.output_attentions = True + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + outputs_encoder_decoder = enc_dec_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + kwargs=kwargs, + ) + self._check_output_with_attentions( + outputs_encoder_decoder, config, input_ids, decoder_config, decoder_input_ids + ) + + def check_encoder_decoder_model_generate(self, input_ids, config, decoder_config, **kwargs): + encoder_model, decoder_model = self.get_encoder_decoder_model(config, decoder_config) + enc_dec_model = TFEncoderDecoderModel(encoder=encoder_model, decoder=decoder_model) + + # Generate until max length + if hasattr(enc_dec_model.config, "eos_token_id"): + enc_dec_model.config.eos_token_id = None + if hasattr(enc_dec_model.config, "decoder") and hasattr(enc_dec_model.config.decoder, "eos_token_id"): + enc_dec_model.config.decoder.eos_token_id = None + + # Bert does not have a bos token id, so use pad_token_id instead + generated_output = enc_dec_model.generate( + input_ids, decoder_start_token_id=enc_dec_model.config.decoder.pad_token_id + ) + self.assertEqual(tuple(generated_output.shape.as_list()), (input_ids.shape[0],) + (decoder_config.max_length,)) + + def check_pt_tf_outputs(self, tf_outputs, pt_outputs, model_class, tol=1e-5, name="outputs", attributes=None): + """Check the outputs from PyTorch and TensorFlow models are close enough. Checks are done in a recursive way. + + Args: + model_class: The class of the model that is currently testing. For example, `TFBertModel`, + TFBertForMaskedLM`, `TFBertForSequenceClassification`, etc. Mainly used for providing more informative + error messages. + name (`str`): The name of the output. For example, `output.hidden_states`, `output.attentions`, etc. + attributes (`Tuple[str]`): The names of the output's element if the output is a tuple/list with each element + being a named field in the output. + """ + + self.assertEqual(type(name), str) + if attributes is not None: + self.assertEqual(type(attributes), tuple, f"{name}: The argument `attributes` should be a `tuple`") + + # Allow `ModelOutput` (e.g. `CLIPOutput` has `text_model_output` and `vision_model_output`). + if isinstance(tf_outputs, ModelOutput): + self.assertTrue( + isinstance(pt_outputs, ModelOutput), + f"{name}: `pt_outputs` should an instance of `ModelOutput` when `tf_outputs` is", + ) + + tf_keys = [k for k, v in tf_outputs.items() if v is not None] + pt_keys = [k for k, v in pt_outputs.items() if v is not None] + + self.assertEqual(tf_keys, pt_keys, f"{name}: Output keys differ between TF and PyTorch") + + # convert to the case of `tuple` + # appending each key to the current (string) `names` + attributes = tuple([f"{name}.{k}" for k in tf_keys]) + self.check_pt_tf_outputs( + tf_outputs.to_tuple(), pt_outputs.to_tuple(), model_class, tol=tol, name=name, attributes=attributes + ) + + # Allow `list` (e.g. `TransfoXLModelOutput.mems` is a list of tensors.) + elif type(tf_outputs) in [tuple, list]: + self.assertEqual(type(tf_outputs), type(pt_outputs), f"{name}: Output types differ between TF and PyTorch") + self.assertEqual(len(tf_outputs), len(pt_outputs), f"{name}: Output lengths differ between TF and PyTorch") + + if attributes is not None: + # case 1: each output has assigned name (e.g. a tuple form of a `ModelOutput`) + self.assertEqual( + len(attributes), + len(tf_outputs), + f"{name}: The tuple `names` should have the same length as `tf_outputs`", + ) + else: + # case 2: each output has no assigned name (e.g. hidden states of each layer) -> add an index to `names` + attributes = tuple([f"{name}_{idx}" for idx in range(len(tf_outputs))]) + + for tf_output, pt_output, attr in zip(tf_outputs, pt_outputs, attributes): + self.check_pt_tf_outputs(tf_output, pt_output, model_class, tol=tol, name=attr) + + elif isinstance(tf_outputs, tf.Tensor): + self.assertTrue( + isinstance(pt_outputs, torch.Tensor), f"{name}: `pt_outputs` should a tensor when `tf_outputs` is" + ) + + tf_outputs = tf_outputs.numpy() + pt_outputs = pt_outputs.detach().to("cpu").numpy() + + self.assertEqual( + tf_outputs.shape, pt_outputs.shape, f"{name}: Output shapes differ between TF and PyTorch" + ) + + # deal with NumPy's scalars to make replacing nan values by 0 work. + if np.isscalar(tf_outputs): + tf_outputs = np.array([tf_outputs]) + pt_outputs = np.array([pt_outputs]) + + tf_nans = np.isnan(tf_outputs) + pt_nans = np.isnan(pt_outputs) + + pt_outputs[tf_nans] = 0 + tf_outputs[tf_nans] = 0 + pt_outputs[pt_nans] = 0 + tf_outputs[pt_nans] = 0 + + max_diff = np.amax(np.abs(tf_outputs - pt_outputs)) + self.assertLessEqual(max_diff, tol, f"{name}: Difference between torch and tf is {max_diff} (>= {tol}).") + else: + raise ValueError( + "`tf_outputs` should be an instance of `tf.Tensor`, a `tuple`, or an instance of `tf.Tensor`. Got" + f" {type(tf_outputs)} instead." + ) + + def prepare_pt_inputs_from_tf_inputs(self, tf_inputs_dict): + pt_inputs_dict = {} + for name, key in tf_inputs_dict.items(): + if type(key) == bool: + pt_inputs_dict[name] = key + elif name == "input_values": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + elif name == "pixel_values": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + elif name == "input_features": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + # other general float inputs + elif tf_inputs_dict[name].dtype.is_floating: + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + else: + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.long) + + return pt_inputs_dict + + def check_pt_tf_models(self, tf_model, pt_model, tf_inputs_dict): + pt_inputs_dict = self.prepare_pt_inputs_from_tf_inputs(tf_inputs_dict) + + # send pytorch inputs to the correct device + pt_inputs_dict = { + k: v.to(device=torch_device) if isinstance(v, torch.Tensor) else v for k, v in pt_inputs_dict.items() + } + + # send pytorch model to the correct device + pt_model.to(torch_device) + + # Check predictions on first output (logits/hidden-states) are close enough given low-level computational differences + pt_model.eval() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs_dict) + tf_outputs = tf_model(tf_inputs_dict) + + # tf models returned loss is usually a tensor rather than a scalar. + # (see `hf_compute_loss`: it uses `tf.keras.losses.Reduction.NONE`) + # Change it here to a scalar to match PyTorch models' loss + tf_loss = getattr(tf_outputs, "loss", None) + if tf_loss is not None: + tf_outputs.loss = tf.math.reduce_mean(tf_loss) + + self.check_pt_tf_outputs(tf_outputs, pt_outputs, type(tf_model)) + + def check_pt_tf_equivalence(self, tf_model, pt_model, tf_inputs_dict): + """Wrap `check_pt_tf_models` to further check PT -> TF again""" + + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + # PT -> TF + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + tf_model = TFEncoderDecoderModel.from_pretrained(tmpdirname, from_pt=True) + + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + def check_pt_to_tf_equivalence(self, config, decoder_config, tf_inputs_dict): + """EncoderDecoderModel requires special way to cross load (PT -> TF)""" + + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + # Output all for aggressive testing + encoder_decoder_config.output_hidden_states = True + # All models tested in this file have attentions + encoder_decoder_config.output_attentions = True + + pt_model = EncoderDecoderModel(encoder_decoder_config) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + tf_model = TFEncoderDecoderModel.from_pretrained(tmpdirname, from_pt=True) + + self.check_pt_tf_equivalence(tf_model, pt_model, tf_inputs_dict) + + def check_tf_to_pt_equivalence(self, config, decoder_config, tf_inputs_dict): + """EncoderDecoderModel requires special way to cross load (TF -> PT)""" + + encoder_decoder_config = EncoderDecoderConfig.from_encoder_decoder_configs(config, decoder_config) + # Output all for aggressive testing + encoder_decoder_config.output_hidden_states = True + # TODO: A generalizable way to determine this attribute + encoder_decoder_config.output_attentions = True + + tf_model = TFEncoderDecoderModel(encoder_decoder_config) + # Make sure model is built before saving + tf_model(**tf_inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + tf_model.save_pretrained(tmpdirname) + pt_model = EncoderDecoderModel.from_pretrained(tmpdirname, from_tf=True) + + self.check_pt_tf_equivalence(tf_model, pt_model, tf_inputs_dict) + + def test_encoder_decoder_model(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model(**input_ids_dict) + + def test_encoder_decoder_model_from_pretrained_configs(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained_configs(**input_ids_dict) + + def test_encoder_decoder_model_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=False) + + def test_encoder_decoder_model_from_pretrained_return_dict(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_from_pretrained(**input_ids_dict, return_dict=True) + + def test_save_and_load_from_pretrained(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_save_and_load(**input_ids_dict) + + def test_encoder_decoder_model_labels(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_labels(**input_ids_dict) + + def test_encoder_decoder_model_output_attentions(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_output_attentions(**input_ids_dict) + + def test_encoder_decoder_model_output_attentions_from_config(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_output_attentions_from_config(**input_ids_dict) + + def test_encoder_decoder_model_generate(self): + input_ids_dict = self.prepare_config_and_inputs() + self.check_encoder_decoder_model_generate(**input_ids_dict) + + def assert_almost_equals(self, a: np.ndarray, b: np.ndarray, tol: float): + diff = np.abs((a - b)).max() + self.assertLessEqual(diff, tol, f"Difference between torch and tf is {diff} (>= {tol}).") + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self): + config_inputs_dict = self.prepare_config_and_inputs() + labels = config_inputs_dict.pop("decoder_token_labels") + + # Keep only common arguments + arg_names = [ + "config", + "input_ids", + "attention_mask", + "decoder_config", + "decoder_input_ids", + "decoder_attention_mask", + "encoder_hidden_states", + ] + config_inputs_dict = {k: v for k, v in config_inputs_dict.items() if k in arg_names} + + config = config_inputs_dict.pop("config") + decoder_config = config_inputs_dict.pop("decoder_config") + + # Output all for aggressive testing + config.output_hidden_states = True + decoder_config.output_hidden_states = True + # All models tested in this file have attentions + config.output_attentions = True + decoder_config.output_attentions = True + + tf_inputs_dict = config_inputs_dict + # `encoder_hidden_states` is not used in model call/forward + del tf_inputs_dict["encoder_hidden_states"] + + # Make sure no sequence has all zeros as attention mask, otherwise some tests fail due to the inconsistency + # of the usage `1e-4`, `1e-9`, `1e-30`, `-inf`. + for k in ["attention_mask", "decoder_attention_mask"]: + attention_mask = tf_inputs_dict[k] + + # Make sure no all 0s attention masks - to avoid failure at this moment. + # Put `1` at the beginning of sequences to make it still work when combining causal attention masks. + # TODO: remove this line once a fix regarding large negative values for attention mask is done. + attention_mask = tf.concat( + [tf.ones_like(attention_mask[:, :1], dtype=attention_mask.dtype), attention_mask[:, 1:]], axis=-1 + ) + tf_inputs_dict[k] = attention_mask + + tf_inputs_dict_with_labels = copy.copy(tf_inputs_dict) + tf_inputs_dict_with_labels["labels"] = labels + + self.assertTrue(decoder_config.cross_attention_hidden_size is None) + + # Original test: check without `labels` and without `enc_to_dec_proj` projection + self.assertTrue(config.hidden_size == decoder_config.hidden_size) + self.check_pt_to_tf_equivalence(config, decoder_config, tf_inputs_dict) + self.check_tf_to_pt_equivalence(config, decoder_config, tf_inputs_dict) + + # check with `labels` + self.check_pt_to_tf_equivalence(config, decoder_config, tf_inputs_dict_with_labels) + self.check_tf_to_pt_equivalence(config, decoder_config, tf_inputs_dict_with_labels) + + # check `enc_to_dec_proj` work as expected + decoder_config.hidden_size = decoder_config.hidden_size * 2 + self.assertTrue(config.hidden_size != decoder_config.hidden_size) + self.check_pt_to_tf_equivalence(config, decoder_config, tf_inputs_dict) + self.check_tf_to_pt_equivalence(config, decoder_config, tf_inputs_dict) + + def test_model_save_load_from_pretrained(self): + model_2 = self.get_pretrained_model() + input_ids = ids_tensor([13, 5], model_2.config.encoder.vocab_size) + decoder_input_ids = ids_tensor([13, 1], model_2.config.decoder.vocab_size) + attention_mask = ids_tensor([13, 5], vocab_size=2) + + outputs = model_2( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_2 = np.array(outputs[0]) + out_2[np.isnan(out_2)] = 0 + + with tempfile.TemporaryDirectory() as tmp_dirname: + model_2.save_pretrained(tmp_dirname) + model_1 = TFEncoderDecoderModel.from_pretrained(tmp_dirname) + + after_outputs = model_1( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + ) + out_1 = np.array(after_outputs[0]) + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + +@require_tf +class TFBertEncoderDecoderModelTest(TFEncoderDecoderMixin, unittest.TestCase): + def setUp(self): + self.encoder_model_tester = TFBertModelTester(self, batch_size=13) + self.decoder_model_tester = TFBertModelTester(self, batch_size=13) + + def get_pretrained_model(self): + return TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "hf-internal-testing/tiny-random-bert", + "hf-internal-testing/tiny-random-bert", + ) + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = TFBertModel(config, name="encoder") + decoder_model = TFBertLMHeadModel(decoder_config, name="decoder") + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + encoder_config_and_inputs = self.encoder_model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = self.decoder_model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + attention_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_token_type_ids, + decoder_attention_mask, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_attention_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + @slow + @is_pt_tf_cross_test + def test_bert2bert_summarization(self): + from transformers import EncoderDecoderModel + + tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") + + """Not working, because pt checkpoint has `encoder.encoder.layer...` while tf model has `encoder.bert.encoder.layer...`. + (For Bert decoder, there is no issue, because `BertModel` is wrapped into `decoder` as `bert`) + model = TFEncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16", from_pt=True) + """ + + # workaround to load from pt + _model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") + _model.encoder.save_pretrained("./encoder") + _model.decoder.save_pretrained("./decoder") + model = TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "./encoder", "./decoder", encoder_from_pt=True, decoder_from_pt=True + ) + model.config = _model.config + + ARTICLE_STUDENTS = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David Boren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 1856, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confederate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking full membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on the fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more involved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members allegedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a fraternity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloyd's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing incidents.""" + EXPECTED_SUMMARY_STUDENTS = """sae was founded in 1856, five years before the civil war. the fraternity has had to work hard to change recently. the university of oklahoma president says the university's affiliation with the fraternity is permanently done. the sae has had a string of members in recent months.""" + + input_dict = tokenizer(ARTICLE_STUDENTS, return_tensors="tf") + output_ids = model.generate(input_ids=input_dict["input_ids"]).numpy().tolist() + summary = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_STUDENTS]) + + # Test with the TF checkpoint + model = TFEncoderDecoderModel.from_pretrained("ydshieh/bert2bert-cnn_dailymail-fp16") + + output_ids = model.generate(input_ids=input_dict["input_ids"]).numpy().tolist() + summary = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_STUDENTS]) + + +@require_tf +class TFGPT2EncoderDecoderModelTest(TFEncoderDecoderMixin, unittest.TestCase): + def setUp(self): + self.encoder_model_tester = TFBertModelTester(self, batch_size=13) + self.decoder_model_tester = TFGPT2ModelTester(self) + + def get_pretrained_model(self): + return TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "hf-internal-testing/tiny-random-bert", + "hf-internal-testing/tiny-random-gpt2", + ) + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = TFBertModel(config, name="encoder") + decoder_model = TFGPT2LMHeadModel(decoder_config, name="decoder") + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + encoder_config_and_inputs = self.encoder_model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = self.decoder_model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + attention_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_attention_mask, + decoder_head_mask, + decoder_token_type_ids, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_attention_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + @slow + @is_pt_tf_cross_test + def test_bert2gpt2_summarization(self): + from transformers import EncoderDecoderModel + + tokenizer_in = AutoTokenizer.from_pretrained("bert-base-cased") + tokenizer_out = AutoTokenizer.from_pretrained("gpt2") + + """Not working, because pt checkpoint has `encoder.encoder.layer...` while tf model has `encoder.bert.encoder.layer...`. + (For GPT2 decoder, there is no issue) + model = TFEncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16", from_pt=True) + """ + + # workaround to load from pt + _model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16") + _model.encoder.save_pretrained("./encoder") + _model.decoder.save_pretrained("./decoder") + model = TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "./encoder", "./decoder", encoder_from_pt=True, decoder_from_pt=True + ) + model.config = _model.config + + ARTICLE_STUDENTS = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David Boren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 1856, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confederate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking full membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on the fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more involved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members allegedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a fraternity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloyd's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing incidents.""" + EXPECTED_SUMMARY_STUDENTS = """SAS Alpha Epsilon suspended the students, but university president says it's permanent.\nThe fraternity has had to deal with a string of student deaths since 2010.\nSAS has more than 200,000 members, many of whom are students.\nA student died while being forced into excessive alcohol consumption.""" + + input_dict = tokenizer_in(ARTICLE_STUDENTS, return_tensors="tf") + output_ids = model.generate(input_ids=input_dict["input_ids"]).numpy().tolist() + summary = tokenizer_out.batch_decode(output_ids, skip_special_tokens=True) + + self.assertEqual(summary, [EXPECTED_SUMMARY_STUDENTS]) + + +@require_tf +class TFRoBertaEncoderDecoderModelTest(TFEncoderDecoderMixin, unittest.TestCase): + def setUp(self): + self.encoder_model_tester = TFRobertaModelTester(self) + self.decoder_model_tester = TFRobertaModelTester(self) + + def get_pretrained_model(self): + return TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "hf-internal-testing/tiny-random-roberta", + "hf-internal-testing/tiny-random-roberta", + ) + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = TFRobertaModel(config, name="encoder") + decoder_model = TFRobertaForCausalLM(decoder_config, name="decoder") + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + encoder_config_and_inputs = self.encoder_model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = self.decoder_model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_token_type_ids, + decoder_input_mask, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + +@require_tf +class TFRembertEncoderDecoderModelTest(TFEncoderDecoderMixin, unittest.TestCase): + def setUp(self): + self.encoder_model_tester = TFRemBertModelTester(self) + self.decoder_model_tester = TFRemBertModelTester(self) + + def get_pretrained_model(self): + return TFEncoderDecoderModel.from_encoder_decoder_pretrained( + "hf-internal-testing/tiny-random-rembert", + "hf-internal-testing/tiny-random-rembert", + ) + + def get_encoder_decoder_model(self, config, decoder_config): + encoder_model = TFRemBertModel(config, name="encoder") + decoder_model = TFRemBertForCausalLM(decoder_config, name="decoder") + return encoder_model, decoder_model + + def prepare_config_and_inputs(self): + encoder_config_and_inputs = self.encoder_model_tester.prepare_config_and_inputs() + decoder_config_and_inputs = self.decoder_model_tester.prepare_config_and_inputs_for_decoder() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = encoder_config_and_inputs + ( + decoder_config, + decoder_input_ids, + decoder_token_type_ids, + decoder_input_mask, + decoder_sequence_labels, + decoder_token_labels, + decoder_choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = decoder_config_and_inputs + + # make sure that cross attention layers are added + decoder_config.add_cross_attention = True + # disable cache for now + decoder_config.use_cache = False + return { + "config": config, + "input_ids": input_ids, + "attention_mask": input_mask, + "decoder_config": decoder_config, + "decoder_input_ids": decoder_input_ids, + "decoder_token_type_ids": decoder_token_type_ids, + "decoder_attention_mask": decoder_input_mask, + "decoder_sequence_labels": decoder_sequence_labels, + "decoder_token_labels": decoder_token_labels, + "decoder_choice_labels": decoder_choice_labels, + "encoder_hidden_states": encoder_hidden_states, + "labels": decoder_token_labels, + } + + +@require_tf +class TFEncoderDecoderModelTest(unittest.TestCase): + def get_from_encoderdecoder_pretrained_model(self): + return TFEncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "bert-base-cased") + + def get_decoder_config(self): + config = AutoConfig.from_pretrained("bert-base-cased") + config.is_decoder = True + config.add_cross_attention = True + return config + + def get_encoderdecoder_model(self): + return TFEncoderDecoderModel.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16") + + def get_encoder_decoder_models(self): + encoder_model = TFBertModel.from_pretrained("bert-base-cased", name="encoder") + decoder_model = TFBertLMHeadModel.from_pretrained( + "bert-base-cased", config=self.get_decoder_config(), name="decoder" + ) + return {"encoder": encoder_model, "decoder": decoder_model} + + def _check_configuration_tie(self, model): + assert id(model.decoder.config) == id(model.config.decoder) + assert id(model.encoder.config) == id(model.config.encoder) + + @slow + def test_configuration_tie(self): + model = self.get_from_encoderdecoder_pretrained_model() + self._check_configuration_tie(model) + + model = TFEncoderDecoderModel(**self.get_encoder_decoder_models()) + self._check_configuration_tie(model) + + # # This should be enabled once we upload the TF version of + # # "patrickvonplaten/bert2bert-cnn_dailymail-fp16" to the Hub. + # model = self.get_encoderdecoder_model() + # self._check_configuration_tie(model) + + +@require_tf +class TFEncoderDecoderModelSaveLoadTests(unittest.TestCase): + def get_encoder_decoder_config(self): + encoder_config = AutoConfig.from_pretrained("bert-base-uncased") + decoder_config = AutoConfig.from_pretrained("bert-base-uncased", is_decoder=True, add_cross_attention=True) + return EncoderDecoderConfig.from_encoder_decoder_configs(encoder_config, decoder_config) + + def get_encoder_decoder_config_small(self): + encoder_config = AutoConfig.from_pretrained("hf-internal-testing/tiny-bert") + decoder_config = AutoConfig.from_pretrained( + "hf-internal-testing/tiny-bert", is_decoder=True, add_cross_attention=True + ) + return EncoderDecoderConfig.from_encoder_decoder_configs(encoder_config, decoder_config) + + def test_encoder_decoder_save_load_from_encoder_decoder(self): + config = self.get_encoder_decoder_config_small() + + # create two random BERT models for bert2bert & initialize weights (+cross_attention weights) + encoder = TFBertModel(config.encoder) + encoder(encoder.dummy_inputs) + decoder = TFBertLMHeadModel(config.decoder) + decoder(decoder.dummy_inputs) + + encoder_decoder_orig = TFEncoderDecoderModel(encoder=encoder, decoder=decoder) + + input_ids = ids_tensor([13, 5], encoder.config.vocab_size) + decoder_input_ids = ids_tensor([13, 1], decoder.config.vocab_size) + + logits_orig = encoder_decoder_orig(input_ids=input_ids, decoder_input_ids=decoder_input_ids).logits + + with tempfile.TemporaryDirectory() as tmp_dirname: + encoder_path = os.path.join(tmp_dirname, "encoder") + decoder_path = os.path.join(tmp_dirname, "decoder") + + encoder.save_pretrained(encoder_path) + decoder.save_pretrained(decoder_path) + + encoder_decoder = TFEncoderDecoderModel.from_encoder_decoder_pretrained(encoder_path, decoder_path) + + logits_1 = encoder_decoder(input_ids=input_ids, decoder_input_ids=decoder_input_ids).logits + + self.assertTrue(logits_orig.numpy().sum() - logits_1.numpy().sum() < 1e-3) + + max_diff = np.max(np.abs(logits_1.numpy() - logits_orig.numpy())) + self.assertAlmostEqual(max_diff, 0.0, places=4) + + with tempfile.TemporaryDirectory() as tmp_dirname: + encoder_decoder.save_pretrained(tmp_dirname) + encoder_decoder = TFEncoderDecoderModel.from_pretrained(tmp_dirname) + + logits_2 = encoder_decoder(input_ids=input_ids, decoder_input_ids=decoder_input_ids).logits + + max_diff = np.max(np.abs(logits_2.numpy() - logits_orig.numpy())) + self.assertAlmostEqual(max_diff, 0.0, places=4) + + @require_torch + @is_pt_tf_cross_test + def test_encoder_decoder_save_load_from_encoder_decoder_from_pt(self): + config = self.get_encoder_decoder_config_small() + + # create two random BERT models for bert2bert & initialize weights (+cross_attention weights) + encoder_pt = BertModel(config.encoder).to(torch_device).eval() + decoder_pt = BertLMHeadModel(config.decoder).to(torch_device).eval() + + encoder_decoder_pt = EncoderDecoderModel(encoder=encoder_pt, decoder=decoder_pt).to(torch_device).eval() + + input_ids = ids_tensor([13, 5], encoder_pt.config.vocab_size) + decoder_input_ids = ids_tensor([13, 1], decoder_pt.config.vocab_size) + + pt_input_ids = torch.tensor(input_ids.numpy(), device=torch_device, dtype=torch.long) + pt_decoder_input_ids = torch.tensor(decoder_input_ids.numpy(), device=torch_device, dtype=torch.long) + + logits_pt = encoder_decoder_pt(input_ids=pt_input_ids, decoder_input_ids=pt_decoder_input_ids).logits + + # PyTorch => TensorFlow + with tempfile.TemporaryDirectory() as tmp_dirname_1, tempfile.TemporaryDirectory() as tmp_dirname_2: + encoder_decoder_pt.encoder.save_pretrained(tmp_dirname_1) + encoder_decoder_pt.decoder.save_pretrained(tmp_dirname_2) + encoder_decoder_tf = TFEncoderDecoderModel.from_encoder_decoder_pretrained( + tmp_dirname_1, tmp_dirname_2, encoder_from_pt=True, decoder_from_pt=True + ) + + logits_tf = encoder_decoder_tf(input_ids=input_ids, decoder_input_ids=decoder_input_ids).logits + + max_diff = np.max(np.abs(logits_pt.detach().cpu().numpy() - logits_tf.numpy())) + self.assertAlmostEqual(max_diff, 0.0, places=3) + + # Make sure `from_pretrained` following `save_pretrained` work and give the same result + with tempfile.TemporaryDirectory() as tmp_dirname: + encoder_decoder_tf.save_pretrained(tmp_dirname) + encoder_decoder_tf = TFEncoderDecoderModel.from_pretrained(tmp_dirname) + + logits_tf_2 = encoder_decoder_tf(input_ids=input_ids, decoder_input_ids=decoder_input_ids).logits + + max_diff = np.max(np.abs(logits_tf_2.numpy() - logits_tf.numpy())) + self.assertAlmostEqual(max_diff, 0.0, places=3) + + # TensorFlow => PyTorch + with tempfile.TemporaryDirectory() as tmp_dirname: + encoder_decoder_tf.save_pretrained(tmp_dirname) + encoder_decoder_pt = EncoderDecoderModel.from_pretrained(tmp_dirname, from_tf=True) + + max_diff = np.max(np.abs(logits_pt.detach().cpu().numpy() - logits_tf.numpy())) + self.assertAlmostEqual(max_diff, 0.0, places=3) + + @slow + def test_encoder_decoder_from_pretrained(self): + load_weight_prefix = TFEncoderDecoderModel.load_weight_prefix + + config = self.get_encoder_decoder_config() + encoder_tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") + decoder_tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") + + input_ids = encoder_tokenizer("who sings does he love me with reba", return_tensors="tf").input_ids + decoder_input_ids = decoder_tokenizer("Linda Davis", return_tensors="tf").input_ids + + with tempfile.TemporaryDirectory() as tmp_dirname: + # Since most of HF's models don't have pretrained cross-attention layers, they are randomly + # initialized even if we create models using `from_pretrained` method. + # For the tests, the decoder need to be a model with pretrained cross-attention layers. + # So we create pretrained models (without `load_weight_prefix`), save them, and later, + # we load them using `from_pretrained`. + # (we don't need to do this for encoder, but let's make the code more similar between encoder/decoder) + encoder = TFAutoModel.from_pretrained("bert-base-uncased", name="encoder") + # It's necessary to specify `add_cross_attention=True` here. + decoder = TFAutoModelForCausalLM.from_pretrained( + "bert-base-uncased", is_decoder=True, add_cross_attention=True, name="decoder" + ) + pretrained_encoder_dir = os.path.join(tmp_dirname, "pretrained_encoder") + pretrained_decoder_dir = os.path.join(tmp_dirname, "pretrained_decoder") + encoder.save_pretrained(pretrained_encoder_dir) + decoder.save_pretrained(pretrained_decoder_dir) + del encoder + del decoder + + enc_dec_model = TFEncoderDecoderModel.from_encoder_decoder_pretrained( + pretrained_encoder_dir, + pretrained_decoder_dir, + ) + # check that the from pretrained methods work + enc_dec_model.save_pretrained(tmp_dirname) + enc_dec_model = TFEncoderDecoderModel.from_pretrained(tmp_dirname) + + output = enc_dec_model(input_ids, decoder_input_ids=decoder_input_ids, labels=decoder_input_ids) + + loss_pretrained = output.loss + del enc_dec_model + + # Create the model using `__init__` with loaded ``pretrained`` encoder / decoder + encoder = TFAutoModel.from_pretrained( + pretrained_encoder_dir, load_weight_prefix=load_weight_prefix, name="encoder" + ) + decoder = TFAutoModelForCausalLM.from_pretrained( + pretrained_decoder_dir, load_weight_prefix=load_weight_prefix, name="decoder" + ) + enc_dec_model = TFEncoderDecoderModel(config=config, encoder=encoder, decoder=decoder) + + output = enc_dec_model(input_ids, decoder_input_ids=decoder_input_ids, labels=decoder_input_ids) + + loss_init = output.loss + + max_diff = np.max(np.abs(loss_pretrained - loss_init)) + expected_diff = 0.0 + + self.assertAlmostEqual(max_diff, expected_diff, places=4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie/test_modeling_ernie.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie/test_modeling_ernie.py new file mode 100644 index 0000000000000000000000000000000000000000..e845bd1f83cf0462e9978e6468ae4fa8cbb58afe --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie/test_modeling_ernie.py @@ -0,0 +1,596 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import tempfile +import unittest + +from transformers import ErnieConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_torch_gpu, 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 ( + MODEL_FOR_PRETRAINING_MAPPING, + ErnieForCausalLM, + ErnieForMaskedLM, + ErnieForMultipleChoice, + ErnieForNextSentencePrediction, + ErnieForPreTraining, + ErnieForQuestionAnswering, + ErnieForSequenceClassification, + ErnieForTokenClassification, + ErnieModel, + ) + from transformers.models.ernie.modeling_ernie import ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST + + +class ErnieModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + """ + Returns a tiny configuration by default. + """ + return ErnieConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = ErnieModel(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_causal_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + model = ErnieForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_model_for_causal_lm_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = ErnieForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + encoder_hidden_states=encoder_hidden_states, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.is_decoder = True + config.add_cross_attention = True + model = ErnieForCausalLM(config=config).to(torch_device).eval() + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + )["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_for_next_sequence_prediction( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieForNextSentencePrediction(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=sequence_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, 2)) + + def create_and_check_for_pretraining( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + next_sentence_label=sequence_labels, + ) + self.parent.assertEqual(result.prediction_logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + self.parent.assertEqual(result.seq_relationship_logits.shape, (self.batch_size, 2)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ErnieForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ErnieForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = ErnieForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class ErnieModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + ErnieModel, + ErnieForCausalLM, + ErnieForMaskedLM, + ErnieForMultipleChoice, + ErnieForNextSentencePrediction, + ErnieForPreTraining, + ErnieForQuestionAnswering, + ErnieForSequenceClassification, + ErnieForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (ErnieForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": ErnieModel, + "fill-mask": ErnieForMaskedLM, + "question-answering": ErnieForQuestionAnswering, + "text-classification": ErnieForSequenceClassification, + "text-generation": ErnieForCausalLM, + "token-classification": ErnieForTokenClassification, + "zero-shot": ErnieForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = False + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + inputs_dict["next_sentence_label"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = ErnieModelTester(self) + self.config_tester = ConfigTester(self, config_class=ErnieConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_as_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def test_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_causal_lm_decoder(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_for_causal_lm_as_decoder(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_decoder_model_past_with_large_inputs_relative_pos_emb(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + config_and_inputs[0].position_embedding_type = "relative_key" + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_next_sequence_prediction(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_next_sequence_prediction(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ErnieModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + @require_torch_gpu + def test_torchscript_device_change(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # ErnieForMultipleChoice behaves incorrectly in JIT environments. + if model_class == ErnieForMultipleChoice: + return + + config.torchscript = True + model = model_class(config=config) + + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + traced_model = torch.jit.trace( + model, (inputs_dict["input_ids"].to("cpu"), inputs_dict["attention_mask"].to("cpu")) + ) + + with tempfile.TemporaryDirectory() as tmp: + torch.jit.save(traced_model, os.path.join(tmp, "ernie.pt")) + loaded = torch.jit.load(os.path.join(tmp, "ernie.pt"), map_location=torch_device) + loaded(inputs_dict["input_ids"].to(torch_device), inputs_dict["attention_mask"].to(torch_device)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_modeling_ernie_m.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_modeling_ernie_m.py new file mode 100644 index 0000000000000000000000000000000000000000..5e0ac95233d980fee42cab0436f0187adba8eabd --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_modeling_ernie_m.py @@ -0,0 +1,325 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. and Baidu team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ErnieM model. """ + + +import unittest + +from transformers import ErnieMConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + ErnieMForInformationExtraction, + ErnieMForMultipleChoice, + ErnieMForQuestionAnswering, + ErnieMForSequenceClassification, + ErnieMForTokenClassification, + ErnieMModel, + ) + from transformers.models.ernie_m.modeling_ernie_m import ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST + + +class ErnieMModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def prepare_config_and_inputs_for_uiem(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return ErnieMConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels): + model = ErnieMModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, return_dict=True) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_question_answering( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieMForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_information_extraction( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = ErnieMForInformationExtraction(config=config) + model.to(torch_device) + model.eval() + sequence_labels = torch.ones_like(input_ids, dtype=torch.float32) + result = model( + input_ids, + attention_mask=input_mask, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ErnieMForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = ErnieMForTokenClassification(config=config) + model.to(torch_device) + model.eval() + input_ids.to(torch_device) + input_mask.to(torch_device) + token_labels.to(torch_device) + + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = ErnieMForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class ErnieMModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + ErnieMModel, + ErnieMForMultipleChoice, + ErnieMForQuestionAnswering, + ErnieMForSequenceClassification, + ErnieMForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = () + pipeline_model_mapping = ( + { + "feature-extraction": ErnieMModel, + "question-answering": ErnieMForQuestionAnswering, + "text-classification": ErnieMForSequenceClassification, + "token-classification": ErnieMForTokenClassification, + "zero-shot": ErnieMForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_torchscript = False + + # TODO: Fix the failed tests when this model gets more usage + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "QAPipelineTests": + return True + + return False + + def setUp(self): + self.model_tester = ErnieMModelTester(self) + self.config_tester = ConfigTester(self, config_class=ErnieMConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_information_extraction(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_information_extraction(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ErnieMModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class ErnieMModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_model(self): + model = ErnieMModel.from_pretrained("susnato/ernie-m-base_pytorch") + model.eval() + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + # TODO Replace vocab size + hidden_size = 768 + + expected_shape = torch.Size((1, 6, hidden_size)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[[-0.0012, 0.1245, -0.0214], [-0.0742, 0.0244, -0.0771], [-0.0333, 0.1164, -0.1554]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-3)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_tokenization_ernie_m.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_tokenization_ernie_m.py new file mode 100644 index 0000000000000000000000000000000000000000..2e06bb20c10cf262dd3d5c4a844596a14e74e0f2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ernie_m/test_tokenization_ernie_m.py @@ -0,0 +1,144 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. and Baidu team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ErnieM model. """ + +import unittest + +from transformers import ErnieMTokenizer +from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/spiece.model") + + +@require_sentencepiece +@require_tokenizers +class ErnieMTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = ErnieMTokenizer + test_seq2seq = False + test_sentencepiece = True + test_rust_tokenizer = False + test_sentencepiece_ignore_case = False + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = ErnieMTokenizer(SAMPLE_VOCAB, unk_token="", pad_token="") + tokenizer.save_pretrained(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_text = "this is a test" + output_text = "this is a test" + return input_text, output_text + + def test_convert_token_and_id(self): + """Test ``_convert_token_to_id`` and ``_convert_id_to_token``.""" + token = "" + token_id = 0 + + self.assertEqual(self.get_tokenizer()._convert_token_to_id(token), token_id) + self.assertEqual(self.get_tokenizer()._convert_id_to_token(token_id), token) + + def test_get_vocab(self): + vocab_keys = list(self.get_tokenizer().get_vocab().keys()) + + self.assertEqual(vocab_keys[0], "") + self.assertEqual(vocab_keys[1], "") + self.assertEqual(vocab_keys[-1], "▁eloquent") + self.assertEqual(len(vocab_keys), 30_000) + + def test_vocab_size(self): + self.assertEqual(self.get_tokenizer().vocab_size, 30_000) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence = "I was born in 92000, and this is falsé." + + tokens = tokenizer.tokenize(sequence) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + rust_tokenizer = self.get_rust_tokenizer() + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + def test_full_tokenizer(self): + tokenizer = ErnieMTokenizer(SAMPLE_VOCAB, do_lower_case=True, unk_token="", pad_token="") + + tokens = tokenizer.tokenize("This is a test") + self.assertListEqual(tokens, ["▁this", "▁is", "▁a", "▁test"]) + + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [48, 25, 21, 1289]) + + tokens = tokenizer.tokenize("I was born in 92000, and this is falsé.") + # ErnieMTokenizer(paddlenlp implementation) outputs '9' instead of '_9' so to mimic that '_9' is changed to '9' + self.assertListEqual( + tokens, ["▁i", "▁was", "▁born", "▁in", "9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "é", "."] + ) + ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual(ids, [31, 23, 386, 19, 518, 3050, 15, 17, 48, 25, 8256, 18, 1, 9]) + + back_tokens = tokenizer.convert_ids_to_tokens(ids) + self.assertListEqual( + back_tokens, + ["▁i", "▁was", "▁born", "▁in", "9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "", "."], + ) + + def test_sequence_builders(self): + tokenizer = ErnieMTokenizer(SAMPLE_VOCAB, unk_token="", pad_token="") + + text = tokenizer.encode("sequence builders") + text_2 = tokenizer.encode("multi-sequence build") + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + assert encoded_pair == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + [ + tokenizer.sep_token_id + ] + text_2 + [tokenizer.sep_token_id] + + @slow + def test_tokenizer_integration(self): + # fmt: off + expected_encoding = {'input_ids': [[0, 11062, 82772, 7, 15, 82772, 538, 51529, 237, 17198, 1290, 206, 9, 215175, 1314, 136, 17198, 1290, 206, 9, 56359, 42, 122009, 9, 16466, 16, 87344, 4537, 9, 4717, 78381, 6, 159958, 7, 15, 24480, 618, 4, 527, 22693, 9, 304, 4, 2777, 24480, 9874, 4, 43523, 594, 4, 803, 18392, 33189, 18, 4, 43523, 24447, 5, 5, 5, 16, 100, 24955, 83658, 9626, 144057, 15, 839, 22335, 16, 136, 24955, 83658, 83479, 15, 39102, 724, 16, 678, 645, 6460, 1328, 4589, 42, 122009, 115774, 23, 3559, 1328, 46876, 7, 136, 53894, 1940, 42227, 41159, 17721, 823, 425, 4, 27512, 98722, 206, 136, 5531, 4970, 919, 17336, 5, 2], [0, 20080, 618, 83, 82775, 47, 479, 9, 1517, 73, 53894, 333, 80581, 110117, 18811, 5256, 1295, 51, 152526, 297, 7986, 390, 124416, 538, 35431, 214, 98, 15044, 25737, 136, 7108, 43701, 23, 756, 135355, 7, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 581, 63773, 119455, 6, 147797, 88203, 7, 645, 70, 21, 3285, 10269, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]} + # fmt: on + + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="susnato/ernie-m-base_pytorch", + sequences=[ + "Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides " + "general-purpose architectures (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet...) for Natural " + "Language Understanding (NLU) and Natural Language Generation (NLG) with over32+ pretrained " + "models in100+ languages and deep interoperability between Jax, PyTorch and TensorFlow.", + "BERT is designed to pre-train deep bidirectional representations from unlabeled text by jointly " + "conditioning on both left and right context in all layers.", + "The quick brown fox jumps over the lazy dog.", + ], + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esm.py new file mode 100644 index 0000000000000000000000000000000000000000..2e5d48082be2b19327463e6a54d9a28d6e28c01a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esm.py @@ -0,0 +1,315 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ESM model. """ + + +import unittest + +from transformers import EsmConfig, is_torch_available +from transformers.testing_utils import TestCasePlus, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import EsmForMaskedLM, EsmForSequenceClassification, EsmForTokenClassification, EsmModel + from transformers.models.esm.modeling_esm import ( + ESM_PRETRAINED_MODEL_ARCHIVE_LIST, + EsmEmbeddings, + create_position_ids_from_input_ids, + ) + + +# copied from tests.test_modeling_roberta +class EsmModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=False, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=33, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return EsmConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + pad_token_id=1, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels): + model = EsmModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = EsmForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_token_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = EsmForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class EsmModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_mismatched_shapes = False + + all_model_classes = ( + ( + EsmForMaskedLM, + EsmModel, + EsmForSequenceClassification, + EsmForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = () + pipeline_model_mapping = ( + { + "feature-extraction": EsmModel, + "fill-mask": EsmForMaskedLM, + "text-classification": EsmForSequenceClassification, + "token-classification": EsmForTokenClassification, + "zero-shot": EsmForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_sequence_classification_problem_types = True + + def setUp(self): + self.model_tester = EsmModelTester(self) + self.config_tester = ConfigTester(self, config_class=EsmConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ESM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = EsmModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_create_position_ids_respects_padding_index(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is EsmEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + model = EsmEmbeddings(config=config) + + input_ids = torch.as_tensor([[12, 31, 13, model.padding_idx]]) + expected_positions = torch.as_tensor( + [ + [ + 0 + model.padding_idx + 1, + 1 + model.padding_idx + 1, + 2 + model.padding_idx + 1, + model.padding_idx, + ] + ] + ) + position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + def test_create_position_ids_from_inputs_embeds(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is EsmEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + embeddings = EsmEmbeddings(config=config) + + inputs_embeds = torch.empty(2, 4, 30) + expected_single_positions = [ + 0 + embeddings.padding_idx + 1, + 1 + embeddings.padding_idx + 1, + 2 + embeddings.padding_idx + 1, + 3 + embeddings.padding_idx + 1, + ] + expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + @unittest.skip("Esm does not support embedding resizing") + def test_resize_embeddings_untied(self): + pass + + @unittest.skip("Esm does not support embedding resizing") + def test_resize_tokens_embeddings(self): + pass + + +@require_torch +class EsmModelIntegrationTest(TestCasePlus): + @slow + def test_inference_masked_lm(self): + with torch.no_grad(): + model = EsmForMaskedLM.from_pretrained("facebook/esm2_t6_8M_UR50D") + model.eval() + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + vocab_size = 33 + + expected_shape = torch.Size((1, 6, vocab_size)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[[8.9215, -10.5898, -6.4671], [-6.3967, -13.9114, -1.1212], [-7.7812, -13.9516, -3.7406]]] + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) + + @slow + def test_inference_no_head(self): + with torch.no_grad(): + model = EsmModel.from_pretrained("facebook/esm2_t6_8M_UR50D") + model.eval() + + input_ids = torch.tensor([[0, 6, 4, 13, 5, 4, 16, 12, 11, 7, 2]]) + output = model(input_ids)[0] + # compare the actual values for a slice. + expected_slice = torch.tensor( + [[[0.1444, 0.5413, 0.3248], [0.3034, 0.0053, 0.3108], [0.3228, -0.2499, 0.3415]]] + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esmfold.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esmfold.py new file mode 100644 index 0000000000000000000000000000000000000000..84444f322237d9cb5e29e40842c380f2c6e28e56 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_esmfold.py @@ -0,0 +1,256 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch ESM model. """ + + +import unittest + +from transformers import EsmConfig, is_torch_available +from transformers.testing_utils import TestCasePlus, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers.models.esm.modeling_esmfold import EsmForProteinFolding + + +class EsmFoldModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=False, + use_input_mask=True, + use_token_type_ids=False, + use_labels=False, + vocab_size=19, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + config = EsmConfig( + vocab_size=33, + hidden_size=self.hidden_size, + pad_token_id=1, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + is_folding_model=True, + esmfold_config={"trunk": {"num_blocks": 2}, "fp16_esm": False}, + ) + return config + + def create_and_check_model(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels): + model = EsmForProteinFolding(config=config).float() + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + result = model(input_ids) + + self.parent.assertEqual(result.positions.shape, (8, self.batch_size, self.seq_length, 14, 3)) + self.parent.assertEqual(result.angles.shape, (8, self.batch_size, self.seq_length, 7, 2)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class EsmFoldModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_mismatched_shapes = False + + all_model_classes = (EsmForProteinFolding,) if is_torch_available() else () + all_generative_model_classes = () + pipeline_model_mapping = {} if is_torch_available() else {} + test_sequence_classification_problem_types = False + + def setUp(self): + self.model_tester = EsmFoldModelTester(self) + self.config_tester = ConfigTester(self, config_class=EsmConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip("Does not support attention outputs") + def test_attention_outputs(self): + pass + + @unittest.skip + def test_correct_missing_keys(self): + pass + + @unittest.skip("Esm does not support embedding resizing") + def test_resize_embeddings_untied(self): + pass + + @unittest.skip("Esm does not support embedding resizing") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip("ESMFold does not support passing input embeds!") + def test_inputs_embeds(self): + pass + + @unittest.skip("ESMFold does not support head pruning.") + def test_head_pruning(self): + pass + + @unittest.skip("ESMFold does not support head pruning.") + def test_head_pruning_integration(self): + pass + + @unittest.skip("ESMFold does not support head pruning.") + def test_head_pruning_save_load_from_config_init(self): + pass + + @unittest.skip("ESMFold does not support head pruning.") + def test_head_pruning_save_load_from_pretrained(self): + pass + + @unittest.skip("ESMFold does not support head pruning.") + def test_headmasking(self): + pass + + @unittest.skip("ESMFold does not output hidden states in the normal way.") + def test_hidden_states_output(self): + pass + + @unittest.skip("ESMfold does not output hidden states in the normal way.") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip("ESMFold only has one output format.") + def test_model_outputs_equivalence(self): + pass + + @unittest.skip("This test doesn't work for ESMFold and doesn't test core functionality") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip("ESMFold does not support input chunking.") + def test_feed_forward_chunking(self): + pass + + @unittest.skip("ESMFold doesn't respect you and it certainly doesn't respect your initialization arguments.") + def test_initialization(self): + pass + + @unittest.skip("ESMFold doesn't support torchscript compilation.") + def test_torchscript_output_attentions(self): + pass + + @unittest.skip("ESMFold doesn't support torchscript compilation.") + def test_torchscript_output_hidden_state(self): + pass + + @unittest.skip("ESMFold doesn't support torchscript compilation.") + def test_torchscript_simple(self): + pass + + @unittest.skip("ESMFold doesn't support data parallel.") + def test_multi_gpu_data_parallel_forward(self): + pass + + +@require_torch +class EsmModelIntegrationTest(TestCasePlus): + @slow + def test_inference_protein_folding(self): + model = EsmForProteinFolding.from_pretrained("facebook/esmfold_v1").float() + model.eval() + input_ids = torch.tensor([[0, 6, 4, 13, 5, 4, 16, 12, 11, 7, 2]]) + position_outputs = model(input_ids)["positions"] + expected_slice = torch.tensor([2.5828, 0.7993, -10.9334], dtype=torch.float32) + self.assertTrue(torch.allclose(position_outputs[0, 0, 0, 0], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_tf_esm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_tf_esm.py new file mode 100644 index 0000000000000000000000000000000000000000..dc9d430d07edae139fa6a470793c53b4ddc2b5b7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_modeling_tf_esm.py @@ -0,0 +1,322 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import EsmConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import numpy + import tensorflow as tf + + from transformers.models.esm.modeling_tf_esm import ( + TF_ESM_PRETRAINED_MODEL_ARCHIVE_LIST, + TFEsmForMaskedLM, + TFEsmForSequenceClassification, + TFEsmForTokenClassification, + TFEsmModel, + ) + + +# copied from tests.test_modeling_tf_roberta +class TFEsmModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = EsmConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + pad_token_id=1, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + config.is_decoder = True + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_model(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels): + model = TFEsmModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + + model = TFEsmModel(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "encoder_hidden_states": encoder_hidden_states, + "encoder_attention_mask": encoder_attention_mask, + } + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs, encoder_hidden_states=encoder_hidden_states) + + # Also check the case where encoder outputs are not passed + result = model(input_ids, attention_mask=input_mask) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFEsmForMaskedLM(config=config) + result = model([input_ids, input_mask]) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_token_classification( + self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFEsmForTokenClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFEsmModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFEsmModel, + TFEsmForMaskedLM, + TFEsmForSequenceClassification, + TFEsmForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFEsmModel, + "fill-mask": TFEsmForMaskedLM, + "text-classification": TFEsmForSequenceClassification, + "token-classification": TFEsmForTokenClassification, + "zero-shot": TFEsmForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFEsmModelTester(self) + self.config_tester = ConfigTester(self, config_class=EsmConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + """Test the base model""" + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_as_decoder(self): + """Test the base model as a decoder (of an encoder-decoder architecture) + + is_deocder=True + cross_attention + pass encoder outputs + """ + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_ESM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFEsmModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @unittest.skip("Protein models do not support embedding resizing.") + def test_resize_token_embeddings(self): + pass + + @unittest.skip("Protein models do not support embedding resizing.") + def test_save_load_after_resize_token_embeddings(self): + pass + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + if model_class is TFEsmForMaskedLM: + # Output embedding test differs from the main test because they're a matrix, not a layer + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + +@require_tf +class TFEsmModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TFEsmForMaskedLM.from_pretrained("facebook/esm2_t6_8M_UR50D") + + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + expected_shape = [1, 6, 33] + self.assertEqual(list(output.numpy().shape), expected_shape) + # compare the actual values for a slice. + expected_slice = tf.constant( + [ + [ + [8.921518, -10.589814, -6.4671307], + [-6.3967156, -13.911377, -1.1211915], + [-7.781247, -13.951557, -3.740592], + ] + ] + ) + self.assertTrue(numpy.allclose(output[:, :3, :3].numpy(), expected_slice.numpy(), atol=1e-2)) + + @slow + def test_inference_no_head(self): + model = TFEsmModel.from_pretrained("facebook/esm2_t6_8M_UR50D") + + input_ids = tf.constant([[0, 6, 4, 13, 5, 4, 16, 12, 11, 7, 2]]) + output = model(input_ids)[0] + # compare the actual values for a slice. + expected_slice = tf.constant( + [ + [ + [0.14443092, 0.54125327, 0.3247739], + [0.30340484, 0.00526676, 0.31077722], + [0.32278043, -0.24987096, 0.3414628], + ] + ] + ) + self.assertTrue(numpy.allclose(output[:, :3, :3].numpy(), expected_slice.numpy(), atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_tokenization_esm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_tokenization_esm.py new file mode 100644 index 0000000000000000000000000000000000000000..242f6d77081ff57a99c3529a0732cfff526f2f18 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/esm/test_tokenization_esm.py @@ -0,0 +1,91 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os +import tempfile +import unittest +from typing import List + +from transformers.models.esm.tokenization_esm import VOCAB_FILES_NAMES, EsmTokenizer +from transformers.testing_utils import require_tokenizers +from transformers.tokenization_utils import PreTrainedTokenizer +from transformers.tokenization_utils_base import PreTrainedTokenizerBase + + +@require_tokenizers +class ESMTokenizationTest(unittest.TestCase): + tokenizer_class = EsmTokenizer + + def setUp(self): + super().setUp() + self.tmpdirname = tempfile.mkdtemp() + # fmt: off + vocab_tokens: List[str] = ["", "", "", "", "L", "A", "G", "V", "S", "E", "R", "T", "I", "D", "P", "K", "Q", "N", "F", "Y", "M", "H", "W", "C", "X", "B", "U", "Z", "O", ".", "-", "", ""] # noqa: E501 + # fmt: on + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + def get_tokenizers(self, **kwargs) -> List[PreTrainedTokenizerBase]: + return [self.get_tokenizer(**kwargs)] + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def test_tokenizer_single_example(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + tokens = tokenizer.tokenize("LAGVS") + self.assertListEqual(tokens, ["L", "A", "G", "V", "S"]) + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [4, 5, 6, 7, 8]) + + def test_tokenizer_encode_single(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + seq = "LAGVS" + self.assertListEqual(tokenizer.encode(seq), [0, 4, 5, 6, 7, 8, 2]) + + def test_tokenizer_call_no_pad(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + seq_batch = ["LAGVS", "WCB"] + tokens_batch = tokenizer(seq_batch, padding=False)["input_ids"] + + self.assertListEqual(tokens_batch, [[0, 4, 5, 6, 7, 8, 2], [0, 22, 23, 25, 2]]) + + def test_tokenizer_call_pad(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + seq_batch = ["LAGVS", "WCB"] + tokens_batch = tokenizer(seq_batch, padding=True)["input_ids"] + + self.assertListEqual(tokens_batch, [[0, 4, 5, 6, 7, 8, 2], [0, 22, 23, 25, 2, 1, 1]]) + + def test_tokenize_special_tokens(self): + """Test `tokenize` with special tokens.""" + tokenizers = self.get_tokenizers(fast=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + SPECIAL_TOKEN_1 = "" + SPECIAL_TOKEN_2 = "" + + token_1 = tokenizer.tokenize(SPECIAL_TOKEN_1) + token_2 = tokenizer.tokenize(SPECIAL_TOKEN_2) + + self.assertEqual(len(token_1), 1) + self.assertEqual(len(token_2), 1) + self.assertEqual(token_1[0], SPECIAL_TOKEN_1) + self.assertEqual(token_2[0], SPECIAL_TOKEN_2) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_flaubert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_flaubert.py new file mode 100644 index 0000000000000000000000000000000000000000..99dbf927e18b1e0e19bbe81d4889f9839817d060 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_flaubert.py @@ -0,0 +1,502 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import tempfile +import unittest + +from transformers import FlaubertConfig, is_torch_available +from transformers.testing_utils import require_torch, require_torch_gpu, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + FlaubertForMultipleChoice, + FlaubertForQuestionAnswering, + FlaubertForQuestionAnsweringSimple, + FlaubertForSequenceClassification, + FlaubertForTokenClassification, + FlaubertModel, + FlaubertWithLMHeadModel, + ) + from transformers.models.flaubert.modeling_flaubert import FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST + + +class FlaubertModelTester(object): + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_lengths=True, + use_token_type_ids=True, + use_labels=True, + gelu_activation=True, + sinusoidal_embeddings=False, + causal=False, + asm=False, + n_langs=2, + vocab_size=99, + n_special=0, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=12, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + summary_type="last", + use_proj=None, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_lengths = use_input_lengths + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.gelu_activation = gelu_activation + self.sinusoidal_embeddings = sinusoidal_embeddings + self.causal = causal + self.asm = asm + self.n_langs = n_langs + self.vocab_size = vocab_size + self.n_special = n_special + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.summary_type = summary_type + self.use_proj = use_proj + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + input_lengths = None + if self.use_input_lengths: + input_lengths = ( + ids_tensor([self.batch_size], vocab_size=2) + self.seq_length - 2 + ) # small variation of seq_length + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.n_langs) + + sequence_labels = None + token_labels = None + is_impossible_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + is_impossible_labels = ids_tensor([self.batch_size], 2).float() + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return ( + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ) + + def get_config(self): + return FlaubertConfig( + vocab_size=self.vocab_size, + n_special=self.n_special, + emb_dim=self.hidden_size, + n_layers=self.num_hidden_layers, + n_heads=self.num_attention_heads, + dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_probs_dropout_prob, + gelu_activation=self.gelu_activation, + sinusoidal_embeddings=self.sinusoidal_embeddings, + asm=self.asm, + causal=self.causal, + n_langs=self.n_langs, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + summary_type=self.summary_type, + use_proj=self.use_proj, + ) + + def create_and_check_flaubert_model( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = FlaubertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, lengths=input_lengths, langs=token_type_ids) + result = model(input_ids, langs=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_flaubert_lm_head( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = FlaubertWithLMHeadModel(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_flaubert_simple_qa( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = FlaubertForQuestionAnsweringSimple(config) + model.to(torch_device) + model.eval() + + result = model(input_ids) + + result = model(input_ids, start_positions=sequence_labels, end_positions=sequence_labels) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_flaubert_qa( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = FlaubertForQuestionAnswering(config) + model.to(torch_device) + model.eval() + + result = model(input_ids) + + result_with_labels = model( + input_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + cls_index=sequence_labels, + is_impossible=is_impossible_labels, + p_mask=input_mask, + ) + + result_with_labels = model( + input_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + cls_index=sequence_labels, + is_impossible=is_impossible_labels, + ) + + (total_loss,) = result_with_labels.to_tuple() + + result_with_labels = model(input_ids, start_positions=sequence_labels, end_positions=sequence_labels) + + (total_loss,) = result_with_labels.to_tuple() + + self.parent.assertEqual(result_with_labels.loss.shape, ()) + self.parent.assertEqual(result.start_top_log_probs.shape, (self.batch_size, model.config.start_n_top)) + self.parent.assertEqual(result.start_top_index.shape, (self.batch_size, model.config.start_n_top)) + self.parent.assertEqual( + result.end_top_log_probs.shape, (self.batch_size, model.config.start_n_top * model.config.end_n_top) + ) + self.parent.assertEqual( + result.end_top_index.shape, (self.batch_size, model.config.start_n_top * model.config.end_n_top) + ) + self.parent.assertEqual(result.cls_logits.shape, (self.batch_size,)) + + def create_and_check_flaubert_sequence_classif( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = FlaubertForSequenceClassification(config) + model.to(torch_device) + model.eval() + + result = model(input_ids) + result = model(input_ids, labels=sequence_labels) + + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def create_and_check_flaubert_token_classif( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + config.num_labels = self.num_labels + model = FlaubertForTokenClassification(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_flaubert_multiple_choice( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + config.num_choices = self.num_choices + model = FlaubertForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "lengths": input_lengths, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_torch +class FlaubertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + FlaubertModel, + FlaubertWithLMHeadModel, + FlaubertForQuestionAnswering, + FlaubertForQuestionAnsweringSimple, + FlaubertForSequenceClassification, + FlaubertForTokenClassification, + FlaubertForMultipleChoice, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": FlaubertModel, + "fill-mask": FlaubertWithLMHeadModel, + "question-answering": FlaubertForQuestionAnsweringSimple, + "text-classification": FlaubertForSequenceClassification, + "token-classification": FlaubertForTokenClassification, + "zero-shot": FlaubertForSequenceClassification, + } + if is_torch_available() + else {} + ) + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if ( + pipeline_test_casse_name == "QAPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `QAPipelineTests` fails for a few models when the slower tokenizer are used. + # (The slower tokenizers were never used for pipeline tests before the pipeline testing rework) + # TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer + return True + + return False + + # Flaubert has 2 QA models -> need to manually set the correct labels for one of them here + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "FlaubertForQuestionAnswering": + inputs_dict["start_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + inputs_dict["end_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + + return inputs_dict + + def setUp(self): + self.model_tester = FlaubertModelTester(self) + self.config_tester = ConfigTester(self, config_class=FlaubertConfig, emb_dim=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_flaubert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_model(*config_and_inputs) + + def test_flaubert_lm_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_lm_head(*config_and_inputs) + + def test_flaubert_simple_qa(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_simple_qa(*config_and_inputs) + + def test_flaubert_qa(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_qa(*config_and_inputs) + + def test_flaubert_sequence_classif(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_sequence_classif(*config_and_inputs) + + def test_flaubert_token_classif(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_token_classif(*config_and_inputs) + + def test_flaubert_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_multiple_choice(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlaubertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + @require_torch_gpu + def test_torchscript_device_change(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + # FlauBertForMultipleChoice behaves incorrectly in JIT environments. + if model_class == FlaubertForMultipleChoice: + return + + config.torchscript = True + model = model_class(config=config) + + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + traced_model = torch.jit.trace( + model, (inputs_dict["input_ids"].to("cpu"), inputs_dict["attention_mask"].to("cpu")) + ) + + with tempfile.TemporaryDirectory() as tmp: + torch.jit.save(traced_model, os.path.join(tmp, "traced_model.pt")) + loaded = torch.jit.load(os.path.join(tmp, "traced_model.pt"), map_location=torch_device) + loaded(inputs_dict["input_ids"].to(torch_device), inputs_dict["attention_mask"].to(torch_device)) + + +@require_torch +class FlaubertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = FlaubertModel.from_pretrained("flaubert/flaubert_base_cased") + input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]) + with torch.no_grad(): + output = model(input_ids)[0] + expected_shape = torch.Size((1, 11, 768)) + self.assertEqual(output.shape, expected_shape) + expected_slice = torch.tensor( + [[[-2.6251, -1.4298, -0.0227], [-2.8510, -1.6387, 0.2258], [-2.8114, -1.1832, -0.3066]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_tf_flaubert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_tf_flaubert.py new file mode 100644 index 0000000000000000000000000000000000000000..6b7f4fc0316ea7c5fc233ecf1633d64b353765ca --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flaubert/test_modeling_tf_flaubert.py @@ -0,0 +1,391 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import is_tf_available +from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import numpy as np + import tensorflow as tf + + from transformers import ( + TF_FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + FlaubertConfig, + TFFlaubertForMultipleChoice, + TFFlaubertForQuestionAnsweringSimple, + TFFlaubertForSequenceClassification, + TFFlaubertForTokenClassification, + TFFlaubertModel, + TFFlaubertWithLMHeadModel, + ) + + +class TFFlaubertModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_lengths = True + self.use_token_type_ids = True + self.use_labels = True + self.gelu_activation = True + self.sinusoidal_embeddings = False + self.causal = False + self.asm = False + self.n_langs = 2 + self.vocab_size = 99 + self.n_special = 0 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.summary_type = "last" + self.use_proj = True + self.scope = None + self.bos_token_id = 0 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + input_mask = random_attention_mask([self.batch_size, self.seq_length], dtype=tf.float32) + + input_lengths = None + if self.use_input_lengths: + input_lengths = ( + ids_tensor([self.batch_size], vocab_size=2) + self.seq_length - 2 + ) # small variation of seq_length + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.n_langs) + + sequence_labels = None + token_labels = None + is_impossible_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + is_impossible_labels = ids_tensor([self.batch_size], 2, dtype=tf.float32) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = FlaubertConfig( + vocab_size=self.vocab_size, + n_special=self.n_special, + emb_dim=self.hidden_size, + n_layers=self.num_hidden_layers, + n_heads=self.num_attention_heads, + dropout=self.hidden_dropout_prob, + attention_dropout=self.attention_probs_dropout_prob, + gelu_activation=self.gelu_activation, + sinusoidal_embeddings=self.sinusoidal_embeddings, + asm=self.asm, + causal=self.causal, + n_langs=self.n_langs, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + summary_type=self.summary_type, + use_proj=self.use_proj, + bos_token_id=self.bos_token_id, + ) + + return ( + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ) + + def create_and_check_flaubert_model( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = TFFlaubertModel(config=config) + inputs = {"input_ids": input_ids, "lengths": input_lengths, "langs": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_flaubert_lm_head( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = TFFlaubertWithLMHeadModel(config) + + inputs = {"input_ids": input_ids, "lengths": input_lengths, "langs": token_type_ids} + result = model(inputs) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_flaubert_qa( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = TFFlaubertForQuestionAnsweringSimple(config) + + inputs = {"input_ids": input_ids, "lengths": input_lengths} + + result = model(inputs) + + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_flaubert_sequence_classif( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + model = TFFlaubertForSequenceClassification(config) + + inputs = {"input_ids": input_ids, "lengths": input_lengths} + + result = model(inputs) + + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def create_and_check_flaubert_for_token_classification( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + config.num_labels = self.num_labels + model = TFFlaubertForTokenClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_flaubert_for_multiple_choice( + self, + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ): + config.num_choices = self.num_choices + model = TFFlaubertForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_lengths, + sequence_labels, + token_labels, + is_impossible_labels, + choice_labels, + input_mask, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "langs": token_type_ids, + "lengths": input_lengths, + } + return config, inputs_dict + + +@require_tf +class TFFlaubertModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFFlaubertModel, + TFFlaubertWithLMHeadModel, + TFFlaubertForSequenceClassification, + TFFlaubertForQuestionAnsweringSimple, + TFFlaubertForTokenClassification, + TFFlaubertForMultipleChoice, + ) + if is_tf_available() + else () + ) + all_generative_model_classes = ( + (TFFlaubertWithLMHeadModel,) if is_tf_available() else () + ) # TODO (PVP): Check other models whether language generation is also applicable + pipeline_model_mapping = ( + { + "feature-extraction": TFFlaubertModel, + "fill-mask": TFFlaubertWithLMHeadModel, + "question-answering": TFFlaubertForQuestionAnsweringSimple, + "text-classification": TFFlaubertForSequenceClassification, + "token-classification": TFFlaubertForTokenClassification, + "zero-shot": TFFlaubertForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if ( + pipeline_test_casse_name == "QAPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `QAPipelineTests` fails for a few models when the slower tokenizer are used. + # (The slower tokenizers were never used for pipeline tests before the pipeline testing rework) + # TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer + return True + + return False + + def setUp(self): + self.model_tester = TFFlaubertModelTester(self) + self.config_tester = ConfigTester(self, config_class=FlaubertConfig, emb_dim=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_flaubert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_model(*config_and_inputs) + + def test_flaubert_lm_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_lm_head(*config_and_inputs) + + def test_flaubert_qa(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_qa(*config_and_inputs) + + def test_flaubert_sequence_classif(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_sequence_classif(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_flaubert_for_multiple_choice(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_FLAUBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFFlaubertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_tf +@require_sentencepiece +@require_tokenizers +class TFFlaubertModelIntegrationTest(unittest.TestCase): + @slow + def test_output_embeds_base_model(self): + model = TFFlaubertModel.from_pretrained("jplu/tf-flaubert-small-cased") + + input_ids = tf.convert_to_tensor( + [[0, 158, 735, 2592, 1424, 6727, 82, 1]], + dtype=tf.int32, + ) # "J'aime flaubert !" + + output = model(input_ids)[0] + expected_shape = tf.TensorShape((1, 8, 512)) + self.assertEqual(output.shape, expected_shape) + # compare the actual values for a slice. + expected_slice = tf.convert_to_tensor( + [ + [ + [-1.8768773, -1.566555, 0.27072418], + [-1.6920038, -0.5873505, 1.9329599], + [-2.9563985, -1.6993835, 1.7972052], + ] + ], + dtype=tf.float32, + ) + + self.assertTrue(np.allclose(output[:, :3, :3].numpy(), expected_slice.numpy(), atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_image_processing_flava.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_image_processing_flava.py new file mode 100644 index 0000000000000000000000000000000000000000..f9751725697e0a6f8a2302e181227e6c6b5c812a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_image_processing_flava.py @@ -0,0 +1,372 @@ +# coding=utf-8 +# Copyright 2022 Meta Platforms authors and HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + import PIL + + from transformers import FlavaImageProcessor + from transformers.image_utils import PILImageResampling + from transformers.models.flava.image_processing_flava import ( + FLAVA_CODEBOOK_MEAN, + FLAVA_CODEBOOK_STD, + FLAVA_IMAGE_MEAN, + FLAVA_IMAGE_STD, + ) +else: + FLAVA_IMAGE_MEAN = FLAVA_IMAGE_STD = FLAVA_CODEBOOK_MEAN = FLAVA_CODEBOOK_STD = None + + +class FlavaImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_center_crop=True, + crop_size=None, + resample=None, + do_rescale=True, + rescale_factor=1 / 255, + do_normalize=True, + image_mean=FLAVA_IMAGE_MEAN, + image_std=FLAVA_IMAGE_STD, + input_size_patches=14, + total_mask_patches=75, + mask_group_max_patches=None, + mask_group_min_patches=16, + mask_group_min_aspect_ratio=0.3, + mask_group_max_aspect_ratio=None, + codebook_do_resize=True, + codebook_size=None, + codebook_resample=None, + codebook_do_center_crop=True, + codebook_crop_size=None, + codebook_do_map_pixels=True, + codebook_do_normalize=True, + codebook_image_mean=FLAVA_CODEBOOK_MEAN, + codebook_image_std=FLAVA_CODEBOOK_STD, + ): + size = size if size is not None else {"height": 224, "width": 224} + crop_size = crop_size if crop_size is not None else {"height": 224, "width": 224} + codebook_size = codebook_size if codebook_size is not None else {"height": 112, "width": 112} + codebook_crop_size = codebook_crop_size if codebook_crop_size is not None else {"height": 112, "width": 112} + + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.do_resize = do_resize + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.size = size + self.resample = resample if resample is not None else PILImageResampling.BICUBIC + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + self.do_center_crop = do_center_crop + self.crop_size = crop_size + + self.input_size_patches = input_size_patches + self.total_mask_patches = total_mask_patches + self.mask_group_max_patches = mask_group_max_patches + self.mask_group_min_patches = mask_group_min_patches + self.mask_group_min_aspect_ratio = mask_group_min_aspect_ratio + self.mask_group_max_aspect_ratio = mask_group_max_aspect_ratio + + self.codebook_do_resize = codebook_do_resize + self.codebook_size = codebook_size + self.codebook_resample = codebook_resample if codebook_resample is not None else PILImageResampling.LANCZOS + self.codebook_do_center_crop = codebook_do_center_crop + self.codebook_crop_size = codebook_crop_size + self.codebook_do_map_pixels = codebook_do_map_pixels + self.codebook_do_normalize = codebook_do_normalize + self.codebook_image_mean = codebook_image_mean + self.codebook_image_std = codebook_image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "size": self.size, + "resample": self.resample, + "do_rescale": self.do_rescale, + "rescale_factor": self.rescale_factor, + "do_center_crop": self.do_center_crop, + "crop_size": self.crop_size, + "input_size_patches": self.input_size_patches, + "total_mask_patches": self.total_mask_patches, + "mask_group_max_patches": self.mask_group_max_patches, + "mask_group_min_patches": self.mask_group_min_patches, + "mask_group_min_aspect_ratio": self.mask_group_min_aspect_ratio, + "mask_group_max_aspect_ratio": self.mask_group_min_aspect_ratio, + "codebook_do_resize": self.codebook_do_resize, + "codebook_size": self.codebook_size, + "codebook_resample": self.codebook_resample, + "codebook_do_center_crop": self.codebook_do_center_crop, + "codebook_crop_size": self.codebook_crop_size, + "codebook_do_map_pixels": self.codebook_do_map_pixels, + "codebook_do_normalize": self.codebook_do_normalize, + "codebook_image_mean": self.codebook_image_mean, + "codebook_image_std": self.codebook_image_std, + } + + def get_expected_image_size(self): + return (self.size["height"], self.size["width"]) + + def get_expected_mask_size(self): + return ( + (self.input_size_patches, self.input_size_patches) + if not isinstance(self.input_size_patches, tuple) + else self.input_size_patches + ) + + def get_expected_codebook_image_size(self): + return (self.codebook_size["height"], self.codebook_size["width"]) + + +@require_torch +@require_vision +class FlavaImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = FlavaImageProcessor if is_vision_available() else None + maxDiff = None + + def setUp(self): + self.image_processor_tester = FlavaImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "resample")) + self.assertTrue(hasattr(image_processing, "crop_size")) + self.assertTrue(hasattr(image_processing, "do_center_crop")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + self.assertTrue(hasattr(image_processing, "rescale_factor")) + self.assertTrue(hasattr(image_processing, "masking_generator")) + self.assertTrue(hasattr(image_processing, "codebook_do_resize")) + self.assertTrue(hasattr(image_processing, "codebook_size")) + self.assertTrue(hasattr(image_processing, "codebook_resample")) + self.assertTrue(hasattr(image_processing, "codebook_do_center_crop")) + self.assertTrue(hasattr(image_processing, "codebook_crop_size")) + self.assertTrue(hasattr(image_processing, "codebook_do_map_pixels")) + self.assertTrue(hasattr(image_processing, "codebook_do_normalize")) + self.assertTrue(hasattr(image_processing, "codebook_image_mean")) + self.assertTrue(hasattr(image_processing, "codebook_image_std")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 224, "width": 224}) + self.assertEqual(image_processor.crop_size, {"height": 224, "width": 224}) + self.assertEqual(image_processor.codebook_size, {"height": 112, "width": 112}) + self.assertEqual(image_processor.codebook_crop_size, {"height": 112, "width": 112}) + + image_processor = self.image_processing_class.from_dict( + self.image_processor_dict, size=42, crop_size=84, codebook_size=33, codebook_crop_size=66 + ) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + self.assertEqual(image_processor.crop_size, {"height": 84, "width": 84}) + self.assertEqual(image_processor.codebook_size, {"height": 33, "width": 33}) + self.assertEqual(image_processor.codebook_crop_size, {"height": 66, "width": 66}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, PIL.Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt") + + # Test no bool masked pos + self.assertFalse("bool_masked_pos" in encoded_images) + + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + + self.assertEqual( + encoded_images.pixel_values.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt") + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + + # Test no bool masked pos + self.assertFalse("bool_masked_pos" in encoded_images) + + self.assertEqual( + encoded_images.pixel_values.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + def _test_call_framework(self, instance_class, prepare_kwargs): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, **prepare_kwargs) + for image in image_inputs: + self.assertIsInstance(image, instance_class) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt") + + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + self.assertEqual( + encoded_images.pixel_values.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + encoded_images = image_processing(image_inputs, return_image_mask=True, return_tensors="pt") + + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + self.assertEqual( + encoded_images.pixel_values.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + expected_height, expected_width = self.image_processor_tester.get_expected_mask_size() + self.assertEqual( + encoded_images.bool_masked_pos.shape, + ( + self.image_processor_tester.batch_size, + expected_height, + expected_width, + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + # Test masking + encoded_images = image_processing(image_inputs, return_image_mask=True, return_tensors="pt") + + expected_height, expected_width = self.image_processor_tester.get_expected_image_size() + self.assertEqual( + encoded_images.pixel_values.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) + + expected_height, expected_width = self.image_processor_tester.get_expected_mask_size() + self.assertEqual( + encoded_images.bool_masked_pos.shape, + ( + self.image_processor_tester.batch_size, + expected_height, + expected_width, + ), + ) + + def test_call_numpy(self): + self._test_call_framework(np.ndarray, prepare_kwargs={"numpify": True}) + + def test_call_pytorch(self): + self._test_call_framework(torch.Tensor, prepare_kwargs={"torchify": True}) + + def test_masking(self): + # Initialize image_processing + random.seed(1234) + image_processing = self.image_processing_class(**self.image_processor_dict) + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_image_mask=True, return_tensors="pt") + self.assertEqual(encoded_images.bool_masked_pos.sum().item(), 75) + + def test_codebook_pixels(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, PIL.Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_codebook_pixels=True, return_tensors="pt") + expected_height, expected_width = self.image_processor_tester.get_expected_codebook_image_size() + self.assertEqual( + encoded_images.codebook_pixel_values.shape, + (1, self.image_processor_tester.num_channels, expected_height, expected_width), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_codebook_pixels=True, return_tensors="pt") + expected_height, expected_width = self.image_processor_tester.get_expected_codebook_image_size() + self.assertEqual( + encoded_images.codebook_pixel_values.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + expected_height, + expected_width, + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_modeling_flava.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_modeling_flava.py new file mode 100644 index 0000000000000000000000000000000000000000..2544b7ee93f6caaf3b0825312bbbbd41fc0670e2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_modeling_flava.py @@ -0,0 +1,1240 @@ +# coding=utf-8 +# Copyright 2022 Meta Platforms authors and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch FLAVA model. """ + + +import inspect +import os +import random +import tempfile +import unittest + +import numpy as np +import requests + +from transformers import ( + FlavaConfig, + FlavaImageCodebookConfig, + FlavaImageConfig, + FlavaMultimodalConfig, + FlavaTextConfig, +) +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + FlavaForPreTraining, + FlavaImageCodebook, + FlavaImageModel, + FlavaModel, + FlavaMultimodalModel, + FlavaTextModel, + ) + from transformers.models.flava.modeling_flava import ( + FLAVA_CODEBOOK_PRETRAINED_MODEL_ARCHIVE_LIST, + FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST, + ) +else: + FlavaModel = None + FlavaForPreTraining = None + torch = {} + + +if is_vision_available(): + from PIL import Image + + from transformers import FlavaProcessor + + +class FlavaImageModelTester: + def __init__( + self, + parent, + batch_size=12, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + image_size=30, + patch_size=2, + num_channels=3, + qkv_bias=True, + mask_token=True, + vocab_size=8192, + ): + self.parent = parent + self.batch_size = batch_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.qkv_bias = qkv_bias + self.mask_token = mask_token + self.vocab_size = vocab_size + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + num_patches = self.image_size // self.patch_size + bool_masked_pos = ( + torch.rand((self.batch_size, num_patches, num_patches), device=pixel_values.device) < 0.9 + ).long() + config = self.get_config() + return config, pixel_values, bool_masked_pos + + def get_config(self): + return FlavaImageConfig( + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + qkv_bias=self.qkv_bias, + mask_token=self.mask_token, + vocab_size=self.vocab_size, + ) + + def create_and_check_model(self, config, pixel_values, bool_masked_pos): + model = FlavaImageModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values, bool_masked_pos) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, bool_masked_pos = config_and_inputs + inputs_dict = {"pixel_values": pixel_values, "bool_masked_pos": bool_masked_pos} + return config, inputs_dict + + +@require_torch +class FlavaImageModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as FLAVA does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (FlavaImageModel,) if is_torch_available() else () + + test_pruning = False + test_torchscript = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = FlavaImageModelTester(self) + self.config_tester = ConfigTester(self, config_class=FlavaImageConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_inputs_embeds(self): + # FLAVA does not use inputs_embeds + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + # in FLAVA, the seq_len equals the number of patches + 1 (we add 1 for the [CLS] token) + image_size = (self.model_tester.image_size, self.model_tester.image_size) + patch_size = (self.model_tester.patch_size, self.model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_len = num_patches + 1 + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_len, seq_len], + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # FLAVA has a different seq_length + image_size = (self.model_tester.image_size, self.model_tester.image_size) + patch_size = (self.model_tester.patch_size, self.model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_length = num_patches + 1 + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + # skip this test as FlavaImageModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_from_base(self): + pass + + # skip this test as FlavaImageModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlavaImageModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class FlavaTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + vocab_size=30522, + type_vocab_size=2, + max_position_embeddings=512, + position_embedding_type="absolute", + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=0, + qkv_bias=True, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.seq_length = seq_length + self.vocab_size = vocab_size + self.type_vocab_size = type_vocab_size + self.max_position_embeddings = max_position_embeddings + self.position_embedding_type = position_embedding_type + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.qkv_bias = qkv_bias + self.pad_token_id = pad_token_id + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + token_type_ids = None + + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask + + def get_config(self): + return FlavaTextConfig( + vocab_size=self.vocab_size, + type_vocab_size=self.type_vocab_size, + max_position_embeddings=self.max_position_embeddings, + position_embedding_type=self.position_embedding_type, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + pad_token_id=self.pad_token_id, + qkv_bias=self.qkv_bias, + ) + + def create_and_check_model(self, config, input_ids, token_type_ids, input_mask): + model = FlavaTextModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, token_type_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class FlavaTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (FlavaTextModel,) if is_torch_available() else () + test_pruning = False + test_head_masking = False + test_torchscript = False + + def setUp(self): + self.model_tester = FlavaTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=FlavaTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + def test_inputs_embeds(self): + # FLAVA does not use inputs_embeds + pass + + # skip this test as FlavaTextModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_from_base(self): + pass + + # skip this test as FlavaTextModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlavaTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class FlavaMultimodalModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=44, + use_input_mask=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + initializer_range=0.02, + layer_norm_eps=1e-12, + qkv_bias=True, + ce_ignore_index=-100, + use_cls_token=True, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.use_input_mask = use_input_mask + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.qkv_bias = qkv_bias + self.ce_ignore_index = ce_ignore_index + self.use_cls_token = use_cls_token + + def prepare_config_and_inputs(self): + hidden_states = floats_tensor([self.batch_size, self.seq_length - 1, self.hidden_size]) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = self.get_config() + + return config, hidden_states, input_mask + + def get_config(self): + return FlavaMultimodalConfig( + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + qkv_bias=self.qkv_bias, + use_cls_token=self.use_cls_token, + ce_ignore_index=self.ce_ignore_index, + ) + + def create_and_check_model(self, config, hidden_states, input_mask): + model = FlavaMultimodalModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(hidden_states, attention_mask=input_mask) + result = model(hidden_states) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, hidden_states, input_mask = config_and_inputs + inputs_dict = {"hidden_states": hidden_states, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class FlavaMultimodalModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (FlavaMultimodalModel,) if is_torch_available() else () + test_pruning = False + test_head_masking = False + test_resize_embeddings = False + test_torchscript = False + + def setUp(self): + self.model_tester = FlavaMultimodalModelTester(self) + self.config_tester = ConfigTester( + self, config_class=FlavaMultimodalConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["hidden_states"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model_common_attributes(self): + # No embedding in multimodal model + pass + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + def test_inputs_embeds(self): + # FLAVA does not use inputs_embeds + pass + + # skip this test as FlavaMultimodalModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_from_base(self): + pass + + # skip this test as FlavaMultimodalModel has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlavaMultimodalModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class FlavaImageCodebookTester: + def __init__(self, parent, batch_size=12, image_size=112, num_channels=3): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return FlavaImageCodebookConfig() + + def create_and_check_model(self, config, pixel_values): + model = FlavaImageCodebook(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + self.parent.assertEqual( + result.shape, (self.batch_size, config.vocab_size, self.image_size // 8, self.image_size // 8) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class FlavaImageCodebookTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (FlavaImageCodebook,) if is_torch_available() else () + test_pruning = False + test_head_masking = False + test_resize_embeddings = False + test_torchscript = False + has_attentions = False + + def setUp(self): + self.model_tester = FlavaImageCodebookTester(self) + self.config_tester = ConfigTester(self, config_class=FlavaImageCodebookConfig, has_text_modality=False) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + @unittest.skip(reason="Flava does not output attentions") + def test_attention_outputs(self): + pass + + def test_model_common_attributes(self): + # No embedding in multimodal model + pass + + def test_training(self): + pass + + def test_hidden_states_output(self): + pass + + def test_retain_grad_hidden_states_attentions(self): + # no attentions + pass + + def test_training_gradient_checkpointing(self): + pass + + def test_inputs_embeds(self): + # FLAVA does not use inputs_embeds + pass + + def test_model_outputs_equivalence(self): + pass + + # skip this test as FlavaImageCodebook has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_from_base(self): + pass + + # skip this test as FlavaImageCodebook has no base class and is + # not available in MODEL_MAPPING + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in FLAVA_CODEBOOK_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlavaImageCodebook.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class FlavaModelTester: + model_class = FlavaModel + + def __init__( + self, + parent, + text_kwargs=None, + image_kwargs=None, + multimodal_kwargs=None, + image_codebook_kwargs=None, + is_training=True, + hidden_size=32, + projection_dim=32, + initializer_range=0.02, + layer_norm_eps=1e-12, + ): + if text_kwargs is None: + text_kwargs = {} + if image_kwargs is None: + image_kwargs = {} + if multimodal_kwargs is None: + multimodal_kwargs = {} + if image_codebook_kwargs is None: + image_codebook_kwargs = {} + + self.parent = parent + self.image_model_tester = FlavaImageModelTester(parent, **image_kwargs) + self.text_model_tester = FlavaTextModelTester(parent, **text_kwargs) + self.multimodal_model_tester = FlavaMultimodalModelTester(parent, **multimodal_kwargs) + self.image_codebook_tester = FlavaImageCodebookTester(parent, **image_codebook_kwargs) + self.is_training = is_training + self.config_tester = ConfigTester(self, config_class=FlavaConfig, hidden_size=37) + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + + def test_config(self): + self.config_tester.run_common_tests() + + def prepare_config_and_inputs_for_common(self): + _, pixel_values, bool_masked_pos = self.image_model_tester.prepare_config_and_inputs() + _, input_ids, token_type_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "bool_masked_pos": bool_masked_pos, + } + + def get_config(self): + return FlavaConfig.from_configs( + self.image_model_tester.get_config(), + self.text_model_tester.get_config(), + self.multimodal_model_tester.get_config(), + self.image_codebook_tester.get_config(), + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + ) + + def create_and_check_model(self, config, inputs): + self._test_model(config, inputs, test_image=True) + self._test_model(config, inputs, test_text=True) + self._test_model(config, inputs, test_image=True, test_text=True) + + def _test_model(self, config, inputs, test_image=False, test_text=False): + model = self.model_class(config).to(torch_device).eval() + with torch.no_grad(): + result = model( + input_ids=inputs["input_ids"] if test_text else None, + attention_mask=inputs["attention_mask"] if test_text else None, + token_type_ids=inputs["token_type_ids"] if test_text else None, + pixel_values=inputs["pixel_values"] if test_image else None, + bool_masked_pos=inputs["bool_masked_pos"] if test_image else None, + ) + image_size = (self.image_model_tester.image_size, self.image_model_tester.image_size) + patch_size = (self.image_model_tester.patch_size, self.image_model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + + if test_image: + self.parent.assertEqual( + result.image_embeddings.shape, + (self.image_model_tester.batch_size, num_patches + 1, self.image_model_tester.hidden_size), + ) + else: + self.parent.assertIsNone(result.image_embeddings) + + if test_text: + self.parent.assertEqual( + result.text_embeddings.shape, + ( + self.text_model_tester.batch_size, + self.text_model_tester.seq_length, + self.text_model_tester.hidden_size, + ), + ) + else: + self.parent.assertIsNone(result.text_embeddings) + + if test_image and test_text: + self.parent.assertEqual( + result.multimodal_embeddings.shape, + ( + self.multimodal_model_tester.batch_size, + self.text_model_tester.seq_length + num_patches + 2, + self.multimodal_model_tester.hidden_size, + ), + ) + else: + self.parent.assertIsNone(result.multimodal_embeddings) + + +@require_torch +class FlavaModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (FlavaModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": FlavaModel} if is_torch_available() else {} + class_for_tester = FlavaModelTester + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def setUp(self): + self.model_tester = self.class_for_tester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.create_and_check_model(*config_and_inputs) + + # hidden_states are tested in individual model tests + def test_hidden_states_output(self): + pass + + # input_embeds are tested in individual model tests + def test_inputs_embeds(self): + pass + + # tested in individual model tests + def test_retain_grad_hidden_states_attentions(self): + pass + + # FlavaModel does not have input/output embeddings + def test_model_common_attributes(self): + pass + + # override as the `logit_scale` parameter initilization is different for FLAVA + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if name == "logit_scale" or name == "flava.logit_scale": + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + configs_no_init.return_loss = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + pixel_values = inputs_dict["pixel_values"] # FLAVA needs pixel_values + + if "input_ids_masked" in inputs_dict: + # For pretraining + inputs = (input_ids, inputs_dict["input_ids_masked"], pixel_values) + else: + inputs = (input_ids, pixel_values) + + traced_model = torch.jit.trace(model, inputs) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + # Non persistent buffers won't be in original state dict + loaded_model_state_dict.pop("text_model.embeddings.token_type_ids", None) + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_load_image_text_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Save FlavaConfig and check if we can load FlavaImageConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + image_config = FlavaImageConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.image_config.to_dict(), image_config.to_dict()) + + # Save FlavaConfig and check if we can load FlavaTextConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + text_config = FlavaTextConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.text_config.to_dict(), text_config.to_dict()) + + # Save FlavaConfig and check if we can load FlavaMultimodalConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + multimodal_config = FlavaMultimodalConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.multimodal_config.to_dict(), multimodal_config.to_dict()) + + # overwrite from common since FlavaModel/TFFlavaModel return FLAVAOutput/TFFLAVAOutput + @slow + def test_model_from_pretrained(self): + for model_name in FLAVA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FlavaModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class FlavaForPreTrainingTester(FlavaModelTester): + model_class = FlavaForPreTraining + + def prepare_config_and_inputs_for_common(self): + _, pixel_values, bool_masked_pos = self.image_model_tester.prepare_config_and_inputs() + _, input_ids, token_type_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + config = self.get_config() + + input_ids_masked = input_ids.detach().clone() + input_ids_masked[:, 1:3] = 100 + mlm_labels = input_ids.detach().clone() + mlm_labels[:, :] = config.ce_ignore_index + mlm_labels[:, 1:3] = input_ids[:, 1:3] + mim_labels = torch.randint( + 0, self.image_model_tester.vocab_size, bool_masked_pos.size(), device=bool_masked_pos.device + ).long() + mim_labels[bool_masked_pos.ne(True)] = config.ce_ignore_index + itm_labels = torch.ones(mlm_labels.size(0), device=bool_masked_pos.device).long() + + return config, { + "input_ids": input_ids, + "input_ids_masked": input_ids_masked, + "token_type_ids": token_type_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "bool_masked_pos": bool_masked_pos, + "mlm_labels": mlm_labels, + "mim_labels": mim_labels, + "itm_labels": itm_labels, + "return_loss": True, + } + + def _test_model(self, config, inputs, test_image=False, test_text=False): + model = self.model_class(config).to(torch_device).eval() + with torch.no_grad(): + result = model( + input_ids=inputs["input_ids"] if test_text else None, + input_ids_masked=inputs["input_ids_masked"] if test_text else None, + attention_mask=inputs["attention_mask"] if test_text else None, + token_type_ids=inputs["token_type_ids"] if test_text else None, + pixel_values=inputs["pixel_values"] if test_image else None, + bool_masked_pos=inputs["bool_masked_pos"] if test_image else None, + mlm_labels=inputs["mlm_labels"], + mim_labels=inputs["mim_labels"], + itm_labels=inputs["itm_labels"], + return_loss=inputs["return_loss"], + ) + image_size = (self.image_model_tester.image_size, self.image_model_tester.image_size) + patch_size = (self.image_model_tester.patch_size, self.image_model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + + if test_image: + self.parent.assertEqual( + result.image_embeddings.shape, + (self.image_model_tester.batch_size, num_patches + 1, self.image_model_tester.hidden_size), + ) + if not test_text: + self.parent.assertEqual( + result.loss_info.mim.dim(), + 0, + ) + self.parent.assertEqual( + result.mim_logits.shape, + (inputs["bool_masked_pos"].sum().item(), self.image_model_tester.vocab_size), + ) + + else: + self.parent.assertIsNone(result.image_embeddings) + + if test_text: + self.parent.assertEqual( + result.text_embeddings.shape, + ( + self.text_model_tester.batch_size, + self.text_model_tester.seq_length, + self.text_model_tester.hidden_size, + ), + ) + if not test_image: + self.parent.assertEqual(result.loss_info.mlm.dim(), 0) + self.parent.assertEqual( + result.mlm_logits.shape, + ( + (inputs["mlm_labels"] != self.multimodal_model_tester.ce_ignore_index).sum().item(), + self.text_model_tester.vocab_size, + ), + ) + else: + self.parent.assertIsNone(result.text_embeddings) + + if test_image and test_text: + self.parent.assertEqual( + result.multimodal_masked_embeddings.shape, + ( + self.multimodal_model_tester.batch_size, + self.text_model_tester.seq_length + num_patches + 2, + self.multimodal_model_tester.hidden_size, + ), + ) + self.parent.assertEqual( + result.itm_logits.shape, + (self.text_model_tester.batch_size, 2), + ) + self.parent.assertEqual( + result.mmm_text_logits.shape, + ( + (inputs["mlm_labels"] != self.multimodal_model_tester.ce_ignore_index).sum().item(), + self.text_model_tester.vocab_size, + ), + ) + self.parent.assertEqual( + result.mmm_image_logits.shape, + (inputs["bool_masked_pos"].sum().item(), self.image_model_tester.vocab_size), + ) + self.parent.assertEqual( + result.contrastive_logits_per_image.shape, + (self.image_model_tester.batch_size, self.text_model_tester.batch_size), + ) + self.parent.assertEqual( + result.contrastive_logits_per_text.shape, + (self.text_model_tester.batch_size, self.image_model_tester.batch_size), + ) + + for item in [ + result.loss_info.global_contrastive, + result.loss_info.itm, + result.loss_info.mmm_text, + result.loss_info.mmm_image, + ]: + self.parent.assertEqual(item.dim(), 0) + + for item in [result.loss_info.mim, result.loss_info.mlm]: + self.parent.assertIsNone(item) + + else: + self.parent.assertIsNone(result.multimodal_masked_embeddings) + for item in [ + result.loss_info.global_contrastive, + result.loss_info.itm, + result.loss_info.mmm_text, + result.loss_info.mmm_image, + ]: + self.parent.assertIsNone(item) + + self.parent.assertIsNone(result.multimodal_embeddings) + + +@require_torch +class FlavaForPreTrainingTest(FlavaModelTest): + all_model_classes = (FlavaForPreTraining,) if is_torch_available() else () + class_for_tester = FlavaForPreTrainingTester + test_torchscript = False + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@require_vision +@require_torch +class FlavaModelIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "facebook/flava-full" + model = FlavaModel.from_pretrained(model_name).to(torch_device) + processor = FlavaProcessor.from_pretrained(model_name) + + image = prepare_img() + inputs = processor( + text=["a photo of a cat", "a photo of a dog"], + images=[image, image], + padding="max_length", + max_length=77, + return_tensors="pt", + ).to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs, return_dict=True) + + # verify the embeddings + self.assertAlmostEqual(outputs.image_embeddings.sum().item(), -1352.53540, places=4) + self.assertAlmostEqual(outputs.text_embeddings.sum().item(), -198.98225, places=4) + self.assertAlmostEqual(outputs.multimodal_embeddings.sum().item(), -3988.51367, places=4) + + +@require_vision +@require_torch +class FlavaForPreTrainingIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "facebook/flava-full" + model = FlavaForPreTraining.from_pretrained(model_name).to(torch_device) + processor = FlavaProcessor.from_pretrained(model_name) + torch.manual_seed(1) + random.seed(1) + + image = prepare_img() + inputs = processor( + text=["a photo of a cat", "a photo of a dog"], + images=[image, image], + padding="max_length", + max_length=77, + return_tensors="pt", + return_codebook_pixels=True, + return_image_mask=True, + ) + inputs["input_ids_masked"] = inputs["input_ids"].clone() + inputs["input_ids_masked"][0, 4:6] = 103 + inputs["mlm_labels"] = inputs["input_ids"].clone() + inputs["mlm_labels"][:, :] = -100 + inputs["mlm_labels"][0, 4:6] = inputs["input_ids"][0, 4:6] + inputs = inputs.to(torch_device) + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + self.assertEqual( + outputs.contrastive_logits_per_image.shape, + torch.Size((inputs.pixel_values.shape[0], inputs.input_ids.shape[0])), + ) + self.assertEqual( + outputs.contrastive_logits_per_text.shape, + torch.Size((inputs.input_ids.shape[0], inputs.pixel_values.shape[0])), + ) + + expected_logits = torch.tensor([[16.1291, 8.4033], [16.1291, 8.4033]], device=torch_device) + self.assertTrue(torch.allclose(outputs.contrastive_logits_per_image, expected_logits, atol=1e-3)) + self.assertAlmostEqual(outputs.loss_info.mmm_text.item(), 1.75533199, places=4) + self.assertAlmostEqual(outputs.loss_info.mmm_image.item(), 7.0290069, places=4) + self.assertAlmostEqual(outputs.loss.item(), 11.0626, places=4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_processor_flava.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_processor_flava.py new file mode 100644 index 0000000000000000000000000000000000000000..f89d7edfaa9ac46f57f8f5e5cce9892770036a71 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/flava/test_processor_flava.py @@ -0,0 +1,246 @@ +# Copyright 2022 Meta Platforms authors and The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import random +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import BertTokenizer, BertTokenizerFast +from transformers.models.bert.tokenization_bert import VOCAB_FILES_NAMES +from transformers.testing_utils import require_vision +from transformers.utils import IMAGE_PROCESSOR_NAME, is_vision_available + + +if is_vision_available(): + from PIL import Image + + from transformers import FlavaImageProcessor, FlavaProcessor + from transformers.models.flava.image_processing_flava import ( + FLAVA_CODEBOOK_MEAN, + FLAVA_CODEBOOK_STD, + FLAVA_IMAGE_MEAN, + FLAVA_IMAGE_STD, + ) + + +@require_vision +class FlavaProcessorTest(unittest.TestCase): + def setUp(self): + self.tmpdirname = tempfile.mkdtemp() + + # fmt: off + vocab_tokens = ["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]", "want", "##want", "##ed", "wa", "un", "runn", "##ing", ",", "low", "lowest"] + # fmt: on + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write("".join([x + "\n" for x in vocab_tokens])) + + image_processor_map = { + "image_mean": FLAVA_IMAGE_MEAN, + "image_std": FLAVA_IMAGE_STD, + "do_normalize": True, + "do_resize": True, + "size": 224, + "do_center_crop": True, + "crop_size": 224, + "input_size_patches": 14, + "total_mask_patches": 75, + "mask_group_max_patches": None, + "mask_group_min_patches": 16, + "mask_group_min_aspect_ratio": 0.3, + "mask_group_max_aspect_ratio": None, + "codebook_do_resize": True, + "codebook_size": 112, + "codebook_do_center_crop": True, + "codebook_crop_size": 112, + "codebook_do_map_pixels": True, + "codebook_do_normalize": True, + "codebook_image_mean": FLAVA_CODEBOOK_MEAN, + "codebook_image_std": FLAVA_CODEBOOK_STD, + } + + self.image_processor_file = os.path.join(self.tmpdirname, IMAGE_PROCESSOR_NAME) + with open(self.image_processor_file, "w", encoding="utf-8") as fp: + json.dump(image_processor_map, fp) + + def get_tokenizer(self, **kwargs): + return BertTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + return BertTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_image_processor(self, **kwargs): + return FlavaImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + tokenizer_slow = self.get_tokenizer() + tokenizer_fast = self.get_rust_tokenizer() + image_processor = self.get_image_processor() + + processor_slow = FlavaProcessor(tokenizer=tokenizer_slow, image_processor=image_processor) + processor_slow.save_pretrained(self.tmpdirname) + processor_slow = FlavaProcessor.from_pretrained(self.tmpdirname, use_fast=False) + + processor_fast = FlavaProcessor(tokenizer=tokenizer_fast, image_processor=image_processor) + processor_fast.save_pretrained(self.tmpdirname) + processor_fast = FlavaProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor_slow.tokenizer.get_vocab(), tokenizer_slow.get_vocab()) + self.assertEqual(processor_fast.tokenizer.get_vocab(), tokenizer_fast.get_vocab()) + self.assertEqual(tokenizer_slow.get_vocab(), tokenizer_fast.get_vocab()) + self.assertIsInstance(processor_slow.tokenizer, BertTokenizer) + self.assertIsInstance(processor_fast.tokenizer, BertTokenizerFast) + + self.assertEqual(processor_slow.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertEqual(processor_fast.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor_slow.image_processor, FlavaImageProcessor) + self.assertIsInstance(processor_fast.image_processor, FlavaImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = FlavaProcessor(tokenizer=self.get_tokenizer(), image_processor=self.get_image_processor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_normalize=False, padding_value=1.0) + + processor = FlavaProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_normalize=False, padding_value=1.0 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, BertTokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, FlavaImageProcessor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = FlavaProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + + input_feat_extract = image_processor(image_input, return_tensors="np") + input_processor = processor(images=image_input, return_tensors="np") + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + # With rest of the args + random.seed(1234) + input_feat_extract = image_processor( + image_input, return_image_mask=True, return_codebook_pixels=True, return_tensors="np" + ) + random.seed(1234) + input_processor = processor( + images=image_input, return_image_mask=True, return_codebook_pixels=True, return_tensors="np" + ) + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = FlavaProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = FlavaProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), ["input_ids", "token_type_ids", "attention_mask", "pixel_values"]) + + # add extra args + inputs = processor(text=input_str, images=image_input, return_codebook_pixels=True, return_image_mask=True) + + self.assertListEqual( + list(inputs.keys()), + [ + "input_ids", + "token_type_ids", + "attention_mask", + "pixel_values", + "codebook_pixel_values", + "bool_masked_pos", + ], + ) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_tokenizer_decode(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = FlavaProcessor(tokenizer=tokenizer, image_processor=image_processor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = FlavaProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_modeling_fnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_modeling_fnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e7e592d5b62ff57ca64ecc12b04cc3212e0334e7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_modeling_fnet.py @@ -0,0 +1,587 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch FNet model. """ + + +import unittest +from typing import Dict, List, Tuple + +from transformers import FNetConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_tokenizers, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_PRETRAINING_MAPPING, + FNetForMaskedLM, + FNetForMultipleChoice, + FNetForNextSentencePrediction, + FNetForPreTraining, + FNetForQuestionAnswering, + FNetForSequenceClassification, + FNetForTokenClassification, + FNetModel, + FNetTokenizerFast, + ) + from transformers.models.fnet.modeling_fnet import ( + FNET_PRETRAINED_MODEL_ARCHIVE_LIST, + FNetBasicFourierTransform, + is_scipy_available, + ) + + +# Override ConfigTester +class FNetConfigTester(ConfigTester): + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + if self.has_text_modality: + self.parent.assertTrue(hasattr(config, "vocab_size")) + self.parent.assertTrue(hasattr(config, "hidden_size")) + self.parent.assertTrue(hasattr(config, "num_hidden_layers")) + + +class FNetModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + + def get_config(self): + return FNetConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + tpu_short_seq_length=self.seq_length, + ) + + @require_torch + def create_and_check_fourier_transform(self, config): + hidden_states = floats_tensor([self.batch_size, self.seq_length, config.hidden_size]) + transform = FNetBasicFourierTransform(config) + fftn_output = transform(hidden_states) + + config.use_tpu_fourier_optimizations = True + if is_scipy_available(): + transform = FNetBasicFourierTransform(config) + dft_output = transform(hidden_states) + + config.max_position_embeddings = 4097 + transform = FNetBasicFourierTransform(config) + fft_output = transform(hidden_states) + + if is_scipy_available(): + self.parent.assertTrue(torch.allclose(fftn_output[0][0], dft_output[0][0], atol=1e-4)) + self.parent.assertTrue(torch.allclose(fft_output[0][0], dft_output[0][0], atol=1e-4)) + self.parent.assertTrue(torch.allclose(fftn_output[0][0], fft_output[0][0], atol=1e-4)) + + def create_and_check_model(self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels): + model = FNetModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_pretraining( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + model = FNetForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + token_type_ids=token_type_ids, + labels=token_labels, + next_sentence_label=sequence_labels, + ) + self.parent.assertEqual(result.prediction_logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + self.parent.assertEqual(result.seq_relationship_logits.shape, (self.batch_size, 2)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + model = FNetForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_next_sentence_prediction( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + model = FNetForNextSentencePrediction(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + token_type_ids=token_type_ids, + next_sentence_label=sequence_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, 2)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + model = FNetForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = FNetForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = FNetForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = FNetForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids} + return config, inputs_dict + + +@require_torch +class FNetModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + FNetModel, + FNetForPreTraining, + FNetForMaskedLM, + FNetForNextSentencePrediction, + FNetForMultipleChoice, + FNetForQuestionAnswering, + FNetForSequenceClassification, + FNetForTokenClassification, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": FNetModel, + "fill-mask": FNetForMaskedLM, + "question-answering": FNetForQuestionAnswering, + "text-classification": FNetForSequenceClassification, + "token-classification": FNetForTokenClassification, + "zero-shot": FNetForSequenceClassification, + } + if is_torch_available() + else {} + ) + + # Skip Tests + test_pruning = False + test_head_masking = False + test_pruning = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "QAPipelineTests" and not tokenizer_name.endswith("Fast"): + return True + + return False + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + inputs_dict["next_sentence_label"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + return inputs_dict + + # Overriden Tests + def test_attention_outputs(self): + pass + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def set_nan_tensor_to_zero(t): + t[t != t] = 0 + return t + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + with torch.no_grad(): + tuple_output = model(**tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(**dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif isinstance(tuple_object, Dict): + for tuple_iterable_value, dict_iterable_value in zip( + tuple_object.values(), dict_object.values() + ): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + torch.allclose( + set_nan_tensor_to_zero(tuple_object), set_nan_tensor_to_zero(dict_object), atol=1e-5 + ), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {torch.max(torch.abs(tuple_object - dict_object))}. Tuple has `nan`:" + f" {torch.isnan(tuple_object).any()} and `inf`: {torch.isinf(tuple_object)}. Dict has" + f" `nan`: {torch.isnan(dict_object).any()} and `inf`: {torch.isinf(dict_object)}." + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + # tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + # dict_inputs = self._prepare_for_class(inputs_dict, model_class) + # check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + hidden_states = outputs.hidden_states[0] + + hidden_states.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + + def setUp(self): + self.model_tester = FNetModelTester(self) + self.config_tester = FNetConfigTester(self, config_class=FNetConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in FNET_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FNetModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class FNetModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_for_masked_lm(self): + """ + For comparison: + 1. Modify the pre-training model `__call__` to skip computing metrics and return masked_lm_output like so: + ``` + ... + sequence_output, pooled_output = EncoderModel( + self.config, random_seed=self.random_seed, name="encoder")( + input_ids, input_mask, type_ids, deterministic=deterministic) + + masked_lm_output = nn.Dense( + self.config.d_emb, + kernel_init=default_kernel_init, + name="predictions_dense")( + sequence_output) + masked_lm_output = nn.gelu(masked_lm_output) + masked_lm_output = nn.LayerNorm( + epsilon=LAYER_NORM_EPSILON, name="predictions_layer_norm")( + masked_lm_output) + masked_lm_logits = layers.OutputProjection( + kernel=self._get_embedding_table(), name="predictions_output")( + masked_lm_output) + + next_sentence_logits = layers.OutputProjection( + n_out=2, kernel_init=default_kernel_init, name="classification")( + pooled_output) + + return masked_lm_logits + ... + ``` + 2. Run the following: + >>> import jax.numpy as jnp + >>> import sentencepiece as spm + >>> from flax.training import checkpoints + >>> from f_net.models import PreTrainingModel + >>> from f_net.configs.pretraining import get_config, ModelArchitecture + + >>> pretrained_params = checkpoints.restore_checkpoint('./f_net/f_net_checkpoint', None) # Location of original checkpoint + >>> pretrained_config = get_config() + >>> pretrained_config.model_arch = ModelArchitecture.F_NET + + >>> vocab_filepath = "./f_net/c4_bpe_sentencepiece.model" # Location of the sentence piece model + >>> tokenizer = spm.SentencePieceProcessor() + >>> tokenizer.Load(vocab_filepath) + >>> with pretrained_config.unlocked(): + >>> pretrained_config.vocab_size = tokenizer.GetPieceSize() + >>> tokens = jnp.array([[0, 1, 2, 3, 4, 5]]) + >>> type_ids = jnp.zeros_like(tokens, dtype="i4") + >>> attention_mask = jnp.ones_like(tokens) # Dummy. This gets deleted inside the model. + + >>> flax_pretraining_model = PreTrainingModel(pretrained_config) + >>> pretrained_model_params = freeze(pretrained_params['target']) + >>> flax_model_outputs = flax_pretraining_model.apply({"params": pretrained_model_params}, tokens, attention_mask, type_ids, None, None, None, None, deterministic=True) + >>> masked_lm_logits[:, :3, :3] + """ + + model = FNetForMaskedLM.from_pretrained("google/fnet-base") + model.to(torch_device) + + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]], device=torch_device) + with torch.no_grad(): + output = model(input_ids)[0] + + vocab_size = 32000 + + expected_shape = torch.Size((1, 6, vocab_size)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[[-1.7819, -7.7384, -7.5002], [-3.4746, -8.5943, -7.7762], [-3.2052, -9.0771, -8.3468]]], + device=torch_device, + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) + + @slow + @require_tokenizers + def test_inference_long_sentence(self): + model = FNetForMaskedLM.from_pretrained("google/fnet-base") + model.to(torch_device) + tokenizer = FNetTokenizerFast.from_pretrained("google/fnet-base") + + inputs = tokenizer( + "the man worked as a [MASK].", + "this is his [MASK].", + return_tensors="pt", + padding="max_length", + max_length=512, + ) + inputs = {k: v.to(torch_device) for k, v in inputs.items()} + + logits = model(**inputs).logits + predictions_mask_1 = tokenizer.decode(logits[0, 6].topk(5).indices) + predictions_mask_2 = tokenizer.decode(logits[0, 12].topk(5).indices) + + self.assertEqual(predictions_mask_1.split(" "), ["man", "child", "teacher", "woman", "model"]) + self.assertEqual(predictions_mask_2.split(" "), ["work", "wife", "job", "story", "name"]) + + @slow + def test_inference_for_next_sentence_prediction(self): + model = FNetForNextSentencePrediction.from_pretrained("google/fnet-base") + model.to(torch_device) + + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]], device=torch_device) + with torch.no_grad(): + output = model(input_ids)[0] + + expected_shape = torch.Size((1, 2)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor([[-0.2234, -0.0226]], device=torch_device) + + self.assertTrue(torch.allclose(output, expected_slice, atol=1e-4)) + + @slow + def test_inference_model(self): + model = FNetModel.from_pretrained("google/fnet-base") + model.to(torch_device) + + input_ids = torch.tensor([[0, 1, 2, 3, 4, 5]], device=torch_device) + with torch.no_grad(): + output = model(input_ids)[0] + + expected_shape = torch.Size((1, 6, model.config.hidden_size)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[[4.1541, -0.1051, -0.1667], [-0.9144, 0.2939, -0.0086], [-0.8472, -0.7281, 0.0256]]], device=torch_device + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_tokenization_fnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_tokenization_fnet.py new file mode 100644 index 0000000000000000000000000000000000000000..17fe3e0dd3082014b3be3fb235d131c33f392d87 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fnet/test_tokenization_fnet.py @@ -0,0 +1,448 @@ +# coding=utf-8 +# Copyright 2019 Hugging Face inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import FNetTokenizer, FNetTokenizerFast +from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow, tooslow +from transformers.tokenization_utils import AddedToken + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/spiece.model") + + +@require_sentencepiece +@require_tokenizers +class FNetTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = FNetTokenizer + rust_tokenizer_class = FNetTokenizerFast + test_rust_tokenizer = True + test_sentencepiece = True + test_sentencepiece_ignore_case = True + test_seq2seq = False + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = FNetTokenizer(SAMPLE_VOCAB) + tokenizer.save_pretrained(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_text = "this is a test" + output_text = "this is a test" + return input_text, output_text + + def test_convert_token_and_id(self): + """Test ``_convert_token_to_id`` and ``_convert_id_to_token``.""" + token = "" + token_id = 0 + + self.assertEqual(self.get_tokenizer()._convert_token_to_id(token), token_id) + self.assertEqual(self.get_tokenizer()._convert_id_to_token(token_id), token) + + def test_get_vocab(self): + vocab_keys = list(self.get_tokenizer().get_vocab().keys()) + + self.assertEqual(vocab_keys[0], "") + self.assertEqual(vocab_keys[1], "") + self.assertEqual(vocab_keys[-1], "▁eloquent") + self.assertEqual(len(vocab_keys), 30_000) + + def test_vocab_size(self): + self.assertEqual(self.get_tokenizer().vocab_size, 30_000) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence = "I was born in 92000, and this is falsé." + + tokens = tokenizer.tokenize(sequence) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + rust_tokenizer = self.get_rust_tokenizer() + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + def test_full_tokenizer(self): + tokenizer = FNetTokenizer(SAMPLE_VOCAB, keep_accents=True) + + tokens = tokenizer.tokenize("This is a test") + self.assertListEqual(tokens, ["▁", "T", "his", "▁is", "▁a", "▁test"]) + + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [13, 1, 4398, 25, 21, 1289]) + + tokens = tokenizer.tokenize("I was born in 92000, and this is falsé.") + self.assertListEqual( + tokens, + ["▁", "I", "▁was", "▁born", "▁in", "▁9", "2000", ",", "▁and", "▁this", "▁is", "▁fal", "s", "é", "."], + ) + ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual(ids, [13, 1, 23, 386, 19, 561, 3050, 15, 17, 48, 25, 8256, 18, 1, 9]) + + back_tokens = tokenizer.convert_ids_to_tokens(ids) + self.assertListEqual( + back_tokens, + [ + "▁", + "", + "▁was", + "▁born", + "▁in", + "▁9", + "2000", + ",", + "▁and", + "▁this", + "▁is", + "▁fal", + "s", + "", + ".", + ], + ) + + def test_sequence_builders(self): + tokenizer = FNetTokenizer(SAMPLE_VOCAB) + + text = tokenizer.encode("sequence builders") + text_2 = tokenizer.encode("multi-sequence build") + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + assert encoded_pair == [tokenizer.cls_token_id] + text + [tokenizer.sep_token_id] + text_2 + [ + tokenizer.sep_token_id + ] + + # Overriden Tests - loading the fast tokenizer from slow just takes too long + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + r_output = tokenizer_r.encode("Hey this is a token") + + special_token_id = tokenizer_r.encode("", add_special_tokens=False)[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + p_output = tokenizer_p.encode("Hey this is a token") + + cr_output = tokenizer_r.encode("Hey this is a token") + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + @tooslow + def test_special_tokens_initialization_from_slow(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs, from_slow=True + ) + special_token_id = tokenizer_r.encode("", add_special_tokens=False)[0] + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + p_output = tokenizer_p.encode("Hey this is a token") + cr_output = tokenizer_r.encode("Hey this is a token") + + self.assertEqual(p_output, cr_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + # Overriden Tests + def test_padding(self, max_length=50): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + # Encode - Simple input + input_r = tokenizer_r.encode("This is a simple input", max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode("This is a simple input", max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode("This is a simple input", max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode("This is a simple input", max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.encode("This is a simple input", padding="longest") + input_p = tokenizer_p.encode("This is a simple input", padding=True) + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode - Pair input + input_r = tokenizer_r.encode( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode("This is a simple input", "This is a pair", padding=True) + input_p = tokenizer_p.encode("This is a simple input", "This is a pair", padding="longest") + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode_plus - Simple input + input_r = tokenizer_r.encode_plus( + "This is a simple input", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + input_r = tokenizer_r.encode_plus( + "This is a simple input", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + input_r = tokenizer_r.encode_plus("This is a simple input", padding="longest") + input_p = tokenizer_p.encode_plus("This is a simple input", padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Encode_plus - Pair input + input_r = tokenizer_r.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + input_r = tokenizer_r.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + input_r = tokenizer_r.encode_plus("This is a simple input", "This is a pair", padding="longest") + input_p = tokenizer_p.encode_plus("This is a simple input", "This is a pair", padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Batch_encode_plus - Simple input + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + pad_to_max_length=True, + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + pad_to_max_length=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="longest", + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], padding="longest" + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], padding=True + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Batch_encode_plus - Pair input + input_r = tokenizer_r.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + max_length=max_length, + truncation=True, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + max_length=max_length, + truncation=True, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + padding=True, + ) + input_p = tokenizer_p.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + padding="longest", + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus("This is a input 1") + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.encode_plus("This is a input 1") + input_p = tokenizer_r.pad(input_p) + + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus("This is a input 1") + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.encode_plus("This is a input 1") + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + # Using pad after tokenization + input_r = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_p = tokenizer_r.pad(input_p) + + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad after tokenization + input_r = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + @slow + def test_save_pretrained(self): + super().test_save_pretrained() + + @slow + def test_save_slow_from_fast_and_reload_fast(self): + super().test_save_slow_from_fast_and_reload_fast() + + def assert_batch_padded_input_match( + self, + input_r: dict, + input_p: dict, + max_length: int, + pad_token_id: int, + model_main_input_name: str = "input_ids", + ): + for i_r in input_r.values(): + self.assertEqual(len(i_r), 2), self.assertEqual(len(i_r[0]), max_length), self.assertEqual( + len(i_r[1]), max_length + ) + self.assertEqual(len(i_r), 2), self.assertEqual(len(i_r[0]), max_length), self.assertEqual( + len(i_r[1]), max_length + ) + + for i_r, i_p in zip(input_r[model_main_input_name], input_p[model_main_input_name]): + self.assert_padded_input_match(i_r, i_p, max_length, pad_token_id) + + @slow + def test_tokenizer_integration(self): + # fmt: off + expected_encoding = {'input_ids': [[4, 4616, 107, 163, 328, 14, 63, 1726, 106, 11954, 16659, 23, 83, 16688, 11427, 328, 107, 36, 11954, 16659, 23, 83, 16688, 6153, 82, 961, 16688, 3474, 16710, 1696, 2306, 16688, 10854, 2524, 3827, 561, 163, 3474, 16680, 62, 226, 2092, 16680, 379, 3474, 16660, 16680, 2436, 16667, 16671, 16680, 999, 87, 3474, 16680, 2436, 16667, 5208, 800, 16710, 68, 2018, 2959, 3037, 163, 16663, 11617, 16710, 36, 2018, 2959, 4737, 163, 16663, 16667, 16674, 16710, 91, 372, 5087, 16745, 2205, 82, 961, 3608, 38, 1770, 16745, 7984, 36, 2565, 751, 9017, 1204, 864, 218, 1244, 16680, 11954, 16659, 23, 83, 36, 14686, 23, 7619, 16678, 5], [4, 28, 532, 65, 1929, 33, 391, 16688, 3979, 9, 2565, 7849, 299, 225, 34, 2040, 305, 167, 289, 16667, 16078, 32, 1966, 181, 4626, 63, 10575, 71, 851, 1491, 36, 624, 4757, 38, 208, 8038, 16678, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 13, 1467, 5187, 26, 2521, 4567, 16664, 372, 13, 16209, 3314, 16678, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E501 + # fmt: on + + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="google/fnet-base", + revision="34219a71ca20e280cc6000b89673a169c65d605c", + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/focalnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/focalnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/focalnet/test_modeling_focalnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/focalnet/test_modeling_focalnet.py new file mode 100644 index 0000000000000000000000000000000000000000..75127e5fd3827229396716731ec189d8bcbb5d41 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/focalnet/test_modeling_focalnet.py @@ -0,0 +1,452 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch FocalNet model. """ + +import collections +import inspect +import unittest + +from transformers import FocalNetConfig +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...test_backbone_common import BackboneTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + FocalNetBackbone, + FocalNetForImageClassification, + FocalNetForMaskedImageModeling, + FocalNetModel, + ) + from transformers.models.focalnet.modeling_focalnet import FOCALNET_PRETRAINED_MODEL_ARCHIVE_LIST + +if is_vision_available(): + from PIL import Image + + from transformers import AutoImageProcessor + + +class FocalNetModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=32, + patch_size=2, + num_channels=3, + embed_dim=16, + hidden_sizes=[32, 64, 128], + depths=[1, 2, 1], + num_heads=[2, 2, 4], + window_size=2, + mlp_ratio=2.0, + qkv_bias=True, + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + drop_path_rate=0.1, + hidden_act="gelu", + use_absolute_embeddings=False, + patch_norm=True, + initializer_range=0.02, + layer_norm_eps=1e-5, + is_training=True, + scope=None, + use_labels=True, + type_sequence_label_size=10, + encoder_stride=8, + out_features=["stage1", "stage2"], + out_indices=[1, 2], + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.embed_dim = embed_dim + self.hidden_sizes = hidden_sizes + self.depths = depths + self.num_heads = num_heads + self.window_size = window_size + self.mlp_ratio = mlp_ratio + self.qkv_bias = qkv_bias + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.drop_path_rate = drop_path_rate + self.hidden_act = hidden_act + self.use_absolute_embeddings = use_absolute_embeddings + self.patch_norm = patch_norm + self.layer_norm_eps = layer_norm_eps + self.initializer_range = initializer_range + self.is_training = is_training + self.scope = scope + self.use_labels = use_labels + self.type_sequence_label_size = type_sequence_label_size + self.encoder_stride = encoder_stride + self.out_features = out_features + self.out_indices = out_indices + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + + config = self.get_config() + + return config, pixel_values, labels + + def get_config(self): + return FocalNetConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + embed_dim=self.embed_dim, + hidden_sizes=self.hidden_sizes, + depths=self.depths, + num_heads=self.num_heads, + window_size=self.window_size, + mlp_ratio=self.mlp_ratio, + qkv_bias=self.qkv_bias, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + drop_path_rate=self.drop_path_rate, + hidden_act=self.hidden_act, + use_absolute_embeddings=self.use_absolute_embeddings, + path_norm=self.patch_norm, + layer_norm_eps=self.layer_norm_eps, + initializer_range=self.initializer_range, + encoder_stride=self.encoder_stride, + out_features=self.out_features, + out_indices=self.out_indices, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = FocalNetModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + expected_seq_len = ((config.image_size // config.patch_size) ** 2) // (4 ** (len(config.depths) - 1)) + expected_dim = int(config.embed_dim * 2 ** (len(config.depths) - 1)) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, expected_seq_len, expected_dim)) + + def create_and_check_backbone(self, config, pixel_values, labels): + model = FocalNetBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify feature maps + self.parent.assertEqual(len(result.feature_maps), len(config.out_features)) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.image_size, 8, 8]) + + # verify channels + self.parent.assertEqual(len(model.channels), len(config.out_features)) + self.parent.assertListEqual(model.channels, config.hidden_sizes[:-1]) + + # verify backbone works with out_features=None + config.out_features = None + model = FocalNetBackbone(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + + # verify feature maps + self.parent.assertEqual(len(result.feature_maps), 1) + self.parent.assertListEqual(list(result.feature_maps[0].shape), [self.batch_size, self.image_size * 2, 4, 4]) + + # verify channels + self.parent.assertEqual(len(model.channels), 1) + self.parent.assertListEqual(model.channels, [config.hidden_sizes[-1]]) + + def create_and_check_for_masked_image_modeling(self, config, pixel_values, labels): + model = FocalNetForMaskedImageModeling(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual( + result.reconstruction.shape, (self.batch_size, self.num_channels, self.image_size, self.image_size) + ) + + # test greyscale images + config.num_channels = 1 + model = FocalNetForMaskedImageModeling(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.reconstruction.shape, (self.batch_size, 1, self.image_size, self.image_size)) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.type_sequence_label_size + model = FocalNetForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + # test greyscale images + config.num_channels = 1 + model = FocalNetForImageClassification(config) + model.to(torch_device) + model.eval() + + pixel_values = floats_tensor([self.batch_size, 1, self.image_size, self.image_size]) + result = model(pixel_values) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.type_sequence_label_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class FocalNetModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + FocalNetModel, + FocalNetForImageClassification, + FocalNetForMaskedImageModeling, + FocalNetBackbone, + ) + if is_torch_available() + else () + ) + fx_compatible = False + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = FocalNetModelTester(self) + self.config_tester = ConfigTester(self, config_class=FocalNetConfig, embed_dim=37, has_text_modality=False) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_backbone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_backbone(*config_and_inputs) + + def test_for_masked_image_modeling(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_image_modeling(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + @unittest.skip(reason="FocalNet does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="FocalNet does not use feedforward chunking") + def test_feed_forward_chunking(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes[:-1]: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes[:-1]: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def check_hidden_states_output(self, inputs_dict, config, model_class, image_size): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", len(self.model_tester.depths) + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # FocalNet has a different seq_length + patch_size = ( + config.patch_size + if isinstance(config.patch_size, collections.abc.Iterable) + else (config.patch_size, config.patch_size) + ) + + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [num_patches, self.model_tester.embed_dim], + ) + + reshaped_hidden_states = outputs.reshaped_hidden_states + self.assertEqual(len(reshaped_hidden_states), expected_num_layers) + + batch_size, num_channels, height, width = reshaped_hidden_states[0].shape + reshaped_hidden_states = ( + reshaped_hidden_states[0].view(batch_size, num_channels, height * width).permute(0, 2, 1) + ) + self.assertListEqual( + list(reshaped_hidden_states.shape[-2:]), + [num_patches, self.model_tester.embed_dim], + ) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + + for model_class in self.all_model_classes[:-1]: + inputs_dict["output_hidden_states"] = True + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + self.check_hidden_states_output(inputs_dict, config, model_class, image_size) + + def test_hidden_states_output_with_padding(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.patch_size = 3 + + image_size = ( + self.model_tester.image_size + if isinstance(self.model_tester.image_size, collections.abc.Iterable) + else (self.model_tester.image_size, self.model_tester.image_size) + ) + patch_size = ( + config.patch_size + if isinstance(config.patch_size, collections.abc.Iterable) + else (config.patch_size, config.patch_size) + ) + + padded_height = image_size[0] + patch_size[0] - (image_size[0] % patch_size[0]) + padded_width = image_size[1] + patch_size[1] - (image_size[1] % patch_size[1]) + + for model_class in self.all_model_classes[:-1]: + inputs_dict["output_hidden_states"] = True + self.check_hidden_states_output(inputs_dict, config, model_class, (padded_height, padded_width)) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + self.check_hidden_states_output(inputs_dict, config, model_class, (padded_height, padded_width)) + + @slow + def test_model_from_pretrained(self): + for model_name in FOCALNET_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = FocalNetModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if "embeddings" not in name and param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +@require_vision +@require_torch +class FocalNetModelIntegrationTest(unittest.TestCase): + @cached_property + def default_image_processor(self): + # TODO update organization + return AutoImageProcessor.from_pretrained("microsoft/focalnet-tiny") if is_vision_available() else None + + @slow + def test_inference_image_classification_head(self): + model = FocalNetForImageClassification.from_pretrained("microsoft/focalnet-tiny").to(torch_device) + image_processor = self.default_image_processor + + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + inputs = image_processor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + expected_slice = torch.tensor([0.2166, -0.4368, 0.2191]).to(torch_device) + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) + self.assertTrue(outputs.logits.argmax(dim=-1).item(), 281) + + +@require_torch +class FocalNetBackboneTest(BackboneTesterMixin, unittest.TestCase): + all_model_classes = (FocalNetBackbone,) if is_torch_available() else () + config_class = FocalNetConfig + + has_attentions = False + + def setUp(self): + self.model_tester = FocalNetModelTester(self) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_modeling_fsmt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_modeling_fsmt.py new file mode 100644 index 0000000000000000000000000000000000000000..7a39e82aeafd33746708d4676455f6120cc8298b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_modeling_fsmt.py @@ -0,0 +1,569 @@ +# coding=utf-8 +# Copyright 2020 Huggingface +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tempfile +import unittest + +import timeout_decorator # noqa +from parameterized import parameterized + +from transformers import FSMTConfig, is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import FSMTForConditionalGeneration, FSMTModel, FSMTTokenizer + from transformers.models.fsmt.modeling_fsmt import ( + SinusoidalPositionalEmbedding, + _prepare_fsmt_decoder_inputs, + invert_mask, + shift_tokens_right, + ) + from transformers.pipelines import TranslationPipeline + + +class FSMTModelTester: + def __init__( + self, + parent, + src_vocab_size=99, + tgt_vocab_size=99, + langs=["ru", "en"], + batch_size=13, + seq_length=7, + is_training=False, + use_labels=False, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="relu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + bos_token_id=0, + pad_token_id=1, + eos_token_id=2, + ): + self.parent = parent + self.src_vocab_size = src_vocab_size + self.tgt_vocab_size = tgt_vocab_size + self.langs = langs + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.bos_token_id = bos_token_id + self.pad_token_id = pad_token_id + self.eos_token_id = eos_token_id + torch.manual_seed(0) + + # hack needed for modeling_common tests - despite not really having this attribute in this model + self.vocab_size = self.src_vocab_size + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.src_vocab_size).clamp( + 3, + ) + input_ids[:, -1] = 2 # Eos Token + + config = self.get_config() + inputs_dict = prepare_fsmt_inputs_dict(config, input_ids) + return config, inputs_dict + + def get_config(self): + return FSMTConfig( + vocab_size=self.src_vocab_size, # hack needed for common tests + src_vocab_size=self.src_vocab_size, + tgt_vocab_size=self.tgt_vocab_size, + langs=self.langs, + 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_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + ) + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + inputs_dict["decoder_input_ids"] = inputs_dict["input_ids"] + inputs_dict["decoder_attention_mask"] = inputs_dict["attention_mask"] + inputs_dict["use_cache"] = False + return config, inputs_dict + + +def prepare_fsmt_inputs_dict( + config, + input_ids, + attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = input_ids.ne(config.pad_token_id) + if head_mask is None: + head_mask = torch.ones(config.encoder_layers, config.encoder_attention_heads, device=torch_device) + if decoder_head_mask is None: + decoder_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + if cross_attn_head_mask is None: + cross_attn_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + return { + "input_ids": input_ids, + "attention_mask": attention_mask, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + } + + +@require_torch +class FSMTModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (FSMTModel, FSMTForConditionalGeneration) if is_torch_available() else () + all_generative_model_classes = (FSMTForConditionalGeneration,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": FSMTForConditionalGeneration, + "feature-extraction": FSMTModel, + "summarization": FSMTForConditionalGeneration, + "text2text-generation": FSMTForConditionalGeneration, + "translation": FSMTForConditionalGeneration, + } + if is_torch_available() + else {} + ) + is_encoder_decoder = True + test_pruning = False + test_missing_keys = False + + def setUp(self): + self.model_tester = FSMTModelTester(self) + self.langs = ["en", "ru"] + config = { + "langs": self.langs, + "src_vocab_size": 10, + "tgt_vocab_size": 20, + } + # XXX: hack to appease to all other models requiring `vocab_size` + config["vocab_size"] = 99 # no such thing in FSMT + self.config_tester = ConfigTester(self, config_class=FSMTConfig, **config) + + def test_config(self): + self.config_tester.run_common_tests() + + # XXX: override test_model_common_attributes / different Embedding type + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Embedding)) + model.set_input_embeddings(nn.Embedding(10, 10)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.modules.sparse.Embedding)) + + def test_initialization_more(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + model = FSMTModel(config) + model.to(torch_device) + model.eval() + # test init + # self.assertTrue((model.encoder.embed_tokens.weight == model.shared.weight).all().item()) + + def _check_var(module): + """Check that we initialized various parameters from N(0, config.init_std).""" + self.assertAlmostEqual(torch.std(module.weight).item(), config.init_std, 2) + + _check_var(model.encoder.embed_tokens) + _check_var(model.encoder.layers[0].self_attn.k_proj) + _check_var(model.encoder.layers[0].fc1) + # XXX: different std for fairseq version of SinusoidalPositionalEmbedding + # self.assertAlmostEqual(torch.std(model.encoder.embed_positions.weights).item(), config.init_std, 2) + + def test_advanced_inputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + config.use_cache = False + inputs_dict["input_ids"][:, -2:] = config.pad_token_id + decoder_input_ids, decoder_attn_mask, causal_mask = _prepare_fsmt_decoder_inputs( + config, inputs_dict["input_ids"] + ) + model = FSMTModel(config).to(torch_device).eval() + + decoder_features_with_created_mask = model(**inputs_dict)[0] + decoder_features_with_passed_mask = model( + decoder_attention_mask=invert_mask(decoder_attn_mask), decoder_input_ids=decoder_input_ids, **inputs_dict + )[0] + _assert_tensors_equal(decoder_features_with_passed_mask, decoder_features_with_created_mask) + useless_mask = torch.zeros_like(decoder_attn_mask) + decoder_features = model(decoder_attention_mask=useless_mask, **inputs_dict)[0] + self.assertTrue(isinstance(decoder_features, torch.Tensor)) # no hidden states or attentions + self.assertEqual( + decoder_features.size(), + (self.model_tester.batch_size, self.model_tester.seq_length, config.tgt_vocab_size), + ) + if decoder_attn_mask.min().item() < -1e3: # some tokens were masked + self.assertFalse((decoder_features_with_created_mask == decoder_features).all().item()) + + # Test different encoder attention masks + decoder_features_with_long_encoder_mask = model( + inputs_dict["input_ids"], attention_mask=inputs_dict["attention_mask"].long() + )[0] + _assert_tensors_equal(decoder_features_with_long_encoder_mask, decoder_features_with_created_mask) + + def test_save_load_missing_keys(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + @unittest.skip("Test has a segmentation fault on torch 1.8.0") + def test_export_to_onnx(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + model = FSMTModel(config).to(torch_device) + with tempfile.TemporaryDirectory() as tmpdirname: + torch.onnx.export( + model, + (inputs_dict["input_ids"], inputs_dict["attention_mask"]), + f"{tmpdirname}/fsmt_test.onnx", + export_params=True, + opset_version=12, + input_names=["input_ids", "attention_mask"], + ) + + @unittest.skip("can't be implemented for FSMT due to dual vocab.") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip("Passing inputs_embeds not implemented for FSMT.") + def test_inputs_embeds(self): + pass + + @unittest.skip("model weights aren't tied in FSMT.") + def test_tie_model_weights(self): + pass + + @unittest.skip("TODO: Decoder embeddings cannot be resized at the moment") + def test_resize_embeddings_untied(self): + pass + + +@require_torch +class FSMTHeadTests(unittest.TestCase): + src_vocab_size = 99 + tgt_vocab_size = 99 + langs = ["ru", "en"] + + def _get_config(self): + return FSMTConfig( + src_vocab_size=self.src_vocab_size, + tgt_vocab_size=self.tgt_vocab_size, + langs=self.langs, + d_model=24, + encoder_layers=2, + decoder_layers=2, + encoder_attention_heads=2, + decoder_attention_heads=2, + encoder_ffn_dim=32, + decoder_ffn_dim=32, + max_position_embeddings=48, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ) + + def _get_config_and_data(self): + input_ids = torch.tensor( + [ + [71, 82, 18, 33, 46, 91, 2], + [68, 34, 26, 58, 30, 82, 2], + [5, 97, 17, 39, 94, 40, 2], + [76, 83, 94, 25, 70, 78, 2], + [87, 59, 41, 35, 48, 66, 2], + [55, 13, 16, 58, 5, 2, 1], # note padding + [64, 27, 31, 51, 12, 75, 2], + [52, 64, 86, 17, 83, 39, 2], + [48, 61, 9, 24, 71, 82, 2], + [26, 1, 60, 48, 22, 13, 2], + [21, 5, 62, 28, 14, 76, 2], + [45, 98, 37, 86, 59, 48, 2], + [70, 70, 50, 9, 28, 0, 2], + ], + dtype=torch.long, + device=torch_device, + ) + + batch_size = input_ids.shape[0] + config = self._get_config() + return config, input_ids, batch_size + + def test_generate_beam_search(self): + input_ids = torch.tensor([[71, 82, 2], [68, 34, 2]], dtype=torch.long, device=torch_device) + config = self._get_config() + lm_model = FSMTForConditionalGeneration(config).to(torch_device) + lm_model.eval() + + max_length = 5 + new_input_ids = lm_model.generate( + input_ids.clone(), + do_sample=True, + num_return_sequences=1, + num_beams=2, + no_repeat_ngram_size=3, + max_length=max_length, + ) + self.assertEqual(new_input_ids.shape, (input_ids.shape[0], max_length)) + + def test_shift_tokens_right(self): + input_ids = torch.tensor([[71, 82, 18, 33, 2, 1, 1], [68, 34, 26, 58, 30, 82, 2]], dtype=torch.long) + shifted = shift_tokens_right(input_ids, 1) + n_pad_before = input_ids.eq(1).float().sum() + n_pad_after = shifted.eq(1).float().sum() + self.assertEqual(shifted.shape, input_ids.shape) + self.assertEqual(n_pad_after, n_pad_before - 1) + self.assertTrue(torch.eq(shifted[:, 0], 2).all()) + + def test_generate_fp16(self): + config, input_ids, batch_size = self._get_config_and_data() + attention_mask = input_ids.ne(1).to(torch_device) + model = FSMTForConditionalGeneration(config).eval().to(torch_device) + if torch_device == "cuda": + model.half() + model.generate(input_ids, attention_mask=attention_mask) + model.generate(num_beams=4, do_sample=True, early_stopping=False, num_return_sequences=3) + + def test_dummy_inputs(self): + config, *_ = self._get_config_and_data() + model = FSMTForConditionalGeneration(config).eval().to(torch_device) + model(**model.dummy_inputs) + + def test_prepare_fsmt_decoder_inputs(self): + config, *_ = self._get_config_and_data() + input_ids = _long_tensor(([4, 4, 2])) + decoder_input_ids = _long_tensor([[26388, 2, config.pad_token_id]]) + causal_mask_dtype = torch.float32 + ignore = torch.finfo(causal_mask_dtype).min + decoder_input_ids, decoder_attn_mask, causal_mask = _prepare_fsmt_decoder_inputs( + config, input_ids, decoder_input_ids, causal_mask_dtype=causal_mask_dtype + ) + expected_causal_mask = torch.tensor( + [[0, ignore, ignore], [0, 0, ignore], [0, 0, 0]] # never attend to the final token, because its pad + ).to(input_ids.device) + self.assertEqual(decoder_attn_mask.size(), decoder_input_ids.size()) + self.assertTrue(torch.eq(expected_causal_mask, causal_mask).all()) + + +def _assert_tensors_equal(a, b, atol=1e-12, prefix=""): + """If tensors not close, or a and b arent both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if torch.allclose(a, b, atol=atol): + return True + raise + except Exception: + if len(prefix) > 0: + prefix = f"{prefix}: " + raise AssertionError(f"{prefix}{a} != {b}") + + +def _long_tensor(tok_lst): + return torch.tensor(tok_lst, dtype=torch.long, device=torch_device) + + +TOLERANCE = 1e-4 + + +pairs = [ + ["en-ru"], + ["ru-en"], + ["en-de"], + ["de-en"], +] + + +@require_torch +@require_sentencepiece +@require_tokenizers +class FSMTModelIntegrationTests(unittest.TestCase): + tokenizers_cache = {} + models_cache = {} + default_mname = "facebook/wmt19-en-ru" + + @cached_property + def default_tokenizer(self): + return self.get_tokenizer(self.default_mname) + + @cached_property + def default_model(self): + return self.get_model(self.default_mname) + + def get_tokenizer(self, mname): + if mname not in self.tokenizers_cache: + self.tokenizers_cache[mname] = FSMTTokenizer.from_pretrained(mname) + return self.tokenizers_cache[mname] + + def get_model(self, mname): + if mname not in self.models_cache: + self.models_cache[mname] = FSMTForConditionalGeneration.from_pretrained(mname).to(torch_device) + if torch_device == "cuda": + self.models_cache[mname].half() + return self.models_cache[mname] + + @slow + def test_inference_no_head(self): + tokenizer = self.default_tokenizer + model = FSMTModel.from_pretrained(self.default_mname).to(torch_device) + + src_text = "My friend computer will translate this for me" + input_ids = tokenizer([src_text], return_tensors="pt")["input_ids"] + input_ids = _long_tensor(input_ids).to(torch_device) + inputs_dict = prepare_fsmt_inputs_dict(model.config, input_ids) + with torch.no_grad(): + output = model(**inputs_dict)[0] + expected_shape = torch.Size((1, 10, model.config.tgt_vocab_size)) + self.assertEqual(output.shape, expected_shape) + # expected numbers were generated when en-ru model, using just fairseq's model4.pt + # may have to adjust if switched to a different checkpoint + expected_slice = torch.tensor( + [[-1.5753, -1.5753, 2.8975], [-0.9540, -0.9540, 1.0299], [-3.3131, -3.3131, 0.5219]] + ).to(torch_device) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def translation_setup(self, pair): + text = { + "en": "Machine learning is great, isn't it?", + "ru": "Машинное обучение - это здорово, не так ли?", + "de": "Maschinelles Lernen ist großartig, oder?", + } + + src, tgt = pair.split("-") + print(f"Testing {src} -> {tgt}") + mname = f"facebook/wmt19-{pair}" + + src_text = text[src] + tgt_text = text[tgt] + + tokenizer = self.get_tokenizer(mname) + model = self.get_model(mname) + return tokenizer, model, src_text, tgt_text + + @parameterized.expand(pairs) + @slow + def test_translation_direct(self, pair): + tokenizer, model, src_text, tgt_text = self.translation_setup(pair) + + input_ids = tokenizer.encode(src_text, return_tensors="pt").to(torch_device) + + outputs = model.generate(input_ids) + decoded = tokenizer.decode(outputs[0], skip_special_tokens=True) + assert decoded == tgt_text, f"\n\ngot: {decoded}\nexp: {tgt_text}\n" + + @parameterized.expand(pairs) + @slow + def test_translation_pipeline(self, pair): + tokenizer, model, src_text, tgt_text = self.translation_setup(pair) + device = 0 if torch_device == "cuda" else -1 + pipeline = TranslationPipeline(model, tokenizer, framework="pt", device=device) + output = pipeline([src_text]) + self.assertEqual([tgt_text], [x["translation_text"] for x in output]) + + +@require_torch +class TestSinusoidalPositionalEmbeddings(unittest.TestCase): + padding_idx = 1 + tolerance = 1e-4 + + def test_basic(self): + input_ids = torch.tensor([[4, 10]], dtype=torch.long, device=torch_device) + emb1 = SinusoidalPositionalEmbedding(num_positions=6, embedding_dim=6, padding_idx=self.padding_idx).to( + torch_device + ) + emb = emb1(input_ids) + desired_weights = torch.tensor( + [ + [9.0930e-01, 1.9999e-02, 2.0000e-04, -4.1615e-01, 9.9980e-01, 1.0000e00], + [1.4112e-01, 2.9995e-02, 3.0000e-04, -9.8999e-01, 9.9955e-01, 1.0000e00], + ] + ).to(torch_device) + self.assertTrue( + torch.allclose(emb[0], desired_weights, atol=self.tolerance), + msg=f"\nexp:\n{desired_weights}\ngot:\n{emb[0]}\n", + ) + + def test_odd_embed_dim(self): + # odd embedding_dim is allowed + SinusoidalPositionalEmbedding(num_positions=4, embedding_dim=5, padding_idx=self.padding_idx).to(torch_device) + + # odd num_embeddings is allowed + SinusoidalPositionalEmbedding(num_positions=5, embedding_dim=4, padding_idx=self.padding_idx).to(torch_device) + + @unittest.skip("different from marian (needs more research)") + def test_positional_emb_weights_against_marian(self): + desired_weights = torch.tensor( + [ + [0, 0, 0, 0, 0], + [0.84147096, 0.82177866, 0.80180490, 0.78165019, 0.76140374], + [0.90929741, 0.93651021, 0.95829457, 0.97505713, 0.98720258], + ] + ) + emb1 = SinusoidalPositionalEmbedding(num_positions=512, embedding_dim=512, padding_idx=self.padding_idx).to( + torch_device + ) + weights = emb1.weights.data[:3, :5] + # XXX: only the 1st and 3rd lines match - this is testing against + # verbatim copy of SinusoidalPositionalEmbedding from fairseq + self.assertTrue( + torch.allclose(weights, desired_weights, atol=self.tolerance), + msg=f"\nexp:\n{desired_weights}\ngot:\n{weights}\n", + ) + + # test that forward pass is just a lookup, there is no ignore padding logic + input_ids = torch.tensor( + [[4, 10, self.padding_idx, self.padding_idx, self.padding_idx]], dtype=torch.long, device=torch_device + ) + no_cache_pad_zero = emb1(input_ids)[0] + # XXX: only the 1st line matches the 3rd + self.assertTrue( + torch.allclose(torch.tensor(desired_weights, device=torch_device), no_cache_pad_zero[:3, :5], atol=1e-3) + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_tokenization_fsmt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_tokenization_fsmt.py new file mode 100644 index 0000000000000000000000000000000000000000..7407c2fbc8679561f88fa63384b77f6a8be6d25c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/fsmt/test_tokenization_fsmt.py @@ -0,0 +1,168 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers.models.fsmt.tokenization_fsmt import VOCAB_FILES_NAMES, FSMTTokenizer +from transformers.testing_utils import slow +from transformers.utils import cached_property + +from ...test_tokenization_common import TokenizerTesterMixin + + +# using a different tiny model than the one used for default params defined in init to ensure proper testing +FSMT_TINY2 = "stas/tiny-wmt19-en-ru" + + +class FSMTTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = FSMTTokenizer + test_rust_tokenizer = False + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "w", + "r", + "t", + "lo", + "low", + "er", + "low", + "lowest", + "newer", + "wider", + "", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["l o 123", "lo w 1456", "e r 1789", ""] + + self.langs = ["en", "ru"] + config = { + "langs": self.langs, + "src_vocab_size": 10, + "tgt_vocab_size": 20, + } + + self.src_vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["src_vocab_file"]) + self.tgt_vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["tgt_vocab_file"]) + config_file = os.path.join(self.tmpdirname, "tokenizer_config.json") + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.src_vocab_file, "w") as fp: + fp.write(json.dumps(vocab_tokens)) + with open(self.tgt_vocab_file, "w") as fp: + fp.write(json.dumps(vocab_tokens)) + with open(self.merges_file, "w") as fp: + fp.write("\n".join(merges)) + with open(config_file, "w") as fp: + fp.write(json.dumps(config)) + + @cached_property + def tokenizer_ru_en(self): + return FSMTTokenizer.from_pretrained("facebook/wmt19-ru-en") + + @cached_property + def tokenizer_en_ru(self): + return FSMTTokenizer.from_pretrained("facebook/wmt19-en-ru") + + def test_online_tokenizer_config(self): + """this just tests that the online tokenizer files get correctly fetched and + loaded via its tokenizer_config.json and it's not slow so it's run by normal CI + """ + tokenizer = FSMTTokenizer.from_pretrained(FSMT_TINY2) + self.assertListEqual([tokenizer.src_lang, tokenizer.tgt_lang], ["en", "ru"]) + self.assertEqual(tokenizer.src_vocab_size, 21) + self.assertEqual(tokenizer.tgt_vocab_size, 21) + + def test_full_tokenizer(self): + """Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt""" + tokenizer = FSMTTokenizer(self.langs, self.src_vocab_file, self.tgt_vocab_file, self.merges_file) + + text = "lower" + bpe_tokens = ["low", "er"] + tokens = tokenizer.tokenize(text) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [""] + input_bpe_tokens = [14, 15, 20] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_ru_en + + text = tokenizer.encode("sequence builders", add_special_tokens=False) + text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == text + [2] + assert encoded_pair == text + [2] + text_2 + [2] + + @slow + def test_match_encode_decode(self): + tokenizer_enc = self.tokenizer_en_ru + tokenizer_dec = self.tokenizer_ru_en + + targets = [ + [ + "Here's a little song I wrote. Don't worry, be happy.", + [2470, 39, 11, 2349, 7222, 70, 5979, 7, 8450, 1050, 13160, 5, 26, 6445, 7, 2], + ], + ["This is it. No more. I'm done!", [132, 21, 37, 7, 1434, 86, 7, 70, 6476, 1305, 427, 2]], + ] + + # if data needs to be recreated or added, run: + # import torch + # model = torch.hub.load("pytorch/fairseq", "transformer.wmt19.en-ru", checkpoint_file="model4.pt", tokenizer="moses", bpe="fastbpe") + # for src_text, _ in targets: print(f"""[\n"{src_text}",\n {model.encode(src_text).tolist()}\n],""") + + for src_text, tgt_input_ids in targets: + encoded_ids = tokenizer_enc.encode(src_text, return_tensors=None) + self.assertListEqual(encoded_ids, tgt_input_ids) + + # and decode backward, using the reversed languages model + decoded_text = tokenizer_dec.decode(encoded_ids, skip_special_tokens=True) + self.assertEqual(decoded_text, src_text) + + @slow + def test_tokenizer_lower(self): + tokenizer = FSMTTokenizer.from_pretrained("facebook/wmt19-ru-en", do_lower_case=True) + tokens = tokenizer.tokenize("USA is United States of America") + expected = ["us", "a", "is", "un", "i", "ted", "st", "ates", "of", "am", "er", "ica"] + self.assertListEqual(tokens, expected) + + @unittest.skip("FSMTConfig.__init__ requires non-optional args") + def test_torch_encode_plus_sent_to_model(self): + pass + + @unittest.skip("FSMTConfig.__init__ requires non-optional args") + def test_np_encode_plus_sent_to_model(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_funnel.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_funnel.py new file mode 100644 index 0000000000000000000000000000000000000000..e46e5dc58de63f465fc4fc70ecb054bd3b02f569 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_funnel.py @@ -0,0 +1,525 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import FunnelConfig, FunnelTokenizer, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_PRETRAINING_MAPPING, + FunnelBaseModel, + FunnelForMaskedLM, + FunnelForMultipleChoice, + FunnelForPreTraining, + FunnelForQuestionAnswering, + FunnelForSequenceClassification, + FunnelForTokenClassification, + FunnelModel, + ) + + +class FunnelModelTester: + """You can also import this e.g, from .test_modeling_funnel import FunnelModelTester""" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + block_sizes=[1, 1, 2], + num_decoder_layers=1, + d_model=32, + n_head=4, + d_head=8, + d_inner=37, + hidden_act="gelu_new", + hidden_dropout=0.1, + attention_dropout=0.1, + activation_dropout=0.0, + max_position_embeddings=512, + type_vocab_size=3, + initializer_std=0.02, # Set to a smaller value, so we can keep the small error threshold (1e-5) in the test + num_labels=3, + num_choices=4, + scope=None, + base=False, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.block_sizes = block_sizes + self.num_decoder_layers = num_decoder_layers + self.d_model = d_model + self.n_head = n_head + self.d_head = d_head + self.d_inner = d_inner + self.hidden_act = hidden_act + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = 2 + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.initializer_std = initializer_std + + # Used in the tests to check the size of the first attention layer + self.num_attention_heads = n_head + # Used in the tests to check the size of the first hidden state + self.hidden_size = self.d_model + # Used in the tests to check the number of output hidden states/attentions + self.num_hidden_layers = sum(self.block_sizes) + (0 if base else self.num_decoder_layers) + # FunnelModel adds two hidden layers: input embeddings and the sum of the upsampled encoder hidden state with + # the last hidden state of the first block (which is the first hidden state of the decoder). + if not base: + self.expected_num_hidden_layers = self.num_hidden_layers + 2 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + fake_token_labels = ids_tensor([self.batch_size, self.seq_length], 1) + + config = self.get_config() + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ) + + def get_config(self): + return FunnelConfig( + vocab_size=self.vocab_size, + block_sizes=self.block_sizes, + num_decoder_layers=self.num_decoder_layers, + d_model=self.d_model, + n_head=self.n_head, + d_head=self.d_head, + d_inner=self.d_inner, + hidden_act=self.hidden_act, + hidden_dropout=self.hidden_dropout, + attention_dropout=self.attention_dropout, + activation_dropout=self.activation_dropout, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_std=self.initializer_std, + ) + + def create_and_check_model( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = FunnelModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + model.config.truncate_seq = False + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + model.config.separate_cls = False + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + def create_and_check_base_model( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = FunnelBaseModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 2, self.d_model)) + + model.config.truncate_seq = False + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 3, self.d_model)) + + model.config.separate_cls = False + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 2, self.d_model)) + + def create_and_check_for_pretraining( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = FunnelForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=fake_token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_masked_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = FunnelForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = FunnelForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_choices = self.num_choices + model = FunnelForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_token_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + config.num_labels = self.num_labels + model = FunnelForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ): + model = FunnelForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + fake_token_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class FunnelModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_head_masking = False + test_pruning = False + all_model_classes = ( + ( + FunnelModel, + FunnelForMaskedLM, + FunnelForPreTraining, + FunnelForQuestionAnswering, + FunnelForTokenClassification, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": (FunnelBaseModel, FunnelModel), + "fill-mask": FunnelForMaskedLM, + "question-answering": FunnelForQuestionAnswering, + "text-classification": FunnelForSequenceClassification, + "token-classification": FunnelForTokenClassification, + "zero-shot": FunnelForSequenceClassification, + } + if is_torch_available() + else {} + ) + + # special case for ForPreTraining model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = FunnelModelTester(self) + self.config_tester = ConfigTester(self, config_class=FunnelConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + # overwrite from test_modeling_common + def _mock_init_weights(self, module): + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(3) + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.fill_(3) + + for param in ["r_w_bias", "r_r_bias", "r_kernel", "r_s_bias", "seg_embed"]: + if hasattr(module, param) and getattr(module, param) is not None: + weight = getattr(module, param) + weight.data.fill_(3) + + +@require_torch +class FunnelBaseModelTest(ModelTesterMixin, unittest.TestCase): + test_head_masking = False + test_pruning = False + all_model_classes = ( + (FunnelBaseModel, FunnelForMultipleChoice, FunnelForSequenceClassification) if is_torch_available() else () + ) + + def setUp(self): + self.model_tester = FunnelModelTester(self, base=True) + self.config_tester = ConfigTester(self, config_class=FunnelConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_base_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_base_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + # overwrite from test_modeling_common + def test_training(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class.__name__ == "FunnelBaseModel": + continue + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + # overwrite from test_modeling_common + def _mock_init_weights(self, module): + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(3) + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.fill_(3) + + for param in ["r_w_bias", "r_r_bias", "r_kernel", "r_s_bias", "seg_embed"]: + if hasattr(module, param) and getattr(module, param) is not None: + weight = getattr(module, param) + weight.data.fill_(3) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class FunnelModelIntegrationTest(unittest.TestCase): + def test_inference_tiny_model(self): + batch_size = 13 + sequence_length = 7 + input_ids = torch.arange(0, batch_size * sequence_length).long().reshape(batch_size, sequence_length) + lengths = [0, 1, 2, 3, 4, 5, 6, 4, 1, 3, 5, 0, 1] + token_type_ids = torch.tensor([[2] + [0] * a + [1] * (sequence_length - a - 1) for a in lengths]) + + model = FunnelModel.from_pretrained("sgugger/funnel-random-tiny") + output = model(input_ids, token_type_ids=token_type_ids)[0].abs() + + expected_output_sum = torch.tensor(2344.8352) + expected_output_mean = torch.tensor(0.8052) + self.assertTrue(torch.allclose(output.sum(), expected_output_sum, atol=1e-4)) + self.assertTrue(torch.allclose(output.mean(), expected_output_mean, atol=1e-4)) + + attention_mask = torch.tensor([[1] * 7, [1] * 4 + [0] * 3] * 6 + [[0, 1, 1, 0, 0, 1, 1]]) + output = model(input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)[0].abs() + + expected_output_sum = torch.tensor(2343.8425) + expected_output_mean = torch.tensor(0.8049) + self.assertTrue(torch.allclose(output.sum(), expected_output_sum, atol=1e-4)) + self.assertTrue(torch.allclose(output.mean(), expected_output_mean, atol=1e-4)) + + @slow + def test_inference_model(self): + tokenizer = FunnelTokenizer.from_pretrained("huggingface/funnel-small") + model = FunnelModel.from_pretrained("huggingface/funnel-small") + inputs = tokenizer("Hello! I am the Funnel Transformer model.", return_tensors="pt") + output = model(**inputs)[0] + + expected_output_sum = torch.tensor(235.7246) + expected_output_mean = torch.tensor(0.0256) + self.assertTrue(torch.allclose(output.sum(), expected_output_sum, atol=1e-4)) + self.assertTrue(torch.allclose(output.mean(), expected_output_mean, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_tf_funnel.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_tf_funnel.py new file mode 100644 index 0000000000000000000000000000000000000000..6780605e8936445cbcee81cc870eaaf7d0ffcbee --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_modeling_tf_funnel.py @@ -0,0 +1,425 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import FunnelConfig, is_tf_available +from transformers.testing_utils import require_tf, tooslow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TFFunnelBaseModel, + TFFunnelForMaskedLM, + TFFunnelForMultipleChoice, + TFFunnelForPreTraining, + TFFunnelForQuestionAnswering, + TFFunnelForSequenceClassification, + TFFunnelForTokenClassification, + TFFunnelModel, + ) + + +class TFFunnelModelTester: + """You can also import this e.g, from .test_modeling_funnel import FunnelModelTester""" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + block_sizes=[1, 1, 2], + num_decoder_layers=1, + d_model=32, + n_head=4, + d_head=8, + d_inner=37, + hidden_act="gelu_new", + hidden_dropout=0.1, + attention_dropout=0.1, + activation_dropout=0.0, + max_position_embeddings=512, + type_vocab_size=3, + initializer_std=0.02, # Set to a smaller value, so we can keep the small error threshold (1e-5) in the test + num_labels=3, + num_choices=4, + scope=None, + base=False, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.block_sizes = block_sizes + self.num_decoder_layers = num_decoder_layers + self.d_model = d_model + self.n_head = n_head + self.d_head = d_head + self.d_inner = d_inner + self.hidden_act = hidden_act + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = 2 + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.initializer_std = initializer_std + + # Used in the tests to check the size of the first attention layer + self.num_attention_heads = n_head + # Used in the tests to check the size of the first hidden state + self.hidden_size = self.d_model + # Used in the tests to check the number of output hidden states/attentions + self.num_hidden_layers = sum(self.block_sizes) + (0 if base else self.num_decoder_layers) + # FunnelModel adds two hidden layers: input embeddings and the sum of the upsampled encoder hidden state with + # the last hidden state of the first block (which is the first hidden state of the decoder). + if not base: + self.expected_num_hidden_layers = self.num_hidden_layers + 2 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = FunnelConfig( + vocab_size=self.vocab_size, + block_sizes=self.block_sizes, + num_decoder_layers=self.num_decoder_layers, + d_model=self.d_model, + n_head=self.n_head, + d_head=self.d_head, + d_inner=self.d_inner, + hidden_act=self.hidden_act, + hidden_dropout=self.hidden_dropout, + attention_dropout=self.attention_dropout, + activation_dropout=self.activation_dropout, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_std=self.initializer_std, + ) + + return ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) + + def create_and_check_model( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + model = TFFunnelModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + config.truncate_seq = False + model = TFFunnelModel(config=config) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + config.separate_cls = False + model = TFFunnelModel(config=config) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.d_model)) + + def create_and_check_base_model( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + model = TFFunnelBaseModel(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + + inputs = [input_ids, input_mask] + result = model(inputs) + + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 2, self.d_model)) + + config.truncate_seq = False + model = TFFunnelBaseModel(config=config) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 3, self.d_model)) + + config.separate_cls = False + model = TFFunnelBaseModel(config=config) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, 2, self.d_model)) + + def create_and_check_for_pretraining( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + model = TFFunnelForPreTraining(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_masked_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + model = TFFunnelForMaskedLM(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.num_labels = self.num_labels + model = TFFunnelForSequenceClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.num_choices = self.num_choices + model = TFFunnelForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + inputs = { + "input_ids": multiple_choice_inputs_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_token_classification( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + config.num_labels = self.num_labels + model = TFFunnelForTokenClassification(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ): + model = TFFunnelForQuestionAnswering(config=config) + inputs = {"input_ids": input_ids, "attention_mask": input_mask, "token_type_ids": token_type_ids} + result = model(inputs) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFFunnelModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFFunnelModel, + TFFunnelForMaskedLM, + TFFunnelForPreTraining, + TFFunnelForQuestionAnswering, + TFFunnelForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": (TFFunnelBaseModel, TFFunnelModel), + "fill-mask": TFFunnelForMaskedLM, + "question-answering": TFFunnelForQuestionAnswering, + "text-classification": TFFunnelForSequenceClassification, + "token-classification": TFFunnelForTokenClassification, + "zero-shot": TFFunnelForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFFunnelModelTester(self) + self.config_tester = ConfigTester(self, config_class=FunnelConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_pretraining(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + @tooslow + def test_saved_model_creation(self): + pass + + def test_compile_tf_model(self): + # This test fails the CI. TODO Lysandre re-enable it + pass + + +@require_tf +class TFFunnelBaseModelTest(TFModelTesterMixin, unittest.TestCase): + all_model_classes = ( + (TFFunnelBaseModel, TFFunnelForMultipleChoice, TFFunnelForSequenceClassification) if is_tf_available() else () + ) + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFFunnelModelTester(self, base=True) + self.config_tester = ConfigTester(self, config_class=FunnelConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_base_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_base_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + @tooslow + def test_saved_model_creation(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_tokenization_funnel.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_tokenization_funnel.py new file mode 100644 index 0000000000000000000000000000000000000000..6c5eb87db17ce5106cc03ffdd407f58ab1c540fb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/funnel/test_tokenization_funnel.py @@ -0,0 +1,82 @@ +# coding=utf-8 +# Copyright 2020 HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os +import unittest + +from transformers import FunnelTokenizer, FunnelTokenizerFast +from transformers.models.funnel.tokenization_funnel import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class FunnelTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = FunnelTokenizer + rust_tokenizer_class = FunnelTokenizerFast + test_rust_tokenizer = True + space_between_special_tokens = True + + def setUp(self): + super().setUp() + + vocab_tokens = [ + "", + "", + "", + "want", + "##want", + "##ed", + "wa", + "un", + "runn", + "##ing", + ",", + "low", + "lowest", + ] + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + def get_tokenizer(self, **kwargs): + return FunnelTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + return FunnelTokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "UNwant\u00E9d,running" + output_text = "unwanted, running" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + tokens = tokenizer.tokenize("UNwant\u00E9d,running") + self.assertListEqual(tokens, ["un", "##want", "##ed", ",", "runn", "##ing"]) + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [7, 4, 5, 10, 8, 9]) + + def test_token_type_ids(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + inputs = tokenizer("UNwant\u00E9d,running") + sentence_len = len(inputs["input_ids"]) - 1 + self.assertListEqual(inputs["token_type_ids"], [2] + [0] * sentence_len) + + inputs = tokenizer("UNwant\u00E9d,running", "UNwant\u00E9d,running") + self.assertListEqual(inputs["token_type_ids"], [2] + [0] * sentence_len + [1] * sentence_len) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_modeling_git.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_modeling_git.py new file mode 100644 index 0000000000000000000000000000000000000000..b6384ae15f905bda2be1312ad4decdd664437d8b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_modeling_git.py @@ -0,0 +1,541 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import inspect +import unittest + +from huggingface_hub import hf_hub_download + +from transformers import GitConfig, GitProcessor, GitVisionConfig, is_torch_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, 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 torch import nn + + from transformers import MODEL_FOR_CAUSAL_LM_MAPPING, GitForCausalLM, GitModel, GitVisionModel + from transformers.models.git.modeling_git import GIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + +class GitVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=32, + patch_size=16, + num_channels=3, + is_training=True, + hidden_size=32, + projection_dim=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.projection_dim = projection_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + # in ViT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token) + num_patches = (image_size // patch_size) ** 2 + self.seq_length = num_patches + 1 + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return GitVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + projection_dim=self.projection_dim, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = GitVisionModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + # expected sequence length = num_patches + 1 (we add 1 for the [CLS] token) + image_size = (self.image_size, self.image_size) + patch_size = (self.patch_size, self.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, num_patches + 1, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class GitVisionModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as GIT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (GitVisionModel,) if is_torch_available() else () + fx_compatible = True + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = GitVisionModelTester(self) + self.config_tester = ConfigTester(self, config_class=GitVisionConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="GIT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="GitVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="GitVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in GIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GitVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class GitModelTester: + def __init__( + self, + parent, + num_channels=3, + image_size=32, + patch_size=16, + batch_size=13, + text_seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + initializer_range=0.02, + num_labels=3, + scope=None, + ): + self.parent = parent + self.num_channels = num_channels + self.image_size = image_size + self.patch_size = patch_size + self.batch_size = batch_size + self.text_seq_length = text_seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.scope = scope + + # make sure the BOS, EOS and PAD tokens are within the vocab + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + # for GIT, the sequence length is the sum of the text and patch tokens, + 1 due to the CLS token + self.seq_length = self.text_seq_length + int((self.image_size / self.patch_size) ** 2) + 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.text_seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.text_seq_length]) + + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + config = self.get_config() + + return config, input_ids, input_mask, pixel_values + + def get_config(self): + """ + Returns a tiny configuration by default. + """ + return GitConfig( + vision_config={ + "num_channels": self.num_channels, + "image_size": self.image_size, + "patch_size": self.patch_size, + }, + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + ) + + def create_and_check_model(self, config, input_ids, input_mask, pixel_values): + model = GitModel(config=config) + model.to(torch_device) + model.eval() + + # inference with pixel values + result = model(input_ids, attention_mask=input_mask, pixel_values=pixel_values) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + # inference without pixel values + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.text_seq_length, self.hidden_size) + ) + + def create_and_check_for_causal_lm(self, config, input_ids, input_mask, pixel_values): + model = GitForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # inference with pixel values + result = model(input_ids, attention_mask=input_mask, pixel_values=pixel_values) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + # inference without pixel values + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.text_seq_length, self.vocab_size)) + + # training + result = model(input_ids, attention_mask=input_mask, pixel_values=pixel_values, labels=input_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertTrue(result.loss.item() > 0) + + def _test_beam_search_generate(self, config, input_ids, input_mask, pixel_values): + model = GitForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # generate + generated_ids = model.generate( + input_ids, + attention_mask=input_mask, + pixel_values=pixel_values, + do_sample=False, + max_length=20, + num_beams=2, + num_return_sequences=2, + ) + + self.parent.assertEqual(generated_ids.shape, (self.batch_size * 2, 20)) + + def _test_batched_generate_captioning(self, config, input_ids, input_mask, pixel_values): + model = GitForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # generate + generated_ids = model.generate( + input_ids=None, # captioning -> no input_ids + attention_mask=None, + pixel_values=pixel_values, + do_sample=False, + max_length=20, + num_beams=2, + num_return_sequences=2, + ) + + self.parent.assertEqual(generated_ids.shape, (self.batch_size * 2, 20)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + pixel_values, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": input_mask, + "pixel_values": pixel_values, + } + + return config, inputs_dict + + +@require_torch +class GitModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GitModel, GitForCausalLM) if is_torch_available() else () + all_generative_model_classes = (GitForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": GitModel, "text-generation": GitForCausalLM} if is_torch_available() else {} + ) + fx_compatible = False + test_torchscript = False + + # special case for GitForCausalLM model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class in get_values(MODEL_FOR_CAUSAL_LM_MAPPING): + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.text_seq_length), + dtype=torch.long, + device=torch_device, + ) + return inputs_dict + + def setUp(self): + self.model_tester = GitModelTester(self) + self.config_tester = ConfigTester(self, config_class=GitConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + def test_beam_search_generate(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester._test_beam_search_generate(*config_and_inputs) + + def test_batched_generate_captioning(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester._test_batched_generate_captioning(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in GIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GitModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @unittest.skip(reason="GIT has pixel values as additional input") + def test_beam_search_generate_dict_outputs_use_cache(self): + pass + + @unittest.skip(reason="GIT has pixel values as additional input") + def test_contrastive_generate(self): + pass + + @unittest.skip(reason="GIT has pixel values as additional input") + def test_contrastive_generate_dict_outputs_use_cache(self): + pass + + @unittest.skip(reason="GIT has pixel values as additional input") + def test_greedy_generate_dict_outputs_use_cache(self): + pass + + +@require_torch +@require_vision +@slow +class GitModelIntegrationTest(unittest.TestCase): + def test_forward_pass(self): + processor = GitProcessor.from_pretrained("microsoft/git-base") + model = GitForCausalLM.from_pretrained("microsoft/git-base") + + model.to(torch_device) + + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + inputs = processor(images=image, text="hello world", return_tensors="pt").to(torch_device) + + with torch.no_grad(): + outputs = model(**inputs) + + expected_shape = torch.Size((1, 201, 30522)) + self.assertEqual(outputs.logits.shape, expected_shape) + expected_slice = torch.tensor( + [[-0.9514, -0.9512, -0.9507], [-0.5454, -0.5453, -0.5453], [-0.8862, -0.8857, -0.8848]], + device=torch_device, + ) + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_slice, atol=1e-4)) + + def test_inference_image_captioning(self): + processor = GitProcessor.from_pretrained("microsoft/git-base") + model = GitForCausalLM.from_pretrained("microsoft/git-base") + model.to(torch_device) + + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + inputs = processor(images=image, return_tensors="pt") + pixel_values = inputs.pixel_values.to(torch_device) + + outputs = model.generate( + pixel_values=pixel_values, max_length=20, output_scores=True, return_dict_in_generate=True + ) + generated_caption = processor.batch_decode(outputs.sequences, skip_special_tokens=True)[0] + + expected_shape = torch.Size((1, 9)) + self.assertEqual(outputs.sequences.shape, expected_shape) + self.assertEquals(generated_caption, "two cats laying on a pink blanket") + self.assertTrue(outputs.scores[-1].shape, expected_shape) + expected_slice = torch.tensor([[-0.8805, -0.8803, -0.8799]], device=torch_device) + self.assertTrue(torch.allclose(outputs.scores[-1][0, :3], expected_slice, atol=1e-4)) + + def test_visual_question_answering(self): + processor = GitProcessor.from_pretrained("microsoft/git-base-textvqa") + model = GitForCausalLM.from_pretrained("microsoft/git-base-textvqa") + model.to(torch_device) + + # prepare image + file_path = hf_hub_download(repo_id="nielsr/textvqa-sample", filename="bus.png", repo_type="dataset") + image = Image.open(file_path).convert("RGB") + inputs = processor(images=image, return_tensors="pt") + pixel_values = inputs.pixel_values.to(torch_device) + + # prepare question + question = "what does the front of the bus say at the top?" + input_ids = processor(text=question, add_special_tokens=False).input_ids + input_ids = [processor.tokenizer.cls_token_id] + input_ids + input_ids = torch.tensor(input_ids).unsqueeze(0).to(torch_device) + + generated_ids = model.generate(pixel_values=pixel_values, input_ids=input_ids, max_length=20) + generated_caption = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] + + expected_shape = torch.Size((1, 15)) + self.assertEqual(generated_ids.shape, expected_shape) + self.assertEquals(generated_caption, "what does the front of the bus say at the top? special") + + def test_batched_generation(self): + processor = GitProcessor.from_pretrained("microsoft/git-base-coco") + model = GitForCausalLM.from_pretrained("microsoft/git-base-coco") + model.to(torch_device) + + # create batch of size 2 + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + inputs = processor(images=[image, image], return_tensors="pt") + pixel_values = inputs.pixel_values.to(torch_device) + + # we have to prepare `input_ids` with the same batch size as `pixel_values` + start_token_id = model.config.bos_token_id + input_ids = torch.tensor([[start_token_id], [start_token_id]], device=torch_device) + generated_ids = model.generate(pixel_values=pixel_values, input_ids=input_ids, max_length=50) + generated_captions = processor.batch_decode(generated_ids, skip_special_tokens=True) + + self.assertEquals(generated_captions, ["two cats sleeping on a pink blanket next to remotes."] * 2) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_processor_git.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_processor_git.py new file mode 100644 index 0000000000000000000000000000000000000000..95e436d8e4f5267e63236935147273c9b4ebe66a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/git/test_processor_git.py @@ -0,0 +1,153 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import shutil +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers.testing_utils import require_vision +from transformers.utils import is_vision_available + + +if is_vision_available(): + from PIL import Image + + from transformers import AutoProcessor, BertTokenizer, CLIPImageProcessor, GitProcessor, PreTrainedTokenizerFast + + +@require_vision +class GitProcessorTest(unittest.TestCase): + def setUp(self): + self.tmpdirname = tempfile.mkdtemp() + + image_processor = CLIPImageProcessor() + tokenizer = BertTokenizer.from_pretrained( + "hf-internal-testing/tiny-random-BertModel", model_input_names=["input_ids", "attention_mask"] + ) + + processor = GitProcessor(image_processor, tokenizer) + + processor.save_pretrained(self.tmpdirname) + + def get_tokenizer(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).tokenizer + + def get_image_processor(self, **kwargs): + return AutoProcessor.from_pretrained(self.tmpdirname, **kwargs).image_processor + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_additional_features(self): + processor = GitProcessor(tokenizer=self.get_tokenizer(), image_processor=self.get_image_processor()) + processor.save_pretrained(self.tmpdirname) + + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_normalize=False, padding_value=1.0) + + processor = GitProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_normalize=False, padding_value=1.0 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, PreTrainedTokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, CLIPImageProcessor) + + def test_image_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = GitProcessor(tokenizer=tokenizer, image_processor=image_processor) + + image_input = self.prepare_image_inputs() + + input_feat_extract = image_processor(image_input, return_tensors="np") + input_processor = processor(images=image_input, return_tensors="np") + + for key in input_feat_extract.keys(): + self.assertAlmostEqual(input_feat_extract[key].sum(), input_processor[key].sum(), delta=1e-2) + + def test_tokenizer(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = GitProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + + encoded_processor = processor(text=input_str) + + encoded_tok = tokenizer(input_str, return_token_type_ids=False) + + for key in encoded_tok.keys(): + self.assertListEqual(encoded_tok[key], encoded_processor[key]) + + def test_processor(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = GitProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + self.assertListEqual(list(inputs.keys()), ["input_ids", "attention_mask", "pixel_values"]) + + # test if it raises when no input is passed + with pytest.raises(ValueError): + processor() + + def test_tokenizer_decode(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = GitProcessor(tokenizer=tokenizer, image_processor=image_processor) + + predicted_ids = [[1, 4, 5, 8, 1, 0, 8], [3, 4, 3, 1, 1, 8, 9]] + + decoded_processor = processor.batch_decode(predicted_ids) + decoded_tok = tokenizer.batch_decode(predicted_ids) + + self.assertListEqual(decoded_tok, decoded_processor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = GitProcessor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + inputs = processor(text=input_str, images=image_input) + + # For now the processor supports only ['input_ids', 'attention_mask', 'pixel_values'] + self.assertListEqual(list(inputs.keys()), ["input_ids", "attention_mask", "pixel_values"]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_image_processing_glpn.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_image_processing_glpn.py new file mode 100644 index 0000000000000000000000000000000000000000..dddc2807bc046daf25e588abe1990b877fe8f8f4 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_image_processing_glpn.py @@ -0,0 +1,126 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import GLPNImageProcessor + + +class GLPNImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size_divisor=32, + do_rescale=True, + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size_divisor = size_divisor + self.do_rescale = do_rescale + + def prepare_image_processor_dict(self): + return { + "do_resize": self.do_resize, + "size_divisor": self.size_divisor, + "do_rescale": self.do_rescale, + } + + +@require_torch +@require_vision +class GLPNImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = GLPNImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = GLPNImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size_divisor")) + self.assertTrue(hasattr(image_processing, "resample")) + self.assertTrue(hasattr(image_processing, "do_rescale")) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input (GLPNImageProcessor doesn't support batching) + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input (GLPNImageProcessor doesn't support batching) + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input (GLPNImageProcessor doesn't support batching) + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertTrue(encoded_images.shape[-1] % self.image_processor_tester.size_divisor == 0) + self.assertTrue(encoded_images.shape[-2] % self.image_processor_tester.size_divisor == 0) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_modeling_glpn.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_modeling_glpn.py new file mode 100644 index 0000000000000000000000000000000000000000..bf279de9dff3975913b740b2cb419de4dce505ef --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/glpn/test_modeling_glpn.py @@ -0,0 +1,358 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch GLPN model. """ + + +import inspect +import unittest + +from transformers import is_torch_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import MODEL_MAPPING, GLPNConfig, GLPNForDepthEstimation, GLPNModel + from transformers.models.glpn.modeling_glpn import GLPN_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import GLPNFeatureExtractor + + +class GLPNConfigTester(ConfigTester): + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + self.parent.assertTrue(hasattr(config, "hidden_sizes")) + self.parent.assertTrue(hasattr(config, "num_attention_heads")) + self.parent.assertTrue(hasattr(config, "num_encoder_blocks")) + + +class GLPNModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=64, + num_channels=3, + num_encoder_blocks=4, + depths=[2, 2, 2, 2], + sr_ratios=[8, 4, 2, 1], + hidden_sizes=[16, 32, 64, 128], + downsampling_rates=[1, 4, 8, 16], + num_attention_heads=[1, 2, 4, 8], + is_training=True, + use_labels=True, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + initializer_range=0.02, + decoder_hidden_size=16, + num_labels=3, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.num_encoder_blocks = num_encoder_blocks + self.sr_ratios = sr_ratios + self.depths = depths + self.hidden_sizes = hidden_sizes + self.downsampling_rates = downsampling_rates + self.num_attention_heads = num_attention_heads + self.is_training = is_training + self.use_labels = use_labels + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.initializer_range = initializer_range + self.decoder_hidden_size = decoder_hidden_size + self.num_labels = num_labels + self.scope = scope + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size, self.image_size, self.image_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return GLPNConfig( + image_size=self.image_size, + num_channels=self.num_channels, + num_encoder_blocks=self.num_encoder_blocks, + depths=self.depths, + hidden_sizes=self.hidden_sizes, + num_attention_heads=self.num_attention_heads, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + initializer_range=self.initializer_range, + decoder_hidden_size=self.decoder_hidden_size, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = GLPNModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + expected_height = expected_width = self.image_size // (self.downsampling_rates[-1] * 2) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.hidden_sizes[-1], expected_height, expected_width) + ) + + def create_and_check_for_depth_estimation(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = GLPNForDepthEstimation(config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + self.parent.assertEqual(result.predicted_depth.shape, (self.batch_size, self.image_size, self.image_size)) + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.predicted_depth.shape, (self.batch_size, self.image_size, self.image_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class GLPNModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GLPNModel, GLPNForDepthEstimation) if is_torch_available() else () + pipeline_model_mapping = ( + {"depth-estimation": GLPNForDepthEstimation, "feature-extraction": GLPNModel} if is_torch_available() else {} + ) + + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + + def setUp(self): + self.model_tester = GLPNModelTester(self) + self.config_tester = GLPNConfigTester(self, config_class=GLPNConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_depth_estimation(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_depth_estimation(*config_and_inputs) + + @unittest.skip("GLPN does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip("GLPN does not have get_input_embeddings method and get_output_embeddings methods") + def test_model_common_attributes(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + + expected_num_attentions = sum(self.model_tester.depths) + self.assertEqual(len(attentions), expected_num_attentions) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + + self.assertEqual(len(attentions), expected_num_attentions) + + # verify the first attentions (first block, first layer) + expected_seq_len = (self.model_tester.image_size // 4) ** 2 + expected_reduced_seq_len = (self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2 + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len], + ) + + # verify the last attentions (last block, last layer) + expected_seq_len = (self.model_tester.image_size // 32) ** 2 + expected_reduced_seq_len = (self.model_tester.image_size // (32 * self.model_tester.sr_ratios[-1])) ** 2 + self.assertListEqual( + list(attentions[-1].shape[-3:]), + [self.model_tester.num_attention_heads[-1], expected_seq_len, expected_reduced_seq_len], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + self.assertEqual(out_len + 1, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), expected_num_attentions) + # verify the first attentions (first block, first layer) + expected_seq_len = (self.model_tester.image_size // 4) ** 2 + expected_reduced_seq_len = (self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2 + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len], + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = self.model_tester.num_encoder_blocks + self.assertEqual(len(hidden_states), expected_num_layers) + + # verify the first hidden states (first block) + self.assertListEqual( + list(hidden_states[0].shape[-3:]), + [ + self.model_tester.hidden_sizes[0], + self.model_tester.image_size // 4, + self.model_tester.image_size // 4, + ], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_training(self): + if not self.model_tester.is_training: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class in get_values(MODEL_MAPPING): + continue + # TODO: remove the following 3 lines once we have a MODEL_FOR_DEPTH_ESTIMATION_MAPPING + # this can then be incorporated into _prepare_for_class in test_modeling_common.py + if model_class.__name__ == "GLPNForDepthEstimation": + batch_size, num_channels, height, width = inputs_dict["pixel_values"].shape + inputs_dict["labels"] = torch.zeros( + [self.model_tester.batch_size, height, width], device=torch_device + ).long() + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + @slow + def test_model_from_pretrained(self): + for model_name in GLPN_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GLPNModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +@slow +class GLPNModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_depth_estimation(self): + feature_extractor = GLPNFeatureExtractor.from_pretrained(GLPN_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + model = GLPNForDepthEstimation.from_pretrained(GLPN_PRETRAINED_MODEL_ARCHIVE_LIST[0]).to(torch_device) + + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the predicted depth + expected_shape = torch.Size([1, 480, 640]) + self.assertEqual(outputs.predicted_depth.shape, expected_shape) + + expected_slice = torch.tensor( + [[3.4291, 2.7865, 2.5151], [3.2841, 2.7021, 2.3502], [3.1147, 2.4625, 2.2481]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.predicted_depth[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_flax_gpt2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_flax_gpt2.py new file mode 100644 index 0000000000000000000000000000000000000000..e842bbc73268d93b6f9d536f8ea2066bafb00ba3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_flax_gpt2.py @@ -0,0 +1,337 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +import numpy as np + +import transformers +from transformers import GPT2Config, GPT2Tokenizer, is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax, slow + +from ...generation.test_flax_utils import FlaxGenerationTesterMixin +from ...test_modeling_flax_common import FlaxModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask + + +if is_flax_available(): + import jax + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + from transformers.models.gpt2.modeling_flax_gpt2 import FlaxGPT2LMHeadModel, FlaxGPT2Model + +if is_torch_available(): + import torch + + +class FlaxGPT2ModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + initializer_range=0.02, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = GPT2Config( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + n_positions=self.max_position_embeddings, + use_cache=False, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + ) + + return (config, input_ids, input_mask) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": attention_mask} + return config, inputs_dict + + def prepare_config_and_inputs_for_decoder(self): + config, input_ids, attention_mask = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + attention_mask, + encoder_hidden_states, + encoder_attention_mask, + ) + + def check_use_cache_forward(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + attention_mask = jnp.ones((input_ids.shape[0], max_decoder_length), dtype="i4") + + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + attention_mask=attention_mask, + past_key_values=outputs_cache.past_key_values, + position_ids=position_ids, + ) + + outputs = model(input_ids) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def check_use_cache_forward_with_attn_mask(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + attention_mask_cache = jnp.concatenate( + [attention_mask, jnp.zeros((attention_mask.shape[0], max_decoder_length - attention_mask.shape[1]))], + axis=-1, + ) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask_cache, + past_key_values=past_key_values, + position_ids=position_ids, + ) + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + past_key_values=outputs_cache.past_key_values, + attention_mask=attention_mask_cache, + position_ids=position_ids, + ) + + outputs = model(input_ids, attention_mask=attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + +@require_flax +class FlaxGPT2ModelTest(FlaxModelTesterMixin, FlaxGenerationTesterMixin, unittest.TestCase): + all_model_classes = (FlaxGPT2Model, FlaxGPT2LMHeadModel) if is_flax_available() else () + all_generative_model_classes = (FlaxGPT2LMHeadModel,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxGPT2ModelTester(self) + + def test_use_cache_forward(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward(model_class_name, config, input_ids, attention_mask) + + def test_use_cache_forward_with_attn_mask(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward_with_attn_mask( + model_class_name, config, input_ids, attention_mask + ) + + @slow + def test_batch_generation(self): + tokenizer = GPT2Tokenizer.from_pretrained("gpt2", pad_token="", padding_side="left") + inputs = tokenizer(["Hello this is a long string", "Hey"], return_tensors="np", padding=True, truncation=True) + + model = FlaxGPT2LMHeadModel.from_pretrained("gpt2") + model.do_sample = False + model.config.pad_token_id = model.config.eos_token_id + + jit_generate = jax.jit(model.generate) + + output_sequences = jit_generate(inputs["input_ids"], attention_mask=inputs["attention_mask"]).sequences + + output_string = tokenizer.batch_decode(output_sequences, skip_special_tokens=True) + + expected_string = [ + "Hello this is a long string of words. I'm going to start with the first one.\n", + "Hey, I'm not sure if I'm going to be able to do", + ] + + self.assertListEqual(output_string, expected_string) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**prepared_inputs_dict).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded, pt_outputs): + self.assert_almost_equals(fx_output_loaded[:, -1], pt_output[:, -1].numpy(), 4e-2) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = pt_model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs, pt_outputs_loaded): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("gpt2", from_pt=True) + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_gpt2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_gpt2.py new file mode 100644 index 0000000000000000000000000000000000000000..0575b74e4c8e2972f75d794c6717fbbfab6d8544 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_gpt2.py @@ -0,0 +1,834 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import datetime +import math +import unittest + +from transformers import GPT2Config, 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 ( + GPT2_PRETRAINED_MODEL_ARCHIVE_LIST, + GPT2DoubleHeadsModel, + GPT2ForQuestionAnswering, + GPT2ForSequenceClassification, + GPT2ForTokenClassification, + GPT2LMHeadModel, + GPT2Model, + GPT2Tokenizer, + ) + + +class GPT2ModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def get_large_model_config(self): + return GPT2Config.from_pretrained("gpt2") + + def prepare_config_and_inputs( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config( + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + return GPT2Config( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + n_inner=self.intermediate_size, + activation_function=self.hidden_act, + resid_pdrop=self.hidden_dropout_prob, + attn_pdrop=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_gpt2_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPT2Model(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_gpt2_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPT2Model(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt2_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPT2Model(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt2_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPT2Model(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPT2LMHeadModel(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False + ): + model = GPT2LMHeadModel(config) + model.to(torch_device) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def create_and_check_double_lm_head_model( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, *args + ): + model = GPT2DoubleHeadsModel(config) + model.to(torch_device) + model.eval() + + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + + inputs = { + "input_ids": multiple_choice_inputs_ids, + "mc_token_ids": mc_token_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + "labels": multiple_choice_inputs_ids, + } + + result = model(**inputs) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_choices, self.seq_length, self.vocab_size) + ) + self.parent.assertEqual(result.mc_logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_gpt2_for_question_answering( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPT2ForQuestionAnswering(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_gpt2_for_sequence_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPT2ForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_gpt2_for_token_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPT2ForTokenClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_gpt2_weight_initialization(self, config, *args): + model = GPT2Model(config) + model_std = model.config.initializer_range / math.sqrt(2 * model.config.n_layer) + for key in model.state_dict().keys(): + if "c_proj" in key and "weight" in key: + self.parent.assertLessEqual(abs(torch.std(model.state_dict()[key]) - model_std), 0.001) + self.parent.assertLessEqual(abs(torch.mean(model.state_dict()[key]) - 0.0), 0.01) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "head_mask": head_mask, + } + + return config, inputs_dict + + +@require_torch +class GPT2ModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + GPT2Model, + GPT2LMHeadModel, + GPT2DoubleHeadsModel, + GPT2ForQuestionAnswering, + GPT2ForSequenceClassification, + GPT2ForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (GPT2LMHeadModel, GPT2DoubleHeadsModel) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": GPT2Model, + "question-answering": GPT2ForQuestionAnswering, + "text-classification": GPT2ForSequenceClassification, + "text-generation": GPT2LMHeadModel, + "token-classification": GPT2ForTokenClassification, + "zero-shot": GPT2ForSequenceClassification, + } + if is_torch_available() + else {} + ) + all_parallelizable_model_classes = (GPT2LMHeadModel, GPT2DoubleHeadsModel) if is_torch_available() else () + fx_compatible = True + test_missing_keys = False + test_model_parallel = True + + # special case for DoubleHeads model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "GPT2DoubleHeadsModel": + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.num_choices, self.model_tester.seq_length), + dtype=torch.long, + device=torch_device, + ) + inputs_dict["input_ids"] = inputs_dict["labels"] + inputs_dict["token_type_ids"] = inputs_dict["labels"] + inputs_dict["mc_token_ids"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.num_choices), + dtype=torch.long, + device=torch_device, + ) + inputs_dict["mc_labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = GPT2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPT2Config, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_gpt2_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model(*config_and_inputs) + + def test_gpt2_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_past(*config_and_inputs) + + def test_gpt2_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_attention_mask_past(*config_and_inputs) + + def test_gpt2_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_past_large_inputs(*config_and_inputs) + + def test_gpt2_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_gpt2_double_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_double_lm_head_model(*config_and_inputs) + + def test_gpt2_question_answering_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_for_question_answering(*config_and_inputs) + + def test_gpt2_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_for_sequence_classification(*config_and_inputs) + + def test_gpt2_token_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_for_token_classification(*config_and_inputs) + + def test_gpt2_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + def test_gpt2_scale_attn_by_inverse_layer_idx(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs(scale_attn_by_inverse_layer_idx=True) + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) + + def test_gpt2_reorder_and_upcast_attn(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs(reorder_and_upcast_attn=True) + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) + + def test_gpt2_weight_initialization(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_weight_initialization(*config_and_inputs) + + @slow + def test_batch_generation(self): + model = GPT2LMHeadModel.from_pretrained("gpt2") + model.to(torch_device) + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = [ + "Hello, my dog is a little", + "Today, I", + ] + + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item() + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + "Hello, my dog is a little bit of a mess. I'm not sure if he's going", + "Today, I'm going to be doing a lot of research on this. I", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_batch_generation_2heads(self): + model = GPT2DoubleHeadsModel.from_pretrained("gpt2") + model.to(torch_device) + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + + tokenizer.padding_side = "left" + + # This tokenizer has no pad token, so we have to set it in some way + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = [ + "Hello, my dog is a little", + "Today, I", + ] + + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item() + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + "Hello, my dog is a little bit of a mess. I'm not sure if he's going", + "Today, I'm going to be doing a lot of research on this. I", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_model_from_pretrained(self): + for model_name in GPT2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GPT2Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class GPT2ModelLanguageGenerationTest(unittest.TestCase): + def _test_lm_generate_gpt2_helper( + self, + gradient_checkpointing=False, + reorder_and_upcast_attn=False, + scale_attn_by_inverse_layer_idx=False, + verify_outputs=True, + ): + model = GPT2LMHeadModel.from_pretrained( + "gpt2", + reorder_and_upcast_attn=reorder_and_upcast_attn, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + ) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + else: + model.gradient_checkpointing_disable() + model.to(torch_device) + + # The dog + input_ids = torch.tensor([[464, 3290]], dtype=torch.long, device=torch_device) + + # The dog was found in a field near the intersection of West and West Streets.\n\nThe dog + # fmt: off + expected_output_ids = [ + 464, 3290, 373, 1043, 287, 257, 2214, 1474, 262, 16246, 286, 2688, 290, 2688, 27262, 13, 198, 198, 464, 3290, + ] + # fmt: on + output_ids = model.generate(input_ids, do_sample=False) + if verify_outputs: + self.assertListEqual(output_ids[0].tolist(), expected_output_ids) + + @slow + def test_lm_generate_gpt2(self): + self._test_lm_generate_gpt2_helper() + + @slow + def test_lm_generate_gpt2_with_gradient_checkpointing(self): + self._test_lm_generate_gpt2_helper(gradient_checkpointing=True) + + @slow + def test_lm_generate_gpt2_with_reorder_and_upcast_attn(self): + self._test_lm_generate_gpt2_helper(reorder_and_upcast_attn=True) + + @slow + def test_lm_generate_gpt2_with_scale_attn_by_inverse_layer_idx(self): + self._test_lm_generate_gpt2_helper(scale_attn_by_inverse_layer_idx=True, verify_outputs=False) + + @slow + def test_gpt2_sample(self): + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + model = GPT2LMHeadModel.from_pretrained("gpt2") + model.to(torch_device) + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + output_ids = model.generate(input_ids, do_sample=True) + output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True) + + token_type_ids = tokenized.token_type_ids.to(torch_device) + output_seq = model.generate(input_ids=input_ids, do_sample=True, num_return_sequences=5) + output_seq_tt = model.generate( + input_ids=input_ids, token_type_ids=token_type_ids, do_sample=True, num_return_sequences=5 + ) + output_seq_strs = tokenizer.batch_decode(output_seq, skip_special_tokens=True) + output_seq_tt_strs = tokenizer.batch_decode(output_seq_tt, skip_special_tokens=True) + + EXPECTED_OUTPUT_STR = ( + "Today is a nice day and if you don't know anything about the state of play during your holiday" + ) + self.assertEqual(output_str, EXPECTED_OUTPUT_STR) + self.assertTrue( + all([output_seq_strs[idx] != output_seq_tt_strs[idx] for idx in range(len(output_seq_tt_strs))]) + ) # token_type_ids should change output + + @slow + def test_gpt2_sample_max_time(self): + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + model = GPT2LMHeadModel.from_pretrained("gpt2") + model.to(torch_device) + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + + MAX_TIME = 0.5 + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=None, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + @slow + def test_contrastive_search_gpt2(self): + article = ( + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based" + ) + + gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2-large") + gpt2_model = GPT2LMHeadModel.from_pretrained("gpt2-large").to(torch_device) + input_ids = gpt2_tokenizer(article, return_tensors="pt").input_ids.to(torch_device) + + outputs = gpt2_model.generate(input_ids, penalty_alpha=0.6, top_k=4, max_length=256) + + generated_text = gpt2_tokenizer.batch_decode(outputs, skip_special_tokens=True) + + self.assertListEqual( + generated_text, + [ + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based in London, " + "United Kingdom\n\nGoogle has a lot of data on its users and uses it to improve its products, such as " + "Google Now, which helps users find the information they're looking for on the web. But the company " + "is not the only one to collect data on its users. Facebook, for example, has its own facial " + "recognition technology, as well as a database of millions of photos that it uses to personalize its " + "News Feed.\n\nFacebook's use of data is a hot topic in the tech industry, with privacy advocates " + "concerned about the company's ability to keep users' information private. In a blog post last " + 'year, Facebook CEO Mark Zuckerberg said his company would "do our best to be transparent about our ' + 'data use and how we use it."\n\n"We have made it clear that we do not sell or share your data with ' + 'third parties," Zuckerberg wrote. "If you have questions or concerns, please reach out to us at ' + 'privacy@facebook.com."\n\nGoogle declined to comment on the privacy implications of its use of data, ' + "but said in a statement to The Associated Press that" + ], + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_tf_gpt2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_tf_gpt2.py new file mode 100644 index 0000000000000000000000000000000000000000..7171997546d6b4151a10d894079d2c118bcc5b51 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_modeling_tf_gpt2.py @@ -0,0 +1,750 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import GPT2Config, is_tf_available +from transformers.testing_utils import require_tf, require_tf2onnx, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin +from ...utils.test_modeling_tf_core import TFCoreModelTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import GPT2Tokenizer + from transformers.models.gpt2.modeling_tf_gpt2 import ( + TF_GPT2_PRETRAINED_MODEL_ARCHIVE_LIST, + TFGPT2DoubleHeadsModel, + TFGPT2ForSequenceClassification, + TFGPT2LMHeadModel, + TFGPT2Model, + ) + from transformers.tf_utils import shape_list + + +class TFGPT2ModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_token_type_ids = True + self.use_input_mask = True + self.use_labels = True + self.use_mc_token_ids = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + self.bos_token_id = self.vocab_size - 1 + self.eos_token_id = self.vocab_size - 1 + self.pad_token_id = self.vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = GPT2Config( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + # intermediate_size=self.intermediate_size, + # hidden_act=self.hidden_act, + # hidden_dropout_prob=self.hidden_dropout_prob, + # attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + # type_vocab_size=self.type_vocab_size, + # initializer_range=self.initializer_range + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + return_dict=True, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_gpt2_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPT2Model(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + + inputs = [input_ids, None, input_mask] # None is the input for 'past' + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_gpt2_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPT2Model(config=config) + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_token_type_ids = tf.concat([token_type_ids, next_token_types], axis=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_gpt2_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = TFGPT2Model(config=config) + + # create attention mask + half_seq_length = self.seq_length // 2 + attn_mask_begin = tf.ones((self.batch_size, half_seq_length), dtype=tf.int32) + attn_mask_end = tf.zeros((self.batch_size, self.seq_length - half_seq_length), dtype=tf.int32) + attn_mask = tf.concat([attn_mask_begin, attn_mask_end], axis=1) + + # first forward pass + output, past_key_values = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).numpy() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, self.seq_length), config.vocab_size) + vector_condition = tf.range(self.seq_length) == (self.seq_length - random_seq_idx_to_change) + condition = tf.transpose( + tf.broadcast_to(tf.expand_dims(vector_condition, -1), (self.seq_length, self.batch_size)) + ) + input_ids = tf.where(condition, random_other_next_tokens, input_ids) + + # append to next input_ids and attn_mask + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + attn_mask = tf.concat([attn_mask, tf.ones((shape_list(attn_mask)[0], 1), dtype=tf.int32)], axis=1) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values, attention_mask=attn_mask)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-12) + + def create_and_check_gpt2_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = TFGPT2Model(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + token_type_ids = token_type_ids[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + next_token_types = ids_tensor((self.batch_size, 3), self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + next_token_type_ids = tf.concat([token_type_ids, next_token_types], axis=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, + token_type_ids=next_token_types, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_gpt2_lm_head(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPT2LMHeadModel(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_gpt2_double_head( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, *args + ): + model = TFGPT2DoubleHeadsModel(config=config) + + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + + inputs = { + "input_ids": multiple_choice_inputs_ids, + "mc_token_ids": mc_token_ids, + "attention_mask": multiple_choice_input_mask, + "token_type_ids": multiple_choice_token_type_ids, + } + result = model(inputs) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.num_choices, self.seq_length, self.vocab_size) + ) + self.parent.assertEqual(result.mc_logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_gpt2_for_sequence_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + "labels": sequence_labels, + } + model = TFGPT2ForSequenceClassification(config) + + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_tf +class TFGPT2ModelTest(TFModelTesterMixin, TFCoreModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + (TFGPT2Model, TFGPT2LMHeadModel, TFGPT2ForSequenceClassification, TFGPT2DoubleHeadsModel) + if is_tf_available() + else () + ) + all_generative_model_classes = (TFGPT2LMHeadModel,) if is_tf_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": TFGPT2Model, + "text-classification": TFGPT2ForSequenceClassification, + "text-generation": TFGPT2LMHeadModel, + "zero-shot": TFGPT2ForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = True + onnx_min_opset = 10 + + def setUp(self): + self.model_tester = TFGPT2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPT2Config, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_gpt2_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model(*config_and_inputs) + + def test_gpt2_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_past(*config_and_inputs) + + def test_gpt2_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_attention_mask_past(*config_and_inputs) + + def test_gpt2_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_model_past_large_inputs(*config_and_inputs) + + def test_gpt2_lm_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_lm_head(*config_and_inputs) + + def test_gpt2_double_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_double_head(*config_and_inputs) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in self.all_generative_model_classes: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert name is None + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + def test_gpt2_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt2_for_sequence_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_GPT2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFGPT2Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + # overwrite from common since ONNX runtime optimization doesn't work with tf.gather() when the argument + # `batch_dims` > 0" + @require_tf2onnx + @slow + def test_onnx_runtime_optimize(self): + if not self.test_onnx: + return + + import onnxruntime + import tf2onnx + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + # Skip these 2 classes which uses `tf.gather` with `batch_dims=1` + if model_class in [TFGPT2ForSequenceClassification, TFGPT2DoubleHeadsModel]: + continue + + model = model_class(config) + model(model.dummy_inputs) + + onnx_model_proto, _ = tf2onnx.convert.from_keras(model, opset=self.onnx_min_opset) + + onnxruntime.InferenceSession(onnx_model_proto.SerializeToString()) + + # TODO (Joao): fix me + @unittest.skip("Onnx compliancy broke with TF 2.10") + def test_onnx_compliancy(self): + pass + + +@require_tf +class TFGPT2ModelLanguageGenerationTest(unittest.TestCase): + @slow + def test_lm_generate_greedy_distilgpt2_batch_special(self): + model = TFGPT2LMHeadModel.from_pretrained("distilgpt2") + tokenizer = GPT2Tokenizer.from_pretrained("distilgpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentences = ["Today is a beautiful day and", "Yesterday was"] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + + generation_kwargs = { + "bad_words_ids": [tokenizer("is").input_ids, tokenizer("angry about").input_ids], + "no_repeat_ngram_size": 2, + "do_sample": False, + "repetition_penalty": 1.3, + } + + output_ids = model.generate(**input_ids, **generation_kwargs) + + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + expected_output_string = [ + "Today is a beautiful day and I am so happy to be able take part in this amazing event.", + "Yesterday was a very interesting time for the world to see how much of this is", + ] + self.assertListEqual(output_strings, expected_output_string) + + @slow + def test_lm_generate_sample_distilgpt2_batch_special(self): + model = TFGPT2LMHeadModel.from_pretrained("distilgpt2") + tokenizer = GPT2Tokenizer.from_pretrained("distilgpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentences = ["Today is a beautiful day and", "Yesterday was"] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + + generation_kwargs = { + "do_sample": True, + "bad_words_ids": [tokenizer("is").input_ids, tokenizer("angry about").input_ids], + "no_repeat_ngram_size": 2, + "repetition_penalty": 1.3, + "temperature": 1.5, + "top_k": 500, + "top_p": 0.9, + "seed": [42, 0], # seed set -> deterministic sampling sequence -> deterministic generation + } + + # forces the generation to happen on CPU, to avoid GPU-related quirks + with tf.device(":/CPU:0"): + output_ids = model.generate(**input_ids, **generation_kwargs) + + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + + expected_output_string = [ + "Today is a beautiful day and we will make you feel very hot/terrific in all your", + "Yesterday was known by national television networks as Le Big Show or Wild Dog Jeopard", + ] + self.assertListEqual(output_strings, expected_output_string) + + @slow + def test_lm_generate_greedy_distilgpt2_beam_search_special(self): + model = TFGPT2LMHeadModel.from_pretrained("distilgpt2") + tokenizer = GPT2Tokenizer.from_pretrained("distilgpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentences = ["Today is a beautiful day and", "Yesterday was"] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + + generation_kwargs = { + "bad_words_ids": [tokenizer("is").input_ids, tokenizer("angry about").input_ids], + "no_repeat_ngram_size": 2, + "do_sample": False, + "num_beams": 2, + } + + output_ids = model.generate(**input_ids, **generation_kwargs) + + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + expected_output_string = [ + "Today is a beautiful day and a great day for all of us.\n\nI’m", + "Yesterday was the first time that a person has been arrested in the United States for", + ] + self.assertListEqual(output_strings, expected_output_string) + + @slow + def test_lm_generate_distilgpt2_left_padding(self): + """Tests that the generated text is the same, regarless of left padding""" + model = TFGPT2LMHeadModel.from_pretrained("distilgpt2") + tokenizer = GPT2Tokenizer.from_pretrained("distilgpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + generation_kwargs = { + "bad_words_ids": [tokenizer("is").input_ids, tokenizer("angry about").input_ids], + "no_repeat_ngram_size": 2, + "do_sample": False, + "repetition_penalty": 1.3, + } + expected_output_string = ( + "Today is a beautiful day and I am so happy to be able take part in this amazing event." + ) + + sentences = ["Today is a beautiful day and"] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + # using default length + output_ids = model.generate(**input_ids, **generation_kwargs) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertEqual(output_strings[0], expected_output_string) + + sentences = ["Today is a beautiful day and", "This is a very long input that we absolutely don't care about"] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + # longer max length to capture the full length (remember: it is left padded) + output_ids = model.generate(**input_ids, **generation_kwargs, max_length=27) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertEqual(output_strings[0], expected_output_string) + + @slow + def test_lm_generate_gpt2_greedy_xla(self): + model = TFGPT2LMHeadModel.from_pretrained("gpt2") + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentences = ["The dog", "The flying machine"] + expected_output_strings = [ + "The dog was found in a field near the intersection of West and West Streets.\n\nThe", + "The flying machine is a small, lightweight, and lightweight aircraft that can be used for any type of", + ] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + + output_ids = model.generate(**input_ids, do_sample=False) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_strings) + + xla_generate = tf.function(model.generate, jit_compile=True) + output_ids = xla_generate(**input_ids, do_sample=False) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_strings) + + @slow + def test_lm_generate_gpt2_sample_xla(self): + # NOTE: due to the small numerical differences that are natural when we compile to XLA, sampling the same + # output out of the same seed is far from guaranteed. We can, however, confirm that the results are sensible + # and that we can seed both versions. + + # forces the generation to happen on CPU, to avoid GPU-related quirks + with tf.device(":/CPU:0"): + model = TFGPT2LMHeadModel.from_pretrained("gpt2") + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentence = ["The dog", "The flying machine"] + expected_output_string = [ + "The dog owner asked why did our vet decide there needed to be extra ventilation inside because most" + " puppies", + "The flying machine was made by an artist who found it difficult to control it as it did not use", + ] + expected_output_string_xla = [ + "The dog has been named in connection with the murder of a 20-year-old man in", + "The flying machine is a new and improved system to operate and operate a new system and system " + "system system", + ] + input_ids = tokenizer(sentence, return_tensors="tf", padding=True) + + output_ids = model.generate(**input_ids, do_sample=True, seed=[7, 0]) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_string) + + xla_generate = tf.function(model.generate, jit_compile=True) + output_ids = xla_generate(**input_ids, do_sample=True, seed=[7, 0]) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_string_xla) + + @slow + def test_lm_generate_gpt2_beam_search_xla(self): + model = TFGPT2LMHeadModel.from_pretrained("gpt2") + tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + sentences = ["The dog", "The flying machine"] + expected_output_strings = [ + "The dog was found in the backyard of a home in the 6500 block of South Main Street", + "The flying machine is a very powerful machine, but it's not a very powerful machine. It's", + ] + input_ids = tokenizer(sentences, return_tensors="tf", padding=True) + + output_ids = model.generate(**input_ids, do_sample=False, num_beams=2) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_strings) + + xla_generate = tf.function(model.generate, jit_compile=True) + output_ids = xla_generate(**input_ids, do_sample=False, num_beams=2) + output_strings = tokenizer.batch_decode(output_ids, skip_special_tokens=True) + self.assertListEqual(output_strings, expected_output_strings) + + @slow + def test_contrastive_search_gpt2(self): + article = ( + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based" + ) + + gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2-large") + gpt2_model = TFGPT2LMHeadModel.from_pretrained("gpt2-large") + input_ids = gpt2_tokenizer(article, return_tensors="tf") + + outputs = gpt2_model.generate(**input_ids, penalty_alpha=0.6, top_k=4, max_length=256) + + generated_text = gpt2_tokenizer.batch_decode(outputs, skip_special_tokens=True) + + self.assertListEqual( + generated_text, + [ + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based in London, " + "United Kingdom\n\nGoogle has a lot of data on its users and uses it to improve its products, such as " + "Google Now, which helps users find the information they're looking for on the web. But the company " + "is not the only one to collect data on its users. Facebook, for example, has its own facial " + "recognition technology, as well as a database of millions of photos that it uses to personalize its " + "News Feed.\n\nFacebook's use of data is a hot topic in the tech industry, with privacy advocates " + "concerned about the company's ability to keep users' information private. In a blog post last " + 'year, Facebook CEO Mark Zuckerberg said his company would "do our best to be transparent about our ' + 'data use and how we use it."\n\n"We have made it clear that we do not sell or share your data with ' + 'third parties," Zuckerberg wrote. "If you have questions or concerns, please reach out to us at ' + 'privacy@facebook.com."\n\nGoogle declined to comment on the privacy implications of its use of data, ' + "but said in a statement to The Associated Press that" + ], + ) + + @slow + def test_contrastive_search_gpt2_xla(self): + article = ( + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based" + ) + + gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2-large") + gpt2_model = TFGPT2LMHeadModel.from_pretrained("gpt2-large") + input_ids = gpt2_tokenizer(article, return_tensors="tf") + + xla_generate = tf.function(gpt2_model.generate, jit_compile=True) + outputs = xla_generate(**input_ids, penalty_alpha=0.6, top_k=4, max_length=256) + + generated_text = gpt2_tokenizer.batch_decode(outputs, skip_special_tokens=True) + + self.assertListEqual( + generated_text, + [ + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based in London, " + "United Kingdom\n\nGoogle has a lot of data on its users and uses it to improve its products, such as " + "Google Now, which helps users find the information they're looking for on the web. But the company " + "is not the only one to collect data on its users. Facebook, for example, has its own facial " + "recognition technology, as well as a database of millions of photos that it uses to personalize its " + "News Feed.\n\nFacebook's use of data is a hot topic in the tech industry, with privacy advocates " + "concerned about the company's ability to keep users' information private. In a blog post last " + 'year, Facebook CEO Mark Zuckerberg said his company would "do our best to be transparent about our ' + 'data use and how we use it."\n\n"We have made it clear that we do not sell or share your data with ' + 'third parties," Zuckerberg wrote. "If you have questions or concerns, please reach out to us at ' + 'privacy@facebook.com."\n\nGoogle declined to comment on the privacy implications of its use of data, ' + "but said in a statement to The Associated Press that" + ], + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2.py new file mode 100644 index 0000000000000000000000000000000000000000..0dd33e776d497e4b1bf87b213b22cc4c3c89f072 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2.py @@ -0,0 +1,331 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers import AutoTokenizer, GPT2Tokenizer, GPT2TokenizerFast +from transformers.models.gpt2.tokenization_gpt2 import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class GPT2TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = GPT2Tokenizer + rust_tokenizer_class = GPT2TokenizerFast + test_rust_tokenizer = True + from_pretrained_kwargs = {"add_prefix_space": True} + test_seq2seq = False + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + "<|endoftext|>", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return GPT2Tokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return GPT2TokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = GPT2Tokenizer(self.vocab_file, self.merges_file, **self.special_tokens_map) + text = "lower newer" + bpe_tokens = ["\u0120low", "er", "\u0120", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text, add_prefix_space=True) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [14, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer(add_prefix_space=True) + + sequence = "lower newer" + + # Testing tokenization + tokens = tokenizer.tokenize(sequence, add_prefix_space=True) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + # Testing conversion to ids without special tokens + ids = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=True) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + # Testing conversion to ids with special tokens + rust_tokenizer = self.get_rust_tokenizer(add_prefix_space=True) + ids = tokenizer.encode(sequence, add_prefix_space=True) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + # Testing the unknown token + input_tokens = tokens + [rust_tokenizer.unk_token] + input_bpe_tokens = [14, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(rust_tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_pretokenized_inputs(self, *args, **kwargs): + # It's very difficult to mix/test pretokenization with byte-level + # And get both GPT2 and Roberta to work at the same time (mostly an issue of adding a space before the string) + pass + + def test_padding(self, max_length=15): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Simple input + s = "This is a simple input" + s2 = ["This is a simple input 1", "This is a simple input 2"] + p = ("This is a simple input", "This is a pair") + p2 = [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ] + + # Simple input tests + self.assertRaises(ValueError, tokenizer_r.encode, s, max_length=max_length, padding="max_length") + + # Simple input + self.assertRaises(ValueError, tokenizer_r.encode_plus, s, max_length=max_length, padding="max_length") + + # Simple input + self.assertRaises( + ValueError, + tokenizer_r.batch_encode_plus, + s2, + max_length=max_length, + padding="max_length", + ) + + # Pair input + self.assertRaises(ValueError, tokenizer_r.encode, p, max_length=max_length, padding="max_length") + + # Pair input + self.assertRaises(ValueError, tokenizer_r.encode_plus, p, max_length=max_length, padding="max_length") + + # Pair input + self.assertRaises( + ValueError, + tokenizer_r.batch_encode_plus, + p2, + max_length=max_length, + padding="max_length", + ) + + def test_padding_if_pad_token_set_slow(self): + tokenizer = GPT2Tokenizer.from_pretrained(self.tmpdirname, pad_token="") + + # Simple input + s = "This is a simple input" + s2 = ["This is a simple input looooooooong", "This is a simple input"] + p = ("This is a simple input", "This is a pair") + p2 = [ + ("This is a simple input loooooong", "This is a simple input"), + ("This is a simple pair loooooong", "This is a simple pair"), + ] + + pad_token_id = tokenizer.pad_token_id + + out_s = tokenizer(s, padding="max_length", max_length=30, return_tensors="np") + out_s2 = tokenizer(s2, padding=True, truncate=True, return_tensors="np") + out_p = tokenizer(*p, padding="max_length", max_length=60, return_tensors="np") + out_p2 = tokenizer(p2, padding=True, truncate=True, return_tensors="np") + + # s + # test single string max_length padding + self.assertEqual(out_s["input_ids"].shape[-1], 30) + self.assertTrue(pad_token_id in out_s["input_ids"]) + self.assertTrue(0 in out_s["attention_mask"]) + + # s2 + # test automatic padding + self.assertEqual(out_s2["input_ids"].shape[-1], 33) + # long slice doesn't have padding + self.assertFalse(pad_token_id in out_s2["input_ids"][0]) + self.assertFalse(0 in out_s2["attention_mask"][0]) + # short slice does have padding + self.assertTrue(pad_token_id in out_s2["input_ids"][1]) + self.assertTrue(0 in out_s2["attention_mask"][1]) + + # p + # test single pair max_length padding + self.assertEqual(out_p["input_ids"].shape[-1], 60) + self.assertTrue(pad_token_id in out_p["input_ids"]) + self.assertTrue(0 in out_p["attention_mask"]) + + # p2 + # test automatic padding pair + self.assertEqual(out_p2["input_ids"].shape[-1], 52) + # long slice pair doesn't have padding + self.assertFalse(pad_token_id in out_p2["input_ids"][0]) + self.assertFalse(0 in out_p2["attention_mask"][0]) + # short slice pair does have padding + self.assertTrue(pad_token_id in out_p2["input_ids"][1]) + self.assertTrue(0 in out_p2["attention_mask"][1]) + + def test_add_bos_token_slow(self): + bos_token = "$$$" + tokenizer = GPT2Tokenizer.from_pretrained(self.tmpdirname, bos_token=bos_token, add_bos_token=True) + + s = "This is a simple input" + s2 = ["This is a simple input 1", "This is a simple input 2"] + + bos_token_id = tokenizer.bos_token_id + + out_s = tokenizer(s) + out_s2 = tokenizer(s2) + + self.assertEqual(out_s.input_ids[0], bos_token_id) + self.assertTrue(all(o[0] == bos_token_id for o in out_s2.input_ids)) + + decode_s = tokenizer.decode(out_s.input_ids) + decode_s2 = tokenizer.batch_decode(out_s2.input_ids) + + self.assertEqual(decode_s.split()[0], bos_token) + self.assertTrue(all(d.split()[0] == bos_token for d in decode_s2)) + + # tokenizer has no padding token + def test_padding_different_model_input_name(self): + pass + + def test_special_tokens_mask_input_pairs_and_bos_token(self): + # TODO: change to self.get_tokenizers() when the fast version is implemented + tokenizers = [self.get_tokenizer(do_lower_case=False, add_bos_token=True)] + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence_0 = "Encode this." + sequence_1 = "This one too please." + encoded_sequence = tokenizer.encode(sequence_0, add_special_tokens=False) + encoded_sequence += tokenizer.encode(sequence_1, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + sequence_0, + sequence_1, + add_special_tokens=True, + return_special_tokens_mask=True, + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [ + (x if not special_tokens_mask[i] else None) for i, x in enumerate(encoded_sequence_w_special) + ] + filtered_sequence = [x for x in filtered_sequence if x is not None] + self.assertEqual(encoded_sequence, filtered_sequence) + + +@require_tokenizers +class OPTTokenizationTest(unittest.TestCase): + def test_serialize_deserialize_fast_opt(self): + # More context: + # https://huggingface.co/wjmcat/opt-350m-paddle/discussions/1 + # https://huggingface.slack.com/archives/C01N44FJDHT/p1653511495183519 + # https://github.com/huggingface/transformers/pull/17088#discussion_r871246439 + + tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m", from_slow=True) + text = "A photo of a cat" + + tokens_ids = tokenizer.encode( + text, + ) + self.assertEqual(tokens_ids, [2, 250, 1345, 9, 10, 4758]) + tokenizer.save_pretrained("test_opt") + + tokenizer = AutoTokenizer.from_pretrained("./test_opt") + tokens_ids = tokenizer.encode( + text, + ) + self.assertEqual(tokens_ids, [2, 250, 1345, 9, 10, 4758]) + + def test_fast_slow_equivalence(self): + tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m", use_slow=True) + text = "A photo of a cat" + + tokens_ids = tokenizer.encode( + text, + ) + # Same as above + self.assertEqual(tokens_ids, [2, 250, 1345, 9, 10, 4758]) + + @unittest.skip("This test is failing because of a bug in the fast tokenizer") + def test_users_can_modify_bos(self): + tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m", from_slow=True) + + tokenizer.bos_token = "bos" + tokenizer.bos_token_id = tokenizer.get_vocab()["bos"] + + text = "A photo of a cat" + tokens_ids = tokenizer.encode( + text, + ) + # We changed the bos token + self.assertEqual(tokens_ids, [31957, 250, 1345, 9, 10, 4758]) + tokenizer.save_pretrained("./tok") + tokenizer = AutoTokenizer.from_pretrained("./tok") + self.assertTrue(tokenizer.is_fast) + tokens_ids = tokenizer.encode( + text, + ) + self.assertEqual(tokens_ids, [31957, 250, 1345, 9, 10, 4758]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2_tf.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2_tf.py new file mode 100644 index 0000000000000000000000000000000000000000..e92c9e65dfd38dfc13d30ee41a25c757bf1e5c99 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt2/test_tokenization_gpt2_tf.py @@ -0,0 +1,130 @@ +import unittest +from pathlib import Path +from tempfile import TemporaryDirectory + +from transformers import AutoConfig, TFGPT2LMHeadModel, is_keras_nlp_available, is_tf_available +from transformers.models.gpt2.tokenization_gpt2 import GPT2Tokenizer +from transformers.testing_utils import require_keras_nlp, require_tf, slow + + +if is_tf_available(): + import tensorflow as tf + +if is_keras_nlp_available(): + from transformers.models.gpt2 import TFGPT2Tokenizer + + +TOKENIZER_CHECKPOINTS = ["gpt2"] +TINY_MODEL_CHECKPOINT = "gpt2" + +if is_tf_available(): + + class ModelToSave(tf.Module): + def __init__(self, tokenizer): + super().__init__() + self.tokenizer = tokenizer + config = AutoConfig.from_pretrained(TINY_MODEL_CHECKPOINT) + self.model = TFGPT2LMHeadModel.from_config(config) + + @tf.function(input_signature=(tf.TensorSpec((None,), tf.string, name="text"),)) + def serving(self, text): + tokenized = self.tokenizer(text) + input_ids_dense = tokenized["input_ids"].to_tensor() + + input_mask = tf.cast(input_ids_dense > 0, tf.int32) + # input_mask = tf.reshape(input_mask, [-1, MAX_SEQ_LEN]) + + outputs = self.model(input_ids=input_ids_dense, attention_mask=input_mask)["logits"] + + return outputs + + +@require_tf +@require_keras_nlp +class GPTTokenizationTest(unittest.TestCase): + # The TF tokenizers are usually going to be used as pretrained tokenizers from existing model checkpoints, + # so that's what we focus on here. + + def setUp(self): + super().setUp() + + self.tokenizers = [GPT2Tokenizer.from_pretrained(checkpoint) for checkpoint in (TOKENIZER_CHECKPOINTS)] + self.tf_tokenizers = [TFGPT2Tokenizer.from_pretrained(checkpoint) for checkpoint in TOKENIZER_CHECKPOINTS] + assert len(self.tokenizers) == len(self.tf_tokenizers) + + self.test_sentences = [ + "This is a straightforward English test sentence.", + "This one has some weird characters\rto\nsee\r\nif those\u00E9break things.", + "Now we're going to add some Chinese: 一 二 三 一二三", + "And some much more rare Chinese: 齉 堃 齉堃", + "Je vais aussi écrire en français pour tester les accents", + "Classical Irish also has some unusual characters, so in they go: Gaelaċ, ꝼ", + ] + self.paired_sentences = list(zip(self.test_sentences, self.test_sentences[::-1])) + + def test_output_equivalence(self): + for tokenizer, tf_tokenizer in zip(self.tokenizers, self.tf_tokenizers): + for test_inputs in self.test_sentences: + python_outputs = tokenizer([test_inputs], return_tensors="tf") + tf_outputs = tf_tokenizer([test_inputs]) + + for key in python_outputs.keys(): + # convert them to numpy to avoid messing with ragged tensors + python_outputs_values = python_outputs[key].numpy() + tf_outputs_values = tf_outputs[key].numpy() + + self.assertTrue(tf.reduce_all(python_outputs_values.shape == tf_outputs_values.shape)) + self.assertTrue(tf.reduce_all(tf.cast(python_outputs_values, tf.int64) == tf_outputs_values)) + + @slow + def test_graph_mode(self): + for tf_tokenizer in self.tf_tokenizers: + compiled_tokenizer = tf.function(tf_tokenizer) + for test_inputs in self.test_sentences: + test_inputs = tf.constant(test_inputs) + compiled_outputs = compiled_tokenizer(test_inputs) + eager_outputs = tf_tokenizer(test_inputs) + + for key in eager_outputs.keys(): + self.assertTrue(tf.reduce_all(eager_outputs[key] == compiled_outputs[key])) + + @slow + def test_saved_model(self): + for tf_tokenizer in self.tf_tokenizers: + model = ModelToSave(tokenizer=tf_tokenizer) + test_inputs = tf.convert_to_tensor([self.test_sentences[0]]) + out = model.serving(test_inputs) # Build model with some sample inputs + with TemporaryDirectory() as tempdir: + save_path = Path(tempdir) / "saved.model" + tf.saved_model.save(model, save_path, signatures={"serving_default": model.serving}) + loaded_model = tf.saved_model.load(save_path) + loaded_output = loaded_model.signatures["serving_default"](test_inputs)["output_0"] + # We may see small differences because the loaded model is compiled, so we need an epsilon for the test + self.assertTrue(tf.reduce_all(out == loaded_output)) + + @slow + def test_from_config(self): + for tf_tokenizer in self.tf_tokenizers: + test_inputs = tf.convert_to_tensor([self.test_sentences[0]]) + out = tf_tokenizer(test_inputs) # Build model with some sample inputs + + config = tf_tokenizer.get_config() + model_from_config = TFGPT2Tokenizer.from_config(config) + from_config_output = model_from_config(test_inputs) + + for key in from_config_output.keys(): + self.assertTrue(tf.reduce_all(from_config_output[key] == out[key])) + + @slow + def test_padding(self): + for tf_tokenizer in self.tf_tokenizers: + # for the test to run + tf_tokenizer.pad_token_id = 123123 + + for max_length in [3, 5, 1024]: + test_inputs = tf.convert_to_tensor([self.test_sentences[0]]) + out = tf_tokenizer(test_inputs, max_length=max_length) + + out_length = out["input_ids"].numpy().shape[1] + + assert out_length == max_length diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_bigcode/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_bigcode/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_bigcode/test_modeling_gpt_bigcode.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_bigcode/test_modeling_gpt_bigcode.py new file mode 100644 index 0000000000000000000000000000000000000000..a9f4d204bf9c5558e5c70a39d7f19f9b7a75bd69 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_bigcode/test_modeling_gpt_bigcode.py @@ -0,0 +1,617 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import math +import unittest + +from parameterized import parameterized + +from transformers import GPTBigCodeConfig, 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 ( + GPT2TokenizerFast, + GPTBigCodeForCausalLM, + GPTBigCodeForSequenceClassification, + GPTBigCodeForTokenClassification, + GPTBigCodeModel, + ) + from transformers.models.gpt_bigcode.modeling_gpt_bigcode import GPTBigCodeAttention + + +class GPTBigCodeModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="relu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + multi_query=True, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 2 + self.pad_token_id = vocab_size - 3 + self.multi_query = multi_query + + def get_large_model_config(self): + return GPTBigCodeConfig.from_pretrained("bigcode/gpt_bigcode-santacoder") + + def prepare_config_and_inputs( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config( + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + return GPTBigCodeConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + n_inner=self.intermediate_size, + activation_function=self.hidden_act, + resid_pdrop=self.hidden_dropout_prob, + attn_pdrop=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + attention_softmax_in_fp32=False, + scale_attention_softmax_in_fp32=False, + multi_query=self.multi_query, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_gpt_bigcode_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTBigCodeModel(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_gpt_bigcode_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTBigCodeModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt_bigcode_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTBigCodeModel(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt_bigcode_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTBigCodeModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTBigCodeForCausalLM(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False + ): + model = GPTBigCodeForCausalLM(config) + model.to(torch_device) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def create_and_check_gpt_bigcode_for_sequence_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPTBigCodeForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_gpt_bigcode_for_token_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPTBigCodeForTokenClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_gpt_bigcode_weight_initialization(self, config, *args): + model = GPTBigCodeModel(config) + model_std = model.config.initializer_range / math.sqrt(2 * model.config.n_layer) + for key in model.state_dict().keys(): + if "c_proj" in key and "weight" in key: + self.parent.assertLessEqual(abs(torch.std(model.state_dict()[key]) - model_std), 0.001) + self.parent.assertLessEqual(abs(torch.mean(model.state_dict()[key]) - 0.0), 0.01) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "head_mask": head_mask, + } + + return config, inputs_dict + + +@require_torch +class GPTBigCodeModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + # TODO: Update the tests to use valid pretrained models. + all_model_classes = ( + ( + GPTBigCodeModel, + GPTBigCodeForCausalLM, + GPTBigCodeForSequenceClassification, + GPTBigCodeForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (GPTBigCodeForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": GPTBigCodeModel, + "text-classification": GPTBigCodeForSequenceClassification, + "text-generation": GPTBigCodeForCausalLM, + "token-classification": GPTBigCodeForTokenClassification, + "zero-shot": GPTBigCodeForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = False + test_missing_keys = False + test_pruning = False + test_torchscript = False + multi_query = True + + # special case for DoubleHeads model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + return inputs_dict + + def setUp(self): + self.model_tester = GPTBigCodeModelTester(self, multi_query=self.multi_query) + self.config_tester = ConfigTester(self, config_class=GPTBigCodeConfig, n_embd=37) + + def tearDown(self): + import gc + + gc.collect() + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip("MQA models does not support retain_grad") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip("Contrastive search not supported due to non-standard caching mechanism") + def test_contrastive_generate(self): + pass + + @unittest.skip("Contrastive search not supported due to non-standard caching mechanism") + def test_contrastive_generate_dict_outputs_use_cache(self): + pass + + @unittest.skip("CPU offload seems to be broken for some reason - tiny models keep hitting corner cases") + def test_cpu_offload(self): + pass + + @unittest.skip("Disk offload seems to be broken for some reason - tiny models keep hitting corner cases") + def test_disk_offload(self): + pass + + def test_gpt_bigcode_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_model(*config_and_inputs) + + def test_gpt_bigcode_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_model_past(*config_and_inputs) + + def test_gpt_bigcode_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_model_attention_mask_past(*config_and_inputs) + + def test_gpt_bigcode_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_model_past_large_inputs(*config_and_inputs) + + def test_gpt_bigcode_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_gpt_bigcode_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_for_sequence_classification(*config_and_inputs) + + def test_gpt_bigcode_token_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_for_token_classification(*config_and_inputs) + + def test_gpt_bigcode_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + def test_gpt_bigcode_scale_attn_by_inverse_layer_idx(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs(scale_attn_by_inverse_layer_idx=True) + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) + + def test_gpt_bigcode_reorder_and_upcast_attn(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs(reorder_and_upcast_attn=True) + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs) + + def test_gpt_bigcode_weight_initialization(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_bigcode_weight_initialization(*config_and_inputs) + + +@require_torch +class GPTBigCodeMHAModelTest(GPTBigCodeModelTest): + # `parameterized_class` breaks with mixins, so we use inheritance instead + multi_query = False + + +@slow +@require_torch +class GPTBigCodeModelLanguageGenerationTest(unittest.TestCase): + def test_generate_simple(self): + model = GPTBigCodeForCausalLM.from_pretrained("bigcode/gpt_bigcode-santacoder").to(torch_device) + tokenizer = GPT2TokenizerFast.from_pretrained("bigcode/gpt_bigcode-santacoder") + + input_ids = tokenizer("def print_hello_world():", return_tensors="pt").input_ids.to(torch_device) + + output_sequence = model.generate(input_ids) + output_sentence = tokenizer.decode(output_sequence[0], skip_special_tokens=True) + + expected_output = """def print_hello_world():\n print("Hello World!")\n\n\ndef print_hello_""" + self.assertEqual(output_sentence, expected_output) + + def test_generate_batched(self): + tokenizer = GPT2TokenizerFast.from_pretrained("bigcode/gpt_bigcode-santacoder") + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "left" + + model = GPTBigCodeForCausalLM.from_pretrained("bigcode/gpt_bigcode-santacoder").to(torch_device) + + inputs = tokenizer(["def print_hello_world():", "def say_hello():"], return_tensors="pt", padding=True).to( + torch_device + ) + outputs = model.generate(**inputs) + outputs = tokenizer.batch_decode(outputs, skip_special_tokens=True) + + expected_output = [ + 'def print_hello_world():\n print("Hello World!")\n\n\ndef print_hello_', + 'def say_hello():\n print("Hello, World!")\n\n\nsay_hello()', + ] + self.assertListEqual(outputs, expected_output) + + +@require_torch +class GPTBigCodeMQATest(unittest.TestCase): + def get_attention(self, multi_query): + config = GPTBigCodeConfig.from_pretrained( + "bigcode/gpt_bigcode-santacoder", + multi_query=multi_query, + attn_pdrop=0, + resid_pdrop=0, + ) + return GPTBigCodeAttention(config) + + @parameterized.expand([(seed, is_train_mode) for seed in range(5) for is_train_mode in [True, False]]) + def test_mqa_reduces_to_mha(self, seed, is_train_mode=True): + torch.manual_seed(seed) + + # CREATE MQA AND MHA ATTENTIONS + attention_mqa = self.get_attention(True) + attention_mha = self.get_attention(False) + + # ENFORCE MATCHING WEIGHTS + num_heads = attention_mqa.num_heads + embed_dim = attention_mqa.embed_dim + head_dim = attention_mqa.head_dim + + with torch.no_grad(): + mqa_q_weight = attention_mqa.c_attn.weight[:embed_dim, :].view(num_heads, 1, head_dim, embed_dim) + mqa_kv_weight = attention_mqa.c_attn.weight[embed_dim:, :].view(1, 2, head_dim, embed_dim) + mha_c_weight = torch.cat( + [mqa_q_weight, mqa_kv_weight.expand(num_heads, 2, head_dim, embed_dim)], dim=1 + ).view(3 * num_heads * head_dim, embed_dim) + + mqa_q_bias = attention_mqa.c_attn.bias[:embed_dim].view(num_heads, 1, head_dim) + mqa_kv_bias = attention_mqa.c_attn.bias[embed_dim:].view(1, 2, head_dim) + mha_c_bias = torch.cat([mqa_q_bias, mqa_kv_bias.expand(num_heads, 2, head_dim)], dim=1).view( + 3 * num_heads * head_dim + ) + + attention_mha.c_attn.weight.copy_(mha_c_weight) + attention_mha.c_attn.bias.copy_(mha_c_bias) + attention_mha.c_proj.weight.copy_(attention_mqa.c_proj.weight) + attention_mha.c_proj.bias.copy_(attention_mqa.c_proj.bias) + + # PUT THE MODEL INTO THE CORRECT MODE + attention_mha.train(is_train_mode) + attention_mqa.train(is_train_mode) + + # RUN AN INPUT THROUGH THE MODELS + num_tokens = 5 + hidden_states = torch.randn(1, num_tokens, embed_dim) + attention_mha_result = attention_mha(hidden_states)[0] + attention_mqa_result = attention_mqa(hidden_states)[0] + + # CHECK THAT ALL OUTPUTS ARE THE SAME + self.assertTrue(torch.allclose(attention_mha_result, attention_mqa_result, atol=1e-5)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_flax_gpt_neo.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_flax_gpt_neo.py new file mode 100644 index 0000000000000000000000000000000000000000..a32f35f6e747b168582b31b054f1a8d1c1c9023f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_flax_gpt_neo.py @@ -0,0 +1,331 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +import numpy as np + +import transformers +from transformers import GPT2Tokenizer, GPTNeoConfig, is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax, slow + +from ...generation.test_flax_utils import FlaxGenerationTesterMixin +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask + + +if is_flax_available(): + import jax + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + from transformers.models.gpt_neo.modeling_flax_gpt_neo import FlaxGPTNeoForCausalLM, FlaxGPTNeoModel + +if is_torch_available(): + import torch + + +class FlaxGPTNeoModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=4, + num_attention_heads=4, + attention_types=[[["global", "local"], 2]], + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + window_size=7, + initializer_range=0.02, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.attention_types = attention_types + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.window_size = window_size + self.initializer_range = initializer_range + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = GPTNeoConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_layers=self.num_hidden_layers, + num_heads=self.num_attention_heads, + max_position_embeddings=self.max_position_embeddings, + use_cache=False, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + window_size=self.window_size, + attention_types=self.attention_types, + ) + + return (config, input_ids, input_mask) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": attention_mask} + return config, inputs_dict + + def check_use_cache_forward(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + attention_mask = jnp.ones((input_ids.shape[0], max_decoder_length), dtype="i4") + + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + attention_mask=attention_mask, + past_key_values=outputs_cache.past_key_values, + position_ids=position_ids, + ) + + outputs = model(input_ids) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def check_use_cache_forward_with_attn_mask(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + attention_mask_cache = jnp.concatenate( + [attention_mask, jnp.zeros((attention_mask.shape[0], max_decoder_length - attention_mask.shape[1]))], + axis=-1, + ) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask_cache, + past_key_values=past_key_values, + position_ids=position_ids, + ) + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + past_key_values=outputs_cache.past_key_values, + attention_mask=attention_mask_cache, + position_ids=position_ids, + ) + + outputs = model(input_ids, attention_mask=attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + +@require_flax +class FlaxGPTNeoModelTest(FlaxModelTesterMixin, FlaxGenerationTesterMixin, unittest.TestCase): + all_model_classes = (FlaxGPTNeoModel, FlaxGPTNeoForCausalLM) if is_flax_available() else () + all_generative_model_classes = (FlaxGPTNeoForCausalLM,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxGPTNeoModelTester(self) + + def test_use_cache_forward(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward(model_class_name, config, input_ids, attention_mask) + + def test_use_cache_forward_with_attn_mask(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward_with_attn_mask( + model_class_name, config, input_ids, attention_mask + ) + + @slow + def test_batch_generation(self): + tokenizer = GPT2Tokenizer.from_pretrained("gpt2", pad_token="<|endoftext|>", padding_side="left") + inputs = tokenizer(["Hello this is a long string", "Hey"], return_tensors="np", padding=True, truncation=True) + + model = FlaxGPTNeoForCausalLM.from_pretrained("EleutherAI/gpt-neo-125M") + model.do_sample = False + model.config.pad_token_id = model.config.eos_token_id + + jit_generate = jax.jit(model.generate) + + output_sequences = jit_generate( + inputs["input_ids"], attention_mask=inputs["attention_mask"], pad_token_id=tokenizer.pad_token_id + ).sequences + + output_string = tokenizer.batch_decode(output_sequences, skip_special_tokens=True) + + expected_string = [ + "Hello this is a long string of text.\n\nI'm trying to get the text of the", + "Hey, I'm a little late to the party. I'm going to", + ] + + self.assertListEqual(output_string, expected_string) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**prepared_inputs_dict).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded, pt_outputs): + self.assert_almost_equals(fx_output_loaded[:, -1], pt_output[:, -1].numpy(), 4e-2) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = pt_model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs, pt_outputs_loaded): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("EleutherAI/gpt-neo-125M") + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_gpt_neo.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_gpt_neo.py new file mode 100644 index 0000000000000000000000000000000000000000..c0334bd05aa35ed06e28773156acfaebabfd0e7d --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neo/test_modeling_gpt_neo.py @@ -0,0 +1,608 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch GPT Neo model. """ + + +import unittest + +from transformers import GPTNeoConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device +from transformers.utils import cached_property + +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 ( + GPT_NEO_PRETRAINED_MODEL_ARCHIVE_LIST, + GPT2Tokenizer, + GPTNeoForCausalLM, + GPTNeoForQuestionAnswering, + GPTNeoForSequenceClassification, + GPTNeoForTokenClassification, + GPTNeoModel, + ) + + +class GPTNeoModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=4, + attention_types=[[["global", "local"], 2]], + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + window_size=7, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.window_size = window_size + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + self.attention_types = attention_types + + def get_large_model_config(self): + return GPTNeoConfig.from_pretrained("gpt-neo-125M") + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config(self): + return GPTNeoConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_layers=self.num_hidden_layers, + num_heads=self.num_attention_heads, + max_position_embeddings=self.max_position_embeddings, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + window_size=self.window_size, + attention_types=self.attention_types, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_gpt_neo_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTNeoModel(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + # past_key_values is not implemented + # self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_gpt_neo_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTNeoModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt_neo_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTNeoModel(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gpt_neo_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTNeoModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTNeoForCausalLM(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_gpt_neo_for_question_answering( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPTNeoForQuestionAnswering(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_gpt_neo_for_sequence_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPTNeoForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_gpt_neo_for_token_classification( + self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = GPTNeoForTokenClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False + ): + model = GPTNeoForCausalLM(config) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + model.to(torch_device) + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "head_mask": head_mask, + } + + return config, inputs_dict + + +@require_torch +class GPTNeoModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + GPTNeoModel, + GPTNeoForCausalLM, + GPTNeoForQuestionAnswering, + GPTNeoForSequenceClassification, + GPTNeoForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (GPTNeoForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": GPTNeoModel, + "question-answering": GPTNeoForQuestionAnswering, + "text-classification": GPTNeoForSequenceClassification, + "token-classification": GPTNeoForTokenClassification, + "text-generation": GPTNeoForCausalLM, + "zero-shot": GPTNeoForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + test_missing_keys = False + test_pruning = False + test_model_parallel = False + + # special case for DoubleHeads model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + return inputs_dict + + def setUp(self): + self.model_tester = GPTNeoModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPTNeoConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_gpt_neo_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_model(*config_and_inputs) + + def test_gpt_neo_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_model_past(*config_and_inputs) + + def test_gpt_neo_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_model_attention_mask_past(*config_and_inputs) + + def test_gpt_neo_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_model_past_large_inputs(*config_and_inputs) + + def test_gpt_neo_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_gpt_neo_question_answering_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_for_question_answering(*config_and_inputs) + + def test_gpt_neo_sequence_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_for_sequence_classification(*config_and_inputs) + + def test_gpt_neo_token_classification_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gpt_neo_for_token_classification(*config_and_inputs) + + def test_gpt_neo_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + def _get_hidden_states(self): + return torch.tensor( + [ + [ + [0.4983, -0.7584, -1.6944, 0.5440], + [2.6918, 0.4206, 0.4176, 0.2055], + [-0.0071, -0.0405, -1.4920, -0.3630], + [1.0492, 0.1599, -1.7648, 0.2419], + [-1.8348, 2.0514, -0.1946, 0.3203], + [0.7672, -1.1600, -1.7118, -0.9056], + [0.2986, 0.5372, 0.7729, -0.1927], + [0.0285, 0.2629, -1.1156, -1.1992], + ] + ], + dtype=torch.float32, + device=torch_device, + ) + + def test_local_attn_probs(self): + model = GPTNeoModel.from_pretrained("valhalla/gpt-neo-random-tiny").eval() + layer = model.h[1].attn.attention.to(torch_device) + hidden_states = self._get_hidden_states() + hidden_states = torch.cat([hidden_states, hidden_states - 0.5], dim=2) + + batch_size, seq_length, _ = hidden_states.shape + mask_tokens = 2 + attention_mask = torch.ones(batch_size, seq_length, device=torch_device, dtype=torch.long) + attention_mask[:, -mask_tokens:] = 0 # dont attend last mask_tokens + + attention_mask = attention_mask.view(batch_size, -1) + attention_mask = attention_mask[:, None, None, :] + attention_mask = (1.0 - attention_mask) * -10000.0 + + attn_probs = layer(hidden_states, attention_mask=attention_mask, output_attentions=True)[-1] + + # the last 2 tokens are masked, and should have 0 attn_probs + self.assertTrue(torch.all(attn_probs[:, :, -mask_tokens:, -mask_tokens:] == 0)) + + # in loacal attention each token can only attend to the previous window_size tokens (inlcuding itself) + # here window_size is 4, so a token at index 5 can only attend to indcies [2, 3, 4, 5] + # and the attn_probs should be 0 for token [0, 1] + self.assertTrue(torch.all(attn_probs[:, :, 5, 2:6] != 0)) + self.assertTrue(torch.all(attn_probs[:, :, 5, :2] == 0)) + + +@require_torch +class GPTNeoModelLanguageGenerationTest(unittest.TestCase): + @cached_property + def model(self): + return GPTNeoForCausalLM.from_pretrained("EleutherAI/gpt-neo-1.3B").to(torch_device) + + @cached_property + def tokenizer(self): + return GPT2Tokenizer.from_pretrained("EleutherAI/gpt-neo-1.3B") + + @slow + def test_lm_generate_gpt_neo(self): + for checkpointing in [True, False]: + model = self.model + if checkpointing: + model.gradient_checkpointing_enable() + else: + model.gradient_checkpointing_disable() + input_ids = torch.tensor([[464, 3290]], dtype=torch.long, device=torch_device) # The dog + # fmt: off + # The dog-eared copy of the book, which is a collection of essays by the late author, + expected_output_ids = [464, 3290, 12, 3380, 4866, 286, 262, 1492, 11, 543, 318, 257, 4947, 286, 27126, 416, 262, 2739, 1772, 11] + # fmt: on + output_ids = model.generate(input_ids, do_sample=False) + self.assertListEqual(output_ids[0].tolist(), expected_output_ids) + + @slow + def test_gpt_neo_sample(self): + model = self.model + tokenizer = self.tokenizer + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + output_ids = model.generate(input_ids, do_sample=True) + output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True) + + EXPECTED_OUTPUT_STR = "Today is a nice day and if you don’t get the memo here is what you can" + self.assertEqual(output_str, EXPECTED_OUTPUT_STR) + + @slow + def test_batch_generation(self): + model = self.model + tokenizer = self.tokenizer + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = [ + "Hello, my dog is a little", + "Today, I am", + ] + + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item() + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + "Hello, my dog is a little bit of a kitty. She is a very sweet and loving", + "Today, I am going to talk about the best way to get a job in the", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_model_from_pretrained(self): + for model_name in GPT_NEO_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GPTNeoModel.from_pretrained(model_name) + self.assertIsNotNone(model) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox/test_modeling_gpt_neox.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox/test_modeling_gpt_neox.py new file mode 100644 index 0000000000000000000000000000000000000000..927d097691c5a6b411dd2259ed3666ed285dbd7b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox/test_modeling_gpt_neox.py @@ -0,0 +1,324 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch GPTNeoX model. """ + + +import unittest + +from transformers import AutoTokenizer, GPTNeoXConfig, 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, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + GPTNeoXForCausalLM, + GPTNeoXForQuestionAnswering, + GPTNeoXForSequenceClassification, + GPTNeoXForTokenClassification, + GPTNeoXModel, + ) + + +class GPTNeoXModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.pad_token_id = vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_labels = None + if self.use_labels: + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + + config = self.get_config() + + return config, input_ids, input_mask, token_labels + + def get_config(self): + return GPTNeoXConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + pad_token_id=self.pad_token_id, + ) + + def prepare_config_and_inputs_for_decoder(self): + config, input_ids, input_mask, token_labels = self.prepare_config_and_inputs() + + config.is_decoder = True + + return config, input_ids, input_mask, token_labels + + def create_and_check_model(self, config, input_ids, input_mask): + model = GPTNeoXModel(config=config) + model.to(torch_device) + model.eval() + _ = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder(self, config, input_ids, input_mask): + config.add_cross_attention = True + model = GPTNeoXModel(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_causal_lm(self, config, input_ids, input_mask, token_labels): + model = GPTNeoXForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_question_answering(self, config, input_ids, input_mask, token_labels): + config.num_labels = self.num_labels + model = GPTNeoXForQuestionAnswering(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification(self, config, input_ids, input_mask, token_labels): + config.num_labels = self.num_labels + model = GPTNeoXForSequenceClassification(config) + model.to(torch_device) + model.eval() + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + result = model(input_ids, attention_mask=input_mask, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification(self, config, input_ids, input_mask, token_labels): + config.num_labels = self.num_labels + model = GPTNeoXForTokenClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_decoder_model_past_large_inputs(self, config, input_ids, input_mask): + config.is_decoder = True + model = GPTNeoXForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, use_cache=True) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask, output_hidden_states=True) + output_from_no_past = output_from_no_past["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask, token_labels = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class GPTNeoXModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + GPTNeoXModel, + GPTNeoXForCausalLM, + GPTNeoXForQuestionAnswering, + GPTNeoXForSequenceClassification, + GPTNeoXForTokenClassification, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (GPTNeoXForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": GPTNeoXModel, + "question-answering": GPTNeoXForQuestionAnswering, + "text-classification": GPTNeoXForSequenceClassification, + "token-classification": GPTNeoXForTokenClassification, + "text-generation": GPTNeoXForCausalLM, + "zero-shot": GPTNeoXForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_pruning = False + test_missing_keys = False + test_model_parallel = False + test_head_masking = False + + def setUp(self): + self.model_tester = GPTNeoXModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPTNeoXConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(config, input_ids, input_mask) + + def test_model_as_decoder(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(config, input_ids, input_mask) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder(config, input_ids, input_mask) + + def test_decoder_model_past_large_inputs(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(config, input_ids, input_mask) + + def test_model_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + def test_model_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_model_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_model_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + +@require_torch +class GPTNeoXLanguageGenerationTest(unittest.TestCase): + @slow + def test_lm_generate_gptneox(self): + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/pythia-410m-deduped") + for checkpointing in [True, False]: + model = GPTNeoXForCausalLM.from_pretrained("EleutherAI/pythia-410m-deduped") + + if checkpointing: + model.gradient_checkpointing_enable() + else: + model.gradient_checkpointing_disable() + model.to(torch_device) + + inputs = tokenizer("My favorite food is", return_tensors="pt").to(torch_device) + expected_output = ( + "My favorite food is the chicken and rice.\n\nI love to cook and bake. I love to cook and bake" + ) + + output_ids = model.generate(**inputs, do_sample=False, max_new_tokens=20) + output_str = tokenizer.batch_decode(output_ids)[0] + + self.assertEqual(output_str, expected_output) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_modeling_gpt_neox_japanese.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_modeling_gpt_neox_japanese.py new file mode 100644 index 0000000000000000000000000000000000000000..47bb22b62705a45b7f70e1ce6ee7b6dc70b9717b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_modeling_gpt_neox_japanese.py @@ -0,0 +1,260 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch GPTNeoXJapanese model. """ + + +import unittest + +from transformers import GPTNeoXJapaneseConfig, is_torch_available +from transformers.models.gpt_neox_japanese.tokenization_gpt_neox_japanese import GPTNeoXJapaneseTokenizer +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import GPTNeoXJapaneseForCausalLM, GPTNeoXJapaneseModel + + +class GPTNeoXJapaneseModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_multiple_size=4, + hidden_act="gelu", + hidden_dropout=0.0, + attention_dropout=0.1, + weight_tying=True, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_multiple_size = intermediate_multiple_size + self.hidden_act = hidden_act + self.hidden_dropout = hidden_dropout + self.attention_dropout = attention_dropout + self.weight_tying = weight_tying + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_labels = None + if self.use_labels: + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + + config = self.get_config() + + return config, input_ids, input_mask, token_labels + + def get_config(self): + return GPTNeoXJapaneseConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_multiple_size=self.intermediate_multiple_size, + hidden_act=self.hidden_act, + hidden_dropout=self.hidden_dropout, + attention_dropout=self.attention_dropout, + weight_tying=self.weight_tying, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def prepare_config_and_inputs_for_decoder(self): + config, input_ids, input_mask, token_labels = self.prepare_config_and_inputs() + + config.is_decoder = True + + return config, input_ids, input_mask, token_labels + + def create_and_check_model(self, config, input_ids, input_mask): + model = GPTNeoXJapaneseModel(config=config) + model.to(torch_device) + model.eval() + _ = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder(self, config, input_ids, input_mask): + config.add_cross_attention = True + model = GPTNeoXJapaneseModel(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_causal_lm(self, config, input_ids, input_mask, token_labels): + model = GPTNeoXJapaneseForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_decoder_model_past_large_inputs(self, config, input_ids, input_mask): + config.is_decoder = True + model = GPTNeoXJapaneseForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, use_cache=True) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask, output_hidden_states=True) + output_from_no_past = output_from_no_past["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask, token_labels = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class GPTNeoXModelJapaneseTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GPTNeoXJapaneseModel, GPTNeoXJapaneseForCausalLM) if is_torch_available() else () + all_generative_model_classes = (GPTNeoXJapaneseForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": GPTNeoXJapaneseModel, "text-generation": GPTNeoXJapaneseForCausalLM} + if is_torch_available() + else {} + ) + test_pruning = False + test_missing_keys = False + test_model_parallel = False + test_head_masking = False + + def setUp(self): + self.model_tester = GPTNeoXJapaneseModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPTNeoXJapaneseConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(config, input_ids, input_mask) + + def test_model_as_decoder(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs_for_decoder() + self.model_tester.create_and_check_model_as_decoder(config, input_ids, input_mask) + + def test_model_as_decoder_with_default_input_mask(self): + # This regression test was failing with PyTorch < 1.3 + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs_for_decoder() + + input_mask = None + + self.model_tester.create_and_check_model_as_decoder(config, input_ids, input_mask) + + def test_decoder_model_past_large_inputs(self): + config, input_ids, input_mask, token_labels = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(config, input_ids, input_mask) + + def test_model_for_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_causal_lm(*config_and_inputs) + + @slow + def test_generation(self): + model_id = "abeja/gpt-neox-japanese-2.7b" + + prompts = ["データサイエンティストとは、", "100年後に必要とされる会社は、", "フルリモートの環境で働くために必要なことは、", "国境の長いトンネルを抜けると", "美味しい日本食といえば、"] + + EXPECTED_OUTPUTS = [ + "データサイエンティストとは、データを分析し、ビジネスに役立つ知見を導き出す専門家のことです。", + "100年後に必要とされる会社は、「人」が中心の会社です。", + "フルリモートの環境で働くために必要なことは、「自分の時間をコントロールする」ことです。", + "国境の長いトンネルを抜けると、そこは雪国だった。", + "美味しい日本食といえば、やっぱりお寿司ですよね。", + ] + + tokenizer = GPTNeoXJapaneseTokenizer.from_pretrained(model_id) + model = GPTNeoXJapaneseForCausalLM.from_pretrained(model_id) + + predicted_outputs = [] + for prompt in prompts: + input_ids = tokenizer(prompt, return_tensors="pt").input_ids + generated_ids = model.generate(input_ids, max_length=50) + generated_string = tokenizer.batch_decode(generated_ids, skip_special_tokens=True) + predicted_outputs += generated_string + self.assertListEqual(predicted_outputs, EXPECTED_OUTPUTS) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_tokenization_gpt_neox_japanese.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_tokenization_gpt_neox_japanese.py new file mode 100644 index 0000000000000000000000000000000000000000..293116a24e33bb591aafc5e4fae8064ad5e12e5a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_neox_japanese/test_tokenization_gpt_neox_japanese.py @@ -0,0 +1,136 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers.models.gpt_neox_japanese.tokenization_gpt_neox_japanese import ( + VOCAB_FILES_NAMES, + GPTNeoXJapaneseTokenizer, +) +from transformers.testing_utils import require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class GPTNeoXJapaneseTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = GPTNeoXJapaneseTokenizer + test_rust_tokenizer = False + from_pretrained_kwargs = {"do_clean_text": False, "add_prefix_space": False} + + def setUp(self): + super().setUp() + + vocab_tokens = [ + "こん", + "こんに", + "にちは", + "ばんは", + "世界,㔺界", + "、", + "。", + "
", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "<|emoji1|>", + "", + "<|startoftext|>", + "<|endoftext|>", + ] + emoji_tokens = {"emoji": {"\ud83d\ude00": "<|emoji1|>"}, "emoji_inv": {"<|emoji1|>": "\ud83d\ude00"}} # 😀 + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.emoji_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["emoji_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + with open(self.emoji_file, "w") as emoji_writer: + emoji_writer.write(json.dumps(emoji_tokens)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return GPTNeoXJapaneseTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "こんにちは、世界。 \nこんばんは、㔺界。😀" + output_text = "こんにちは、世界。 \nこんばんは、世界。😀" + return input_text, output_text + + def get_clean_sequence(self, tokenizer): + input_text, output_text = self.get_input_output_texts(tokenizer) + ids = tokenizer.encode(output_text, add_special_tokens=False) + text = tokenizer.decode(ids, clean_up_tokenization_spaces=False) + return text, ids + + def test_pretokenized_inputs(self): + pass # TODO add if relevant + + def test_maximum_encoding_length_pair_input(self): + pass # TODO add if relevant + + def test_maximum_encoding_length_single_input(self): + pass # TODO add if relevant + + def test_full_tokenizer(self): + tokenizer = self.get_tokenizer() + + # Testing tokenization + input_text = "こんにちは、世界。 こんばんは、㔺界。" + expected_token = ["こん", "にちは", "、", "世界", "。", "", "こん", "ばんは", "、", "㔺界", "。"] + tokens = tokenizer.tokenize(input_text) + self.assertListEqual(tokens, expected_token) + + # Testing conversion to ids without special tokens + expected_ids = [0, 2, 5, 4, 6, 8, 0, 3, 5, 4, 6] + input_ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual(input_ids, expected_ids) + + # Testing conversion to ids with special tokens + input_tokens = tokens + [tokenizer.unk_token] + expected_ids = [0, 2, 5, 4, 6, 8, 0, 3, 5, 4, 6, 19] + input_ids = tokenizer.convert_tokens_to_ids(input_tokens) + self.assertListEqual(input_ids, expected_ids) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("abeja/gpt-neox-japanese-2.7b") + + ids_1 = tokenizer.encode("ありがとう。", add_special_tokens=False) + ids_2 = tokenizer.encode("どういたしまして。", add_special_tokens=False) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(ids_1) + encoded_pair = tokenizer.build_inputs_with_special_tokens(ids_1, ids_2) + + assert encoded_sentence == ids_1 + assert encoded_pair == ids_1 + ids_2 + + def test_conversion_reversible(self): + # Intentionally convert some words to accommodate character fluctuations unique to Japanese + pass + + def test_padding_different_model_input_name(self): + # tokenizer has no padding token + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_sw3/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_sw3/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_sw3/test_tokenization_gpt_sw3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_sw3/test_tokenization_gpt_sw3.py new file mode 100644 index 0000000000000000000000000000000000000000..b030996e89dcf02f37439b8c4d42ba00ba890576 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gpt_sw3/test_tokenization_gpt_sw3.py @@ -0,0 +1,130 @@ +# coding=utf-8 +# Copyright 2022 Hugging Face inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import GPTSw3Tokenizer +from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece_with_bytefallback.model") + + +@require_sentencepiece +@require_tokenizers +class GPTSw3TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = GPTSw3Tokenizer + test_rust_tokenizer = False + test_sentencepiece = True + test_sentencepiece_ignore_case = False + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = GPTSw3Tokenizer(SAMPLE_VOCAB, eos_token="", bos_token="", pad_token="") + + tokenizer.save_pretrained(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_text = "This is a test" + output_text = "This is a test" + return input_text, output_text + + def test_convert_token_and_id(self): + """Test ``_convert_token_to_id`` and ``_convert_id_to_token``.""" + token = "" + token_id = 1 + + self.assertEqual(self.get_tokenizer()._convert_token_to_id(token), token_id) + self.assertEqual(self.get_tokenizer()._convert_id_to_token(token_id), token) + + def test_get_vocab(self): + vocab_keys = list(self.get_tokenizer().get_vocab().keys()) + + self.assertEqual(vocab_keys[0], "") + self.assertEqual(vocab_keys[1], "") + self.assertEqual(vocab_keys[-1], "j") + self.assertEqual(len(vocab_keys), 2_000) + + def test_vocab_size(self): + self.assertEqual(self.get_tokenizer().vocab_size, 2_000) + + def test_full_tokenizer(self): + tokenizer = GPTSw3Tokenizer(SAMPLE_VOCAB) + + tokens = tokenizer.tokenize("This is a test") + self.assertListEqual(tokens, ["▁This", "▁is", "▁a", "▁t", "est"]) + + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [465, 287, 265, 631, 842]) + + tokens = tokenizer.tokenize("I was born in 92000, and this is falsé.") + # fmt: off + self.assertListEqual( + tokens, + ["▁I", "▁was", "▁bor", "n", "▁in", "▁", "<0x39>", "2", "0", "0", "0", ",", "▁and", "▁this", "▁is", "▁f", "al", "s", "<0xC3>", "<0xA9>", "."], + ) + # fmt: on + + ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual( + ids, + [262, 272, 1525, 286, 271, 268, 60, 916, 633, 633, 633, 259, 266, 301, 287, 384, 367, 263, 198, 172, 260], + ) + + back_tokens = tokenizer.convert_ids_to_tokens(ids) + # fmt: off + self.assertListEqual( + back_tokens, + ["▁I", "▁was", "▁bor", "n", "▁in", "▁", "<0x39>", "2", "0", "0", "0", ",", "▁and", "▁this", "▁is", "▁f", "al", "s", "<0xC3>", "<0xA9>", "."] + ) + # fmt: on + + def test_fast_encode_decode(self): + tokenizer = GPTSw3Tokenizer(SAMPLE_VOCAB) + texts = ["This is a test", "I was born in 92000, and this is falsé."] + expected_ids_list = [ + [465, 287, 265, 631, 842], + [262, 272, 1525, 286, 271, 268, 60, 916, 633, 633, 633, 259, 266, 301, 287, 384, 367, 263, 198, 172, 260], + ] + + # Test that encode_fast returns the same as tokenize + convert_tokens_to_ids + for text, expected_ids in zip(texts, expected_ids_list): + self.assertListEqual(tokenizer.encode_fast(text), expected_ids) + + # Test that decode_fast returns the input text + for text, token_ids in zip(texts, expected_ids_list): + self.assertEqual(tokenizer.decode_fast(token_ids), text) + + @slow + def test_tokenizer_integration(self): + sequences = [ + "<|python|>def fibonacci(n)\n if n < 0:\n print('Incorrect input')", + "Hey there, how are you doing this fine day?", + "This is a text with a trailing spaces followed by a dot .", + "Häj sväjs lillebrör! =)", + "Det är inget fel på Mr. Cool", + ] + + # fmt: off + expected_encoding = {"input_ids": [[63423, 5, 6811, 14954, 282, 816, 3821, 63466, 63425, 63462, 18, 63978, 678, 301, 1320, 63423, 63455, 63458, 18, 63982, 4246, 3940, 1901, 47789, 5547, 18994], [19630, 1100, 63446, 1342, 633, 544, 4488, 593, 5102, 2416, 63495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1652, 428, 268, 1936, 515, 268, 58593, 22413, 9106, 546, 268, 33213, 63979, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [55130, 63450, 924, 63449, 2249, 4062, 1558, 318, 63504, 21498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [509, 377, 2827, 2559, 332, 6575, 63443, 26801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], "token_type_ids": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], "attention_mask": [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} + # fmt: on + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="AI-Sweden/gpt-sw3-126m", + sequences=sequences, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_flax_gptj.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_flax_gptj.py new file mode 100644 index 0000000000000000000000000000000000000000..d177e345e88ecaefdd1d7c7a37c9763c85950601 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_flax_gptj.py @@ -0,0 +1,328 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +import unittest + +import numpy as np + +import transformers +from transformers import GPT2Tokenizer, GPTJConfig, is_flax_available, is_torch_available +from transformers.testing_utils import is_pt_flax_cross_test, require_flax, tooslow + +from ...generation.test_flax_utils import FlaxGenerationTesterMixin +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask + + +if is_flax_available(): + import jax + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + from transformers.models.gptj.modeling_flax_gptj import FlaxGPTJForCausalLM, FlaxGPTJModel + +if is_torch_available(): + import torch + + +class FlaxGPTJModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=99, + hidden_size=32, + rotary_dim=4, + num_hidden_layers=4, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + initializer_range=0.02, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.rotary_dim = rotary_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = GPTJConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + n_positions=self.max_position_embeddings, + use_cache=False, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + rotary_dim=self.rotary_dim, + ) + + return (config, input_ids, input_mask) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": attention_mask} + return config, inputs_dict + + def check_use_cache_forward(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + attention_mask = jnp.ones((input_ids.shape[0], max_decoder_length), dtype="i4") + + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask, + past_key_values=past_key_values, + position_ids=position_ids, + ) + + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + attention_mask=attention_mask, + past_key_values=outputs_cache.past_key_values, + position_ids=position_ids, + ) + + outputs = model(input_ids) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def check_use_cache_forward_with_attn_mask(self, model_class_name, config, input_ids, attention_mask): + max_decoder_length = 20 + model = model_class_name(config) + + attention_mask_cache = jnp.concatenate( + [attention_mask, jnp.zeros((attention_mask.shape[0], max_decoder_length - attention_mask.shape[1]))], + axis=-1, + ) + + past_key_values = model.init_cache(input_ids.shape[0], max_decoder_length) + position_ids = jnp.broadcast_to( + jnp.arange(input_ids.shape[-1] - 1)[None, :], (input_ids.shape[0], input_ids.shape[-1] - 1) + ) + + outputs_cache = model( + input_ids[:, :-1], + attention_mask=attention_mask_cache, + past_key_values=past_key_values, + position_ids=position_ids, + ) + position_ids = jnp.array(input_ids.shape[0] * [[input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model( + input_ids[:, -1:], + past_key_values=outputs_cache.past_key_values, + attention_mask=attention_mask_cache, + position_ids=position_ids, + ) + + outputs = model(input_ids, attention_mask=attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + +@require_flax +class FlaxGPTJModelTest(FlaxModelTesterMixin, FlaxGenerationTesterMixin, unittest.TestCase): + all_model_classes = (FlaxGPTJModel, FlaxGPTJForCausalLM) if is_flax_available() else () + all_generative_model_classes = (FlaxGPTJForCausalLM,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxGPTJModelTester(self) + + def test_use_cache_forward(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward(model_class_name, config, input_ids, attention_mask) + + def test_use_cache_forward_with_attn_mask(self): + for model_class_name in self.all_model_classes: + config, input_ids, attention_mask = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_use_cache_forward_with_attn_mask( + model_class_name, config, input_ids, attention_mask + ) + + @tooslow + def test_batch_generation(self): + tokenizer = GPT2Tokenizer.from_pretrained("gpt2", pad_token="<|endoftext|>", padding_side="left") + inputs = tokenizer(["Hello this is a long string", "Hey"], return_tensors="np", padding=True, truncation=True) + + model = FlaxGPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B") + model.do_sample = False + model.config.pad_token_id = model.config.eos_token_id + + jit_generate = jax.jit(model.generate) + + output_sequences = jit_generate( + inputs["input_ids"], attention_mask=inputs["attention_mask"], pad_token_id=tokenizer.pad_token_id + ).sequences + + output_string = tokenizer.batch_decode(output_sequences, skip_special_tokens=True) + + expected_string = [ + "Hello this is a long string of text.\n\nI'm trying to get the text of the", + "Hey, I'm a little late to the party. I'm going to", + ] + + self.assertListEqual(output_string, expected_string) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**prepared_inputs_dict).to_tuple() + self.assertEqual( + len(fx_outputs_loaded), len(pt_outputs), "Output lengths differ between Flax and PyTorch" + ) + for fx_output_loaded, pt_output in zip(fx_outputs_loaded, pt_outputs): + self.assert_almost_equals(fx_output_loaded[:, -1], pt_output[:, -1].numpy(), 4e-2) + + # overwrite from common since `attention_mask` in combination + # with `causal_mask` behaves slighly differently + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist()) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + fx_model = model_class(config, dtype=jnp.float32) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + batch_size, seq_length = pt_inputs["input_ids"].shape + rnd_start_indices = np.random.randint(0, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + pt_inputs["attention_mask"][batch_idx, :start_index] = 0 + pt_inputs["attention_mask"][batch_idx, start_index:] = 1 + prepared_inputs_dict["attention_mask"][batch_idx, :start_index] = 0 + prepared_inputs_dict["attention_mask"][batch_idx, start_index:] = 1 + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs).to_tuple() + + fx_outputs = fx_model(**prepared_inputs_dict).to_tuple() + self.assertEqual(len(fx_outputs), len(pt_outputs), "Output lengths differ between Flax and PyTorch") + for fx_output, pt_output in zip(fx_outputs, pt_outputs): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = pt_model_class.from_pretrained(tmpdirname, from_flax=True) + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs).to_tuple() + + self.assertEqual( + len(fx_outputs), len(pt_outputs_loaded), "Output lengths differ between Flax and PyTorch" + ) + for fx_output, pt_output in zip(fx_outputs, pt_outputs_loaded): + self.assert_almost_equals(fx_output[:, -1], pt_output[:, -1].numpy(), 4e-2) + + @tooslow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("EleutherAI/gpt-j-6B") + outputs = model(np.ones((1, 1))) + self.assertIsNotNone(outputs) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_gptj.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_gptj.py new file mode 100644 index 0000000000000000000000000000000000000000..5fe0fec39181f519903dce938839809267fbca56 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_gptj.py @@ -0,0 +1,636 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import datetime +import unittest + +from transformers import GPTJConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, tooslow, 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 ( + GPTJ_PRETRAINED_MODEL_ARCHIVE_LIST, + AutoTokenizer, + GPTJForCausalLM, + GPTJForQuestionAnswering, + GPTJForSequenceClassification, + GPTJModel, + ) + + +class GPTJModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + rotary_dim=4, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.0, + attention_probs_dropout_prob=0.0, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.rotary_dim = rotary_dim + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + self.bos_token_id = vocab_size - 1 + self.eos_token_id = vocab_size - 1 + self.pad_token_id = vocab_size - 1 + + def get_large_model_config(self): + return GPTJConfig.from_pretrained("EleutherAI/gpt-j-6B") + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config(self): + return GPTJConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + rotary_dim=self.rotary_dim, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_gptj_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTJModel(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_gptj_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTJModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gptj_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTJModel(config=config) + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + half_seq_length = self.seq_length // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past, attention_mask=attn_mask)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_gptj_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = GPTJModel(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, attention_mask=input_mask, use_cache=True) + + output, past = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and token_type_ids + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, token_type_ids=next_token_types, attention_mask=next_attention_mask, past_key_values=past + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = GPTJForCausalLM(config) + model.to(torch_device) + model.eval() + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_forward_and_backwards( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args, gradient_checkpointing=False + ): + model = GPTJForCausalLM(config) + if gradient_checkpointing: + model.gradient_checkpointing_enable() + model.to(torch_device) + + result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids) + self.parent.assertEqual(result.loss.shape, ()) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + result.loss.backward() + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "head_mask": head_mask} + + return config, inputs_dict + + +@require_torch +class GPTJModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + (GPTJModel, GPTJForCausalLM, GPTJForSequenceClassification, GPTJForQuestionAnswering) + if is_torch_available() + else () + ) + all_generative_model_classes = (GPTJForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": GPTJModel, + "question-answering": GPTJForQuestionAnswering, + "text-classification": GPTJForSequenceClassification, + "text-generation": GPTJForCausalLM, + "zero-shot": GPTJForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + test_pruning = False + test_missing_keys = False + test_model_parallel = False + test_head_masking = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if ( + pipeline_test_casse_name == "QAPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `QAPipelineTests` fails for a few models when the slower tokenizer are used. + # (The slower tokenizers were never used for pipeline tests before the pipeline testing rework) + # TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer + return True + + return False + + # special case for DoubleHeads model + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + return inputs_dict + + def setUp(self): + self.model_tester = GPTJModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPTJConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_gptj_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model(*config_and_inputs) + + def test_gptj_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_past(*config_and_inputs) + + def test_gptj_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_attention_mask_past(*config_and_inputs) + + def test_gptj_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_past_large_inputs(*config_and_inputs) + + def test_gptj_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_gptj_gradient_checkpointing(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs, gradient_checkpointing=True) + + @tooslow + def test_batch_generation(self): + # Marked as @tooslow due to GPU OOM + model = GPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", revision="float16", torch_dtype=torch.float16) + model.to(torch_device) + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B", revision="float16") + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = [ + "Hello, my dog is a little", + "Today, I", + ] + + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + token_type_ids = torch.cat( + [ + input_ids.new_full((input_ids.shape[0], input_ids.shape[1] - 1), 0), + input_ids.new_full((input_ids.shape[0], 1), 500), + ], + dim=-1, + ) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + ) + + outputs_tt = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + token_type_ids=token_type_ids, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate(input_ids=inputs_non_padded) + + num_paddings = inputs_non_padded.shape[-1] - inputs["attention_mask"][-1].long().sum().cpu().item() + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_length=model.config.max_length - num_paddings) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + batch_out_sentence_tt = tokenizer.batch_decode(outputs_tt, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + "Hello, my dog is a little over a year old and has been diagnosed with a heart murmur", + "Today, I’m going to talk about the most important thing in the", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertTrue(batch_out_sentence_tt != batch_out_sentence) # token_type_ids should change output + self.assertListEqual(expected_output_sentence, [non_padded_sentence, padded_sentence]) + + @slow + def test_model_from_pretrained(self): + for model_name in GPTJ_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GPTJModel.from_pretrained(model_name, revision="float16", torch_dtype=torch.float16) + self.assertIsNotNone(model) + + +@require_torch +class GPTJModelLanguageGenerationTest(unittest.TestCase): + @tooslow + def test_lm_generate_gptj(self): + # Marked as @tooslow due to GPU OOM + for checkpointing in [True, False]: + model = GPTJForCausalLM.from_pretrained( + "EleutherAI/gpt-j-6B", revision="float16", torch_dtype=torch.float16 + ) + if checkpointing: + model.gradient_checkpointing_enable() + else: + model.gradient_checkpointing_disable() + model.to(torch_device) + input_ids = torch.tensor([[464, 3290]], dtype=torch.long, device=torch_device) # The dog + # fmt: off + # The dog is a man's best friend. It is a loyal companion, and it is a friend + expected_output_ids = [464, 3290, 318, 257, 582, 338, 1266, 1545, 13, 632, 318, 257, 9112, 15185, 11, 290, 340, 318, 257, 1545] + # fmt: on + output_ids = model.generate(input_ids, do_sample=False) + self.assertListEqual(output_ids[0].tolist(), expected_output_ids) + + @tooslow + def test_gptj_sample(self): + # Marked as @tooslow due to GPU OOM (issue #13676) + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B", revision="float16") + model = GPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", revision="float16", torch_dtype=torch.float16) + model.to(torch_device) + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + output_ids = model.generate(input_ids, do_sample=True) + output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True) + + token_type_ids = tokenized.token_type_ids.to(torch_device) + output_seq = model.generate(input_ids=input_ids, do_sample=True, num_return_sequences=5) + output_seq_tt = model.generate( + input_ids=input_ids, token_type_ids=token_type_ids, do_sample=True, num_return_sequences=5 + ) + output_seq_strs = tokenizer.batch_decode(output_seq, skip_special_tokens=True) + output_seq_tt_strs = tokenizer.batch_decode(output_seq_tt, skip_special_tokens=True) + + if torch_device == "cuda": + EXPECTED_OUTPUT_STR = ( + "Today is a nice day and I've already been enjoying it. I walked to work with my wife" + ) + else: + EXPECTED_OUTPUT_STR = "Today is a nice day and one of those days that feels a bit more alive. I am ready" + + self.assertEqual(output_str, EXPECTED_OUTPUT_STR) + self.assertTrue( + all([output_seq_strs[idx] != output_seq_tt_strs[idx] for idx in range(len(output_seq_tt_strs))]) + ) # token_type_ids should change output + + @slow + def test_gptj_sample_max_time(self): + tokenizer = AutoTokenizer.from_pretrained("anton-l/gpt-j-tiny-random") + model = GPTJForCausalLM.from_pretrained("anton-l/gpt-j-tiny-random") + model.to(torch_device) + + torch.manual_seed(0) + tokenized = tokenizer("Today is a nice day and", return_tensors="pt", return_token_type_ids=True) + input_ids = tokenized.input_ids.to(torch_device) + + MAX_TIME = 0.5 + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=True, num_beams=2, max_time=MAX_TIME, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=MAX_TIME)) + self.assertLess(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + start = datetime.datetime.now() + model.generate(input_ids, do_sample=False, max_time=None, max_length=256) + duration = datetime.datetime.now() - start + self.assertGreater(duration, datetime.timedelta(seconds=1.5 * MAX_TIME)) + + @tooslow + def test_contrastive_search_gptj(self): + article = ( + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and " + "research laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based" + ) + + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B") + model = GPTJForCausalLM.from_pretrained( + "EleutherAI/gpt-j-6B", revision="float16", torch_dtype=torch.float16 + ).to(torch_device) + input_ids = tokenizer(article, return_tensors="pt").input_ids.to(torch_device) + + outputs = model.generate(input_ids, penalty_alpha=0.6, top_k=4, max_length=256) + generated_text = tokenizer.batch_decode(outputs, skip_special_tokens=True) + + self.assertListEqual( + generated_text, + [ + "DeepMind Technologies is a British artificial intelligence subsidiary of Alphabet Inc. and research " + "laboratory founded in 2010. DeepMind was acquired by Google in 2014. The company is based in London, " + "United Kingdom with offices in Mountain View, San Francisco, New York City, Paris, Tokyo, Seoul, " + "Beijing, Singapore, Tel Aviv, Dublin, Sydney, and Melbourne.[1]\n\nContents\n\nIn 2010, Google's " + "parent company, Alphabet, announced a $500 million investment in DeepMind, with the aim of creating " + "a company that would apply deep learning to problems in healthcare, energy, transportation, and " + "other areas.[2]\n\nOn April 23, 2014, Google announced that it had acquired DeepMind for $400 " + "million in cash and stock.[3] The acquisition was seen as a way for Google to enter the " + "fast-growing field of artificial intelligence (AI), which it had so far avoided due to concerns " + 'about ethical and social implications.[4] Google co-founder Sergey Brin said that he was "thrilled" ' + 'to have acquired DeepMind, and that it would "help us push the boundaries of AI even further."' + "[5]\n\nDeepMind's founders, Demis Hassabis and Mustafa Suleyman, were joined by a number of Google " + "employees" + ], + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_tf_gptj.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_tf_gptj.py new file mode 100644 index 0000000000000000000000000000000000000000..3aa63d2790a4310eb1e6e48c75e68d197e489e76 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptj/test_modeling_tf_gptj.py @@ -0,0 +1,480 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import AutoTokenizer, GPTJConfig, is_tf_available +from transformers.testing_utils import require_tf, slow, tooslow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin +from ...utils.test_modeling_tf_core import TFCoreModelTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.gptj.modeling_tf_gptj import ( + TFGPTJForCausalLM, + TFGPTJForQuestionAnswering, + TFGPTJForSequenceClassification, + TFGPTJModel, + shape_list, + ) + + +class TFGPTJModelTester: + def __init__(self, parent): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_token_type_ids = True + self.use_input_mask = True + self.use_labels = True + self.use_mc_token_ids = True + self.vocab_size = 99 + self.hidden_size = 32 + self.rotary_dim = 4 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + self.bos_token_id = self.vocab_size - 1 + self.eos_token_id = self.vocab_size - 1 + self.pad_token_id = self.vocab_size - 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = GPTJConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + bos_token_id=self.bos_token_id, + eos_token_id=self.eos_token_id, + pad_token_id=self.pad_token_id, + rotary_dim=self.rotary_dim, + return_dict=True, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def create_and_check_gptj_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPTJModel(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + + inputs = [input_ids, None, input_mask] # None is the input for 'past' + result = model(inputs) + + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_gptj_model_past(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPTJModel(config=config) + + # first forward pass + outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids, token_type_ids=token_type_ids) + outputs_no_past = model(input_ids, token_type_ids=token_type_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + next_token_types = ids_tensor([self.batch_size, 1], self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_token_type_ids = tf.concat([token_type_ids, next_token_types], axis=-1) + + output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"] + output_from_past = model(next_tokens, token_type_ids=next_token_types, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6) + + def create_and_check_gptj_model_attention_mask_past( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = TFGPTJModel(config=config) + + # create attention mask + half_seq_length = self.seq_length // 2 + attn_mask_begin = tf.ones((self.batch_size, half_seq_length), dtype=tf.int32) + attn_mask_end = tf.zeros((self.batch_size, self.seq_length - half_seq_length), dtype=tf.int32) + attn_mask = tf.concat([attn_mask_begin, attn_mask_end], axis=1) + + # first forward pass + output, past_key_values = model(input_ids, attention_mask=attn_mask).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).numpy() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, self.seq_length), config.vocab_size) + vector_condition = tf.range(self.seq_length) == (self.seq_length - random_seq_idx_to_change) + condition = tf.transpose( + tf.broadcast_to(tf.expand_dims(vector_condition, -1), (self.seq_length, self.batch_size)) + ) + input_ids = tf.where(condition, random_other_next_tokens, input_ids) + + # append to next input_ids and attn_mask + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + attn_mask = tf.concat([attn_mask, tf.ones((shape_list(attn_mask)[0], 1), dtype=tf.int32)], axis=1) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values, attention_mask=attn_mask)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx] + output_from_past_slice = output_from_past[:, 0, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-12) + + def create_and_check_gptj_model_past_large_inputs( + self, config, input_ids, input_mask, head_mask, token_type_ids, *args + ): + model = TFGPTJModel(config=config) + + input_ids = input_ids[:1, :] + input_mask = input_mask[:1, :] + token_type_ids = token_type_ids[:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + next_token_types = ids_tensor((self.batch_size, 3), self.type_vocab_size) + + # append to next input_ids and token_type_ids + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([input_mask, next_attn_mask], axis=-1) + next_token_type_ids = tf.concat([token_type_ids, next_token_types], axis=-1) + + output_from_no_past = model( + next_input_ids, token_type_ids=next_token_type_ids, attention_mask=next_attention_mask + )["last_hidden_state"] + output_from_past = model( + next_tokens, + token_type_ids=next_token_types, + attention_mask=next_attention_mask, + past_key_values=past_key_values, + )["last_hidden_state"] + self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + def create_and_check_gptj_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args): + model = TFGPTJForCausalLM(config=config) + inputs = { + "input_ids": input_ids, + "attention_mask": input_mask, + "token_type_ids": token_type_ids, + } + result = model(inputs) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + input_ids, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_tf +class TFGPTJModelTest(TFModelTesterMixin, TFCoreModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + (TFGPTJForCausalLM, TFGPTJForSequenceClassification, TFGPTJForQuestionAnswering, TFGPTJModel) + if is_tf_available() + else () + ) + + all_generative_model_classes = (TFGPTJForCausalLM,) if is_tf_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": TFGPTJModel, + "question-answering": TFGPTJForQuestionAnswering, + "text-classification": TFGPTJForSequenceClassification, + "text-generation": TFGPTJForCausalLM, + "zero-shot": TFGPTJForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_onnx = False + test_pruning = False + test_missing_keys = False + test_head_masking = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if ( + pipeline_test_casse_name == "QAPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `QAPipelineTests` fails for a few models when the slower tokenizer are used. + # (The slower tokenizers were never used for pipeline tests before the pipeline testing rework) + # TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer + return True + + return False + + def setUp(self): + self.model_tester = TFGPTJModelTester(self) + self.config_tester = ConfigTester(self, config_class=GPTJConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_gptj_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model(*config_and_inputs) + + def test_gptj_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_past(*config_and_inputs) + + def test_gptj_model_att_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_attention_mask_past(*config_and_inputs) + + def test_gptj_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_model_past_large_inputs(*config_and_inputs) + + def test_gptj_lm_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_gptj_lm_head_model(*config_and_inputs) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in self.all_generative_model_classes: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert name is None + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + @slow + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) > 0, + "skip testing on GPU for now to avoid GPU OOM.", + ) + def test_model_from_pretrained(self): + model = TFGPTJModel.from_pretrained("EleutherAI/gpt-j-6B", from_pt=True) + self.assertIsNotNone(model) + + @unittest.skip(reason="Currently, model embeddings are going to undergo a major refactor.") + def test_resize_token_embeddings(self): + super().test_resize_token_embeddings() + + +@require_tf +@tooslow +# Marked as @tooslow due to GPU OOM -- but still useful to run locally. Requires ~39GB of RAM. +class TFGPTJModelLanguageGenerationTest(unittest.TestCase): + def test_lm_generate_gptj(self): + model = TFGPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", from_pt=True) + input_ids = tf.convert_to_tensor([[464, 3290]], dtype=tf.int32) # The dog + # fmt: off + # The dog is a man's best friend. It is a loyal companion, and it is a friend + expected_output_ids = [464, 3290, 318, 257, 582, 338, 1266, 1545, 13, 632, 318, 257, 9112, 15185, 11, 290, 340, 318, 257, 1545] + # fmt: on + output_ids = model.generate(input_ids, do_sample=False) + self.assertListEqual(output_ids[0].numpy().tolist(), expected_output_ids) + + def test_gptj_sample(self): + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B", revision="float16") + model = TFGPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", revision="float16", from_pt=True) + + tokenized = tokenizer("Today is a nice day and", return_tensors="tf") + # forces the generation to happen on CPU, to avoid GPU-related quirks + with tf.device(":/CPU:0"): + output_ids = model.generate(**tokenized, do_sample=True, seed=[42, 0]) + output_str = tokenizer.decode(output_ids[0], skip_special_tokens=True) + + EXPECTED_OUTPUT_STR = "Today is a nice day and I’m going to go for a walk. I’" + self.assertEqual(output_str, EXPECTED_OUTPUT_STR) + + def _get_beam_search_test_objects(self): + model = TFGPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", revision="float16", from_pt=True) + tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B", revision="float16") + + tokenizer.padding_side = "left" + + # Define PAD Token = EOS Token = 50256 + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + + # use different length sentences to test batching + sentences = [ + "Hello, my dog is a little", + "Today, I", + ] + expected_output_sentences = [ + "Hello, my dog is a little over a year old and has been diagnosed with hip dysplasia", + "Today, I’m going to be talking about a topic that’", + ] + return model, tokenizer, sentences, expected_output_sentences + + def test_batch_beam_search(self): + # Confirms that we get the expected results with left-padded beam search + model, tokenizer, sentences, expected_output_sentences = self._get_beam_search_test_objects() + + inputs = tokenizer(sentences, return_tensors="tf", padding=True) + outputs = model.generate(**inputs, do_sample=False, num_beams=2) + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + self.assertListEqual(expected_output_sentences, batch_out_sentence) + + def test_batch_left_padding(self): + # Confirms that left-padding is working properly + model, tokenizer, sentences, expected_output_sentences = self._get_beam_search_test_objects() + + inputs = tokenizer(sentences, return_tensors="tf", padding=True) + inputs_non_padded = tokenizer(sentences[0], return_tensors="tf") + output_non_padded = model.generate(**inputs_non_padded, do_sample=False, num_beams=2) + num_paddings = ( + shape_list(inputs_non_padded["input_ids"])[-1] + - tf.reduce_sum(tf.cast(inputs["attention_mask"][-1], tf.int64)).numpy() + ) + inputs_padded = tokenizer(sentences[1], return_tensors="tf") + output_padded = model.generate( + **inputs_padded, do_sample=False, num_beams=2, max_length=model.config.max_length - num_paddings + ) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + self.assertListEqual(expected_output_sentences, [non_padded_sentence, padded_sentence]) + + def test_xla_beam_search(self): + # Confirms that XLA is working properly + model, tokenizer, sentences, expected_output_sentences = self._get_beam_search_test_objects() + + inputs = tokenizer(sentences, return_tensors="tf", padding=True) + xla_generate = tf.function(model.generate, jit_compile=True) + outputs_xla = xla_generate(**inputs, do_sample=False, num_beams=2) + xla_sentence = tokenizer.batch_decode(outputs_xla, skip_special_tokens=True) + self.assertListEqual(expected_output_sentences, xla_sentence) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_modeling_gptsan_japanese.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_modeling_gptsan_japanese.py new file mode 100644 index 0000000000000000000000000000000000000000..d00c755f3cb99e8e19953d2e31ec0dfada4750ef --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_modeling_gptsan_japanese.py @@ -0,0 +1,465 @@ +# coding=utf-8 +# Copyright 2023 Toshiyuki Sakamoto(tanreinama) and HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers import ( + GPTSanJapaneseConfig, + GPTSanJapaneseForConditionalGeneration, + GPTSanJapaneseModel, + GPTSanJapaneseTokenizer, + is_torch_available, +) +from transformers.generation import GenerationConfig +from transformers.testing_utils import require_torch, slow, tooslow, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +class GPTSanJapaneseTester: + def __init__( + self, + parent, + vocab_size=36000, + batch_size=13, + num_contexts=7, + # For common tests + is_training=True, + hidden_size=32, + ext_size=42, + num_hidden_layers=5, + num_ext_layers=2, + num_attention_heads=4, + num_experts=2, + d_ff=32, + d_ext=80, + d_spout=33, + dropout_rate=0.0, + layer_norm_epsilon=1e-6, + expert_capacity=100, + router_jitter_noise=0.0, + ): + self.vocab_size = vocab_size + self.parent = parent + self.batch_size = batch_size + self.num_contexts = num_contexts + # For common tests + self.seq_length = self.num_contexts + self.is_training = is_training + self.hidden_size = hidden_size + self.num_ext_layers = num_ext_layers + self.ext_size = ext_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.num_experts = num_experts + self.d_ff = d_ff + self.d_ext = d_ext + self.d_spout = d_spout + self.dropout_rate = dropout_rate + self.layer_norm_epsilon = layer_norm_epsilon + self.expert_capacity = expert_capacity + self.router_jitter_noise = router_jitter_noise + + def get_large_model_config(self): + return GPTSanJapaneseConfig.from_pretrained("Tanrei/GPTSAN-japanese") + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = self.get_config() + + return (config, input_ids) + + def prepare_config_and_inputs_for_common(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = self.get_config() + + return (config, {"input_ids": input_ids}) + + def get_config(self): + return GPTSanJapaneseConfig( + vocab_size=self.vocab_size, + num_contexts=self.seq_length, + d_model=self.hidden_size, + d_ff=self.d_ff, + d_ext=self.d_ext, + d_spout=self.d_spout, + num_switch_layers=self.num_hidden_layers - self.num_ext_layers, + num_ext_layers=self.num_ext_layers, + num_heads=self.num_attention_heads, + num_experts=self.num_experts, + expert_capacity=self.expert_capacity, + dropout_rate=self.dropout_rate, + layer_norm_epsilon=self.layer_norm_epsilon, + router_jitter_noise=self.router_jitter_noise, + ) + + def create_and_check_model( + self, + config, + input_ids, + ): + model = GPTSanJapaneseForConditionalGeneration(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids=input_ids, + ) + self.parent.assertIsNotNone(result) + + +@require_torch +class GPTSanJapaneseTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GPTSanJapaneseModel,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": GPTSanJapaneseForConditionalGeneration, + "feature-extraction": GPTSanJapaneseForConditionalGeneration, + "summarization": GPTSanJapaneseForConditionalGeneration, + "text2text-generation": GPTSanJapaneseForConditionalGeneration, + "translation": GPTSanJapaneseForConditionalGeneration, + } + if is_torch_available() + else {} + ) + fx_compatible = False + is_encoder_decoder = False + test_pruning = False + test_headmasking = False + test_cpu_offload = False + test_disk_offload = False + test_save_load_fast_init_to_base = False + test_training = False + # The small GPTSAN_JAPANESE model needs higher percentages for CPU/MP tests + model_split_percents = [0.8, 0.9] + + # TODO: Fix the failed tests when this model gets more usage + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "SummarizationPipelineTests": + # TODO: fix `_reorder_cache` is not implemented for this model + return True + elif pipeline_test_casse_name == "Text2TextGenerationPipelineTests": + # TODO: check this. + return True + + return False + + def setUp(self): + self.model_tester = GPTSanJapaneseTester(self) + self.config_tester = ConfigTester(self, config_class=GPTSanJapaneseConfig, d_model=37) + + def test_config(self): + GPTSanJapaneseConfig() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip( + reason="skip for now as the computed `max_memory` by `model_split_percents` in the test method will be changed inside `from_pretrained`" + ) + def test_model_parallelism(self): + super().test_model_parallelism() + + +@require_torch +class GPTSanJapaneseForConditionalGenerationTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + all_model_classes = (GPTSanJapaneseForConditionalGeneration,) if is_torch_available() else () + fx_compatible = False + is_encoder_decoder = False + test_pruning = False + test_headmasking = False + test_cpu_offload = False + test_disk_offload = False + # The small GPTSAN_JAPANESE model needs higher percentages for CPU/MP tests + model_split_percents = [0.8, 0.9] + + def setUp(self): + self.model_tester = GPTSanJapaneseTester(self) + self.config_tester = ConfigTester(self, config_class=GPTSanJapaneseConfig, d_model=37) + + def test_config(self): + GPTSanJapaneseConfig() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip( + reason="skip for now as the computed `max_memory` by `model_split_percents` in the test method will be changed inside `from_pretrained`" + ) + def test_model_parallelism(self): + super().test_model_parallelism() + + @slow + def test_logits(self): + model = GPTSanJapaneseForConditionalGeneration.from_pretrained("Tanrei/GPTSAN-japanese") + tokenizer = GPTSanJapaneseTokenizer.from_pretrained("Tanrei/GPTSAN-japanese") + input_ids = tokenizer.encode("武田信玄は", return_tensors="pt") + outputs = model(input_ids) + output_logits = outputs.logits.detach().cpu().numpy() + # Output of original model created with mesh-tensoflow + target = [ + # fmt: off + [-12.037839889526367, -12.433061599731445, -14.333840370178223, -12.450345993041992, -11.1661376953125, + -11.930137634277344, -10.659740447998047, -12.909574508666992, -13.241043090820312, -13.398579597473145, + -11.107524871826172, -12.3685941696167, -22.97943115234375, -10.481067657470703, -12.484030723571777, + -12.807360649108887, -14.769700050354004, -12.233579635620117, -13.428145408630371, -22.624177932739258], + [-7.511149883270264, -8.281851768493652, -7.943127155303955, -7.55021333694458, -6.49869966506958, + -7.586796283721924, -6.978085994720459, -7.839145183563232, -8.21964168548584, -8.695091247558594, + -6.706910610198975, -6.6585798263549805, -19.565698623657227, -5.353842735290527, -8.350686073303223, + -8.039388656616211, -10.856569290161133, -7.75154447555542, -8.819022178649902, -19.51532745361328], + [-9.73066234588623, -10.223922729492188, -9.932981491088867, -11.857836723327637, -7.662626266479492, + -11.13529109954834, -7.765097618103027, -11.472923278808594, -9.543149948120117, -11.905633926391602, + -9.366164207458496, -11.5734281539917, -23.699003219604492, -9.429590225219727, -10.42839241027832, + -10.585240364074707, -10.94771957397461, -11.095416069030762, -10.390240669250488, -23.769372940063477], + [-9.728265762329102, -9.859712600708008, -10.09729290008545, -9.678522109985352, -6.879519939422607, + -9.68487548828125, -4.2803425788879395, -10.018914222717285, -9.308445930480957, -10.63394546508789, + -8.083646774291992, -9.06301498413086, -21.904266357421875, -8.90160846710205, -8.841876029968262, + -11.856719970703125, -12.079398155212402, -11.233753204345703, -10.177338600158691, -21.87256622314453], + [-9.669764518737793, -9.614198684692383, -9.814510345458984, -9.996501922607422, -11.375690460205078, + -10.113405227661133, -10.546867370605469, -10.04369068145752, -10.907809257507324, -10.504216194152832, + -11.129199028015137, -10.151124000549316, -21.96586799621582, -9.086349487304688, -11.730339050292969, + -10.460667610168457, -10.298049926757812, -10.784148216247559, -10.840693473815918, -22.03152847290039], + # fmt: on + ] + target = np.array(target).flatten() + predict = output_logits[0, :, :20].flatten() + + def check(a, b, epsilon=5e-4): + return abs(a - b) < epsilon * max(abs(a), abs(b)) + + self.assertTrue(np.all([check(target[i], predict[i]) for i in range(len(target))])) + + @slow + def test_batch_generation(self): + model = GPTSanJapaneseForConditionalGeneration.from_pretrained("Tanrei/GPTSAN-japanese") + tokenizer = GPTSanJapaneseTokenizer.from_pretrained("Tanrei/GPTSAN-japanese") + model.to(torch_device) + + # set deterministically + generation_config = GenerationConfig.from_pretrained("Tanrei/GPTSAN-japanese") + generation_config.top_k = 1 + + # use different length sentences to test batching + sentences = [ + "甲斐なら武田と言うほど", + "織田信長は、", + ] + + tokenizer.padding_side = "left" + inputs = tokenizer(sentences, return_tensors="pt", padding=True) + input_ids = inputs["input_ids"].to(torch_device) + + self.assertNotEqual(inputs["attention_mask"][0].numpy().tolist(), inputs["attention_mask"][1].numpy().tolist()) + + outputs = model.generate( + input_ids=input_ids, + attention_mask=inputs["attention_mask"].to(torch_device), + max_new_tokens=3, + generation_config=generation_config, + ) + + inputs_non_padded = tokenizer(sentences[0], return_tensors="pt").input_ids.to(torch_device) + output_non_padded = model.generate( + input_ids=inputs_non_padded, max_new_tokens=3, generation_config=generation_config + ) + + inputs_padded = tokenizer(sentences[1], return_tensors="pt").input_ids.to(torch_device) + output_padded = model.generate(input_ids=inputs_padded, max_new_tokens=3, generation_config=generation_config) + + self.assertNotEqual(inputs_non_padded.shape, inputs_padded.shape) + + batch_out_sentence = tokenizer.batch_decode(outputs, skip_special_tokens=True) + non_padded_sentence = tokenizer.decode(output_non_padded[0], skip_special_tokens=True) + padded_sentence = tokenizer.decode(output_padded[0], skip_special_tokens=True) + + expected_output_sentence = [ + "甲斐なら武田と言うほど甲斐の武田", + "織田信長は、このような", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertListEqual(batch_out_sentence, [non_padded_sentence, padded_sentence]) + + @tooslow + def test_sample(self): + model = GPTSanJapaneseForConditionalGeneration.from_pretrained("Tanrei/GPTSAN-japanese") + tokenizer = GPTSanJapaneseTokenizer.from_pretrained("Tanrei/GPTSAN-japanese") + # Output of original model created with mesh-tensoflow + target = [ + ("武田信玄は", 35675), + ("武田信玄は、", 45), + ("武田信玄は、この", 29), + ("武田信玄は、このよう", 30642), + ("武田信玄は、このような", 35680), + ("武田信玄は、このような「", 8640), + ("武田信玄は、このような「武田", 31617), + ("武田信玄は、このような「武田家", 30646), + ("武田信玄は、このような「武田家の", 31617), + ("武田信玄は、このような「武田家の家", 31381), + ] + for input, output in target: + input_ids = tokenizer.encode(input, return_tensors="pt") + outputs = model(input_ids) + output_logits = outputs.logits.detach().cpu().numpy()[0] + output_id = np.argmax(output_logits[-1]) + self.assertEqual(output_id, output) + + @slow + def test_spout_generation(self): + model = GPTSanJapaneseForConditionalGeneration.from_pretrained("Tanrei/GPTSAN-japanese") + tokenizer = GPTSanJapaneseTokenizer.from_pretrained("Tanrei/GPTSAN-japanese") + model.to(torch_device) + + # set deterministically + generation_config = GenerationConfig.from_pretrained("Tanrei/GPTSAN-japanese") + generation_config.top_k = 1 + + input_text = "武田信玄は、" + input_ids = tokenizer(input_text, return_tensors="pt").input_ids.to(torch_device) + input_ids_batch = tokenizer([input_text, input_text], return_tensors="pt").input_ids.to(torch_device) + + # spout from uniform and one-hot + spouts = [ + # fmt: off + [0.87882208, 0.38426396, 0.33220248, 0.43890406, 0.16562252, + 0.04803985, 0.211572 , 0.23188473, 0.37153068, 0.7836377 , + 0.02160172, 0.38761719, 0.75290772, 0.90198857, 0.34365777, + 0.64168169, 0.44318471, 0.14575746, 0.92562881, 0.40812148, + 0.29019122, 0.88861599, 0.65524846, 0.43563456, 0.38177187, + 0.70832965, 0.81527892, 0.68832812, 0.38833192, 0.4561522 , + 0.14828817, 0.47248213, 0.54357335, 0.82009566, 0.1338884 , + 0.02755417, 0.19764677, 0.2422084 , 0.04757674, 0.65409606, + 0.0824589 , 0.03304383, 0.94387689, 0.98764509, 0.82433901, + 0.27646741, 0.64907493, 0.76009406, 0.30087915, 0.17904689, + 0.41601714, 0.67046398, 0.10422822, 0.08447374, 0.07354344, + 0.61423565, 0.70284866, 0.7532333 , 0.1972038 , 0.29575659, + 0.90583886, 0.29265307, 0.50000175, 0.70407655, 0.889363 , + 0.81904418, 0.66829128, 0.64468815, 0.56563723, 0.85601875, + 0.94924672, 0.00166762, 0.25220643, 0.74540219, 0.67993247, + 0.1549675 , 0.39385352, 0.92153607, 0.63745931, 0.27759043, + 0.84702295, 0.65904271, 0.58676614, 0.8666936 , 0.39607438, + 0.79954983, 0.42220697, 0.39650381, 0.7849864 , 0.56150201, + 0.15678925, 0.14746032, 0.34542114, 0.47026783, 0.11956489, + 0.25421435, 0.33788901, 0.68934842, 0.36424685, 0.71737898, + 0.38983449, 0.94393779, 0.39575588, 0.36616553, 0.87104665, + 0.64630203, 0.22516905, 0.88270804, 0.15031338, 0.75144345, + 0.46459025, 0.85396454, 0.86355643, 0.65139851, 0.70266061, + 0.30241389, 0.81056497, 0.88865969, 0.38773807, 0.70635849, + 0.90718459, 0.43245789, 0.28000654, 0.45935562, 0.08773519, + 0.9552151 , 0.93901511, 0.22489288], # uniform + [1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., 0., 0., 0., 0.], + # fmt: on + ] + + output1 = model.generate( + input_ids=input_ids, + spout=spouts[0], + max_new_tokens=20, + generation_config=generation_config, + ) + + output2 = model.generate( + input_ids=input_ids, + spout=spouts[1], + max_new_tokens=20, + generation_config=generation_config, + ) + + output3 = model.generate( + input_ids=input_ids_batch, + spout=spouts, + max_new_tokens=20, + generation_config=generation_config, + ) + + out1_sentence = tokenizer.decode(output1[0]) + out2_sentence = tokenizer.decode(output2[0]) + batch_out_sentence = tokenizer.batch_decode(output3) + + expected_output_sentence = [ + "武田信玄は、武田氏の滅亡後、武田氏の居城であった甲斐武田氏の居城である", + "武田信玄は、武田家の滅亡を防ぐため、武田家の家臣である武田信虎を討", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertListEqual(batch_out_sentence, [out1_sentence, out2_sentence]) + + @slow + def test_prefix_lm_generation(self): + model = GPTSanJapaneseForConditionalGeneration.from_pretrained("Tanrei/GPTSAN-japanese") + tokenizer = GPTSanJapaneseTokenizer.from_pretrained("Tanrei/GPTSAN-japanese") + model.to(torch_device) + + # set deterministically + generation_config = GenerationConfig.from_pretrained("Tanrei/GPTSAN-japanese") + generation_config.top_k = 1 + + prefix_text_1 = "武田信玄" + prefix_text_2 = "織田信長" + input_text_1 = "は、" + input_text_2 = "が、" + input_tok_1 = tokenizer(input_text_1, prefix_text=prefix_text_1, return_tensors="pt") + input_tok_2 = tokenizer(input_text_2, prefix_text=prefix_text_2, return_tensors="pt") + input_tok_3 = tokenizer([[prefix_text_1, input_text_1], [prefix_text_2, input_text_2]], return_tensors="pt") + + output1 = model.generate( + input_ids=input_tok_1.input_ids.to(torch_device), + token_type_ids=input_tok_1.token_type_ids.to(torch_device), + max_new_tokens=20, + generation_config=generation_config, + ) + + output2 = model.generate( + input_ids=input_tok_2.input_ids.to(torch_device), + token_type_ids=input_tok_2.token_type_ids.to(torch_device), + max_new_tokens=20, + generation_config=generation_config, + ) + + output3 = model.generate( + input_ids=input_tok_3.input_ids.to(torch_device), + token_type_ids=input_tok_3.token_type_ids.to(torch_device), + attention_mask=input_tok_3.attention_mask.to(torch_device), + max_new_tokens=20, + generation_config=generation_config, + ) + + out1_sentence = tokenizer.decode(output1[0]) + out2_sentence = tokenizer.decode(output2[0]) + batch_out_sentence = tokenizer.batch_decode(output3) + + expected_output_sentence = [ + "武田信玄は、武田氏の祖である武田信虎を、その子・武田信友を擁して", + "織田信長が、織田信長の妻・お市の方を妻として迎えたという逸話が残", + ] + self.assertListEqual(expected_output_sentence, batch_out_sentence) + self.assertListEqual(batch_out_sentence, [out1_sentence, out2_sentence]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_tokenization_gptsan_japanese.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_tokenization_gptsan_japanese.py new file mode 100644 index 0000000000000000000000000000000000000000..4352f6425f0d328b5f9b0bd53cd5be11054a5beb --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/gptsan_japanese/test_tokenization_gptsan_japanese.py @@ -0,0 +1,195 @@ +# coding=utf-8 +# Copyright 2023 Toshiyuki Sakamoto(tanreinama) and HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers.models.gptsan_japanese.tokenization_gptsan_japanese import ( + VOCAB_FILES_NAMES, + GPTSanJapaneseTokenizer, +) +from transformers.testing_utils import require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class GPTSanJapaneseTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = GPTSanJapaneseTokenizer + test_rust_tokenizer = False + from_pretrained_kwargs = {"do_clean_text": False, "add_prefix_space": False} + + def setUp(self): + super().setUp() + + # fmt: off + vocab_tokens = ["こん", "こんに", "にちは", "ばんは", "世界,㔺界", "、", "。", "
", "", "", "", "", "", "", "", "", "", "", "<|emoji1|>", "", "<|bagoftoken|>", "<|endoftext|>"] + # fmt: on + emoji_tokens = {"emoji": {"\ud83d\ude00": "<|emoji1|>"}, "emoji_inv": {"<|emoji1|>": "\ud83d\ude00"}} # 😀 + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.emoji_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["emoji_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + with open(self.emoji_file, "w") as emoji_writer: + emoji_writer.write(json.dumps(emoji_tokens)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return GPTSanJapaneseTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.get_input_output_texts + def get_input_output_texts(self, tokenizer): + input_text = "こんにちは、世界。 \nこんばんは、㔺界。😀" + output_text = "こんにちは、世界。 \nこんばんは、世界。😀" + return input_text, output_text + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.get_clean_sequence + def get_clean_sequence(self, tokenizer): + input_text, output_text = self.get_input_output_texts(tokenizer) + ids = tokenizer.encode(output_text, add_special_tokens=False) + text = tokenizer.decode(ids, clean_up_tokenization_spaces=False) + return text, ids + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_pretokenized_inputs + def test_pretokenized_inputs(self): + pass # TODO add if relevant + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_maximum_encoding_length_pair_input + def test_maximum_encoding_length_pair_input(self): + pass # TODO add if relevant + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_maximum_encoding_length_single_input + def test_maximum_encoding_length_single_input(self): + pass # TODO add if relevant + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_full_tokenizer + def test_full_tokenizer(self): + tokenizer = self.get_tokenizer() + + # Testing tokenization + input_text = "こんにちは、世界。 こんばんは、㔺界。" + expected_token = ["こん", "にちは", "、", "世界", "。", "", "こん", "ばんは", "、", "㔺界", "。"] + tokens = tokenizer.tokenize(input_text) + self.assertListEqual(tokens, expected_token) + + # Testing conversion to ids without special tokens + expected_ids = [0, 2, 5, 4, 6, 8, 0, 3, 5, 4, 6] + input_ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual(input_ids, expected_ids) + + # Testing conversion to ids with special tokens + input_tokens = tokens + [tokenizer.unk_token] + expected_ids = [0, 2, 5, 4, 6, 8, 0, 3, 5, 4, 6, 19] + input_ids = tokenizer.convert_tokens_to_ids(input_tokens) + self.assertListEqual(input_ids, expected_ids) + + def test_token_bagging(self): + tokenizer = self.get_tokenizer() + + # Testing tokenization + input_text = "こんにちは、<|bagoftoken|>世界。こんばんは、<|bagoftoken|>㔺界。" + expected_text = "こんにちは、、、、世界。こんばんは、、、、世界。" + tokens = tokenizer.encode(input_text) + output_text = tokenizer.decode(tokens) + self.assertEqual(output_text, expected_text) + + @slow + def test_prefix_input(self): + tokenizer = self.tokenizer_class.from_pretrained("Tanrei/GPTSAN-japanese") + + # Testing tokenization + prefix_text = "こんにちは、世界。" + input_text = "こんばんは、㔺界。😀" + expected_text = "こんにちは、世界。こんばんは、世界。😀" + tokens_1 = tokenizer.encode(prefix_text + input_text) + tokens_2 = tokenizer.encode("", prefix_text=prefix_text + input_text) + tokens_3 = tokenizer.encode(input_text, prefix_text=prefix_text) + output_text_1 = tokenizer.decode(tokens_1) + output_text_2 = tokenizer.decode(tokens_2) + output_text_3 = tokenizer.decode(tokens_3) + self.assertEqual(output_text_1, expected_text) + self.assertEqual(output_text_2, expected_text) + self.assertEqual(output_text_3, expected_text) + + @slow + def test_token_type_ids(self): + tokenizer = self.tokenizer_class.from_pretrained("Tanrei/GPTSAN-japanese") + + # Testing tokenization + prefix_text = "こんにちは、世界。" + input_text = "こんばんは、㔺界。😀" + + len_prefix = len(tokenizer.encode(prefix_text)) - 2 + len_text = len(tokenizer.encode(input_text)) - 2 + + expected_mask_1 = [1] + [0] * (len_prefix + len_text + 1) + expected_mask_2 = [1] * (len_prefix + len_text + 1) + [0] + expected_mask_3 = [1] + [1] * (len_prefix) + [0] * (len_text + 1) + + type_id_1 = tokenizer(prefix_text + input_text).token_type_ids + type_id_2 = tokenizer("", prefix_text=prefix_text + input_text).token_type_ids + type_id_3 = tokenizer(input_text, prefix_text=prefix_text).token_type_ids + self.assertListEqual(type_id_1, expected_mask_1) + self.assertListEqual(type_id_2, expected_mask_2) + self.assertListEqual(type_id_3, expected_mask_3) + + @slow + def test_prefix_tokens(self): + tokenizer = self.tokenizer_class.from_pretrained("Tanrei/GPTSAN-japanese") + + x_token_1 = tokenizer.encode("あンいワ") + x_token_2 = tokenizer.encode("", prefix_text="あンいワ") + x_token_3 = tokenizer.encode("いワ", prefix_text="あン") + + self.assertEqual(tokenizer.decode(x_token_1), tokenizer.decode(x_token_2)) + self.assertEqual(tokenizer.decode(x_token_1), tokenizer.decode(x_token_3)) + self.assertNotEqual(x_token_1, x_token_2) + self.assertNotEqual(x_token_1, x_token_3) + self.assertEqual(x_token_1[1], x_token_2[-1]) # SEG token + self.assertEqual(x_token_1[1], x_token_3[3]) # SEG token + + @slow + def test_batch_encode(self): + tokenizer = self.tokenizer_class.from_pretrained("Tanrei/GPTSAN-japanese") + + input_pairs = [["武田信玄", "は、"], ["織田信長", "の配下の、"]] + x_token = tokenizer(input_pairs, padding=True) + x_token_2 = tokenizer.batch_encode_plus(input_pairs, padding=True) + + # fmt: off + expected_outputs = [[35993, 8640, 25948, 35998, 30647, 35675, 35999, 35999], [35993, 10382, 9868, 35998, 30646, 9459, 30646, 35675]] + expected_typeids = [[1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 0, 0]] + expected_attmask = [[1, 1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1]] + # fmt: on + self.assertListEqual(x_token.input_ids, expected_outputs) + self.assertListEqual(x_token.token_type_ids, expected_typeids) + self.assertListEqual(x_token.attention_mask, expected_attmask) + self.assertListEqual(x_token_2.input_ids, expected_outputs) + self.assertListEqual(x_token_2.token_type_ids, expected_typeids) + self.assertListEqual(x_token_2.attention_mask, expected_attmask) + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_conversion_reversible + def test_conversion_reversible(self): + # Intentionally convert some words to accommodate character fluctuations unique to Japanese + pass + + # Copied from tests.models.gpt_neox_japanese.test_tokenization_gpt_neox_japanese.GPTNeoXJapaneseTokenizationTest.test_padding_different_model_input_name + def test_padding_different_model_input_name(self): + # tokenizer has no padding token + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/graphormer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/graphormer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/graphormer/test_modeling_graphormer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/graphormer/test_modeling_graphormer.py new file mode 100644 index 0000000000000000000000000000000000000000..e874ebf0f44a2b92ca7c0ea26c4d104354ef6ac0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/graphormer/test_modeling_graphormer.py @@ -0,0 +1,1291 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Graphormer model. """ + + +import copy +import inspect +import os +import tempfile +import unittest + +from transformers import GraphormerConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import tensor + + from transformers import GraphormerForGraphClassification, GraphormerModel + from transformers.models.graphormer.modeling_graphormer import GRAPHORMER_PRETRAINED_MODEL_ARCHIVE_LIST + + +class GraphormerModelTester: + def __init__( + self, + parent, + num_classes=1, + num_atoms=512 * 9, + num_edges=512 * 3, + num_in_degree=512, + num_out_degree=512, + num_spatial=512, + num_edge_dis=128, + multi_hop_max_dist=5, # sometimes is 20 + spatial_pos_max=1024, + edge_type="multi_hop", + init_fn=None, + max_nodes=512, + share_input_output_embed=False, + num_hidden_layers=12, + embedding_dim=768, + ffn_embedding_dim=768, + num_attention_heads=32, + dropout=0.1, + attention_dropout=0.1, + activation_dropout=0.1, + layerdrop=0.0, + encoder_normalize_before=False, + pre_layernorm=False, + apply_graphormer_init=False, + activation_fn="gelu", + embed_scale=None, + freeze_embeddings=False, + num_trans_layers_to_freeze=0, + traceable=False, + q_noise=0.0, + qn_block_size=8, + kdim=None, + vdim=None, + bias=True, + self_attention=True, + batch_size=10, + graph_size=20, + is_training=True, + ): + self.parent = parent + self.num_classes = num_classes + self.num_labels = num_classes + self.num_atoms = num_atoms + self.num_in_degree = num_in_degree + self.num_out_degree = num_out_degree + self.num_edges = num_edges + self.num_spatial = num_spatial + self.num_edge_dis = num_edge_dis + self.edge_type = edge_type + self.multi_hop_max_dist = multi_hop_max_dist + self.spatial_pos_max = spatial_pos_max + self.max_nodes = max_nodes + self.num_hidden_layers = num_hidden_layers + self.embedding_dim = embedding_dim + self.hidden_size = embedding_dim + self.ffn_embedding_dim = ffn_embedding_dim + self.num_attention_heads = num_attention_heads + self.dropout = dropout + self.attention_dropout = attention_dropout + self.activation_dropout = activation_dropout + self.layerdrop = layerdrop + self.encoder_normalize_before = encoder_normalize_before + self.pre_layernorm = pre_layernorm + self.apply_graphormer_init = apply_graphormer_init + self.activation_fn = activation_fn + self.embed_scale = embed_scale + self.freeze_embeddings = freeze_embeddings + self.num_trans_layers_to_freeze = num_trans_layers_to_freeze + self.share_input_output_embed = share_input_output_embed + self.traceable = traceable + self.q_noise = q_noise + self.qn_block_size = qn_block_size + self.init_fn = init_fn + self.kdim = kdim + self.vdim = vdim + self.self_attention = self_attention + self.bias = bias + self.batch_size = batch_size + self.graph_size = graph_size + self.is_training = is_training + + def prepare_config_and_inputs(self): + attn_bias = ids_tensor( + [self.batch_size, self.graph_size + 1, self.graph_size + 1], self.num_atoms + ) # Def not sure here + attn_edge_type = ids_tensor([self.batch_size, self.graph_size, self.graph_size, 1], self.num_edges) + spatial_pos = ids_tensor([self.batch_size, self.graph_size, self.graph_size], self.num_spatial) + in_degree = ids_tensor([self.batch_size, self.graph_size], self.num_in_degree) + out_degree = ids_tensor([self.batch_size, self.graph_size], self.num_out_degree) + input_nodes = ids_tensor([self.batch_size, self.graph_size, 1], self.num_atoms) + input_edges = ids_tensor( + [self.batch_size, self.graph_size, self.graph_size, self.multi_hop_max_dist, 1], self.num_edges + ) + labels = ids_tensor([self.batch_size], self.num_classes) + + config = self.get_config() + + return config, attn_bias, attn_edge_type, spatial_pos, in_degree, out_degree, input_nodes, input_edges, labels + + def get_config(self): + return GraphormerConfig( + num_atoms=self.num_atoms, + num_in_degree=self.num_in_degree, + num_out_degree=self.num_out_degree, + num_edges=self.num_edges, + num_spatial=self.num_spatial, + num_edge_dis=self.num_edge_dis, + edge_type=self.edge_type, + multi_hop_max_dist=self.multi_hop_max_dist, + spatial_pos_max=self.spatial_pos_max, + max_nodes=self.max_nodes, + num_hidden_layers=self.num_hidden_layers, + embedding_dim=self.embedding_dim, + hidden_size=self.embedding_dim, + ffn_embedding_dim=self.ffn_embedding_dim, + num_attention_heads=self.num_attention_heads, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + activation_dropout=self.activation_dropout, + layerdrop=self.layerdrop, + encoder_normalize_before=self.encoder_normalize_before, + pre_layernorm=self.pre_layernorm, + apply_graphormer_init=self.apply_graphormer_init, + activation_fn=self.activation_fn, + embed_scale=self.embed_scale, + freeze_embeddings=self.freeze_embeddings, + num_trans_layers_to_freeze=self.num_trans_layers_to_freeze, + share_input_output_embed=self.share_input_output_embed, + traceable=self.traceable, + q_noise=self.q_noise, + qn_block_size=self.qn_block_size, + init_fn=self.init_fn, + kdim=self.kdim, + vdim=self.vdim, + self_attention=self.self_attention, + bias=self.bias, + ) + + def create_and_check_model( + self, config, attn_bias, attn_edge_type, spatial_pos, in_degree, out_degree, input_nodes, input_edges, labels + ): + model = GraphormerModel(config=config) + model.to(torch_device) + model.eval() + result = model( + input_nodes=input_nodes, + attn_bias=attn_bias, + in_degree=in_degree, + out_degree=out_degree, + spatial_pos=spatial_pos, + input_edges=input_edges, + attn_edge_type=attn_edge_type, + labels=labels, + ) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.graph_size + 1, self.hidden_size) + ) + + def create_and_check_for_graph_classification( + self, config, attn_bias, attn_edge_type, spatial_pos, in_degree, out_degree, input_nodes, input_edges, labels + ): + model = GraphormerForGraphClassification(config) + model.to(torch_device) + model.eval() + result = model( + input_nodes=input_nodes, + attn_bias=attn_bias, + in_degree=in_degree, + out_degree=out_degree, + spatial_pos=spatial_pos, + input_edges=input_edges, + attn_edge_type=attn_edge_type, + labels=labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + attn_bias, + attn_edge_type, + spatial_pos, + in_degree, + out_degree, + input_nodes, + input_edges, + labels, + ) = config_and_inputs + inputs_dict = { + "attn_bias": attn_bias, + "attn_edge_type": attn_edge_type, + "spatial_pos": spatial_pos, + "in_degree": in_degree, + "out_degree": out_degree, + "input_nodes": input_nodes, + "input_edges": input_edges, + "labels": labels, + } + return config, inputs_dict + + +@require_torch +class GraphormerModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GraphormerForGraphClassification, GraphormerModel) if is_torch_available() else () + all_generative_model_classes = () + pipeline_model_mapping = {"feature-extraction": GraphormerModel} if is_torch_available() else {} + test_pruning = False + test_head_masking = False + test_resize_embeddings = False + main_input_name_nodes = "input_nodes" + main_input_name_edges = "input_edges" + has_attentions = False # does not output attention + + def setUp(self): + self.model_tester = GraphormerModelTester(self) + self.config_tester = ConfigTester(self, config_class=GraphormerConfig, has_text_modality=False) + + # overwrite from common as `Graphormer` requires more input arguments + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + inputs = self._prepare_for_class(inputs_dict, model_class) + + try: + required_keys = ( + "input_nodes", + "input_edges", + "attn_bias", + "in_degree", + "out_degree", + "spatial_pos", + "attn_edge_type", + ) + required_inputs = tuple(inputs[k] for k in required_keys) + model(*required_inputs) + traced_model = torch.jit.trace(model, required_inputs) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + non_persistent_buffers = {} + for key in loaded_model_state_dict.keys(): + if key not in model_state_dict.keys(): + non_persistent_buffers[key] = loaded_model_state_dict[key] + + loaded_model_state_dict = { + key: value for key, value in loaded_model_state_dict.items() if key not in non_persistent_buffers + } + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + model_buffers = list(model.buffers()) + for non_persistent_buffer in non_persistent_buffers.values(): + found_buffer = False + for i, model_buffer in enumerate(model_buffers): + if torch.equal(non_persistent_buffer, model_buffer): + found_buffer = True + break + + self.assertTrue(found_buffer) + model_buffers.pop(i) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + if layer_name in loaded_model_state_dict: + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + # Avoid memory leak. Without this, each call increase RAM usage by ~20MB. + # (Even with this call, there are still memory leak by ~0.04MB) + self.clear_torch_jit_class_registry() + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="Graphormer does not use one single inputs_embedding but three") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Graphormer does not implement feed forward chunking") + def test_feed_forward_chunking(self): + pass + + @unittest.skip(reason="Graphormer does not share input and output embeddings") + def test_model_common_attributes(self): + pass + + def test_initialization(self): + def _config_zero_init(config): + configs_no_init = copy.deepcopy(config) + for key in configs_no_init.__dict__.keys(): + if "_range" in key or "_std" in key or "initializer_factor" in key or "layer_scale" in key: + setattr(configs_no_init, key, 1e-10) + return configs_no_init + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + self.assertTrue( + -1.0 <= ((param.data.mean() * 1e9).round() / 1e9).item() <= 1.0, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + batch_size = self.model_tester.batch_size + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [batch_size, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + # Always returns hidden_states + check_hidden_states_output(inputs_dict, config, model_class) + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = False + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + outputs = model(**inputs_dict) + output = outputs[0] + + hidden_states = outputs.hidden_states[0] + hidden_states.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + + # Inputs are 'input_nodes' and 'input_edges' not 'input_ids' + def test_model_main_input_name(self): + for model_class in self.all_model_classes: + model_signature = inspect.signature(getattr(model_class, "forward")) + # The main input is the name of the argument after `self` + observed_main_input_name_nodes = list(model_signature.parameters.keys())[1] + observed_main_input_name_edges = list(model_signature.parameters.keys())[2] + self.assertEqual(model_class.main_input_name_nodes, observed_main_input_name_nodes) + self.assertEqual(model_class.main_input_name_edges, observed_main_input_name_edges) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_nodes", "input_edges"] + self.assertListEqual(arg_names[:2], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_graph_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_graph_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in GRAPHORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GraphormerForGraphClassification.from_pretrained(model_name) + self.assertIsNotNone(model) + + +@require_torch +class GraphormerModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_graph_classification(self): + model = GraphormerForGraphClassification.from_pretrained("clefourrier/graphormer-base-pcqm4mv2") + + # Actual real graph data from the MUTAG dataset + # fmt: off + model_input = { + "attn_bias": tensor( + [ + [ + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + ], + [ + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, float("-inf"), float("-inf"), float("-inf"), float("-inf")], + ], + ] + ), + "attn_edge_type": tensor( + [ + [ + [[0], [3], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [3], [0], [3], [0], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [3], [0], [3], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[3], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [3], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [3], [0], [0], [0]], + [[0], [0], [0], [3], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [3], [3], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [0], [3], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [3], [3]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0]], + ], + [ + [[0], [3], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0]], + [[3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [3], [0], [3], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [3], [0], [0], [0], [3], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [3], [0], [3], [3], [0], [0], [0], [0], [0], [0]], + [[3], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [3], [3], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [3], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], [0]], + ], + ] + ), + # fmt: on + "spatial_pos": tensor( + [ + [ + [1, 2, 3, 4, 3, 2, 4, 5, 6, 5, 6, 7, 8, 7, 9, 10, 10], + [2, 1, 2, 3, 4, 3, 5, 6, 5, 4, 5, 6, 7, 6, 8, 9, 9], + [3, 2, 1, 2, 3, 4, 4, 5, 4, 3, 4, 5, 6, 5, 7, 8, 8], + [4, 3, 2, 1, 2, 3, 3, 4, 3, 2, 3, 4, 5, 4, 6, 7, 7], + [3, 4, 3, 2, 1, 2, 2, 3, 4, 3, 4, 5, 6, 5, 7, 8, 8], + [2, 3, 4, 3, 2, 1, 3, 4, 5, 4, 5, 6, 7, 6, 8, 9, 9], + [4, 5, 4, 3, 2, 3, 1, 2, 3, 4, 5, 6, 5, 4, 6, 7, 7], + [5, 6, 5, 4, 3, 4, 2, 1, 2, 3, 4, 5, 4, 3, 5, 6, 6], + [6, 5, 4, 3, 4, 5, 3, 2, 1, 2, 3, 4, 3, 2, 4, 5, 5], + [5, 4, 3, 2, 3, 4, 4, 3, 2, 1, 2, 3, 4, 3, 5, 6, 6], + [6, 5, 4, 3, 4, 5, 5, 4, 3, 2, 1, 2, 3, 4, 4, 5, 5], + [7, 6, 5, 4, 5, 6, 6, 5, 4, 3, 2, 1, 2, 3, 3, 4, 4], + [8, 7, 6, 5, 6, 7, 5, 4, 3, 4, 3, 2, 1, 2, 2, 3, 3], + [7, 6, 5, 4, 5, 6, 4, 3, 2, 3, 4, 3, 2, 1, 3, 4, 4], + [9, 8, 7, 6, 7, 8, 6, 5, 4, 5, 4, 3, 2, 3, 1, 2, 2], + [10, 9, 8, 7, 8, 9, 7, 6, 5, 6, 5, 4, 3, 4, 2, 1, 3], + [10, 9, 8, 7, 8, 9, 7, 6, 5, 6, 5, 4, 3, 4, 2, 3, 1], + ], + [ + [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 4, 5, 5, 0, 0, 0, 0], + [2, 1, 2, 3, 4, 5, 4, 3, 4, 3, 5, 6, 6, 0, 0, 0, 0], + [3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 4, 5, 5, 0, 0, 0, 0], + [4, 3, 2, 1, 2, 3, 4, 3, 4, 5, 5, 6, 6, 0, 0, 0, 0], + [5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 6, 7, 7, 0, 0, 0, 0], + [6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 5, 6, 6, 0, 0, 0, 0], + [5, 4, 3, 4, 3, 2, 1, 2, 3, 4, 4, 5, 5, 0, 0, 0, 0], + [4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 3, 4, 4, 0, 0, 0, 0], + [3, 4, 3, 4, 5, 4, 3, 2, 1, 2, 2, 3, 3, 0, 0, 0, 0], + [2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 3, 4, 4, 0, 0, 0, 0], + [4, 5, 4, 5, 6, 5, 4, 3, 2, 3, 1, 2, 2, 0, 0, 0, 0], + [5, 6, 5, 6, 7, 6, 5, 4, 3, 4, 2, 1, 3, 0, 0, 0, 0], + [5, 6, 5, 6, 7, 6, 5, 4, 3, 4, 2, 3, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ], + ] + ), + "in_degree": tensor( + [ + [3, 3, 3, 4, 4, 3, 3, 3, 4, 4, 3, 3, 4, 3, 4, 2, 2], + [3, 3, 4, 3, 3, 3, 3, 4, 4, 3, 4, 2, 2, 0, 0, 0, 0], + ] + ), + "out_degree": tensor( + [ + [3, 3, 3, 4, 4, 3, 3, 3, 4, 4, 3, 3, 4, 3, 4, 2, 2], + [3, 3, 4, 3, 3, 3, 3, 4, 4, 3, 4, 2, 2, 0, 0, 0, 0], + ] + ), + "input_nodes": tensor( + [ + [[3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3]], + [[3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [3], [0], [0], [0], [0]], + ] + ), + "input_edges": tensor( + [ + [ + [ + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + ], + [ + [ + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [4]], + [[4], [4], [4], [4], [0]], + [[4], [4], [4], [0], [0]], + [[4], [4], [0], [0], [0]], + [[4], [4], [4], [0], [0]], + [[4], [0], [0], [0], [0]], + [[4], [4], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + [ + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + [[0], [0], [0], [0], [0]], + ], + ], + ] + ), + "labels": tensor([1, 0]), + } + + output = model(**model_input)["logits"] + + expected_shape = torch.Size((2, 1)) + self.assertEqual(output.shape, expected_shape) + + expected_logs = torch.tensor( + [[7.6060], [7.4126]] + ) + + self.assertTrue(torch.allclose(output, expected_logs, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_groupvit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_groupvit.py new file mode 100644 index 0000000000000000000000000000000000000000..f87cec426b0a565d6b507f45e218630e16ce8f9b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_groupvit.py @@ -0,0 +1,702 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch GroupViT model. """ + + +import inspect +import os +import random +import tempfile +import unittest + +import numpy as np +import requests + +from transformers import GroupViTConfig, GroupViTTextConfig, GroupViTVisionConfig +from transformers.testing_utils import is_pt_tf_cross_test, require_torch, require_vision, slow, torch_device +from transformers.utils import is_torch_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import GroupViTModel, GroupViTTextModel, GroupViTVisionModel + from transformers.models.groupvit.modeling_groupvit import GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import CLIPProcessor + + +class GroupViTVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + depths=[6, 3, 3], + num_group_tokens=[64, 8, 0], + num_output_groups=[64, 8, 8], + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.depths = depths + self.num_hidden_layers = sum(depths) + self.expected_num_hidden_layers = len(depths) + 1 + self.num_group_tokens = num_group_tokens + self.num_output_groups = num_output_groups + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + num_patches = (image_size // patch_size) ** 2 + # no [CLS] token for GroupViT + self.seq_length = num_patches + + def prepare_config_and_inputs(self): + rng = random.Random(0) + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size], rng=rng) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return GroupViTVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + depths=self.depths, + num_group_tokens=self.num_group_tokens, + num_output_groups=self.num_output_groups, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = GroupViTVisionModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(pixel_values) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.num_output_groups[-1], self.hidden_size) + ) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class GroupViTVisionModelTest(ModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as GROUPVIT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (GroupViTVisionModel,) if is_torch_available() else () + + test_pruning = False + test_torchscript = False + test_resize_embeddings = False + test_head_masking = False + + def setUp(self): + self.model_tester = GroupViTVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=GroupViTVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="GroupViT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self): + import tensorflow as tf + + seed = 338 + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + tf.random.set_seed(seed) + return super().test_pt_tf_model_equivalence() + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Module)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + + expected_num_attention_outputs = sum(g > 0 for g in self.model_tester.num_group_tokens) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + # GroupViT returns attention grouping of each stage + self.assertEqual(len(attentions), sum(g > 0 for g in self.model_tester.num_group_tokens)) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + # GroupViT returns attention grouping of each stage + self.assertEqual(len(attentions), expected_num_attention_outputs) + + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + # GroupViT returns attention grouping of each stage + self.assertEqual(len(self_attentions), expected_num_attention_outputs) + for i, self_attn in enumerate(self_attentions): + if self_attn is None: + continue + + self.assertListEqual( + list(self_attentions[i].shape[-2:]), + [ + self.model_tester.num_output_groups[i], + self.model_tester.num_output_groups[i - 1] if i > 0 else seq_len, + ], + ) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="GroupViTVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="GroupViTVisionModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + # override since the attention mask from GroupViT is not used to compute loss, thus no grad + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + if config.is_encoder_decoder: + # Seq2Seq models + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_hidden_states.retain_grad() + + decoder_hidden_states = outputs.decoder_hidden_states[0] + decoder_hidden_states.retain_grad() + + if self.has_attentions: + encoder_attentions = outputs.encoder_attentions[0] + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(decoder_hidden_states.grad) + + if self.has_attentions: + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + else: + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0] + hidden_states.retain_grad() + + if self.has_attentions: + attentions = outputs.attentions[0] + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + + if self.has_attentions: + self.assertIsNone(attentions.grad) + + @slow + def test_model_from_pretrained(self): + for model_name in GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GroupViTVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class GroupViTTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + rng = random.Random(0) + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size, rng=rng) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + if input_mask is not None: + batch_size, seq_length = input_mask.shape + rnd_start_indices = np.random.randint(1, seq_length - 1, size=(batch_size,)) + for batch_idx, start_index in enumerate(rnd_start_indices): + input_mask[batch_idx, :start_index] = 1 + input_mask[batch_idx, start_index:] = 0 + + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return GroupViTTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask): + model = GroupViTTextModel(config=config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class GroupViTTextModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (GroupViTTextModel,) if is_torch_available() else () + test_pruning = False + test_head_masking = False + + def setUp(self): + self.model_tester = GroupViTTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=GroupViTTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_training(self): + pass + + def test_training_gradient_checkpointing(self): + pass + + @unittest.skip(reason="GroupViTTextModel does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="GroupViTTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_from_base(self): + pass + + @unittest.skip(reason="GroupViTTextModel has no base class and is not available in MODEL_MAPPING") + def test_save_load_fast_init_to_base(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GroupViTTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +class GroupViTModelTester: + def __init__(self, parent, text_kwargs=None, vision_kwargs=None, is_training=True): + if text_kwargs is None: + text_kwargs = {} + if vision_kwargs is None: + vision_kwargs = {} + + self.parent = parent + self.text_model_tester = GroupViTTextModelTester(parent, **text_kwargs) + self.vision_model_tester = GroupViTVisionModelTester(parent, **vision_kwargs) + self.is_training = is_training + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, attention_mask, pixel_values + + def get_config(self): + return GroupViTConfig.from_text_vision_configs( + self.text_model_tester.get_config(), self.vision_model_tester.get_config(), projection_dim=64 + ) + + def create_and_check_model(self, config, input_ids, attention_mask, pixel_values): + model = GroupViTModel(config).to(torch_device).eval() + with torch.no_grad(): + result = model(input_ids, pixel_values, attention_mask) + self.parent.assertEqual( + result.logits_per_image.shape, (self.vision_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "return_loss": True, + } + return config, inputs_dict + + +@require_torch +class GroupViTModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (GroupViTModel,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": GroupViTModel} if is_torch_available() else {} + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + + def setUp(self): + self.model_tester = GroupViTModelTester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="hidden_states are tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="input_embeds are tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="tested in individual model tests") + def test_retain_grad_hidden_states_attentions(self): + pass + + @unittest.skip(reason="GroupViTModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self): + import tensorflow as tf + + seed = 163 + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + tf.random.set_seed(seed) + return super().test_pt_tf_model_equivalence() + + # override as the `logit_scale` parameter initilization is different for GROUPVIT + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + # check if `logit_scale` is initilized as per the original implementation + if name == "logit_scale": + self.assertAlmostEqual( + param.data.item(), + np.log(1 / 0.07), + delta=1e-3, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + configs_no_init.return_dict = False + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + try: + input_ids = inputs_dict["input_ids"] + pixel_values = inputs_dict["pixel_values"] # GROUPVIT needs pixel_values + traced_model = torch.jit.trace(model, (input_ids, pixel_values)) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_load_vision_text_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Save GroupViTConfig and check if we can load GroupViTVisionConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + vision_config = GroupViTVisionConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.vision_config.to_dict(), vision_config.to_dict()) + + # Save GroupViTConfig and check if we can load GroupViTTextConfig from it + with tempfile.TemporaryDirectory() as tmp_dir_name: + config.save_pretrained(tmp_dir_name) + text_config = GroupViTTextConfig.from_pretrained(tmp_dir_name) + self.assertDictEqual(config.text_config.to_dict(), text_config.to_dict()) + + @slow + def test_model_from_pretrained(self): + for model_name in GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = GroupViTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@require_vision +@require_torch +class GroupViTModelIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "nvidia/groupvit-gcc-yfcc" + model = GroupViTModel.from_pretrained(model_name) + processor = CLIPProcessor.from_pretrained(model_name) + + image = prepare_img() + inputs = processor( + text=["a photo of a cat", "a photo of a dog"], images=image, padding=True, return_tensors="pt" + ) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + self.assertEqual( + outputs.logits_per_image.shape, + torch.Size((inputs.pixel_values.shape[0], inputs.input_ids.shape[0])), + ) + self.assertEqual( + outputs.logits_per_text.shape, + torch.Size((inputs.input_ids.shape[0], inputs.pixel_values.shape[0])), + ) + + expected_logits = torch.tensor([[13.3523, 6.3629]]) + + self.assertTrue(torch.allclose(outputs.logits_per_image, expected_logits, atol=1e-3)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_tf_groupvit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_tf_groupvit.py new file mode 100644 index 0000000000000000000000000000000000000000..bd499a50fb6cc412c3c94407a940aa7de25aa8f1 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/groupvit/test_modeling_tf_groupvit.py @@ -0,0 +1,739 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the TensorFlow GroupViT model. """ + + +import inspect +import os +import random +import tempfile +import unittest +from importlib import import_module + +import numpy as np +import requests + +from transformers import GroupViTConfig, GroupViTTextConfig, GroupViTVisionConfig +from transformers.testing_utils import ( + is_pt_tf_cross_test, + require_tensorflow_probability, + require_tf, + require_vision, + slow, +) +from transformers.utils import is_tf_available, is_vision_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import TFGroupViTModel, TFGroupViTTextModel, TFGroupViTVisionModel, TFSharedEmbeddings + from transformers.models.groupvit.modeling_tf_groupvit import TF_GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import CLIPProcessor + + +class TFGroupViTVisionModelTester: + def __init__( + self, + parent, + batch_size=12, + image_size=30, + patch_size=2, + num_channels=3, + is_training=True, + hidden_size=32, + depths=[6, 3, 3], + num_group_tokens=[64, 8, 0], + num_output_groups=[64, 8, 8], + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.patch_size = patch_size + self.num_channels = num_channels + self.is_training = is_training + self.hidden_size = hidden_size + self.depths = depths + self.num_hidden_layers = sum(depths) + self.expected_num_hidden_layers = len(depths) + 1 + self.num_group_tokens = num_group_tokens + self.num_output_groups = num_output_groups + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.initializer_range = initializer_range + self.scope = scope + + num_patches = (image_size // patch_size) ** 2 + # no [CLS] token for GroupViT + self.seq_length = num_patches + + def prepare_config_and_inputs(self): + rng = random.Random(0) + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size], rng=rng) + config = self.get_config() + + return config, pixel_values + + def get_config(self): + return GroupViTVisionConfig( + image_size=self.image_size, + patch_size=self.patch_size, + num_channels=self.num_channels, + hidden_size=self.hidden_size, + depths=self.depths, + num_group_tokens=self.num_group_tokens, + num_output_groups=self.num_output_groups, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, pixel_values): + model = TFGroupViTVisionModel(config=config) + result = model(pixel_values, training=False) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.num_output_groups[-1], self.hidden_size) + ) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_tf +class TFGroupViTVisionModelTest(TFModelTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as GroupViT does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = (TFGroupViTVisionModel,) if is_tf_available() else () + + test_pruning = False + test_resize_embeddings = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFGroupViTVisionModelTester(self) + self.config_tester = ConfigTester( + self, config_class=GroupViTVisionConfig, has_text_modality=False, hidden_size=37 + ) + + def test_config(self): + self.config_tester.run_common_tests() + + @unittest.skip(reason="GroupViT does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + """ + During saving, TensorFlow will also run with `training=True` which trigger `gumbel_softmax` that requires + `tensorflow-probability`. + """ + + @require_tensorflow_probability + @slow + def test_saved_model_creation(self): + super().test_saved_model_creation() + + @unittest.skip(reason="GroupViT does not use inputs_embeds") + def test_graph_mode_with_inputs_embeds(self): + pass + + def test_model_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (tf.keras.layers.Layer)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, tf.keras.layers.Layer)) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + + expected_num_attention_outputs = sum(g > 0 for g in self.model_tester.num_group_tokens) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + attentions = outputs.attentions + # GroupViT returns attention grouping of each stage + self.assertEqual(len(attentions), sum(g > 0 for g in self.model_tester.num_group_tokens)) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + attentions = outputs.attentions + # GroupViT returns attention grouping of each stage + self.assertEqual(len(attentions), expected_num_attention_outputs) + + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + # GroupViT returns attention grouping of each stage + self.assertEqual(len(self_attentions), expected_num_attention_outputs) + for i, self_attn in enumerate(self_attentions): + if self_attn is None: + continue + + self.assertListEqual( + list(self_attentions[i].shape[-2:]), + [ + self.model_tester.num_output_groups[i], + self.model_tester.num_output_groups[i - 1] if i > 0 else seq_len, + ], + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + + outputs = model(**self._prepare_for_class(inputs_dict, model_class), training=False) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + seq_length = getattr(self.model_tester, "seq_length", None) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self): + # `GroupViT` computes some indices using argmax, uses them as + # one-hot encoding for further computation. The problem is + # while PT/TF have very small difference in `y_soft` (~ 1e-9), + # the argmax could be totally different, if there are at least + # 2 indices with almost identical values. This leads to very + # large difference in the outputs. We need specific seeds to + # avoid almost identical values happening in `y_soft`. + import torch + + seed = 338 + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + tf.random.set_seed(seed) + return super().test_pt_tf_model_equivalence() + + @slow + def test_model_from_pretrained(self): + for model_name in TF_GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFGroupViTVisionModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @unittest.skip( + "TFGroupViTVisionModel does not convert `hidden_states` and `attentions` to tensors as they are all of" + " different dimensions, and we get `Got a non-Tensor value` error when saving the model." + ) + @slow + def test_saved_model_creation_extended(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + if hasattr(config, "use_cache"): + config.use_cache = True + + seq_len = getattr(self.model_tester, "seq_length", None) + + for model_class in self.all_model_classes: + class_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + num_out = len(model(class_inputs_dict)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=True) + saved_model_dir = os.path.join(tmpdirname, "saved_model", "1") + model = tf.keras.models.load_model(saved_model_dir) + outputs = model(class_inputs_dict) + output_hidden_states = outputs["hidden_states"] + output_attentions = outputs["attentions"] + + # Check num outputs + self.assertEqual(len(outputs), num_out) + + # Check num layers + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + self.assertEqual(len(output_hidden_states), expected_num_layers) + self.assertEqual(len(output_attentions), self.model_tester.num_hidden_layers) + + # Check attention outputs + image_size = (self.model_tester.image_size, self.model_tester.image_size) + patch_size = (self.model_tester.patch_size, self.model_tester.patch_size) + num_patches = (image_size[1] // patch_size[1]) * (image_size[0] // patch_size[0]) + seq_len = num_patches + 1 + + self.assertListEqual( + list(output_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_len, seq_len], + ) + + # Check hidden states + self.assertListEqual( + list(output_hidden_states[0].shape[-2:]), + [seq_len, self.model_tester.hidden_size], + ) + + +class TFGroupViTTextModelTester: + def __init__( + self, + parent, + batch_size=12, + seq_length=7, + is_training=True, + use_input_mask=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + dropout=0.1, + attention_dropout=0.1, + max_position_embeddings=512, + initializer_range=0.02, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.dropout = dropout + self.attention_dropout = attention_dropout + self.max_position_embeddings = max_position_embeddings + self.initializer_range = initializer_range + self.scope = scope + + def prepare_config_and_inputs(self): + rng = random.Random(0) + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size, rng=rng) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + # make sure the first token has attention mask `1` to ensure that, after combining the causal mask, there + # is still at least one token being attended to for each batch. + # TODO: Change `random_attention_mask` in PT/TF/Flax common test file, after a discussion with the team. + input_mask = tf.concat( + [tf.ones_like(input_mask[:, :1], dtype=input_mask.dtype), input_mask[:, 1:]], axis=-1 + ) + + config = self.get_config() + + return config, input_ids, input_mask + + def get_config(self): + return GroupViTTextConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + dropout=self.dropout, + attention_dropout=self.attention_dropout, + max_position_embeddings=self.max_position_embeddings, + initializer_range=self.initializer_range, + ) + + def create_and_check_model(self, config, input_ids, input_mask): + model = TFGroupViTTextModel(config=config) + result = model(input_ids, attention_mask=input_mask, training=False) + result = model(input_ids, training=False) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, input_mask = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_tf +class TFGroupViTTextModelTest(TFModelTesterMixin, unittest.TestCase): + all_model_classes = (TFGroupViTTextModel,) if is_tf_available() else () + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFGroupViTTextModelTester(self) + self.config_tester = ConfigTester(self, config_class=GroupViTTextConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="GroupViTTextModel does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @slow + def test_model_from_pretrained(self): + for model_name in TF_GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFGroupViTTextModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @slow + def test_saved_model_creation_extended(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + if hasattr(config, "use_cache"): + config.use_cache = True + + for model_class in self.all_model_classes: + class_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + num_out = len(model(class_inputs_dict)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=True) + saved_model_dir = os.path.join(tmpdirname, "saved_model", "1") + model = tf.keras.models.load_model(saved_model_dir) + outputs = model(class_inputs_dict) + output_hidden_states = outputs["hidden_states"] + output_attentions = outputs["attentions"] + + # Check number of outputs + self.assertEqual(len(outputs), num_out) + + # Check number of layers + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + # Check hidden states + self.assertEqual(len(output_hidden_states), expected_num_layers) + self.assertListEqual( + list(output_hidden_states[0].shape[-2:]), + [self.model_tester.seq_length, self.model_tester.hidden_size], + ) + + # Check attention outputs + self.assertEqual(len(output_attentions), self.model_tester.num_hidden_layers) + + seq_length = self.model_tester.seq_length + key_length = getattr(self.model_tester, "key_length", seq_length) + + self.assertListEqual( + list(output_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, key_length], + ) + + +class TFGroupViTModelTester: + def __init__(self, parent, is_training=True): + self.parent = parent + self.text_model_tester = TFGroupViTTextModelTester(parent) + self.vision_model_tester = TFGroupViTVisionModelTester(parent) + self.is_training = is_training + + def prepare_config_and_inputs(self): + text_config, input_ids, attention_mask = self.text_model_tester.prepare_config_and_inputs() + vision_config, pixel_values = self.vision_model_tester.prepare_config_and_inputs() + + config = self.get_config() + + return config, input_ids, attention_mask, pixel_values + + def get_config(self): + return GroupViTConfig.from_text_vision_configs( + self.text_model_tester.get_config(), self.vision_model_tester.get_config(), projection_dim=64 + ) + + def create_and_check_model(self, config, input_ids, attention_mask, pixel_values): + model = TFGroupViTModel(config) + result = model(input_ids, pixel_values, attention_mask, training=False) + self.parent.assertEqual( + result.logits_per_image.shape, (self.vision_model_tester.batch_size, self.text_model_tester.batch_size) + ) + self.parent.assertEqual( + result.logits_per_text.shape, (self.text_model_tester.batch_size, self.vision_model_tester.batch_size) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, input_ids, attention_mask, pixel_values = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "pixel_values": pixel_values, + "return_loss": True, + } + return config, inputs_dict + + +@require_tf +class TFGroupViTModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFGroupViTModel,) if is_tf_available() else () + pipeline_model_mapping = {"feature-extraction": TFGroupViTModel} if is_tf_available() else {} + test_head_masking = False + test_pruning = False + test_resize_embeddings = False + test_attention_outputs = False + test_onnx = False + + def setUp(self): + self.model_tester = TFGroupViTModelTester(self) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @unittest.skip(reason="hidden_states are tested in individual model tests") + def test_hidden_states_output(self): + pass + + @unittest.skip(reason="input_embeds are tested in individual model tests") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="CLIPModel does not have input/output embeddings") + def test_model_common_attributes(self): + pass + + @require_tensorflow_probability + def test_keras_fit(self): + super().test_keras_fit() + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self): + # `GroupViT` computes some indices using argmax, uses them as + # one-hot encoding for further computation. The problem is + # while PT/TF have very small difference in `y_soft` (~ 1e-9), + # the argmax could be totally different, if there are at least + # 2 indices with almost identical values. This leads to very + # large difference in the outputs. We need specific seeds to + # avoid almost identical values happening in `y_soft`. + import torch + + seed = 158 + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + tf.random.set_seed(seed) + return super().test_pt_tf_model_equivalence() + + # overwrite from common since `TFGroupViTModelTester` set `return_loss` to `True` and causes the preparation of + # `symbolic_inputs` failed. + def test_keras_save_load(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # remove `return_loss` to make code work + if self.__class__.__name__ == "TFGroupViTModelTest": + inputs_dict.pop("return_loss", None) + + tf_main_layer_classes = { + module_member + for model_class in self.all_model_classes + for module in (import_module(model_class.__module__),) + for module_member_name in dir(module) + if module_member_name.endswith("MainLayer") + # This condition is required, since `modeling_tf_clip.py` has 3 classes whose names end with `MainLayer`. + and module_member_name[: -len("MainLayer")] == model_class.__name__[: -len("Model")] + for module_member in (getattr(module, module_member_name),) + if isinstance(module_member, type) + and tf.keras.layers.Layer in module_member.__bases__ + and getattr(module_member, "_keras_serializable", False) + } + for main_layer_class in tf_main_layer_classes: + # T5MainLayer needs an embed_tokens parameter when called without the inputs_embeds parameter + if "T5" in main_layer_class.__name__: + # Take the same values than in TFT5ModelTester for this shared layer + shared = TFSharedEmbeddings(99, 32, name="shared") + config.use_cache = inputs_dict.pop("use_cache", None) + main_layer = main_layer_class(config, embed_tokens=shared) + else: + main_layer = main_layer_class(config) + + symbolic_inputs = { + name: tf.keras.Input(tensor.shape[1:], dtype=tensor.dtype) for name, tensor in inputs_dict.items() + } + + model = tf.keras.Model(symbolic_inputs, outputs=main_layer(symbolic_inputs)) + outputs = model(inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + filepath = os.path.join(tmpdirname, "keras_model.h5") + model.save(filepath) + if "T5" in main_layer_class.__name__: + model = tf.keras.models.load_model( + filepath, + custom_objects={ + main_layer_class.__name__: main_layer_class, + "TFSharedEmbeddings": TFSharedEmbeddings, + }, + ) + else: + model = tf.keras.models.load_model( + filepath, custom_objects={main_layer_class.__name__: main_layer_class} + ) + assert isinstance(model, tf.keras.Model) + after_outputs = model(inputs_dict) + self.assert_outputs_same(after_outputs, outputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_GROUPVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFGroupViTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + @unittest.skip(reason="Currently `saved_model` doesn't work with nested outputs.") + @slow + def test_saved_model_creation(self): + pass + + @unittest.skip(reason="Currently `saved_model` doesn't work with nested outputs.") + @slow + def test_saved_model_creation_extended(self): + pass + + @unittest.skip(reason="`saved_model` doesn't work with nested outputs so no preparation happens.") + @slow + def test_prepare_serving_output(self): + pass + + +# We will verify our results on an image of cute cats +def prepare_img(): + url = "http://images.cocodataset.org/val2017/000000039769.jpg" + im = Image.open(requests.get(url, stream=True).raw) + return im + + +@require_vision +@require_tf +class TFGroupViTModelIntegrationTest(unittest.TestCase): + @slow + def test_inference(self): + model_name = "nvidia/groupvit-gcc-yfcc" + model = TFGroupViTModel.from_pretrained(model_name) + processor = CLIPProcessor.from_pretrained(model_name) + + image = prepare_img() + inputs = processor( + text=["a photo of a cat", "a photo of a dog"], images=image, padding=True, return_tensors="tf" + ) + + outputs = model(**inputs, training=False) + + # verify the logits + self.assertEqual( + outputs.logits_per_image.shape, + tf.TensorShape((inputs.pixel_values.shape[0], inputs.input_ids.shape[0])), + ) + self.assertEqual( + outputs.logits_per_text.shape, + tf.TensorShape((inputs.input_ids.shape[0], inputs.pixel_values.shape[0])), + ) + + expected_logits = tf.constant([[13.3523, 6.3629]]) + + tf.debugging.assert_near(outputs.logits_per_image, expected_logits, atol=1e-3) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/herbert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/herbert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/herbert/test_tokenization_herbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/herbert/test_tokenization_herbert.py new file mode 100644 index 0000000000000000000000000000000000000000..1afea16bdd28c2a1b76f46024daa8b9dda1a12c2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/herbert/test_tokenization_herbert.py @@ -0,0 +1,127 @@ +# coding=utf-8 +# Copyright 2018 The Google AI Language Team Authors, Allegro.pl and The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import unittest + +from transformers import HerbertTokenizer, HerbertTokenizerFast +from transformers.models.herbert.tokenization_herbert import VOCAB_FILES_NAMES +from transformers.testing_utils import get_tests_dir, require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class HerbertTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = HerbertTokenizer + rust_tokenizer_class = HerbertTokenizerFast + test_rust_tokenizer = True + + def setUp(self): + super().setUp() + + # Use a simpler test file without japanese/chinese characters + with open(f"{get_tests_dir()}/fixtures/sample_text_no_unicode.txt", encoding="utf-8") as f_data: + self._data = f_data.read().replace("\n\n", "\n").strip() + + vocab = [ + "", + "", + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "w", + "r", + "t", + "lo", + "low", + "er", + "low", + "lowest", + "newer", + "wider", + ",", + "", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["l o 123", "lo w 1456", "e r 1789", ""] + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w") as fp: + fp.write(json.dumps(vocab_tokens)) + with open(self.merges_file, "w") as fp: + fp.write("\n".join(merges)) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.tokenizer_class(vocab_file=self.vocab_file, merges_file=self.merges_file) + + text = "lower" + bpe_tokens = ["low", "er"] + tokens = tokenizer.tokenize(text) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [""] + input_bpe_tokens = [16, 17, 23] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence = "lower,newer" + + tokens = tokenizer.tokenize(sequence) + rust_tokens = rust_tokenizer.tokenize(sequence) + self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + rust_tokenizer = self.get_rust_tokenizer() + ids = tokenizer.encode(sequence) + rust_ids = rust_tokenizer.encode(sequence) + self.assertListEqual(ids, rust_ids) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("allegro/herbert-base-cased") + + text = tokenizer.encode("konstruowanie sekwencji", add_special_tokens=False) + text_2 = tokenizer.encode("konstruowanie wielu sekwencji", add_special_tokens=False) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == [0] + text + [2] + assert encoded_pair == [0] + text + [2] + text_2 + [2] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_hubert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_hubert.py new file mode 100644 index 0000000000000000000000000000000000000000..9b18b5580a8f4808ca44205e30e2f718a0947516 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_hubert.py @@ -0,0 +1,945 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Hubert model. """ + + +import math +import os +import pickle +import tempfile +import unittest + +import pytest + +from transformers import HubertConfig, is_torch_available +from transformers.testing_utils import require_soundfile, require_torch, slow, torch_device +from transformers.utils import is_torch_fx_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + HubertForCTC, + HubertForSequenceClassification, + HubertModel, + Wav2Vec2FeatureExtractor, + Wav2Vec2Processor, + ) + from transformers.models.hubert.modeling_hubert import _compute_mask_indices + +if is_torch_fx_available(): + from transformers.utils.fx import symbolic_trace + + +class HubertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=1024, # speech is longer + is_training=False, + hidden_size=16, + feat_extract_norm="group", + feat_extract_dropout=0.0, + feat_extract_activation="gelu", + conv_dim=(32, 32, 32), + conv_stride=(4, 4, 4), + conv_kernel=(8, 8, 8), + conv_bias=False, + num_conv_pos_embeddings=16, + num_conv_pos_embedding_groups=2, + num_hidden_layers=4, + num_attention_heads=2, + hidden_dropout_prob=0.1, # this is most likely not correctly set yet + intermediate_size=20, + layer_norm_eps=1e-5, + hidden_act="gelu", + initializer_range=0.02, + vocab_size=32, + do_stable_layer_norm=False, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.hidden_size = hidden_size + self.feat_extract_norm = feat_extract_norm + self.feat_extract_dropout = feat_extract_dropout + self.feat_extract_activation = feat_extract_activation + self.conv_dim = conv_dim + self.conv_stride = conv_stride + self.conv_kernel = conv_kernel + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_dropout_prob = hidden_dropout_prob + self.intermediate_size = intermediate_size + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.do_stable_layer_norm = do_stable_layer_norm + self.scope = scope + + output_seq_length = self.seq_length + for kernel, stride in zip(self.conv_kernel, self.conv_stride): + output_seq_length = (output_seq_length - (kernel - 1)) / stride + self.output_seq_length = int(math.ceil(output_seq_length)) + self.encoder_seq_length = self.output_seq_length + + def prepare_config_and_inputs(self): + input_values = floats_tensor([self.batch_size, self.seq_length], scale=1.0) + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + config = self.get_config() + + return config, input_values, attention_mask + + def get_config(self): + return HubertConfig( + hidden_size=self.hidden_size, + feat_extract_norm=self.feat_extract_norm, + feat_extract_dropout=self.feat_extract_dropout, + feat_extract_activation=self.feat_extract_activation, + conv_dim=self.conv_dim, + conv_stride=self.conv_stride, + conv_kernel=self.conv_kernel, + conv_bias=self.conv_bias, + num_conv_pos_embeddings=self.num_conv_pos_embeddings, + num_conv_pos_embedding_groups=self.num_conv_pos_embedding_groups, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + hidden_dropout_prob=self.hidden_dropout_prob, + intermediate_size=self.intermediate_size, + layer_norm_eps=self.layer_norm_eps, + hidden_act=self.hidden_act, + initializer_range=self.initializer_range, + vocab_size=self.vocab_size, + do_stable_layer_norm=self.do_stable_layer_norm, + ) + + def create_and_check_model(self, config, input_values, attention_mask): + model = HubertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_values, attention_mask=attention_mask) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.output_seq_length, self.hidden_size) + ) + + def create_and_check_batch_inference(self, config, input_values, *args): + # test does not pass for models making use of `group_norm` + # check: https://github.com/pytorch/fairseq/issues/3227 + model = HubertModel(config=config) + model.to(torch_device) + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.bool) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0.0 + + batch_outputs = model(input_values, attention_mask=attention_mask).last_hidden_state + + for i in range(input_values.shape[0]): + input_slice = input_values[i : i + 1, : input_lengths[i]] + output = model(input_slice).last_hidden_state + + batch_output = batch_outputs[i : i + 1, : output.shape[1]] + self.parent.assertTrue(torch.allclose(output, batch_output, atol=1e-3)) + + def check_ctc_loss(self, config, input_values, *args): + model = HubertForCTC(config=config) + model.to(torch_device) + + # make sure that dropout is disabled + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.long) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], min(max_length_labels) - 1), model.config.vocab_size) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0 + + model.config.ctc_loss_reduction = "sum" + sum_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + + model.config.ctc_loss_reduction = "mean" + mean_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + + self.parent.assertTrue(isinstance(sum_loss, float)) + self.parent.assertTrue(isinstance(mean_loss, float)) + + def check_seq_classifier_loss(self, config, input_values, *args): + model = HubertForSequenceClassification(config=config) + model.to(torch_device) + + # make sure that dropout is disabled + model.eval() + + input_values = input_values[:3] + attention_mask = torch.ones(input_values.shape, device=torch_device, dtype=torch.long) + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + labels = ids_tensor((input_values.shape[0], 1), len(model.config.id2label)) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + attention_mask[i, input_lengths[i] :] = 0 + + masked_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss.item() + unmasked_loss = model(input_values, labels=labels).loss.item() + + self.parent.assertTrue(isinstance(masked_loss, float)) + self.parent.assertTrue(isinstance(unmasked_loss, float)) + self.parent.assertTrue(masked_loss != unmasked_loss) + + def check_ctc_training(self, config, input_values, *args): + config.ctc_zero_infinity = True + model = HubertForCTC(config=config) + model.to(torch_device) + model.train() + + # freeze feature encoder + model.freeze_feature_encoder() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], max(max_length_labels) - 2), model.config.vocab_size) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + + if max_length_labels[i] < labels.shape[-1]: + # it's important that we make sure that target lenghts are at least + # one shorter than logit lenghts to prevent -inf + labels[i, max_length_labels[i] - 1 :] = -100 + + loss = model(input_values, labels=labels).loss + self.parent.assertFalse(torch.isinf(loss).item()) + + loss.backward() + + def check_seq_classifier_training(self, config, input_values, *args): + config.ctc_zero_infinity = True + model = HubertForSequenceClassification(config=config) + model.to(torch_device) + model.train() + + # freeze everything but the classification head + model.freeze_base_model() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + labels = ids_tensor((input_values.shape[0], 1), len(model.config.id2label)) + + # pad input + for i in range(len(input_lengths)): + input_values[i, input_lengths[i] :] = 0.0 + + loss = model(input_values, labels=labels).loss + self.parent.assertFalse(torch.isinf(loss).item()) + + loss.backward() + + def check_labels_out_of_vocab(self, config, input_values, *args): + model = HubertForCTC(config) + model.to(torch_device) + model.train() + + input_values = input_values[:3] + + input_lengths = [input_values.shape[-1] // i for i in [4, 2, 1]] + max_length_labels = model._get_feat_extract_output_lengths(torch.tensor(input_lengths)) + labels = ids_tensor((input_values.shape[0], max(max_length_labels) - 2), model.config.vocab_size + 100) + + with pytest.raises(ValueError): + model(input_values, labels=labels) + + def prepare_config_and_inputs_for_common(self): + config, input_values, attention_mask = self.prepare_config_and_inputs() + inputs_dict = {"input_values": input_values, "attention_mask": attention_mask} + return config, inputs_dict + + +@require_torch +class HubertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (HubertForCTC, HubertForSequenceClassification, HubertModel) if is_torch_available() else () + pipeline_model_mapping = ( + { + "audio-classification": HubertForSequenceClassification, + "automatic-speech-recognition": HubertForCTC, + "feature-extraction": HubertModel, + } + if is_torch_available() + else {} + ) + fx_compatible = True + test_pruning = False + test_headmasking = False + + def setUp(self): + self.model_tester = HubertModelTester(self) + self.config_tester = ConfigTester(self, config_class=HubertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_ctc_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_loss(*config_and_inputs) + + def test_seq_classifier_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_loss(*config_and_inputs) + + def test_ctc_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_training(*config_and_inputs) + + def test_seq_classifier_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_training(*config_and_inputs) + + def test_labels_out_of_vocab(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_labels_out_of_vocab(*config_and_inputs) + + # Hubert has no inputs_embeds + def test_inputs_embeds(self): + pass + + # `input_ids` is renamed to `input_values` + def test_forward_signature(self): + pass + + # Hubert cannot resize token embeddings + # since it has no tokens embeddings + def test_resize_tokens_embeddings(self): + pass + + # Hubert has no inputs_embeds + # and thus the `get_input_embeddings` fn + # is not implemented + def test_model_common_attributes(self): + pass + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + # set layer drop to 0 + model.config.layerdrop = 0.0 + + input_values = inputs_dict["input_values"] + + input_lengths = torch.tensor( + [input_values.shape[1] for _ in range(input_values.shape[0])], dtype=torch.long, device=torch_device + ) + output_lengths = model._get_feat_extract_output_lengths(input_lengths) + + labels = ids_tensor((input_values.shape[0], output_lengths[0] - 2), self.model_tester.vocab_size) + inputs_dict["attention_mask"] = torch.ones_like(inputs_dict["attention_mask"]) + inputs_dict["labels"] = labels + + outputs = model(**inputs_dict) + + output = outputs[0] + + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0] + attentions = outputs.attentions[0] + + hidden_states.retain_grad() + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + self.assertIsNotNone(attentions.grad) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + uniform_init_parms = [ + "conv.weight", + "masked_spec_embed", + "quantizer.weight_proj.weight", + ] + if param.requires_grad: + if any([x in name for x in uniform_init_parms]): + self.assertTrue( + -1.0 <= ((param.data.mean() * 1e9).round() / 1e9).item() <= 1.0, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + # Hubert cannot be TorchScripted because of torch.nn.utils.weight_norm + def _create_and_check_torch_fx_tracing(self, config, inputs_dict, output_loss=False): + if not is_torch_fx_available() or not self.fx_compatible: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.return_dict = False + + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=output_loss) + + try: + if model.config.is_encoder_decoder: + model.config.use_cache = False # FSTM still requires this hack -> FSTM should probably be refactored similar to BART afterward + labels = inputs.get("labels", None) + input_names = [ + "attention_mask", + "decoder_attention_mask", + "decoder_input_ids", + "input_features", + "input_ids", + "input_values", + ] + if labels is not None: + input_names.append("labels") + + filtered_inputs = {k: v for (k, v) in inputs.items() if k in input_names} + input_names = list(filtered_inputs.keys()) + + model_output = model(**filtered_inputs) + + traced_model = symbolic_trace(model, input_names) + traced_output = traced_model(**filtered_inputs) + else: + input_names = [ + "attention_mask", + "bbox", + "input_features", + "input_ids", + "input_values", + "pixel_values", + "token_type_ids", + "visual_feats", + "visual_pos", + ] + + labels = inputs.get("labels", None) + start_positions = inputs.get("start_positions", None) + end_positions = inputs.get("end_positions", None) + if labels is not None: + input_names.append("labels") + if start_positions is not None: + input_names.append("start_positions") + if end_positions is not None: + input_names.append("end_positions") + + filtered_inputs = {k: v for (k, v) in inputs.items() if k in input_names} + input_names = list(filtered_inputs.keys()) + + model_output = model(**filtered_inputs) + + traced_model = symbolic_trace(model, input_names) + traced_output = traced_model(**filtered_inputs) + + except Exception as e: + self.fail(f"Couldn't trace module: {e}") + + def flatten_output(output): + flatten = [] + for x in output: + if isinstance(x, (tuple, list)): + flatten += flatten_output(x) + elif not isinstance(x, torch.Tensor): + continue + else: + flatten.append(x) + return flatten + + model_output = flatten_output(model_output) + traced_output = flatten_output(traced_output) + num_outputs = len(model_output) + + for i in range(num_outputs): + self.assertTrue( + torch.allclose(model_output[i], traced_output[i]), + f"traced {i}th output doesn't match model {i}th output for {model_class}", + ) + + # Test that the model can be serialized and restored properly + with tempfile.TemporaryDirectory() as tmp_dir_name: + pkl_file_name = os.path.join(tmp_dir_name, "model.pkl") + try: + with open(pkl_file_name, "wb") as f: + pickle.dump(traced_model, f) + with open(pkl_file_name, "rb") as f: + loaded = pickle.load(f) + except Exception as e: + self.fail(f"Couldn't serialize / deserialize the traced model: {e}") + + loaded_output = loaded(**filtered_inputs) + loaded_output = flatten_output(loaded_output) + + for i in range(num_outputs): + self.assertTrue( + torch.allclose(model_output[i], loaded_output[i]), + f"serialized model {i}th output doesn't match model {i}th output for {model_class}", + ) + + # overwrite from test_modeling_common + def _mock_init_weights(self, module): + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(3) + if hasattr(module, "weight_g") and module.weight_g is not None: + module.weight_g.data.fill_(3) + if hasattr(module, "weight_v") and module.weight_v is not None: + module.weight_v.data.fill_(3) + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.fill_(3) + if hasattr(module, "masked_spec_embed") and module.masked_spec_embed is not None: + module.masked_spec_embed.data.fill_(3) + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + @slow + def test_model_from_pretrained(self): + model = HubertModel.from_pretrained("facebook/hubert-base-ls960") + self.assertIsNotNone(model) + + +@require_torch +class HubertRobustModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (HubertForCTC, HubertForSequenceClassification, HubertModel) if is_torch_available() else () + test_pruning = False + test_headmasking = False + + def setUp(self): + self.model_tester = HubertModelTester( + self, conv_stride=(3, 3, 3), feat_extract_norm="layer", do_stable_layer_norm=True + ) + self.config_tester = ConfigTester(self, config_class=HubertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_batched_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_batch_inference(*config_and_inputs) + + def test_ctc_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_loss(*config_and_inputs) + + def test_seq_classifier_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_loss(*config_and_inputs) + + def test_ctc_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_training(*config_and_inputs) + + def test_seq_classifier_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_seq_classifier_training(*config_and_inputs) + + def test_labels_out_of_vocab(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_labels_out_of_vocab(*config_and_inputs) + + # Hubert has no inputs_embeds + def test_inputs_embeds(self): + pass + + # `input_ids` is renamed to `input_values` + def test_forward_signature(self): + pass + + # Hubert cannot resize token embeddings + # since it has no tokens embeddings + def test_resize_tokens_embeddings(self): + pass + + # Hubert has no inputs_embeds + # and thus the `get_input_embeddings` fn + # is not implemented + def test_model_common_attributes(self): + pass + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + # set layer drop to 0 + model.config.layerdrop = 0.0 + + input_values = inputs_dict["input_values"] + + input_lengths = torch.tensor( + [input_values.shape[1] for _ in range(input_values.shape[0])], dtype=torch.long, device=torch_device + ) + output_lengths = model._get_feat_extract_output_lengths(input_lengths) + + labels = ids_tensor((input_values.shape[0], output_lengths[0] - 2), self.model_tester.vocab_size) + inputs_dict["attention_mask"] = torch.ones_like(inputs_dict["attention_mask"]) + inputs_dict["labels"] = labels + + outputs = model(**inputs_dict) + + output = outputs[0] + + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0] + attentions = outputs.attentions[0] + + hidden_states.retain_grad() + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + self.assertIsNotNone(attentions.grad) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + uniform_init_parms = [ + "conv.weight", + "masked_spec_embed", + "quantizer.weight_proj.weight", + ] + if param.requires_grad: + if any([x in name for x in uniform_init_parms]): + self.assertTrue( + -1.0 <= ((param.data.mean() * 1e9).round() / 1e9).item() <= 1.0, + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + else: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + # overwrite from test_modeling_common + def _mock_init_weights(self, module): + if hasattr(module, "weight") and module.weight is not None: + module.weight.data.fill_(3) + if hasattr(module, "weight_g") and module.weight_g is not None: + module.weight_g.data.fill_(3) + if hasattr(module, "weight_v") and module.weight_v is not None: + module.weight_v.data.fill_(3) + if hasattr(module, "bias") and module.bias is not None: + module.bias.data.fill_(3) + if hasattr(module, "masked_spec_embed") and module.masked_spec_embed is not None: + module.masked_spec_embed.data.fill_(3) + + @unittest.skip(reason="Feed forward chunking is not implemented") + def test_feed_forward_chunking(self): + pass + + @slow + def test_model_from_pretrained(self): + model = HubertModel.from_pretrained("facebook/hubert-large-ls960-ft") + self.assertIsNotNone(model) + + +@require_torch +class HubertUtilsTest(unittest.TestCase): + def test_compute_mask_indices(self): + batch_size = 4 + sequence_length = 60 + mask_prob = 0.5 + mask_length = 1 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + mask = torch.from_numpy(mask).to(torch_device) + + self.assertListEqual(mask.sum(axis=-1).tolist(), [mask_prob * sequence_length for _ in range(batch_size)]) + + def test_compute_mask_indices_overlap(self): + batch_size = 4 + sequence_length = 80 + mask_prob = 0.5 + mask_length = 4 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + mask = torch.from_numpy(mask).to(torch_device) + + # because of overlap mask don't have to add up exactly to `mask_prob * sequence_length`, but have to be smaller or equal + for batch_sum in mask.sum(axis=-1): + self.assertTrue(int(batch_sum) <= mask_prob * sequence_length) + + +@require_torch +@require_soundfile +@slow +class HubertModelIntegrationTest(unittest.TestCase): + def _load_datasamples(self, num_samples): + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + # automatic decoding with librispeech + speech_samples = ds.sort("id").filter( + lambda x: x["id"] in [f"1272-141231-000{i}" for i in range(num_samples)] + )[:num_samples]["audio"] + + return [x["array"] for x in speech_samples] + + def _load_superb(self, task, num_samples): + from datasets import load_dataset + + ds = load_dataset("anton-l/superb_dummy", task, split="test") + + return ds[:num_samples] + + def test_inference_ctc_batched(self): + model = HubertForCTC.from_pretrained("facebook/hubert-large-ls960-ft", torch_dtype=torch.float16).to( + torch_device + ) + processor = Wav2Vec2Processor.from_pretrained("facebook/hubert-large-ls960-ft", do_lower_case=True) + + input_speech = self._load_datasamples(2) + + inputs = processor(input_speech, return_tensors="pt", padding=True) + + input_values = inputs.input_values.half().to(torch_device) + attention_mask = inputs.attention_mask.to(torch_device) + + with torch.no_grad(): + logits = model(input_values, attention_mask=attention_mask).logits + + predicted_ids = torch.argmax(logits, dim=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = [ + "a man said to the universe sir i exist", + "sweat covered brion's body trickling into the tight loin cloth that was the only garment he wore", + ] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) + + def test_inference_keyword_spotting(self): + model = HubertForSequenceClassification.from_pretrained( + "superb/hubert-base-superb-ks", torch_dtype=torch.float16 + ).to(torch_device) + processor = Wav2Vec2FeatureExtractor.from_pretrained("superb/hubert-base-superb-ks") + input_data = self._load_superb("ks", 4) + inputs = processor(input_data["speech"], return_tensors="pt", padding=True) + + input_values = inputs.input_values.half().to(torch_device) + attention_mask = inputs.attention_mask.to(torch_device) + with torch.no_grad(): + outputs = model(input_values, attention_mask=attention_mask) + predicted_logits, predicted_ids = torch.max(outputs.logits, dim=-1) + + expected_labels = [2, 6, 10, 9] + # s3prl logits for the same batch + expected_logits = torch.tensor([7.6692, 17.7795, 11.1562, 11.8232], dtype=torch.float16, device=torch_device) + + self.assertListEqual(predicted_ids.tolist(), expected_labels) + self.assertTrue(torch.allclose(predicted_logits, expected_logits, atol=3e-2)) + + def test_inference_intent_classification(self): + model = HubertForSequenceClassification.from_pretrained( + "superb/hubert-base-superb-ic", torch_dtype=torch.float16 + ).to(torch_device) + processor = Wav2Vec2FeatureExtractor.from_pretrained("superb/hubert-base-superb-ic") + input_data = self._load_superb("ic", 4) + inputs = processor(input_data["speech"], return_tensors="pt", padding=True) + + input_values = inputs.input_values.half().to(torch_device) + attention_mask = inputs.attention_mask.to(torch_device) + with torch.no_grad(): + outputs = model(input_values, attention_mask=attention_mask) + + predicted_logits_action, predicted_ids_action = torch.max(outputs.logits[:, :6], dim=-1) + predicted_logits_object, predicted_ids_object = torch.max(outputs.logits[:, 6:20], dim=-1) + predicted_logits_location, predicted_ids_location = torch.max(outputs.logits[:, 20:24], dim=-1) + + expected_labels_action = [1, 0, 4, 3] + expected_logits_action = torch.tensor( + [5.9052, 12.5865, 4.4840, 10.0240], dtype=torch.float16, device=torch_device + ) + expected_labels_object = [1, 10, 3, 4] + expected_logits_object = torch.tensor( + [5.5316, 11.7946, 8.1672, 23.2415], dtype=torch.float16, device=torch_device + ) + expected_labels_location = [0, 0, 0, 1] + expected_logits_location = torch.tensor( + [5.2053, 8.9577, 10.0447, 8.1481], dtype=torch.float16, device=torch_device + ) + + self.assertListEqual(predicted_ids_action.tolist(), expected_labels_action) + self.assertListEqual(predicted_ids_object.tolist(), expected_labels_object) + self.assertListEqual(predicted_ids_location.tolist(), expected_labels_location) + + # TODO: lower the tolerance after merging the padding fix https://github.com/pytorch/fairseq/pull/3572 + self.assertTrue(torch.allclose(predicted_logits_action, expected_logits_action, atol=3e-1)) + self.assertTrue(torch.allclose(predicted_logits_object, expected_logits_object, atol=3e-1)) + self.assertTrue(torch.allclose(predicted_logits_location, expected_logits_location, atol=3e-1)) + + def test_inference_speaker_identification(self): + model = HubertForSequenceClassification.from_pretrained( + "superb/hubert-base-superb-sid", torch_dtype=torch.float16 + ).to(torch_device) + processor = Wav2Vec2FeatureExtractor.from_pretrained("superb/hubert-base-superb-sid") + input_data = self._load_superb("si", 4) + + output_logits = [] + with torch.no_grad(): + for example in input_data["speech"]: + input = processor(example, return_tensors="pt", padding=True) + output = model(input.input_values.half().to(torch_device), attention_mask=None) + output_logits.append(output.logits[0]) + output_logits = torch.stack(output_logits) + predicted_logits, predicted_ids = torch.max(output_logits, dim=-1) + + expected_labels = [5, 1, 1, 3] + # s3prl logits for the same batch + expected_logits = torch.tensor( + [78231.5547, 123166.6094, 122785.4141, 84851.2969], dtype=torch.float16, device=torch_device + ) + + self.assertListEqual(predicted_ids.tolist(), expected_labels) + # TODO: lower the tolerance after merging the padding fix https://github.com/pytorch/fairseq/pull/3572 + self.assertTrue(torch.allclose(predicted_logits, expected_logits, atol=10)) + + def test_inference_emotion_recognition(self): + model = HubertForSequenceClassification.from_pretrained( + "superb/hubert-base-superb-er", torch_dtype=torch.float16 + ).to(torch_device) + processor = Wav2Vec2FeatureExtractor.from_pretrained("superb/hubert-base-superb-er") + input_data = self._load_superb("er", 4) + inputs = processor(input_data["speech"], return_tensors="pt", padding=True) + + input_values = inputs.input_values.half().to(torch_device) + attention_mask = inputs.attention_mask.to(torch_device) + with torch.no_grad(): + outputs = model(input_values, attention_mask=attention_mask) + predicted_logits, predicted_ids = torch.max(outputs.logits, dim=-1) + + expected_labels = [1, 1, 2, 2] + # s3prl logits for the same batch + expected_logits = torch.tensor([2.8384, 2.3389, 3.8564, 4.5558], dtype=torch.float16, device=torch_device) + + self.assertListEqual(predicted_ids.tolist(), expected_labels) + # TODO: lower the tolerance after merging the padding fix https://github.com/pytorch/fairseq/pull/3572 + self.assertTrue(torch.allclose(predicted_logits, expected_logits, atol=1e-1)) + + def test_inference_distilhubert(self): + model = HubertModel.from_pretrained("ntu-spml/distilhubert").to(torch_device) + processor = Wav2Vec2FeatureExtractor.from_pretrained("ntu-spml/distilhubert") + + # TODO: can't test on batched inputs due to incompatible padding https://github.com/pytorch/fairseq/pull/3572 + input_speech = self._load_datasamples(1) + + inputs = processor(input_speech, return_tensors="pt", padding=True) + + input_values = inputs.input_values.to(torch_device) + + with torch.no_grad(): + outputs = model(input_values).last_hidden_state + + # expected outputs taken from the original SEW implementation + expected_outputs_first = torch.tensor( + [ + [ + [-0.3505, 0.1167, 0.0608, 0.1294], + [-0.3085, 0.0481, 0.1106, 0.0955], + [-0.3107, -0.0391, 0.0739, 0.1360], + [-0.2385, -0.1795, -0.0928, 0.2389], + ] + ], + device=torch_device, + ) + expected_outputs_last = torch.tensor( + [ + [ + [-0.0732, 0.0255, 0.0529, -0.1372], + [-0.0812, 0.1259, 0.0564, -0.0438], + [-0.0054, 0.0758, -0.0002, -0.1617], + [0.0133, -0.0320, -0.0687, 0.0062], + ] + ], + device=torch_device, + ) + expected_output_sum = -3776.0730 + + self.assertTrue(torch.allclose(outputs[:, :4, :4], expected_outputs_first, atol=5e-3)) + self.assertTrue(torch.allclose(outputs[:, -4:, -4:], expected_outputs_last, atol=5e-3)) + self.assertTrue(abs(outputs.sum() - expected_output_sum) < 0.1) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_tf_hubert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_tf_hubert.py new file mode 100644 index 0000000000000000000000000000000000000000..a48ed0634e8489275b3acae4820c02263f722e40 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/hubert/test_modeling_tf_hubert.py @@ -0,0 +1,675 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import inspect +import math +import os +import tempfile +import unittest + +import numpy as np +import pytest + +from transformers import is_tf_available +from transformers.testing_utils import is_pt_tf_cross_test, require_soundfile, require_tf, slow + +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 HubertConfig, TFHubertForCTC, TFHubertModel, Wav2Vec2Processor + from transformers.models.hubert.modeling_tf_hubert import _compute_mask_indices + + +@require_tf +class TFHubertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=1024, + is_training=False, + hidden_size=16, + feat_extract_norm="group", + feat_extract_dropout=0.0, + feat_extract_activation="gelu", + conv_dim=(32, 32, 32), + conv_stride=(4, 4, 4), + conv_kernel=(8, 8, 8), + conv_bias=False, + num_conv_pos_embeddings=16, + num_conv_pos_embedding_groups=2, + num_hidden_layers=4, + num_attention_heads=2, + hidden_dropout_prob=0.1, # this is most likely not correctly set yet + intermediate_size=20, + layer_norm_eps=1e-5, + hidden_act="gelu", + initializer_range=0.02, + vocab_size=32, + do_stable_layer_norm=False, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.hidden_size = hidden_size + self.feat_extract_norm = feat_extract_norm + self.feat_extract_dropout = feat_extract_dropout + self.feat_extract_activation = feat_extract_activation + self.conv_dim = conv_dim + self.conv_stride = conv_stride + self.conv_kernel = conv_kernel + self.conv_bias = conv_bias + self.num_conv_pos_embeddings = num_conv_pos_embeddings + self.num_conv_pos_embedding_groups = num_conv_pos_embedding_groups + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.hidden_dropout_prob = hidden_dropout_prob + self.intermediate_size = intermediate_size + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.initializer_range = initializer_range + self.vocab_size = vocab_size + self.do_stable_layer_norm = do_stable_layer_norm + self.scope = scope + + output_seq_length = self.seq_length + for kernel, stride in zip(self.conv_kernel, self.conv_stride): + output_seq_length = (output_seq_length - (kernel - 1)) / stride + self.output_seq_length = int(math.ceil(output_seq_length)) + self.encoder_seq_length = self.output_seq_length + + def prepare_config_and_inputs(self): + input_values = tf.cast(ids_tensor([self.batch_size, self.seq_length], 32768), tf.float32) / 32768.0 + attention_mask = tf.ones_like(input_values) + + config = HubertConfig( + hidden_size=self.hidden_size, + feat_extract_norm=self.feat_extract_norm, + feat_extract_dropout=self.feat_extract_dropout, + feat_extract_activation=self.feat_extract_activation, + conv_dim=self.conv_dim, + conv_stride=self.conv_stride, + conv_kernel=self.conv_kernel, + conv_bias=self.conv_bias, + num_conv_pos_embeddings=self.num_conv_pos_embeddings, + num_conv_pos_embedding_groups=self.num_conv_pos_embedding_groups, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + hidden_dropout_prob=self.hidden_dropout_prob, + intermediate_size=self.intermediate_size, + layer_norm_eps=self.layer_norm_eps, + hidden_act=self.hidden_act, + initializer_range=self.initializer_range, + vocab_size=self.vocab_size, + do_stable_layer_norm=self.do_stable_layer_norm, + ) + + return config, input_values, attention_mask + + def create_and_check_model(self, config, input_values, attention_mask): + model = TFHubertModel(config) + result = model(input_values, attention_mask=attention_mask) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.output_seq_length, self.hidden_size) + ) + + def create_and_check_batch_inference(self, config, input_values, *args): + # test does not pass for models making use of `group_norm` + # check: https://github.com/pytorch/fairseq/issues/3227 + config.layerdrop = 0.0 + model = TFHubertModel(config) + + input_values = input_values[:3] + attention_mask = tf.ones_like(input_values) + + input_lengths = tf.constant([input_values.shape[-1] // i for i in [4, 2, 1]]) + length_mask = tf.sequence_mask(input_lengths, dtype=tf.float32) + + # convert values that are over input_lengths to padding + input_values = input_values * length_mask + attention_mask = attention_mask * length_mask + + batch_outputs = model(input_values, attention_mask=attention_mask, training=False).last_hidden_state + + for i in range(input_values.shape[0]): + input_slice = input_values[i : i + 1, : input_lengths[i]] + output = model(input_slice, training=False).last_hidden_state + + batch_output = batch_outputs[i : i + 1, : output.shape[1]] + self.parent.assertTrue(np.allclose(output, batch_output, atol=1e-3)) + + def check_ctc_loss(self, config, input_values, *args): + model = TFHubertForCTC(config) + + input_values = input_values[:3] + attention_mask = tf.ones_like(input_values) + + input_lengths = tf.constant([input_values.shape[-1] // i for i in [4, 2, 1]]) + max_length_labels = model.hubert._get_feat_extract_output_lengths(input_lengths) + labels = ids_tensor((input_values.shape[0], min(max_length_labels) - 1), model.config.vocab_size) + + length_mask = tf.sequence_mask(input_lengths, dtype=tf.float32) + + # convert values that are over input_lengths to padding + input_values = input_values * length_mask + attention_mask = attention_mask * length_mask + + model.config.ctc_loss_reduction = "sum" + sum_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss + + model.config.ctc_loss_reduction = "mean" + mean_loss = model(input_values, attention_mask=attention_mask, labels=labels).loss + + self.parent.assertTrue(abs(labels.shape[0] * mean_loss - sum_loss) < 1e-2) + + def check_training(self, config, input_values, *args): + model = TFHubertForCTC(config) + + # freeze feature encoder + model.freeze_feature_encoder() + + input_values = input_values[:3] + + input_lengths = tf.constant([input_values.shape[-1] // i for i in [4, 2, 1]]) + max_length_labels = model.hubert._get_feat_extract_output_lengths(input_lengths) + labels = ids_tensor((input_values.shape[0], max(max_length_labels) - 2), model.config.vocab_size) + + length_mask = tf.sequence_mask(input_lengths, dtype=tf.float32) + + input_values = input_values * length_mask + + pad_size = max(max_length_labels) - labels.shape[1] + labels = tf.pad(labels, ((0, 0), (0, pad_size)), constant_values=-100) + + loss = model(input_values, labels=labels, training=True).loss + + self.parent.assertFalse(tf.math.is_inf(loss)) + + def check_labels_out_of_vocab(self, config, input_values, *args): + model = TFHubertForCTC(config) + input_lengths = tf.constant([input_values.shape[-1] // i for i in [4, 2, 1]]) + max_length_labels = model.hubert._get_feat_extract_output_lengths(input_lengths) + labels = ids_tensor((input_values.shape[0], min(max_length_labels) - 1), model.config.vocab_size + 100) + with pytest.raises(ValueError): + model(input_values, labels=labels) + + def prepare_config_and_inputs_for_common(self): + config, input_values, attention_mask = self.prepare_config_and_inputs() + inputs_dict = {"input_values": input_values, "attention_mask": attention_mask} + return config, inputs_dict + + +@require_tf +class TFHubertModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFHubertModel, TFHubertForCTC) if is_tf_available() else () + pipeline_model_mapping = {"feature-extraction": TFHubertModel} if is_tf_available() else {} + test_resize_embeddings = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFHubertModelTester(self) + self.config_tester = ConfigTester(self, config_class=HubertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + # overwrite because input_values != input_ids + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + # overwrite because input_values != input_ids + def test_keyword_and_dict_args(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs_dict = model(inputs) + + inputs_keywords = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + input_values = inputs_keywords.pop("input_values", None) + outputs_keywords = model(input_values, **inputs_keywords) + output_dict = outputs_dict[0].numpy() + output_keywords = outputs_keywords[0].numpy() + + self.assertLess(np.sum(np.abs(output_dict - output_keywords)), 1e-6) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_hidden_states_output(config, inputs_dict, model_class): + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + hidden_states = outputs.hidden_states + self.assertEqual(config.output_attentions, False) + self.assertEqual(len(hidden_states), expected_num_layers) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.output_seq_length, self.model_tester.hidden_size], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(config, inputs_dict, model_class) + + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + check_hidden_states_output(config, inputs_dict, model_class) + + def test_ctc_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_loss(*config_and_inputs) + + def test_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_training(*config_and_inputs) + + def test_labels_out_of_vocab(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_labels_out_of_vocab(*config_and_inputs) + + @unittest.skip(reason="Hubert has no input embeddings") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Hubert has no tokens embeddings") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip(reason="Hubert has no input embeddings") + def test_model_common_attributes(self): + pass + + @slow + def test_model_from_pretrained(self): + model = TFHubertModel.from_pretrained("facebook/hubert-base-ls960") + self.assertIsNotNone(model) + + @unittest.skip(reason="Fix me! Hubert hits OOM errors when loss is computed on full batch") + def test_dataset_conversion(self): + # TODO: (Amy) - check whether skipping CTC model resolves this issue and possible resolutions for CTC + pass + + @unittest.skip(reason="Fix me! Hubert hits OOM errors when loss is computed on full batch") + def test_keras_fit(self): + # TODO: (Amy) - check whether skipping CTC model resolves this issue and possible resolutions for CTC + pass + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self, allow_missing_keys=False): + # We override the base test here to skip loss calculation for Hubert models because the loss is massive with + # the default labels and frequently overflows to inf or exceeds numerical tolerances between TF/PT + import torch + + import transformers + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # Make sure no sequence has all zeros as attention mask, otherwise some tests fail due to the inconsistency + # of the usage `1e-4`, `1e-9`, `1e-30`, `-inf`. + # TODO: Use a uniform value for all models, make sure all tests pass without this processing, and remove it. + self._make_attention_mask_non_null(inputs_dict) + + pt_model_class_name = model_class.__name__[2:] # Skip the "TF" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + tf_model = model_class(config) + pt_model = pt_model_class(config) + + tf_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + + # Check we can load pt model in tf and vice-versa with model => model functions + tf_model = transformers.load_pytorch_model_in_tf2_model( + tf_model, pt_model, tf_inputs=tf_inputs_dict, allow_missing_keys=allow_missing_keys + ) + pt_model = transformers.load_tf2_model_in_pytorch_model( + pt_model, tf_model, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + # Check we can load pt model in tf and vice-versa with checkpoint => model functions + with tempfile.TemporaryDirectory() as tmpdirname: + pt_checkpoint_path = os.path.join(tmpdirname, "pt_model.bin") + torch.save(pt_model.state_dict(), pt_checkpoint_path) + tf_model = transformers.load_pytorch_checkpoint_in_tf2_model( + tf_model, pt_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + tf_checkpoint_path = os.path.join(tmpdirname, "tf_model.h5") + tf_model.save_weights(tf_checkpoint_path) + pt_model = transformers.load_tf2_checkpoint_in_pytorch_model( + pt_model, tf_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + +@require_tf +class TFHubertRobustModelTest(TFModelTesterMixin, unittest.TestCase): + all_model_classes = (TFHubertModel, TFHubertForCTC) if is_tf_available() else () + test_resize_embeddings = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFHubertModelTester( + self, + conv_stride=(3, 3, 3), + feat_extract_norm="layer", + do_stable_layer_norm=True, + scope="robust", + ) + self.config_tester = ConfigTester(self, config_class=HubertConfig, hidden_size=37) + + # overwrite because input_values != input_ids + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + # overwrite because input_values != input_ids + def test_keyword_and_dict_args(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs_dict = model(inputs) + + inputs_keywords = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + input_values = inputs_keywords.pop("input_values", None) + outputs_keywords = model(input_values, **inputs_keywords) + output_dict = outputs_dict[0].numpy() + output_keywords = outputs_keywords[0].numpy() + + self.assertLess(np.sum(np.abs(output_dict - output_keywords)), 1e-6) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_hidden_states_output(config, inputs_dict, model_class): + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + hidden_states = outputs.hidden_states + self.assertEqual(config.output_attentions, False) + self.assertEqual(len(hidden_states), expected_num_layers) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.output_seq_length, self.model_tester.hidden_size], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(config, inputs_dict, model_class) + + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + check_hidden_states_output(config, inputs_dict, model_class) + + def test_batched_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_batch_inference(*config_and_inputs) + + def test_ctc_loss_inference(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_ctc_loss(*config_and_inputs) + + def test_train(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_training(*config_and_inputs) + + def test_labels_out_of_vocab(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_labels_out_of_vocab(*config_and_inputs) + + @unittest.skip(reason="Hubert has no input embeddings") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Hubert has no tokens embeddings") + def test_resize_tokens_embeddings(self): + pass + + @unittest.skip(reason="Hubert has no input embeddings or get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @slow + def test_model_from_pretrained(self): + model = TFHubertModel.from_pretrained("facebook/hubert-large-ls960-ft") + self.assertIsNotNone(model) + + @unittest.skip(reason="Fix me! Hubert hits OOM errors when loss is computed on full batch") + def test_dataset_conversion(self): + # TODO: (Amy) - check whether skipping CTC model resolves this issue and possible resolutions for CTC + pass + + @unittest.skip(reason="Fix me! Hubert hits OOM errors when loss is computed on full batch") + def test_keras_fit(self): + # TODO: (Amy) - check whether skipping CTC model resolves this issue and possible resolutions for CTC + pass + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self, allow_missing_keys=False): + # We override the base test here to skip loss calculation for Hubert models because the loss is massive with + # the default labels and frequently overflows to inf or exceeds numerical tolerances between TF/PT + import torch + + import transformers + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # Make sure no sequence has all zeros as attention mask, otherwise some tests fail due to the inconsistency + # of the usage `1e-4`, `1e-9`, `1e-30`, `-inf`. + # TODO: Use a uniform value for all models, make sure all tests pass without this processing, and remove it. + self._make_attention_mask_non_null(inputs_dict) + + pt_model_class_name = model_class.__name__[2:] # Skip the "TF" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + tf_model = model_class(config) + pt_model = pt_model_class(config) + + tf_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + + # Check we can load pt model in tf and vice-versa with model => model functions + tf_model = transformers.load_pytorch_model_in_tf2_model( + tf_model, pt_model, tf_inputs=tf_inputs_dict, allow_missing_keys=allow_missing_keys + ) + pt_model = transformers.load_tf2_model_in_pytorch_model( + pt_model, tf_model, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + # Check we can load pt model in tf and vice-versa with checkpoint => model functions + with tempfile.TemporaryDirectory() as tmpdirname: + pt_checkpoint_path = os.path.join(tmpdirname, "pt_model.bin") + torch.save(pt_model.state_dict(), pt_checkpoint_path) + tf_model = transformers.load_pytorch_checkpoint_in_tf2_model( + tf_model, pt_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + tf_checkpoint_path = os.path.join(tmpdirname, "tf_model.h5") + tf_model.save_weights(tf_checkpoint_path) + pt_model = transformers.load_tf2_checkpoint_in_pytorch_model( + pt_model, tf_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + + +@require_tf +class TFHubertUtilsTest(unittest.TestCase): + def test_compute_mask_indices(self): + batch_size = 4 + sequence_length = 60 + mask_prob = 0.5 + mask_length = 1 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + + self.assertListEqual( + tf.reduce_sum(mask, -1).numpy().tolist(), [mask_prob * sequence_length for _ in range(batch_size)] + ) + + def test_compute_mask_indices_overlap(self): + batch_size = 4 + sequence_length = 80 + mask_prob = 0.5 + mask_length = 4 + + mask = _compute_mask_indices((batch_size, sequence_length), mask_prob, mask_length) + + # because of overlap mask don't have to add up exactly to `mask_prob * sequence_length`, but have to be smaller or equal + for batch_sum in tf.reduce_sum(mask, -1): + self.assertTrue(int(batch_sum) <= mask_prob * sequence_length) + + +@require_tf +@slow +@require_soundfile +class TFHubertModelIntegrationTest(unittest.TestCase): + def _load_datasamples(self, num_samples): + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") + # automatic decoding with librispeech + speech_samples = ds.sort("id").filter( + lambda x: x["id"] in [f"1272-141231-000{i}" for i in range(num_samples)] + )[:num_samples]["audio"] + + return [x["array"] for x in speech_samples] + + def test_inference_ctc_normal(self): + model = TFHubertForCTC.from_pretrained("facebook/hubert-large-ls960-ft") + processor = Wav2Vec2Processor.from_pretrained("facebook/hubert-large-ls960-ft", do_lower_case=True) + input_speech = self._load_datasamples(1) + + input_values = processor(input_speech, return_tensors="tf", sampling_rate=16000).input_values + + logits = model(input_values).logits + + predicted_ids = tf.argmax(logits, axis=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = ["a man said to the universe sir i exist"] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) + + def test_inference_ctc_normal_batched(self): + model = TFHubertForCTC.from_pretrained("facebook/hubert-large-ls960-ft") + processor = Wav2Vec2Processor.from_pretrained("facebook/hubert-large-ls960-ft", do_lower_case=True) + + input_speech = self._load_datasamples(2) + + input_values = processor(input_speech, return_tensors="tf", padding=True, sampling_rate=16000).input_values + + logits = model(input_values).logits + + predicted_ids = tf.argmax(logits, axis=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = [ + "a man said to the universe sir i exist", + "sweat covered brion's body trickling into the tight loin cloth that was the only garment he wore", + ] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) + + def test_inference_ctc_robust_batched(self): + model = TFHubertForCTC.from_pretrained("facebook/hubert-large-ls960-ft") + processor = Wav2Vec2Processor.from_pretrained("facebook/hubert-large-ls960-ft", do_lower_case=True) + + input_speech = self._load_datasamples(4) + + inputs = processor(input_speech, return_tensors="tf", padding=True, sampling_rate=16000) + + input_values = inputs.input_values + attention_mask = inputs.attention_mask + + logits = model(input_values, attention_mask=attention_mask).logits + + predicted_ids = tf.argmax(logits, axis=-1) + predicted_trans = processor.batch_decode(predicted_ids) + + EXPECTED_TRANSCRIPTIONS = [ + "a man said to the universe sir i exist", + "sweat covered brion's body trickling into the tight loin cloth that was the only garment he wore", + "the cut on his chest still dripping blood the ache of his overstrained eyes even the soaring arena around" + " him with the thousands of spectators were trivialities not worth thinking about", + "his instant of panic was followed by a small sharp blow high on his chest", + ] + self.assertListEqual(predicted_trans, EXPECTED_TRANSCRIPTIONS) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ibert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ibert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ibert/test_modeling_ibert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ibert/test_modeling_ibert.py new file mode 100644 index 0000000000000000000000000000000000000000..9f2f2c9502320299c07e02e38fd0dbf543144bed --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/ibert/test_modeling_ibert.py @@ -0,0 +1,736 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import unittest + +from transformers import IBertConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + from torch import nn + + from transformers import ( + IBERT_PRETRAINED_MODEL_ARCHIVE_LIST, + IBertForMaskedLM, + IBertForMultipleChoice, + IBertForQuestionAnswering, + IBertForSequenceClassification, + IBertForTokenClassification, + IBertModel, + ) + from transformers.models.ibert.modeling_ibert import ( + IBertEmbeddings, + IntGELU, + IntLayerNorm, + IntSoftmax, + QuantAct, + QuantEmbedding, + QuantLinear, + create_position_ids_from_input_ids, + ) + + +class IBertModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return IBertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + quant_mode=True, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 300 + return config + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = IBertModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = IBertForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = IBertForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = IBertForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = IBertForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class IBertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_pruning = False + test_torchscript = False + test_head_masking = False + test_resize_embeddings = False + + all_model_classes = ( + ( + IBertForMaskedLM, + IBertModel, + IBertForSequenceClassification, + IBertForTokenClassification, + IBertForMultipleChoice, + IBertForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": IBertModel, + "fill-mask": IBertForMaskedLM, + "question-answering": IBertForQuestionAnswering, + "text-classification": IBertForSequenceClassification, + "token-classification": IBertForTokenClassification, + "zero-shot": IBertForSequenceClassification, + } + if is_torch_available() + else {} + ) + + def setUp(self): + self.model_tester = IBertModelTester(self) + self.config_tester = ConfigTester(self, config_class=IBertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + # I-BERT only supports absolute embedding + for type in ["absolute"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in IBERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = IBertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_create_position_ids_respects_padding_index(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is IBertEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + model = IBertEmbeddings(config=config) + + input_ids = torch.as_tensor([[12, 31, 13, model.padding_idx]]) + expected_positions = torch.as_tensor( + [[0 + model.padding_idx + 1, 1 + model.padding_idx + 1, 2 + model.padding_idx + 1, model.padding_idx]] + ) + + position_ids = create_position_ids_from_input_ids(input_ids, model.padding_idx) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + def test_create_position_ids_from_inputs_embeds(self): + """Ensure that the default position ids only assign a sequential . This is a regression + test for https://github.com/huggingface/transformers/issues/1761 + + The position ids should be masked with the embedding object's padding index. Therefore, the + first available non-padding position index is IBertEmbeddings.padding_idx + 1 + """ + config = self.model_tester.prepare_config_and_inputs()[0] + embeddings = IBertEmbeddings(config=config) + + inputs_embeds = torch.empty(2, 4, 30) + expected_single_positions = [ + 0 + embeddings.padding_idx + 1, + 1 + embeddings.padding_idx + 1, + 2 + embeddings.padding_idx + 1, + 3 + embeddings.padding_idx + 1, + ] + expected_positions = torch.as_tensor([expected_single_positions, expected_single_positions]) + position_ids = embeddings.create_position_ids_from_inputs_embeds(inputs_embeds) + self.assertEqual(position_ids.shape, expected_positions.shape) + self.assertTrue(torch.all(torch.eq(position_ids, expected_positions))) + + # Override + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), QuantEmbedding) + model.set_input_embeddings(nn.Embedding(10, 10)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + # Override + def test_feed_forward_chunking(self): + pass # I-BERT does not support chunking + + # Override + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + wte = model.get_input_embeddings() + if not self.is_encoder_decoder: + embed, embed_scaling_factor = wte(input_ids) + inputs["inputs_embeds"] = embed + else: + inputs["inputs_embeds"] = wte(encoder_input_ids) + inputs["decoder_inputs_embeds"] = wte(decoder_input_ids) + + with torch.no_grad(): + model(**inputs)[0] + + +@require_torch +class IBertModelIntegrationTest(unittest.TestCase): + def test_quant_embedding(self): + weight_bit = 8 + embedding = QuantEmbedding(2, 4, quant_mode=True, weight_bit=weight_bit) + embedding_weight = torch.tensor([[-1.0, -2.0, -3.0, -4.0], [5.0, 6.0, 7.0, 8.0]]) + embedding.weight = nn.Parameter(embedding_weight) + + expected_scaling_factor = embedding_weight.abs().max() / (2 ** (weight_bit - 1) - 1) + x, x_scaling_factor = embedding(torch.tensor(0)) + y, y_scaling_factor = embedding(torch.tensor(1)) + + # scaling factor should follow the symmetric quantization rule + self.assertTrue(torch.allclose(x_scaling_factor, expected_scaling_factor, atol=1e-4)) + self.assertTrue(torch.allclose(x_scaling_factor, expected_scaling_factor, atol=1e-4)) + self.assertTrue(torch.allclose(y_scaling_factor, expected_scaling_factor, atol=1e-4)) + + # quantization error should not exceed the scaling factor + self.assertTrue(torch.allclose(x, embedding_weight[0], atol=expected_scaling_factor)) + self.assertTrue(torch.allclose(y, embedding_weight[1], atol=expected_scaling_factor)) + + def test_quant_act(self): + def _test_range(): + act = QuantAct(activation_bit, act_range_momentum, quant_mode=True) + + # First pass + x = torch.tensor([[-1.0, -2.0, -3.0, -4.0], [5.0, 6.0, 7.0, 8.0]]) + x_scaling_factor = torch.tensor(1.0) + y, y_scaling_factor = act(x, x_scaling_factor) + y_int = y / y_scaling_factor + + # After the first pass, x_min and x_max should be initialized with x.min() and x.max() + expected_x_min, expected_x_max = x.min(), x.max() + self.assertTrue(torch.allclose(act.x_min, expected_x_min, atol=1e-4)) + self.assertTrue(torch.allclose(act.x_max, expected_x_max, atol=1e-4)) + + # scaling factor should follow the symmetric quantization rule + expected_range = torch.max(expected_x_min.abs(), expected_x_max.abs()) + expected_scaling_factor = expected_range / (2 ** (activation_bit - 1) - 1) + self.assertTrue(torch.allclose(y_scaling_factor, expected_scaling_factor, atol=1e-4)) + + # quantization error should not exceed the scaling factor + self.assertTrue(torch.allclose(x, y, atol=expected_scaling_factor)) + + # output should be integer + self.assertTrue(torch.allclose(y_int, y_int.round(), atol=1e-4)) + + # Second Pass + x = torch.tensor([[-1.0, -2.0, -3.0, -4.0], [5.0, 6.0, 7.0, 8.0]]) * 2 + x_scaling_factor = torch.tensor(1.0) + y, y_scaling_factor = act(x, x_scaling_factor) + y_int = y / y_scaling_factor + + # From the second pass, x_min and x_max should be updated with moving average + expected_x_min = expected_x_min * act_range_momentum + x.min() * (1 - act_range_momentum) + expected_x_max = expected_x_max * act_range_momentum + x.max() * (1 - act_range_momentum) + self.assertTrue(torch.allclose(act.x_min, expected_x_min, atol=1e-4)) + self.assertTrue(torch.allclose(act.x_max, expected_x_max, atol=1e-4)) + + # scaling factor should follow the symmetric quantization rule + expected_range = torch.max(expected_x_min.abs(), expected_x_max.abs()) + expected_scaling_factor = expected_range / (2 ** (activation_bit - 1) - 1) + self.assertTrue(torch.allclose(y_scaling_factor, expected_scaling_factor, atol=1e-4)) + + # quantization error should not exceed the scaling factor + x = x.clamp(min=-expected_range, max=expected_range) + self.assertTrue(torch.allclose(x, y, atol=expected_scaling_factor)) + + # output should be integer + self.assertTrue(torch.allclose(y_int, y_int.round(), atol=1e-4)) + + # Third pass, with eval() + act.eval() + x = torch.tensor([[-1.0, -2.0, -3.0, -4.0], [5.0, 6.0, 7.0, 8.0]]) * 3 + + # In eval mode, min/max and scaling factor must be fixed + self.assertTrue(torch.allclose(act.x_min, expected_x_min, atol=1e-4)) + self.assertTrue(torch.allclose(act.x_max, expected_x_max, atol=1e-4)) + self.assertTrue(torch.allclose(y_scaling_factor, expected_scaling_factor, atol=1e-4)) + + def _test_identity(): + # test if identity and identity_scaling_factor are given + # should add the input values + act = QuantAct(activation_bit, act_range_momentum, quant_mode=True) + x = torch.tensor([[-1.0, -2.0, -3.0, -4.0], [5.0, 6.0, 7.0, 8.0]]) + y = torch.tensor([[6.0, -7.0, 1.0, -2.0], [3.0, -4.0, -8.0, 5.0]]) + x_scaling_factor = torch.tensor(1.0) + y_scaling_factor = torch.tensor(0.5) + z, z_scaling_factor = act(x, x_scaling_factor, y, y_scaling_factor) + z_int = z / z_scaling_factor + self.assertTrue(torch.allclose(x + y, z, atol=0.1)) + self.assertTrue(torch.allclose(z_int, z_int.round(), atol=1e-4)) + + activation_bit = 8 + act_range_momentum = 0.95 + _test_range() + _test_identity() + + def test_quant_linear(self): + def _test(per_channel): + linear_q = QuantLinear(2, 4, quant_mode=True, per_channel=per_channel, weight_bit=weight_bit) + linear_dq = QuantLinear(2, 4, quant_mode=False, per_channel=per_channel, weight_bit=weight_bit) + linear_weight = torch.tensor([[-1.0, 2.0, 3.0, -4.0], [5.0, -6.0, -7.0, 8.0]]).T + linear_q.weight = nn.Parameter(linear_weight) + linear_dq.weight = nn.Parameter(linear_weight) + + q, q_scaling_factor = linear_q(x, x_scaling_factor) + q_int = q / q_scaling_factor + dq, dq_scaling_factor = linear_dq(x, x_scaling_factor) + + if per_channel: + q_max = linear_weight.abs().max(dim=1).values + else: + q_max = linear_weight.abs().max() + expected_scaling_factor = q_max / (2 ** (weight_bit - 1) - 1) + + # scaling factor should follow the symmetric quantization rule + self.assertTrue(torch.allclose(linear_q.fc_scaling_factor, expected_scaling_factor, atol=1e-4)) + + # output of the normal linear layer and the quantized linear layer should be similar + self.assertTrue(torch.allclose(q, dq, atol=0.5)) + + # output of the quantized linear layer should be integer + self.assertTrue(torch.allclose(q_int, q_int.round(), atol=1e-4)) + + weight_bit = 8 + x = torch.tensor([[2.0, -5.0], [-3.0, 4.0]]) + x_scaling_factor = torch.tensor([1.0]) + _test(True) + _test(False) + + def test_int_gelu(self): + gelu_q = IntGELU(quant_mode=True) + gelu_dq = nn.GELU() + + x_int = torch.range(-10000, 10000, 1) + x_scaling_factor = torch.tensor(0.001) + x = x_int * x_scaling_factor + + q, q_scaling_factor = gelu_q(x, x_scaling_factor) + q_int = q / q_scaling_factor + dq = gelu_dq(x) + + # output of the normal GELU and the quantized GELU should be similar + self.assertTrue(torch.allclose(q, dq, atol=0.5)) + + # output of the quantized GELU layer should be integer + self.assertTrue(torch.allclose(q_int, q_int.round(), atol=1e-4)) + + def test_force_dequant_gelu(self): + x_int = torch.range(-10000, 10000, 1) + x_scaling_factor = torch.tensor(0.001) + x = x_int * x_scaling_factor + + gelu_dq = IntGELU(quant_mode=False) + gelu_fdqs_dict = { + True: [ + IntGELU(quant_mode=True, force_dequant="nonlinear"), + IntGELU(quant_mode=True, force_dequant="gelu"), + ], + False: [ + IntGELU(quant_mode=True, force_dequant="none"), + IntGELU(quant_mode=True, force_dequant="softmax"), + IntGELU(quant_mode=True, force_dequant="layernorm"), + ], + } + + dq, dq_scaling_factor = gelu_dq(x, x_scaling_factor) + for label, gelu_fdqs in gelu_fdqs_dict.items(): + for gelu_fdq in gelu_fdqs: + q, q_scaling_factor = gelu_fdq(x, x_scaling_factor) + if label: + self.assertTrue(torch.allclose(q, dq, atol=1e-4)) + else: + self.assertFalse(torch.allclose(q, dq, atol=1e-4)) + + def test_int_softmax(self): + output_bit = 8 + softmax_q = IntSoftmax(output_bit, quant_mode=True) + softmax_dq = nn.Softmax() + + # x_int = torch.range(-10000, 10000, 1) + def _test(array): + x_int = torch.tensor(array) + x_scaling_factor = torch.tensor(0.1) + x = x_int * x_scaling_factor + + q, q_scaling_factor = softmax_q(x, x_scaling_factor) + q_int = q / q_scaling_factor + dq = softmax_dq(x) + + # output of the normal Softmax and the quantized Softmax should be similar + self.assertTrue(torch.allclose(q, dq, atol=0.5)) + + # output of the quantized GELU layer should be integer + self.assertTrue(torch.allclose(q_int, q_int.round(), atol=1e-4)) + + # Output of the quantize Softmax should not exceed the output_bit + self.assertTrue(q.abs().max() < 2**output_bit) + + array = [[i + j for j in range(10)] for i in range(-10, 10)] + _test(array) + array = [[i + j for j in range(50)] for i in range(-10, 10)] + _test(array) + array = [[i + 100 * j for j in range(2)] for i in range(-10, 10)] + _test(array) + + def test_force_dequant_softmax(self): + output_bit = 8 + array = [[i + j for j in range(10)] for i in range(-10, 10)] + x_int = torch.tensor(array) + x_scaling_factor = torch.tensor(0.1) + x = x_int * x_scaling_factor + + softmax_dq = IntSoftmax(output_bit, quant_mode=False) + softmax_fdqs_dict = { + True: [ + IntSoftmax(output_bit, quant_mode=True, force_dequant="nonlinear"), + IntSoftmax(output_bit, quant_mode=True, force_dequant="softmax"), + ], + False: [ + IntSoftmax(output_bit, quant_mode=True, force_dequant="none"), + IntSoftmax(output_bit, quant_mode=True, force_dequant="gelu"), + IntSoftmax(output_bit, quant_mode=True, force_dequant="layernorm"), + ], + } + + dq, dq_scaling_factor = softmax_dq(x, x_scaling_factor) + for label, softmax_fdqs in softmax_fdqs_dict.items(): + for softmax_fdq in softmax_fdqs: + q, q_scaling_factor = softmax_fdq(x, x_scaling_factor) + if label: + self.assertTrue(torch.allclose(q, dq, atol=1e-4)) + else: + self.assertFalse(torch.allclose(q, dq, atol=1e-4)) + + def test_int_layernorm(self): + output_bit = 8 + + # some random matrix + array = [[[i * j * j + j for j in range(5, 15)]] for i in range(-10, 10)] + x_int = torch.tensor(array) + x_scaling_factor = torch.tensor(0.1) + x = x_int * x_scaling_factor + + ln_q = IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit) + ln_dq = nn.LayerNorm(x.shape[1:], 1e-5) + + ln_q.weight = nn.Parameter(torch.ones(x.shape[1:])) + ln_q.bias = nn.Parameter(torch.ones(x.shape[1:])) + ln_dq.weight = nn.Parameter(torch.ones(x.shape[1:])) + ln_dq.bias = nn.Parameter(torch.ones(x.shape[1:])) + + q, q_scaling_factor = ln_q(x, x_scaling_factor) + q_int = q / q_scaling_factor + dq = ln_dq(x) + + # output of the normal LN and the quantized LN should be similar + self.assertTrue(torch.allclose(q, dq, atol=0.5)) + + # output of the quantized GELU layer should be integer + self.assertTrue(torch.allclose(q_int, q_int.round(), atol=1e-4)) + + def test_force_dequant_layernorm(self): + output_bit = 8 + array = [[[i * j * j + j for j in range(5, 15)]] for i in range(-10, 10)] + x_int = torch.tensor(array) + x_scaling_factor = torch.tensor(0.1) + x = x_int * x_scaling_factor + + ln_dq = IntLayerNorm(x.shape[1:], 1e-5, quant_mode=False, output_bit=output_bit) + ln_fdqs_dict = { + True: [ + IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit, force_dequant="nonlinear"), + IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit, force_dequant="layernorm"), + ], + False: [ + IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit, force_dequant="none"), + IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit, force_dequant="gelu"), + IntLayerNorm(x.shape[1:], 1e-5, quant_mode=True, output_bit=output_bit, force_dequant="softmax"), + ], + } + + ln_dq.weight = nn.Parameter(torch.ones(x.shape[1:])) + ln_dq.bias = nn.Parameter(torch.ones(x.shape[1:])) + dq, dq_scaling_factor = ln_dq(x, x_scaling_factor) + for label, ln_fdqs in ln_fdqs_dict.items(): + for ln_fdq in ln_fdqs: + ln_fdq.weight = nn.Parameter(torch.ones(x.shape[1:])) + ln_fdq.bias = nn.Parameter(torch.ones(x.shape[1:])) + q, q_scaling_factor = ln_fdq(x, x_scaling_factor) + if label: + self.assertTrue(torch.allclose(q, dq, atol=1e-4)) + else: + self.assertFalse(torch.allclose(q, dq, atol=1e-4)) + + def quantize(self, model): + # Helper function that quantizes the given model + # Recursively convert all the `quant_mode` attributes as `True` + if hasattr(model, "quant_mode"): + model.quant_mode = True + elif type(model) == nn.Sequential: + for n, m in model.named_children(): + self.quantize(m) + elif type(model) == nn.ModuleList: + for n in model: + self.quantize(n) + else: + for attr in dir(model): + mod = getattr(model, attr) + if isinstance(mod, nn.Module) and mod != model: + self.quantize(mod) + + @slow + def test_inference_masked_lm(self): + # I-BERT should be "equivalent" to RoBERTa if not quantized + # Test coped from `test_modeling_roberta.py` + model = IBertForMaskedLM.from_pretrained("kssteven/ibert-roberta-base") + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + output = model(input_ids)[0] + expected_shape = torch.Size((1, 11, 50265)) + self.assertEqual(output.shape, expected_shape) + expected_slice = torch.tensor( + [[[33.8802, -4.3103, 22.7761], [4.6539, -2.8098, 13.6253], [1.8228, -3.6898, 8.8600]]] + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) + + # I-BERT should be "similar" to RoBERTa if quantized + self.quantize(model) + output = model(input_ids)[0] + self.assertEqual(output.shape, expected_shape) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=0.1)) + + @slow + def test_inference_classification_head(self): + # I-BERT should be "equivalent" to RoBERTa if not quantized + # Test coped from `test_modeling_roberta.py` + model = IBertForSequenceClassification.from_pretrained("kssteven/ibert-roberta-large-mnli") + input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]]) + output = model(input_ids)[0] + expected_shape = torch.Size((1, 3)) + self.assertEqual(output.shape, expected_shape) + expected_tensor = torch.tensor([[-0.9469, 0.3913, 0.5118]]) + self.assertTrue(torch.allclose(output, expected_tensor, atol=1e-4)) + + # I-BERT should be "similar" to RoBERTa if quantized + self.quantize(model) + output = model(input_ids)[0] + self.assertEqual(output.shape, expected_shape) + self.assertTrue(torch.allclose(output, expected_tensor, atol=0.1)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_image_processing_imagegpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_image_processing_imagegpt.py new file mode 100644 index 0000000000000000000000000000000000000000..b0a2d5ceb0a3bdaeb47953455a595eebfec18c9c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_image_processing_imagegpt.py @@ -0,0 +1,184 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import tempfile +import unittest + +import numpy as np +from datasets import load_dataset + +from transformers.testing_utils import require_torch, require_vision, slow +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import ImageGPTImageProcessor + + +class ImageGPTImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_normalize=True, + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_normalize = do_normalize + + def prepare_image_processor_dict(self): + return { + # here we create 2 clusters for the sake of simplicity + "clusters": np.asarray( + [ + [0.8866443634033203, 0.6618829369544983, 0.3891746401786804], + [-0.6042559146881104, -0.02295008860528469, 0.5423797369003296], + ] + ), + "do_resize": self.do_resize, + "size": self.size, + "do_normalize": self.do_normalize, + } + + +@require_torch +@require_vision +class ImageGPTImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = ImageGPTImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = ImageGPTImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "clusters")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + def test_image_processor_to_json_string(self): + image_processor = self.image_processing_class(**self.image_processor_dict) + obj = json.loads(image_processor.to_json_string()) + for key, value in self.image_processor_dict.items(): + if key == "clusters": + self.assertTrue(np.array_equal(value, obj[key])) + else: + self.assertEqual(obj[key], value) + + def test_image_processor_to_json_file(self): + image_processor_first = self.image_processing_class(**self.image_processor_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + json_file_path = os.path.join(tmpdirname, "image_processor.json") + image_processor_first.to_json_file(json_file_path) + image_processor_second = self.image_processing_class.from_json_file(json_file_path).to_dict() + + image_processor_first = image_processor_first.to_dict() + for key, value in image_processor_first.items(): + if key == "clusters": + self.assertTrue(np.array_equal(value, image_processor_second[key])) + else: + self.assertEqual(image_processor_first[key], value) + + def test_image_processor_from_and_save_pretrained(self): + image_processor_first = self.image_processing_class(**self.image_processor_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + image_processor_first.save_pretrained(tmpdirname) + image_processor_second = self.image_processing_class.from_pretrained(tmpdirname).to_dict() + + image_processor_first = image_processor_first.to_dict() + for key, value in image_processor_first.items(): + if key == "clusters": + self.assertTrue(np.array_equal(value, image_processor_second[key])) + else: + self.assertEqual(image_processor_first[key], value) + + @unittest.skip("ImageGPT requires clusters at initialization") + def test_init_without_params(self): + pass + + +def prepare_images(): + dataset = load_dataset("hf-internal-testing/fixtures_image_utils", split="test") + + image1 = Image.open(dataset[4]["file"]) + image2 = Image.open(dataset[5]["file"]) + + images = [image1, image2] + + return images + + +@require_vision +@require_torch +class ImageGPTImageProcessorIntegrationTest(unittest.TestCase): + @slow + def test_image(self): + image_processing = ImageGPTImageProcessor.from_pretrained("openai/imagegpt-small") + + images = prepare_images() + + # test non-batched + encoding = image_processing(images[0], return_tensors="pt") + + self.assertIsInstance(encoding.input_ids, torch.LongTensor) + self.assertEqual(encoding.input_ids.shape, (1, 1024)) + + expected_slice = [306, 191, 191] + self.assertEqual(encoding.input_ids[0, :3].tolist(), expected_slice) + + # test batched + encoding = image_processing(images, return_tensors="pt") + + self.assertIsInstance(encoding.input_ids, torch.LongTensor) + self.assertEqual(encoding.input_ids.shape, (2, 1024)) + + expected_slice = [303, 13, 13] + self.assertEqual(encoding.input_ids[1, -3:].tolist(), expected_slice) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_modeling_imagegpt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_modeling_imagegpt.py new file mode 100644 index 0000000000000000000000000000000000000000..e6c8524c6d6f2b4d980bec42068007825efbd7d7 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/imagegpt/test_modeling_imagegpt.py @@ -0,0 +1,557 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import inspect +import os +import tempfile +import unittest + +from transformers import ImageGPTConfig +from transformers.testing_utils import require_torch, require_vision, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ( + ModelTesterMixin, + _config_zero_init, + floats_tensor, + ids_tensor, + random_attention_mask, +) +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + IMAGEGPT_PRETRAINED_MODEL_ARCHIVE_LIST, + ImageGPTForCausalImageModeling, + ImageGPTForImageClassification, + ImageGPTModel, + ) + +if is_vision_available(): + from PIL import Image + + from transformers import ImageGPTFeatureExtractor + + +class ImageGPTModelTester: + def __init__( + self, + parent, + batch_size=14, + seq_length=7, + is_training=True, + use_token_type_ids=True, + use_input_mask=True, + use_labels=True, + use_mc_token_ids=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_token_type_ids = use_token_type_ids + self.use_input_mask = use_input_mask + self.use_labels = use_labels + self.use_mc_token_ids = use_mc_token_ids + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = None + + def get_large_model_config(self): + return ImageGPTConfig.from_pretrained("imagegpt") + + def prepare_config_and_inputs( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + pixel_values = ids_tensor([self.batch_size, self.seq_length], self.vocab_size - 1) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + mc_token_ids = None + if self.use_mc_token_ids: + mc_token_ids = ids_tensor([self.batch_size, self.num_choices], self.seq_length) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config( + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + ) + + head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2) + + return ( + config, + pixel_values, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) + + def get_config( + self, gradient_checkpointing=False, scale_attn_by_inverse_layer_idx=False, reorder_and_upcast_attn=False + ): + return ImageGPTConfig( + vocab_size=self.vocab_size, + n_embd=self.hidden_size, + n_layer=self.num_hidden_layers, + n_head=self.num_attention_heads, + n_inner=self.intermediate_size, + activation_function=self.hidden_act, + resid_pdrop=self.hidden_dropout_prob, + attn_pdrop=self.attention_probs_dropout_prob, + n_positions=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + use_cache=True, + gradient_checkpointing=gradient_checkpointing, + scale_attn_by_inverse_layer_idx=scale_attn_by_inverse_layer_idx, + reorder_and_upcast_attn=reorder_and_upcast_attn, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.vocab_size = 513 + config.max_position_embeddings = 1024 + return config + + def prepare_config_and_inputs_for_decoder(self): + ( + config, + pixel_values, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = self.prepare_config_and_inputs() + + encoder_hidden_states = floats_tensor([self.batch_size, self.seq_length, self.hidden_size]) + encoder_attention_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + return ( + config, + pixel_values, + input_mask, + head_mask, + token_type_ids, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ) + + def create_and_check_imagegpt_model(self, config, pixel_values, input_mask, head_mask, token_type_ids, *args): + model = ImageGPTModel(config=config) + model.to(torch_device) + model.eval() + + result = model(pixel_values, token_type_ids=token_type_ids, head_mask=head_mask) + result = model(pixel_values, token_type_ids=token_type_ids) + result = model(pixel_values) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(len(result.past_key_values), config.n_layer) + + def create_and_check_lm_head_model(self, config, pixel_values, input_mask, head_mask, token_type_ids, *args): + model = ImageGPTForCausalImageModeling(config) + model.to(torch_device) + model.eval() + + labels = ids_tensor([self.batch_size, self.seq_length], self.vocab_size - 1) + result = model(pixel_values, token_type_ids=token_type_ids, labels=labels) + self.parent.assertEqual(result.loss.shape, ()) + # ImageGPTForCausalImageModeling doens't have tied input- and output embeddings + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size - 1)) + + def create_and_check_imagegpt_for_image_classification( + self, config, pixel_values, input_mask, head_mask, token_type_ids, mc_token_ids, sequence_labels, *args + ): + config.num_labels = self.num_labels + model = ImageGPTForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + + ( + config, + pixel_values, + input_mask, + head_mask, + token_type_ids, + mc_token_ids, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + inputs_dict = { + "pixel_values": pixel_values, + "token_type_ids": token_type_ids, + "head_mask": head_mask, + } + + return config, inputs_dict + + +@require_torch +class ImageGPTModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + (ImageGPTForCausalImageModeling, ImageGPTForImageClassification, ImageGPTModel) if is_torch_available() else () + ) + all_generative_model_classes = (ImageGPTForCausalImageModeling,) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": ImageGPTModel, "image-classification": ImageGPTForImageClassification} + if is_torch_available() + else {} + ) + test_missing_keys = False + input_name = "pixel_values" + + # as ImageGPTForImageClassification isn't included in any auto mapping, we add labels here + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "ImageGPTForImageClassification": + inputs_dict["labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + + return inputs_dict + + # we overwrite the _check_scores method of GenerationTesterMixin, as ImageGPTForCausalImageModeling doesn't have tied input- and output embeddings + def _check_scores(self, batch_size, scores, length, config): + expected_shape = (batch_size, config.vocab_size - 1) + self.assertIsInstance(scores, tuple) + self.assertEqual(len(scores), length) + self.assertListEqual([iter_scores.shape for iter_scores in scores], [expected_shape] * len(scores)) + + def setUp(self): + self.model_tester = ImageGPTModelTester(self) + self.config_tester = ConfigTester(self, config_class=ImageGPTConfig, n_embd=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_imagegpt_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_imagegpt_model(*config_and_inputs) + + def test_imagegpt_causal_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lm_head_model(*config_and_inputs) + + def test_imagegpt_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_imagegpt_for_image_classification(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in IMAGEGPT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = ImageGPTModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["input_ids"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_resize_tokens_embeddings(self): + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + if not self.test_resize_embeddings: + return + + for model_class in self.all_model_classes: + config = copy.deepcopy(original_config) + model = model_class(config) + model.to(torch_device) + + if self.model_tester.is_training is False: + model.eval() + + model_vocab_size = config.vocab_size + # Retrieve the embeddings and clone theme + model_embed = model.resize_token_embeddings(model_vocab_size) + cloned_embeddings = model_embed.weight.clone() + + # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size + model_embed = model.resize_token_embeddings(model_vocab_size + 10) + self.assertEqual(model.config.vocab_size, model_vocab_size + 10) + # Check that it actually resizes the embeddings matrix + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] + 10) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that resizing the token embeddings with a smaller vocab size decreases the model's vocab size + model_embed = model.resize_token_embeddings(model_vocab_size - 15) + self.assertEqual(model.config.vocab_size, model_vocab_size - 15) + # Check that it actually resizes the embeddings matrix + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] - 15) + + # Check that the model can still do a forward pass successfully (every parameter should be resized) + # Input ids should be clamped to the maximum size of the vocabulary + inputs_dict["pixel_values"].clamp_(max=model_vocab_size - 15 - 1) + + # Check that adding and removing tokens has not modified the first part of the embedding matrix. + models_equal = True + for p1, p2 in zip(cloned_embeddings, model_embed.weight): + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_resize_embeddings_untied(self): + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + if not self.test_resize_embeddings: + return + + original_config.tie_word_embeddings = False + + # if model cannot untied embeddings -> leave test + if original_config.tie_word_embeddings: + return + + for model_class in self.all_model_classes: + config = copy.deepcopy(original_config) + model = model_class(config).to(torch_device) + + # if no output embeddings -> leave test + if model.get_output_embeddings() is None: + continue + + # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size + model_vocab_size = config.vocab_size + model.resize_token_embeddings(model_vocab_size + 10) + self.assertEqual(model.config.vocab_size, model_vocab_size + 10) + output_embeds = model.get_output_embeddings() + self.assertEqual(output_embeds.weight.shape[0], model_vocab_size + 10) + # Check bias if present + if output_embeds.bias is not None: + self.assertEqual(output_embeds.bias.shape[0], model_vocab_size + 10) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that resizing the token embeddings with a smaller vocab size decreases the model's vocab size + model.resize_token_embeddings(model_vocab_size - 15) + self.assertEqual(model.config.vocab_size, model_vocab_size - 15) + # Check that it actually resizes the embeddings matrix + output_embeds = model.get_output_embeddings() + self.assertEqual(output_embeds.weight.shape[0], model_vocab_size - 15) + # Check bias if present + if output_embeds.bias is not None: + self.assertEqual(output_embeds.bias.shape[0], model_vocab_size - 15) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + # Input ids should be clamped to the maximum size of the vocabulary + inputs_dict["pixel_values"].clamp_(max=model_vocab_size - 15 - 1) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + pixel_values = inputs["pixel_values"] + del inputs["pixel_values"] + + wte = model.get_input_embeddings() + inputs["inputs_embeds"] = wte(pixel_values) + + with torch.no_grad(): + model(**inputs)[0] + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + inputs = self._prepare_for_class(inputs_dict, model_class) + + try: + pixel_values = inputs["pixel_values"] + traced_model = torch.jit.trace(model, pixel_values) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + non_persistent_buffers = {} + for key in loaded_model_state_dict.keys(): + if key not in model_state_dict.keys(): + non_persistent_buffers[key] = loaded_model_state_dict[key] + + loaded_model_state_dict = { + key: value for key, value in loaded_model_state_dict.items() if key not in non_persistent_buffers + } + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + model_buffers = list(model.buffers()) + for non_persistent_buffer in non_persistent_buffers.values(): + found_buffer = False + for i, model_buffer in enumerate(model_buffers): + if torch.equal(non_persistent_buffer, model_buffer): + found_buffer = True + break + + self.assertTrue(found_buffer) + model_buffers.pop(i) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + if layer_name in loaded_model_state_dict: + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class ImageGPTModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return ImageGPTFeatureExtractor.from_pretrained("openai/imagegpt-small") if is_vision_available() else None + + @slow + def test_inference_causal_lm_head(self): + model = ImageGPTForCausalImageModeling.from_pretrained("openai/imagegpt-small").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1024, 512)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor( + [[2.3445, 2.6889, 2.7313], [1.0530, 1.2416, 0.5699], [0.2205, 0.7749, 0.3953]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/informer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/informer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/informer/test_modeling_informer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/informer/test_modeling_informer.py new file mode 100644 index 0000000000000000000000000000000000000000..493846b6708b8297a0caf32aad482a642df21d82 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/informer/test_modeling_informer.py @@ -0,0 +1,513 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Informer model. """ + +import inspect +import tempfile +import unittest + +import numpy as np +from huggingface_hub import hf_hub_download + +from transformers import is_torch_available +from transformers.testing_utils import is_flaky, require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +TOLERANCE = 1e-4 + +if is_torch_available(): + import torch + + from transformers import InformerConfig, InformerForPrediction, InformerModel + from transformers.models.informer.modeling_informer import InformerDecoder, InformerEncoder + + +@require_torch +class InformerModelTester: + def __init__( + self, + parent, + batch_size=13, + prediction_length=7, + context_length=14, + cardinality=19, + embedding_dimension=5, + num_time_features=4, + is_training=True, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + lags_sequence=[1, 2, 3, 4, 5], + sampling_factor=10, + distil=False, + ): + self.parent = parent + self.batch_size = batch_size + self.prediction_length = prediction_length + self.context_length = context_length + self.cardinality = cardinality + self.num_time_features = num_time_features + self.lags_sequence = lags_sequence + self.embedding_dimension = embedding_dimension + self.is_training = is_training + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + + self.encoder_seq_length = min( + sampling_factor * np.ceil(np.log1p(context_length)).astype("int").item(), context_length + ) + self.decoder_seq_length = min( + sampling_factor * np.ceil(np.log1p(prediction_length)).astype("int").item(), prediction_length + ) + self.sampling_factor = sampling_factor + self.distil = distil + + def get_config(self): + return InformerConfig( + prediction_length=self.prediction_length, + 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, + context_length=self.context_length, + lags_sequence=self.lags_sequence, + num_time_features=self.num_time_features, + num_static_categorical_features=1, + num_static_real_features=1, + cardinality=[self.cardinality], + embedding_dimension=[self.embedding_dimension], + sampling_factor=self.sampling_factor, + distil=self.distil, + ) + + def prepare_informer_inputs_dict(self, config): + _past_length = config.context_length + max(config.lags_sequence) + + static_categorical_features = ids_tensor([self.batch_size, 1], config.cardinality[0]) + static_real_features = floats_tensor([self.batch_size, 1]) + + past_time_features = floats_tensor([self.batch_size, _past_length, config.num_time_features]) + past_values = floats_tensor([self.batch_size, _past_length]) + past_observed_mask = floats_tensor([self.batch_size, _past_length]) > 0.5 + + # decoder inputs + future_time_features = floats_tensor([self.batch_size, config.prediction_length, config.num_time_features]) + future_values = floats_tensor([self.batch_size, config.prediction_length]) + + inputs_dict = { + "past_values": past_values, + "static_categorical_features": static_categorical_features, + "static_real_features": static_real_features, + "past_time_features": past_time_features, + "past_observed_mask": past_observed_mask, + "future_time_features": future_time_features, + "future_values": future_values, + } + return inputs_dict + + def prepare_config_and_inputs(self): + config = self.get_config() + inputs_dict = self.prepare_informer_inputs_dict(config) + return config, inputs_dict + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + def check_encoder_decoder_model_standalone(self, config, inputs_dict): + model = InformerModel(config=config).to(torch_device).eval() + outputs = model(**inputs_dict) + + encoder_last_hidden_state = outputs.encoder_last_hidden_state + last_hidden_state = outputs.last_hidden_state + + with tempfile.TemporaryDirectory() as tmpdirname: + encoder = model.get_encoder() + encoder.save_pretrained(tmpdirname) + encoder = InformerEncoder.from_pretrained(tmpdirname).to(torch_device) + + transformer_inputs, _, _, _ = model.create_network_inputs(**inputs_dict) + enc_input = transformer_inputs[:, : config.context_length, ...] + dec_input = transformer_inputs[:, config.context_length :, ...] + + encoder_last_hidden_state_2 = encoder(inputs_embeds=enc_input)[0] + + self.parent.assertTrue((encoder_last_hidden_state_2 - encoder_last_hidden_state).abs().max().item() < 1e-3) + + with tempfile.TemporaryDirectory() as tmpdirname: + decoder = model.get_decoder() + decoder.save_pretrained(tmpdirname) + decoder = InformerDecoder.from_pretrained(tmpdirname).to(torch_device) + + last_hidden_state_2 = decoder( + inputs_embeds=dec_input, + encoder_hidden_states=encoder_last_hidden_state, + )[0] + + self.parent.assertTrue((last_hidden_state_2 - last_hidden_state).abs().max().item() < 1e-3) + + +@require_torch +class InformerModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (InformerModel, InformerForPrediction) if is_torch_available() else () + all_generative_model_classes = (InformerForPrediction,) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": InformerModel} if is_torch_available() else {} + is_encoder_decoder = True + test_pruning = False + test_head_masking = False + test_missing_keys = False + test_torchscript = False + test_inputs_embeds = False + test_model_common_attributes = False + + def setUp(self): + self.model_tester = InformerModelTester(self) + self.config_tester = ConfigTester( + self, + config_class=InformerConfig, + has_text_modality=False, + prediction_length=self.model_tester.prediction_length, + ) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_save_load_strict(self): + config, _ = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + def test_encoder_decoder_model_standalone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_encoder_decoder_model_standalone(*config_and_inputs) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + if hasattr(self.model_tester, "encoder_seq_length"): + seq_length = self.model_tester.context_length + if hasattr(self.model_tester, "chunk_length") and self.model_tester.chunk_length > 1: + seq_length = seq_length * self.model_tester.chunk_length + else: + seq_length = self.model_tester.seq_length + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + if config.is_encoder_decoder: + hidden_states = outputs.decoder_hidden_states + + self.assertIsInstance(hidden_states, (list, tuple)) + self.assertEqual(len(hidden_states), expected_num_layers) + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "prediction_length", seq_len) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [decoder_seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + # Ignore since we have no tokens embeddings + def test_resize_tokens_embeddings(self): + pass + + def test_model_outputs_equivalence(self): + pass + + def test_determinism(self): + pass + + # # Input is 'static_categorical_features' not 'input_ids' + def test_model_main_input_name(self): + model_signature = inspect.signature(getattr(InformerModel, "forward")) + # The main input is the name of the argument after `self` + observed_main_input_name = list(model_signature.parameters.keys())[1] + self.assertEqual(InformerModel.main_input_name, observed_main_input_name) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = [ + "past_values", + "past_time_features", + "past_observed_mask", + "static_categorical_features", + "static_real_features", + "future_values", + "future_time_features", + ] + + expected_arg_names.extend( + [ + "future_observed_mask", + "decoder_attention_mask", + "head_mask", + "decoder_head_mask", + "cross_attn_head_mask", + "encoder_outputs", + "past_key_values", + "output_hidden_states", + "output_attentions", + "use_cache", + "return_dict", + ] + if "future_observed_mask" in arg_names + else [ + "decoder_attention_mask", + "head_mask", + "decoder_head_mask", + "cross_attn_head_mask", + "encoder_outputs", + "past_key_values", + "output_hidden_states", + "output_attentions", + "use_cache", + "return_dict", + ] + ) + + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + context_length = getattr(self.model_tester, "context_length", seq_len) + prediction_length = getattr(self.model_tester, "prediction_length", seq_len) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, context_length], + ) + out_len = len(outputs) + + correct_outlen = 7 + + if "last_hidden_state" in outputs: + correct_outlen += 1 + + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + if "loss" in outputs: + correct_outlen += 1 + + if "params" in outputs: + correct_outlen += 1 + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, prediction_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_seq_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + self.assertEqual(out_len + 2, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, context_length], + ) + + @is_flaky() + def test_retain_grad_hidden_states_attentions(self): + super().test_retain_grad_hidden_states_attentions() + + +def prepare_batch(filename="train-batch.pt"): + file = hf_hub_download(repo_id="kashif/tourism-monthly-batch", filename=filename, repo_type="dataset") + batch = torch.load(file, map_location=torch_device) + return batch + + +@require_torch +@slow +class InformerModelIntegrationTests(unittest.TestCase): + def test_inference_no_head(self): + model = InformerModel.from_pretrained("huggingface/informer-tourism-monthly").to(torch_device) + batch = prepare_batch() + + torch.manual_seed(0) + with torch.no_grad(): + output = model( + past_values=batch["past_values"], + past_time_features=batch["past_time_features"], + past_observed_mask=batch["past_observed_mask"], + static_categorical_features=batch["static_categorical_features"], + future_values=batch["future_values"], + future_time_features=batch["future_time_features"], + ).last_hidden_state + expected_shape = torch.Size((64, model.config.context_length, model.config.d_model)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[0.4699, 0.7295, 0.8967], [0.4858, 0.3810, 0.9641], [-0.0233, 0.3608, 1.0303]], + device=torch_device, + ) + self.assertTrue(torch.allclose(output[0, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_inference_head(self): + model = InformerForPrediction.from_pretrained("huggingface/informer-tourism-monthly").to(torch_device) + batch = prepare_batch("val-batch.pt") + + torch.manual_seed(0) + with torch.no_grad(): + output = model( + past_values=batch["past_values"], + past_time_features=batch["past_time_features"], + past_observed_mask=batch["past_observed_mask"], + static_categorical_features=batch["static_categorical_features"], + future_time_features=batch["future_time_features"], + ).encoder_last_hidden_state + + # encoder distils the context length to 1/8th of the original length + expected_shape = torch.Size((64, model.config.context_length // 8, model.config.d_model)) + self.assertEqual(output.shape, expected_shape) + + expected_slice = torch.tensor( + [[0.4170, 0.9067, 0.8153], [0.3004, 0.7574, 0.7066], [0.6803, -0.6323, 1.2802]], device=torch_device + ) + self.assertTrue(torch.allclose(output[0, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_seq_to_seq_generation(self): + model = InformerForPrediction.from_pretrained("huggingface/informer-tourism-monthly").to(torch_device) + batch = prepare_batch("val-batch.pt") + + torch.manual_seed(0) + with torch.no_grad(): + outputs = model.generate( + static_categorical_features=batch["static_categorical_features"], + past_time_features=batch["past_time_features"], + past_values=batch["past_values"], + future_time_features=batch["future_time_features"], + past_observed_mask=batch["past_observed_mask"], + ) + expected_shape = torch.Size((64, model.config.num_parallel_samples, model.config.prediction_length)) + self.assertEqual(outputs.sequences.shape, expected_shape) + + expected_slice = torch.tensor([3400.8005, 4289.2637, 7101.9209], device=torch_device) + mean_prediction = outputs.sequences.mean(dim=1) + self.assertTrue(torch.allclose(mean_prediction[0, -3:], expected_slice, rtol=1e-1)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_modeling_jukebox.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_modeling_jukebox.py new file mode 100644 index 0000000000000000000000000000000000000000..93de8871567119d61fc351e7b08c80dae2dcc129 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_modeling_jukebox.py @@ -0,0 +1,396 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest +from unittest import skip + +from transformers import is_torch_available +from transformers.testing_utils import require_torch, slow +from transformers.trainer_utils import set_seed + + +if is_torch_available(): + import torch + + from transformers import JukeboxModel, JukeboxPrior, JukeboxTokenizer + + +@require_torch +class Jukebox1bModelTester(unittest.TestCase): + all_model_classes = (JukeboxModel,) if is_torch_available() else () + model_id = "openai/jukebox-1b-lyrics" + metas = { + "artist": "Zac Brown Band", + "genres": "Country", + "lyrics": """I met a traveller from an antique land, + Who said "Two vast and trunkless legs of stone + Stand in the desert. . . . Near them, on the sand, + Half sunk a shattered visage lies, whose frown, + And wrinkled lip, and sneer of cold command, + Tell that its sculptor well those passions read + Which yet survive, stamped on these lifeless things, + The hand that mocked them, and the heart that fed; + And on the pedestal, these words appear: + My name is Ozymandias, King of Kings; + Look on my Works, ye Mighty, and despair! + Nothing beside remains. Round the decay + Of that colossal Wreck, boundless and bare + The lone and level sands stretch far away + """, + } + # fmt: off + EXPECTED_OUTPUT_2 = [ + 1864, 1536, 1213, 1870, 1357, 1536, 519, 880, 1323, 789, 1082, 534, + 1000, 1445, 1105, 1130, 967, 515, 1434, 1620, 534, 1495, 283, 1445, + 333, 1307, 539, 1631, 1528, 375, 1434, 673, 627, 710, 778, 1883, + 1405, 1276, 1455, 1228 + ] + + EXPECTED_OUTPUT_2_PT_2 = [ + 1489, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653 + ] + + EXPECTED_OUTPUT_1 = [ + 1125, 1751, 697, 1776, 1141, 1476, 391, 697, 1125, 684, 867, 416, + 844, 1372, 1274, 717, 1274, 844, 1299, 1419, 697, 1370, 317, 1125, + 191, 1440, 1370, 1440, 1370, 282, 1621, 1370, 368, 349, 867, 1872, + 1262, 869, 1728, 747 + ] + EXPECTED_OUTPUT_1_PT_2 = [ + 416, 416, 1125, 1125, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416 + ] + + EXPECTED_OUTPUT_0 = [ + 1755, 842, 307, 1843, 1022, 1395, 234, 1554, 806, 739, 1022, 442, + 616, 556, 268, 1499, 933, 457, 1440, 1837, 755, 985, 308, 902, + 293, 1443, 1671, 1141, 1533, 555, 1562, 1061, 287, 417, 1022, 2008, + 1186, 1015, 1777, 268 + ] + EXPECTED_OUTPUT_0_PT_2 = [ + 854, 842, 1353, 114, 1353, 842, 185, 842, 185, 114, 591, 842, + 185, 417, 185, 842, 307, 842, 591, 842, 185, 842, 307, 842, + 591, 842, 1353, 842, 185, 842, 591, 842, 591, 114, 591, 842, + 185, 842, 591, 89 + ] + + EXPECTED_Y_COND = [1058304, 0, 786432, 7169, 507, 76, 27, 40, 30, 76] + + EXPECTED_PRIMED_0 = [ + 390, 1160, 1002, 1907, 1788, 1788, 1788, 1907, 1002, 1002, 1854, 1002, + 1002, 1002, 1002, 1002, 1002, 1160, 1160, 1606, 596, 596, 1160, 1002, + 1516, 596, 1002, 1002, 1002, 1907, 1788, 1788, 1788, 1854, 1788, 1907, + 1907, 1788, 596, 1626 + ] + EXPECTED_PRIMED_1 = [ + 1236, 1668, 1484, 1920, 1848, 1409, 139, 864, 1828, 1272, 1599, 824, + 1672, 139, 555, 1484, 824, 1920, 555, 596, 1579, 1599, 1231, 1599, + 1637, 1407, 212, 824, 1599, 116, 1433, 824, 258, 1599, 1433, 1895, + 1063, 1433, 1433, 1599 + ] + EXPECTED_PRIMED_2 = [ + 1684, 1873, 1119, 1189, 395, 611, 1901, 972, 890, 1337, 1392, 1927, + 96, 972, 672, 780, 1119, 890, 158, 771, 1073, 1927, 353, 1331, + 1269, 1459, 1333, 1645, 812, 1577, 1337, 606, 353, 981, 1466, 619, + 197, 391, 302, 1930 + ] + EXPECTED_VQVAE_ENCODE = [ + 390, 1160, 1002, 1907, 1788, 1788, 1788, 1907, 1002, 1002, 1854, 1002, + 1002, 1002, 1002, 1002, 1002, 1160, 1160, 1606, 596, 596, 1160, 1002, + 1516, 596, 1002, 1002, 1002, 1907, 1788, 1788, 1788, 1854, 1788, 1907, + 1907, 1788, 596, 1626 + ] + EXPECTED_VQVAE_DECODE = [ + -0.0492, -0.0524, -0.0565, -0.0640, -0.0686, -0.0684, -0.0677, -0.0664, + -0.0605, -0.0490, -0.0330, -0.0168, -0.0083, -0.0075, -0.0051, 0.0025, + 0.0136, 0.0261, 0.0386, 0.0497, 0.0580, 0.0599, 0.0583, 0.0614, + 0.0740, 0.0889, 0.1023, 0.1162, 0.1211, 0.1212, 0.1251, 0.1336, + 0.1502, 0.1686, 0.1883, 0.2148, 0.2363, 0.2458, 0.2507, 0.2531 + ] + EXPECTED_AUDIO_COND = [ + 0.0256, -0.0544, 0.1600, -0.0032, 0.1066, 0.0825, -0.0013, 0.3440, + 0.0210, 0.0412, -0.1777, -0.0892, -0.0164, 0.0285, -0.0613, -0.0617, + -0.0137, -0.0201, -0.0175, 0.0215, -0.0627, 0.0520, -0.0730, 0.0970, + -0.0100, 0.0442, -0.0586, 0.0207, -0.0015, -0.0082 + ] + EXPECTED_META_COND = [ + 0.0415, 0.0877, 0.0022, -0.0055, 0.0751, 0.0334, 0.0324, -0.0068, + 0.0011, 0.0017, -0.0676, 0.0655, -0.0143, 0.0399, 0.0303, 0.0743, + -0.0168, -0.0394, -0.1113, 0.0124, 0.0442, 0.0267, -0.0003, -0.1536, + -0.0116, -0.1837, -0.0180, -0.1026, -0.0777, -0.0456 + ] + EXPECTED_LYRIC_COND = [ + 76, 27, 40, 30, 76, 46, 44, 47, 40, 37, 38, 31, 45, 45, 76, 38, 31, 33, + 45, 76, 41, 32, 76, 45, 46, 41, 40, 31, 78, 76 + ] + # fmt: on + + def prepare_inputs(self): + tokenizer = JukeboxTokenizer.from_pretrained(self.model_id) + tokens = tokenizer(**self.metas)["input_ids"] + return tokens + + @slow + def test_sampling(self): + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + labels = self.prepare_inputs() + + set_seed(0) + zs = [torch.zeros(1, 0, dtype=torch.long).cpu() for _ in range(3)] + zs = model._sample(zs, labels, [0], sample_length=40 * model.priors[0].raw_to_tokens, save_results=False) + self.assertIn(zs[0][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_2, self.EXPECTED_OUTPUT_2_PT_2]) + + set_seed(0) + zs = model._sample(zs, labels, [1], sample_length=40 * model.priors[1].raw_to_tokens, save_results=False) + self.assertIn(zs[1][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_1, self.EXPECTED_OUTPUT_1_PT_2]) + + set_seed(0) + zs = model._sample(zs, labels, [2], sample_length=40 * model.priors[2].raw_to_tokens, save_results=False) + self.assertIn(zs[2][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_0, self.EXPECTED_OUTPUT_0_PT_2]) + + @slow + def test_conditioning(self): + torch.backends.cuda.matmul.allow_tf32 = False + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + + labels = self.prepare_inputs() + set_seed(0) + zs = [torch.zeros(1, 0, dtype=torch.long) for _ in range(3)] + + top_prior = model.priors[0] + start = 0 + music_token_conds = top_prior.get_music_tokens_conds(zs, start=start, end=start + top_prior.n_ctx) + metadata = top_prior.get_metadata(labels[0].clone(), start, 1058304, 0) + + self.assertIsNone(music_token_conds) + self.assertListEqual(metadata.numpy()[0][:10].tolist(), self.EXPECTED_Y_COND) + + audio_conditioning, metadata_conditioning, lyric_tokens = top_prior.get_cond(music_token_conds, metadata) + torch.testing.assert_allclose( + audio_conditioning[0][0][:30].detach(), torch.tensor(self.EXPECTED_AUDIO_COND), atol=1e-4, rtol=1e-4 + ) + torch.testing.assert_allclose( + metadata_conditioning[0][0][:30].detach(), torch.tensor(self.EXPECTED_META_COND), atol=1e-4, rtol=1e-4 + ) + torch.testing.assert_allclose( + lyric_tokens[0, :30].detach(), torch.tensor(self.EXPECTED_LYRIC_COND), atol=1e-4, rtol=1e-4 + ) + + @slow + def test_primed_sampling(self): + torch.backends.cuda.matmul.allow_tf32 = False + + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + set_seed(0) + waveform = torch.rand((1, 5120, 1)) + tokens = list(self.prepare_inputs()) + + zs = [model.vqvae.encode(waveform, start_level=2, bs_chunks=waveform.shape[0])[0], None, None] + zs = model._sample( + zs, tokens, sample_levels=[0], save_results=False, sample_length=40 * model.priors[0].raw_to_tokens + ) + torch.testing.assert_allclose(zs[0][0][:40], torch.tensor(self.EXPECTED_PRIMED_0)) + + upper_2 = torch.cat((zs[0], torch.zeros(1, 2048 - zs[0].shape[-1])), dim=-1).long() + zs = [upper_2, model.vqvae.encode(waveform, start_level=1, bs_chunks=waveform.shape[0])[0], None] + zs = model._sample( + zs, tokens, sample_levels=[1], save_results=False, sample_length=40 * model.priors[1].raw_to_tokens + ) + torch.testing.assert_allclose(zs[1][0][:40], torch.tensor(self.EXPECTED_PRIMED_1)) + + upper_1 = torch.cat((zs[1], torch.zeros(1, 2048 - zs[1].shape[-1])), dim=-1).long() + zs = [upper_2, upper_1, model.vqvae.encode(waveform, start_level=0, bs_chunks=waveform.shape[0])[0]] + zs = model._sample( + zs, tokens, sample_levels=[2], save_results=False, sample_length=40 * model.priors[2].raw_to_tokens + ) + torch.testing.assert_allclose(zs[2][0][:40].cpu(), torch.tensor(self.EXPECTED_PRIMED_2)) + + @slow + def test_vqvae(self): + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + set_seed(0) + x = torch.rand((1, 5120, 1)) + with torch.no_grad(): + zs = model.vqvae.encode(x, start_level=2, bs_chunks=x.shape[0]) + torch.testing.assert_allclose(zs[0][0], torch.tensor(self.EXPECTED_VQVAE_ENCODE)) + + with torch.no_grad(): + x = model.vqvae.decode(zs, start_level=2, bs_chunks=x.shape[0]) + torch.testing.assert_allclose(x[0, :40, 0], torch.tensor(self.EXPECTED_VQVAE_DECODE), atol=1e-4, rtol=1e-4) + + +@require_torch +class Jukebox5bModelTester(unittest.TestCase): + all_model_classes = (JukeboxModel,) if is_torch_available() else () + model_id = "openai/jukebox-5b-lyrics" + metas = { + "artist": "Zac Brown Band", + "genres": "Country", + "lyrics": """I met a traveller from an antique land, + Who said "Two vast and trunkless legs of stone + Stand in the desert. . . . Near them, on the sand, + Half sunk a shattered visage lies, whose frown, + And wrinkled lip, and sneer of cold command, + Tell that its sculptor well those passions read + Which yet survive, stamped on these lifeless things, + The hand that mocked them, and the heart that fed; + And on the pedestal, these words appear: + My name is Ozymandias, King of Kings; + Look on my Works, ye Mighty, and despair! + Nothing beside remains. Round the decay + Of that colossal Wreck, boundless and bare + The lone and level sands stretch far away + """, + } + + # fmt: off + EXPECTED_OUTPUT_2 = [ + 1489, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 1489, 1489, 1489, 1489, 1150, 1853, 1509, 1150, 1357, 1509, 6, 1272 + ] + EXPECTED_OUTPUT_2_PT_2 = [ + 1489, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653 + ] + + EXPECTED_OUTPUT_1 = [ + 1125, 416, 1125, 1125, 1125, 1125, 1125, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416 + ] + EXPECTED_OUTPUT_1_PT_2 = [ + 416, 416, 1125, 1125, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416 + ] + + EXPECTED_OUTPUT_0 = [ + 1755, 1061, 234, 1755, 1061, 1755, 185, 290, 307, 307, 616, 616, + 616, 616, 616, 616, 307, 290, 417, 1755, 234, 1755, 185, 290, + 290, 290, 307, 616, 616, 616, 616, 616, 290, 234, 234, 1755, + 234, 234, 1755, 234, 185, 185, 307, 616, 616, 616, 616, 290, + 1755, 1755, 1755, 234, 234, 1755, 1572, 290, 307, 616, 34, 616 + ] + EXPECTED_OUTPUT_0_PT_2 = [ + 854, 842, 1353, 114, 1353, 842, 185, 842, 185, 114, 591, 842, 185, + 417, 185, 842, 307, 842, 591, 842, 185, 842, 185, 842, 591, 842, + 1353, 842, 185, 842, 591, 842, 591, 114, 591, 842, 185, 842, 591, + 89, 591, 842, 591, 842, 591, 417, 1372, 842, 1372, 842, 34, 842, + 185, 89, 591, 842, 185, 842, 591, 632 + ] + + EXPECTED_GPU_OUTPUTS_2 = [ + 1489, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653 + ] + EXPECTED_GPU_OUTPUTS_2_PT_2 = [ + 1489, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 1853, 1177, 1536, 1228, + 710, 475, 1489, 1229, 1224, 231, 1224, 252, 1434, 653, 475, + 1106, 1877, 1599, 1228, 1600, 1683, 1182, 1853, 475, 1864, + 252, 1229, 1434, 2001 + ] + + EXPECTED_GPU_OUTPUTS_1 = [ + 1125, 1125, 416, 1125, 1125, 416, 1125, 1125, 416, 416, 1125, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416 + ] + EXPECTED_GPU_OUTPUTS_0 = [ + 491, 1755, 34, 1613, 1755, 417, 992, 1613, 222, 842, 1353, 1613, + 844, 632, 185, 1613, 844, 632, 185, 1613, 185, 842, 677, 1613, + 185, 114, 1353, 1613, 307, 89, 844, 1613, 307, 1332, 234, 1979, + 307, 89, 1353, 616, 34, 842, 185, 842, 34, 842, 185, 842, + 307, 114, 185, 89, 34, 1268, 185, 89, 34, 842, 185, 89 + ] + # fmt: on + + def prepare_inputs(self, model_id): + tokenizer = JukeboxTokenizer.from_pretrained(model_id) + tokens = tokenizer(**self.metas)["input_ids"] + return tokens + + @slow + def test_sampling(self): + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + labels = self.prepare_inputs(self.model_id) + + set_seed(0) + zs = [torch.zeros(1, 0, dtype=torch.long).cpu() for _ in range(3)] + zs = model._sample(zs, labels, [0], sample_length=60 * model.priors[0].raw_to_tokens, save_results=False) + self.assertIn(zs[0][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_2, self.EXPECTED_OUTPUT_2_PT_2]) + + set_seed(0) + zs = model._sample(zs, labels, [1], sample_length=60 * model.priors[1].raw_to_tokens, save_results=False) + self.assertIn(zs[1][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_1, self.EXPECTED_OUTPUT_1_PT_2]) + + set_seed(0) + zs = model._sample(zs, labels, [2], sample_length=60 * model.priors[2].raw_to_tokens, save_results=False) + self.assertIn(zs[2][0].detach().cpu().tolist(), [self.EXPECTED_OUTPUT_0, self.EXPECTED_OUTPUT_0_PT_2]) + + @slow + @skip("Not enough GPU memory on CI runners") + def test_slow_sampling(self): + model = JukeboxModel.from_pretrained(self.model_id, min_duration=0).eval() + labels = [i.cuda() for i in self.prepare_inputs(self.model_id)] + + set_seed(0) + model.priors[0].cuda() + zs = [torch.zeros(1, 0, dtype=torch.long).cuda() for _ in range(3)] + zs = model._sample(zs, labels, [0], sample_length=60 * model.priors[0].raw_to_tokens, save_results=False) + torch.testing.assert_allclose(zs[0][0].cpu(), torch.tensor(self.EXPECTED_GPU_OUTPUTS_2)) + model.priors[0].cpu() + + set_seed(0) + model.priors[1].cuda() + zs = model._sample(zs, labels, [1], sample_length=60 * model.priors[1].raw_to_tokens, save_results=False) + torch.testing.assert_allclose(zs[1][0].cpu(), torch.tensor(self.EXPECTED_GPU_OUTPUTS_1)) + model.priors[1].cpu() + + set_seed(0) + model.priors[2].cuda() + zs = model._sample(zs, labels, [2], sample_length=60 * model.priors[2].raw_to_tokens, save_results=False) + torch.testing.assert_allclose(zs[2][0].cpu(), torch.tensor(self.EXPECTED_GPU_OUTPUTS_0)) + + @slow + def test_fp16_slow_sampling(self): + prior_id = "ArthurZ/jukebox_prior_0" + model = JukeboxPrior.from_pretrained(prior_id, min_duration=0).eval().half().to("cuda") + + labels = self.prepare_inputs(prior_id)[0].cuda() + metadata = model.get_metadata(labels, 0, 7680, 0) + set_seed(0) + outputs = model.sample(1, metadata=metadata, sample_tokens=60) + self.assertIn(outputs[0].cpu().tolist(), [self.EXPECTED_GPU_OUTPUTS_2, self.EXPECTED_GPU_OUTPUTS_2_PT_2]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_tokenization_jukebox.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_tokenization_jukebox.py new file mode 100644 index 0000000000000000000000000000000000000000..c434cf6aa17f79671b148e50329736b22ba8095f --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/jukebox/test_tokenization_jukebox.py @@ -0,0 +1,209 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from transformers import JukeboxTokenizer +from transformers.testing_utils import require_torch + + +class JukeboxTokenizationTest(unittest.TestCase): + tokenizer_class = JukeboxTokenizer + metas = { + "artist": "Zac Brown Band", + "genres": "Country", + "lyrics": """I met a traveller from an antique land, + Who said "Two vast and trunkless legs of stone + Stand in the desert. . . . Near them, on the sand, + Half sunk a shattered visage lies, whose frown, + And wrinkled lip, and sneer of cold command, + Tell that its sculptor well those passions read + Which yet survive, stamped on these lifeless things, + The hand that mocked them, and the heart that fed; + And on the pedestal, these words appear: + My name is Ozymandias, King of Kings; + Look on my Works, ye Mighty, and despair! + Nothing beside remains. Round the decay + Of that colossal Wreck, boundless and bare + The lone and level sands stretch far away + """, + } + + @require_torch + def test_1b_lyrics_tokenizer(self): + """ + how to run the same test with openAI + ... + """ + import torch + + tokenizer = JukeboxTokenizer.from_pretrained("openai/jukebox-1b-lyrics") + tokens = tokenizer(**self.metas)["input_ids"] + # fmt: off + EXPECTED_OUTPUT = [ + torch.tensor([[ + 0, 0, 0, 7169, 507, 9, 76, 39, 31, 46, 76, 27, + 76, 46, 44, 27, 48, 31, 38, 38, 31, 44, 76, 32, + 44, 41, 39, 76, 27, 40, 76, 27, 40, 46, 35, 43, + 47, 31, 76, 38, 27, 40, 30, 64, 78, 76, 76, 76, + 76, 76, 76, 76, 76, 23, 34, 41, 76, 45, 27, 35, + 30, 76, 71, 20, 49, 41, 76, 48, 27, 45, 46, 76, + 27, 40, 30, 76, 46, 44, 47, 40, 37, 38, 31, 45, + 45, 76, 38, 31, 33, 45, 76, 41, 32, 76, 45, 46, + 41, 40, 31, 78, 76, 76, 76, 76, 76, 76, 76, 76, + 19, 46, 27, 40, 30, 76, 35, 40, 76, 46, 34, 31, + 76, 30, 31, 45, 31, 44, 46, 63, 76, 63, 76, 63, + 76, 63, 76, 14, 31, 27, 44, 76, 46, 34, 31, 39, + 64, 76, 41, 40, 76, 46, 34, 31, 76, 45, 27, 40, + 30, 64, 78, 76, 76, 76, 76, 76, 76, 76, 76, 8, + 27, 38, 32, 76, 45, 47, 40, 37, 76, 27, 76, 45, + 34, 27, 46, 46, 31, 44, 31, 30, 76, 48, 35, 45, + 27, 33, 31, 76, 38, 35, 31, 45, 64, 76, 49, 34, + 41, 45, 31, 76, 32, 44, 41, 49, 40, 64, 78, 76, + 76, 76, 76, 76, 76, 76, 76, 1, 40, 30, 76, 49, + 44, 35, 40, 37, 38, 31, 30, 76, 38, 35, 42, 64, + 76, 27, 40, 30, 76, 45, 40, 31, 31, 44, 76, 41, + 32, 76, 29, 41, 38, 30, 76, 29, 41, 39, 39, 27, + 40, 30, 64, 78, 76, 76, 76, 76, 76, 76, 76, 76, + 20, 31, 38, 38, 76, 46, 34, 27, 46, 76, 35, 46, + 45, 76, 45, 29, 47, 38, 42, 46, 41, 44, 76, 49, + 31, 38, 38, 76, 46, 34, 41, 45, 31, 76, 42, 27, + 45, 45, 35, 41, 40, 45, 76, 44, 31, 27, 30, 78, + 76, 76, 76, 76, 76, 76, 76, 76, 23, 34, 35, 29, + 34, 76, 51, 31, 46, 76, 45, 47, 44, 48, 35, 48, + 31, 64, 76, 45, 46, 27, 39, 42, 31, 30, 76, 41, + 40, 76, 46, 34, 31, 45, 31, 76, 38, 35, 32, 31, + 38, 31, 45, 45, 76, 46, 34, 35, 40, 33, 45, 64, + 78, 76, 76, 76, 76, 76, 76, 76, 76, 20, 34, 31, + 76, 34, 27, 40, 30, 76, 46, 34, 27, 46, 76, 39, + 41, 29, 37, 31, 30, 76, 46, 34, 31, 39, 64, 76, + 27, 40, 30, 76, 46, 34, 31, 76, 34, 31, 27, 44, + 46, 76, 46, 34, 27, 46, 76, 32, 31, 30, 66, 78, + 76, 76, 76, 76, 76, 76, 76, 76, 1, 40, 30, 76, + 41, 40, 76, 46, 34, 31, 76, 42, 31, 30, 31, 45, + 46, 27, 38, 64, 76, 46, 34, 31, 45, 31, 76, 49, + 41, 44, 30, 45, 76, 27, 42, 42, 31, 27, 44, 65, + 78, 76, 76, 76, 76, 76, 76, 76, 76, 13, 51, 76, + 40, 27, 39, 31, 76, 35, 45, 76, 15, 52, 51, 39, + 27, 40, 30, 35, 27, 45, 64, 76, 11, 35, 40, 33, + 76, 41, 32, 76, 11, 35, 40, 33, 45, 66, 78, 76, + 76, 76, 76, 76, 76, 76, 76, 12, 41, 41, 37, 76, + 41, 40, 76, 39, 51, 76, 23, 41, 44, 37, 45, 64, + 76, 51, 31, 76, 13, 35, 33, 34, 46, 51, 64, 76, + 27, 40, 30, 76, 30, 31, 45, 42, 27, 35, 44, 67, + 78, 76, 76, 76, 76, 76, 76, 76, 76, 14, 41, 46, + 34, 35, 40, 33, 76, 28, 31, 45, 35, 30, 31, 76, + 44, 31, 39, 27, 35, 40, 45, 63, 76, 18, 41, 47, + 40, 30, 76, 46, 34, 31, 76, 30, 31, 29, 27, 51, + 78, 76, 76, 76, 76, 76, 76, 76, 76, 15, 32, 76, + 46, 34, 27, 46, 76, 29, 41, 38, 41, 45, 45, 27, + 38, 76, 23, 44, 31, 29, 37, 64, 76, 28, 41, 47, + 40, 30, 38, 31, 45, 45, 76, 27, 40, 30, 76, 28, + 27, 44, 31, 78, 76, 76, 76, 76, 76, 76, 76, 76, + 20, 34, 31, 76, 38, 41, 40, 31, 76, 27, 40, 30, + 76, 38, 31, 48, 31, 38, 76, 45, 27, 40, 30, 45, + 76, 45, 46, 44, 31, 46, 29, 34, 76, 32, 27, 44, + 76, 27, 49, 27, 51, 78, 76, 76, 76, 76, 76, 76, + 76, 76]]), + torch.tensor([[0, 0, 0, 1069, 11]]), + torch.tensor([[0, 0, 0, 1069, 11]]), + ] + # fmt: on + self.assertTrue(torch.allclose(tokens[0], EXPECTED_OUTPUT[0])) + self.assertTrue(torch.allclose(tokens[1], EXPECTED_OUTPUT[1])) + self.assertTrue(torch.allclose(tokens[2], EXPECTED_OUTPUT[2])) + + @require_torch + def test_5b_lyrics_tokenizer(self): + """ + The outputs are similar that open AI but do not have the same format as this one is adapted to the HF integration. + """ + import torch + + tokenizer = JukeboxTokenizer.from_pretrained("openai/jukebox-5b-lyrics") + tokens = tokenizer(**self.metas)["input_ids"] + # fmt: off + EXPECTED_OUTPUT = [ + torch.tensor([[ + 0, 0, 0, 1069, 11, -1, -1, -1, -1, 9, 77, 39, + 31, 46, 77, 27, 77, 46, 44, 27, 48, 31, 38, 38, + 31, 44, 77, 32, 44, 41, 39, 77, 27, 40, 77, 27, + 40, 46, 35, 43, 47, 31, 77, 38, 27, 40, 30, 64, + 79, 77, 77, 77, 77, 77, 77, 77, 77, 23, 34, 41, + 77, 45, 27, 35, 30, 77, 72, 20, 49, 41, 77, 48, + 27, 45, 46, 77, 27, 40, 30, 77, 46, 44, 47, 40, + 37, 38, 31, 45, 45, 77, 38, 31, 33, 45, 77, 41, + 32, 77, 45, 46, 41, 40, 31, 79, 77, 77, 77, 77, + 77, 77, 77, 77, 19, 46, 27, 40, 30, 77, 35, 40, + 77, 46, 34, 31, 77, 30, 31, 45, 31, 44, 46, 63, + 77, 63, 77, 63, 77, 63, 77, 14, 31, 27, 44, 77, + 46, 34, 31, 39, 64, 77, 41, 40, 77, 46, 34, 31, + 77, 45, 27, 40, 30, 64, 79, 77, 77, 77, 77, 77, + 77, 77, 77, 8, 27, 38, 32, 77, 45, 47, 40, 37, + 77, 27, 77, 45, 34, 27, 46, 46, 31, 44, 31, 30, + 77, 48, 35, 45, 27, 33, 31, 77, 38, 35, 31, 45, + 64, 77, 49, 34, 41, 45, 31, 77, 32, 44, 41, 49, + 40, 64, 79, 77, 77, 77, 77, 77, 77, 77, 77, 1, + 40, 30, 77, 49, 44, 35, 40, 37, 38, 31, 30, 77, + 38, 35, 42, 64, 77, 27, 40, 30, 77, 45, 40, 31, + 31, 44, 77, 41, 32, 77, 29, 41, 38, 30, 77, 29, + 41, 39, 39, 27, 40, 30, 64, 79, 77, 77, 77, 77, + 77, 77, 77, 77, 20, 31, 38, 38, 77, 46, 34, 27, + 46, 77, 35, 46, 45, 77, 45, 29, 47, 38, 42, 46, + 41, 44, 77, 49, 31, 38, 38, 77, 46, 34, 41, 45, + 31, 77, 42, 27, 45, 45, 35, 41, 40, 45, 77, 44, + 31, 27, 30, 79, 77, 77, 77, 77, 77, 77, 77, 77, + 23, 34, 35, 29, 34, 77, 51, 31, 46, 77, 45, 47, + 44, 48, 35, 48, 31, 64, 77, 45, 46, 27, 39, 42, + 31, 30, 77, 41, 40, 77, 46, 34, 31, 45, 31, 77, + 38, 35, 32, 31, 38, 31, 45, 45, 77, 46, 34, 35, + 40, 33, 45, 64, 79, 77, 77, 77, 77, 77, 77, 77, + 77, 20, 34, 31, 77, 34, 27, 40, 30, 77, 46, 34, + 27, 46, 77, 39, 41, 29, 37, 31, 30, 77, 46, 34, + 31, 39, 64, 77, 27, 40, 30, 77, 46, 34, 31, 77, + 34, 31, 27, 44, 46, 77, 46, 34, 27, 46, 77, 32, + 31, 30, 66, 79, 77, 77, 77, 77, 77, 77, 77, 77, + 1, 40, 30, 77, 41, 40, 77, 46, 34, 31, 77, 42, + 31, 30, 31, 45, 46, 27, 38, 64, 77, 46, 34, 31, + 45, 31, 77, 49, 41, 44, 30, 45, 77, 27, 42, 42, + 31, 27, 44, 65, 79, 77, 77, 77, 77, 77, 77, 77, + 77, 13, 51, 77, 40, 27, 39, 31, 77, 35, 45, 77, + 15, 52, 51, 39, 27, 40, 30, 35, 27, 45, 64, 77, + 11, 35, 40, 33, 77, 41, 32, 77, 11, 35, 40, 33, + 45, 66, 79, 77, 77, 77, 77, 77, 77, 77, 77, 12, + 41, 41, 37, 77, 41, 40, 77, 39, 51, 77, 23, 41, + 44, 37, 45, 64, 77, 51, 31, 77, 13, 35, 33, 34, + 46, 51, 64, 77, 27, 40, 30, 77, 30, 31, 45, 42, + 27, 35, 44, 67, 79, 77, 77, 77, 77, 77, 77, 77, + 77, 14, 41, 46, 34, 35, 40, 33, 77, 28, 31, 45, + 35, 30, 31, 77, 44, 31, 39, 27, 35, 40, 45, 63, + 77, 18, 41, 47, 40, 30, 77, 46, 34, 31, 77, 30, + 31, 29, 27, 51, 79, 77, 77, 77, 77, 77, 77, 77, + 77, 15, 32, 77, 46, 34, 27, 46, 77, 29, 41, 38, + 41, 45, 45, 27, 38, 77, 23, 44, 31, 29, 37, 64, + 77, 28, 41, 47, 40, 30, 38, 31, 45, 45, 77, 27, + 40, 30, 77, 28, 27, 44, 31, 79, 77, 77, 77, 77, + 77, 77, 77, 77, 20, 34, 31, 77, 38, 41, 40, 31, + 77, 27, 40, 30, 77, 38, 31, 48, 31, 38, 77, 45, + 27, 40, 30, 45, 77, 45, 46, 44, 31, 46, 29, 34, + 77, 32, 27, 44, 77, 27, 49, 27, 51, 79, 77, 77, + 77, 77, 77, 77, 77, 77]]), + torch.tensor([[0, 0, 0, 1069, 11, -1, -1, -1, -1]]), + torch.tensor([[0, 0, 0, 1069, 11, -1, -1, -1, -1]]), + ] + # fmt: on + self.assertTrue(torch.allclose(tokens[0], EXPECTED_OUTPUT[0])) + self.assertTrue(torch.allclose(tokens[1], EXPECTED_OUTPUT[1])) + self.assertTrue(torch.allclose(tokens[2], EXPECTED_OUTPUT[2])) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_layoutlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_layoutlm.py new file mode 100644 index 0000000000000000000000000000000000000000..0535fbf4e1f4c88c25d81597ef2b0ddfa23d6270 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_layoutlm.py @@ -0,0 +1,387 @@ +# coding=utf-8 +# Copyright 2018 The Microsoft Research Asia LayoutLM Team Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from transformers import LayoutLMConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + LayoutLMForMaskedLM, + LayoutLMForQuestionAnswering, + LayoutLMForSequenceClassification, + LayoutLMForTokenClassification, + LayoutLMModel, + ) + + +class LayoutLMModelTester: + """You can also import this e.g from .test_modeling_layoutlm import LayoutLMModelTester""" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + range_bbox=1000, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.range_bbox = range_bbox + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + bbox = ids_tensor([self.batch_size, self.seq_length, 4], self.range_bbox) + # Ensure that bbox is legal + for i in range(bbox.shape[0]): + for j in range(bbox.shape[1]): + if bbox[i, j, 3] < bbox[i, j, 1]: + t = bbox[i, j, 3] + bbox[i, j, 3] = bbox[i, j, 1] + bbox[i, j, 1] = t + if bbox[i, j, 2] < bbox[i, j, 0]: + t = bbox[i, j, 2] + bbox[i, j, 2] = bbox[i, j, 0] + bbox[i, j, 0] = t + + input_mask = None + if self.use_input_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return LayoutLMConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + def create_and_check_model( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = LayoutLMModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, bbox, token_type_ids=token_type_ids) + result = model(input_ids, bbox) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = LayoutLMForMaskedLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = LayoutLMForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = LayoutLMForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = LayoutLMForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + bbox, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "bbox": bbox, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_torch +class LayoutLMModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + LayoutLMModel, + LayoutLMForMaskedLM, + LayoutLMForSequenceClassification, + LayoutLMForTokenClassification, + LayoutLMForQuestionAnswering, + ) + if is_torch_available() + else None + ) + pipeline_model_mapping = ( + { + "document-question-answering": LayoutLMForQuestionAnswering, + "feature-extraction": LayoutLMModel, + "fill-mask": LayoutLMForMaskedLM, + "text-classification": LayoutLMForSequenceClassification, + "token-classification": LayoutLMForTokenClassification, + "zero-shot": LayoutLMForSequenceClassification, + } + if is_torch_available() + else {} + ) + fx_compatible = True + + def setUp(self): + self.model_tester = LayoutLMModelTester(self) + self.config_tester = ConfigTester(self, config_class=LayoutLMConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + +def prepare_layoutlm_batch_inputs(): + # Here we prepare a batch of 2 sequences to test a LayoutLM forward pass on: + # fmt: off + input_ids = torch.tensor([[101,1019,1014,1016,1037,12849,4747,1004,14246,2278,5439,4524,5002,2930,2193,2930,4341,3208,1005,1055,2171,2848,11300,3531,102],[101,4070,4034,7020,1024,3058,1015,1013,2861,1013,6070,19274,2772,6205,27814,16147,16147,4343,2047,10283,10969,14389,1012,2338,102]],device=torch_device) # noqa: E231 + attention_mask = torch.tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],],device=torch_device) # noqa: E231 + bbox = torch.tensor([[[0,0,0,0],[423,237,440,251],[427,272,441,287],[419,115,437,129],[961,885,992,912],[256,38,330,58],[256,38,330,58],[336,42,353,57],[360,39,401,56],[360,39,401,56],[411,39,471,59],[479,41,528,59],[533,39,630,60],[67,113,134,131],[141,115,209,132],[68,149,133,166],[141,149,187,164],[195,148,287,165],[195,148,287,165],[195,148,287,165],[295,148,349,165],[441,149,492,166],[497,149,546,164],[64,201,125,218],[1000,1000,1000,1000]],[[0,0,0,0],[662,150,754,166],[665,199,742,211],[519,213,554,228],[519,213,554,228],[134,433,187,454],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[314,469,376,482],[504,684,582,706],[941,825,973,900],[941,825,973,900],[941,825,973,900],[941,825,973,900],[610,749,652,765],[130,659,168,672],[176,657,237,672],[238,657,312,672],[443,653,628,672],[443,653,628,672],[716,301,825,317],[1000,1000,1000,1000]]],device=torch_device) # noqa: E231 + token_type_ids = torch.tensor([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],device=torch_device) # noqa: E231 + # these are sequence labels (i.e. at the token level) + labels = torch.tensor([[-100,10,10,10,9,1,-100,7,7,-100,7,7,4,2,5,2,8,8,-100,-100,5,0,3,2,-100],[-100,12,12,12,-100,12,10,-100,-100,-100,-100,10,12,9,-100,-100,-100,10,10,10,9,12,-100,10,-100]],device=torch_device) # noqa: E231 + # fmt: on + + return input_ids, attention_mask, bbox, token_type_ids, labels + + +@require_torch +class LayoutLMModelIntegrationTest(unittest.TestCase): + @slow + def test_forward_pass_no_head(self): + model = LayoutLMModel.from_pretrained("microsoft/layoutlm-base-uncased").to(torch_device) + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids) + + # test the sequence output on [0, :3, :3] + expected_slice = torch.tensor( + [[0.1785, -0.1947, -0.0425], [-0.3254, -0.2807, 0.2553], [-0.5391, -0.3322, 0.3364]], + device=torch_device, + ) + + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-3)) + + # test the pooled output on [1, :3] + expected_slice = torch.tensor([-0.6580, -0.0214, 0.8552], device=torch_device) + + self.assertTrue(torch.allclose(outputs.pooler_output[1, :3], expected_slice, atol=1e-3)) + + @slow + def test_forward_pass_sequence_classification(self): + # initialize model with randomly initialized sequence classification head + model = LayoutLMForSequenceClassification.from_pretrained("microsoft/layoutlm-base-uncased", num_labels=2).to( + torch_device + ) + + input_ids, attention_mask, bbox, token_type_ids, _ = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model( + input_ids=input_ids, + bbox=bbox, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + labels=torch.tensor([1, 1], device=torch_device), + ) + + # test whether we get a loss as a scalar + loss = outputs.loss + expected_shape = torch.Size([]) + self.assertEqual(loss.shape, expected_shape) + + # test the shape of the logits + logits = outputs.logits + expected_shape = torch.Size((2, 2)) + self.assertEqual(logits.shape, expected_shape) + + @slow + def test_forward_pass_token_classification(self): + # initialize model with randomly initialized token classification head + model = LayoutLMForTokenClassification.from_pretrained("microsoft/layoutlm-base-uncased", num_labels=13).to( + torch_device + ) + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model( + input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids, labels=labels + ) + + # test the loss calculation to be around 2.65 + # expected_loss = torch.tensor(2.65, device=torch_device) + + # The loss is currently somewhat random and can vary between 0.1-0.3 atol. + # self.assertTrue(torch.allclose(outputs.loss, expected_loss, atol=0.1)) + + # test the shape of the logits + logits = outputs.logits + expected_shape = torch.Size((2, 25, 13)) + self.assertEqual(logits.shape, expected_shape) + + @slow + def test_forward_pass_question_answering(self): + # initialize model with randomly initialized token classification head + model = LayoutLMForQuestionAnswering.from_pretrained("microsoft/layoutlm-base-uncased").to(torch_device) + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids) + + # test the shape of the logits + expected_shape = torch.Size((2, 25)) + self.assertEqual(outputs.start_logits.shape, expected_shape) + self.assertEqual(outputs.end_logits.shape, expected_shape) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_tf_layoutlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_tf_layoutlm.py new file mode 100644 index 0000000000000000000000000000000000000000..95e24023bb23c34595f825809b0b45c6e47001d6 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_modeling_tf_layoutlm.py @@ -0,0 +1,369 @@ +# coding=utf-8 +# Copyright 2018 The Microsoft Research Asia LayoutLM Team Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +import numpy as np + +from transformers import LayoutLMConfig, is_tf_available +from transformers.testing_utils import require_tf, slow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.layoutlm.modeling_tf_layoutlm import ( + TF_LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST, + TFLayoutLMForMaskedLM, + TFLayoutLMForQuestionAnswering, + TFLayoutLMForSequenceClassification, + TFLayoutLMForTokenClassification, + TFLayoutLMModel, + ) + + +class TFLayoutLMModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + range_bbox=1000, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.range_bbox = range_bbox + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + # convert bbox to numpy since TF does not support item assignment + bbox = ids_tensor([self.batch_size, self.seq_length, 4], self.range_bbox).numpy() + # Ensure that bbox is legal + for i in range(bbox.shape[0]): + for j in range(bbox.shape[1]): + if bbox[i, j, 3] < bbox[i, j, 1]: + t = bbox[i, j, 3] + bbox[i, j, 3] = bbox[i, j, 1] + bbox[i, j, 1] = t + if bbox[i, j, 2] < bbox[i, j, 0]: + t = bbox[i, j, 2] + bbox[i, j, 2] = bbox[i, j, 0] + bbox[i, j, 0] = t + bbox = tf.convert_to_tensor(bbox) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = LayoutLMConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + ) + + return config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_model( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFLayoutLMModel(config=config) + + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, bbox, token_type_ids=token_type_ids) + result = model(input_ids, bbox) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFLayoutLMForMaskedLM(config=config) + + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFLayoutLMForSequenceClassification(config=config) + + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFLayoutLMForTokenClassification(config=config) + + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFLayoutLMForQuestionAnswering(config=config) + + result = model(input_ids, bbox, attention_mask=input_mask, token_type_ids=token_type_ids) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + bbox, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "bbox": bbox, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_tf +class TFLayoutLMModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFLayoutLMModel, + TFLayoutLMForMaskedLM, + TFLayoutLMForTokenClassification, + TFLayoutLMForSequenceClassification, + TFLayoutLMForQuestionAnswering, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFLayoutLMModel, + "fill-mask": TFLayoutLMForMaskedLM, + "text-classification": TFLayoutLMForSequenceClassification, + "token-classification": TFLayoutLMForTokenClassification, + "zero-shot": TFLayoutLMForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = True + onnx_min_opset = 10 + + def setUp(self): + self.model_tester = TFLayoutLMModelTester(self) + self.config_tester = ConfigTester(self, config_class=LayoutLMConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFLayoutLMModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + # TODO (Joao): fix me + @unittest.skip("Onnx compliancy broke with TF 2.10") + def test_onnx_compliancy(self): + pass + + +def prepare_layoutlm_batch_inputs(): + # Here we prepare a batch of 2 sequences to test a LayoutLM forward pass on: + # fmt: off + input_ids = tf.convert_to_tensor([[101,1019,1014,1016,1037,12849,4747,1004,14246,2278,5439,4524,5002,2930,2193,2930,4341,3208,1005,1055,2171,2848,11300,3531,102],[101,4070,4034,7020,1024,3058,1015,1013,2861,1013,6070,19274,2772,6205,27814,16147,16147,4343,2047,10283,10969,14389,1012,2338,102]]) # noqa: E231 + attention_mask = tf.convert_to_tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],]) # noqa: E231 + bbox = tf.convert_to_tensor([[[0,0,0,0],[423,237,440,251],[427,272,441,287],[419,115,437,129],[961,885,992,912],[256,38,330,58],[256,38,330,58],[336,42,353,57],[360,39,401,56],[360,39,401,56],[411,39,471,59],[479,41,528,59],[533,39,630,60],[67,113,134,131],[141,115,209,132],[68,149,133,166],[141,149,187,164],[195,148,287,165],[195,148,287,165],[195,148,287,165],[295,148,349,165],[441,149,492,166],[497,149,546,164],[64,201,125,218],[1000,1000,1000,1000]],[[0,0,0,0],[662,150,754,166],[665,199,742,211],[519,213,554,228],[519,213,554,228],[134,433,187,454],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[314,469,376,482],[504,684,582,706],[941,825,973,900],[941,825,973,900],[941,825,973,900],[941,825,973,900],[610,749,652,765],[130,659,168,672],[176,657,237,672],[238,657,312,672],[443,653,628,672],[443,653,628,672],[716,301,825,317],[1000,1000,1000,1000]]]) # noqa: E231 + token_type_ids = tf.convert_to_tensor([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]) # noqa: E231 + # these are sequence labels (i.e. at the token level) + labels = tf.convert_to_tensor([[-100,10,10,10,9,1,-100,7,7,-100,7,7,4,2,5,2,8,8,-100,-100,5,0,3,2,-100],[-100,12,12,12,-100,12,10,-100,-100,-100,-100,10,12,9,-100,-100,-100,10,10,10,9,12,-100,10,-100]]) # noqa: E231 + # fmt: on + + return input_ids, attention_mask, bbox, token_type_ids, labels + + +@require_tf +class TFLayoutLMModelIntegrationTest(unittest.TestCase): + @slow + def test_forward_pass_no_head(self): + model = TFLayoutLMModel.from_pretrained("microsoft/layoutlm-base-uncased") + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids) + + # test the sequence output on [0, :3, :3] + expected_slice = tf.convert_to_tensor( + [[0.1785, -0.1947, -0.0425], [-0.3254, -0.2807, 0.2553], [-0.5391, -0.3322, 0.3364]], + ) + + self.assertTrue(np.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-3)) + + # test the pooled output on [1, :3] + expected_slice = tf.convert_to_tensor([-0.6580, -0.0214, 0.8552]) + + self.assertTrue(np.allclose(outputs.pooler_output[1, :3], expected_slice, atol=1e-3)) + + @slow + def test_forward_pass_sequence_classification(self): + # initialize model with randomly initialized sequence classification head + model = TFLayoutLMForSequenceClassification.from_pretrained("microsoft/layoutlm-base-uncased", num_labels=2) + + input_ids, attention_mask, bbox, token_type_ids, _ = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model( + input_ids=input_ids, + bbox=bbox, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + labels=tf.convert_to_tensor([1, 1]), + ) + + # test whether we get a loss as a scalar + loss = outputs.loss + expected_shape = (2,) + self.assertEqual(loss.shape, expected_shape) + + # test the shape of the logits + logits = outputs.logits + expected_shape = (2, 2) + self.assertEqual(logits.shape, expected_shape) + + @slow + def test_forward_pass_token_classification(self): + # initialize model with randomly initialized token classification head + model = TFLayoutLMForTokenClassification.from_pretrained("microsoft/layoutlm-base-uncased", num_labels=13) + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model( + input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids, labels=labels + ) + + # test the shape of the logits + logits = outputs.logits + expected_shape = tf.convert_to_tensor((2, 25, 13)) + self.assertEqual(logits.shape, expected_shape) + + @slow + def test_forward_pass_question_answering(self): + # initialize model with randomly initialized token classification head + model = TFLayoutLMForQuestionAnswering.from_pretrained("microsoft/layoutlm-base-uncased") + + input_ids, attention_mask, bbox, token_type_ids, labels = prepare_layoutlm_batch_inputs() + + # forward pass + outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids) + + # test the shape of the logits + expected_shape = tf.convert_to_tensor((2, 25)) + self.assertEqual(outputs.start_logits.shape, expected_shape) + self.assertEqual(outputs.end_logits.shape, expected_shape) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_tokenization_layoutlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_tokenization_layoutlm.py new file mode 100644 index 0000000000000000000000000000000000000000..b73b2aa8e4465826f30f732f2dd66c92715f11ce --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlm/test_tokenization_layoutlm.py @@ -0,0 +1,73 @@ +# coding=utf-8 +# Copyright 2018 The Microsoft Research Asia LayoutLM Team Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os +import unittest + +from transformers import LayoutLMTokenizer, LayoutLMTokenizerFast +from transformers.models.layoutlm.tokenization_layoutlm import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class LayoutLMTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LayoutLMTokenizer + rust_tokenizer_class = LayoutLMTokenizerFast + test_rust_tokenizer = True + space_between_special_tokens = True + + def setUp(self): + super().setUp() + + vocab_tokens = [ + "[UNK]", + "[CLS]", + "[SEP]", + "want", + "##want", + "##ed", + "wa", + "un", + "runn", + "##ing", + ",", + "low", + "lowest", + ] + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + def get_tokenizer(self, **kwargs): + return LayoutLMTokenizer.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "UNwant\u00E9d,running" + output_text = "unwanted, running" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.tokenizer_class(self.vocab_file) + + tokens = tokenizer.tokenize("UNwant\u00E9d,running") + self.assertListEqual(tokens, ["un", "##want", "##ed", ",", "runn", "##ing"]) + self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [7, 4, 5, 10, 8, 9]) + + def test_special_tokens_as_you_expect(self): + """If you are training a seq2seq model that expects a decoder_prefix token make sure it is prepended to decoder_input_ids""" + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py new file mode 100644 index 0000000000000000000000000000000000000000..52bb80e14c98d5ebd5cbf60ee19a0e773065cca0 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_image_processing_layoutlmv2.py @@ -0,0 +1,220 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_pytesseract, require_torch +from transformers.utils import is_pytesseract_available, is_torch_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_pytesseract_available(): + from PIL import Image + + from transformers import LayoutLMv2ImageProcessor + + +class LayoutLMv2ImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + apply_ocr=True, + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.apply_ocr = apply_ocr + + def prepare_image_processor_dict(self): + return {"do_resize": self.do_resize, "size": self.size, "apply_ocr": self.apply_ocr} + + +@require_torch +@require_pytesseract +class LayoutLMv2ImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = LayoutLMv2ImageProcessor if is_pytesseract_available() else None + + def setUp(self): + self.image_processor_tester = LayoutLMv2ImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "apply_ocr")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoding = image_processing(image_inputs[0], return_tensors="pt") + self.assertEqual( + encoding.pixel_values.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + self.assertIsInstance(encoding.words, list) + self.assertIsInstance(encoding.boxes, list) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_layoutlmv2_integration_test(self): + # with apply_OCR = True + image_processing = LayoutLMv2ImageProcessor() + + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/fixtures_docvqa", split="test") + + image = Image.open(ds[0]["file"]).convert("RGB") + + encoding = image_processing(image, return_tensors="pt") + + self.assertEqual(encoding.pixel_values.shape, (1, 3, 224, 224)) + self.assertEqual(len(encoding.words), len(encoding.boxes)) + + # fmt: off + # the words and boxes were obtained with Tesseract 4.1.1 + expected_words = [['11:14', 'to', '11:39', 'a.m', '11:39', 'to', '11:44', 'a.m.', '11:44', 'a.m.', 'to', '12:25', 'p.m.', '12:25', 'to', '12:58', 'p.m.', '12:58', 'to', '4:00', 'p.m.', '2:00', 'to', '5:00', 'p.m.', 'Coffee', 'Break', 'Coffee', 'will', 'be', 'served', 'for', 'men', 'and', 'women', 'in', 'the', 'lobby', 'adjacent', 'to', 'exhibit', 'area.', 'Please', 'move', 'into', 'exhibit', 'area.', '(Exhibits', 'Open)', 'TRRF', 'GENERAL', 'SESSION', '(PART', '|)', 'Presiding:', 'Lee', 'A.', 'Waller', 'TRRF', 'Vice', 'President', '“Introductory', 'Remarks”', 'Lee', 'A.', 'Waller,', 'TRRF', 'Vice', 'Presi-', 'dent', 'Individual', 'Interviews', 'with', 'TRRF', 'Public', 'Board', 'Members', 'and', 'Sci-', 'entific', 'Advisory', 'Council', 'Mem-', 'bers', 'Conducted', 'by', 'TRRF', 'Treasurer', 'Philip', 'G.', 'Kuehn', 'to', 'get', 'answers', 'which', 'the', 'public', 'refrigerated', 'warehousing', 'industry', 'is', 'looking', 'for.', 'Plus', 'questions', 'from', 'the', 'floor.', 'Dr.', 'Emil', 'M.', 'Mrak,', 'University', 'of', 'Cal-', 'ifornia,', 'Chairman,', 'TRRF', 'Board;', 'Sam', 'R.', 'Cecil,', 'University', 'of', 'Georgia', 'College', 'of', 'Agriculture;', 'Dr.', 'Stanley', 'Charm,', 'Tufts', 'University', 'School', 'of', 'Medicine;', 'Dr.', 'Robert', 'H.', 'Cotton,', 'ITT', 'Continental', 'Baking', 'Company;', 'Dr.', 'Owen', 'Fennema,', 'University', 'of', 'Wis-', 'consin;', 'Dr.', 'Robert', 'E.', 'Hardenburg,', 'USDA.', 'Questions', 'and', 'Answers', 'Exhibits', 'Open', 'Capt.', 'Jack', 'Stoney', 'Room', 'TRRF', 'Scientific', 'Advisory', 'Council', 'Meeting', 'Ballroom', 'Foyer']] # noqa: E231 + expected_boxes = [[[141, 57, 214, 69], [228, 58, 252, 69], [141, 75, 216, 88], [230, 79, 280, 88], [142, 260, 218, 273], [230, 261, 255, 273], [143, 279, 218, 290], [231, 282, 290, 291], [143, 342, 218, 354], [231, 345, 289, 355], [202, 362, 227, 373], [143, 379, 220, 392], [231, 382, 291, 394], [144, 714, 220, 726], [231, 715, 256, 726], [144, 732, 220, 745], [232, 736, 291, 747], [144, 769, 218, 782], [231, 770, 256, 782], [141, 788, 202, 801], [215, 791, 274, 804], [143, 826, 204, 838], [215, 826, 240, 838], [142, 844, 202, 857], [215, 847, 274, 859], [334, 57, 427, 69], [440, 57, 522, 69], [369, 75, 461, 88], [469, 75, 516, 88], [528, 76, 562, 88], [570, 76, 667, 88], [675, 75, 711, 87], [721, 79, 778, 88], [789, 75, 840, 88], [369, 97, 470, 107], [484, 94, 507, 106], [518, 94, 562, 107], [576, 94, 655, 110], [668, 94, 792, 109], [804, 95, 829, 107], [369, 113, 465, 125], [477, 116, 547, 125], [562, 113, 658, 125], [671, 116, 748, 125], [761, 113, 811, 125], [369, 131, 465, 143], [477, 133, 548, 143], [563, 130, 698, 145], [710, 130, 802, 146], [336, 171, 412, 183], [423, 171, 572, 183], [582, 170, 716, 184], [728, 171, 817, 187], [829, 171, 844, 186], [338, 197, 482, 212], [507, 196, 557, 209], [569, 196, 595, 208], [610, 196, 702, 209], [505, 214, 583, 226], [595, 214, 656, 227], [670, 215, 807, 227], [335, 259, 543, 274], [556, 259, 708, 272], [372, 279, 422, 291], [435, 279, 460, 291], [474, 279, 574, 292], [587, 278, 664, 291], [676, 278, 738, 291], [751, 279, 834, 291], [372, 298, 434, 310], [335, 341, 483, 354], [497, 341, 655, 354], [667, 341, 728, 354], [740, 341, 825, 354], [335, 360, 430, 372], [442, 360, 534, 372], [545, 359, 687, 372], [697, 360, 754, 372], [765, 360, 823, 373], [334, 378, 428, 391], [440, 378, 577, 394], [590, 378, 705, 391], [720, 378, 801, 391], [334, 397, 400, 409], [370, 416, 529, 429], [544, 416, 576, 432], [587, 416, 665, 428], [677, 416, 814, 429], [372, 435, 452, 450], [465, 434, 495, 447], [511, 434, 600, 447], [611, 436, 637, 447], [649, 436, 694, 451], [705, 438, 824, 447], [369, 453, 452, 466], [464, 454, 509, 466], [522, 453, 611, 469], [625, 453, 792, 469], [370, 472, 556, 488], [570, 472, 684, 487], [697, 472, 718, 485], [732, 472, 835, 488], [369, 490, 411, 503], [425, 490, 484, 503], [496, 490, 635, 506], [645, 490, 707, 503], [718, 491, 761, 503], [771, 490, 840, 503], [336, 510, 374, 521], [388, 510, 447, 522], [460, 510, 489, 521], [503, 510, 580, 522], [592, 509, 736, 525], [745, 509, 770, 522], [781, 509, 840, 522], [338, 528, 434, 541], [448, 528, 596, 541], [609, 527, 687, 540], [700, 528, 792, 541], [336, 546, 397, 559], [407, 546, 431, 559], [443, 546, 525, 560], [537, 546, 680, 562], [688, 546, 714, 559], [722, 546, 837, 562], [336, 565, 449, 581], [461, 565, 485, 577], [497, 565, 665, 581], [681, 565, 718, 577], [732, 565, 837, 580], [337, 584, 438, 597], [452, 583, 521, 596], [535, 584, 677, 599], [690, 583, 787, 596], [801, 583, 825, 596], [338, 602, 478, 615], [492, 602, 530, 614], [543, 602, 638, 615], [650, 602, 676, 614], [688, 602, 788, 615], [802, 602, 843, 614], [337, 621, 502, 633], [516, 621, 615, 637], [629, 621, 774, 636], [789, 621, 827, 633], [337, 639, 418, 652], [432, 640, 571, 653], [587, 639, 731, 655], [743, 639, 769, 652], [780, 639, 841, 652], [338, 658, 440, 673], [455, 658, 491, 670], [508, 658, 602, 671], [616, 658, 638, 670], [654, 658, 835, 674], [337, 677, 429, 689], [337, 714, 482, 726], [495, 714, 548, 726], [561, 714, 683, 726], [338, 770, 461, 782], [474, 769, 554, 785], [489, 788, 562, 803], [576, 788, 643, 801], [656, 787, 751, 804], [764, 788, 844, 801], [334, 825, 421, 838], [430, 824, 574, 838], [584, 824, 723, 841], [335, 844, 450, 857], [464, 843, 583, 860], [628, 862, 755, 875], [769, 861, 848, 878]]] # noqa: E231 + # fmt: on + + self.assertListEqual(encoding.words, expected_words) + self.assertListEqual(encoding.boxes, expected_boxes) + + # with apply_OCR = False + image_processing = LayoutLMv2ImageProcessor(apply_ocr=False) + + encoding = image_processing(image, return_tensors="pt") + + self.assertEqual(encoding.pixel_values.shape, (1, 3, 224, 224)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_modeling_layoutlmv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_modeling_layoutlmv2.py new file mode 100644 index 0000000000000000000000000000000000000000..c2b7fe34ee73f8ec853560a7b97ef40be68c0150 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_modeling_layoutlmv2.py @@ -0,0 +1,500 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LayoutLMv2 model. """ + + +import unittest + +from transformers.testing_utils import require_detectron2, require_torch, require_torch_multi_gpu, slow, torch_device +from transformers.utils import is_detectron2_available, is_torch_available + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, _config_zero_init, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + LayoutLMv2Config, + LayoutLMv2ForQuestionAnswering, + LayoutLMv2ForSequenceClassification, + LayoutLMv2ForTokenClassification, + LayoutLMv2Model, + ) + from transformers.models.layoutlmv2.modeling_layoutlmv2 import LAYOUTLMV2_PRETRAINED_MODEL_ARCHIVE_LIST + +if is_detectron2_available(): + from detectron2.structures.image_list import ImageList + + +class LayoutLMv2ModelTester: + def __init__( + self, + parent, + batch_size=2, + num_channels=3, + image_size=4, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=36, + num_hidden_layers=3, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + image_feature_pool_shape=[7, 7, 256], + coordinate_size=6, + shape_size=6, + num_labels=3, + num_choices=4, + scope=None, + range_bbox=1000, + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.image_feature_pool_shape = image_feature_pool_shape + self.coordinate_size = coordinate_size + self.shape_size = shape_size + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.range_bbox = range_bbox + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + bbox = ids_tensor([self.batch_size, self.seq_length, 4], self.range_bbox) + # Ensure that bbox is legal + for i in range(bbox.shape[0]): + for j in range(bbox.shape[1]): + if bbox[i, j, 3] < bbox[i, j, 1]: + t = bbox[i, j, 3] + bbox[i, j, 3] = bbox[i, j, 1] + bbox[i, j, 1] = t + if bbox[i, j, 2] < bbox[i, j, 0]: + t = bbox[i, j, 2] + bbox[i, j, 2] = bbox[i, j, 0] + bbox[i, j, 0] = t + + image = ImageList( + torch.zeros(self.batch_size, self.num_channels, self.image_size, self.image_size, device=torch_device), + self.image_size, + ) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + + config = LayoutLMv2Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + image_feature_pool_shape=self.image_feature_pool_shape, + coordinate_size=self.coordinate_size, + shape_size=self.shape_size, + ) + + # use smaller resnet backbone to make tests faster + config.detectron2_config_args["MODEL.RESNETS.DEPTH"] = 18 + config.detectron2_config_args["MODEL.RESNETS.RES2_OUT_CHANNELS"] = 64 + config.detectron2_config_args["MODEL.RESNETS.NUM_GROUPS"] = 1 + + return config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels + + def create_and_check_model( + self, config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels + ): + model = LayoutLMv2Model(config=config) + model.to(torch_device) + model.eval() + + result = model(input_ids, bbox=bbox, image=image, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, bbox=bbox, image=image, token_type_ids=token_type_ids) + result = model(input_ids, bbox=bbox, image=image) + + # LayoutLMv2 has a different expected sequence length, namely also visual tokens are added + expected_seq_len = self.seq_length + self.image_feature_pool_shape[0] * self.image_feature_pool_shape[1] + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, expected_seq_len, self.hidden_size)) + self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_for_sequence_classification( + self, config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels + ): + config.num_labels = self.num_labels + model = LayoutLMv2ForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + image=image, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=sequence_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels + ): + config.num_labels = self.num_labels + model = LayoutLMv2ForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + image=image, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, bbox, image, token_type_ids, input_mask, sequence_labels, token_labels + ): + model = LayoutLMv2ForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + image=image, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + bbox, + image, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "bbox": bbox, + "image": image, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_torch +@require_detectron2 +class LayoutLMv2ModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_pruning = False + test_torchscript = True + test_mismatched_shapes = False + + all_model_classes = ( + ( + LayoutLMv2Model, + LayoutLMv2ForSequenceClassification, + LayoutLMv2ForTokenClassification, + LayoutLMv2ForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "document-question-answering": LayoutLMv2ForQuestionAnswering, + "feature-extraction": LayoutLMv2Model, + } + if is_torch_available() + else {} + ) + + def setUp(self): + self.model_tester = LayoutLMv2ModelTester(self) + self.config_tester = ConfigTester(self, config_class=LayoutLMv2Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @require_torch_multi_gpu + @unittest.skip( + reason=( + "LayoutLMV2 and its dependency `detectron2` have some layers using `add_module` which doesn't work well" + " with `nn.DataParallel`" + ) + ) + def test_multi_gpu_data_parallel_forward(self): + pass + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + # LayoutLMv2 has a different expected sequence length + expected_seq_len = ( + self.model_tester.seq_length + + self.model_tester.image_feature_pool_shape[0] * self.model_tester.image_feature_pool_shape[1] + ) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, expected_seq_len, expected_seq_len], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, expected_seq_len, expected_seq_len], + ) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + # LayoutLMv2 has a different expected sequence length + expected_seq_len = ( + self.model_tester.seq_length + + self.model_tester.image_feature_pool_shape[0] * self.model_tester.image_feature_pool_shape[1] + ) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [expected_seq_len, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + @slow + def test_model_from_pretrained(self): + for model_name in LAYOUTLMV2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = LayoutLMv2Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if "backbone" in name or "visual_segment_embedding" in name: + continue + + if param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + +def prepare_layoutlmv2_batch_inputs(): + # Here we prepare a batch of 2 sequences to test a LayoutLMv2 forward pass on: + # fmt: off + input_ids = torch.tensor([[101,1019,1014,1016,1037,12849,4747,1004,14246,2278,5439,4524,5002,2930,2193,2930,4341,3208,1005,1055,2171,2848,11300,3531,102],[101,4070,4034,7020,1024,3058,1015,1013,2861,1013,6070,19274,2772,6205,27814,16147,16147,4343,2047,10283,10969,14389,1012,2338,102]]) # noqa: E231 + bbox = torch.tensor([[[0,0,0,0],[423,237,440,251],[427,272,441,287],[419,115,437,129],[961,885,992,912],[256,38,330,58],[256,38,330,58],[336,42,353,57],[360,39,401,56],[360,39,401,56],[411,39,471,59],[479,41,528,59],[533,39,630,60],[67,113,134,131],[141,115,209,132],[68,149,133,166],[141,149,187,164],[195,148,287,165],[195,148,287,165],[195,148,287,165],[295,148,349,165],[441,149,492,166],[497,149,546,164],[64,201,125,218],[1000,1000,1000,1000]],[[0,0,0,0],[662,150,754,166],[665,199,742,211],[519,213,554,228],[519,213,554,228],[134,433,187,454],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[314,469,376,482],[504,684,582,706],[941,825,973,900],[941,825,973,900],[941,825,973,900],[941,825,973,900],[610,749,652,765],[130,659,168,672],[176,657,237,672],[238,657,312,672],[443,653,628,672],[443,653,628,672],[716,301,825,317],[1000,1000,1000,1000]]]) # noqa: E231 + image = ImageList(torch.randn((2,3,224,224)), image_sizes=[(224,224), (224,224)]) # noqa: E231 + attention_mask = torch.tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],]) # noqa: E231 + token_type_ids = torch.tensor([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]) # noqa: E231 + # fmt: on + + return input_ids, bbox, image, attention_mask, token_type_ids + + +@require_torch +@require_detectron2 +class LayoutLMv2ModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head(self): + model = LayoutLMv2Model.from_pretrained("microsoft/layoutlmv2-base-uncased").to(torch_device) + + ( + input_ids, + bbox, + image, + attention_mask, + token_type_ids, + ) = prepare_layoutlmv2_batch_inputs() + + # forward pass + outputs = model( + input_ids=input_ids.to(torch_device), + bbox=bbox.to(torch_device), + image=image.to(torch_device), + attention_mask=attention_mask.to(torch_device), + token_type_ids=token_type_ids.to(torch_device), + ) + + # verify the sequence output + expected_shape = torch.Size( + ( + 2, + input_ids.shape[1] + + model.config.image_feature_pool_shape[0] * model.config.image_feature_pool_shape[1], + model.config.hidden_size, + ) + ) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor( + [[-0.1087, 0.0727, -0.3075], [0.0799, -0.0427, -0.0751], [-0.0367, 0.0480, -0.1358]], device=torch_device + ) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-3)) + + # verify the pooled output + expected_shape = torch.Size((2, model.config.hidden_size)) + self.assertEqual(outputs.pooler_output.shape, expected_shape) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_processor_layoutlmv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_processor_layoutlmv2.py new file mode 100644 index 0000000000000000000000000000000000000000..91a8da9cafb0a3b37db2f06b7d43bcf2ebe7f507 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_processor_layoutlmv2.py @@ -0,0 +1,489 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest +from typing import List + +import numpy as np + +from transformers import PreTrainedTokenizer, PreTrainedTokenizerBase, PreTrainedTokenizerFast +from transformers.models.layoutlmv2 import LayoutLMv2Tokenizer, LayoutLMv2TokenizerFast +from transformers.models.layoutlmv2.tokenization_layoutlmv2 import VOCAB_FILES_NAMES +from transformers.testing_utils import require_pytesseract, require_tokenizers, require_torch, slow +from transformers.utils import FEATURE_EXTRACTOR_NAME, cached_property, is_pytesseract_available + + +if is_pytesseract_available(): + from PIL import Image + + from transformers import LayoutLMv2ImageProcessor, LayoutLMv2Processor + + +@require_pytesseract +@require_tokenizers +class LayoutLMv2ProcessorTest(unittest.TestCase): + tokenizer_class = LayoutLMv2Tokenizer + rust_tokenizer_class = LayoutLMv2TokenizerFast + + def setUp(self): + vocab_tokens = [ + "[UNK]", + "[CLS]", + "[SEP]", + "[PAD]", + "[MASK]", + "want", + "##want", + "##ed", + "wa", + "un", + "runn", + "##ing", + ",", + "low", + "lowest", + ] + + image_processor_map = { + "do_resize": True, + "size": 224, + "apply_ocr": True, + } + + self.tmpdirname = tempfile.mkdtemp() + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + self.image_processing_file = os.path.join(self.tmpdirname, FEATURE_EXTRACTOR_NAME) + with open(self.image_processing_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(image_processor_map) + "\n") + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs) -> PreTrainedTokenizerFast: + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_tokenizers(self, **kwargs) -> List[PreTrainedTokenizerBase]: + return [self.get_tokenizer(**kwargs), self.get_rust_tokenizer(**kwargs)] + + def get_image_processor(self, **kwargs): + return LayoutLMv2ImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + image_processor = self.get_image_processor() + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + processor.save_pretrained(self.tmpdirname) + processor = LayoutLMv2Processor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertIsInstance(processor.tokenizer, (LayoutLMv2Tokenizer, LayoutLMv2TokenizerFast)) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv2ImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = LayoutLMv2Processor(image_processor=self.get_image_processor(), tokenizer=self.get_tokenizer()) + processor.save_pretrained(self.tmpdirname) + + # slow tokenizer + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_resize=False, size=30) + + processor = LayoutLMv2Processor.from_pretrained( + self.tmpdirname, use_fast=False, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutLMv2Tokenizer) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv2ImageProcessor) + + # fast tokenizer + tokenizer_add_kwargs = self.get_rust_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_resize=False, size=30) + + processor = LayoutLMv2Processor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutLMv2TokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv2ImageProcessor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = LayoutLMv2Processor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + # add extra args + inputs = processor(text=input_str, images=image_input, return_codebook_pixels=False, return_image_mask=False) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) + + @slow + def test_overflowing_tokens(self): + # In the case of overflowing tokens, test that we still have 1-to-1 mapping between the images and input_ids (sequences that are too long are broken down into multiple sequences). + + from datasets import load_dataset + + # set up + datasets = load_dataset("nielsr/funsd") + processor = LayoutLMv2Processor.from_pretrained("microsoft/layoutlmv2-base-uncased", revision="no_ocr") + + def preprocess_data(examples): + images = [Image.open(path).convert("RGB") for path in examples["image_path"]] + words = examples["words"] + boxes = examples["bboxes"] + word_labels = examples["ner_tags"] + encoded_inputs = processor( + images, + words, + boxes=boxes, + word_labels=word_labels, + padding="max_length", + truncation=True, + return_overflowing_tokens=True, + stride=50, + return_offsets_mapping=True, + return_tensors="pt", + ) + return encoded_inputs + + train_data = preprocess_data(datasets["train"]) + + self.assertEqual(len(train_data["image"]), len(train_data["input_ids"])) + + +# different use cases tests +@require_torch +@require_pytesseract +class LayoutLMv2ProcessorIntegrationTests(unittest.TestCase): + @cached_property + def get_images(self): + # we verify our implementation on 2 document images from the DocVQA dataset + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/fixtures_docvqa", split="test") + + image_1 = Image.open(ds[0]["file"]).convert("RGB") + image_2 = Image.open(ds[1]["file"]).convert("RGB") + + return image_1, image_2 + + @cached_property + def get_tokenizers(self): + slow_tokenizer = LayoutLMv2Tokenizer.from_pretrained("microsoft/layoutlmv2-base-uncased") + fast_tokenizer = LayoutLMv2TokenizerFast.from_pretrained("microsoft/layoutlmv2-base-uncased") + return [slow_tokenizer, fast_tokenizer] + + @slow + def test_processor_case_1(self): + # case 1: document image classification (training, inference) + token classification (inference), apply_ocr = True + + image_processor = LayoutLMv2ImageProcessor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + input_image_proc = image_processor(images[0], return_tensors="pt") + input_processor = processor(images[0], return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify image + self.assertAlmostEqual(input_image_proc["pixel_values"].sum(), input_processor["image"].sum(), delta=1e-2) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = "[CLS] 11 : 14 to 11 : 39 a. m 11 : 39 to 11 : 44 a. m. 11 : 44 a. m. to 12 : 25 p. m. 12 : 25 to 12 : 58 p. m. 12 : 58 to 4 : 00 p. m. 2 : 00 to 5 : 00 p. m. coffee break coffee will be served for men and women in the lobby adjacent to exhibit area. please move into exhibit area. ( exhibits open ) trrf general session ( part | ) presiding : lee a. waller trrf vice president “ introductory remarks ” lee a. waller, trrf vice presi - dent individual interviews with trrf public board members and sci - entific advisory council mem - bers conducted by trrf treasurer philip g. kuehn to get answers which the public refrigerated warehousing industry is looking for. plus questions from the floor. dr. emil m. mrak, university of cal - ifornia, chairman, trrf board ; sam r. cecil, university of georgia college of agriculture ; dr. stanley charm, tufts university school of medicine ; dr. robert h. cotton, itt continental baking company ; dr. owen fennema, university of wis - consin ; dr. robert e. hardenburg, usda. questions and answers exhibits open capt. jack stoney room trrf scientific advisory council meeting ballroom foyer [SEP]" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + input_image_proc = image_processor(images, return_tensors="pt") + input_processor = processor(images, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify images + self.assertAlmostEqual(input_image_proc["pixel_values"].sum(), input_processor["image"].sum(), delta=1e-2) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = "[CLS] 7 itc limited report and accounts 2013 itc ’ s brands : an asset for the nation the consumer needs and aspirations they fulfil, the benefit they generate for millions across itc ’ s value chains, the future - ready capabilities that support them, and the value that they create for the country, have made itc ’ s brands national assets, adding to india ’ s competitiveness. it is itc ’ s aspiration to be the no 1 fmcg player in the country, driven by its new fmcg businesses. a recent nielsen report has highlighted that itc's new fmcg businesses are the fastest growing among the top consumer goods companies operating in india. itc takes justifiable pride that, along with generating economic value, these celebrated indian brands also drive the creation of larger societal capital through the virtuous cycle of sustainable and inclusive growth. di wills * ; love delightfully soft skin? aia ans source : https : / / www. industrydocuments. ucsf. edu / docs / snbx0223 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + @slow + def test_processor_case_2(self): + # case 2: document image classification (training, inference) + token classification (inference), apply_ocr=False + + image_processor = LayoutLMv2ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], words, boxes=boxes, return_tensors="pt") + + # verify keys + expected_keys = ["input_ids", "bbox", "token_type_ids", "attention_mask", "image"] + actual_keys = list(input_processor.keys()) + for key in expected_keys: + self.assertIn(key, actual_keys) + + # verify input_ids + expected_decoding = "[CLS] hello world [SEP]" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, words, boxes=boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "[CLS] hello world [SEP] [PAD] [PAD] [PAD]" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [1000, 1000, 1000, 1000], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_3(self): + # case 3: token classification (training), apply_ocr=False + + image_processor = LayoutLMv2ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + words = ["weirdly", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + word_labels = [1, 2] + input_processor = processor(images[0], words, boxes=boxes, word_labels=word_labels, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "labels", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "[CLS] weirdly world [SEP]" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify labels + expected_labels = [-100, 1, -100, 2, -100] + self.assertListEqual(input_processor.labels.squeeze().tolist(), expected_labels) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + word_labels = [[1, 2], [6, 3, 10, 2]] + input_processor = processor( + images, words, boxes=boxes, word_labels=word_labels, padding=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "labels", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "[CLS] my name is niels [SEP]" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [1000, 1000, 1000, 1000], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + # verify labels + expected_labels = [-100, 6, 3, 10, 2, -100, -100] + self.assertListEqual(input_processor.labels[1].tolist(), expected_labels) + + @slow + def test_processor_case_4(self): + # case 4: visual question answering (inference), apply_ocr=True + + image_processor = LayoutLMv2ImageProcessor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + input_processor = processor(images[0], question, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = "[CLS] what's his name? [SEP] 11 : 14 to 11 : 39 a. m 11 : 39 to 11 : 44 a. m. 11 : 44 a. m. to 12 : 25 p. m. 12 : 25 to 12 : 58 p. m. 12 : 58 to 4 : 00 p. m. 2 : 00 to 5 : 00 p. m. coffee break coffee will be served for men and women in the lobby adjacent to exhibit area. please move into exhibit area. ( exhibits open ) trrf general session ( part | ) presiding : lee a. waller trrf vice president “ introductory remarks ” lee a. waller, trrf vice presi - dent individual interviews with trrf public board members and sci - entific advisory council mem - bers conducted by trrf treasurer philip g. kuehn to get answers which the public refrigerated warehousing industry is looking for. plus questions from the floor. dr. emil m. mrak, university of cal - ifornia, chairman, trrf board ; sam r. cecil, university of georgia college of agriculture ; dr. stanley charm, tufts university school of medicine ; dr. robert h. cotton, itt continental baking company ; dr. owen fennema, university of wis - consin ; dr. robert e. hardenburg, usda. questions and answers exhibits open capt. jack stoney room trrf scientific advisory council meeting ballroom foyer [SEP]" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + input_processor = processor( + images, questions, padding="max_length", max_length=20, truncation=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + expected_decoding = "[CLS] what's the time [SEP] 7 itc limited report and accounts 2013 itc ’ s [SEP]" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + # fmt: off + expected_bbox = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [0, 45, 67, 80], [72, 56, 109, 67], [72, 56, 109, 67], [116, 56, 189, 67], [198, 59, 253, 66], [257, 59, 285, 66], [289, 59, 365, 66], [372, 59, 407, 66], [74, 136, 161, 158], [74, 136, 161, 158], [74, 136, 161, 158], [74, 136, 161, 158], [1000, 1000, 1000, 1000]] # noqa: E231 + # fmt: on + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_5(self): + # case 5: visual question answering (inference), apply_ocr=False + + image_processor = LayoutLMv2ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv2Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], question, words, boxes, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "[CLS] what's his name? [SEP] hello world [SEP]" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, questions, words, boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "token_type_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "[CLS] how old is he? [SEP] hello world [SEP] [PAD] [PAD] [PAD]" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + expected_decoding = "[CLS] what's the time [SEP] my name is niels [SEP]" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [[6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3], [1, 1, 2, 3], [1000, 1000, 1000, 1000]] + self.assertListEqual(input_processor.bbox[1].tolist()[-5:], expected_bbox) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py new file mode 100644 index 0000000000000000000000000000000000000000..9224fbd87ea49cfcbe1f66e979078aecefa66b59 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv2/test_tokenization_layoutlmv2.py @@ -0,0 +1,2484 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import inspect +import os +import re +import shutil +import tempfile +import unittest +from typing import List + +from transformers import ( + AddedToken, + LayoutLMv2TokenizerFast, + SpecialTokensMixin, + is_tf_available, + is_torch_available, + logging, +) +from transformers.models.layoutlmv2.tokenization_layoutlmv2 import ( + VOCAB_FILES_NAMES, + BasicTokenizer, + LayoutLMv2Tokenizer, + WordpieceTokenizer, + _is_control, + _is_punctuation, + _is_whitespace, +) +from transformers.testing_utils import ( + is_pt_tf_cross_test, + require_detectron2, + require_pandas, + require_tokenizers, + require_torch, + slow, +) + +from ...test_tokenization_common import ( + SMALL_TRAINING_CORPUS, + TokenizerTesterMixin, + filter_non_english, + merge_model_tokenizer_mappings, +) + + +logger = logging.get_logger(__name__) + + +@require_tokenizers +@require_pandas +class LayoutLMv2TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LayoutLMv2Tokenizer + rust_tokenizer_class = LayoutLMv2TokenizerFast + test_rust_tokenizer = True + space_between_special_tokens = True + from_pretrained_filter = filter_non_english + test_seq2seq = False + + def get_words_and_boxes(self): + words = ["a", "weirdly", "test"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]] + + return words, boxes + + def get_words_and_boxes_batch(self): + words = [["a", "weirdly", "test"], ["hello", "my", "name", "is", "bob"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]], + [[961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69]], + ] + + return words, boxes + + def get_question_words_and_boxes(self): + question = "what's his name?" + words = ["a", "weirdly", "test"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]] + + return question, words, boxes + + def get_question_words_and_boxes_batch(self): + questions = ["what's his name?", "how is he called?"] + words = [["a", "weirdly", "test"], ["what", "a", "laif", "gastn"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]], + [[256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69]], + ] + + return questions, words, boxes + + def setUp(self): + super().setUp() + + vocab_tokens = [ + "[UNK]", + "[CLS]", + "[SEP]", + "[PAD]", + "[MASK]", + "what", + "s", + "his", + "name", + "?", + "a", + "weird", + "##ly", + "test", + "lowest", + ] + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in vocab_tokens])) + + def get_input_output_texts(self, tokenizer): + input_text = "UNwant\u00E9d,running" + output_text = "unwanted, running" + return input_text, output_text + + def test_chinese(self): + tokenizer = BasicTokenizer() + + self.assertListEqual(tokenizer.tokenize("ah\u535A\u63A8zz"), ["ah", "\u535A", "\u63A8", "zz"]) + + def test_basic_tokenizer_lower(self): + tokenizer = BasicTokenizer(do_lower_case=True) + + self.assertListEqual( + tokenizer.tokenize(" \tHeLLo!how \n Are yoU? "), ["hello", "!", "how", "are", "you", "?"] + ) + self.assertListEqual(tokenizer.tokenize("H\u00E9llo"), ["hello"]) + + def test_basic_tokenizer_lower_strip_accents_false(self): + tokenizer = BasicTokenizer(do_lower_case=True, strip_accents=False) + + self.assertListEqual( + tokenizer.tokenize(" \tHäLLo!how \n Are yoU? "), ["hällo", "!", "how", "are", "you", "?"] + ) + self.assertListEqual(tokenizer.tokenize("H\u00E9llo"), ["h\u00E9llo"]) + + def test_basic_tokenizer_lower_strip_accents_true(self): + tokenizer = BasicTokenizer(do_lower_case=True, strip_accents=True) + + self.assertListEqual( + tokenizer.tokenize(" \tHäLLo!how \n Are yoU? "), ["hallo", "!", "how", "are", "you", "?"] + ) + self.assertListEqual(tokenizer.tokenize("H\u00E9llo"), ["hello"]) + + def test_basic_tokenizer_lower_strip_accents_default(self): + tokenizer = BasicTokenizer(do_lower_case=True) + + self.assertListEqual( + tokenizer.tokenize(" \tHäLLo!how \n Are yoU? "), ["hallo", "!", "how", "are", "you", "?"] + ) + self.assertListEqual(tokenizer.tokenize("H\u00E9llo"), ["hello"]) + + def test_basic_tokenizer_no_lower(self): + tokenizer = BasicTokenizer(do_lower_case=False) + + self.assertListEqual( + tokenizer.tokenize(" \tHeLLo!how \n Are yoU? "), ["HeLLo", "!", "how", "Are", "yoU", "?"] + ) + + def test_basic_tokenizer_no_lower_strip_accents_false(self): + tokenizer = BasicTokenizer(do_lower_case=False, strip_accents=False) + + self.assertListEqual( + tokenizer.tokenize(" \tHäLLo!how \n Are yoU? "), ["HäLLo", "!", "how", "Are", "yoU", "?"] + ) + + def test_basic_tokenizer_no_lower_strip_accents_true(self): + tokenizer = BasicTokenizer(do_lower_case=False, strip_accents=True) + + self.assertListEqual( + tokenizer.tokenize(" \tHäLLo!how \n Are yoU? "), ["HaLLo", "!", "how", "Are", "yoU", "?"] + ) + + def test_basic_tokenizer_respects_never_split_tokens(self): + tokenizer = BasicTokenizer(do_lower_case=False, never_split=["[UNK]"]) + + self.assertListEqual( + tokenizer.tokenize(" \tHeLLo!how \n Are yoU? [UNK]"), ["HeLLo", "!", "how", "Are", "yoU", "?", "[UNK]"] + ) + + def test_wordpiece_tokenizer(self): + vocab_tokens = ["[UNK]", "[CLS]", "[SEP]", "want", "##want", "##ed", "wa", "un", "runn", "##ing"] + + vocab = {} + for i, token in enumerate(vocab_tokens): + vocab[token] = i + tokenizer = WordpieceTokenizer(vocab=vocab, unk_token="[UNK]") + + self.assertListEqual(tokenizer.tokenize(""), []) + + self.assertListEqual(tokenizer.tokenize("unwanted running"), ["un", "##want", "##ed", "runn", "##ing"]) + + self.assertListEqual(tokenizer.tokenize("unwantedX running"), ["[UNK]", "runn", "##ing"]) + + def test_is_whitespace(self): + self.assertTrue(_is_whitespace(" ")) + self.assertTrue(_is_whitespace("\t")) + self.assertTrue(_is_whitespace("\r")) + self.assertTrue(_is_whitespace("\n")) + self.assertTrue(_is_whitespace("\u00A0")) + + self.assertFalse(_is_whitespace("A")) + self.assertFalse(_is_whitespace("-")) + + def test_is_control(self): + self.assertTrue(_is_control("\u0005")) + + self.assertFalse(_is_control("A")) + self.assertFalse(_is_control(" ")) + self.assertFalse(_is_control("\t")) + self.assertFalse(_is_control("\r")) + + def test_is_punctuation(self): + self.assertTrue(_is_punctuation("-")) + self.assertTrue(_is_punctuation("$")) + self.assertTrue(_is_punctuation("`")) + self.assertTrue(_is_punctuation(".")) + + self.assertFalse(_is_punctuation("A")) + self.assertFalse(_is_punctuation(" ")) + + def test_clean_text(self): + tokenizer = self.get_tokenizer() + + # Example taken from the issue https://github.com/huggingface/tokenizers/issues/340 + self.assertListEqual([tokenizer.tokenize(t) for t in ["Hello", "\xad", "hello"]], [["[UNK]"], [], ["[UNK]"]]) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("microsoft/layoutlmv2-base-uncased") + + question, words, boxes = self.get_question_words_and_boxes() + + text = tokenizer.encode( + question.split(), + boxes=[tokenizer.pad_token_box for _ in range(len(question.split()))], + add_special_tokens=False, + ) + text_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_pair == [101] + text + [102] + text_2 + [102] + + def test_offsets_with_special_characters(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words, boxes = self.get_words_and_boxes() + words[1] = tokenizer_r.mask_token + tokens = tokenizer_r.encode_plus( + words, + boxes=boxes, + return_attention_mask=False, + return_token_type_ids=False, + return_offsets_mapping=True, + add_special_tokens=True, + ) + + expected_results = [ + ((0, 0), tokenizer_r.cls_token), + ((0, 1), "a"), + ((0, 6), tokenizer_r.mask_token), + ((0, 4), "test"), + ((0, 0), tokenizer_r.sep_token), + ] + + self.assertEqual( + [e[1] for e in expected_results], tokenizer_r.convert_ids_to_tokens(tokens["input_ids"]) + ) + self.assertEqual([e[0] for e in expected_results], tokens["offset_mapping"]) + + def test_add_special_tokens(self): + tokenizers: List[LayoutLMv2Tokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + special_token = "[SPECIAL_TOKEN]" + special_token_box = [1000, 1000, 1000, 1000] + + tokenizer.add_special_tokens({"cls_token": special_token}) + encoded_special_token = tokenizer.encode( + [special_token], boxes=[special_token_box], add_special_tokens=False + ) + self.assertEqual(len(encoded_special_token), 1) + + decoded = tokenizer.decode(encoded_special_token, skip_special_tokens=True) + self.assertTrue(special_token not in decoded) + + def test_add_tokens_tokenizer(self): + tokenizers: List[LayoutLMv2Tokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab_size = tokenizer.vocab_size + all_size = len(tokenizer) + + self.assertNotEqual(vocab_size, 0) + + # We usually have added tokens from the start in tests because our vocab fixtures are + # smaller than the original vocabs - let's not assert this + # self.assertEqual(vocab_size, all_size) + + new_toks = ["aaaaa", "bbbbbb", "cccccccccdddddddd"] + added_toks = tokenizer.add_tokens(new_toks) + vocab_size_2 = tokenizer.vocab_size + all_size_2 = len(tokenizer) + + self.assertNotEqual(vocab_size_2, 0) + self.assertEqual(vocab_size, vocab_size_2) + self.assertEqual(added_toks, len(new_toks)) + self.assertEqual(all_size_2, all_size + len(new_toks)) + + words = "aaaaa bbbbbb low cccccccccdddddddd l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + self.assertGreaterEqual(len(tokens), 4) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + + new_toks_2 = {"eos_token": ">>>>|||<||<<|<<", "pad_token": "<<<<<|||>|>>>>|>"} + added_toks_2 = tokenizer.add_special_tokens(new_toks_2) + vocab_size_3 = tokenizer.vocab_size + all_size_3 = len(tokenizer) + + self.assertNotEqual(vocab_size_3, 0) + self.assertEqual(vocab_size, vocab_size_3) + self.assertEqual(added_toks_2, len(new_toks_2)) + self.assertEqual(all_size_3, all_size_2 + len(new_toks_2)) + + words = ">>>>|||<||<<|<< aaaaabbbbbb low cccccccccdddddddd <<<<<|||>|>>>>|> l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode( + words, + boxes=boxes, + add_special_tokens=False, + ) + + self.assertGreaterEqual(len(tokens), 6) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[0], tokens[1]) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokens[-3]) + self.assertEqual(tokens[0], tokenizer.eos_token_id) + self.assertEqual(tokens[-2], tokenizer.pad_token_id) + + @require_tokenizers + def test_encode_decode_with_spaces(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + new_toks = [AddedToken("[ABC]", normalized=False), AddedToken("[DEF]", normalized=False)] + tokenizer.add_tokens(new_toks) + input = "[ABC][DEF][ABC][DEF]" + if self.space_between_special_tokens: + output = "[ABC] [DEF] [ABC] [DEF]" + else: + output = input + encoded = tokenizer.encode(input.split(), boxes=boxes, add_special_tokens=False) + decoded = tokenizer.decode(encoded, spaces_between_special_tokens=self.space_between_special_tokens) + self.assertIn(decoded, [output, output.lower()]) + + @unittest.skip("Not implemented") + def test_right_and_left_truncation(self): + pass + + def test_encode_plus_with_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_size = 10 + padding_idx = tokenizer.pad_token_id + + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_special_tokens_mask=True) + input_ids = encoded_sequence["input_ids"] + special_tokens_mask = encoded_sequence["special_tokens_mask"] + sequence_length = len(input_ids) + + # Test 'longest' and 'no_padding' don't do anything + tokenizer.padding_side = "right" + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + # Test right padding + tokenizer.padding_side = "right" + + right_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + right_padded_input_ids = right_padded_sequence["input_ids"] + + right_padded_special_tokens_mask = right_padded_sequence["special_tokens_mask"] + right_padded_sequence_length = len(right_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == right_padded_sequence_length) + self.assertTrue(input_ids + [padding_idx] * padding_size == right_padded_input_ids) + self.assertTrue(special_tokens_mask + [1] * padding_size == right_padded_special_tokens_mask) + + # Test left padding + tokenizer.padding_side = "left" + left_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + left_padded_input_ids = left_padded_sequence["input_ids"] + left_padded_special_tokens_mask = left_padded_sequence["special_tokens_mask"] + left_padded_sequence_length = len(left_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == left_padded_sequence_length) + self.assertTrue([padding_idx] * padding_size + input_ids == left_padded_input_ids) + self.assertTrue([1] * padding_size + special_tokens_mask == left_padded_special_tokens_mask) + + if "token_type_ids" in tokenizer.model_input_names: + token_type_ids = encoded_sequence["token_type_ids"] + left_padded_token_type_ids = left_padded_sequence["token_type_ids"] + right_padded_token_type_ids = right_padded_sequence["token_type_ids"] + + assert token_type_ids + [0] * padding_size == right_padded_token_type_ids + assert [0] * padding_size + token_type_ids == left_padded_token_type_ids + + if "attention_mask" in tokenizer.model_input_names: + attention_mask = encoded_sequence["attention_mask"] + right_padded_attention_mask = right_padded_sequence["attention_mask"] + left_padded_attention_mask = left_padded_sequence["attention_mask"] + + self.assertTrue(attention_mask + [0] * padding_size == right_padded_attention_mask) + self.assertTrue([0] * padding_size + attention_mask == left_padded_attention_mask) + + def test_internal_consistency(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + tokens = [] + for word in words: + tokens.extend(tokenizer.tokenize(word)) + ids = tokenizer.convert_tokens_to_ids(tokens) + ids_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, ids_2) + + tokens_2 = tokenizer.convert_ids_to_tokens(ids) + self.assertNotEqual(len(tokens_2), 0) + text_2 = tokenizer.decode(ids) + self.assertIsInstance(text_2, str) + + output_text = "a weirdly test" + self.assertEqual(text_2, output_text) + + def test_mask_output(self): + tokenizers = self.get_tokenizers(fast=False, do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + if ( + tokenizer.build_inputs_with_special_tokens.__qualname__.split(".")[0] != "PreTrainedTokenizer" + and "token_type_ids" in tokenizer.model_input_names + ): + information = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + sequences, mask = information["input_ids"], information["token_type_ids"] + self.assertEqual(len(sequences), len(mask)) + + def test_number_of_added_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=False), len(attached_sequences) - len(sequences) + ) + + # test 2: two sequences + question, words, boxes = self.get_question_words_and_boxes() + + sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=True), len(attached_sequences) - len(sequences) + ) + + def test_padding_to_max_length(self): + """We keep this test for backward compatibility but it should be removed when `pad_to_max_length` will be deprecated""" + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_idx = tokenizer.pad_token_id + + # Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + # FIXME: the next line should be padding(max_length) to avoid warning + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, pad_to_max_length=True + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # Check that nothing is done when a maximum length is not specified + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, pad_to_max_length=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + def test_padding(self, max_length=50): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + # Encode - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.encode(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode(words, boxes=boxes, padding=True) + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, padding=True) + input_p = tokenizer_p.encode(question, words, boxes=boxes, padding="longest") + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode_plus - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + input_r = tokenizer_r.encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Encode_plus - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(question, words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(question, words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Batch_encode_plus - Simple input + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="longest", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.batch_encode_plus(words, boxes=boxes, padding=True) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Batch_encode_plus - Pair input + questions, words, boxes = self.get_question_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding=True, + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding="longest", + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad on single examples after tokenization + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p) + + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p) + + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + def test_padding_warning_message_fast_tokenizer(self): + if not self.test_rust_tokenizer: + return + + words, boxes = self.get_words_and_boxes_batch() + + tokenizer_fast = self.get_rust_tokenizer() + + encoding_fast = tokenizer_fast( + words, + boxes=boxes, + ) + + with self.assertLogs("transformers", level="WARNING") as cm: + tokenizer_fast.pad(encoding_fast) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to" + " encode the text followed by a call to the `pad` method to get a padded encoding.", + cm.records[0].message, + ) + + if not self.test_slow_tokenizer: + return + + tokenizer_slow = self.get_tokenizer() + + encoding_slow = tokenizer_slow( + words, + boxes=boxes, + ) + + with self.assertLogs(level="WARNING") as cm: + # We want to assert there are no warnings, but the 'assertLogs' method does not support that. + # Therefore, we are adding a dummy warning, and then we will assert it is the only warning. + logger.warning("Dummy warning") + tokenizer_slow.pad(encoding_slow) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Dummy warning", + cm.records[0].message, + ) + + def test_call(self): + # Tests that all call wrap to encode_plus and batch_encode_plus + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Test not batched + words, boxes = self.get_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test not batched pairs + question, words, boxes = self.get_question_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test batched + words, boxes = self.get_words_and_boxes_batch() + encoded_sequences_1 = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + def test_batch_encode_plus_batch_sequence_length(self): + # Tests that all encoded values have the correct size + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + encoded_sequences = [ + tokenizer.encode_plus(words_example, boxes=boxes_example) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes, padding=False) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + maximum_length = len( + max([encoded_sequence["input_ids"] for encoded_sequence in encoded_sequences], key=len) + ) + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences_padded = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=maximum_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + + encoded_sequences_batch_padded = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + self.assertListEqual( + encoded_sequences_padded, + self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch_padded), + ) + + # check 'longest' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding="longest" + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + # check 'no_padding' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=False + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding=False + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + @unittest.skip("batch_encode_plus does not handle overflowing tokens.") + def test_batch_encode_plus_overflowing_tokens(self): + pass + + def test_batch_encode_plus_padding(self): + # Test that padded sequences are equivalent between batch_encode_plus and encode_plus + + # Right padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + # Left padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokenizer.padding_side = "left" + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + def test_padding_to_multiple_of(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.pad_token is None: + self.skipTest("No padding token.") + else: + words, boxes = self.get_words_and_boxes() + + # empty_tokens = tokenizer([""], [[]], padding=True, pad_to_multiple_of=8) + normal_tokens = tokenizer(words, boxes=boxes, padding=True, pad_to_multiple_of=8) + # for key, value in empty_tokens.items(): + # self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + normal_tokens = tokenizer(words, boxes=boxes, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertNotEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # Should also work with truncation + normal_tokens = tokenizer(words, boxes=boxes, padding=True, truncation=True, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # truncation to something which is not a multiple of pad_to_multiple_of raises an error + self.assertRaises( + ValueError, + tokenizer.__call__, + words, + boxes=boxes, + padding=True, + truncation=True, + max_length=12, + pad_to_multiple_of=8, + ) + + def test_tokenizer_slow_store_full_signature(self): + signature = inspect.signature(self.tokenizer_class.__init__) + tokenizer = self.get_tokenizer() + + for parameter_name, parameter in signature.parameters.items(): + if parameter.default != inspect.Parameter.empty: + self.assertIn(parameter_name, tokenizer.init_kwargs) + + def test_build_inputs_with_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Input tokens id + words, boxes = self.get_words_and_boxes() + input_simple = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + input_pair = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + + # Generate output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple) + self.assertEqual(output_p, output_r) + + # Generate pair output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple, input_pair) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple, input_pair) + self.assertEqual(output_p, output_r) + + def test_special_tokens_mask_input_pairs(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + return_special_tokens_mask=True, + # add_prefix_space=False, + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [ + (x if not special_tokens_mask[i] else None) for i, x in enumerate(encoded_sequence_w_special) + ] + filtered_sequence = [x for x in filtered_sequence if x is not None] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_special_tokens_mask(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + # Testing single inputs + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, boxes=boxes, add_special_tokens=True, return_special_tokens_mask=True + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [x for i, x in enumerate(encoded_sequence_w_special) if not special_tokens_mask[i]] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_save_and_load_tokenizer(self): + # safety check on max_len default value so we are sure the test works + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertNotEqual(tokenizer.model_max_length, 42) + + # Now let's start the test + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + words, boxes = self.get_words_and_boxes() + tmpdirname = tempfile.mkdtemp() + + before_tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + + shutil.rmtree(tmpdirname) + + def test_right_and_left_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + sequence = "Sequence" + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_idx = tokenizer.pad_token_id + + # RIGHT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # LEFT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "left" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert [padding_idx] * padding_size + encoded_sequence == padded_sequence + + # RIGHT & LEFT PADDING - Check that nothing is done for 'longest' and 'no_padding' + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, padding=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding="longest") + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding=False) + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + def test_token_type_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + output = tokenizer(words, boxes=boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + self.assertNotIn(1, output["token_type_ids"]) + + # test 2: two sequences (question + words) + question, words, boxes = self.get_question_words_and_boxes() + + output = tokenizer(question, words, boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + self.assertIn(1, output["token_type_ids"]) + + def test_offsets_mapping(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + text = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(text))] + + # No pair + tokens_with_offsets = tokenizer_r.encode_plus( + text, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(False) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + # Pairs + text = "what's his name" + pair = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(pair))] + tokens_with_offsets = tokenizer_r.encode_plus( + text, + pair, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(True) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + @require_torch + @require_detectron2 + @slow + def test_torch_encode_plus_sent_to_model(self): + import torch + + from transformers import MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + is_using_common_embeddings = hasattr(model.get_input_embeddings(), "weight") + assert ( + (model.get_input_embeddings().weight.shape[0] >= len(tokenizer)) + if is_using_common_embeddings + else True + ) + + # Build sequence + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_tensors="pt") + batch_encoded_sequence = tokenizer.batch_encode_plus( + [words, words], boxes=[boxes, boxes], return_tensors="pt" + ) + + # We add dummy image keys (as LayoutLMv2 actually also requires a feature extractor + # to prepare the image input) + encoded_sequence["image"] = torch.randn(1, 3, 224, 224) + batch_encoded_sequence["image"] = torch.randn(2, 3, 224, 224) + + # This should not fail + with torch.no_grad(): # saves some time + model(**encoded_sequence) + model(**batch_encoded_sequence) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + words, boxes = self.get_words_and_boxes() + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + self.assertListEqual(ids, rust_ids) + + def test_tokenization_python_rust_equals(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words, boxes = self.get_words_and_boxes() + + # Ensure basic input match + input_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + input_pairs_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_pairs_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_pairs_p[key], input_pairs_r[key]) + + words = ["hello" for _ in range(1000)] + boxes = [[1000, 1000, 1000, 1000] for _ in range(1000)] + + # Ensure truncation match + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + # Ensure truncation with stride match + input_p = tokenizer_p.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + input_r = tokenizer_r.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key][0]) + + def test_embeded_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + words, boxes = self.get_words_and_boxes() + tokens_r = tokenizer_r.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + tokens_p = tokenizer_p.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + + for key in tokens_p.keys(): + self.assertEqual(tokens_r[key], tokens_p[key]) + + if "token_type_ids" in tokens_r: + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + tokens_r = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + self.assertSequenceEqual(tokens_r, tokens_p) + + def test_compare_add_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + simple_num_special_tokens_to_add = tokenizer_r.num_special_tokens_to_add(pair=False) + + words, boxes = self.get_words_and_boxes() + # tokenize() + no_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=False) + with_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode() + no_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode_plus() + no_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + self.assertEqual( + len(no_special_tokens[key]), + len(with_special_tokens[key]) - simple_num_special_tokens_to_add, + ) + + # # batch_encode_plus + words, boxes = self.get_words_and_boxes_batch() + + no_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + for i_no, i_with in zip(no_special_tokens[key], with_special_tokens[key]): + self.assertEqual(len(i_no), len(i_with) - simple_num_special_tokens_to_add) + + @slow + def test_layoutlmv2_truncation_integration_test(self): + words, boxes = self.get_words_and_boxes() + + tokenizer = LayoutLMv2Tokenizer.from_pretrained("microsoft/layoutlmv2-base-uncased", model_max_length=512) + + for i in range(12, 512): + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, max_length=i, truncation=True) + + # Ensure that the input IDs are less than the max length defined. + self.assertLessEqual(len(new_encoded_inputs), i) + + tokenizer.model_max_length = 20 + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + dropped_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + + # Ensure that the input IDs are still truncated when no max_length is specified + self.assertListEqual(new_encoded_inputs, dropped_encoded_inputs) + self.assertLessEqual(len(new_encoded_inputs), 20) + + @is_pt_tf_cross_test + def test_batch_encode_plus_tensors(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + # A Tensor cannot be build by sequences which are not the same size + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="pt") + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="tf") + + if tokenizer.pad_token_id is None: + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding=True, + return_tensors="pt", + ) + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding="longest", + return_tensors="tf", + ) + else: + pytorch_tensor = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True, return_tensors="pt") + tensorflow_tensor = tokenizer.batch_encode_plus( + words, boxes=boxes, padding="longest", return_tensors="tf" + ) + encoded_sequences = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True) + + for key in encoded_sequences.keys(): + pytorch_value = pytorch_tensor[key].tolist() + tensorflow_value = tensorflow_tensor[key].numpy().tolist() + encoded_value = encoded_sequences[key] + + self.assertEqual(pytorch_value, tensorflow_value, encoded_value) + + def test_sequence_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + if not tokenizer.is_fast: + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + seq_1 = ["With", "these", "inputs."] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(seq_1))] + + # We want to have sequence 0 and sequence 1 are tagged + # respectively with 0 and 1 token_ids + # (regardless of whether the model use token type ids) + # We use this assumption in the QA pipeline among other place + output = tokenizer(seq_0.split(), boxes=boxes) + self.assertIn(0, output.sequence_ids()) + + output = tokenizer(seq_0, seq_1, boxes=boxes) + self.assertIn(0, output.sequence_ids()) + self.assertIn(1, output.sequence_ids()) + + if tokenizer.num_special_tokens_to_add(pair=True): + self.assertIn(None, output.sequence_ids()) + + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + r_output = tokenizer_r.encode(words, boxes=boxes) + + special_token_id = tokenizer_r.encode( + [""], boxes=[1000, 1000, 1000, 1000], add_special_tokens=False + )[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_cr = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs, from_slow=True + ) + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + p_output = tokenizer_p.encode(words, boxes=boxes) + cr_output = tokenizer_cr.encode(words, boxes=boxes) + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + def test_training_new_tokenizer(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + new_tokenizer = tokenizer.train_new_from_iterator(SMALL_TRAINING_CORPUS, 100) + + # Test we can use the new tokenizer with something not seen during training + text = [["this", "is", "the"], ["how", "are", "you"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8], [1, 3, 4, 8]], [[5, 6, 7, 8], [4, 5, 6, 7], [3, 9, 2, 7]]] + inputs = new_tokenizer(text, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "this is the" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + # We check that the parameters of the tokenizer remained the same + # Check we have the same number of added_tokens for both pair and non-pair inputs. + self.assertEqual(tokenizer.num_special_tokens_to_add(False), new_tokenizer.num_special_tokens_to_add(False)) + self.assertEqual(tokenizer.num_special_tokens_to_add(True), new_tokenizer.num_special_tokens_to_add(True)) + + # Check we have the correct max_length for both pair and non-pair inputs. + self.assertEqual(tokenizer.max_len_single_sentence, new_tokenizer.max_len_single_sentence) + self.assertEqual(tokenizer.max_len_sentences_pair, new_tokenizer.max_len_sentences_pair) + + # Assert the set of special tokens match as we didn't ask to change them + self.assertSequenceEqual( + tokenizer.all_special_tokens_extended, + new_tokenizer.all_special_tokens_extended, + ) + + self.assertDictEqual(tokenizer.special_tokens_map, new_tokenizer.special_tokens_map) + + def test_training_new_tokenizer_with_special_tokens_change(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + # Test with a special tokens map + class_signature = inspect.signature(tokenizer.__class__) + if "cls_token" in class_signature.parameters: + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map={tokenizer.cls_token: ""} + ) + cls_id = new_tokenizer.get_vocab()[""] + self.assertEqual(new_tokenizer.cls_token, "") + self.assertEqual(new_tokenizer.cls_token_id, cls_id) + + # Create a new mapping from the special tokens defined in the original tokenizer + special_tokens_list = SpecialTokensMixin.SPECIAL_TOKENS_ATTRIBUTES.copy() + special_tokens_list.remove("additional_special_tokens") + special_tokens_map = {} + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is not None: + special_token = getattr(tokenizer, token) + special_tokens_map[special_token] = f"{special_token}a" + + # Train new tokenizer + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map=special_tokens_map + ) + + # Check the changes + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is None: + continue + special_token = getattr(tokenizer, token) + if special_token in special_tokens_map: + new_special_token = getattr(new_tokenizer, token) + self.assertEqual(special_tokens_map[special_token], new_special_token) + + new_id = new_tokenizer.get_vocab()[new_special_token] + self.assertEqual(getattr(new_tokenizer, f"{token}_id"), new_id) + + # Check if the AddedToken / string format has been kept + for special_token in tokenizer.all_special_tokens_extended: + if isinstance(special_token, AddedToken) and special_token.content not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + elif isinstance(special_token, AddedToken): + # The special token must appear in the list of the new tokenizer as an object of type AddedToken with + # the same parameters as the old AddedToken except the content that the user has requested to change. + special_token_str = special_token.content + new_special_token_str = special_tokens_map[special_token_str] + + find = False + for candidate in new_tokenizer.all_special_tokens_extended: + if ( + isinstance(candidate, AddedToken) + and candidate.content == new_special_token_str + and candidate.lstrip == special_token.lstrip + and candidate.rstrip == special_token.rstrip + and candidate.normalized == special_token.normalized + and candidate.single_word == special_token.single_word + ): + find = True + break + self.assertTrue( + find, + f"'{new_special_token_str}' doesn't appear in the list " + f"'{new_tokenizer.all_special_tokens_extended}' as an AddedToken with the same parameters as " + f"'{special_token}' in the list {tokenizer.all_special_tokens_extended}", + ) + elif special_token not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + + else: + # The special token must appear in the list of the new tokenizer as an object of type string. + self.assertTrue(special_tokens_map[special_token] in new_tokenizer.all_special_tokens_extended) + + # Test we can use the new tokenizer with something not seen during training + words = [["this", "is"], ["hello", "🤗"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[1, 2, 3, 4], [5, 6, 7, 8]]] + inputs = new_tokenizer(words, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "this is" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + def test_prepare_for_model(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + # only test prepare_for_model for the slow tokenizer + if tokenizer.__class__.__name__ == "LayoutLMv2TokenizerFast": + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + prepared_input_dict = tokenizer.prepare_for_model(words, boxes=boxes, add_special_tokens=True) + + input_dict = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + + self.assertEqual(input_dict, prepared_input_dict) + + def test_padding_different_model_input_name(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes) + input_p = tokenizer_r.batch_encode_plus(words, boxes=boxes) + + # rename encoded batch to "inputs" + input_r["inputs"] = input_r[tokenizer_r.model_input_names[0]] + del input_r[tokenizer_r.model_input_names[0]] + + input_p["inputs"] = input_p[tokenizer_p.model_input_names[0]] + del input_p[tokenizer_p.model_input_names[0]] + + # Renaming `input_ids` to `inputs` + tokenizer_r.model_input_names = ["inputs"] + tokenizer_r.model_input_names[1:] + tokenizer_p.model_input_names = ["inputs"] + tokenizer_p.model_input_names[1:] + + input_r = tokenizer_r.pad(input_r, padding="longest") + input_p = tokenizer_r.pad(input_p, padding="longest") + + max_length = len(input_p["inputs"][0]) + self.assert_batch_padded_input_match( + input_r, input_p, max_length, pad_token_id, model_main_input_name="inputs" + ) + + def test_batch_encode_dynamic_overflowing(self): + """ + When calling batch_encode with multiple sequences, it can return different number of + overflowing encoding for each sequence: + [ + Sequence 1: [Encoding 1, Encoding 2], + Sequence 2: [Encoding 1], + Sequence 3: [Encoding 1, Encoding 2, ... Encoding N] + ] + This needs to be padded so that it can represented as a tensor + """ + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): + if is_torch_available(): + returned_tensor = "pt" + elif is_tf_available(): + returned_tensor = "tf" + else: + returned_tensor = "jax" + + # Single example + words, boxes = self.get_words_and_boxes() + tokens = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=6, + padding=True, + truncation=True, + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + else: + self.assertEqual(len(tokens[key].shape), 3) + + # Batch of examples + # For these 2 examples, 3 training examples will be created + words, boxes = self.get_words_and_boxes_batch() + tokens = tokenizer.batch_encode_plus( + words, + boxes=boxes, + max_length=6, + padding=True, + truncation="only_first", + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + self.assertEqual(tokens[key].shape[-1], 6) + else: + self.assertEqual(len(tokens[key].shape), 3) + self.assertEqual(tokens[key].shape[-1], 4) + + @unittest.skip("TO DO: overwrite this very extensive test.") + def test_alignement_methods(self): + pass + + def get_clean_sequence(self, tokenizer, with_prefix_space=False, max_length=20, min_length=5): + toks = [(i, tokenizer.decode([i], clean_up_tokenization_spaces=False)) for i in range(len(tokenizer))] + toks = list(filter(lambda t: re.match(r"^[ a-zA-Z]+$", t[1]), toks)) + toks = list( + filter( + lambda t: [t[0]] + == tokenizer.encode(t[1].split(" "), boxes=len(t[1]) * [[1, 1, 1, 1]], add_special_tokens=False), + toks, + ) + ) + if max_length is not None and len(toks) > max_length: + toks = toks[:max_length] + if min_length is not None and len(toks) < min_length and len(toks) > 0: + while len(toks) < min_length: + toks = toks + toks + # toks_str = [t[1] for t in toks] + toks_ids = [t[0] for t in toks] + + # Ensure consistency + output_txt = tokenizer.decode(toks_ids, clean_up_tokenization_spaces=False) + if " " not in output_txt and len(toks_ids) > 1: + output_txt = ( + tokenizer.decode([toks_ids[0]], clean_up_tokenization_spaces=False) + + " " + + tokenizer.decode(toks_ids[1:], clean_up_tokenization_spaces=False) + ) + if with_prefix_space: + output_txt = " " + output_txt + words = output_txt.split(" ") + boxes = [[i, i, i, i] for i in range(len(words))] + output_ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + return words, boxes, output_ids + + # @unittest.skip("LayoutLMv2 tokenizer requires boxes besides sequences.") + def test_maximum_encoding_length_pair_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Build a sequence from our model's vocabulary + stride = 2 + seq_0, boxes_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + question_0 = " ".join(map(str, seq_0)) + if len(ids) <= 2 + stride: + seq_0 = (seq_0 + " ") * (2 + stride) + ids = None + + seq0_tokens = tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False) + self.assertGreater(len(seq0_tokens["input_ids"]), 2 + stride) + question_1 = "This is another sentence to be encoded." + seq_1 = ["what", "a", "weird", "test", "weirdly", "weird"] + boxes_1 = [[i, i, i, i] for i in range(len(seq_1))] + seq1_tokens = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + if abs(len(seq0_tokens["input_ids"]) - len(seq1_tokens["input_ids"])) <= 2: + seq1_tokens_input_ids = seq1_tokens["input_ids"] + seq1_tokens["input_ids"] + seq_1 = tokenizer.decode(seq1_tokens_input_ids, clean_up_tokenization_spaces=False) + seq_1 = seq_1.split(" ") + boxes_1 = [[i, i, i, i] for i in range(len(seq_1))] + seq1_tokens = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + + self.assertGreater(len(seq1_tokens["input_ids"]), 2 + stride) + + smallest = ( + seq1_tokens["input_ids"] + if len(seq0_tokens["input_ids"]) > len(seq1_tokens["input_ids"]) + else seq0_tokens["input_ids"] + ) + + # We are not using the special tokens - a bit too hard to test all the tokenizers with this + # TODO try this again later + sequence = tokenizer( + question_0, seq_1, boxes=boxes_1, add_special_tokens=False + ) # , add_prefix_space=False) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_2 = seq_0 * model_max_length + question_2 = " ".join(map(str, seq_2)) + boxes_2 = boxes_0 * model_max_length + self.assertGreater(len(seq_2), model_max_length) + + sequence1 = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + sequence2 = tokenizer(question_2, seq_1, boxes=boxes_1, add_special_tokens=False) + total_length2 = len(sequence2["input_ids"]) + self.assertLess(total_length1, model_max_length, "Issue with the testing sequence, please update it.") + self.assertGreater( + total_length2, model_max_length, "Issue with the testing sequence, please update it." + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"{tokenizer.__class__.__name__} Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"{tokenizer.__class__.__name__} Truncation: {truncation_state}"): + output = tokenizer( + question_2, + seq_1, + boxes=boxes_1, + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [question_2], + [seq_1], + boxes=[boxes_1], + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple + output = tokenizer( + question_1, seq_2, boxes=boxes_2, padding=padding_state, truncation="only_second" + ) + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [question_1], [seq_2], boxes=[boxes_2], padding=padding_state, truncation="only_second" + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer( + question_1, seq_2, boxes=boxes_2, padding=padding_state, truncation=False + ) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertNotEqual(len(output["bbox"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer( + [question_1], [seq_2], boxes=[boxes_2], padding=padding_state, truncation=False + ) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertNotEqual(len(output["bbox"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + # Check the order of Sequence of input ids, overflowing tokens and bbox sequence with truncation + truncated_first_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"][:-2] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"] + ) + truncated_second_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"][:-2] + ) + truncated_longest_sequence = ( + truncated_first_sequence if len(seq0_tokens) > len(seq1_tokens) else truncated_second_sequence + ) + + overflow_first_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"][-(2 + stride) :] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"] + ) + overflow_second_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"][-(2 + stride) :] + ) + overflow_longest_sequence = ( + overflow_first_sequence if len(seq0_tokens) > len(seq1_tokens) else overflow_second_sequence + ) + + bbox_first = [[0, 0, 0, 0]] * (len(seq_0) - 2) + bbox_first_sequence = bbox_first + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["bbox"] + overflowing_token_bbox_first_sequence_slow = [[0, 0, 0, 0]] * (2 + stride) + overflowing_token_bbox_first_sequence_fast = [[0, 0, 0, 0]] * (2 + stride) + tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"] + + bbox_second = [[0, 0, 0, 0]] * len(seq_0) + bbox_second_sequence = ( + bbox_second + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["bbox"][:-2] + ) + overflowing_token_bbox_second_sequence_slow = tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"][-(2 + stride) :] + overflowing_token_bbox_second_sequence_fast = [[0, 0, 0, 0]] * len(seq_0) + tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"][-(2 + stride) :] + + bbox_longest_sequence = ( + bbox_first_sequence if len(seq0_tokens) > len(seq1_tokens) else bbox_second_sequence + ) + overflowing_token_bbox_longest_sequence_fast = ( + overflowing_token_bbox_first_sequence_fast + if len(seq0_tokens) > len(seq1_tokens) + else overflowing_token_bbox_second_sequence_fast + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv2TokenizerFast): + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + bbox = information["bbox"][0] + overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + self.assertEqual(bbox, bbox_longest_sequence) + + self.assertEqual(len(overflowing_bbox), 2 + stride + len(smallest)) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_longest_sequence_fast) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv2TokenizerFast): + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + bbox = information["bbox"][0] + overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + self.assertEqual(bbox, bbox_longest_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_longest_sequence_fast) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + information_first_truncated = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv2TokenizerFast): + truncated_sequence = information_first_truncated["input_ids"][0] + overflowing_tokens = information_first_truncated["input_ids"][1] + bbox = information_first_truncated["bbox"][0] + overflowing_bbox = information_first_truncated["bbox"][1] + self.assertEqual(len(information_first_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq1_tokens["input_ids"])) + self.assertEqual(overflowing_tokens, overflow_first_sequence) + self.assertEqual(bbox, bbox_first_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_first_sequence_fast) + else: + truncated_sequence = information_first_truncated["input_ids"] + overflowing_tokens = information_first_truncated["overflowing_tokens"] + overflowing_bbox = information_first_truncated["overflowing_token_boxes"] + bbox = information_first_truncated["bbox"] + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq0_tokens["input_ids"][-(2 + stride) :]) + self.assertEqual(bbox, bbox_first_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_first_sequence_slow) + + information_second_truncated = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_second", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv2TokenizerFast): + truncated_sequence = information_second_truncated["input_ids"][0] + overflowing_tokens = information_second_truncated["input_ids"][1] + bbox = information_second_truncated["bbox"][0] + overflowing_bbox = information_second_truncated["bbox"][1] + + self.assertEqual(len(information_second_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq0_tokens["input_ids"])) + self.assertEqual(overflowing_tokens, overflow_second_sequence) + self.assertEqual(bbox, bbox_second_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_second_sequence_fast) + else: + truncated_sequence = information_second_truncated["input_ids"] + overflowing_tokens = information_second_truncated["overflowing_tokens"] + bbox = information_second_truncated["bbox"] + overflowing_bbox = information_second_truncated["overflowing_token_boxes"] + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq1_tokens["input_ids"][-(2 + stride) :]) + self.assertEqual(bbox, bbox_second_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_second_sequence_slow) + + # @unittest.skip("LayoutLMv2 tokenizer requires boxes besides sequences.") + def test_maximum_encoding_length_single_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0, boxes_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + + sequence = tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False) + total_length = len(sequence["input_ids"]) + + self.assertGreater( + total_length, 4, "Issue with the testing sequence, please update it, it's too short" + ) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_1 = seq_0 * model_max_length + boxes_1 = boxes_0 * model_max_length + sequence1 = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + self.assertGreater( + total_length1, + model_max_length, + "Issue with the testing sequence, please update it, it's too short", + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"Truncation: {truncation_state}"): + output = tokenizer( + seq_1, + boxes=boxes_1, + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [seq_1], + boxes=[boxes_1], + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer(seq_1, boxes=boxes_1, padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertNotEqual(len(output["bbox"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer([seq_1], boxes=[boxes_1], padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertNotEqual(len(output["bbox"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + # Check the order of Sequence of input ids, overflowing tokens and bbox sequence with truncation + stride = 2 + information = tokenizer( + seq_0, + boxes=boxes_0, + max_length=total_length - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv2TokenizerFast): + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + bbox = information["bbox"][0] + overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence["input_ids"][:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence["input_ids"][-(2 + stride) :]) + + self.assertEqual(bbox, sequence["bbox"][:-2]) + self.assertEqual(overflowing_bbox, sequence["bbox"][-(2 + stride) :]) + else: + truncated_sequence = information["input_ids"] + overflowing_tokens = information["overflowing_tokens"] + bbox = information["bbox"] + overflowing_bbox = information["overflowing_token_boxes"] + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence["input_ids"][:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence["input_ids"][-(2 + stride) :]) + self.assertEqual(bbox, sequence["bbox"][:-2]) + self.assertEqual(overflowing_bbox, sequence["bbox"][-(2 + stride) :]) + + @unittest.skip("LayoutLMv2 tokenizer requires boxes besides sequences.") + def test_pretokenized_inputs(self): + pass + + @unittest.skip("LayoutLMv2 tokenizer always expects pretokenized inputs.") + def test_compare_pretokenized_inputs(self): + pass + + @unittest.skip("LayoutLMv2 fast tokenizer does not support prepare_for_model") + def test_compare_prepare_for_model(self): + pass + + @slow + def test_only_label_first_subword(self): + words = ["hello", "niels"] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + word_labels = [0, 1] + + # test slow tokenizer + tokenizer_p = LayoutLMv2Tokenizer.from_pretrained("microsoft/layoutlmv2-base-uncased") + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, -100, -100]) + + tokenizer_p = LayoutLMv2Tokenizer.from_pretrained( + "microsoft/layoutlmv2-base-uncased", only_label_first_subword=False + ) + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, 1, -100]) + + # test fast tokenizer + tokenizer_r = LayoutLMv2TokenizerFast.from_pretrained("microsoft/layoutlmv2-base-uncased") + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, -100, -100]) + + tokenizer_r = LayoutLMv2Tokenizer.from_pretrained( + "microsoft/layoutlmv2-base-uncased", only_label_first_subword=False + ) + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, 1, -100]) + + @slow + def test_layoutlmv2_integration_test(self): + tokenizer_p = LayoutLMv2Tokenizer.from_pretrained("microsoft/layoutlmv2-base-uncased") + tokenizer_r = LayoutLMv2TokenizerFast.from_pretrained("microsoft/layoutlmv2-base-uncased") + + # There are 3 cases: + # CASE 1: document image classification (training + inference), document image token classification (inference), + # in which case only words and normalized bounding boxes are provided to the tokenizer + # CASE 2: document image token classification (training), + # in which case one also provides word labels to the tokenizer + # CASE 3: document image visual question answering (inference), + # in which case one also provides a question to the tokenizer + + # We need to test all 3 cases both on batched and non-batched inputs. + + # CASE 1: not batched + words, boxes = self.get_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [101, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 1: batched + words, boxes = self.get_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[101, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 7592, 2026, 2171, 2003, 3960, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 2: not batched + words, boxes = self.get_words_and_boxes() + word_labels = [1, 2, 3] + + # fmt: off + expected_results = {'input_ids': [101, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'labels': [-100, 1, 2, -100, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], 'attention_mask': [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 2: batched + words, boxes = self.get_words_and_boxes_batch() + word_labels = [[1, 2, 3], [2, 46, 17, 22, 3]] + + # fmt: off + expected_results = {'input_ids': [[101, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 7592, 2026, 2171, 2003, 3960, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'labels': [[-100, 1, 2, -100, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], [-100, 2, 46, 17, 22, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 3: not batched + question, words, boxes = self.get_question_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [101, 2054, 1005, 1055, 2010, 2171, 1029, 102, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0], 'bbox': [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(question, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(question, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 3: batched + questions, words, boxes = self.get_question_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[101, 2054, 1005, 1055, 2010, 2171, 1029, 102, 1037, 6881, 2135, 3231, 102, 0, 0, 0, 0, 0, 0, 0], [101, 2129, 2003, 2002, 2170, 1029, 102, 2054, 1037, 21110, 2546, 3806, 2102, 2078, 102, 0, 0, 0, 0, 0]], 'bbox': [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [336, 42, 353, 57], [34, 42, 66, 69], [34, 42, 66, 69], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(questions, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(questions, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + @unittest.skip("Doesn't support another framework than PyTorch") + def test_np_encode_plus_sent_to_model(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py new file mode 100644 index 0000000000000000000000000000000000000000..8827cdeea2335fba8b877af9a73613df05435c6b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_image_processing_layoutlmv3.py @@ -0,0 +1,220 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_pytesseract, require_torch +from transformers.utils import is_pytesseract_available, is_torch_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_pytesseract_available(): + from PIL import Image + + from transformers import LayoutLMv3ImageProcessor + + +class LayoutLMv3ImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + apply_ocr=True, + ): + size = size if size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.apply_ocr = apply_ocr + + def prepare_image_processor_dict(self): + return {"do_resize": self.do_resize, "size": self.size, "apply_ocr": self.apply_ocr} + + +@require_torch +@require_pytesseract +class LayoutLMv3ImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = LayoutLMv3ImageProcessor if is_pytesseract_available() else None + + def setUp(self): + self.image_processor_tester = LayoutLMv3ImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "size")) + self.assertTrue(hasattr(image_processing, "apply_ocr")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42) + self.assertEqual(image_processor.size, {"height": 42, "width": 42}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoding = image_processing(image_inputs[0], return_tensors="pt") + self.assertEqual( + encoding.pixel_values.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + self.assertIsInstance(encoding.words, list) + self.assertIsInstance(encoding.boxes, list) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.size["height"], + self.image_processor_tester.size["width"], + ), + ) + + def test_LayoutLMv3_integration_test(self): + # with apply_OCR = True + image_processing = LayoutLMv3ImageProcessor() + + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/fixtures_docvqa", split="test") + + image = Image.open(ds[0]["file"]).convert("RGB") + + encoding = image_processing(image, return_tensors="pt") + + self.assertEqual(encoding.pixel_values.shape, (1, 3, 224, 224)) + self.assertEqual(len(encoding.words), len(encoding.boxes)) + + # fmt: off + # the words and boxes were obtained with Tesseract 4.1.1 + expected_words = [['11:14', 'to', '11:39', 'a.m', '11:39', 'to', '11:44', 'a.m.', '11:44', 'a.m.', 'to', '12:25', 'p.m.', '12:25', 'to', '12:58', 'p.m.', '12:58', 'to', '4:00', 'p.m.', '2:00', 'to', '5:00', 'p.m.', 'Coffee', 'Break', 'Coffee', 'will', 'be', 'served', 'for', 'men', 'and', 'women', 'in', 'the', 'lobby', 'adjacent', 'to', 'exhibit', 'area.', 'Please', 'move', 'into', 'exhibit', 'area.', '(Exhibits', 'Open)', 'TRRF', 'GENERAL', 'SESSION', '(PART', '|)', 'Presiding:', 'Lee', 'A.', 'Waller', 'TRRF', 'Vice', 'President', '“Introductory', 'Remarks”', 'Lee', 'A.', 'Waller,', 'TRRF', 'Vice', 'Presi-', 'dent', 'Individual', 'Interviews', 'with', 'TRRF', 'Public', 'Board', 'Members', 'and', 'Sci-', 'entific', 'Advisory', 'Council', 'Mem-', 'bers', 'Conducted', 'by', 'TRRF', 'Treasurer', 'Philip', 'G.', 'Kuehn', 'to', 'get', 'answers', 'which', 'the', 'public', 'refrigerated', 'warehousing', 'industry', 'is', 'looking', 'for.', 'Plus', 'questions', 'from', 'the', 'floor.', 'Dr.', 'Emil', 'M.', 'Mrak,', 'University', 'of', 'Cal-', 'ifornia,', 'Chairman,', 'TRRF', 'Board;', 'Sam', 'R.', 'Cecil,', 'University', 'of', 'Georgia', 'College', 'of', 'Agriculture;', 'Dr.', 'Stanley', 'Charm,', 'Tufts', 'University', 'School', 'of', 'Medicine;', 'Dr.', 'Robert', 'H.', 'Cotton,', 'ITT', 'Continental', 'Baking', 'Company;', 'Dr.', 'Owen', 'Fennema,', 'University', 'of', 'Wis-', 'consin;', 'Dr.', 'Robert', 'E.', 'Hardenburg,', 'USDA.', 'Questions', 'and', 'Answers', 'Exhibits', 'Open', 'Capt.', 'Jack', 'Stoney', 'Room', 'TRRF', 'Scientific', 'Advisory', 'Council', 'Meeting', 'Ballroom', 'Foyer']] # noqa: E231 + expected_boxes = [[[141, 57, 214, 69], [228, 58, 252, 69], [141, 75, 216, 88], [230, 79, 280, 88], [142, 260, 218, 273], [230, 261, 255, 273], [143, 279, 218, 290], [231, 282, 290, 291], [143, 342, 218, 354], [231, 345, 289, 355], [202, 362, 227, 373], [143, 379, 220, 392], [231, 382, 291, 394], [144, 714, 220, 726], [231, 715, 256, 726], [144, 732, 220, 745], [232, 736, 291, 747], [144, 769, 218, 782], [231, 770, 256, 782], [141, 788, 202, 801], [215, 791, 274, 804], [143, 826, 204, 838], [215, 826, 240, 838], [142, 844, 202, 857], [215, 847, 274, 859], [334, 57, 427, 69], [440, 57, 522, 69], [369, 75, 461, 88], [469, 75, 516, 88], [528, 76, 562, 88], [570, 76, 667, 88], [675, 75, 711, 87], [721, 79, 778, 88], [789, 75, 840, 88], [369, 97, 470, 107], [484, 94, 507, 106], [518, 94, 562, 107], [576, 94, 655, 110], [668, 94, 792, 109], [804, 95, 829, 107], [369, 113, 465, 125], [477, 116, 547, 125], [562, 113, 658, 125], [671, 116, 748, 125], [761, 113, 811, 125], [369, 131, 465, 143], [477, 133, 548, 143], [563, 130, 698, 145], [710, 130, 802, 146], [336, 171, 412, 183], [423, 171, 572, 183], [582, 170, 716, 184], [728, 171, 817, 187], [829, 171, 844, 186], [338, 197, 482, 212], [507, 196, 557, 209], [569, 196, 595, 208], [610, 196, 702, 209], [505, 214, 583, 226], [595, 214, 656, 227], [670, 215, 807, 227], [335, 259, 543, 274], [556, 259, 708, 272], [372, 279, 422, 291], [435, 279, 460, 291], [474, 279, 574, 292], [587, 278, 664, 291], [676, 278, 738, 291], [751, 279, 834, 291], [372, 298, 434, 310], [335, 341, 483, 354], [497, 341, 655, 354], [667, 341, 728, 354], [740, 341, 825, 354], [335, 360, 430, 372], [442, 360, 534, 372], [545, 359, 687, 372], [697, 360, 754, 372], [765, 360, 823, 373], [334, 378, 428, 391], [440, 378, 577, 394], [590, 378, 705, 391], [720, 378, 801, 391], [334, 397, 400, 409], [370, 416, 529, 429], [544, 416, 576, 432], [587, 416, 665, 428], [677, 416, 814, 429], [372, 435, 452, 450], [465, 434, 495, 447], [511, 434, 600, 447], [611, 436, 637, 447], [649, 436, 694, 451], [705, 438, 824, 447], [369, 453, 452, 466], [464, 454, 509, 466], [522, 453, 611, 469], [625, 453, 792, 469], [370, 472, 556, 488], [570, 472, 684, 487], [697, 472, 718, 485], [732, 472, 835, 488], [369, 490, 411, 503], [425, 490, 484, 503], [496, 490, 635, 506], [645, 490, 707, 503], [718, 491, 761, 503], [771, 490, 840, 503], [336, 510, 374, 521], [388, 510, 447, 522], [460, 510, 489, 521], [503, 510, 580, 522], [592, 509, 736, 525], [745, 509, 770, 522], [781, 509, 840, 522], [338, 528, 434, 541], [448, 528, 596, 541], [609, 527, 687, 540], [700, 528, 792, 541], [336, 546, 397, 559], [407, 546, 431, 559], [443, 546, 525, 560], [537, 546, 680, 562], [688, 546, 714, 559], [722, 546, 837, 562], [336, 565, 449, 581], [461, 565, 485, 577], [497, 565, 665, 581], [681, 565, 718, 577], [732, 565, 837, 580], [337, 584, 438, 597], [452, 583, 521, 596], [535, 584, 677, 599], [690, 583, 787, 596], [801, 583, 825, 596], [338, 602, 478, 615], [492, 602, 530, 614], [543, 602, 638, 615], [650, 602, 676, 614], [688, 602, 788, 615], [802, 602, 843, 614], [337, 621, 502, 633], [516, 621, 615, 637], [629, 621, 774, 636], [789, 621, 827, 633], [337, 639, 418, 652], [432, 640, 571, 653], [587, 639, 731, 655], [743, 639, 769, 652], [780, 639, 841, 652], [338, 658, 440, 673], [455, 658, 491, 670], [508, 658, 602, 671], [616, 658, 638, 670], [654, 658, 835, 674], [337, 677, 429, 689], [337, 714, 482, 726], [495, 714, 548, 726], [561, 714, 683, 726], [338, 770, 461, 782], [474, 769, 554, 785], [489, 788, 562, 803], [576, 788, 643, 801], [656, 787, 751, 804], [764, 788, 844, 801], [334, 825, 421, 838], [430, 824, 574, 838], [584, 824, 723, 841], [335, 844, 450, 857], [464, 843, 583, 860], [628, 862, 755, 875], [769, 861, 848, 878]]] # noqa: E231 + # fmt: on + + self.assertListEqual(encoding.words, expected_words) + self.assertListEqual(encoding.boxes, expected_boxes) + + # with apply_OCR = False + image_processing = LayoutLMv3ImageProcessor(apply_ocr=False) + + encoding = image_processing(image, return_tensors="pt") + + self.assertEqual(encoding.pixel_values.shape, (1, 3, 224, 224)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_layoutlmv3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_layoutlmv3.py new file mode 100644 index 0000000000000000000000000000000000000000..c6a2a1bf37f2e30b680d583daaae09551ef14e22 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_layoutlmv3.py @@ -0,0 +1,417 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LayoutLMv3 model. """ + +import copy +import unittest + +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, slow, torch_device +from transformers.utils import cached_property, is_torch_available, is_vision_available + +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 ( + MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + LayoutLMv3Config, + LayoutLMv3ForQuestionAnswering, + LayoutLMv3ForSequenceClassification, + LayoutLMv3ForTokenClassification, + LayoutLMv3Model, + ) + from transformers.models.layoutlmv3.modeling_layoutlmv3 import LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST + +if is_vision_available(): + from PIL import Image + + from transformers import LayoutLMv3FeatureExtractor + + +class LayoutLMv3ModelTester: + def __init__( + self, + parent, + batch_size=2, + num_channels=3, + image_size=4, + patch_size=2, + text_seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=36, + num_hidden_layers=3, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + coordinate_size=6, + shape_size=6, + num_labels=3, + num_choices=4, + scope=None, + range_bbox=1000, + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.patch_size = patch_size + self.text_seq_length = text_seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.coordinate_size = coordinate_size + self.shape_size = shape_size + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.range_bbox = range_bbox + + # LayoutLMv3's sequence length equals the number of text tokens + number of patches + 1 (we add 1 for the CLS token) + self.text_seq_length = text_seq_length + self.image_seq_length = (image_size // patch_size) ** 2 + 1 + self.seq_length = self.text_seq_length + self.image_seq_length + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.text_seq_length], self.vocab_size) + + bbox = ids_tensor([self.batch_size, self.text_seq_length, 4], self.range_bbox) + # Ensure that bbox is legal + for i in range(bbox.shape[0]): + for j in range(bbox.shape[1]): + if bbox[i, j, 3] < bbox[i, j, 1]: + t = bbox[i, j, 3] + bbox[i, j, 3] = bbox[i, j, 1] + bbox[i, j, 1] = t + if bbox[i, j, 2] < bbox[i, j, 0]: + t = bbox[i, j, 2] + bbox[i, j, 2] = bbox[i, j, 0] + bbox[i, j, 0] = t + + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.text_seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.text_seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.text_seq_length], self.num_labels) + + config = LayoutLMv3Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + coordinate_size=self.coordinate_size, + shape_size=self.shape_size, + input_size=self.image_size, + patch_size=self.patch_size, + ) + + return config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + + def create_and_check_model( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + ): + model = LayoutLMv3Model(config=config) + model.to(torch_device) + model.eval() + + # text + image + result = model(input_ids, pixel_values=pixel_values) + result = model( + input_ids, bbox=bbox, pixel_values=pixel_values, attention_mask=input_mask, token_type_ids=token_type_ids + ) + result = model(input_ids, bbox=bbox, pixel_values=pixel_values, token_type_ids=token_type_ids) + result = model(input_ids, bbox=bbox, pixel_values=pixel_values) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + # text only + result = model(input_ids) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.text_seq_length, self.hidden_size) + ) + + # image only + result = model(pixel_values=pixel_values) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.image_seq_length, self.hidden_size) + ) + + def create_and_check_for_sequence_classification( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + ): + config.num_labels = self.num_labels + model = LayoutLMv3ForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=sequence_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + ): + config.num_labels = self.num_labels + model = LayoutLMv3ForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.text_seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + ): + model = LayoutLMv3ForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "bbox": bbox, + "pixel_values": pixel_values, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_torch +class LayoutLMv3ModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + test_pruning = False + test_torchscript = False + test_mismatched_shapes = False + + all_model_classes = ( + ( + LayoutLMv3Model, + LayoutLMv3ForSequenceClassification, + LayoutLMv3ForTokenClassification, + LayoutLMv3ForQuestionAnswering, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "document-question-answering": LayoutLMv3ForQuestionAnswering, + "feature-extraction": LayoutLMv3Model, + } + if is_torch_available() + else {} + ) + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + # `DocumentQuestionAnsweringPipeline` is expected to work with this model, but it combines the text and visual + # embedding along the sequence dimension (dim 1), which causes an error during post-processing as `p_mask` has + # the sequence dimension of the text embedding only. + # (see the line `embedding_output = torch.cat([embedding_output, visual_embeddings], dim=1)`) + return True + + def setUp(self): + self.model_tester = LayoutLMv3ModelTester(self) + self.config_tester = ConfigTester(self, config_class=LayoutLMv3Config, hidden_size=37) + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = copy.deepcopy(inputs_dict) + if model_class in get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict = { + k: v.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() + if isinstance(v, torch.Tensor) and v.ndim > 1 + else v + for k, v in inputs_dict.items() + } + if return_labels: + if model_class in get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict["labels"] = torch.ones(self.model_tester.batch_size, dtype=torch.long, device=torch_device) + elif model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + inputs_dict["start_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + inputs_dict["end_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class in [ + *get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING), + ]: + inputs_dict["labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class in [ + *get_values(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING), + ]: + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.text_seq_length), + dtype=torch.long, + device=torch_device, + ) + + return inputs_dict + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = LayoutLMv3Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +class LayoutLMv3ModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return LayoutLMv3FeatureExtractor(apply_ocr=False) if is_vision_available() else None + + @slow + def test_inference_no_head(self): + model = LayoutLMv3Model.from_pretrained("microsoft/layoutlmv3-base").to(torch_device) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + pixel_values = feature_extractor(images=image, return_tensors="pt").pixel_values.to(torch_device) + + input_ids = torch.tensor([[1, 2]]) + bbox = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]).unsqueeze(0) + + # forward pass + outputs = model( + input_ids=input_ids.to(torch_device), + bbox=bbox.to(torch_device), + pixel_values=pixel_values.to(torch_device), + ) + + # verify the logits + expected_shape = torch.Size((1, 199, 768)) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor( + [[-0.0529, 0.3618, 0.1632], [-0.1587, -0.1667, -0.0400], [-0.1557, -0.1671, -0.0505]] + ).to(torch_device) + + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_tf_layoutlmv3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_tf_layoutlmv3.py new file mode 100644 index 0000000000000000000000000000000000000000..df103194ab25c99ccfe2f17277c85486239b60b8 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_modeling_tf_layoutlmv3.py @@ -0,0 +1,514 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the TensorFlow LayoutLMv3 model. """ + +import copy +import inspect +import unittest + +import numpy as np + +from transformers import is_tf_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_tf, slow +from transformers.utils import cached_property + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + TF_LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST, + TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + LayoutLMv3Config, + TFLayoutLMv3ForQuestionAnswering, + TFLayoutLMv3ForSequenceClassification, + TFLayoutLMv3ForTokenClassification, + TFLayoutLMv3Model, + ) + +if is_vision_available(): + from PIL import Image + + from transformers import LayoutLMv3FeatureExtractor + + +class TFLayoutLMv3ModelTester: + def __init__( + self, + parent, + batch_size=2, + num_channels=3, + image_size=4, + patch_size=2, + text_seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=True, + use_labels=True, + vocab_size=99, + hidden_size=36, + num_hidden_layers=3, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + coordinate_size=6, + shape_size=6, + num_labels=3, + num_choices=4, + scope=None, + range_bbox=1000, + ): + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.patch_size = patch_size + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.coordinate_size = coordinate_size + self.shape_size = shape_size + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + self.range_bbox = range_bbox + + # LayoutLMv3's sequence length equals the number of text tokens + number of patches + 1 (we add 1 for the CLS token) + self.text_seq_length = text_seq_length + self.image_seq_length = (image_size // patch_size) ** 2 + 1 + self.seq_length = self.text_seq_length + self.image_seq_length + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.text_seq_length], self.vocab_size) + + bbox = ids_tensor([self.batch_size, self.text_seq_length, 4], self.range_bbox) + bbox = bbox.numpy() + # Ensure that bbox is legal + for i in range(bbox.shape[0]): + for j in range(bbox.shape[1]): + if bbox[i, j, 3] < bbox[i, j, 1]: + tmp_coordinate = bbox[i, j, 3] + bbox[i, j, 3] = bbox[i, j, 1] + bbox[i, j, 1] = tmp_coordinate + if bbox[i, j, 2] < bbox[i, j, 0]: + tmp_coordinate = bbox[i, j, 2] + bbox[i, j, 2] = bbox[i, j, 0] + bbox[i, j, 0] = tmp_coordinate + bbox = tf.constant(bbox) + + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.text_seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.text_seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.text_seq_length], self.num_labels) + + config = LayoutLMv3Config( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + coordinate_size=self.coordinate_size, + shape_size=self.shape_size, + input_size=self.image_size, + patch_size=self.patch_size, + ) + + return config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels + + def create_and_check_model(self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask): + model = TFLayoutLMv3Model(config=config) + + # text + image + result = model(input_ids, pixel_values=pixel_values, training=False) + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + training=False, + ) + result = model(input_ids, bbox=bbox, pixel_values=pixel_values, training=False) + + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + # text only + result = model(input_ids, training=False) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.text_seq_length, self.hidden_size) + ) + + # image only + result = model({"pixel_values": pixel_values}, training=False) + self.parent.assertEqual( + result.last_hidden_state.shape, (self.batch_size, self.image_seq_length, self.hidden_size) + ) + + def create_and_check_for_sequence_classification( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels + ): + config.num_labels = self.num_labels + model = TFLayoutLMv3ForSequenceClassification(config=config) + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=sequence_labels, + training=False, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, token_labels + ): + config.num_labels = self.num_labels + model = TFLayoutLMv3ForTokenClassification(config=config) + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + labels=token_labels, + training=False, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.text_seq_length, self.num_labels)) + + def create_and_check_for_question_answering( + self, config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels + ): + config.num_labels = 2 + model = TFLayoutLMv3ForQuestionAnswering(config=config) + result = model( + input_ids, + bbox=bbox, + pixel_values=pixel_values, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + training=False, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + (config, input_ids, bbox, pixel_values, token_type_ids, input_mask, _, _) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "bbox": bbox, + "pixel_values": pixel_values, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + return config, inputs_dict + + +@require_tf +class TFLayoutLMv3ModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFLayoutLMv3Model, + TFLayoutLMv3ForQuestionAnswering, + TFLayoutLMv3ForSequenceClassification, + TFLayoutLMv3ForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFLayoutLMv3Model, + "question-answering": TFLayoutLMv3ForQuestionAnswering, + "text-classification": TFLayoutLMv3ForSequenceClassification, + "token-classification": TFLayoutLMv3ForTokenClassification, + "zero-shot": TFLayoutLMv3ForSequenceClassification, + } + if is_tf_available() + else {} + ) + + test_pruning = False + test_resize_embeddings = False + test_onnx = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + return True + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False) -> dict: + inputs_dict = copy.deepcopy(inputs_dict) + + if model_class in get_values(TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict = { + k: tf.tile(tf.expand_dims(v, 1), (1, self.model_tester.num_choices) + (1,) * (v.ndim - 1)) + if isinstance(v, tf.Tensor) and v.ndim > 0 + else v + for k, v in inputs_dict.items() + } + + if return_labels: + if model_class in get_values(TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict["labels"] = tf.ones(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in get_values(TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING): + inputs_dict["start_positions"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + inputs_dict["end_positions"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in get_values(TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING): + inputs_dict["labels"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in get_values(TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING): + inputs_dict["labels"] = tf.zeros( + (self.model_tester.batch_size, self.model_tester.text_seq_length), dtype=tf.int32 + ) + + return inputs_dict + + def setUp(self): + self.model_tester = TFLayoutLMv3ModelTester(self) + self.config_tester = ConfigTester(self, config_class=LayoutLMv3Config, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_loss_computation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + if getattr(model, "hf_compute_loss", None): + # The number of elements in the loss should be the same as the number of elements in the label + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + added_label = prepared_for_class[ + sorted(prepared_for_class.keys() - inputs_dict.keys(), reverse=True)[0] + ] + expected_loss_size = added_label.shape.as_list()[:1] + + # Test that model correctly compute the loss with kwargs + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + input_ids = prepared_for_class.pop("input_ids") + + loss = model(input_ids, **prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + # Test that model correctly compute the loss when we mask some positions + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + input_ids = prepared_for_class.pop("input_ids") + if "labels" in prepared_for_class: + labels = prepared_for_class["labels"].numpy() + if len(labels.shape) > 1 and labels.shape[1] != 1: + labels[0] = -100 + prepared_for_class["labels"] = tf.convert_to_tensor(labels) + loss = model(input_ids, **prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + self.assertTrue(not np.any(np.isnan(loss.numpy()))) + + # Test that model correctly compute the loss with a dict + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + loss = model(prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + # Test that model correctly compute the loss with a tuple + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + + # Get keys that were added with the _prepare_for_class function + label_keys = prepared_for_class.keys() - inputs_dict.keys() + signature = inspect.signature(model.call).parameters + signature_names = list(signature.keys()) + + # Create a dictionary holding the location of the tensors in the tuple + tuple_index_mapping = {0: "input_ids"} + for label_key in label_keys: + label_key_index = signature_names.index(label_key) + tuple_index_mapping[label_key_index] = label_key + sorted_tuple_index_mapping = sorted(tuple_index_mapping.items()) + # Initialize a list with their default values, update the values and convert to a tuple + list_input = [] + + for name in signature_names: + if name != "kwargs": + list_input.append(signature[name].default) + + for index, value in sorted_tuple_index_mapping: + list_input[index] = prepared_for_class[value] + + tuple_input = tuple(list_input) + + # Send to model + loss = model(tuple_input[:-1])[0] + + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + def test_model(self): + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + _, + _, + ) = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(config, input_ids, bbox, pixel_values, token_type_ids, input_mask) + + def test_model_various_embeddings(self): + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + _, + _, + ) = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config.position_embedding_type = type + self.model_tester.create_and_check_model(config, input_ids, bbox, pixel_values, token_type_ids, input_mask) + + def test_for_sequence_classification(self): + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + sequence_labels, + _, + ) = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification( + config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels + ) + + def test_for_token_classification(self): + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + _, + token_labels, + ) = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification( + config, input_ids, bbox, pixel_values, token_type_ids, input_mask, token_labels + ) + + def test_for_question_answering(self): + ( + config, + input_ids, + bbox, + pixel_values, + token_type_ids, + input_mask, + sequence_labels, + _, + ) = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering( + config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels + ) + + @slow + def test_model_from_pretrained(self): + for model_name in TF_LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = TFLayoutLMv3Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_tf +class TFLayoutLMv3ModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return LayoutLMv3FeatureExtractor(apply_ocr=False) if is_vision_available() else None + + @slow + def test_inference_no_head(self): + model = TFLayoutLMv3Model.from_pretrained("microsoft/layoutlmv3-base") + + feature_extractor = self.default_feature_extractor + image = prepare_img() + pixel_values = feature_extractor(images=image, return_tensors="tf").pixel_values + + input_ids = tf.constant([[1, 2]]) + bbox = tf.expand_dims(tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]]), axis=0) + + # forward pass + outputs = model(input_ids=input_ids, bbox=bbox, pixel_values=pixel_values, training=False) + + # verify the logits + expected_shape = (1, 199, 768) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = tf.constant( + [[-0.0529, 0.3618, 0.1632], [-0.1587, -0.1667, -0.0400], [-0.1557, -0.1671, -0.0505]] + ) + + self.assertTrue(np.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_processor_layoutlmv3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_processor_layoutlmv3.py new file mode 100644 index 0000000000000000000000000000000000000000..f649e0c275a2c8030a2ed450261de3bbfafa6685 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_processor_layoutlmv3.py @@ -0,0 +1,473 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest +from typing import List + +import numpy as np + +from transformers import PreTrainedTokenizer, PreTrainedTokenizerBase, PreTrainedTokenizerFast +from transformers.models.layoutlmv3 import LayoutLMv3Tokenizer, LayoutLMv3TokenizerFast +from transformers.models.layoutlmv3.tokenization_layoutlmv3 import VOCAB_FILES_NAMES +from transformers.testing_utils import require_pytesseract, require_tokenizers, require_torch, slow +from transformers.utils import FEATURE_EXTRACTOR_NAME, cached_property, is_pytesseract_available + + +if is_pytesseract_available(): + from PIL import Image + + from transformers import LayoutLMv3ImageProcessor, LayoutLMv3Processor + + +@require_pytesseract +@require_tokenizers +class LayoutLMv3ProcessorTest(unittest.TestCase): + tokenizer_class = LayoutLMv3Tokenizer + rust_tokenizer_class = LayoutLMv3TokenizerFast + + def setUp(self): + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + ] + self.tmpdirname = tempfile.mkdtemp() + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + image_processor_map = { + "do_resize": True, + "size": 224, + "apply_ocr": True, + } + + self.feature_extraction_file = os.path.join(self.tmpdirname, FEATURE_EXTRACTOR_NAME) + with open(self.feature_extraction_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(image_processor_map) + "\n") + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs) -> PreTrainedTokenizerFast: + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_tokenizers(self, **kwargs) -> List[PreTrainedTokenizerBase]: + return [self.get_tokenizer(**kwargs), self.get_rust_tokenizer(**kwargs)] + + def get_image_processor(self, **kwargs): + return LayoutLMv3ImageProcessor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + image_processor = self.get_image_processor() + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + processor.save_pretrained(self.tmpdirname) + processor = LayoutLMv3Processor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertIsInstance(processor.tokenizer, (LayoutLMv3Tokenizer, LayoutLMv3TokenizerFast)) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv3ImageProcessor) + + def test_save_load_pretrained_additional_features(self): + processor = LayoutLMv3Processor(image_processor=self.get_image_processor(), tokenizer=self.get_tokenizer()) + processor.save_pretrained(self.tmpdirname) + + # slow tokenizer + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_resize=False, size=30) + + processor = LayoutLMv3Processor.from_pretrained( + self.tmpdirname, use_fast=False, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutLMv3Tokenizer) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv3ImageProcessor) + + # fast tokenizer + tokenizer_add_kwargs = self.get_rust_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + image_processor_add_kwargs = self.get_image_processor(do_resize=False, size=30) + + processor = LayoutLMv3Processor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutLMv3TokenizerFast) + + self.assertEqual(processor.image_processor.to_json_string(), image_processor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.image_processor, LayoutLMv3ImageProcessor) + + def test_model_input_names(self): + image_processor = self.get_image_processor() + tokenizer = self.get_tokenizer() + + processor = LayoutLMv3Processor(tokenizer=tokenizer, image_processor=image_processor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + # add extra args + inputs = processor(text=input_str, images=image_input, return_codebook_pixels=False, return_image_mask=False) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) + + +# different use cases tests +@require_torch +@require_pytesseract +class LayoutLMv3ProcessorIntegrationTests(unittest.TestCase): + @cached_property + def get_images(self): + # we verify our implementation on 2 document images from the DocVQA dataset + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/fixtures_docvqa", split="test") + + image_1 = Image.open(ds[0]["file"]).convert("RGB") + image_2 = Image.open(ds[1]["file"]).convert("RGB") + + return image_1, image_2 + + @cached_property + def get_tokenizers(self): + slow_tokenizer = LayoutLMv3Tokenizer.from_pretrained("microsoft/layoutlmv3-base", add_visual_labels=False) + fast_tokenizer = LayoutLMv3TokenizerFast.from_pretrained("microsoft/layoutlmv3-base", add_visual_labels=False) + return [slow_tokenizer, fast_tokenizer] + + @slow + def test_processor_case_1(self): + # case 1: document image classification (training, inference) + token classification (inference), apply_ocr = True + + image_processor = LayoutLMv3ImageProcessor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + input_image_proc = image_processor(images[0], return_tensors="pt") + input_processor = processor(images[0], return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify image + self.assertAlmostEqual( + input_image_proc["pixel_values"].sum(), input_processor["pixel_values"].sum(), delta=1e-2 + ) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " 11:14 to 11:39 a.m 11:39 to 11:44 a.m. 11:44 a.m. to 12:25 p.m. 12:25 to 12:58 p.m. 12:58 to 4:00 p.m. 2:00 to 5:00 p.m. Coffee Break Coffee will be served for men and women in the lobby adjacent to exhibit area. Please move into exhibit area. (Exhibits Open) TRRF GENERAL SESSION (PART |) Presiding: Lee A. Waller TRRF Vice President “Introductory Remarks” Lee A. Waller, TRRF Vice Presi- dent Individual Interviews with TRRF Public Board Members and Sci- entific Advisory Council Mem- bers Conducted by TRRF Treasurer Philip G. Kuehn to get answers which the public refrigerated warehousing industry is looking for. Plus questions from the floor. Dr. Emil M. Mrak, University of Cal- ifornia, Chairman, TRRF Board; Sam R. Cecil, University of Georgia College of Agriculture; Dr. Stanley Charm, Tufts University School of Medicine; Dr. Robert H. Cotton, ITT Continental Baking Company; Dr. Owen Fennema, University of Wis- consin; Dr. Robert E. Hardenburg, USDA. Questions and Answers Exhibits Open Capt. Jack Stoney Room TRRF Scientific Advisory Council Meeting Ballroom Foyer" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + input_image_proc = image_processor(images, return_tensors="pt") + input_processor = processor(images, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify images + self.assertAlmostEqual( + input_image_proc["pixel_values"].sum(), input_processor["pixel_values"].sum(), delta=1e-2 + ) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " 7 ITC Limited REPORT AND ACCOUNTS 2013 ITC’s Brands: An Asset for the Nation The consumer needs and aspirations they fulfil, the benefit they generate for millions across ITC’s value chains, the future-ready capabilities that support them, and the value that they create for the country, have made ITC’s brands national assets, adding to India’s competitiveness. It is ITC’s aspiration to be the No 1 FMCG player in the country, driven by its new FMCG businesses. A recent Nielsen report has highlighted that ITC's new FMCG businesses are the fastest growing among the top consumer goods companies operating in India. ITC takes justifiable pride that, along with generating economic value, these celebrated Indian brands also drive the creation of larger societal capital through the virtuous cycle of sustainable and inclusive growth. DI WILLS * ; LOVE DELIGHTFULLY SOFT SKIN? aia Ans Source: https://www.industrydocuments.ucsf.edu/docs/snbx0223" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + @slow + def test_processor_case_2(self): + # case 2: document image classification (training, inference) + token classification (inference), apply_ocr=False + + image_processor = LayoutLMv3ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], words, boxes=boxes, return_tensors="pt") + + # verify keys + expected_keys = ["input_ids", "bbox", "attention_mask", "pixel_values"] + actual_keys = list(input_processor.keys()) + for key in expected_keys: + self.assertIn(key, actual_keys) + + # verify input_ids + expected_decoding = " hello world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, words, boxes=boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " hello world" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [0, 0, 0, 0], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_3(self): + # case 3: token classification (training), apply_ocr=False + + image_processor = LayoutLMv3ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + words = ["weirdly", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + word_labels = [1, 2] + input_processor = processor(images[0], words, boxes=boxes, word_labels=word_labels, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "labels", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " weirdly world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify labels + expected_labels = [-100, 1, -100, 2, -100] + self.assertListEqual(input_processor.labels.squeeze().tolist(), expected_labels) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + word_labels = [[1, 2], [6, 3, 10, 2]] + input_processor = processor( + images, words, boxes=boxes, word_labels=word_labels, padding=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "labels", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " my name is niels" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [0, 0, 0, 0], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + # verify labels + expected_labels = [-100, 6, 3, 10, 2, -100, -100] + self.assertListEqual(input_processor.labels[1].tolist(), expected_labels) + + @slow + def test_processor_case_4(self): + # case 4: visual question answering (inference), apply_ocr=True + + image_processor = LayoutLMv3ImageProcessor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + input_processor = processor(images[0], question, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " What's his name?
11:14 to 11:39 a.m 11:39 to 11:44 a.m. 11:44 a.m. to 12:25 p.m. 12:25 to 12:58 p.m. 12:58 to 4:00 p.m. 2:00 to 5:00 p.m. Coffee Break Coffee will be served for men and women in the lobby adjacent to exhibit area. Please move into exhibit area. (Exhibits Open) TRRF GENERAL SESSION (PART |) Presiding: Lee A. Waller TRRF Vice President “Introductory Remarks” Lee A. Waller, TRRF Vice Presi- dent Individual Interviews with TRRF Public Board Members and Sci- entific Advisory Council Mem- bers Conducted by TRRF Treasurer Philip G. Kuehn to get answers which the public refrigerated warehousing industry is looking for. Plus questions from the floor. Dr. Emil M. Mrak, University of Cal- ifornia, Chairman, TRRF Board; Sam R. Cecil, University of Georgia College of Agriculture; Dr. Stanley Charm, Tufts University School of Medicine; Dr. Robert H. Cotton, ITT Continental Baking Company; Dr. Owen Fennema, University of Wis- consin; Dr. Robert E. Hardenburg, USDA. Questions and Answers Exhibits Open Capt. Jack Stoney Room TRRF Scientific Advisory Council Meeting Ballroom Foyer
" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + input_processor = processor( + images, questions, padding="max_length", max_length=20, truncation=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + expected_decoding = " what's the time 7 ITC Limited REPORT AND ACCOUNTS 2013 ITC" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + # fmt: off + expected_bbox = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 45, 67, 80], [72, 56, 109, 67], [72, 56, 109, 67], [116, 56, 189, 67], [198, 59, 253, 66], [257, 59, 285, 66], [289, 59, 365, 66], [289, 59, 365, 66], [289, 59, 365, 66], [372, 59, 407, 66], [74, 136, 161, 158], [74, 136, 161, 158], [0, 0, 0, 0]] # noqa: E231 + # fmt: on + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_5(self): + # case 5: visual question answering (inference), apply_ocr=False + + image_processor = LayoutLMv3ImageProcessor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutLMv3Processor(image_processor=image_processor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], question, words, boxes, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " What's his name? hello world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, questions, words, boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "input_ids", "pixel_values"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " How old is he? hello world" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + expected_decoding = " what's the time my name is niels" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [[6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3], [1, 1, 2, 3], [0, 0, 0, 0]] + self.assertListEqual(input_processor.bbox[1].tolist()[-5:], expected_bbox) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py new file mode 100644 index 0000000000000000000000000000000000000000..63d86f280cc00792aa85ea01c480aa9f815f5696 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutlmv3/test_tokenization_layoutlmv3.py @@ -0,0 +1,2437 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import inspect +import json +import os +import re +import shutil +import tempfile +import unittest +from typing import List + +from transformers import ( + AddedToken, + LayoutLMv3TokenizerFast, + SpecialTokensMixin, + is_tf_available, + is_torch_available, + logging, +) +from transformers.models.layoutlmv3.tokenization_layoutlmv3 import VOCAB_FILES_NAMES, LayoutLMv3Tokenizer +from transformers.testing_utils import ( + is_pt_tf_cross_test, + require_pandas, + require_tf, + require_tokenizers, + require_torch, + slow, +) + +from ...test_tokenization_common import SMALL_TRAINING_CORPUS, TokenizerTesterMixin, merge_model_tokenizer_mappings + + +logger = logging.get_logger(__name__) + + +@require_tokenizers +@require_pandas +class LayoutLMv3TokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LayoutLMv3Tokenizer + rust_tokenizer_class = LayoutLMv3TokenizerFast + test_rust_tokenizer = True + # determined by the tokenization algortihm and the way it's decoded by the fast tokenizers + space_between_special_tokens = False + test_seq2seq = False + from_pretrained_kwargs = {"cls_token": ""} + + def get_words_and_boxes(self): + words = ["lower", "newer"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287]] + + return words, boxes + + def get_words_and_boxes_batch(self): + words = [["lower", "newer"], ["new", "low"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287]], + [[961, 885, 992, 912], [256, 38, 330, 58]], + ] + + return words, boxes + + def get_question_words_and_boxes(self): + question = "what's his name?" + words = ["lower", "newer"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287]] + + return question, words, boxes + + def get_question_words_and_boxes_batch(self): + questions = ["what's his name?", "how is he called?"] + words = [["lower", "newer"], ["newer", "lower"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287]], + [[256, 38, 330, 58], [256, 38, 330, 58]], + ] + + return questions, words, boxes + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return LayoutLMv3TokenizerFast.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.tokenizer_class(self.vocab_file, self.merges_file, **self.special_tokens_map) + text = "lower newer" + bpe_tokens = ["Ġlow", "er", "Ġ", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text) # , add_prefix_space=True) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [14, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("microsoft/layoutlmv3-base") + + question, words, boxes = self.get_question_words_and_boxes() + + text = tokenizer.encode( + question.split(), + boxes=[tokenizer.pad_token_box for _ in range(len(question.split()))], + add_special_tokens=False, + ) + text_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_pair == [0] + text + [2] + [2] + text_2 + [2] + + def test_add_special_tokens(self): + tokenizers: List[LayoutLMv3Tokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + special_token = "[SPECIAL_TOKEN]" + special_token_box = [1000, 1000, 1000, 1000] + + tokenizer.add_special_tokens({"cls_token": special_token}) + encoded_special_token = tokenizer.encode( + [special_token], boxes=[special_token_box], add_special_tokens=False + ) + self.assertEqual(len(encoded_special_token), 1) + + decoded = tokenizer.decode(encoded_special_token, skip_special_tokens=True) + self.assertTrue(special_token not in decoded) + + def test_add_tokens_tokenizer(self): + tokenizers: List[LayoutLMv3Tokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab_size = tokenizer.vocab_size + all_size = len(tokenizer) + + self.assertNotEqual(vocab_size, 0) + + # We usually have added tokens from the start in tests because our vocab fixtures are + # smaller than the original vocabs - let's not assert this + # self.assertEqual(vocab_size, all_size) + + new_toks = ["aaaaa", "bbbbbb", "cccccccccdddddddd"] + added_toks = tokenizer.add_tokens(new_toks) + vocab_size_2 = tokenizer.vocab_size + all_size_2 = len(tokenizer) + + self.assertNotEqual(vocab_size_2, 0) + self.assertEqual(vocab_size, vocab_size_2) + self.assertEqual(added_toks, len(new_toks)) + self.assertEqual(all_size_2, all_size + len(new_toks)) + + words = "aaaaa bbbbbb low cccccccccdddddddd l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + self.assertGreaterEqual(len(tokens), 4) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + + new_toks_2 = {"eos_token": ">>>>|||<||<<|<<", "pad_token": "<<<<<|||>|>>>>|>"} + added_toks_2 = tokenizer.add_special_tokens(new_toks_2) + vocab_size_3 = tokenizer.vocab_size + all_size_3 = len(tokenizer) + + self.assertNotEqual(vocab_size_3, 0) + self.assertEqual(vocab_size, vocab_size_3) + self.assertEqual(added_toks_2, len(new_toks_2)) + self.assertEqual(all_size_3, all_size_2 + len(new_toks_2)) + + words = ">>>>|||<||<<|<< aaaaabbbbbb low cccccccccdddddddd <<<<<|||>|>>>>|> l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode( + words, + boxes=boxes, + add_special_tokens=False, + ) + + self.assertGreaterEqual(len(tokens), 6) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[0], tokens[1]) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokens[-3]) + self.assertEqual(tokens[0], tokenizer.eos_token_id) + self.assertEqual(tokens[-2], tokenizer.pad_token_id) + + @require_tokenizers + def test_encode_decode_with_spaces(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + new_toks = [AddedToken("[ABC]", normalized=False), AddedToken("[DEF]", normalized=False)] + tokenizer.add_tokens(new_toks) + input = "[ABC][DEF][ABC][DEF]" + if self.space_between_special_tokens: + output = "[ABC] [DEF] [ABC] [DEF]" + else: + output = input + encoded = tokenizer.encode(input.split(), boxes=boxes, add_special_tokens=False) + decoded = tokenizer.decode(encoded, spaces_between_special_tokens=self.space_between_special_tokens) + self.assertIn(decoded, [output, output.lower()]) + + @unittest.skip("Not implemented") + def test_right_and_left_truncation(self): + pass + + def test_encode_plus_with_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_size = 10 + padding_idx = tokenizer.pad_token_id + + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_special_tokens_mask=True) + input_ids = encoded_sequence["input_ids"] + special_tokens_mask = encoded_sequence["special_tokens_mask"] + sequence_length = len(input_ids) + + # Test 'longest' and 'no_padding' don't do anything + tokenizer.padding_side = "right" + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + # Test right padding + tokenizer.padding_side = "right" + + right_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + right_padded_input_ids = right_padded_sequence["input_ids"] + + right_padded_special_tokens_mask = right_padded_sequence["special_tokens_mask"] + right_padded_sequence_length = len(right_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == right_padded_sequence_length) + self.assertTrue(input_ids + [padding_idx] * padding_size == right_padded_input_ids) + self.assertTrue(special_tokens_mask + [1] * padding_size == right_padded_special_tokens_mask) + + # Test left padding + tokenizer.padding_side = "left" + left_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + left_padded_input_ids = left_padded_sequence["input_ids"] + left_padded_special_tokens_mask = left_padded_sequence["special_tokens_mask"] + left_padded_sequence_length = len(left_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == left_padded_sequence_length) + self.assertTrue([padding_idx] * padding_size + input_ids == left_padded_input_ids) + self.assertTrue([1] * padding_size + special_tokens_mask == left_padded_special_tokens_mask) + + if "token_type_ids" in tokenizer.model_input_names: + token_type_ids = encoded_sequence["token_type_ids"] + left_padded_token_type_ids = left_padded_sequence["token_type_ids"] + right_padded_token_type_ids = right_padded_sequence["token_type_ids"] + + assert token_type_ids + [0] * padding_size == right_padded_token_type_ids + assert [0] * padding_size + token_type_ids == left_padded_token_type_ids + + if "attention_mask" in tokenizer.model_input_names: + attention_mask = encoded_sequence["attention_mask"] + right_padded_attention_mask = right_padded_sequence["attention_mask"] + left_padded_attention_mask = left_padded_sequence["attention_mask"] + + self.assertTrue(attention_mask + [0] * padding_size == right_padded_attention_mask) + self.assertTrue([0] * padding_size + attention_mask == left_padded_attention_mask) + + def test_internal_consistency(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + tokens = [] + for word in words: + tokens.extend(tokenizer.tokenize(word)) + ids = tokenizer.convert_tokens_to_ids(tokens) + ids_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, ids_2) + + tokens_2 = tokenizer.convert_ids_to_tokens(ids) + self.assertNotEqual(len(tokens_2), 0) + text_2 = tokenizer.decode(ids) + self.assertIsInstance(text_2, str) + + output_text = " lower newer" + self.assertEqual(text_2, output_text) + + def test_mask_output(self): + tokenizers = self.get_tokenizers(fast=False, do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + if ( + tokenizer.build_inputs_with_special_tokens.__qualname__.split(".")[0] != "PreTrainedTokenizer" + and "token_type_ids" in tokenizer.model_input_names + ): + information = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + sequences, mask = information["input_ids"], information["token_type_ids"] + self.assertEqual(len(sequences), len(mask)) + + def test_number_of_added_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=False), len(attached_sequences) - len(sequences) + ) + + # test 2: two sequences + question, words, boxes = self.get_question_words_and_boxes() + + sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=True), len(attached_sequences) - len(sequences) + ) + + def test_padding_to_max_length(self): + """We keep this test for backward compatibility but it should be removed when `pad_to_max_length` will be deprecated""" + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_idx = tokenizer.pad_token_id + + # Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + # FIXME: the next line should be padding(max_length) to avoid warning + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, pad_to_max_length=True + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # Check that nothing is done when a maximum length is not specified + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, pad_to_max_length=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + def test_padding(self, max_length=50): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + # Encode - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.encode(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode(words, boxes=boxes, padding=True) + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, padding=True) + input_p = tokenizer_p.encode(question, words, boxes=boxes, padding="longest") + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode_plus - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + input_r = tokenizer_r.encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Encode_plus - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(question, words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(question, words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Batch_encode_plus - Simple input + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="longest", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.batch_encode_plus(words, boxes=boxes, padding=True) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Batch_encode_plus - Pair input + questions, words, boxes = self.get_question_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding=True, + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding="longest", + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad on single examples after tokenization + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p) + + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p) + + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + def test_padding_warning_message_fast_tokenizer(self): + if not self.test_rust_tokenizer: + return + + words, boxes = self.get_words_and_boxes_batch() + + tokenizer_fast = self.get_rust_tokenizer() + + encoding_fast = tokenizer_fast( + words, + boxes=boxes, + ) + + with self.assertLogs("transformers", level="WARNING") as cm: + tokenizer_fast.pad(encoding_fast) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to" + " encode the text followed by a call to the `pad` method to get a padded encoding.", + cm.records[0].message, + ) + + if not self.test_slow_tokenizer: + return + + tokenizer_slow = self.get_tokenizer() + + encoding_slow = tokenizer_slow( + words, + boxes=boxes, + ) + + with self.assertLogs(level="WARNING") as cm: + # We want to assert there are no warnings, but the 'assertLogs' method does not support that. + # Therefore, we are adding a dummy warning, and then we will assert it is the only warning. + logger.warning("Dummy warning") + tokenizer_slow.pad(encoding_slow) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Dummy warning", + cm.records[0].message, + ) + + def test_call(self): + # Tests that all call wrap to encode_plus and batch_encode_plus + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Test not batched + words, boxes = self.get_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test not batched pairs + question, words, boxes = self.get_question_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test batched + words, boxes = self.get_words_and_boxes_batch() + encoded_sequences_1 = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + def test_batch_encode_plus_batch_sequence_length(self): + # Tests that all encoded values have the correct size + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + encoded_sequences = [ + tokenizer.encode_plus(words_example, boxes=boxes_example) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes, padding=False) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + maximum_length = len( + max([encoded_sequence["input_ids"] for encoded_sequence in encoded_sequences], key=len) + ) + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences_padded = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=maximum_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + + encoded_sequences_batch_padded = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + self.assertListEqual( + encoded_sequences_padded, + self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch_padded), + ) + + # check 'longest' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding="longest" + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + # check 'no_padding' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=False + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding=False + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + @unittest.skip("batch_encode_plus does not handle overflowing tokens.") + def test_batch_encode_plus_overflowing_tokens(self): + pass + + def test_batch_encode_plus_padding(self): + # Test that padded sequences are equivalent between batch_encode_plus and encode_plus + + # Right padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + # Left padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokenizer.padding_side = "left" + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + def test_padding_to_multiple_of(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.pad_token is None: + self.skipTest("No padding token.") + else: + words, boxes = self.get_words_and_boxes() + + # empty_tokens = tokenizer([""], [[]], padding=True, pad_to_multiple_of=8) + normal_tokens = tokenizer(words, boxes=boxes, padding=True, pad_to_multiple_of=8) + # for key, value in empty_tokens.items(): + # self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + normal_tokens = tokenizer(words, boxes=boxes, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertNotEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # Should also work with truncation + normal_tokens = tokenizer(words, boxes=boxes, padding=True, truncation=True, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # truncation to something which is not a multiple of pad_to_multiple_of raises an error + self.assertRaises( + ValueError, + tokenizer.__call__, + words, + boxes=boxes, + padding=True, + truncation=True, + max_length=12, + pad_to_multiple_of=8, + ) + + def test_tokenizer_slow_store_full_signature(self): + signature = inspect.signature(self.tokenizer_class.__init__) + tokenizer = self.get_tokenizer() + + for parameter_name, parameter in signature.parameters.items(): + if parameter.default != inspect.Parameter.empty: + self.assertIn(parameter_name, tokenizer.init_kwargs) + + def test_build_inputs_with_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Input tokens id + words, boxes = self.get_words_and_boxes() + input_simple = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + input_pair = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + + # Generate output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple) + self.assertEqual(output_p, output_r) + + # Generate pair output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple, input_pair) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple, input_pair) + self.assertEqual(output_p, output_r) + + def test_special_tokens_mask_input_pairs(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + return_special_tokens_mask=True, + # add_prefix_space=False, + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [ + (x if not special_tokens_mask[i] else None) for i, x in enumerate(encoded_sequence_w_special) + ] + filtered_sequence = [x for x in filtered_sequence if x is not None] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_special_tokens_mask(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + # Testing single inputs + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, boxes=boxes, add_special_tokens=True, return_special_tokens_mask=True + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [x for i, x in enumerate(encoded_sequence_w_special) if not special_tokens_mask[i]] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_save_and_load_tokenizer(self): + # safety check on max_len default value so we are sure the test works + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertNotEqual(tokenizer.model_max_length, 42) + + # Now let's start the test + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + words, boxes = self.get_words_and_boxes() + tmpdirname = tempfile.mkdtemp() + + before_tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + + shutil.rmtree(tmpdirname) + + def test_right_and_left_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + sequence = "Sequence" + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_idx = tokenizer.pad_token_id + + # RIGHT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # LEFT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "left" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert [padding_idx] * padding_size + encoded_sequence == padded_sequence + + # RIGHT & LEFT PADDING - Check that nothing is done for 'longest' and 'no_padding' + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, padding=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding="longest") + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding=False) + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + def test_token_type_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + output = tokenizer(words, boxes=boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + self.assertNotIn(1, output["token_type_ids"]) + + # test 2: two sequences (question + words) + question, words, boxes = self.get_question_words_and_boxes() + + output = tokenizer(question, words, boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + + def test_offsets_mapping(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + text = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(text))] + + # No pair + tokens_with_offsets = tokenizer_r.encode_plus( + text, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(False) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + # Pairs + text = "what's his name" + pair = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(pair))] + tokens_with_offsets = tokenizer_r.encode_plus( + text, + pair, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(True) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + @require_torch + @slow + def test_torch_encode_plus_sent_to_model(self): + import torch + + from transformers import MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + is_using_common_embeddings = hasattr(model.get_input_embeddings(), "weight") + assert ( + (model.get_input_embeddings().weight.shape[0] >= len(tokenizer)) + if is_using_common_embeddings + else True + ) + + # Build sequence + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_tensors="pt") + batch_encoded_sequence = tokenizer.batch_encode_plus( + [words, words], boxes=[boxes, boxes], return_tensors="pt" + ) + + # We add dummy pixel_values keys (as LayoutLMv3 actually also requires a feature extractor + # to prepare the image input) + encoded_sequence["pixel_values"] = torch.randn(1, 3, 224, 224) + batch_encoded_sequence["pixel_values"] = torch.randn(2, 3, 224, 224) + + # This should not fail + with torch.no_grad(): # saves some time + model(**encoded_sequence) + model(**batch_encoded_sequence) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + words, boxes = self.get_words_and_boxes() + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + self.assertListEqual(ids, rust_ids) + + def test_tokenization_python_rust_equals(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words, boxes = self.get_words_and_boxes() + + # Ensure basic input match + input_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + input_pairs_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_pairs_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_pairs_p[key], input_pairs_r[key]) + + words = ["hello" for _ in range(1000)] + boxes = [[1000, 1000, 1000, 1000] for _ in range(1000)] + + # Ensure truncation match + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + # Ensure truncation with stride match + input_p = tokenizer_p.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + input_r = tokenizer_r.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key][0]) + + def test_embeded_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + words, boxes = self.get_words_and_boxes() + tokens_r = tokenizer_r.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + tokens_p = tokenizer_p.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + + for key in tokens_p.keys(): + self.assertEqual(tokens_r[key], tokens_p[key]) + + if "token_type_ids" in tokens_r: + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + tokens_r = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + self.assertSequenceEqual(tokens_r, tokens_p) + + def test_compare_add_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + simple_num_special_tokens_to_add = tokenizer_r.num_special_tokens_to_add(pair=False) + + words, boxes = self.get_words_and_boxes() + # tokenize() + no_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=False) + with_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode() + no_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode_plus() + no_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + self.assertEqual( + len(no_special_tokens[key]), + len(with_special_tokens[key]) - simple_num_special_tokens_to_add, + ) + + # # batch_encode_plus + words, boxes = self.get_words_and_boxes_batch() + + no_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + for i_no, i_with in zip(no_special_tokens[key], with_special_tokens[key]): + self.assertEqual(len(i_no), len(i_with) - simple_num_special_tokens_to_add) + + @slow + def test_layoutlmv3_truncation_integration_test(self): + words, boxes = self.get_words_and_boxes() + + tokenizer = LayoutLMv3Tokenizer.from_pretrained("microsoft/layoutlmv3-base", model_max_length=512) + + for i in range(12, 512): + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, max_length=i, truncation=True) + + # Ensure that the input IDs are less than the max length defined. + self.assertLessEqual(len(new_encoded_inputs), i) + + tokenizer.model_max_length = 20 + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + dropped_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + + # Ensure that the input IDs are still truncated when no max_length is specified + self.assertListEqual(new_encoded_inputs, dropped_encoded_inputs) + self.assertLessEqual(len(new_encoded_inputs), 20) + + @is_pt_tf_cross_test + def test_batch_encode_plus_tensors(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + # A Tensor cannot be build by sequences which are not the same size + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="pt") + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="tf") + + if tokenizer.pad_token_id is None: + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding=True, + return_tensors="pt", + ) + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding="longest", + return_tensors="tf", + ) + else: + pytorch_tensor = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True, return_tensors="pt") + tensorflow_tensor = tokenizer.batch_encode_plus( + words, boxes=boxes, padding="longest", return_tensors="tf" + ) + encoded_sequences = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True) + + for key in encoded_sequences.keys(): + pytorch_value = pytorch_tensor[key].tolist() + tensorflow_value = tensorflow_tensor[key].numpy().tolist() + encoded_value = encoded_sequences[key] + + self.assertEqual(pytorch_value, tensorflow_value, encoded_value) + + def test_sequence_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + if not tokenizer.is_fast: + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + seq_1 = ["With", "these", "inputs."] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(seq_1))] + + # We want to have sequence 0 and sequence 1 are tagged + # respectively with 0 and 1 token_ids + # (regardless of whether the model use token type ids) + # We use this assumption in the QA pipeline among other place + output = tokenizer(seq_0.split(), boxes=boxes) + self.assertIn(0, output.sequence_ids()) + + output = tokenizer(seq_0, seq_1, boxes=boxes) + self.assertIn(0, output.sequence_ids()) + self.assertIn(1, output.sequence_ids()) + + if tokenizer.num_special_tokens_to_add(pair=True): + self.assertIn(None, output.sequence_ids()) + + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + r_output = tokenizer_r.encode(words, boxes=boxes) + + special_token_id = tokenizer_r.encode( + [""], boxes=[1000, 1000, 1000, 1000], add_special_tokens=False + )[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_cr = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs, from_slow=True + ) + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + p_output = tokenizer_p.encode(words, boxes=boxes) + cr_output = tokenizer_cr.encode(words, boxes=boxes) + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + def test_training_new_tokenizer(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + new_tokenizer = tokenizer.train_new_from_iterator(SMALL_TRAINING_CORPUS, 100) + + # Test we can use the new tokenizer with something not seen during training + text = [["this", "is", "the"], ["how", "are", "you"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8], [1, 3, 4, 8]], [[5, 6, 7, 8], [4, 5, 6, 7], [3, 9, 2, 7]]] + inputs = new_tokenizer(text, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = " this is the" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + # We check that the parameters of the tokenizer remained the same + # Check we have the same number of added_tokens for both pair and non-pair inputs. + self.assertEqual(tokenizer.num_special_tokens_to_add(False), new_tokenizer.num_special_tokens_to_add(False)) + self.assertEqual(tokenizer.num_special_tokens_to_add(True), new_tokenizer.num_special_tokens_to_add(True)) + + # Check we have the correct max_length for both pair and non-pair inputs. + self.assertEqual(tokenizer.max_len_single_sentence, new_tokenizer.max_len_single_sentence) + self.assertEqual(tokenizer.max_len_sentences_pair, new_tokenizer.max_len_sentences_pair) + + # Assert the set of special tokens match as we didn't ask to change them + self.assertSequenceEqual( + tokenizer.all_special_tokens_extended, + new_tokenizer.all_special_tokens_extended, + ) + + self.assertDictEqual(tokenizer.special_tokens_map, new_tokenizer.special_tokens_map) + + def test_training_new_tokenizer_with_special_tokens_change(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + # Test with a special tokens map + class_signature = inspect.signature(tokenizer.__class__) + if "cls_token" in class_signature.parameters: + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map={tokenizer.cls_token: ""} + ) + cls_id = new_tokenizer.get_vocab()[""] + self.assertEqual(new_tokenizer.cls_token, "") + self.assertEqual(new_tokenizer.cls_token_id, cls_id) + + # Create a new mapping from the special tokens defined in the original tokenizer + special_tokens_list = SpecialTokensMixin.SPECIAL_TOKENS_ATTRIBUTES.copy() + special_tokens_list.remove("additional_special_tokens") + special_tokens_map = {} + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is not None: + special_token = getattr(tokenizer, token) + special_tokens_map[special_token] = f"{special_token}a" + + # Train new tokenizer + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map=special_tokens_map + ) + + # Check the changes + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is None: + continue + special_token = getattr(tokenizer, token) + if special_token in special_tokens_map: + new_special_token = getattr(new_tokenizer, token) + self.assertEqual(special_tokens_map[special_token], new_special_token) + + new_id = new_tokenizer.get_vocab()[new_special_token] + self.assertEqual(getattr(new_tokenizer, f"{token}_id"), new_id) + + # Check if the AddedToken / string format has been kept + for special_token in tokenizer.all_special_tokens_extended: + if isinstance(special_token, AddedToken) and special_token.content not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + elif isinstance(special_token, AddedToken): + # The special token must appear in the list of the new tokenizer as an object of type AddedToken with + # the same parameters as the old AddedToken except the content that the user has requested to change. + special_token_str = special_token.content + new_special_token_str = special_tokens_map[special_token_str] + + find = False + for candidate in new_tokenizer.all_special_tokens_extended: + if ( + isinstance(candidate, AddedToken) + and candidate.content == new_special_token_str + and candidate.lstrip == special_token.lstrip + and candidate.rstrip == special_token.rstrip + and candidate.normalized == special_token.normalized + and candidate.single_word == special_token.single_word + ): + find = True + break + self.assertTrue( + find, + f"'{new_special_token_str}' doesn't appear in the list " + f"'{new_tokenizer.all_special_tokens_extended}' as an AddedToken with the same parameters as " + f"'{special_token}' in the list {tokenizer.all_special_tokens_extended}", + ) + elif special_token not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + + else: + # The special token must appear in the list of the new tokenizer as an object of type string. + self.assertTrue(special_tokens_map[special_token] in new_tokenizer.all_special_tokens_extended) + + # Test we can use the new tokenizer with something not seen during training + words = [["this", "is"], ["hello", "🤗"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[1, 2, 3, 4], [5, 6, 7, 8]]] + inputs = new_tokenizer(words, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = " this is" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + def test_prepare_for_model(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + # only test prepare_for_model for the slow tokenizer + if tokenizer.__class__.__name__ == "LayoutLMv3TokenizerFast": + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + prepared_input_dict = tokenizer.prepare_for_model(words, boxes=boxes, add_special_tokens=True) + + input_dict = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + + self.assertEqual(input_dict, prepared_input_dict) + + def test_padding_different_model_input_name(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes) + input_p = tokenizer_r.batch_encode_plus(words, boxes=boxes) + + # rename encoded batch to "inputs" + input_r["inputs"] = input_r[tokenizer_r.model_input_names[0]] + del input_r[tokenizer_r.model_input_names[0]] + + input_p["inputs"] = input_p[tokenizer_p.model_input_names[0]] + del input_p[tokenizer_p.model_input_names[0]] + + # Renaming `input_ids` to `inputs` + tokenizer_r.model_input_names = ["inputs"] + tokenizer_r.model_input_names[1:] + tokenizer_p.model_input_names = ["inputs"] + tokenizer_p.model_input_names[1:] + + input_r = tokenizer_r.pad(input_r, padding="longest") + input_p = tokenizer_r.pad(input_p, padding="longest") + + max_length = len(input_p["inputs"][0]) + self.assert_batch_padded_input_match( + input_r, input_p, max_length, pad_token_id, model_main_input_name="inputs" + ) + + def test_batch_encode_dynamic_overflowing(self): + """ + When calling batch_encode with multiple sequences, it can return different number of + overflowing encoding for each sequence: + [ + Sequence 1: [Encoding 1, Encoding 2], + Sequence 2: [Encoding 1], + Sequence 3: [Encoding 1, Encoding 2, ... Encoding N] + ] + This needs to be padded so that it can represented as a tensor + """ + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): + if is_torch_available(): + returned_tensor = "pt" + elif is_tf_available(): + returned_tensor = "tf" + else: + returned_tensor = "jax" + + # Single example + words = ["HuggingFace", "is", "solving", "NLP", "one", "commit", "at", "a", "time"] + boxes = [[i, i, i, i] for i in range(len(words))] + tokens = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=6, + padding=True, + truncation=True, + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + else: + self.assertEqual(len(tokens[key].shape), 3) + + # Batch of examples + # For these 2 examples, 3 training examples will be created + words_batched = [ + ["HuggingFace", "is", "solving", "NLP", "one", "commit", "at", "a", "time"], + ["Very", "tiny", "input"], + ] + boxes_batched = [[[i, i, i, i] for i in range(len(words_item))] for words_item in words_batched] + tokens = tokenizer.batch_encode_plus( + words_batched, + boxes=boxes_batched, + max_length=6, + padding=True, + truncation="only_first", + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + self.assertEqual(tokens[key].shape[-1], 6) + else: + self.assertEqual(len(tokens[key].shape), 3) + self.assertEqual(tokens[key].shape[-1], 4) + + @unittest.skip("TO DO: overwrite this very extensive test.") + def test_alignement_methods(self): + pass + + def get_clean_sequence(self, tokenizer, with_prefix_space=False, max_length=20, min_length=5): + toks = [(i, tokenizer.decode([i], clean_up_tokenization_spaces=False)) for i in range(len(tokenizer))] + toks = list(filter(lambda t: re.match(r"^[ a-zA-Z]+$", t[1]), toks)) + toks = list( + filter( + lambda t: [t[0]] + == tokenizer.encode(t[1].split(" "), boxes=len(t[1]) * [[1, 1, 1, 1]], add_special_tokens=False), + toks, + ) + ) + if max_length is not None and len(toks) > max_length: + toks = toks[:max_length] + if min_length is not None and len(toks) < min_length and len(toks) > 0: + while len(toks) < min_length: + toks = toks + toks + # toks_str = [t[1] for t in toks] + toks_ids = [t[0] for t in toks] + + # Ensure consistency + output_txt = tokenizer.decode(toks_ids, clean_up_tokenization_spaces=False) + if " " not in output_txt and len(toks_ids) > 1: + output_txt = ( + tokenizer.decode([toks_ids[0]], clean_up_tokenization_spaces=False) + + " " + + tokenizer.decode(toks_ids[1:], clean_up_tokenization_spaces=False) + ) + if with_prefix_space: + output_txt = " " + output_txt + words = output_txt.split(" ") + boxes = [[i, i, i, i] for i in range(len(words))] + output_ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + return words, boxes, output_ids + + def test_added_token_with_space_before(self): + tokenizer_s = self.get_tokenizer() + tokenizer_f = self.get_rust_tokenizer() + + tokens_to_add = ["AAA", "bbb"] + + words_with_space = [f" {token}" for token in tokens_to_add + tokenizer_s.unique_no_split_tokens] + words_without_space = tokens_to_add + tokenizer_s.unique_no_split_tokens + boxes = [[i, i, i, i] for i in range(len(words_with_space))] + + tokens_to_add_formated = [ + AddedToken(token, rstrip=True, lstrip=True, single_word=False) for token in tokens_to_add + ] + tokenizer_s.add_tokens(tokens_to_add_formated) + tokenizer_f.add_tokens(tokens_to_add_formated) + + ids_s = tokenizer_s(words_with_space, boxes=boxes).input_ids + ids_f = tokenizer_f(words_with_space, boxes=boxes).input_ids + + tokens_s = tokenizer_s.convert_ids_to_tokens(ids_s) + tokens_f = tokenizer_f.convert_ids_to_tokens(ids_f) + + ids_s = tokenizer_s(words_without_space, boxes=boxes).input_ids + ids_f = tokenizer_f(words_without_space, boxes=boxes).input_ids + + tokens_s = tokenizer_s.convert_ids_to_tokens(ids_s) + tokens_f = tokenizer_f.convert_ids_to_tokens(ids_f) + + self.assertEqual(tokens_s, tokens_f) + + def test_maximum_encoding_length_pair_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Build a sequence from our model's vocabulary + stride = 2 + seq_0, boxes_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + question_0 = " ".join(map(str, seq_0)) + if len(ids) <= 2 + stride: + seq_0 = (seq_0 + " ") * (2 + stride) + ids = None + + seq0_tokens = tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False) + seq0_input_ids = seq0_tokens["input_ids"] + + self.assertGreater(len(seq0_input_ids), 2 + stride) + question_1 = "This is another sentence to be encoded." + seq_1 = ["what", "a", "weird", "test", "weirdly", "weird"] + boxes_1 = [[i, i, i, i] for i in range(1, len(seq_1) + 1)] + seq1_tokens = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + if abs(len(seq0_input_ids) - len(seq1_tokens["input_ids"])) <= 2: + seq1_tokens_input_ids = seq1_tokens["input_ids"] + seq1_tokens["input_ids"] + seq_1 = tokenizer.decode(seq1_tokens_input_ids, clean_up_tokenization_spaces=False) + seq_1 = seq_1.split(" ") + boxes_1 = [[i, i, i, i] for i in range(1, len(seq_1) + 1)] + seq1_tokens = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + seq1_input_ids = seq1_tokens["input_ids"] + + self.assertGreater(len(seq1_input_ids), 2 + stride) + + smallest = seq1_input_ids if len(seq0_input_ids) > len(seq1_input_ids) else seq0_input_ids + + # We are not using the special tokens - a bit too hard to test all the tokenizers with this + # TODO try this again later + sequence = tokenizer( + question_0, seq_1, boxes=boxes_1, add_special_tokens=False + ) # , add_prefix_space=False) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_2 = seq_0 * model_max_length + question_2 = " ".join(map(str, seq_2)) + boxes_2 = boxes_0 * model_max_length + self.assertGreater(len(seq_2), model_max_length) + + sequence1 = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + sequence2 = tokenizer(question_2, seq_1, boxes=boxes_1, add_special_tokens=False) + total_length2 = len(sequence2["input_ids"]) + self.assertLess(total_length1, model_max_length, "Issue with the testing sequence, please update it.") + self.assertGreater( + total_length2, model_max_length, "Issue with the testing sequence, please update it." + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"{tokenizer.__class__.__name__} Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"{tokenizer.__class__.__name__} Truncation: {truncation_state}"): + output = tokenizer( + question_2, + seq_1, + boxes=boxes_1, + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [question_2], + [seq_1], + boxes=[boxes_1], + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple + output = tokenizer( + question_1, seq_2, boxes=boxes_2, padding=padding_state, truncation="only_second" + ) + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [question_1], [seq_2], boxes=[boxes_2], padding=padding_state, truncation="only_second" + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer( + question_1, seq_2, boxes=boxes_2, padding=padding_state, truncation=False + ) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertNotEqual(len(output["bbox"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer( + [question_1], [seq_2], boxes=[boxes_2], padding=padding_state, truncation=False + ) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertNotEqual(len(output["bbox"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + # Check the order of Sequence of input ids, overflowing tokens and bbox sequence with truncation + truncated_first_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"][:-2] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"] + ) + truncated_second_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"][:-2] + ) + truncated_longest_sequence = ( + truncated_first_sequence + if len(seq0_input_ids) > len(seq1_input_ids) + else truncated_second_sequence + ) + + overflow_first_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"][-(2 + stride) :] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"] + ) + overflow_second_sequence = ( + tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False)["input_ids"] + + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["input_ids"][-(2 + stride) :] + ) + overflow_longest_sequence = ( + overflow_first_sequence if len(seq0_input_ids) > len(seq1_input_ids) else overflow_second_sequence + ) + + bbox_first = [[0, 0, 0, 0]] * (len(seq0_input_ids) - 2) + bbox_first_sequence = bbox_first + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["bbox"] + overflowing_token_bbox_first_sequence_slow = [[0, 0, 0, 0]] * (2 + stride) + overflowing_token_bbox_first_sequence_fast = [[0, 0, 0, 0]] * (2 + stride) + tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"] + + bbox_second = [[0, 0, 0, 0]] * len(seq0_input_ids) + bbox_second_sequence = ( + bbox_second + tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False)["bbox"][:-2] + ) + overflowing_token_bbox_second_sequence_slow = tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"][-(2 + stride) :] + overflowing_token_bbox_second_sequence_fast = [[0, 0, 0, 0]] * len(seq0_input_ids) + tokenizer( + seq_1, boxes=boxes_1, add_special_tokens=False + )["bbox"][-(2 + stride) :] + + bbox_longest_sequence = ( + bbox_first_sequence if len(seq0_tokens) > len(seq1_tokens) else bbox_second_sequence + ) + overflowing_token_bbox_longest_sequence_fast = ( + overflowing_token_bbox_first_sequence_fast + if len(seq0_tokens) > len(seq1_tokens) + else overflowing_token_bbox_second_sequence_fast + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv3TokenizerFast): + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + bbox = information["bbox"][0] + overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + self.assertEqual(bbox, bbox_longest_sequence) + + self.assertEqual(len(overflowing_bbox), 2 + stride + len(smallest)) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_longest_sequence_fast) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv3TokenizerFast): + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + bbox = information["bbox"][0] + overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + self.assertEqual(bbox, bbox_longest_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_longest_sequence_fast) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + information_first_truncated = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv3TokenizerFast): + truncated_sequence = information_first_truncated["input_ids"][0] + overflowing_tokens = information_first_truncated["input_ids"][1] + bbox = information_first_truncated["bbox"][0] + overflowing_bbox = information_first_truncated["bbox"][0] + self.assertEqual(len(information_first_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq1_input_ids)) + self.assertEqual(overflowing_tokens, overflow_first_sequence) + self.assertEqual(bbox, bbox_first_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_first_sequence_fast) + else: + truncated_sequence = information_first_truncated["input_ids"] + overflowing_tokens = information_first_truncated["overflowing_tokens"] + overflowing_bbox = information_first_truncated["overflowing_token_boxes"] + bbox = information_first_truncated["bbox"] + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq0_input_ids[-(2 + stride) :]) + self.assertEqual(bbox, bbox_first_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_first_sequence_slow) + + information_second_truncated = tokenizer( + question_0, + seq_1, + boxes=boxes_1, + max_length=len(sequence["input_ids"]) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_second", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv3TokenizerFast): + truncated_sequence = information_second_truncated["input_ids"][0] + overflowing_tokens = information_second_truncated["input_ids"][1] + bbox = information_second_truncated["bbox"][0] + overflowing_bbox = information_second_truncated["bbox"][1] + + self.assertEqual(len(information_second_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq0_input_ids)) + self.assertEqual(overflowing_tokens, overflow_second_sequence) + self.assertEqual(bbox, bbox_second_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_second_sequence_fast) + else: + truncated_sequence = information_second_truncated["input_ids"] + overflowing_tokens = information_second_truncated["overflowing_tokens"] + bbox = information_second_truncated["bbox"] + overflowing_bbox = information_second_truncated["overflowing_token_boxes"] + + self.assertEqual(len(truncated_sequence), len(sequence["input_ids"]) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq1_input_ids[-(2 + stride) :]) + self.assertEqual(bbox, bbox_second_sequence) + self.assertEqual(overflowing_bbox, overflowing_token_bbox_second_sequence_slow) + + def test_maximum_encoding_length_single_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0, boxes_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + + sequence = tokenizer(seq_0, boxes=boxes_0, add_special_tokens=False) + total_length = len(sequence["input_ids"]) + + self.assertGreater( + total_length, 4, "Issue with the testing sequence, please update it, it's too short" + ) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_1 = seq_0 * model_max_length + boxes_1 = boxes_0 * model_max_length + sequence1 = tokenizer(seq_1, boxes=boxes_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + self.assertGreater( + total_length1, + model_max_length, + "Issue with the testing sequence, please update it, it's too short", + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"Truncation: {truncation_state}"): + output = tokenizer( + seq_1, + boxes=boxes_1, + padding=padding_state, + truncation=truncation_state, + ) + + self.assertEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(output["bbox"]), model_max_length) + + output = tokenizer( + [seq_1], + boxes=[boxes_1], + padding=padding_state, + truncation=truncation_state, + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(output["bbox"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer(seq_1, boxes=boxes_1, padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertNotEqual(len(output["bbox"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer([seq_1], boxes=[boxes_1], padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertNotEqual(len(output["bbox"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + # Check the order of Sequence of input ids, overflowing tokens and bbox sequence with truncation + stride = 2 + information = tokenizer( + seq_0, + boxes=boxes_0, + max_length=total_length - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, LayoutLMv3TokenizerFast): + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + # bbox = information["bbox"][0] + # overflowing_bbox = information["bbox"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence["input_ids"][:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence["input_ids"][-(2 + stride) :]) + + # self.assertEqual(bbox, sequence["bbox"][:-2]) + # self.assertEqual(overflowing_bbox, sequence["bbox"][-(2 + stride) :]) + else: + truncated_sequence = information["input_ids"] + overflowing_tokens = information["overflowing_tokens"] + # bbox = information["bbox"] + # overflowing_bbox = information["overflowing_token_boxes"] + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence["input_ids"][:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence["input_ids"][-(2 + stride) :]) + # self.assertEqual(bbox, sequence["bbox"][:-2]) + # self.assertEqual(overflowing_bbox, sequence["bbox"][-(2 + stride) :]) + + @unittest.skip("LayoutLMv3 tokenizer requires boxes besides sequences.") + def test_pretokenized_inputs(self): + pass + + @unittest.skip("LayoutLMv3 tokenizer always expects pretokenized inputs.") + def test_compare_pretokenized_inputs(self): + pass + + @unittest.skip("LayoutLMv3 fast tokenizer does not support prepare_for_model") + def test_compare_prepare_for_model(self): + pass + + @slow + def test_only_label_first_subword(self): + words = ["hello", "niels", "0000000000000000"] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + word_labels = [0, 1, 2] + + # test slow tokenizer + tokenizer_p = LayoutLMv3Tokenizer.from_pretrained("microsoft/layoutlmv3-base", add_visual_labels=False) + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, -100, 2, -100, -100]) + + tokenizer_p = LayoutLMv3Tokenizer.from_pretrained( + "microsoft/layoutlmv3-base", + only_label_first_subword=False, + add_visual_labels=False, + ) + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, 1, 2, 2, -100]) + + # test fast tokenizer + tokenizer_r = LayoutLMv3TokenizerFast.from_pretrained("microsoft/layoutlmv3-base", add_visual_labels=False) + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, -100, 2, -100, -100]) + + tokenizer_r = LayoutLMv3Tokenizer.from_pretrained( + "microsoft/layoutlmv3-base", + only_label_first_subword=False, + add_visual_labels=False, + ) + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 1, 1, 2, 2, -100]) + + @slow + def test_layoutlmv3_integration_test(self): + tokenizer_p = LayoutLMv3Tokenizer.from_pretrained("microsoft/layoutlmv3-base") + tokenizer_r = LayoutLMv3TokenizerFast.from_pretrained("microsoft/layoutlmv3-base") + + # There are 3 cases: + # CASE 1: document image classification (training + inference), document image token classification (inference), + # in which case only words and normalized bounding boxes are provided to the tokenizer + # CASE 2: document image token classification (training), + # in which case one also provides word labels to the tokenizer + # CASE 3: document image visual question answering (inference), + # in which case one also provides a question to the tokenizer + + # We need to test all 3 cases both on batched and non-batched inputs. + + # CASE 1: not batched + words, boxes = self.get_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [0, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'attention_mask': [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 1: batched + words, boxes = self.get_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[0, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 92, 614, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [256, 38, 330, 58], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'attention_mask': [[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 2: not batched + words, boxes = self.get_words_and_boxes() + word_labels = [1, 2] + + # fmt: off + expected_results = {'input_ids': [0, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'labels': [-100, 1, 2, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], 'attention_mask': [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # # CASE 2: batched + words, boxes = self.get_words_and_boxes_batch() + word_labels = [[1, 2], [2, 46]] + + # fmt: off + expected_results = {'input_ids': [[0, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 92, 614, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [256, 38, 330, 58], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'labels': [[-100, 1, 2, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], [-100, 2, 46, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100]], 'attention_mask': [[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # # CASE 3: not batched + question, words, boxes = self.get_question_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [0, 99, 18, 39, 766, 116, 2, 2, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'bbox': [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(question, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(question, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # # CASE 3: batched + questions, words, boxes = self.get_question_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[0, 99, 18, 39, 766, 116, 2, 2, 795, 13964, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 141, 16, 37, 373, 116, 2, 2, 13964, 795, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'bbox': [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [256, 38, 330, 58], [256, 38, 330, 58], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(questions, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(questions, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + @unittest.skip("Doesn't support another framework than PyTorch") + def test_np_encode_plus_sent_to_model(self): + pass + + @require_tf + @slow + def test_tf_encode_plus_sent_to_model(self): + from transformers import TF_MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(TF_MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + self.assertGreaterEqual(model.config.vocab_size, len(tokenizer)) + + # Build sequence + first_ten_tokens = list(tokenizer.get_vocab().keys())[:10] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(first_ten_tokens))] + encoded_sequence = tokenizer.encode_plus(first_ten_tokens, boxes=boxes, return_tensors="tf") + batch_encoded_sequence = tokenizer.batch_encode_plus( + [first_ten_tokens, first_ten_tokens], boxes=[boxes, boxes], return_tensors="tf" + ) + + # This should not fail + model(encoded_sequence) + model(batch_encoded_sequence) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_processor_layoutxlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_processor_layoutxlm.py new file mode 100644 index 0000000000000000000000000000000000000000..5d74bacfa0bdaad34f38e5335fafa54ac71513e3 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_processor_layoutxlm.py @@ -0,0 +1,488 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest +from typing import List + +import numpy as np + +from transformers import PreTrainedTokenizer, PreTrainedTokenizerBase, PreTrainedTokenizerFast +from transformers.models.layoutxlm import LayoutXLMTokenizer, LayoutXLMTokenizerFast +from transformers.testing_utils import ( + require_pytesseract, + require_sentencepiece, + require_tokenizers, + require_torch, + slow, +) +from transformers.utils import FEATURE_EXTRACTOR_NAME, cached_property, is_pytesseract_available + + +if is_pytesseract_available(): + from PIL import Image + + from transformers import LayoutLMv2FeatureExtractor, LayoutXLMProcessor + + +@require_pytesseract +@require_sentencepiece +@require_tokenizers +class LayoutXLMProcessorTest(unittest.TestCase): + tokenizer_class = LayoutXLMTokenizer + rust_tokenizer_class = LayoutXLMTokenizerFast + + def setUp(self): + feature_extractor_map = { + "do_resize": True, + "size": 224, + "apply_ocr": True, + } + + self.tmpdirname = tempfile.mkdtemp() + self.feature_extraction_file = os.path.join(self.tmpdirname, FEATURE_EXTRACTOR_NAME) + with open(self.feature_extraction_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(feature_extractor_map) + "\n") + + # taken from `test_tokenization_layoutxlm.LayoutXLMTokenizationTest.test_save_pretrained` + self.tokenizer_pretrained_name = "hf-internal-testing/tiny-random-layoutxlm" + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tokenizer_pretrained_name, **kwargs) + + def get_rust_tokenizer(self, **kwargs) -> PreTrainedTokenizerFast: + return self.rust_tokenizer_class.from_pretrained(self.tokenizer_pretrained_name, **kwargs) + + def get_tokenizers(self, **kwargs) -> List[PreTrainedTokenizerBase]: + return [self.get_tokenizer(**kwargs), self.get_rust_tokenizer(**kwargs)] + + def get_feature_extractor(self, **kwargs): + return LayoutLMv2FeatureExtractor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def prepare_image_inputs(self): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + """ + + image_inputs = [np.random.randint(255, size=(3, 30, 400), dtype=np.uint8)] + + image_inputs = [Image.fromarray(np.moveaxis(x, 0, -1)) for x in image_inputs] + + return image_inputs + + def test_save_load_pretrained_default(self): + feature_extractor = self.get_feature_extractor() + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + processor.save_pretrained(self.tmpdirname) + processor = LayoutXLMProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertIsInstance(processor.tokenizer, (LayoutXLMTokenizer, LayoutXLMTokenizerFast)) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor.to_json_string()) + self.assertIsInstance(processor.feature_extractor, LayoutLMv2FeatureExtractor) + + def test_save_load_pretrained_additional_features(self): + processor = LayoutXLMProcessor(feature_extractor=self.get_feature_extractor(), tokenizer=self.get_tokenizer()) + processor.save_pretrained(self.tmpdirname) + + # slow tokenizer + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + feature_extractor_add_kwargs = self.get_feature_extractor(do_resize=False, size=30) + + processor = LayoutXLMProcessor.from_pretrained( + self.tmpdirname, + use_fast=False, + bos_token="(BOS)", + eos_token="(EOS)", + do_resize=False, + size=30, + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutXLMTokenizer) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.feature_extractor, LayoutLMv2FeatureExtractor) + + # fast tokenizer + tokenizer_add_kwargs = self.get_rust_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + feature_extractor_add_kwargs = self.get_feature_extractor(do_resize=False, size=30) + + processor = LayoutXLMProcessor.from_pretrained( + self.tmpdirname, use_xlm=True, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, LayoutXLMTokenizerFast) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.feature_extractor, LayoutLMv2FeatureExtractor) + + def test_model_input_names(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = LayoutXLMProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + input_str = "lower newer" + image_input = self.prepare_image_inputs() + + # add extra args + inputs = processor(text=input_str, images=image_input, return_codebook_pixels=False, return_image_mask=False) + + self.assertListEqual(list(inputs.keys()), processor.model_input_names) + + @slow + def test_overflowing_tokens(self): + # In the case of overflowing tokens, test that we still have 1-to-1 mapping between the images and input_ids (sequences that are too long are broken down into multiple sequences). + + from datasets import load_dataset + + # set up + datasets = load_dataset("nielsr/funsd") + processor = LayoutXLMProcessor.from_pretrained("microsoft/layoutxlm-base", apply_ocr=False) + + def preprocess_data(examples): + images = [Image.open(path).convert("RGB") for path in examples["image_path"]] + words = examples["words"] + boxes = examples["bboxes"] + word_labels = examples["ner_tags"] + encoded_inputs = processor( + images, + words, + boxes=boxes, + word_labels=word_labels, + max_length=512, + padding="max_length", + truncation=True, + return_overflowing_tokens=True, + stride=50, + return_offsets_mapping=True, + return_tensors="pt", + ) + return encoded_inputs + + train_data = preprocess_data(datasets["train"]) + + self.assertEqual(len(train_data["image"]), len(train_data["input_ids"])) + + +# different use cases tests +@require_sentencepiece +@require_torch +@require_pytesseract +class LayoutXLMProcessorIntegrationTests(unittest.TestCase): + @cached_property + def get_images(self): + # we verify our implementation on 2 document images from the DocVQA dataset + from datasets import load_dataset + + ds = load_dataset("hf-internal-testing/fixtures_docvqa", split="test") + + image_1 = Image.open(ds[0]["file"]).convert("RGB") + image_2 = Image.open(ds[1]["file"]).convert("RGB") + + return image_1, image_2 + + @cached_property + def get_tokenizers(self): + slow_tokenizer = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base") + fast_tokenizer = LayoutXLMTokenizerFast.from_pretrained("microsoft/layoutxlm-base") + return [slow_tokenizer, fast_tokenizer] + + @slow + def test_processor_case_1(self): + # case 1: document image classification (training, inference) + token classification (inference), apply_ocr = True + + feature_extractor = LayoutLMv2FeatureExtractor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + input_feat_extract = feature_extractor(images[0], return_tensors="pt") + input_processor = processor(images[0], return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify image + self.assertAlmostEqual( + input_feat_extract["pixel_values"].sum(), input_processor["image"].sum(), delta=1e-2 + ) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " 11:14 to 11:39 a.m 11:39 to 11:44 a.m. 11:44 a.m. to 12:25 p.m. 12:25 to 12:58 p.m. 12:58 to 4:00 p.m. 2:00 to 5:00 p.m. Coffee Break Coffee will be served for men and women in the lobby adjacent to exhibit area. Please move into exhibit area. (Exhibits Open) TRRF GENERAL SESSION (PART |) Presiding: Lee A. Waller TRRF Vice President “Introductory Remarks” Lee A. Waller, TRRF Vice Presi- dent Individual Interviews with TRRF Public Board Members and Sci- entific Advisory Council Mem- bers Conducted by TRRF Treasurer Philip G. Kuehn to get answers which the public refrigerated warehousing industry is looking for. Plus questions from the floor. Dr. Emil M. Mrak, University of Cal- ifornia, Chairman, TRRF Board; Sam R. Cecil, University of Georgia College of Agriculture; Dr. Stanley Charm, Tufts University School of Medicine; Dr. Robert H. Cotton, ITT Continental Baking Company; Dr. Owen Fennema, University of Wis- consin; Dr. Robert E. Hardenburg, USDA. Questions and Answers Exhibits Open Capt. Jack Stoney Room TRRF Scientific Advisory Council Meeting Ballroom Foyer" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + input_feat_extract = feature_extractor(images, return_tensors="pt") + input_processor = processor(images, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify images + self.assertAlmostEqual( + input_feat_extract["pixel_values"].sum(), input_processor["image"].sum(), delta=1e-2 + ) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " 7 ITC Limited REPORT AND ACCOUNTS 2013 ITC’s Brands: An Asset for the Nation The consumer needs and aspirations they fulfil, the benefit they generate for millions across ITC’s value chains, the future-ready capabilities that support them, and the value that they create for the country, have made ITC’s brands national assets, adding to India’s competitiveness. It is ITC’s aspiration to be the No 1 FMCG player in the country, driven by its new FMCG businesses. A recent Nielsen report has highlighted that ITC's new FMCG businesses are the fastest growing among the top consumer goods companies operating in India. ITC takes justifiable pride that, along with generating economic value, these celebrated Indian brands also drive the creation of larger societal capital through the virtuous cycle of sustainable and inclusive growth. DI WILLS * ; LOVE DELIGHTFULLY SOFT SKIN? aia Ans Source: https://www.industrydocuments.ucsf.edu/docs/snbx0223" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + @slow + def test_processor_case_2(self): + # case 2: document image classification (training, inference) + token classification (inference), apply_ocr=False + + feature_extractor = LayoutLMv2FeatureExtractor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], words, boxes=boxes, return_tensors="pt") + + # verify keys + expected_keys = ["input_ids", "bbox", "attention_mask", "image"] + actual_keys = list(input_processor.keys()) + for key in expected_keys: + self.assertIn(key, actual_keys) + + # verify input_ids + expected_decoding = " hello world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, words, boxes=boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " hello world" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [1000, 1000, 1000, 1000], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_3(self): + # case 3: token classification (training), apply_ocr=False + + feature_extractor = LayoutLMv2FeatureExtractor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + words = ["weirdly", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + word_labels = [1, 2] + input_processor = processor(images[0], words, boxes=boxes, word_labels=word_labels, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "labels"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " weirdly world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify labels + expected_labels = [-100, 1, -100, 2, -100] + self.assertListEqual(input_processor.labels.squeeze().tolist(), expected_labels) + + # batched + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + word_labels = [[1, 2], [6, 3, 10, 2]] + input_processor = processor( + images, words, boxes=boxes, word_labels=word_labels, padding=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids", "labels"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " my name is niels" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [ + [0, 0, 0, 0], + [3, 2, 5, 1], + [6, 7, 4, 2], + [3, 9, 2, 4], + [1, 1, 2, 3], + [1, 1, 2, 3], + [1000, 1000, 1000, 1000], + ] + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + # verify labels + expected_labels = [-100, 6, 3, 10, 2, -100, -100] + self.assertListEqual(input_processor.labels[1].tolist(), expected_labels) + + @slow + def test_processor_case_4(self): + # case 4: visual question answering (inference), apply_ocr=True + + feature_extractor = LayoutLMv2FeatureExtractor() + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + input_processor = processor(images[0], question, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + # fmt: off + expected_decoding = " What's his name? 11:14 to 11:39 a.m 11:39 to 11:44 a.m. 11:44 a.m. to 12:25 p.m. 12:25 to 12:58 p.m. 12:58 to 4:00 p.m. 2:00 to 5:00 p.m. Coffee Break Coffee will be served for men and women in the lobby adjacent to exhibit area. Please move into exhibit area. (Exhibits Open) TRRF GENERAL SESSION (PART |) Presiding: Lee A. Waller TRRF Vice President “Introductory Remarks” Lee A. Waller, TRRF Vice Presi- dent Individual Interviews with TRRF Public Board Members and Sci- entific Advisory Council Mem- bers Conducted by TRRF Treasurer Philip G. Kuehn to get answers which the public refrigerated warehousing industry is looking for. Plus questions from the floor. Dr. Emil M. Mrak, University of Cal- ifornia, Chairman, TRRF Board; Sam R. Cecil, University of Georgia College of Agriculture; Dr. Stanley Charm, Tufts University School of Medicine; Dr. Robert H. Cotton, ITT Continental Baking Company; Dr. Owen Fennema, University of Wis- consin; Dr. Robert E. Hardenburg, USDA. Questions and Answers Exhibits Open Capt. Jack Stoney Room TRRF Scientific Advisory Council Meeting Ballroom Foyer" # noqa: E231 + # fmt: on + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + input_processor = processor( + images, questions, padding="max_length", max_length=20, truncation=True, return_tensors="pt" + ) + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # this was obtained with Tesseract 4.1.1 + expected_decoding = " what's the time 7 ITC Limited REPORT AND ACCOUNTS 2013" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + # fmt: off + expected_bbox = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [1000, 1000, 1000, 1000], [0, 45, 67, 80], [72, 56, 109, 67], [72, 56, 109, 67], [116, 56, 189, 67], [198, 59, 253, 66], [257, 59, 285, 66], [289, 59, 365, 66], [289, 59, 365, 66], [289, 59, 365, 66], [289, 59, 365, 66], [372, 59, 407, 66], [1000, 1000, 1000, 1000]] # noqa: E231 + # fmt: on + self.assertListEqual(input_processor.bbox[1].tolist(), expected_bbox) + + @slow + def test_processor_case_5(self): + # case 5: visual question answering (inference), apply_ocr=False + + feature_extractor = LayoutLMv2FeatureExtractor(apply_ocr=False) + tokenizers = self.get_tokenizers + images = self.get_images + + for tokenizer in tokenizers: + processor = LayoutXLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + words = ["hello", "world"] + boxes = [[1, 2, 3, 4], [5, 6, 7, 8]] + input_processor = processor(images[0], question, words, boxes, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " What's his name? hello world" + decoding = processor.decode(input_processor.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + words = [["hello", "world"], ["my", "name", "is", "niels"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[3, 2, 5, 1], [6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3]]] + input_processor = processor(images, questions, words, boxes, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "bbox", "image", "input_ids"] + actual_keys = sorted(input_processor.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = " How old is he? hello world" + decoding = processor.decode(input_processor.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + expected_decoding = " what's the time my name is niels" + decoding = processor.decode(input_processor.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify bbox + expected_bbox = [[6, 7, 4, 2], [3, 9, 2, 4], [1, 1, 2, 3], [1, 1, 2, 3], [1000, 1000, 1000, 1000]] + self.assertListEqual(input_processor.bbox[1].tolist()[-5:], expected_bbox) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_tokenization_layoutxlm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_tokenization_layoutxlm.py new file mode 100644 index 0000000000000000000000000000000000000000..bf295c9c925e0ea179f36e12715b9d9694013b72 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/layoutxlm/test_tokenization_layoutxlm.py @@ -0,0 +1,1947 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import inspect +import shutil +import tempfile +import unittest +from typing import List + +from transformers import ( + AddedToken, + LayoutXLMTokenizerFast, + SpecialTokensMixin, + is_tf_available, + is_torch_available, + logging, +) +from transformers.models.layoutxlm.tokenization_layoutxlm import LayoutXLMTokenizer +from transformers.testing_utils import ( + get_tests_dir, + is_pt_tf_cross_test, + require_pandas, + require_sentencepiece, + require_tokenizers, + require_torch, + slow, +) + +from ...test_tokenization_common import ( + SMALL_TRAINING_CORPUS, + TokenizerTesterMixin, + filter_non_english, + merge_model_tokenizer_mappings, +) + + +logger = logging.get_logger(__name__) +SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") + + +@require_sentencepiece +@require_tokenizers +@require_pandas +class LayoutXLMTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LayoutXLMTokenizer + rust_tokenizer_class = LayoutXLMTokenizerFast + test_rust_tokenizer = True + from_pretrained_filter = filter_non_english + test_seq2seq = False + test_sentencepiece = True + maxDiff = None + + def get_words_and_boxes(self): + words = ["a", "weirdly", "test"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]] + + return words, boxes + + def get_words_and_boxes_batch(self): + words = [["a", "weirdly", "test"], ["hello", "my", "name", "is", "bob"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]], + [[961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69]], + ] + + return words, boxes + + def get_question_words_and_boxes(self): + question = "what's his name?" + words = ["a", "weirdly", "test"] + boxes = [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]] + + return question, words, boxes + + def get_question_words_and_boxes_batch(self): + questions = ["what's his name?", "how is he called?"] + words = [["a", "weirdly", "test"], ["what", "a", "laif", "gastn"]] + boxes = [ + [[423, 237, 440, 251], [427, 272, 441, 287], [419, 115, 437, 129]], + [[256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69]], + ] + + return questions, words, boxes + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = LayoutXLMTokenizer(SAMPLE_VOCAB, keep_accents=True) + tokenizer.save_pretrained(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_text = "UNwant\u00E9d,running" + output_text = "unwanted, running" + return input_text, output_text + + # override test in `test_tokenization_common.py` because of the required input format of the `__call__`` method of + # this tokenizer + def test_save_sentencepiece_tokenizer(self) -> None: + if not self.test_sentencepiece or not self.test_slow_tokenizer: + return + # We want to verify that we will be able to save the tokenizer even if the original files that were used to + # build the tokenizer have been deleted in the meantime. + words, boxes = self.get_words_and_boxes() + + tokenizer_slow_1 = self.get_tokenizer() + encoding_tokenizer_slow_1 = tokenizer_slow_1( + words, + boxes=boxes, + ) + + tmpdirname_1 = tempfile.mkdtemp() + tmpdirname_2 = tempfile.mkdtemp() + + tokenizer_slow_1.save_pretrained(tmpdirname_1) + tokenizer_slow_2 = self.tokenizer_class.from_pretrained(tmpdirname_1) + encoding_tokenizer_slow_2 = tokenizer_slow_2( + words, + boxes=boxes, + ) + + shutil.rmtree(tmpdirname_1) + tokenizer_slow_2.save_pretrained(tmpdirname_2) + + tokenizer_slow_3 = self.tokenizer_class.from_pretrained(tmpdirname_2) + encoding_tokenizer_slow_3 = tokenizer_slow_3( + words, + boxes=boxes, + ) + shutil.rmtree(tmpdirname_2) + + self.assertEqual(encoding_tokenizer_slow_1, encoding_tokenizer_slow_2) + self.assertEqual(encoding_tokenizer_slow_1, encoding_tokenizer_slow_3) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("microsoft/layoutxlm-base") + + question, words, boxes = self.get_question_words_and_boxes() + + text = tokenizer.encode( + question.split(), + boxes=[tokenizer.pad_token_box for _ in range(len(question.split()))], + add_special_tokens=False, + ) + text_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_pair == [0] + text + [2] + [2] + text_2 + [2] + + def test_offsets_with_special_characters(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words, boxes = self.get_words_and_boxes() + words[1] = tokenizer_r.mask_token + tokens = tokenizer_r.encode_plus( + words, + boxes=boxes, + return_attention_mask=False, + return_token_type_ids=False, + return_offsets_mapping=True, + add_special_tokens=True, + ) + + expected_results = [ + ((0, 0), tokenizer_r.cls_token), + ((0, 1), "▁a"), + ((0, 6), tokenizer_r.mask_token), + ((0, 4), "▁test"), + ((0, 0), tokenizer_r.sep_token), + ] + + self.assertEqual( + [e[1] for e in expected_results], tokenizer_r.convert_ids_to_tokens(tokens["input_ids"]) + ) + self.assertEqual([e[0] for e in expected_results], tokens["offset_mapping"]) + + def test_add_special_tokens(self): + tokenizers: List[LayoutXLMTokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + special_token = "[SPECIAL_TOKEN]" + special_token_box = [1000, 1000, 1000, 1000] + + tokenizer.add_special_tokens({"cls_token": special_token}) + encoded_special_token = tokenizer.encode( + [special_token], boxes=[special_token_box], add_special_tokens=False + ) + self.assertEqual(len(encoded_special_token), 1) + + decoded = tokenizer.decode(encoded_special_token, skip_special_tokens=True) + self.assertTrue(special_token not in decoded) + + def test_add_tokens_tokenizer(self): + tokenizers: List[LayoutXLMTokenizer] = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab_size = tokenizer.vocab_size + all_size = len(tokenizer) + + self.assertNotEqual(vocab_size, 0) + + # We usually have added tokens from the start in tests because our vocab fixtures are + # smaller than the original vocabs - let's not assert this + # self.assertEqual(vocab_size, all_size) + + new_toks = ["aaaaa", "bbbbbb", "cccccccccdddddddd"] + added_toks = tokenizer.add_tokens(new_toks) + vocab_size_2 = tokenizer.vocab_size + all_size_2 = len(tokenizer) + + self.assertNotEqual(vocab_size_2, 0) + self.assertEqual(vocab_size, vocab_size_2) + self.assertEqual(added_toks, len(new_toks)) + self.assertEqual(all_size_2, all_size + len(new_toks)) + + words = "aaaaa bbbbbb low cccccccccdddddddd l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + + self.assertGreaterEqual(len(tokens), 4) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + + new_toks_2 = {"eos_token": ">>>>|||<||<<|<<", "pad_token": "<<<<<|||>|>>>>|>"} + added_toks_2 = tokenizer.add_special_tokens(new_toks_2) + vocab_size_3 = tokenizer.vocab_size + all_size_3 = len(tokenizer) + + self.assertNotEqual(vocab_size_3, 0) + self.assertEqual(vocab_size, vocab_size_3) + self.assertEqual(added_toks_2, len(new_toks_2)) + self.assertEqual(all_size_3, all_size_2 + len(new_toks_2)) + + words = ">>>>|||<||<<|<< aaaaabbbbbb low cccccccccdddddddd <<<<<|||>|>>>>|> l".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + tokens = tokenizer.encode( + words, + boxes=boxes, + add_special_tokens=False, + ) + + self.assertGreaterEqual(len(tokens), 6) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[0], tokens[1]) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokens[-3]) + self.assertEqual(tokens[0], tokenizer.eos_token_id) + self.assertEqual(tokens[-2], tokenizer.pad_token_id) + + @require_tokenizers + def test_encode_decode_with_spaces(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + new_toks = [AddedToken("[ABC]", normalized=False), AddedToken("[DEF]", normalized=False)] + tokenizer.add_tokens(new_toks) + input = "[ABC][DEF][ABC][DEF]" + if self.space_between_special_tokens: + output = "[ABC] [DEF] [ABC] [DEF]" + else: + output = input + encoded = tokenizer.encode(input.split(), boxes=boxes, add_special_tokens=False) + decoded = tokenizer.decode(encoded, spaces_between_special_tokens=self.space_between_special_tokens) + self.assertIn(decoded, [output, output.lower()]) + + def test_encode_plus_with_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_size = 10 + padding_idx = tokenizer.pad_token_id + + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_special_tokens_mask=True) + input_ids = encoded_sequence["input_ids"] + special_tokens_mask = encoded_sequence["special_tokens_mask"] + sequence_length = len(input_ids) + + # Test 'longest' and 'no_padding' don't do anything + tokenizer.padding_side = "right" + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + not_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertTrue(sequence_length == not_padded_sequence_length) + self.assertTrue(input_ids == not_padded_input_ids) + self.assertTrue(special_tokens_mask == not_padded_special_tokens_mask) + + # Test right padding + tokenizer.padding_side = "right" + + right_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + right_padded_input_ids = right_padded_sequence["input_ids"] + + right_padded_special_tokens_mask = right_padded_sequence["special_tokens_mask"] + right_padded_sequence_length = len(right_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == right_padded_sequence_length) + self.assertTrue(input_ids + [padding_idx] * padding_size == right_padded_input_ids) + self.assertTrue(special_tokens_mask + [1] * padding_size == right_padded_special_tokens_mask) + + # Test left padding + tokenizer.padding_side = "left" + left_padded_sequence = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + left_padded_input_ids = left_padded_sequence["input_ids"] + left_padded_special_tokens_mask = left_padded_sequence["special_tokens_mask"] + left_padded_sequence_length = len(left_padded_input_ids) + + self.assertTrue(sequence_length + padding_size == left_padded_sequence_length) + self.assertTrue([padding_idx] * padding_size + input_ids == left_padded_input_ids) + self.assertTrue([1] * padding_size + special_tokens_mask == left_padded_special_tokens_mask) + + if "token_type_ids" in tokenizer.model_input_names: + token_type_ids = encoded_sequence["token_type_ids"] + left_padded_token_type_ids = left_padded_sequence["token_type_ids"] + right_padded_token_type_ids = right_padded_sequence["token_type_ids"] + + assert token_type_ids + [0] * padding_size == right_padded_token_type_ids + assert [0] * padding_size + token_type_ids == left_padded_token_type_ids + + if "attention_mask" in tokenizer.model_input_names: + attention_mask = encoded_sequence["attention_mask"] + right_padded_attention_mask = right_padded_sequence["attention_mask"] + left_padded_attention_mask = left_padded_sequence["attention_mask"] + + self.assertTrue(attention_mask + [0] * padding_size == right_padded_attention_mask) + self.assertTrue([0] * padding_size + attention_mask == left_padded_attention_mask) + + def test_internal_consistency(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + tokens = [] + for word in words: + tokens.extend(tokenizer.tokenize(word)) + ids = tokenizer.convert_tokens_to_ids(tokens) + ids_2 = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, ids_2) + + tokens_2 = tokenizer.convert_ids_to_tokens(ids) + self.assertNotEqual(len(tokens_2), 0) + text_2 = tokenizer.decode(ids) + self.assertIsInstance(text_2, str) + + output_text = "a weirdly test" + self.assertEqual(text_2, output_text) + + def test_mask_output(self): + tokenizers = self.get_tokenizers(fast=False, do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + + if ( + tokenizer.build_inputs_with_special_tokens.__qualname__.split(".")[0] != "PreTrainedTokenizer" + and "token_type_ids" in tokenizer.model_input_names + ): + information = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + sequences, mask = information["input_ids"], information["token_type_ids"] + self.assertEqual(len(sequences), len(mask)) + + def test_number_of_added_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=False), len(attached_sequences) - len(sequences) + ) + + # test 2: two sequences + question, words, boxes = self.get_question_words_and_boxes() + + sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=False) + attached_sequences = tokenizer.encode(question, words, boxes=boxes, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=True), len(attached_sequences) - len(sequences) + ) + + def test_padding_to_max_length(self): + """We keep this test for backward compatibility but it should be removed when `pad_to_max_length` will be deprecated""" + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + padding_idx = tokenizer.pad_token_id + + # Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + # FIXME: the next line should be padding(max_length) to avoid warning + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, pad_to_max_length=True + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # Check that nothing is done when a maximum length is not specified + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, pad_to_max_length=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + def test_padding(self, max_length=50): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + # Encode - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.encode(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode(words, boxes=boxes, padding=True) + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode(question, words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode(question, words, boxes=boxes, padding=True) + input_p = tokenizer_p.encode(question, words, boxes=boxes, padding="longest") + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode_plus - Simple input + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + input_r = tokenizer_r.encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Encode_plus - Pair input + question, words, boxes = self.get_question_words_and_boxes() + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + question, words, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus(question, words, boxes=boxes, padding="longest") + input_p = tokenizer_p.encode_plus(question, words, boxes=boxes, padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Batch_encode_plus - Simple input + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + pad_to_max_length=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding="longest", + ) + input_p = tokenizer_p.batch_encode_plus( + words, + boxes=boxes, + max_length=max_length, + padding=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes, padding="longest") + input_p = tokenizer_p.batch_encode_plus(words, boxes=boxes, padding=True) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Batch_encode_plus - Pair input + questions, words, boxes = self.get_question_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + max_length=max_length, + truncation=True, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding=True, + ) + input_p = tokenizer_p.batch_encode_plus( + list(zip(questions, words)), + is_pair=True, + boxes=boxes, + padding="longest", + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad on single examples after tokenization + words, boxes = self.get_words_and_boxes() + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p) + + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.encode_plus(words, boxes=boxes) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p) + + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad after tokenization + words, boxes = self.get_words_and_boxes_batch() + input_r = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_r.batch_encode_plus( + words, + boxes=boxes, + ) + input_p = tokenizer_r.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + def test_padding_warning_message_fast_tokenizer(self): + if not self.test_rust_tokenizer: + return + + words, boxes = self.get_words_and_boxes_batch() + + tokenizer_fast = self.get_rust_tokenizer() + + encoding_fast = tokenizer_fast( + words, + boxes=boxes, + ) + + with self.assertLogs("transformers", level="WARNING") as cm: + tokenizer_fast.pad(encoding_fast) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to" + " encode the text followed by a call to the `pad` method to get a padded encoding.", + cm.records[0].message, + ) + + if not self.test_slow_tokenizer: + return + + tokenizer_slow = self.get_tokenizer() + + encoding_slow = tokenizer_slow( + words, + boxes=boxes, + ) + + with self.assertLogs(level="WARNING") as cm: + # We want to assert there are no warnings, but the 'assertLogs' method does not support that. + # Therefore, we are adding a dummy warning, and then we will assert it is the only warning. + logger.warning("Dummy warning") + tokenizer_slow.pad(encoding_slow) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Dummy warning", + cm.records[0].message, + ) + + def test_call(self): + # Tests that all call wrap to encode_plus and batch_encode_plus + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Test not batched + words, boxes = self.get_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test not batched pairs + question, words, boxes = self.get_question_words_and_boxes() + encoded_sequences_1 = tokenizer.encode_plus(words, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test batched + words, boxes = self.get_words_and_boxes_batch() + encoded_sequences_1 = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes) + encoded_sequences_2 = tokenizer(words, boxes=boxes) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + def test_batch_encode_plus_batch_sequence_length(self): + # Tests that all encoded values have the correct size + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + encoded_sequences = [ + tokenizer.encode_plus(words_example, boxes=boxes_example) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus(words, is_pair=False, boxes=boxes, padding=False) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + maximum_length = len( + max([encoded_sequence["input_ids"] for encoded_sequence in encoded_sequences], key=len) + ) + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences_padded = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=maximum_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + + encoded_sequences_batch_padded = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + self.assertListEqual( + encoded_sequences_padded, + self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch_padded), + ) + + # check 'longest' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=True + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding="longest" + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + # check 'no_padding' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, padding=False + ) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=maximum_length + 10, padding=False + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + @unittest.skip("batch_encode_plus does not handle overflowing tokens.") + def test_batch_encode_plus_overflowing_tokens(self): + pass + + def test_batch_encode_plus_padding(self): + # Test that padded sequences are equivalent between batch_encode_plus and encode_plus + + # Right padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + # Left padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokenizer.padding_side = "left" + words, boxes = self.get_words_and_boxes_batch() + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, words) + + encoded_sequences = [ + tokenizer.encode_plus( + words_example, boxes=boxes_example, max_length=max_length, padding="max_length" + ) + for words_example, boxes_example in zip(words, boxes) + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + words, is_pair=False, boxes=boxes, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + def test_padding_to_multiple_of(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.pad_token is None: + self.skipTest("No padding token.") + else: + words, boxes = self.get_words_and_boxes() + + # empty_tokens = tokenizer([""], [[]], padding=True, pad_to_multiple_of=8) + normal_tokens = tokenizer(words, boxes=boxes, padding=True, pad_to_multiple_of=8) + # for key, value in empty_tokens.items(): + # self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + normal_tokens = tokenizer(words, boxes=boxes, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertNotEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # Should also work with truncation + normal_tokens = tokenizer(words, boxes=boxes, padding=True, truncation=True, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # truncation to something which is not a multiple of pad_to_multiple_of raises an error + self.assertRaises( + ValueError, + tokenizer.__call__, + words, + boxes=boxes, + padding=True, + truncation=True, + max_length=12, + pad_to_multiple_of=8, + ) + + def test_tokenizer_slow_store_full_signature(self): + signature = inspect.signature(self.tokenizer_class.__init__) + tokenizer = self.get_tokenizer() + + for parameter_name, parameter in signature.parameters.items(): + if parameter.default != inspect.Parameter.empty: + self.assertIn(parameter_name, tokenizer.init_kwargs) + + def test_build_inputs_with_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Input tokens id + words, boxes = self.get_words_and_boxes() + input_simple = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + input_pair = tokenizer_p.encode(words, boxes=boxes, add_special_tokens=False) + + # Generate output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple) + self.assertEqual(output_p, output_r) + + # Generate pair output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple, input_pair) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple, input_pair) + self.assertEqual(output_p, output_r) + + def test_special_tokens_mask_input_pairs(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + return_special_tokens_mask=True, + # add_prefix_space=False, + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [ + (x if not special_tokens_mask[i] else None) for i, x in enumerate(encoded_sequence_w_special) + ] + filtered_sequence = [x for x in filtered_sequence if x is not None] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_special_tokens_mask(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + # Testing single inputs + encoded_sequence = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + words, boxes=boxes, add_special_tokens=True, return_special_tokens_mask=True + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [x for i, x in enumerate(encoded_sequence_w_special) if not special_tokens_mask[i]] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_save_and_load_tokenizer(self): + # safety check on max_len default value so we are sure the test works + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertNotEqual(tokenizer.model_max_length, 42) + + # Now let's start the test + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + words, boxes = self.get_words_and_boxes() + tmpdirname = tempfile.mkdtemp() + + before_tokens = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + + shutil.rmtree(tmpdirname) + + @unittest.skip("Not implemented") + def test_right_and_left_truncation(self): + pass + + def test_right_and_left_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + sequence = "Sequence" + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_idx = tokenizer.pad_token_id + + # RIGHT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert encoded_sequence + [padding_idx] * padding_size == padded_sequence + + # LEFT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "left" + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + words, boxes=boxes, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + assert sequence_length + padding_size == padded_sequence_length + assert [padding_idx] * padding_size + encoded_sequence == padded_sequence + + # RIGHT & LEFT PADDING - Check that nothing is done for 'longest' and 'no_padding' + encoded_sequence = tokenizer.encode(words, boxes=boxes) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes, padding=True) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding="longest") + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(words, boxes=boxes) + padded_sequence_right_length = len(padded_sequence_right) + assert sequence_length == padded_sequence_right_length + assert encoded_sequence == padded_sequence_right + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(words, boxes=boxes, padding=False) + padded_sequence_left_length = len(padded_sequence_left) + assert sequence_length == padded_sequence_left_length + assert encoded_sequence == padded_sequence_left + + def test_token_type_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # test 1: single sequence + words, boxes = self.get_words_and_boxes() + + output = tokenizer(words, boxes=boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + self.assertNotIn(1, output["token_type_ids"]) + + # test 2: two sequences (question + words) + question, words, boxes = self.get_question_words_and_boxes() + + output = tokenizer(question, words, boxes, return_token_type_ids=True) + + # Assert that the token type IDs have the same length as the input IDs + self.assertEqual(len(output["token_type_ids"]), len(output["input_ids"])) + + # Assert that the token type IDs have the same length as the attention mask + self.assertEqual(len(output["token_type_ids"]), len(output["attention_mask"])) + + self.assertIn(0, output["token_type_ids"]) + self.assertNotIn(1, output["token_type_ids"]) + + def test_offsets_mapping(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + text = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(text))] + + # No pair + tokens_with_offsets = tokenizer_r.encode_plus( + text, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(False) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + # Pairs + text = "what's his name" + pair = ["a", "wonderful", "test"] + boxes = [[1, 8, 12, 20] for _ in range(len(pair))] + tokens_with_offsets = tokenizer_r.encode_plus( + text, + pair, + boxes=boxes, + return_special_tokens_mask=True, + return_offsets_mapping=True, + add_special_tokens=True, + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(True) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + @require_torch + @slow + def test_torch_encode_plus_sent_to_model(self): + import torch + + from transformers import MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + is_using_common_embeddings = hasattr(model.get_input_embeddings(), "weight") + assert ( + (model.get_input_embeddings().weight.shape[0] >= len(tokenizer)) + if is_using_common_embeddings + else True + ) + + # Build sequence + words, boxes = self.get_words_and_boxes() + encoded_sequence = tokenizer.encode_plus(words, boxes=boxes, return_tensors="pt") + batch_encoded_sequence = tokenizer.batch_encode_plus( + [words, words], [boxes, boxes], return_tensors="pt" + ) + # This should not fail + + with torch.no_grad(): # saves some time + model(**encoded_sequence) + model(**batch_encoded_sequence) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + words, boxes = self.get_words_and_boxes() + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + ids = tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + rust_ids = rust_tokenizer.encode(words, boxes=boxes, add_special_tokens=True) + self.assertListEqual(ids, rust_ids) + + def test_tokenization_python_rust_equals(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words, boxes = self.get_words_and_boxes() + + # Ensure basic input match + input_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + input_pairs_p = tokenizer_p.encode_plus(words, boxes=boxes) + input_pairs_r = tokenizer_r.encode_plus(words, boxes=boxes) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_pairs_p[key], input_pairs_r[key]) + + words = ["hello" for _ in range(1000)] + boxes = [[1000, 1000, 1000, 1000] for _ in range(1000)] + + # Ensure truncation match + input_p = tokenizer_p.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + input_r = tokenizer_r.encode_plus(words, boxes=boxes, max_length=512, truncation=True) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key]) + + # Ensure truncation with stride match + input_p = tokenizer_p.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + input_r = tokenizer_r.encode_plus( + words, boxes=boxes, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + + for key in filter( + lambda x: x in ["input_ids", "token_type_ids", "attention_mask", "bbox"], input_p.keys() + ): + self.assertSequenceEqual(input_p[key], input_r[key][0]) + + def test_embeded_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + words, boxes = self.get_words_and_boxes() + tokens_r = tokenizer_r.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + tokens_p = tokenizer_p.encode_plus( + words, + boxes=boxes, + add_special_tokens=True, + ) + + for key in tokens_p.keys(): + self.assertEqual(tokens_r[key], tokens_p[key]) + + if "token_type_ids" in tokens_r: + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + tokens_r = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + self.assertSequenceEqual(tokens_r, tokens_p) + + def test_compare_add_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + simple_num_special_tokens_to_add = tokenizer_r.num_special_tokens_to_add(pair=False) + + words, boxes = self.get_words_and_boxes() + # tokenize() + no_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=False) + with_special_tokens = tokenizer_r.tokenize(" ".join(words), add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode() + no_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode(words, boxes=boxes, add_special_tokens=True) + self.assertEqual(len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add) + + # encode_plus() + no_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + self.assertEqual( + len(no_special_tokens[key]), + len(with_special_tokens[key]) - simple_num_special_tokens_to_add, + ) + + # # batch_encode_plus + words, boxes = self.get_words_and_boxes_batch() + + no_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=False) + with_special_tokens = tokenizer_r.batch_encode_plus(words, boxes=boxes, add_special_tokens=True) + for key in no_special_tokens.keys(): + for i_no, i_with in zip(no_special_tokens[key], with_special_tokens[key]): + self.assertEqual(len(i_no), len(i_with) - simple_num_special_tokens_to_add) + + @slow + def test_layoutxlm_truncation_integration_test(self): + words, boxes = self.get_words_and_boxes() + + tokenizer = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base", model_max_length=512) + + for i in range(12, 512): + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, max_length=i, truncation=True) + + # Ensure that the input IDs are less than the max length defined. + self.assertLessEqual(len(new_encoded_inputs), i) + + tokenizer.model_max_length = 20 + new_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + dropped_encoded_inputs = tokenizer.encode(words, boxes=boxes, truncation=True) + + # Ensure that the input IDs are still truncated when no max_length is specified + self.assertListEqual(new_encoded_inputs, dropped_encoded_inputs) + self.assertLessEqual(len(new_encoded_inputs), 20) + + @is_pt_tf_cross_test + def test_batch_encode_plus_tensors(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes_batch() + + # A Tensor cannot be build by sequences which are not the same size + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="pt") + self.assertRaises(ValueError, tokenizer.batch_encode_plus, words, boxes=boxes, return_tensors="tf") + + if tokenizer.pad_token_id is None: + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding=True, + return_tensors="pt", + ) + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + words, + boxes=boxes, + padding="longest", + return_tensors="tf", + ) + else: + pytorch_tensor = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True, return_tensors="pt") + tensorflow_tensor = tokenizer.batch_encode_plus( + words, boxes=boxes, padding="longest", return_tensors="tf" + ) + encoded_sequences = tokenizer.batch_encode_plus(words, boxes=boxes, padding=True) + + for key in encoded_sequences.keys(): + pytorch_value = pytorch_tensor[key].tolist() + tensorflow_value = tensorflow_tensor[key].numpy().tolist() + encoded_value = encoded_sequences[key] + + self.assertEqual(pytorch_value, tensorflow_value, encoded_value) + + def test_sequence_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + if not tokenizer.is_fast: + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + seq_1 = ["With", "these", "inputs."] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(seq_1))] + + # We want to have sequence 0 and sequence 1 are tagged + # respectively with 0 and 1 token_ids + # (regardless of whether the model use token type ids) + # We use this assumption in the QA pipeline among other place + output = tokenizer(seq_0.split(), boxes=boxes) + self.assertIn(0, output.sequence_ids()) + + output = tokenizer(seq_0, seq_1, boxes=boxes) + self.assertIn(0, output.sequence_ids()) + self.assertIn(1, output.sequence_ids()) + + if tokenizer.num_special_tokens_to_add(pair=True): + self.assertIn(None, output.sequence_ids()) + + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + r_output = tokenizer_r.encode(words, boxes=boxes) + + special_token_id = tokenizer_r.encode( + [""], boxes=[1000, 1000, 1000, 1000], add_special_tokens=False + )[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_cr = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs, from_slow=True + ) + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + words = "Hey this is a token".split() + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + + p_output = tokenizer_p.encode(words, boxes=boxes) + cr_output = tokenizer_cr.encode(words, boxes=boxes) + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + def test_training_new_tokenizer(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + new_tokenizer = tokenizer.train_new_from_iterator(SMALL_TRAINING_CORPUS, 100) + + # Test we can use the new tokenizer with something not seen during training + text = [["this", "is", "the"], ["how", "are", "you"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8], [1, 3, 4, 8]], [[5, 6, 7, 8], [4, 5, 6, 7], [3, 9, 2, 7]]] + inputs = new_tokenizer(text, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "this is the" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + # We check that the parameters of the tokenizer remained the same + # Check we have the same number of added_tokens for both pair and non-pair inputs. + self.assertEqual(tokenizer.num_special_tokens_to_add(False), new_tokenizer.num_special_tokens_to_add(False)) + self.assertEqual(tokenizer.num_special_tokens_to_add(True), new_tokenizer.num_special_tokens_to_add(True)) + + # Check we have the correct max_length for both pair and non-pair inputs. + self.assertEqual(tokenizer.max_len_single_sentence, new_tokenizer.max_len_single_sentence) + self.assertEqual(tokenizer.max_len_sentences_pair, new_tokenizer.max_len_sentences_pair) + + # Assert the set of special tokens match as we didn't ask to change them + self.assertSequenceEqual( + tokenizer.all_special_tokens_extended, + new_tokenizer.all_special_tokens_extended, + ) + + self.assertDictEqual(tokenizer.special_tokens_map, new_tokenizer.special_tokens_map) + + def test_training_new_tokenizer_with_special_tokens_change(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + # Test with a special tokens map + class_signature = inspect.signature(tokenizer.__class__) + if "cls_token" in class_signature.parameters: + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map={tokenizer.cls_token: ""} + ) + cls_id = new_tokenizer.get_vocab()[""] + self.assertEqual(new_tokenizer.cls_token, "") + self.assertEqual(new_tokenizer.cls_token_id, cls_id) + + # Create a new mapping from the special tokens defined in the original tokenizer + special_tokens_list = SpecialTokensMixin.SPECIAL_TOKENS_ATTRIBUTES.copy() + special_tokens_list.remove("additional_special_tokens") + special_tokens_map = {} + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is not None: + special_token = getattr(tokenizer, token) + special_tokens_map[special_token] = f"{special_token}a" + + # Train new tokenizer + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map=special_tokens_map + ) + + # Check the changes + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is None: + continue + special_token = getattr(tokenizer, token) + if special_token in special_tokens_map: + new_special_token = getattr(new_tokenizer, token) + self.assertEqual(special_tokens_map[special_token], new_special_token) + + new_id = new_tokenizer.get_vocab()[new_special_token] + self.assertEqual(getattr(new_tokenizer, f"{token}_id"), new_id) + + # Check if the AddedToken / string format has been kept + for special_token in tokenizer.all_special_tokens_extended: + if isinstance(special_token, AddedToken) and special_token.content not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + elif isinstance(special_token, AddedToken): + # The special token must appear in the list of the new tokenizer as an object of type AddedToken with + # the same parameters as the old AddedToken except the content that the user has requested to change. + special_token_str = special_token.content + new_special_token_str = special_tokens_map[special_token_str] + + find = False + for candidate in new_tokenizer.all_special_tokens_extended: + if ( + isinstance(candidate, AddedToken) + and candidate.content == new_special_token_str + and candidate.lstrip == special_token.lstrip + and candidate.rstrip == special_token.rstrip + and candidate.normalized == special_token.normalized + and candidate.single_word == special_token.single_word + ): + find = True + break + self.assertTrue( + find, + f"'{new_special_token_str}' doesn't appear in the list " + f"'{new_tokenizer.all_special_tokens_extended}' as an AddedToken with the same parameters as " + f"'{special_token}' in the list {tokenizer.all_special_tokens_extended}", + ) + elif special_token not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + + else: + # The special token must appear in the list of the new tokenizer as an object of type string. + self.assertTrue(special_tokens_map[special_token] in new_tokenizer.all_special_tokens_extended) + + # Test we can use the new tokenizer with something not seen during training + words = [["this", "is"], ["hello", "🤗"]] + boxes = [[[1, 2, 3, 4], [5, 6, 7, 8]], [[1, 2, 3, 4], [5, 6, 7, 8]]] + inputs = new_tokenizer(words, boxes=boxes) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "this is" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + def test_prepare_for_model(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + # only test prepare_for_model for the slow tokenizer + if tokenizer.__class__.__name__ == "LayoutXLMTokenizerFast": + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + words, boxes = self.get_words_and_boxes() + prepared_input_dict = tokenizer.prepare_for_model(words, boxes=boxes, add_special_tokens=True) + + input_dict = tokenizer.encode_plus(words, boxes=boxes, add_special_tokens=True) + + self.assertEqual(input_dict, prepared_input_dict) + + def test_padding_different_model_input_name(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + words, boxes = self.get_words_and_boxes_batch() + + input_r = tokenizer_r.batch_encode_plus(words, boxes=boxes) + input_p = tokenizer_r.batch_encode_plus(words, boxes=boxes) + + # rename encoded batch to "inputs" + input_r["inputs"] = input_r[tokenizer_r.model_input_names[0]] + del input_r[tokenizer_r.model_input_names[0]] + + input_p["inputs"] = input_p[tokenizer_p.model_input_names[0]] + del input_p[tokenizer_p.model_input_names[0]] + + # Renaming `input_ids` to `inputs` + tokenizer_r.model_input_names = ["inputs"] + tokenizer_r.model_input_names[1:] + tokenizer_p.model_input_names = ["inputs"] + tokenizer_p.model_input_names[1:] + + input_r = tokenizer_r.pad(input_r, padding="longest") + input_p = tokenizer_r.pad(input_p, padding="longest") + + max_length = len(input_p["inputs"][0]) + self.assert_batch_padded_input_match( + input_r, input_p, max_length, pad_token_id, model_main_input_name="inputs" + ) + + def test_batch_encode_dynamic_overflowing(self): + """ + When calling batch_encode with multiple sequences, it can return different number of + overflowing encoding for each sequence: + [ + Sequence 1: [Encoding 1, Encoding 2], + Sequence 2: [Encoding 1], + Sequence 3: [Encoding 1, Encoding 2, ... Encoding N] + ] + This needs to be padded so that it can represented as a tensor + """ + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): + if is_torch_available(): + returned_tensor = "pt" + elif is_tf_available(): + returned_tensor = "tf" + else: + returned_tensor = "jax" + + # Single example + words, boxes = self.get_words_and_boxes() + tokens = tokenizer.encode_plus( + words, + boxes=boxes, + max_length=6, + padding=True, + truncation=True, + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + else: + self.assertEqual(len(tokens[key].shape), 3) + + # Batch of examples + # For these 2 examples, 3 training examples will be created + words, boxes = self.get_words_and_boxes_batch() + tokens = tokenizer.batch_encode_plus( + words, + boxes=boxes, + max_length=6, + padding=True, + truncation="only_first", + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + if key != "bbox": + self.assertEqual(len(tokens[key].shape), 2) + self.assertEqual(tokens[key].shape[-1], 6) + else: + self.assertEqual(len(tokens[key].shape), 3) + self.assertEqual(tokens[key].shape[-1], 4) + + # overwrite from test_tokenization_common to speed up test + def test_save_pretrained(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + self.tokenizers_list[0] = (self.rust_tokenizer_class, "hf-internal-testing/tiny-random-layoutxlm", {}) + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it save with the same files + the tokenizer.json file for the fast one + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + tokenizer_r_files = tuple(f for f in tokenizer_r_files if "tokenizer.json" not in f) + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + # self.assertEqual(getattr(tokenizer_rp, key), getattr(tokenizer_pp, key)) + # self.assertEqual(getattr(tokenizer_rp, key + "_id"), getattr(tokenizer_pp, key + "_id")) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=True + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=True) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it save with the same files + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=False + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=False) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it saved the tokenizer.json file + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + @unittest.skip("TO DO: overwrite this very extensive test.") + def test_alignement_methods(self): + pass + + @unittest.skip("layoutxlm tokenizer requires boxes besides sequences.") + def test_maximum_encoding_length_pair_input(self): + pass + + @unittest.skip("layoutxlm tokenizer requires boxes besides sequences.") + def test_maximum_encoding_length_single_input(self): + pass + + @unittest.skip("layoutxlm tokenizer requires boxes besides sequences.") + def test_pretokenized_inputs(self): + pass + + @unittest.skip("layoutxlm tokenizer always expects pretokenized inputs.") + def test_compare_pretokenized_inputs(self): + pass + + @unittest.skip("layoutxlm fast tokenizer does not support prepare_for_model") + def test_compare_prepare_for_model(self): + pass + + @slow + def test_only_label_first_subword(self): + words = ["hello", "niels"] + boxes = [[1000, 1000, 1000, 1000] for _ in range(len(words))] + word_labels = [0, 1] + + # test slow tokenizer + tokenizer_p = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base") + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, -100, 1, -100, -100]) + + tokenizer_p = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base", only_label_first_subword=False) + encoding = tokenizer_p(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 0, 1, 1, -100]) + + # test fast tokenizer + tokenizer_r = LayoutXLMTokenizerFast.from_pretrained("microsoft/layoutxlm-base") + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, -100, 1, -100, -100]) + + tokenizer_r = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base", only_label_first_subword=False) + encoding = tokenizer_r(words, boxes=boxes, word_labels=word_labels) + self.assertListEqual(encoding.labels, [-100, 0, 0, 1, 1, -100]) + + @slow + def test_layoutxlm_integration_test(self): + tokenizer_p = LayoutXLMTokenizer.from_pretrained("microsoft/layoutxlm-base") + tokenizer_r = LayoutXLMTokenizerFast.from_pretrained("microsoft/layoutxlm-base") + + # There are 3 cases: + # CASE 1: document image classification (training + inference), document image token classification (inference), + # in which case only words and normalized bounding boxes are provided to the tokenizer + # CASE 2: document image token classification (training), + # in which case one also provides word labels to the tokenizer + # CASE 3: document image visual question answering (inference), + # in which case one also provides a question to the tokenizer + + # We need to test all 3 cases both on batched and non-batched inputs. + + # CASE 1: not batched + words, boxes = self.get_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [0, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'attention_mask': [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 1: batched + words, boxes = self.get_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[0, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 33600, 31, 759, 9351, 83, 21895, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 2: not batched + words, boxes = self.get_words_and_boxes() + word_labels = [1, 2, 3] + + # fmt: off + expected_results = {'input_ids': [0, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'bbox': [[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 'labels': [-100, 1, 2, -100, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], 'attention_mask': [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 2: batched + words, boxes = self.get_words_and_boxes_batch() + word_labels = [[1, 2, 3], [2, 46, 17, 22, 3]] + + # fmt: off + expected_results = {'input_ids': [[0, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 33600, 31, 759, 9351, 83, 21895, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'bbox': [[[0, 0, 0, 0], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [961, 885, 992, 912], [961, 885, 992, 912], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]], 'labels': [[-100, 1, 2, -100, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100], [-100, 2, -100, 46, 17, 22, 3, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + encoding_r = tokenizer_r(words, boxes=boxes, word_labels=word_labels, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 3: not batched + question, words, boxes = self.get_question_words_and_boxes() + + # fmt: off + expected_results = {'input_ids': [0, 2367, 25, 7, 1919, 9351, 32, 2, 2, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], 'bbox': [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [1000, 1000, 1000, 1000], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(question, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(question, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + # CASE 3: batched + questions, words, boxes = self.get_question_words_and_boxes_batch() + + # fmt: off + expected_results = {'input_ids': [[0, 2367, 25, 7, 1919, 9351, 32, 2, 2, 10, 179459, 538, 3034, 2, 1, 1, 1, 1, 1, 1], [0, 3642, 83, 764, 35839, 32, 2, 2, 2367, 10, 21, 3190, 53496, 19, 2, 1, 1, 1, 1, 1]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]], 'bbox': [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [1000, 1000, 1000, 1000], [423, 237, 440, 251], [427, 272, 441, 287], [427, 272, 441, 287], [419, 115, 437, 129], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1000, 1000, 1000, 1000], [1000, 1000, 1000, 1000], [256, 38, 330, 58], [256, 38, 330, 58], [336, 42, 353, 57], [336, 42, 353, 57], [34, 42, 66, 69], [34, 42, 66, 69], [1000, 1000, 1000, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]} # noqa: E231 + # fmt: on + + encoding_p = tokenizer_p(questions, words, boxes, padding="max_length", max_length=20) + encoding_r = tokenizer_r(questions, words, boxes, padding="max_length", max_length=20) + self.assertDictEqual(dict(encoding_p), expected_results) + self.assertDictEqual(dict(encoding_r), expected_results) + + @unittest.skip("Doesn't support another framework than PyTorch") + def test_np_encode_plus_sent_to_model(self): + pass + + @unittest.skip("Doesn't use SentencePiece") + def test_sentencepiece_tokenize_and_convert_tokens_to_string(self): + pass + + @unittest.skip("Doesn't use SentencePiece") + def test_sentencepiece_tokenize_and_decode(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_led.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_led.py new file mode 100644 index 0000000000000000000000000000000000000000..b6dfc3256b05116748fcc94c9e3a94fa20b57c68 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_led.py @@ -0,0 +1,577 @@ +# coding=utf-8 +# Copyright 2021 Iz Beltagy, Matthew E. Peters, Arman Cohan and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LED model. """ + + +import copy +import tempfile +import unittest + +from transformers import LEDConfig, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + LEDForConditionalGeneration, + LEDForQuestionAnswering, + LEDForSequenceClassification, + LEDModel, + LEDTokenizer, + ) + from transformers.models.led.modeling_led import LEDDecoder, LEDEncoder + + +def prepare_led_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = input_ids.ne(config.pad_token_id) + if decoder_attention_mask is None: + decoder_attention_mask = decoder_input_ids.ne(config.pad_token_id) + if head_mask is None: + head_mask = torch.ones(config.encoder_layers, config.encoder_attention_heads, device=torch_device) + if decoder_head_mask is None: + decoder_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + if cross_attn_head_mask is None: + cross_attn_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + 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, + } + + +class LEDModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=11, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=32, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + attention_window=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + self.attention_window = attention_window + + # `ModelTesterMixin.test_attention_outputs` is expecting attention tensors to be of size + # [num_attention_heads, encoder_seq_length, encoder_key_length], but LongformerSelfAttention + # returns attention of shape [num_attention_heads, encoder_seq_length, self.attention_window + 1] + # because its local attention only attends to `self.attention_window + 1` locations + # (assuming no token with global attention, otherwise the last dimension of attentions + # is x + self.attention_window + 1, where x is the number of tokens with global attention) + # x is set to 1 + self.encoder_key_length = self.attention_window + 2 + + # because of padding `encoder_seq_length`, is different from `seq_length`. Relevant for + # the `test_attention_outputs` and `test_hidden_states_output` tests + self.encoder_seq_length = self.seq_length + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size).clamp( + 3, + ) + input_ids[:, -1] = self.eos_token_id # Eos Token + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = self.get_config() + inputs_dict = prepare_led_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def get_config(self): + return LEDConfig( + 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_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + attention_window=self.attention_window, + ) + + def get_pipeline_config(self): + config = self.get_config() + config.max_position_embeddings = 100 + config.vocab_size = 300 + return config + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + global_attention_mask = torch.zeros_like(inputs_dict["input_ids"]) + global_attention_mask[:, -1] = 1 + inputs_dict["global_attention_mask"] = global_attention_mask + + return config, inputs_dict + + def create_and_check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = LEDModel(config=config).get_decoder().to(torch_device).eval() + input_ids = inputs_dict["input_ids"] + attention_mask = inputs_dict["attention_mask"] + head_mask = inputs_dict["head_mask"] + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, head_mask=head_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([attention_mask, next_attn_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-2)) + + def check_encoder_decoder_model_standalone(self, config, inputs_dict): + model = LEDModel(config=config).to(torch_device).eval() + outputs = model(**inputs_dict) + + encoder_last_hidden_state = outputs.encoder_last_hidden_state + last_hidden_state = outputs.last_hidden_state + + with tempfile.TemporaryDirectory() as tmpdirname: + encoder = model.get_encoder() + encoder.save_pretrained(tmpdirname) + encoder = LEDEncoder.from_pretrained(tmpdirname).to(torch_device) + + encoder_last_hidden_state_2 = encoder( + inputs_dict["input_ids"], + attention_mask=inputs_dict["attention_mask"], + global_attention_mask=inputs_dict["global_attention_mask"], + )[0] + + self.parent.assertTrue((encoder_last_hidden_state_2 - encoder_last_hidden_state).abs().max().item() < 1e-3) + + with tempfile.TemporaryDirectory() as tmpdirname: + decoder = model.get_decoder() + decoder.save_pretrained(tmpdirname) + decoder = LEDDecoder.from_pretrained(tmpdirname).to(torch_device) + + last_hidden_state_2 = decoder( + input_ids=inputs_dict["decoder_input_ids"], + attention_mask=inputs_dict["decoder_attention_mask"], + encoder_hidden_states=encoder_last_hidden_state, + encoder_attention_mask=inputs_dict["attention_mask"], + )[0] + + self.parent.assertTrue((last_hidden_state_2 - last_hidden_state).abs().max().item() < 1e-3) + + def check_global_attention(self, config, inputs_dict): + model = LEDModel(config=config).to(torch_device).eval() + model.config.output_attentions = True + attention_mask = ids_tensor(inputs_dict["input_ids"].shape, vocab_size=2) + global_attention_mask = torch.zeros_like(attention_mask) + + # set some tokens to global_attention + num_tokens_with_global_attention = 2 + + attention_mask[:, 2 : 2 + num_tokens_with_global_attention] = 1 + global_attention_mask[:, 2 : 2 + num_tokens_with_global_attention] = 1 + inputs_dict["attention_mask"] = attention_mask + inputs_dict["global_attention_mask"] = global_attention_mask + + outputs = model(**inputs_dict) + self.parent.assertIsNotNone(outputs.encoder_global_attentions) + + # setting `num_tokens_with_global_attention` to global_attentions yields + # makes last dim to be of `num_tokens_with_global_attention` + self.parent.assertTrue( + outputs.encoder_global_attentions[0].shape, + (self.batch_size, self.num_attention_heads, self.encoder_seq_length, num_tokens_with_global_attention), + ) + + +@require_torch +class LEDModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + (LEDModel, LEDForConditionalGeneration, LEDForSequenceClassification, LEDForQuestionAnswering) + if is_torch_available() + else () + ) + all_generative_model_classes = (LEDForConditionalGeneration,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": LEDForConditionalGeneration, + "feature-extraction": LEDModel, + "question-answering": LEDForQuestionAnswering, + "summarization": LEDForConditionalGeneration, + "text-classification": LEDForSequenceClassification, + "text2text-generation": LEDForConditionalGeneration, + "translation": LEDForConditionalGeneration, + "zero-shot": LEDForSequenceClassification, + } + if is_torch_available() + else {} + ) + is_encoder_decoder = True + test_pruning = False + test_missing_keys = False + test_torchscript = False + + # TODO: Fix the failed tests when this model gets more usage + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "QAPipelineTests" and not tokenizer_name.endswith("Fast"): + return True + + return False + + def setUp(self): + self.model_tester = LEDModelTester(self) + self.config_tester = ConfigTester(self, config_class=LEDConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_save_load_strict(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_encoder_decoder_model_standalone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_encoder_decoder_model_standalone(*config_and_inputs) + + def test_global_attention(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_global_attention(*config_and_inputs) + + # LEDForSequenceClassification does not support inputs_embeds + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in (LEDModel, LEDForConditionalGeneration, LEDForQuestionAnswering): + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + wte = model.get_input_embeddings() + if not self.is_encoder_decoder: + inputs["inputs_embeds"] = wte(input_ids) + else: + inputs["inputs_embeds"] = wte(encoder_input_ids) + inputs["decoder_inputs_embeds"] = wte(decoder_input_ids) + + with torch.no_grad(): + model(**inputs)[0] + + def test_generate_fp16(self): + config, input_dict = self.model_tester.prepare_config_and_inputs() + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + model = LEDForConditionalGeneration(config).eval().to(torch_device) + if torch_device == "cuda": + model.half() + model.generate(input_ids, attention_mask=attention_mask) + model.generate(num_beams=4, do_sample=True, early_stopping=False, num_return_sequences=3) + + def test_retain_grad_hidden_states_attentions(self): + # longformer cannot keep gradients in attentions or hidden states + return + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_length = self.model_tester.seq_length + encoder_seq_length = self.model_tester.encoder_seq_length + encoder_key_length = self.model_tester.encoder_key_length + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + # global attention outputs are added as well => so +1 here + correct_outlen = 6 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Question Answering model returns start_logits and end_logits + if model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, seq_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + seq_length, + seq_length, + ], + ) + + +def assert_tensors_close(a, b, atol=1e-12, prefix=""): + """If tensors have different shapes, different values or a and b are not both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if torch.allclose(a, b, atol=atol): + return True + raise + except Exception: + pct_different = (torch.gt((a - b).abs(), atol)).float().mean().item() + if a.numel() > 100: + msg = f"tensor values are {pct_different:.1%} percent different." + else: + msg = f"{a} != {b}" + if prefix: + msg = prefix + ": " + msg + raise AssertionError(msg) + + +def _long_tensor(tok_lst): + return torch.tensor(tok_lst, dtype=torch.long, device=torch_device) + + +TOLERANCE = 1e-4 + + +@require_torch +@require_sentencepiece +@require_tokenizers +@slow +class LEDModelIntegrationTests(unittest.TestCase): + """All the below results were obtained with the original checkpoints and code + base from https://github.com/allenai/longformer. + IMPORTANT: Note that the original checkpoints include a `postion_embeddings` "hack" + and have to be cut to have the correct shape. + See: https://github.com/huggingface/transformers/pull/9278#issue-544709661. + """ + + @cached_property + def default_tokenizer(self): + return LEDTokenizer.from_pretrained("allenai/led-base-16384") + + def test_inference_no_head(self): + model = LEDModel.from_pretrained("allenai/led-base-16384").to(torch_device) + + # change to intended input + input_ids = _long_tensor([512 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + decoder_input_ids = _long_tensor([128 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + inputs_dict = prepare_led_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict).last_hidden_state + expected_shape = torch.Size((1, 1024, 768)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[2.3050, 2.8279, 0.6531], [-1.8457, -0.1455, -3.5661], [-1.0186, 0.4586, -2.2043]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_inference_head(self): + model = LEDForConditionalGeneration.from_pretrained("allenai/led-base-16384").to(torch_device) + + # change to intended input + input_ids = _long_tensor([512 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + decoder_input_ids = _long_tensor([128 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + inputs_dict = prepare_led_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict, use_cache=False).logits + expected_shape = torch.Size((1, 1024, model.config.vocab_size)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[33.6507, 6.4572, 16.8089], [5.8739, -2.4238, 11.2902], [-3.2139, -4.3149, 4.2783]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_seq_to_seq_generation(self): + # this test requires 16GB of RAM + hf = LEDForConditionalGeneration.from_pretrained("allenai/led-large-16384-arxiv").to(torch_device) + tok = LEDTokenizer.from_pretrained("allenai/led-large-16384-arxiv") + + ARTICLE_LEP = r"""the lep experiments at the resonance of @xmath1-boson have tested the standard model ( sm ) at quantum level , measuring the @xmath1-decay into fermion pairs with an accuracy of one part in ten thousands . the good agreement of the lep data with the sm predictions have severely constrained the behavior of new physics at the @xmath1-pole . taking these achievements into account one can imagine that the physics of @xmath1-boson will again play the central role in the frontier of particle physics if the next generation @xmath1 factory comes true with the generated @xmath1 events several orders of magnitude higher than that of the lep . this factory can be realized in the gigaz option of the international linear collider ( ilc)@xcite . the ilc is a proposed electron - positron collider with tunable energy ranging from @xmath12 to @xmath13 and polarized beams in its first phase , and the gigaz option corresponds to its operation on top of the resonance of @xmath1 boson by adding a bypass to its main beam line . given the high luminosity , @xmath14 , and the cross section at the resonance of @xmath1 boson , @xmath15 , about @xmath16 @xmath1 events can be generated in an operational year of @xmath17 of gigaz , which implies that the expected sensitivity to the branching ratio of @xmath1-decay can be improved from @xmath18 at the lep to @xmath19 at the gigaz@xcite . in light of this , the @xmath1-boson properties , especially its exotic or rare decays which are widely believed to be sensitive to new physics , should be investigated comprehensively to evaluate their potential in probing new physics . among the rare @xmath1-decays , the flavor changing ( fc ) processes were most extensively studied to explore the flavor texture in new physics @xcite , and it was found that , although these processes are severely suppressed in the sm , their branching ratios in new physics models can be greatly enhanced to @xmath19 for lepton flavor violation decays @xcite and @xmath20 for quark flavor violation decays @xcite . besides the fc processes , the @xmath1-decay into light higgs boson(s ) is another type of rare process that was widely studied , e.g. the decay @xmath21 ( @xmath22 ) with the particle @xmath0 denoting a light higgs boson was studied in @xcite , the decay @xmath23 was studied in the two higgs doublet model ( 2hdm)@xcite and the minimal supersymmetric standard model ( mssm)@xcite , and the decay @xmath4 was studied in a model independent way @xcite , in 2hdm@xcite and also in mssm@xcite . these studies indicate that , in contrast with the kinematic forbidden of these decays in the sm , the rates of these decays can be as large as @xmath18 in new physics models , which lie within the expected sensitivity of the gigaz . in this work , we extend the previous studies of these decays to some new models and investigate these decays altogether . we are motivated by some recent studies on the singlet extension of the mssm , such as the next - to - minimal supersymmetric standard model ( nmssm ) @xcite and the nearly minimal supersymmetric standard model ( nmssm ) @xcite , where a light cp - odd higgs boson @xmath0 with singlet - dominant component may naturally arise from the spontaneous breaking of some approximate global symmetry like @xmath24 or peccei - quuin symmetry @xcite . these non - minimal supersymmetric models can not only avoid the @xmath25-problem , but also alleviate the little hierarchy by having such a light higgs boson @xmath0 @xcite . we are also motivated by that , with the latest experiments , the properties of the light higgs boson are more stringently constrained than before . so it is worth updating the previous studies . so far there is no model - independent lower bound on the lightest higgs boson mass . in the sm , it must be heavier than @xmath26 gev , obtained from the null observation of the higgs boson at lep experiments . however , due to the more complex structure of the higgs sector in the extensions of the sm , this lower bound can be significantly relaxed according to recent studies , e.g. , for the cp - odd higgs boson @xmath0 we have @xmath27 gev in the nmssm @xcite , @xmath28 gev in the nmssm @xcite , and @xmath29 gev in the lepton - specific 2hdm ( l2hdm ) @xcite . with such a light cp - odd higgs boson , the z - decay into one or more @xmath0 is open up . noting that the decay @xmath30 is forbidden due to bose symmetry , we in this work study the rare @xmath1-decays @xmath6 ( @xmath22 ) , @xmath31 and @xmath4 in a comparative way for four models , namely the type - ii 2hdm@xcite , the l2hdm @xcite , the nmssm and the nmssm . in our study , we examine carefully the constraints on the light @xmath0 from many latest experimental results . this work is organized as follows . in sec . ii we briefly describe the four new physics models . in sec . iii we present the calculations of the rare @xmath1-decays . in sec . iv we list the constraints on the four new physics models . in sec . v we show the numerical results for the branching ratios of the rare @xmath1-decays in various models . finally , the conclusion is given in sec . as the most economical way , the sm utilizes one higgs doublet to break the electroweak symmetry . as a result , the sm predicts only one physical higgs boson with its properties totally determined by two free parameters . in new physics models , the higgs sector is usually extended by adding higgs doublets and/or singlets , and consequently , more physical higgs bosons are predicted along with more free parameters involved in . the general 2hdm contains two @xmath32 doublet higgs fields @xmath33 and @xmath34 , and with the assumption of cp - conserving , its scalar potential can be parameterized as@xcite : @xmath35,\end{aligned}\ ] ] where @xmath36 ( @xmath37 ) are free dimensionless parameters , and @xmath38 ( @xmath39 ) are the parameters with mass dimension . after the electroweak symmetry breaking , the spectrum of this higgs sector includes three massless goldstone modes , which become the longitudinal modes of @xmath40 and @xmath1 bosons , and five massive physical states : two cp - even higgs bosons @xmath41 and @xmath42 , one neutral cp - odd higgs particle @xmath0 and a pair of charged higgs bosons @xmath43 . noting the constraint @xmath44 with @xmath45 and @xmath46 denoting the vacuum expectation values ( vev ) of @xmath33 and @xmath34 respectively , we choose @xmath47 as the input parameters with @xmath48 , and @xmath49 being the mixing angle that diagonalizes the mass matrix of the cp - even higgs fields . the difference between the type - ii 2hdm and the l2hdm comes from the yukawa coupling of the higgs bosons to quark / lepton . in the type - ii 2hdm , one higgs doublet @xmath34 generates the masses of up - type quarks and the other doublet @xmath33 generates the masses of down - type quarks and charged leptons ; while in the l2hdm one higgs doublet @xmath33 couples only to leptons and the other doublet @xmath34 couples only to quarks . so the yukawa interactions of @xmath0 to fermions in these two models are given by @xcite @xmath50 with @xmath51 denoting generation index . obviously , in the type - ii 2hdm the @xmath52 coupling and the @xmath53 coupling can be simultaneously enhanced by @xmath54 , while in the l2hdm only the @xmath53 coupling is enhanced by @xmath55 . the structures of the nmssm and the nmssm are described by their superpotentials and corresponding soft - breaking terms , which are given by @xcite @xmath56 where @xmath57 is the superpotential of the mssm without the @xmath25 term , @xmath58 and @xmath59 are higgs doublet and singlet superfields with @xmath60 and @xmath61 being their scalar component respectively , @xmath62 , @xmath63 , @xmath64 , @xmath65 , @xmath66 and @xmath67 are soft breaking parameters , and @xmath68 and @xmath69 are coefficients of the higgs self interactions . with the superpotentials and the soft - breaking terms , one can get the higgs potentials of the nmssm and the nmssm respectively . like the 2hdm , the higgs bosons with same cp property will mix and the mass eigenstates are obtained by diagonalizing the corresponding mass matrices : @xmath70 where the fields on the right hands of the equations are component fields of @xmath71 , @xmath72 and @xmath61 defined by @xmath73 @xmath74 and @xmath75 are respectively the cp - even and cp - odd neutral higgs bosons , @xmath76 and @xmath77 are goldstone bosons eaten by @xmath1 and @xmath78 , and @xmath79 is the charged higgs boson . so both the nmssm and nmssm predict three cp - even higgs bosons , two cp - odd higgs bosons and one pair of charged higgs bosons . in general , the lighter cp - odd higgs @xmath0 in these model is the mixture of the singlet field @xmath80 and the doublet field combination , @xmath81 , i.e. @xmath82 and its couplings to down - type quarks are then proportional to @xmath83 . so for singlet dominated @xmath0 , @xmath84 is small and the couplings are suppressed . as a comparison , the interactions of @xmath0 with the squarks are given by@xcite @xmath85 i.e. the interaction does not vanish when @xmath86 approaches zero . just like the 2hdm where we use the vevs of the higgs fields as fundamental parameters , we choose @xmath68 , @xmath69 , @xmath87 , @xmath88 , @xmath66 and @xmath89 as input parameters for the nmssm@xcite and @xmath68 , @xmath54 , @xmath88 , @xmath65 , @xmath90 and @xmath91 as input parameters for the nmssm@xcite . about the nmssm and the nmssm , three points should be noted . the first is for the two models , there is no explicit @xmath92term , and the effective @xmath25 parameter ( @xmath93 ) is generated when the scalar component of @xmath59 develops a vev . the second is , the nmssm is actually same as the nmssm with @xmath94@xcite , because the tadpole terms @xmath95 and its soft breaking term @xmath96 in the nmssm do not induce any interactions , except for the tree - level higgs boson masses and the minimization conditions . and the last is despite of the similarities , the nmssm has its own peculiarity , which comes from its neutralino sector . in the basis @xmath97 , its neutralino mass matrix is given by @xcite @xmath98 where @xmath99 and @xmath100 are @xmath101 and @xmath102 gaugino masses respectively , @xmath103 , @xmath104 , @xmath105 and @xmath106 . after diagonalizing this matrix one can get the mass eigenstate of the lightest neutralino @xmath107 with mass taking the following form @xcite @xmath108 this expression implies that @xmath107 must be lighter than about @xmath109 gev for @xmath110 ( from lower bound on chargnio mass ) and @xmath111 ( perturbativity bound ) . like the other supersymmetric models , @xmath107 as the lightest sparticle acts as the dark matter in the universe , but due to its singlino - dominated nature , it is difficult to annihilate sufficiently to get the correct density in the current universe . so the relic density of @xmath107 plays a crucial way in selecting the model parameters . for example , as shown in @xcite , for @xmath112 , there is no way to get the correct relic density , and for the other cases , @xmath107 mainly annihilates by exchanging @xmath1 boson for @xmath113 , or by exchanging a light cp - odd higgs boson @xmath0 with mass satisfying the relation @xmath114 for @xmath115 . for the annihilation , @xmath54 and @xmath25 are required to be less than 10 and @xmath116 respectively because through eq.([mass - exp ] ) a large @xmath87 or @xmath25 will suppress @xmath117 to make the annihilation more difficult . the properties of the lightest cp - odd higgs boson @xmath0 , such as its mass and couplings , are also limited tightly since @xmath0 plays an important role in @xmath107 annihilation . the phenomenology of the nmssm is also rather special , and this was discussed in detail in @xcite . in the type - ii 2hdm , l2hdm , nmssm and nmssm , the rare @xmath1-decays @xmath118 ( @xmath22 ) , @xmath3 and @xmath4 may proceed by the feynman diagrams shown in fig.[fig1 ] , fig.[fig2 ] and fig.[fig3 ] respectively . for these diagrams , the intermediate state @xmath119 represents all possible cp - even higgs bosons in the corresponding model , i.e. @xmath41 and @xmath42 in type - ii 2hdm and l2hdm and @xmath41 , @xmath42 and @xmath120 in nmssm and nmssm . in order to take into account the possible resonance effects of @xmath119 in fig.[fig1](c ) for @xmath2 and fig.[fig3 ] ( a ) for @xmath11 , we have calculated all the decay modes of @xmath119 and properly included the width effect in its propagator . as to the decay @xmath121 , two points should be noted . one is , unlike the decays @xmath6 and @xmath11 , this process proceeds only through loops mediated by quarks / leptons in the type - ii 2hdm and l2hdm , and additionally by sparticles in the nmssm and nmssm . so in most cases its rate should be much smaller than the other two . the other is due to cp - invariance , loops mediated by squarks / sleptons give no contribution to the decay@xcite . in actual calculation , this is reflected by the fact that the coupling coefficient of @xmath122 differs from that of @xmath123 by a minus sign ( see eq.([asqsq ] ) ) , and as a result , the squark - mediated contributions to @xmath121 are completely canceled out . with regard to the rare decay @xmath11 , we have more explanations . in the lowest order , this decay proceeds by the diagram shown in fig.[fig3 ] ( a ) , and hence one may think that , as a rough estimate , it is enough to only consider the contributions from fig.[fig3](a ) . however , we note that in some cases of the type - ii 2hdm and l2hdm , due to the cancelation of the contributions from different @xmath119 in fig.[fig3 ] ( a ) and also due to the potentially largeness of @xmath124 couplings ( i.e. larger than the electroweak scale @xmath125 ) , the radiative correction from the higgs - mediated loops may dominate over the tree level contribution even when the tree level prediction of the rate , @xmath126 , exceeds @xmath20 . on the other hand , we find the contribution from quark / lepton - mediated loops can be safely neglected if @xmath127 in the type - ii 2hdm and the l2hdm . in the nmssm and the nmssm , besides the corrections from the higgs- and quark / lepton - mediated loops , loops involving sparticles such as squarks , charginos and neutralinos can also contribute to the decay . we numerically checked that the contributions from squarks and charginos can be safely neglected if @xmath127 . we also calculated part of potentially large neutralino correction ( note that there are totally about @xmath128 diagrams for such correction ! ) and found they can be neglected too . since considering all the radiative corrections will make our numerical calculation rather slow , we only include the most important correction , namely that from higgs - mediated loops , in presenting our results for the four models . one can intuitively understand the relative smallness of the sparticle contribution to @xmath11 as follows . first consider the squark contribution which is induced by the @xmath129 interaction ( @xmath130 denotes the squark in chirality state ) and the @xmath131 interaction through box diagrams . because the @xmath132 interaction conserves the chirality of the squarks while the @xmath133 interaction violates the chirality , to get non - zero contribution to @xmath11 from the squark loops , at least four chiral flippings are needed , with three of them provided by @xmath131 interaction and the rest provided by the left - right squark mixing . this means that , if one calculates the amplitude in the chirality basis with the mass insertion method , the amplitude is suppressed by the mixing factor @xmath134 with @xmath135 being the off diagonal element in squark mass matrix . next consider the chargino / neutralino contributions . since for a light @xmath0 , its doublet component , parameterized by @xmath84 in eq.([mixing ] ) , is usually small , the couplings of @xmath0 with the sparticles will never be tremendously large@xcite . so the chargino / neutralino contributions are not important too . in our calculation of the decays , we work in the mass eigenstates of sparticles instead of in the chirality basis . for the type - ii 2hdm and the l2hdm , we consider the following constraints @xcite : * theoretical constraints on @xmath136 from perturbativity , unitarity and requirements that the scalar potential is finit at large field values and contains no flat directions @xcite , which imply that @xmath137 * the constraints from the lep search for neutral higgs bosons . we compute the signals from the higgs - strahlung production @xmath138 ( @xmath139 ) with @xmath140 @xcite and from the associated production @xmath141 with @xmath142 @xcite , and compare them with the corresponding lep data which have been inputted into our code . we also consider the constraints from @xmath138 by looking for a peak of @xmath143 recoil mass distribution of @xmath1-boson @xcite and the constraint of @xmath144 mev when @xmath145 @xcite . + these constraints limit the quantities such as @xmath146 \times br ( h_i \to \bar{b } b ) $ ] on the @xmath147 plane with the the subscript @xmath148 denoting the coupling coefficient of the @xmath149 interaction . they also impose a model - dependent lower bound on @xmath150 , e.g. , @xmath151 for the type - ii 2hdm ( from our scan results ) , @xmath152 for the l2hdm@xcite , and @xmath153 for the nmssm @xcite . these bounds are significantly lower than that of the sm , i.e. @xmath154 , partially because in new physics models , unconventional decay modes of @xmath155 such as @xmath156 are open up . as to the nmssm , another specific reason for allowing a significantly lighter cp - even higgs boson is that the boson may be singlet - dominated in this model . + with regard to the lightest cp - odd higgs boson @xmath0 , we checked that there is no lower bound on its mass so long as the @xmath157 interaction is weak or @xmath155 is sufficiently heavy . * the constraints from the lep search for a light higgs boson via the yukawa process @xmath158 with @xmath22 and @xmath61 denoting a scalar @xcite . these constraints can limit the @xmath159 coupling versus @xmath160 in new physics models . * the constraints from the cleo - iii limit on @xmath161 and the latest babar limits on @xmath162 . these constraints will put very tight constraints on the @xmath163 coupling for @xmath164 . in our analysis , we use the results of fig.8 in the second paper of @xcite to excluded the unfavored points . * the constraints from @xmath165 couplings . since the higgs sector can give sizable higher order corrections to @xmath165 couplings , we calculate them to one loop level and require the corrected @xmath165 couplings to lie within the @xmath166 range of their fitted value . the sm predictions for the couplings at @xmath1-pole are given by @xmath167 and @xmath168 @xcite , and the fitted values are given by @xmath169 and @xmath170 , respectively@xcite . we adopt the formula in @xcite to the 2hdm in our calculation . * the constraints from @xmath171 leptonic decay . we require the new physics correction to the branching ratio @xmath172 to be in the range of @xmath173 @xcite . we use the formula in @xcite in our calculation . + about the constraints ( 5 ) and ( 6 ) , two points should be noted . one is all higgs bosons are involved in the constraints by entering the self energy of @xmath171 lepton , the @xmath174 vertex correction or the @xmath175 vertex correction , and also the box diagrams for @xmath176@xcite . since the yukawa couplings of the higgs bosons to @xmath171 lepton get enhanced by @xmath54 and so do the corrections , @xmath54 must be upper bounded for given spectrum of the higgs sector . generally speaking , the lighter @xmath0 is , the more tightly @xmath54 is limited@xcite . the other point is in the type - ii 2hdm , @xmath177 , b - physics observables as well as @xmath178 decays discussed above can constraint the model in a tighter way than the constraints ( 5 ) and ( 6 ) since the yukawa couplings of @xmath171 lepton and @xmath179 quark are simultaneously enhanced by @xmath54 . but for the l2hdm , because only the yukawa couplings of @xmath171 lepton get enhanced ( see eq.[yukawa ] ) , the constraints ( 5 ) and ( 6 ) are more important in limiting @xmath54 . * indirect constraints from the precision electroweak observables such as @xmath180 , @xmath181 and @xmath182 , or their combinations @xmath183 @xcite . we require @xmath184 to be compatible with the lep / sld data at @xmath185 confidence level@xcite . we also require new physics prediction of @xmath186 is within the @xmath187 range of its experimental value . the latest results for @xmath188 are @xmath189 ( measured value ) and @xmath190 ( sm prediction ) for @xmath191 gev @xcite . in our code , we adopt the formula for these observables presented in @xcite to the type - ii 2hdm and the l2hdm respectively . + in calculating @xmath180 , @xmath181 and @xmath182 , we note that these observables get dominant contributions from the self energies of the gauge bosons @xmath1 , @xmath192 and @xmath193 . since there is no @xmath194 coupling or @xmath195 coupling , @xmath0 must be associated with the other higgs bosons to contribute to the self energies . so by the uv convergence of these quantities , one can infer that , for the case of a light @xmath0 and @xmath196 , these quantities depend on the spectrum of the higgs sector in a way like @xmath197 at leading order , which implies that a light @xmath0 can still survive the constraints from the precision electroweak observables given the splitting between @xmath150 and @xmath198 is moderate@xcite . * the constraints from b physics observables such as the branching ratios for @xmath199 , @xmath200 and @xmath201 , and the mass differences @xmath202 and @xmath203 . we require their theoretical predications to agree with the corresponding experimental values at @xmath187 level . + in the type - ii 2hdm and the l2hdm , only the charged higgs boson contributes to these observables by loops , so one can expect that @xmath198 versus @xmath54 is to be limited . combined analysis of the limits in the type - ii 2hdm has been done by the ckmfitter group , and the lower bound of @xmath204 as a function of @xmath87 was given in fig.11 of @xcite . this analysis indicates that @xmath198 must be heavier than @xmath205 at @xmath185 c.l . regardless the value of @xmath54 . in this work , we use the results of fig.11 in @xcite to exclude the unfavored points . as for the l2hdm , b physics actually can not put any constraints@xcite because in this model the couplings of the charged higgs boson to quarks are proportional to @xmath206 and in the case of large @xmath54 which we are interested in , they are suppressed . in our analysis of the l2hdm , we impose the lep bound on @xmath198 , i.e. @xmath207@xcite . * the constraints from the muon anomalous magnetic moment @xmath208 . now both the theoretical prediction and the experimental measured value of @xmath208 have reached a remarkable precision , but a significant deviation still exists : @xmath209 @xcite . in the 2hdm , @xmath208 gets additional contributions from the one - loop diagrams induced by the higgs bosons and also from the two - loop barr - zee diagrams mediated by @xmath0 and @xmath155@xcite . if the higgs bosons are much heavier than @xmath25 lepton mass , the contributions from the barr - zee diagrams are more important , and to efficiently alleviate the discrepancy of @xmath208 , one needs a light @xmath0 along with its enhanced couplings to @xmath25 lepton and also to heavy fermions such as bottom quark and @xmath171 lepton to push up the effects of the barr - zee diagram@xcite . the cp - even higgs bosons are usually preferred to be heavy since their contributions to @xmath208 are negative . + in the type - ii 2hdm , because @xmath54 is tightly constrained by the process @xmath210 at the lep@xcite and the @xmath178 decay@xcite , the barr - zee diagram contribution is insufficient to enhance @xmath208 to @xmath187 range around its measured value@xcite . so in our analysis , we require the type - ii 2hdm to explain @xmath208 at @xmath211 level . while for the l2hdm , @xmath54 is less constrained compared with the type - ii 2hdm , and the barr - zee diagram involving the @xmath171-loop is capable to push up greatly the theoretical prediction of @xmath208@xcite . therefore , we require the l2hdm to explain the discrepancy at @xmath187 level . + unlike the other constraints discussed above , the @xmath208 constraint will put a two - sided bound on @xmath54 since on the one hand , it needs a large @xmath54 to enhance the barr - zee contribution , but on the other hand , too large @xmath54 will result in an unacceptable large @xmath208 . * since this paper concentrates on a light @xmath0 , the decay @xmath212 is open up with a possible large decay width . we require the width of any higgs boson to be smaller than its mass to avoid a too fat higgs boson@xcite . we checked that for the scenario characterized by @xmath213 , the coefficient of @xmath214 interaction is usually larger than the electroweak scale @xmath125 , and consequently a large decay width is resulted . for the nmssm and nmssm , the above constraints become more complicated because in these models , not only more higgs bosons are involved in , but also sparticles enter the constraints . so it is not easy to understand some of the constraints intuitively . take the process @xmath199 as an example . in the supersymmetric models , besides the charged higgs contribution , chargino loops , gluino loops as well as neutralino loops also contribute to the process@xcite , and depending on the susy parameters , any of these contributions may become dominated over or be canceled by other contributions . as a result , although the charged higgs affects the process in the same way as that in the type - ii 2hdm , charged higgs as light as @xmath215 is still allowed even for @xmath216@xcite . since among the constraints , @xmath208 is rather peculiar in that it needs new physics to explain the discrepancy between @xmath217 and @xmath218 , we discuss more about its dependence on susy parameters . in the nmssm and the nmssm , @xmath208 receives contributions from higgs loops and neutralino / chargino loops . for the higgs contribution , it is quite similar to that of the type - ii 2hdm except that more higgs bosons are involved in@xcite . for the neutralino / chargino contribution , in the light bino limit ( i.e. @xmath219 ) , it can be approximated by@xcite @xmath220 for @xmath221 with @xmath222 being smuon mass . so combining the two contributions together , one can learn that a light @xmath0 along with large @xmath54 and/or light smuon with moderate @xmath87 are favored to dilute the discrepancy . because more parameters are involved in the constraints on the supersymmetric models , we consider following additional constraints to further limit their parameters : * direct bounds on sparticle masses from the lep1 , the lep2 and the tevatron experiments @xcite . * the lep1 bound on invisible z decay @xmath223 ; the lep2 bound on neutralino production @xmath224 and @xmath225@xcite . * dark matter constraints from the wmap relic density 0.0975 @xmath226 0.1213 @xcite . note that among the above constraints , the constraint ( 2 ) on higgs sector and the constraint ( c ) on neutralino sector are very important . this is because in the supersymmetric models , the sm - like higgs is upper bounded by about @xmath227 at tree level and by about @xmath228 at loop level , and that the relic density restricts the lsp annihilation cross section in a certain narrow range . in our analysis of the nmssm , we calculate the constraints ( 3 ) and ( 5 - 7 ) by ourselves and utilize the code nmssmtools @xcite to implement the rest constraints . we also extend nmssmtools to the nmssm to implement the constraints . for the extension , the most difficult thing we faced is how to adapt the code micromegas@xcite to the nmssm case . we solve this problem by noting the following facts : * as we mentioned before , the nmssm is actually same as the nmssm with the trilinear singlet term setting to zero . so we can utilize the model file of the nmssm as the input of the micromegas and set @xmath229 . * since in the nmssm , the lsp is too light to annihilate into higgs pairs , there is no need to reconstruct the effective higgs potential to calculate precisely the annihilation channel @xmath230 with @xmath61 denoting any of higgs bosons@xcite . we thank the authors of the nmssmtools for helpful discussion on this issue when we finish such extension@xcite . with the above constraints , we perform four independent random scans over the parameter space of the type - ii 2hdm , the l2hdm , the nmssm and the nmssm respectively . we vary the parameters in following ranges : @xmath231 for the type - ii 2hdm , @xmath232 for the l2hdm , @xmath233 for the nmssm , and @xmath234 for the nmssm . in performing the scans , we note that for the nmssm and the nmssm , some constraints also rely on the gaugino masses and the soft breaking parameters in the squark sector and the slepton sector . since these parameters affect little on the properties of @xmath0 , we fix them to reduce the number of free parameters in our scan . for the squark sector , we adopt the @xmath235 scenario which assumes that the soft mass parameters for the third generation squarks are degenerate : @xmath236 800 gev , and that the trilinear couplings of the third generation squarks are also degenerate , @xmath237 with @xmath238 . for the slepton sector , we assume all the soft - breaking masses and trilinear parameters to be 100 gev . this setting is necessary for the nmssm since this model is difficult to explain the muon anomalous moment at @xmath239 level for heavy sleptons@xcite . finally , we assume the grand unification relation @xmath240 for the gaugino masses with @xmath241 being fine structure constants of the different gauge group . with large number of random points in the scans , we finally get about @xmath242 , @xmath243 , @xmath244 and @xmath242 samples for the type - ii 2hdm , the l2hdm , the nmssm and the nmssm respectively which survive the constraints and satisfy @xmath245 . analyzing the properties of the @xmath0 indicates that for most of the surviving points in the nmssm and the nmssm , its dominant component is the singlet field ( numerically speaking , @xmath246 ) so that its couplings to the sm fermions are suppressed@xcite . our analysis also indicates that the main decay products of @xmath0 are @xmath247 for the l2hdm@xcite , @xmath248 ( dominant ) and @xmath247 ( subdominant ) for the type - ii 2hdm , the nmssm and the nmssm , and in some rare cases , neutralino pairs in the nmssm@xcite . in fig.[fig4 ] , we project the surviving samples on the @xmath249 plane . this figure shows that the allowed range of @xmath54 is from @xmath250 to @xmath251 in the type - ii 2hdm , and from @xmath252 to @xmath253 in the l2hdm . just as we introduced before , the lower bounds of @xmath254 come from the fact that we require the models to explain the muon anomalous moment , while the upper bound is due to we have imposed the constraint from the lep process @xmath255 , which have limited the upper reach of the @xmath256 coupling for light @xmath61 @xcite(for the dependence of @xmath256 coupling on @xmath54 , see sec . this figure also indicates that for the nmssm and the nmssm , @xmath54 is upper bounded by @xmath257 . for the nmssm , this is because large @xmath87 can suppress the dark matter mass to make its annihilation difficult ( see @xcite and also sec . ii ) , but for the nmssm , this is because we choose a light slepton mass so that large @xmath54 can enhance @xmath208 too significantly to be experimentally unacceptable . we checked that for the slepton mass as heavy as @xmath258 , @xmath259 is still allowed for the nmssm . in fig.[fig5 ] and fig.[fig6 ] , we show the branching ratios of @xmath260 and @xmath261 respectively . fig.[fig5 ] indicates , among the four models , the type - ii 2hdm predicts the largest ratio for @xmath260 with its value varying from @xmath262 to @xmath263 . the underlying reason is in the type - ii 2hdm , the @xmath264 coupling is enhanced by @xmath54 ( see fig.[fig4 ] ) , while in the other three model , the coupling is suppressed either by @xmath265 or by the singlet component of the @xmath0 . fig.[fig6 ] shows that the l2hdm predicts the largest rate for @xmath266 with its value reaching @xmath5 in optimum case , and for the other three models , the ratio of @xmath261 is at least about one order smaller than that of @xmath267 . this feature can be easily understood from the @xmath268 coupling introduced in sect . we emphasize that , if the nature prefers a light @xmath0 , @xmath260 and/or @xmath269 in the type - ii 2hdm and the l2hdm will be observable at the gigaz . then by the rates of the two decays , one can determine whether the type - ii 2hdm or the l2hdm is the right theory . on the other hand , if both decays are observed with small rates or fail to be observed , the singlet extensions of the mssm are favored . in fig.[fig7 ] , we show the rate of @xmath3 as the function of @xmath270 . this figure indicates that the branching ratio of @xmath121 can reach @xmath271 , @xmath272 , @xmath273 and @xmath274 for the optimal cases of the type - ii 2hdm , the l2hdm , the nmssm and the nmssm respectively , which implies that the decay @xmath121 will never be observable at the gigaz if the studied model is chosen by nature . the reason for the smallness is , as we pointed out before , that the decay @xmath121 proceeds only at loop level . comparing the optimum cases of the type - ii 2hdm , the nmssm and the nmssm shown in fig.5 - 7 , one may find that the relation @xmath275 holds for any of the decays . this is because the decays are all induced by the yukawa couplings with similar structure for the models . in the supersymmetric models , the large singlet component of the light @xmath0 is to suppress the yukawa couplings , and the @xmath0 in the nmssm has more singlet component than that in the nmssm . next we consider the decay @xmath11 , which , unlike the above decays , depends on the higgs self interactions . in fig.[fig8 ] we plot its rate as a function of @xmath270 and this figure indicates that the @xmath276 may be the largest among the ratios of the exotic @xmath1 decays , reaching @xmath277 in the optimum cases of the type - ii 2hdm , the l2hdm and the nmssm . the underlying reason is , in some cases , the intermediate state @xmath119 in fig.[fig3 ] ( a ) may be on - shell . in fact , we find this is one of the main differences between the nmssm and the nmssm , that is , in the nmssm , @xmath119 in fig.[fig3 ] ( a ) may be on - shell ( corresponds to the points with large @xmath278 ) while in the nmssm , this seems impossible . so we conclude that the decay @xmath11 may serve as an alternative channel to test new physics models , especially it may be used to distinguish the nmssm from the nmssm if the supersymmetry is found at the lhc and the @xmath11 is observed at the gigaz with large rate . before we end our discussion , we note that in the nmssm , the higgs boson @xmath0 may be lighter than @xmath279 without conflicting with low energy data from @xmath178 decays and the other observables ( see fig.[fig4]-[fig8 ] ) . in this case , @xmath0 is axion - like as pointed out in @xcite . we checked that , among the rare @xmath1 decays discussed in this paper , the largest branching ratio comes from @xmath280 which can reach @xmath281 . since in this case , the decay product of @xmath0 is highly collinear muon pair , detecting the decay @xmath280 may need some knowledge about detectors , which is beyond our discussion . in this paper , we studied the rare @xmath1-decays @xmath2 ( @xmath7 ) , @xmath282 and @xmath4 in the type - ii 2hdm , lepton - specific 2hdm , nmssm and nmssm , which predict a light cp - odd higgs boson @xmath0 . in the parameter space allowed by current experiments , the branching ratio can be as large as @xmath5 for @xmath118 , @xmath8 for @xmath3 and @xmath9 for @xmath4 , which implies that the decays @xmath2 and @xmath283 may be accessible at the gigaz option . since different models predict different size of branching ratios , these decays can be used to distinguish different model through the measurement of these rare decays . this work was supported in part by hastit under grant no . 2009hastit004 , by the national natural science foundation of china ( nnsfc ) under grant nos . 10821504 , 10725526 , 10635030 , 10775039 , 11075045 and by the project of knowledge innovation program ( pkip ) of chinese academy of sciences under grant no . . for some reviews , see , e.g. , m. a. perez , g. tavares - velasco and j. j. toscano , int . j. mod . a * 19 * , 159 ( 2004 ) ; j. m. yang , arxiv:1006.2594 . j. i. illana , m. masip , 67 , 035004 ( 2003 ) ; j. cao , z. xiong , j. m. yang , 32 , 245 ( 2004 ) . d. atwood _ et al_. , 66 , 093005 ( 2002 ) . j. kalinowski , and s. pokorski , 219 , 116 ( 1989 ) ; a. djouadi , p. m. zerwas and j. zunft , 259 , 175 ( 1991 ) ; a. djouadi , j. kalinowski , and p. m. zerwas , z. phys . c * 54 * , 255 ( 1992 ) . m. krawczyk , _ et al . _ , 19 , 463 ( 2001 ) ; 8 , 495 ( 1999 ) . j. f. gunion , g. gamberini and s. f. novaes , 38 , 3481 ( 1988 ) ; thomas j. weiler and tzu - chiang yuan , 318 , 337 ( 1989 ) ; a. djouadi , _ et al . _ , 1 , 163 ( 1998)[hep - ph/9701342 ] . d. chang and w. y. keung , phys . lett . * 77 * , 3732 ( 1996 ) . e. keith and e. ma , 57 , 2017 ( 1998 ) ; m. a. perez , g. tavares - velasco and j. j. toscano , int . j. mod.phys . a * 19 * , 159 ( 2004 ) . f. larios , g. tavares - velasco and c. p. yuan , 64 , 055004 ( 2001 ) ; 66 , 075006 ( 2002 ) . a. djouadi , _ et al . _ , 10 , 27 ( 1999 ) [ hep - ph/9903229 ] . for a detailed introduction of the nmssm , see f. franke and h. fraas , int . j. mod . a * 12 * ( 1997 ) 479 ; for a recent review of the nmssm , see for example , u. ellwanger , c. hugonie , and a. m. teixeira , arxiv : 0910.1785 . see , e.g. , j. r. ellis , j. f. gunion , h. e. haber , l. roszkowski and f. zwirner , phys . rev . d * 39 * ( 1989 ) 844 ; m. drees , int . j. mod . phys . a * 4 * ( 1989 ) 3635 ; u. ellwanger , m. rausch de traubenberg and c. a. savoy , phys . b * 315 * ( 1993 ) 331 ; nucl . b * 492 * ( 1997 ) 21 ; d.j . miller , r. nevzorov , p.m. zerwas , 681 , 3 ( 2004 ) . c. panagiotakopoulos , k. tamvakis , 446 , 224 ( 1999 ) ; 469 , 145 ( 1999 ) ; c. panagiotakopoulos , a. pilaftsis , 63 , 055003 ( 2001 ) ; a. dedes , _ et al . _ , 63 , 055009 ( 2001 ) ; a. menon , _ et al . _ , 70 , 035005 ( 2004 ) ; v. barger , _ et al . _ , 630 , 85 ( 2005 ) . c. balazs , _ et al . _ , 0706 , 066 ( 2007 ) . b. a. dobrescu , k. t. matchev , 0009 , 031 ( 2000 ) ; a. arhrib , k. cheung , t. j. hou , k. w. song , hep - ph/0611211 ; 0703 , 073 ( 2007 ) ; x. g. he , j. tandean , and g. valencia , 98 , 081802 ( 2007 ) ; 0806 , 002 ( 2008 ) ; f. domingo _ et al_. , 0901 , 061 ( 2009 ) ; gudrun hiller , 70 , 034018 ( 2004 ) ; r. dermisek , and john f. gunion , 75 , 075019 ( 2007 ) ; 79 , 055014 ( 2009 ) ; 81 , 055001 ( 2010 ) ; r. dermisek , john f. gunion , and b. mcelrath , 76 , 051105 ( 2007 ) ; z. heng , _ et al_. , 77 , 095012 ( 2008 ) ; a. belyaev _ et al_. , 81 , 075021 ( 2010 ) ; d. das and u. ellwanger , arxiv:1007.1151 [ hep - ph ] . s. andreas , o. lebedev , s. ramos - sanchez and a. ringwald , arxiv:1005.3978 [ hep - ph ] . j. f. gunion , jhep * 0908 * , 032 ( 2009 ) ; r. dermisek and j. f. gunion , phys . rev . d * 81 * , 075003 ( 2010 ) . r. dermisek and j. f. gunion , phys . lett . * 95 * , 041801 ( 2005 ) ; phys . d * 73 * , 111701 ( 2006 ) . j. cao , h. e. logan , j. m. yang , 79 , 091701 ( 2009 ) . j. cao , p. wan , l. wu , j. m. yang , 80 , 071701 ( 2009 ) . j. f. gunion and h. e. haber , 67 , 075019 ( 2003 ) . r. m. barnett , _ et al . _ , phys . b * 136 * , 191 ( 1984 ) ; r. m. barnett , g. senjanovic and d. wyler , phys . d * 30 * , 1529 ( 1984 ) ; y. grossman , nucl . b * 426 * , 355 ( 1994 ) . h. s. goh , l. j. hall and p. kumar , jhep * 0905 * , 097 ( 2009 ) ; a. g. akeroyd and w. j. stirling , nucl . b * 447 * , 3 ( 1995 ) ; a. g. akeroyd , phys . b * 377 * , 95 ( 1996 ) ; h. e. logan and d. maclennan , phys . rev . d * 79 * , 115022 ( 2009 ) ; m. aoki , _ et al . _ , arxiv:0902.4665 [ hep - ph ] . v. barger , p. langacker , h. s. lee and g. shaughnessy , phys . d * 73 * , 115010 ( 2006 ) . s. hesselbach , _ et . _ , arxiv:0810.0511v2 [ hep - ph ] . de vivie and p. janot [ aleph collaboration ] , pa13 - 027 contribution to the international conference on high energy physics , warsaw , poland , 2531 july 1996 ; j. kurowska , o. grajek and p. zalewski [ delphi collaboration ] , cern - open-99 - 385 . [ aleph collaboration and delphi collaboration and l3 collaboration ] , phys . rept . * 427 * , 257 ( 2006 ) . j. cao and j. m. yang , jhep * 0812 * , 006 ( 2008 ) . m. krawczyk and d. temes , eur . j. c * 44 * , 435 ( 2005 ) . g. altarelli and r. barbieri , 253 , 161 ( 1991 ) ; m. e. peskin , t. takeuchi , 46 , 381 ( 1992 ) . c. amsler , _ et al . _ , ( particle data group ) , 667 , 1 ( 2008 ) . o. deschamps , s. descotes - genon , s. monteil , v. niess , s. tjampens and v. tisserand , arxiv:0907.5135 [ hep - ph ] . s. su and b. thomas , phys . d * 79 * , 095014 ( 2009 ) . g. abbiendi , _ et al . _ , eur . phys . j. c * 32 * , 453 ( 2004 ) . m. davier , _ et al . _ , 66 , 1 ( 2010 ) . k. cheung , _ et al . _ , phys . d * 64 * , 111301 ( 2001 ) . k. cheung and o. c. w. kong , phys . d * 68 * , 053003 ( 2003 ) . t. besmer , c. greub , t.hurth , 609 , 359 ( 2001 ) ; f. borzumati , _ et al . _ , 62 , 075005(2000 ) . j. cao , k. i. hikasa , w. wang , j. m. yang and l. x. yu , phys . d * 82 * , 051701 ( 2010 ) [ arxiv:1006.4811 [ hep - ph ] ] . j. f. gunion , _ et . d * 73 * , 015011 ( 2006 ) . martin and j. d. wells , phys . d * 64 * , 035003 ( 2001 ) . j. abdallah _ et al . _ , eur . j. c * 31 * , 421 ( 2004 ) ; g. abbiendi _ et al . _ , eur . j. c * 35 * , 1 ( 2004 ) . j. dunkley _ et al . _ [ wmap collaboration ] , astrophys . j. suppl . * 180 * , 306 ( 2009 ) [ arxiv:0803.0586 [ astro - ph ] ] . u. ellwanger _ et al . _ , 02 , 066 ( 2005 ) . g. belanger , f. boudjema , a. pukhov and a. semenov , comput . commun . * 174 * , 577 ( 2006 ) ; comput . phys . commun . * 176 * , 367 ( 2007 ) . g. belanger , f. boudjema , c. hugonie , a. pukhov and a. semenov , jcap * 0509 * , 001 ( 2005 ) .""" + + ARTICLE_MAGNET = r"""it is well known that the classical magnetoresistance ( mr ) in metals or semiconductors with a closed free electron fermi surface increases quadratically with increasing magnetic field @xmath2 for @xmath3 and saturates when @xmath4 . here @xmath5 is the zero - magnetic - field mobility . hence , the extraordinarily high and linear mr ( lmr ) , which breaks this familiar rule , has been gaining much attention as soon as its discovery . in the past decade , this unexpected lmr has been reported in silver chalcogenide,@xcite indium antimonide,@xcite silicon,@xcite mnas - gaas composite material,@xcite and graphene.@xcite kapitza s linear law@xcite indicates that the metal shows a magnetoresistance linear in perpendicular magnetic field when it has an open fermi surface and a mean free path longer than the electronic larmor radius . recently , another two models , irrespective of the open fermi surface , have been constructed to provide possible mechanisms for the lmr phenomenon . abrikosov suggested a quantum - limit origin of lmr for the homogenous system with a gapless linear energy spectrum.@xcite his model requires that landau levels are well formed and the carrier concentration is small that all electrons occupy only the lowest landau band . alternatively , parish and littlewood developed a classical model without involving linear spectrum.@xcite ignoring the concrete microscopic mechanism , they attributed this unusual mr to the mobility fluctuations in a strongly inhomogenous system . topological insulators@xcite ( tis ) are novel materials with a full energy gap in bulk , while there are gapless surface states . due to its unique band structure with only one helical dirac cone and linear energy dispersion,@xcite the surface states of the ti bi@xmath0se@xmath1 become an excellent platform for the study of quantum - limit lmr . the recent experiment in this flat surface system , however , reported that a large positive mr , which becomes very linear above a characteristic field of @xmath6@xmath7@xmath8 t , was observed even in an opposite situation where the carrier sheet density is high that electrons occupy more than one landau levels.@xcite moreover , they found that raising temperature to room temperature almost has no influence on the observed lmr . it is striking that this observation is in conflict with abrikosov s model and also with the classical parish - littlewood model . so far a reliable theoretical scheme capable of explaining this novel experiment has still been lacking . in this paper , we generalize the balance - equation approach@xcite to a system modeling the surface states of a three - dimensional ti to investigate the two - dimensional magnetotransport in it . we find that a positive , nonsaturating and dominantly linear magnetoresistance can appear within quite wide magnetic - field range in the ti surface state having a positive and finite effective g - factor . this linear magnetoresistance shows up in the system of high carrier concentration and low mobility when electrons are in extended states and spread over many smeared landau levels , and persists up to room temperature , providing a possible mechanism for the recently observed linear magnetoresistance in topological insulator bi@xmath0se@xmath1 nanoribbons.@xcite we consider the surface state of a bi@xmath0se@xmath1-type large bulk gap ti in the @xmath9-@xmath10 plane under the influence of a uniform magnetic field @xmath11 applied along the @xmath12 direction.@xcite following the experimental observation,@xcite we assume that the fermi energy locates in the gap of the bulk band and above the dirac point , i.e. the surface carriers are electrons . further , the separations of the fermi energy from the bottom of bulk band and dirac point are much larger than the highest temperature ( @xmath13 ) considered in this work . hence , the contribution from the bulk band to the magnetotransport is negligible . these electrons , scattered by randomly distributed impurities and by phonons , are driven by a uniform in - plane electric field @xmath14 in the topological surface . the hamiltonian of this many - electron and phonon system consists of an electron part @xmath15 , a phonon part @xmath16 , and electron - impurity and electron - phonon interactions @xmath17 and @xmath18 : @xmath19 here , the electron hamiltonian is taken in the form @xmath20 , \ ] ] in which @xmath21 , @xmath22 , @xmath23 and @xmath24 , stand , respectively , for the canonical momentum , coordinate , momentum and spin operators of the @xmath25th electron having charge @xmath26 , @xmath27 is the vector potential of the perpendicular magnetic field @xmath28 in the landau gauge , @xmath29 is the fermi velocity , @xmath30 is the effective g - factor of the surface electron , and @xmath31 is the bohr magneton with @xmath32 the free electron mass . the sum index @xmath25 in eq.([helectron ] ) goes over all electrons of total number @xmath33 in the surface state of unit area . in the frame work of balance equation approach,@xcite the two - dimensional center - of - mass ( c.m . ) momentum and coordinate @xmath34 and @xmath35 , and the relative - electron momenta and coordinates @xmath36 and @xmath37 are introduced to write the hamiltonian @xmath15 into the sum of a single - particle c.m . part @xmath38 and a many - particle relative - electron part @xmath39 : @xmath40 , with @xmath41.\end{aligned}\ ] ] in this , @xmath42 is the canonical momentum of the center - of - mass and @xmath43 is the canonical momentum for the @xmath25th relative electron . here we have also introduced c.m . spin operators @xmath44 and @xmath45 . the commutation relations between the c.m . spin operators @xmath46 and @xmath47 and the spin operators @xmath48 , @xmath49 and @xmath50 of the @xmath25th electron are of order of @xmath51 : @xmath52= n^{-1}2\,{\rm i}\,\varepsi lon_{\beta_1\beta_2\beta_3}\sigma_j^{\beta_3}$ ] with @xmath53 . therefore , for a macroscopic large @xmath33 system , the c.m . part @xmath38 actually commutes with the relative - electron part @xmath54 in the hamiltonian , i.e. the c.m . motion and the relative motion of electrons are truly separated from each other . the couplings between the two emerge only through the electron impurity and electron phonon interactions . furthermore , the electric field @xmath55 shows up only in @xmath38 . and , in view of @xmath56={\rm i}\delta_{\alpha \beta}(\delta_{ij}-1/n)\simeq { \rm i}\delta_{\alpha\beta}\delta_{ij}$ ] , i.e. the relative - electron momenta and coordinates can be treated as canonical conjugate variables , the relative - motion part @xmath54 is just the hamiltonian of @xmath33 electrons in the surface state of ti in the magnetic field without the presence of the electric field . in terms of the c.m . coordinate @xmath57 and the relative electron density operator @xmath58 , the electron impurity and electron phonon interactions can be written as@xcite @xmath59 here @xmath60 and @xmath61 are respectively the impurity potential ( an impurity at randomly distributed position @xmath62 ) and electron phonon coupling matrix element in the plane - wave representation , and @xmath63 with @xmath64 and @xmath65 being the creation and annihilation operators for a phonon of wavevector @xmath66 in branch @xmath67 having frequency @xmath68 . velocity ( operator ) @xmath69 is the time variation of its coordinate : @xmath70= v_{\rm f}(\sigma_{\rm c}^y\ , \hat{i}-\sigma_{\rm c}^x\ , \hat{j})$ ] . to derive a force - balance equation for steady state transport we consider the heisenberg equation for the rate of change of the c.m . canonical momentum @xmath71 : @xmath72= - n e({\bm v}\times { \bm b})- n e{\bm e}+{\bm { f}}_{\rm i}+{\bm { f}}_{\rm p},\ ] ] in which the frictional forces @xmath73 and @xmath74 share the same expressions as given in ref .. the statistical average of the operator equation can be determined to linear order in the electron impurity and electron phonon interactions @xmath17 and @xmath18 with the initial density matrix @xmath75 at temperature @xmath76 when the in - plane electric field @xmath77 is not strong . for steady - transport states we have @xmath78 , leading to a force - balance equation of the form @xmath79 here @xmath80 , the statistically averaged velocity of the moving center - of - mass , is identified as the average rate of change of its position , i.e. the drift velocity of the electron system driven by the electric field @xmath77 , and @xmath81 and @xmath82 are frictional forces experienced by the center - of - mass due to impurity and phonon scatterings : @xmath83,\label{fp}\end{aligned}\ ] ] in which @xmath84 is the bose distribution function , @xmath85 , and @xmath86 stands for the imaginary part of the fourier spectrum of the relative - electron density correlation function defined by @xmath87\big\rangle_{0},\ ] ] where @xmath88 and @xmath89 denotes the statistical averaging over the initial density matrix @xmath90.@xcite the force - balance equation describes the steady - state two - dimensional magnetotransport in the surface state of a ti . note that the frictional forces @xmath81 and @xmath82 are in the opposite direction of the drift velocity @xmath91 and their magnitudes are functions of @xmath92 only . with the drift velocity @xmath93 in the @xmath9 direction , the force - balance equation eq . yields a transverse resistivity @xmath94 , and a longitudinal resistivity @xmath95 . the linear one is in the form @xmath96 for calculating the electron density correlation function @xmath97 we proceed in the landau representation.@xcite the landau levels of the single - particle hamiltonian @xmath98 of the relative - electron system in the absence of electric field are composed of a positive `` @xmath99 '' and a negative `` @xmath100 '' branch@xcite @xmath101 with @xmath102 and @xmath103 , and a zero ( @xmath104 ) level @xmath105 the corresponding landau wave functions are @xmath106 and @xmath107 for @xmath108 ; and @xmath109 for @xmath104 . here @xmath110 is the wavevector of the system along @xmath9 direction ; @xmath111 with @xmath112 ; and @xmath113 is the harmonic oscillator eigenfunction with @xmath114 being the hermite polynomial , @xmath115 , and @xmath116 . each landau level contains @xmath117 electron states for system of unit surface area . the positive branch @xmath118 and the @xmath104 level @xmath119 of the above energy spectra are indeed quite close to those of the surface states in the bulk gap of bi@xmath0se@xmath1-family materials derived from microscopic band calculation.@xcite the landau levels are broadened due to impurity , phonon and electron - electron scatterings . we model the imaginary part of the retarded green s function , or the density - of - states , of the broadened landau level @xmath120 ( written for `` + ' ' -branch and @xmath104 levels ) , using a gaussian - type form:@xcite @xmath121,\ ] ] with a half - width @xmath122 of the form:@xcite @xmath123^{1/2}$ ] . here @xmath124 is the single - particle lifetime and @xmath125 is the cyclotron frequency of linear - energy - dispersion system with @xmath126 being the zero - temperature fermi level . using a semi - empirical parameter @xmath127 to relate @xmath124 with the transport scattering time @xmath128 , and expressing @xmath129 with the zero - field mobility @xmath5 at finite temperature,@xcite we can write the landau - level broadening as @xmath130^{1/2}.\ ] ] in the present study we consider the case of @xmath120-doping , i.e. the fermi level is high enough above the energy zero of the dirac cone in the range of `` + ' ' -branch levels and the states of `` @xmath100''-branch levels are completely filled , that they are irrelevant to electron transport . special attention has to be paid to the @xmath104 level , since , depending on the direction of exchange potential the effective g - factor of a ti surface state , @xmath30 , can be positive , zero or negative.@xcite the sign and magnitude of the effective g - factor determines how many states of the zero level should be included in or excluded from the available states for electron occupation in the case of @xmath120-doping at a magnetic field . ( i ) if @xmath131 , the @xmath104 level center is exactly at @xmath132 and the system is electron - hole symmetric . the total number of negative energy states ( including the states of the lower half of the @xmath104 level and states of the @xmath100"-branch levels ) and that of positive energy states ( including the states of the upper half of the @xmath104 level and states of the @xmath99"-branch levels ) do not change when changing magnetic field . therefore , the lower - half negative energy states of this level are always filled and the upper - half positive - energy states of it are available for the occupation of particles which are counted as electrons participating in transport in the case of @xmath120-doping . ( ii ) for a finite positive @xmath133 , the @xmath104 level @xmath134 moves downward to negative energy and its distance to the nearest @xmath100"-branch level is @xmath135 closer than to the nearest + " -branch level at finite magnetic field strength @xmath2 . this is equivalent to the opening of an increasingly enlarged ( with increasing @xmath2 ) energy gap between the + " -branch states and the states of the zero - level and the @xmath100"-branch levels . the opening of a sufficient energy gap implies that with increasing magnetic field the states in the + " -branch levels would no longer shrink into the zero - level , and thus the @xmath104 level should be completely excluded from the conduction band , i.e. only particles occupying the + " -branch states are counted as electrons participating in transport in the case of @xmath120-doping , when the magnetic field @xmath2 gets larger than a certain value ( depending on the magnitude of @xmath30 ) . ( iii ) for a finite negative @xmath136 , the @xmath104 level @xmath134 moves upward to positive energy and an increasingly enlarged energy gap will be opened between the states of the zero - level and the + " -branch and the states of @xmath100"-branch levels , and particles occupying the @xmath104 level and + " -branch states are electrons participating in transport when the magnetic field @xmath2 gets larger than a certain value . as a result , the experimentally accessible sheet density @xmath33 of electrons participating in transport is related to the fermi energy @xmath137 by the following equation valid at finite @xmath30 for the magnetic field @xmath2 larger than a certain value : @xmath138 in which @xmath139 + 1\}^{-1}$ ] is the fermi distribution function at temperature @xmath76 and the summation index @xmath120 goes over @xmath140 for @xmath133 , or @xmath141 for @xmath136 . in the case of @xmath131 , @xmath142\ ] ] valid for arbitrary magnetic field , in which @xmath143 . the imaginary part of relative - electron density correlation function in the presence of a magnetic field , @xmath86 , can be expressed in the landau representation as@xcite @xmath144 in which the transform factor @xmath145 ^ 2,\end{aligned}\ ] ] with @xmath146 , @xmath147 , @xmath148 , and @xmath149 being associated laguerre polynomials . the landau - representation correlation function @xmath150 in eq.([piqw ] ) can be constructed with the imaginary part of the retarded green s function @xmath151 , or the density - of - states , of the @xmath120th landau level as@xcite @xmath152\nonumber\\ & \hspace{1.2cm}\times{\rm im}g_n(\epsilon+\omega){\rm im}g_{n'}(\epsilon).\end{aligned}\ ] ] the summation indices @xmath120 and @xmath153 in eq.([piqw ] ) are taken over @xmath140 for @xmath133 , or @xmath154 for @xmath136 . in the case of @xmath131 , eq.([piqw ] ) still works and the summation indices @xmath120 and @xmath153 go over @xmath154 but with @xmath155 replaced by @xmath156 in eq.([p2nn ] ) . numerical calculations are performed for the magnetoresistivity @xmath157 of surface state in a uniform ti bi@xmath0se@xmath1 . at zero temperature the elastic scattering contributing to the resistivity is modeled by a coulomb potential due to charged impurities:@xcite @xmath158 with @xmath159 being the impurity density , which is determined by the zero - magnetic - field mobility @xmath5 . at temperatures higher than @xmath160,@xcite phonon scatterings play increasingly important role and the dominant inelastic contribution comes from optical phonons . for this polar material , the scattering by optical phonons via the deformation potential can be neglected . hence , we take account of inelastic scattering from optical phonons via frhlich coupling : @xmath161 . in the numerical calculation we use the following parameters:@xcite fermi velocity @xmath162 , static dielectric constant @xmath163 , optical dielectric constant @xmath164 , and phonon energy @xmath165 . the broadening parameter is taken to be @xmath166 . as a function of the magnetic field @xmath2 having different effective g - factors : @xmath167 and @xmath168 for a ti surface system with electron sheet density @xmath169 in the cases of zero - magnetic - field mobility @xmath170 ( a ) and @xmath171 ( b ) . several integer - number positions of filling factor @xmath172 are marked in ( b).,scaledwidth=40.0% ] fig.[diffg ] shows the calculated magnetoresistivity @xmath157 versus the magnetic field strength @xmath2 for a ti surface system with electron sheet density @xmath169 but having different effective g - factors : @xmath167 and @xmath168 for two values of zero - magnetic - field mobility @xmath170 and @xmath171 , representing different degree of landau - level broadening . in the case without zeeman splitting ( @xmath131 ) the resistivity @xmath157 exhibits almost no change with changing magnetic field up to 10 t , except the shubnikov - de haas ( sdh ) oscillation showing up in the case of @xmath171 . this kind of magnetoresistance behavior was indeed seen experimentally in the electron - hole symmetrical massless system of single - layer graphene.@xcite in the case of a positive g - factor , @xmath173 , the magnetoresistivity increases linearly with increasing magnetic field ; while for a negative g - factor , @xmath174 , the magnetoresistivity decreases linearly with increasing magnetic field . is shown as a function of the magnetic field @xmath2 for different values of zero - magnetic - field mobility : ( a ) @xmath175 , ( b ) @xmath176 , ( c ) @xmath177 , ( d ) @xmath178 , ( e ) @xmath179 , and ( f ) @xmath180 . the inset of ( a ) illustrates the same for a larger magnetic - field range @xmath181 . the filling factor @xmath182 is plotted versus the magnetic field in ( f ) ; and several integer - number positions of @xmath182 are also marked in ( d ) and ( e ) . here the surface electron density @xmath169 and the lattice temperature @xmath183.,scaledwidth=47.0% ] in the following we will give more detailed examination on the linearly increasing magnetoresistance in the positive @xmath30 case . fig.[rhob ] shows the calculated resistivity @xmath157 versus the magnetic field strength @xmath2 at lattice temperature @xmath183 for system of carrier sheet density @xmath169 and @xmath173 , having different zero - field mobility @xmath184 and @xmath180 . all resistivity curves for mobility @xmath185 exhibit clear linearity in the magnetic - field range and appear no tendency of saturation at the highest field shown in the figure . especially , for the case @xmath170 , the linear behavior extends even up to the magnetic field of @xmath186 , as illustrated in the inset of fig.[rhob](a ) . this feature contradicts the classical mr which saturates at sufficiently large magnetic field @xmath187 . note that here we only present the calculated @xmath157 for magnetic field @xmath2 larger than @xmath188 t , for which a sufficient energy gap @xmath135 is assumed to open that with further increase of the magnetic field the states in the `` + ' ' -branch levels no longer shrink into the zero level and thus it should be excluded from the conduction band . this is of course not true for very weak magnetic field . when @xmath189 the energy gap @xmath190 , the situation becomes similar to the case of @xmath131 : the whole upper half of the zero - level states are available to electron occupation and we should have a flat resistivity @xmath157 when changing magnetic field . with increasing @xmath2 the portion of the zero - level states available to conduction electrons decreases until the magnetic field reaches @xmath191 . as a result the resistivity @xmath157 should exhibit a crossover from a flat changing at small @xmath2 to positively linear increasing at @xmath192 . this is just the behavior observed in the ti bi@xmath0se@xmath1.@xcite note that in the case of @xmath170 , the broadened landau - level widths are always larger than the neighboring level interval : @xmath193 , which requires @xmath194 ^ 2 $ ] , even for the lowest landau level @xmath195 , i.e. the whole landau - level spectrum is smeared . with increasing the zero - field mobility the magnitude of resistivity @xmath157 decreases , and when the broadened landau - level width becomes smaller than the neighboring level interval , @xmath196 , a weak sdh oscillation begin to occur around the linearly - dependent average value of @xmath157 at higher portion of the magnetic field range , as seen in fig.[rhob](c ) , ( d ) and ( e ) for @xmath197 and @xmath198 . on the other hand , in the case of large mobility , e.g. @xmath199 , where the broadened landau - level widths @xmath200 are much smaller than the neighboring level interval even for level index @xmath120 as large as @xmath201 , the magnetoresistivity shows pronounced sdh oscillation and the linear - dependent behavior disappears , before the appearance of quantum hall effect,@xcite as shown in fig.[rhob](f ) . abrikosov s model for the lmr requires the applied magnetic field large enough to reach the quantum limit at which all the carriers are within the lowest landau level,@xcite while it is obvious that more than one landau levels are occupied in the experimental samples in the field range in which the linear and non - saturating magnetoresistivity was observed.@xcite for the given electron surface density @xmath202 , the number of occupied landau levels , or the filling factor @xmath172 , at different magnetic fields is shown in fig.[rhob](f ) , as well as in the fig.[rhob](d ) and ( e ) , where the integer - number positions of @xmath203 , i.e. filling up to entire @xmath182 landau levels , coincide with the minima of the density - of - states or the dips of sdh oscillation . this is in contrast with @xmath131 case , where the integer number of @xmath203 , which implies a filling up to the center position of the @xmath182th landau levels , locates at a peak of sdh oscillation , as shown in fig.[diffg]b . the observed sdh oscillations in the bi@xmath0se@xmath1 nanoribbon exhibiting nonsaturating surface lmr in the experiment@xcite favor the former case : a finite positive effective @xmath133 . is plotted as a function of the surface electron density @xmath33 at magnetic field @xmath204 : ( a ) at different values of zero - field mobility @xmath5 , and ( b ) at different values of zero - field conductivity @xmath205.,scaledwidth=40.0% ] at various lattice temperatures . here the zero - magnetic - field mobility at zero temperature is @xmath206.,scaledwidth=35.0% ] next , we examine the density - dependence of the linear magnetoresistivity . to compare with abrikosov s quantum magnetoresistance which suggests a @xmath207 behavior,@xcite we show the calculated @xmath208 for above lmr versus the carrier sheet density @xmath33 in fig.[rhon ] at fixed magnetic field @xmath209 t . the mobility is taken respectively to be @xmath210 and @xmath211m@xmath212/vs to make the resistivity in the lmr regime . a clearly linear dependence of @xmath213 on the surface density @xmath33 is seen in all cases , indicating that this non - saturating linear resistivity is almost inversely proportional to the carrier density . in the figure we also show @xmath208 versus @xmath33 under the condition of different given conductivity @xmath214 and @xmath215 . in this case the half - width @xmath216 is independent of surface density . the linear dependence still holds , indicating that this linear behavior is not sensitive to the modest @xmath33-dependence of landau level broadening @xmath216 as long as the system is in the overlapped landau level regime . from the above discussion , it is obvious that lmr shows up in the system having overlapped landau levels and the separation of landau levels makes the mr departure from the linear increase . at high temperature , the thermal energy would smear the level separation and phonon scatterings further broaden landau levels . hence , it is believed that this lmr will be robust against raising temperature . this is indeed the case as seen in fig.[rhot ] , where we plot the calculated magnetoresistivity @xmath157 for the above system with zero - temperature linear mobility @xmath217m@xmath212/vs versus the magnetic field at different lattice temperatures . we can see that raising temperature to room temperature has little effect on the linearity of mr . due to the decreased mobility at higher temperature from phonon scattering , the weak sdh oscillation on the linear background tends to vanish . these features are in good agreement with the experimental report.@xcite in summary , we have studied the two - dimensional magnetotransport in the flat surface of a three - dimensional ti , which arises from the surface states with a wavevector - linear energy dispersion and a finite , positive zeeman splitting within the bulk energy gap . when the level broadening is comparable to or larger than the landau - level separation and the conduction electrons spread over many landau levels , a positive , dominantly linear and non - saturating magnetoresistance appears within a quite wide range of magnetic field and persists up to room temperature . this remarkable lmr provides a possible mechanism for the recently observed linear magnetoresistance in topological insulator bi@xmath0se@xmath1 nanoribbons.@xcite in contrast to quantum hall effect which appears in the case of well formed landau levels and to abrikosov s quantum magnetotransport,@xcite which is limited to the extreme quantum limit that all electrons coalesce into the lowest landau level , the discussed lmr is a phenomena of pure classical two - dimensional magnetotransport in a system having linear - energy - dispersion , appearing in the regime of overlapped landau levels , irrespective of its showing up in relatively high magnetic field range . furthermore , the present scheme deals with spatially uniform case without invoking the mobility fluctuation in a strongly inhomogeneous system , which is required in the classical parish and littlewood model to produce a lmr.@xcite the appearance of this significant positive - increasing linear magnetoresistance depends on the existence of a positive and sizable effective g - factor . if the zeeman energy splitting is quite small the resistivity @xmath157 would exhibit little change with changing magnetic field . in the case of a negative and sizable effective g - factor the magnetoresistivity would decrease linearly with increasing magnetic field . therefore , the behavior of the longitudinal resistivity versus magnetic field may provide a useful way for judging the direction and the size of the effective zeeman energy splitting in ti surface states . this work was supported by the national science foundation of china ( grant no . 11104002 ) , the national basic research program of china ( grant no . 2012cb927403 ) and by the program for science&technology innovation talents in universities of henan province ( grant no . 2012hastit029 ) .""" + + dct = tok.batch_encode_plus( + [ARTICLE_LEP, ARTICLE_MAGNET], + max_length=6144, + padding="max_length", + truncation=True, + return_tensors="pt", + ) + + hypotheses_batch = hf.generate( + input_ids=dct["input_ids"].to(torch_device), + attention_mask=dct["attention_mask"].to(torch_device), + num_beams=4, + max_length=512, + early_stopping=True, + no_repeat_ngram_size=3, + ) + + EXPECTED_LEP = ( + " the physics of @xmath0-boson will again play the central role in the frontier of particle physics if the" + " gigaz option of the international linear collider ( ilc ) can be realized in its first phase. \n the" + " expected sensitivity to the branching ratio of rare decays, especially its exotic or rare processes," + " should be investigated comprehensively to evaluate their potential in probing new physics. in this work" + " \n, we study the rare decay into light higgs boson(s ) in the framework of the minimal supersymmetric" + " standard model ( mssm ), where a light cp - odd higgs - boson with singlet - dominant component may" + " naturally arise from the spontaneous breaking of some approximate global symmetry. " + ) + + EXPECTED_MAGNET = ( + " the recent experiment in the surface states of the topological insulator bi@xmath0se @xmath1, however," + " reported that a large positive magnetoresistance becomes very linear in perpendicular magnetic field" + " even in an opposite situation where the carrier sheet density is high that all electrons occupy more" + " than one landau levels. \n it is striking that this observation is in conflict with abrikosov s model" + " and also with the classical parish - littlewood model. " + ) + + generated = tok.batch_decode( + hypotheses_batch.tolist(), clean_up_tokenization_spaces=True, skip_special_tokens=True + ) + assert generated == [EXPECTED_LEP, EXPECTED_MAGNET] diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_tf_led.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_tf_led.py new file mode 100644 index 0000000000000000000000000000000000000000..7bac1ced835b09548f3ba3610e53883add07360e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_modeling_tf_led.py @@ -0,0 +1,366 @@ +# coding=utf-8 +# Copyright Iz Beltagy, Matthew E. Peters, Arman Cohan and The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import LEDConfig, is_tf_available +from transformers.testing_utils import require_tf, slow, tooslow + +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 TFLEDForConditionalGeneration, TFLEDModel + + +@require_tf +class TFLEDModelTester: + config_cls = LEDConfig + config_updates = {} + hidden_act = "gelu" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + attention_window=4, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + self.attention_window = attention_window + + # `ModelTesterMixin.test_attention_outputs` is expecting attention tensors to be of size + # [num_attention_heads, encoder_seq_length, encoder_key_length], but TFLongformerSelfAttention + # returns attention of shape [num_attention_heads, encoder_seq_length, self.attention_window + 1] + # because its local attention only attends to `self.attention_window` and one before and one after + self.key_length = self.attention_window + 2 + + # because of padding `encoder_seq_length`, is different from `seq_length`. Relevant for + # the `test_attention_outputs` and `test_hidden_states_output` tests + self.encoder_seq_length = ( + self.seq_length + (self.attention_window - self.seq_length % self.attention_window) % self.attention_window + ) + + def prepare_config_and_inputs_for_common(self): + input_ids = ids_tensor([self.batch_size, self.seq_length - 1], self.vocab_size) + eos_tensor = tf.expand_dims(tf.constant([self.eos_token_id] * self.batch_size), 1) + input_ids = tf.concat([input_ids, eos_tensor], axis=1) + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = 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, + attention_window=self.attention_window, + **self.config_updates, + ) + inputs_dict = prepare_led_inputs_dict(config, input_ids, decoder_input_ids) + global_attention_mask = tf.concat( + [tf.zeros_like(input_ids)[:, :-1], tf.ones_like(input_ids)[:, -1:]], + axis=-1, + ) + inputs_dict["global_attention_mask"] = global_attention_mask + return config, inputs_dict + + def check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = TFLEDModel(config=config).get_decoder() + input_ids = inputs_dict["input_ids"] + + input_ids = input_ids[:1, :] + attention_mask = inputs_dict["attention_mask"][:1, :] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = tf.cast(ids_tensor((self.batch_size, 3), 2), tf.int8) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([attention_mask, next_attn_mask], axis=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)[0] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + +def prepare_led_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, +): + if attention_mask is None: + attention_mask = tf.cast(tf.math.not_equal(input_ids, config.pad_token_id), tf.int8) + if decoder_attention_mask is None: + decoder_attention_mask = tf.concat( + [ + tf.ones(decoder_input_ids[:, :1].shape, dtype=tf.int8), + tf.cast(tf.math.not_equal(decoder_input_ids[:, 1:], config.pad_token_id), tf.int8), + ], + axis=-1, + ) + if head_mask is None: + head_mask = tf.ones((config.encoder_layers, config.encoder_attention_heads)) + if decoder_head_mask is None: + decoder_head_mask = tf.ones((config.decoder_layers, config.decoder_attention_heads)) + return { + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + } + + +@require_tf +class TFLEDModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFLEDForConditionalGeneration, TFLEDModel) if is_tf_available() else () + all_generative_model_classes = (TFLEDForConditionalGeneration,) if is_tf_available() else () + pipeline_model_mapping = ( + { + "conversational": TFLEDForConditionalGeneration, + "feature-extraction": TFLEDModel, + "summarization": TFLEDForConditionalGeneration, + "text2text-generation": TFLEDForConditionalGeneration, + "translation": TFLEDForConditionalGeneration, + } + if is_tf_available() + else {} + ) + is_encoder_decoder = True + test_pruning = False + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFLEDModelTester(self) + self.config_tester = ConfigTester(self, config_class=LEDConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_decoder_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in self.all_generative_model_classes: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + inputs_dict["global_attention_mask"] = tf.zeros_like(inputs_dict["attention_mask"]) + num_global_attn_indices = 2 + inputs_dict["global_attention_mask"] = tf.where( + tf.range(self.model_tester.seq_length)[None, :] < num_global_attn_indices, + 1, + inputs_dict["global_attention_mask"], + ) + + config.return_dict = True + seq_length = self.model_tester.seq_length + encoder_seq_length = self.model_tester.encoder_seq_length + + def check_decoder_attentions_output(outputs): + decoder_attentions = outputs.decoder_attentions + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, seq_length], + ) + + def check_encoder_attentions_output(outputs): + attentions = [t.numpy() for t in outputs.encoder_attentions] + global_attentions = [t.numpy() for t in outputs.encoder_global_attentions] + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + self.assertEqual(len(global_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length, seq_length], + ) + self.assertListEqual( + list(global_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, num_global_attn_indices], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["use_cache"] = False + config.output_hidden_states = False + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + out_len = len(outputs) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + if self.is_encoder_decoder: + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_decoder_attentions_output(outputs) + + # Check that output attentions can also be changed via the config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + self.assertEqual(out_len + (2 if self.is_encoder_decoder else 1), len(outputs)) + self.assertEqual(model.config.output_hidden_states, True) + check_encoder_attentions_output(outputs) + + def test_xla_mode(self): + # TODO JP: Make LED XLA compliant + pass + + @tooslow + def test_saved_model_creation(self): + pass + + def test_generate_with_headmasking(self): + # TODO: Head-masking not yet implement + pass + + +def _long_tensor(tok_lst): + return tf.constant(tok_lst, dtype=tf.int32) + + +TOLERANCE = 1e-4 + + +@slow +@require_tf +class TFLEDModelIntegrationTest(unittest.TestCase): + def test_inference_no_head(self): + model = TFLEDForConditionalGeneration.from_pretrained("allenai/led-base-16384").led + + # change to intended input here + input_ids = _long_tensor([512 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + decoder_input_ids = _long_tensor([128 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + inputs_dict = prepare_led_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 1024, 768) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = tf.convert_to_tensor( + [[2.3050, 2.8279, 0.6531], [-1.8457, -0.1455, -3.5661], [-1.0186, 0.4586, -2.2043]], + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-3) + + def test_inference_with_head(self): + model = TFLEDForConditionalGeneration.from_pretrained("allenai/led-base-16384") + + # change to intended input here + input_ids = _long_tensor([512 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + decoder_input_ids = _long_tensor([128 * [0, 31414, 232, 328, 740, 1140, 12695, 69]]) + inputs_dict = prepare_led_inputs_dict(model.config, input_ids, decoder_input_ids) + output = model(**inputs_dict)[0] + expected_shape = (1, 1024, model.config.vocab_size) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = tf.convert_to_tensor( + [[33.6507, 6.4572, 16.8089], [5.8739, -2.4238, 11.2902], [-3.2139, -4.3149, 4.2783]], + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-3, rtol=1e-3) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_tokenization_led.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_tokenization_led.py new file mode 100644 index 0000000000000000000000000000000000000000..7ff81749946aa4e51b3fd5034beab6be61b6ef81 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/led/test_tokenization_led.py @@ -0,0 +1,183 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import json +import os +import unittest + +from transformers import BatchEncoding, LEDTokenizer, LEDTokenizerFast +from transformers.models.led.tokenization_led import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers, require_torch +from transformers.utils import cached_property + +from ...test_tokenization_common import TokenizerTesterMixin + + +@require_tokenizers +class TestTokenizationLED(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LEDTokenizer + rust_tokenizer_class = LEDTokenizerFast + test_rust_tokenizer = True + + def setUp(self): + super().setUp() + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + return "lower newer", "lower newer" + + @cached_property + def default_tokenizer(self): + return LEDTokenizer.from_pretrained("allenai/led-base-16384") + + @cached_property + def default_tokenizer_fast(self): + return LEDTokenizerFast.from_pretrained("allenai/led-base-16384") + + @require_torch + def test_prepare_batch(self): + src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] + expected_src_tokens = [0, 250, 251, 17818, 13, 39186, 1938, 4, 2] + + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + batch = tokenizer(src_text, max_length=len(expected_src_tokens), padding=True, return_tensors="pt") + self.assertIsInstance(batch, BatchEncoding) + + self.assertEqual((2, 9), batch.input_ids.shape) + self.assertEqual((2, 9), batch.attention_mask.shape) + result = batch.input_ids.tolist()[0] + self.assertListEqual(expected_src_tokens, result) + + @require_torch + def test_prepare_batch_empty_target_text(self): + src_text = ["A long paragraph for summarization.", "Another paragraph for summarization."] + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + batch = tokenizer(src_text, padding=True, return_tensors="pt") + self.assertIn("input_ids", batch) + self.assertIn("attention_mask", batch) + self.assertNotIn("labels", batch) + self.assertNotIn("decoder_attention_mask", batch) + + @require_torch + def test_tokenizer_as_target_length(self): + tgt_text = [ + "Summary of the text.", + "Another summary.", + ] + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + targets = tokenizer(text_target=tgt_text, max_length=32, padding="max_length", return_tensors="pt") + self.assertEqual(32, targets["input_ids"].shape[1]) + + @require_torch + def test_prepare_batch_not_longer_than_maxlen(self): + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + batch = tokenizer( + ["I am a small frog" * 1024, "I am a small frog"], padding=True, truncation=True, return_tensors="pt" + ) + self.assertIsInstance(batch, BatchEncoding) + self.assertEqual(batch.input_ids.shape, (2, 5122)) + + @require_torch + def test_special_tokens(self): + src_text = ["A long paragraph for summarization."] + tgt_text = [ + "Summary of the text.", + ] + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + inputs = tokenizer(src_text, return_tensors="pt") + targets = tokenizer(text_target=tgt_text, return_tensors="pt") + input_ids = inputs["input_ids"] + labels = targets["input_ids"] + self.assertTrue((input_ids[:, 0] == tokenizer.bos_token_id).all().item()) + self.assertTrue((labels[:, 0] == tokenizer.bos_token_id).all().item()) + self.assertTrue((input_ids[:, -1] == tokenizer.eos_token_id).all().item()) + self.assertTrue((labels[:, -1] == tokenizer.eos_token_id).all().item()) + + @require_torch + def test_global_attention_mask(self): + for tokenizer in [self.default_tokenizer, self.default_tokenizer_fast]: + src_text = ["Summary of the text.", "Another summary."] + expected_global_attention_mask = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, -1, -1]] + + encoded_output = tokenizer(src_text, padding=False) + encoded_output["global_attention_mask"] = [[0] * len(x) for x in encoded_output["input_ids"]] + outputs = tokenizer.pad(encoded_output) + self.assertSequenceEqual(outputs["global_attention_mask"], expected_global_attention_mask) + + def test_pretokenized_inputs(self): + pass + + def test_embeded_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + sentence = "A, AllenNLP sentence." + tokens_r = tokenizer_r.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + tokens_p = tokenizer_p.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + self.assertEqual( + sum(tokens_r["attention_mask"]) / len(tokens_r["attention_mask"]), + sum(tokens_p["attention_mask"]) / len(tokens_p["attention_mask"]), + ) + + tokens_r_str = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p_str = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + self.assertSequenceEqual(tokens_p["input_ids"], [0, 250, 6, 50264, 3823, 487, 21992, 3645, 4, 2]) + self.assertSequenceEqual(tokens_r["input_ids"], [0, 250, 6, 50264, 3823, 487, 21992, 3645, 4, 2]) + + self.assertSequenceEqual( + tokens_p_str, ["", "A", ",", "", "ĠAllen", "N", "LP", "Ġsentence", ".", ""] + ) + self.assertSequenceEqual( + tokens_r_str, ["", "A", ",", "", "ĠAllen", "N", "LP", "Ġsentence", ".", ""] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_image_processing_levit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_image_processing_levit.py new file mode 100644 index 0000000000000000000000000000000000000000..12d64c8177155087badf4ff9e7baeeaa67a38821 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_image_processing_levit.py @@ -0,0 +1,208 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +import numpy as np + +from transformers.testing_utils import require_torch, require_vision +from transformers.utils import is_torch_available, is_vision_available + +from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs + + +if is_torch_available(): + import torch + +if is_vision_available(): + from PIL import Image + + from transformers import LevitImageProcessor + + +class LevitImageProcessingTester(unittest.TestCase): + def __init__( + self, + parent, + batch_size=7, + num_channels=3, + image_size=18, + min_resolution=30, + max_resolution=400, + do_resize=True, + size=None, + do_center_crop=True, + crop_size=None, + do_normalize=True, + image_mean=[0.5, 0.5, 0.5], + image_std=[0.5, 0.5, 0.5], + ): + size = size if size is not None else {"shortest_edge": 18} + crop_size = crop_size if crop_size is not None else {"height": 18, "width": 18} + self.parent = parent + self.batch_size = batch_size + self.num_channels = num_channels + self.image_size = image_size + self.min_resolution = min_resolution + self.max_resolution = max_resolution + self.do_resize = do_resize + self.size = size + self.do_center_crop = do_center_crop + self.crop_size = crop_size + self.do_normalize = do_normalize + self.image_mean = image_mean + self.image_std = image_std + + def prepare_image_processor_dict(self): + return { + "image_mean": self.image_mean, + "image_std": self.image_std, + "do_normalize": self.do_normalize, + "do_resize": self.do_resize, + "do_center_crop": self.do_center_crop, + "size": self.size, + "crop_size": self.crop_size, + } + + +@require_torch +@require_vision +class LevitImageProcessingTest(ImageProcessingSavingTestMixin, unittest.TestCase): + image_processing_class = LevitImageProcessor if is_vision_available() else None + + def setUp(self): + self.image_processor_tester = LevitImageProcessingTester(self) + + @property + def image_processor_dict(self): + return self.image_processor_tester.prepare_image_processor_dict() + + def test_image_processor_properties(self): + image_processing = self.image_processing_class(**self.image_processor_dict) + self.assertTrue(hasattr(image_processing, "image_mean")) + self.assertTrue(hasattr(image_processing, "image_std")) + self.assertTrue(hasattr(image_processing, "do_normalize")) + self.assertTrue(hasattr(image_processing, "do_resize")) + self.assertTrue(hasattr(image_processing, "do_center_crop")) + self.assertTrue(hasattr(image_processing, "size")) + + def test_image_processor_from_dict_with_kwargs(self): + image_processor = self.image_processing_class.from_dict(self.image_processor_dict) + self.assertEqual(image_processor.size, {"shortest_edge": 18}) + self.assertEqual(image_processor.crop_size, {"height": 18, "width": 18}) + + image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42, crop_size=84) + self.assertEqual(image_processor.size, {"shortest_edge": 42}) + self.assertEqual(image_processor.crop_size, {"height": 84, "width": 84}) + + def test_batch_feature(self): + pass + + def test_call_pil(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PIL images + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False) + for image in image_inputs: + self.assertIsInstance(image, Image.Image) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_numpy(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random numpy tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, numpify=True) + for image in image_inputs: + self.assertIsInstance(image, np.ndarray) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + def test_call_pytorch(self): + # Initialize image_processing + image_processing = self.image_processing_class(**self.image_processor_dict) + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + for image in image_inputs: + self.assertIsInstance(image, torch.Tensor) + + # Test not batched input + encoded_images = image_processing(image_inputs[0], return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + 1, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) + + # Test batched + encoded_images = image_processing(image_inputs, return_tensors="pt").pixel_values + self.assertEqual( + encoded_images.shape, + ( + self.image_processor_tester.batch_size, + self.image_processor_tester.num_channels, + self.image_processor_tester.crop_size["height"], + self.image_processor_tester.crop_size["width"], + ), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_modeling_levit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_modeling_levit.py new file mode 100644 index 0000000000000000000000000000000000000000..18764a0090f53513e926a83ba4fc5771242c9d22 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/levit/test_modeling_levit.py @@ -0,0 +1,441 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LeViT model. """ + + +import inspect +import unittest +import warnings +from math import ceil, floor + +from packaging import version + +from transformers import LevitConfig +from transformers.file_utils import cached_property, is_torch_available, is_vision_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, require_vision, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + MODEL_MAPPING, + LevitForImageClassification, + LevitForImageClassificationWithTeacher, + LevitModel, + ) + from transformers.models.levit.modeling_levit import LEVIT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_vision_available(): + from PIL import Image + + from transformers import LevitFeatureExtractor + + +class LevitConfigTester(ConfigTester): + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + self.parent.assertTrue(hasattr(config, "hidden_sizes")) + self.parent.assertTrue(hasattr(config, "num_attention_heads")) + + +class LevitModelTester: + def __init__( + self, + parent, + batch_size=13, + image_size=64, + num_channels=3, + kernel_size=3, + stride=2, + padding=1, + patch_size=16, + hidden_sizes=[128, 256, 384], + num_attention_heads=[4, 6, 8], + depths=[2, 3, 4], + key_dim=[16, 16, 16], + drop_path_rate=0, + mlp_ratio=[2, 2, 2], + attention_ratio=[2, 2, 2], + initializer_range=0.02, + is_training=True, + use_labels=True, + num_labels=2, # Check + ): + self.parent = parent + self.batch_size = batch_size + self.image_size = image_size + self.num_channels = num_channels + self.kernel_size = kernel_size + self.stride = stride + self.padding = padding + self.hidden_sizes = hidden_sizes + self.num_attention_heads = num_attention_heads + self.depths = depths + self.key_dim = key_dim + self.drop_path_rate = drop_path_rate + self.patch_size = patch_size + self.attention_ratio = attention_ratio + self.mlp_ratio = mlp_ratio + self.initializer_range = initializer_range + self.down_ops = [ + ["Subsample", key_dim[0], hidden_sizes[0] // key_dim[0], 4, 2, 2], + ["Subsample", key_dim[0], hidden_sizes[1] // key_dim[0], 4, 2, 2], + ] + self.is_training = is_training + self.use_labels = use_labels + self.num_labels = num_labels + self.initializer_range = initializer_range + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]) + + labels = None + if self.use_labels: + labels = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + return config, pixel_values, labels + + def get_config(self): + return LevitConfig( + image_size=self.image_size, + num_channels=self.num_channels, + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + patch_size=self.patch_size, + hidden_sizes=self.hidden_sizes, + num_attention_heads=self.num_attention_heads, + depths=self.depths, + key_dim=self.key_dim, + drop_path_rate=self.drop_path_rate, + mlp_ratio=self.mlp_ratio, + attention_ratio=self.attention_ratio, + initializer_range=self.initializer_range, + down_ops=self.down_ops, + ) + + def create_and_check_model(self, config, pixel_values, labels): + model = LevitModel(config=config) + model.to(torch_device) + model.eval() + result = model(pixel_values) + image_size = (self.image_size, self.image_size) + height, width = image_size[0], image_size[1] + for _ in range(4): + height = floor(((height + 2 * self.padding - self.kernel_size) / self.stride) + 1) + width = floor(((width + 2 * self.padding - self.kernel_size) / self.stride) + 1) + self.parent.assertEqual( + result.last_hidden_state.shape, + (self.batch_size, ceil(height / 4) * ceil(width / 4), self.hidden_sizes[-1]), + ) + + def create_and_check_for_image_classification(self, config, pixel_values, labels): + config.num_labels = self.num_labels + model = LevitForImageClassification(config) + model.to(torch_device) + model.eval() + result = model(pixel_values, labels=labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + config, pixel_values, labels = config_and_inputs + inputs_dict = {"pixel_values": pixel_values} + return config, inputs_dict + + +@require_torch +class LevitModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + """ + Here we also overwrite some of the tests of test_modeling_common.py, as Levit does not use input_ids, inputs_embeds, + attention_mask and seq_length. + """ + + all_model_classes = ( + (LevitModel, LevitForImageClassification, LevitForImageClassificationWithTeacher) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": LevitModel, + "image-classification": (LevitForImageClassification, LevitForImageClassificationWithTeacher), + } + if is_torch_available() + else {} + ) + + test_pruning = False + test_torchscript = False + test_resize_embeddings = False + test_head_masking = False + has_attentions = False + + def setUp(self): + self.model_tester = LevitModelTester(self) + self.config_tester = ConfigTester(self, config_class=LevitConfig, has_text_modality=False, hidden_size=37) + + def test_config(self): + self.create_and_test_config_common_properties() + self.config_tester.create_and_test_config_to_json_string() + self.config_tester.create_and_test_config_to_json_file() + self.config_tester.create_and_test_config_from_and_save_pretrained() + self.config_tester.create_and_test_config_with_num_labels() + self.config_tester.check_config_can_be_init_without_params() + self.config_tester.check_config_arguments_init() + + def create_and_test_config_common_properties(self): + return + + @unittest.skip(reason="Levit does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Levit does not support input and output embeddings") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="Levit does not output attentions") + def test_attention_outputs(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.hidden_states + + expected_num_layers = len(self.model_tester.depths) + 1 + self.assertEqual(len(hidden_states), expected_num_layers) + + image_size = (self.model_tester.image_size, self.model_tester.image_size) + height, width = image_size[0], image_size[1] + for _ in range(4): + height = floor( + ( + (height + 2 * self.model_tester.padding - self.model_tester.kernel_size) + / self.model_tester.stride + ) + + 1 + ) + width = floor( + ( + (width + 2 * self.model_tester.padding - self.model_tester.kernel_size) + / self.model_tester.stride + ) + + 1 + ) + # verify the first hidden states (first block) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [ + height * width, + self.model_tester.hidden_sizes[0], + ], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + + if return_labels: + if model_class.__name__ == "LevitForImageClassificationWithTeacher": + del inputs_dict["labels"] + + return inputs_dict + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_for_image_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_image_classification(*config_and_inputs) + + # special case for LevitForImageClassificationWithTeacher model + def test_training(self): + if not self.model_tester.is_training: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + # LevitForImageClassificationWithTeacher supports inference-only + if ( + model_class in get_values(MODEL_MAPPING) + or model_class.__name__ == "LevitForImageClassificationWithTeacher" + ): + continue + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if not self.model_tester.is_training: + return + + config.use_cache = False + config.return_dict = True + + for model_class in self.all_model_classes: + if model_class in get_values(MODEL_MAPPING) or not model_class.supports_gradient_checkpointing: + continue + # LevitForImageClassificationWithTeacher supports inference-only + if model_class.__name__ == "LevitForImageClassificationWithTeacher": + continue + model = model_class(config) + model.gradient_checkpointing_enable() + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_problem_types(self): + parsed_torch_version_base = version.parse(version.parse(torch.__version__).base_version) + if parsed_torch_version_base.base_version.startswith("1.9"): + self.skipTest(reason="This test fails with PyTorch 1.9.x: some CUDA issue") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + problem_types = [ + {"title": "multi_label_classification", "num_labels": 2, "dtype": torch.float}, + {"title": "single_label_classification", "num_labels": 1, "dtype": torch.long}, + {"title": "regression", "num_labels": 1, "dtype": torch.float}, + ] + + for model_class in self.all_model_classes: + if ( + model_class + not in [ + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING), + ] + or model_class.__name__ == "LevitForImageClassificationWithTeacher" + ): + continue + + for problem_type in problem_types: + with self.subTest(msg=f"Testing {model_class} with {problem_type['title']}"): + config.problem_type = problem_type["title"] + config.num_labels = problem_type["num_labels"] + + model = model_class(config) + model.to(torch_device) + model.train() + + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + + if problem_type["num_labels"] > 1: + inputs["labels"] = inputs["labels"].unsqueeze(1).repeat(1, problem_type["num_labels"]) + + inputs["labels"] = inputs["labels"].to(problem_type["dtype"]) + + # This tests that we do not trigger the warning form PyTorch "Using a target size that is different + # to the input size. This will likely lead to incorrect results due to broadcasting. Please ensure + # they have the same size." which is a symptom something in wrong for the regression problem. + # See https://github.com/huggingface/transformers/issues/11780 + with warnings.catch_warnings(record=True) as warning_list: + loss = model(**inputs).loss + for w in warning_list: + if "Using a target size that is different to the input size" in str(w.message): + raise ValueError( + f"Something is going wrong in the regression problem: intercepted {w.message}" + ) + + loss.backward() + + @slow + def test_model_from_pretrained(self): + for model_name in LEVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = LevitModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_torch +@require_vision +class LevitModelIntegrationTest(unittest.TestCase): + @cached_property + def default_feature_extractor(self): + return LevitFeatureExtractor.from_pretrained(LEVIT_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + + @slow + def test_inference_image_classification_head(self): + model = LevitForImageClassificationWithTeacher.from_pretrained(LEVIT_PRETRAINED_MODEL_ARCHIVE_LIST[0]).to( + torch_device + ) + + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(images=image, return_tensors="pt").to(torch_device) + + # forward pass + with torch.no_grad(): + outputs = model(**inputs) + + # verify the logits + expected_shape = torch.Size((1, 1000)) + self.assertEqual(outputs.logits.shape, expected_shape) + + expected_slice = torch.tensor([1.0448, -0.3745, -1.8317]).to(torch_device) + + self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lilt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lilt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_modeling_llama.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_modeling_llama.py new file mode 100644 index 0000000000000000000000000000000000000000..113f74d309763954a16e85e58de86e7c92654afa --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_modeling_llama.py @@ -0,0 +1,334 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LLaMA model. """ + + +import unittest + +from transformers import LlamaConfig, is_torch_available +from transformers.testing_utils import require_torch, torch_device + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import LlamaForCausalLM, LlamaForSequenceClassification, LlamaModel + + +class LlamaModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_input_mask=True, + use_token_type_ids=False, + use_labels=True, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_input_mask = use_input_mask + self.use_token_type_ids = use_token_type_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.scope = scope + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = self.get_config() + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def get_config(self): + return LlamaConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + ) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = LlamaModel(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_model_as_decoder( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.add_cross_attention = True + model = LlamaModel(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + result = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + ) + result = model(input_ids, attention_mask=input_mask) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_causal_lm( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + model = LlamaForCausalLM(config=config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=input_mask, labels=token_labels) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + encoder_hidden_states, + encoder_attention_mask, + ): + config.is_decoder = True + config.add_cross_attention = True + model = LlamaForCausalLM(config=config) + model.to(torch_device) + model.eval() + + # first forward pass + outputs = model( + input_ids, + attention_mask=input_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + use_cache=True, + ) + past_key_values = outputs.past_key_values + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([input_mask, next_mask], dim=-1) + + output_from_no_past = model( + next_input_ids, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + output_hidden_states=True, + )["hidden_states"][0] + output_from_past = model( + next_tokens, + attention_mask=next_attention_mask, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + past_key_values=past_key_values, + output_hidden_states=True, + )["hidden_states"][0] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask} + return config, inputs_dict + + +@require_torch +class LlamaModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (LlamaModel, LlamaForCausalLM, LlamaForSequenceClassification) if is_torch_available() else () + all_generative_model_classes = (LlamaForCausalLM,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "feature-extraction": LlamaModel, + "text-classification": LlamaForSequenceClassification, + "text-generation": LlamaForCausalLM, + "zero-shot": LlamaForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_headmasking = False + test_pruning = False + + def setUp(self): + self.model_tester = LlamaModelTester(self) + self.config_tester = ConfigTester(self, config_class=LlamaConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_various_embeddings(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for type in ["absolute", "relative_key", "relative_key_query"]: + config_and_inputs[0].position_embedding_type = type + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_llama_sequence_classification_model(self): + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.num_labels = 3 + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + sequence_labels = ids_tensor([self.model_tester.batch_size], self.model_tester.type_sequence_label_size) + model = LlamaForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, labels=sequence_labels) + self.assertEqual(result.logits.shape, (self.model_tester.batch_size, self.model_tester.num_labels)) + + def test_llama_sequence_classification_model_for_single_label(self): + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.num_labels = 3 + config.problem_type = "single_label_classification" + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + sequence_labels = ids_tensor([self.model_tester.batch_size], self.model_tester.type_sequence_label_size) + model = LlamaForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, labels=sequence_labels) + self.assertEqual(result.logits.shape, (self.model_tester.batch_size, self.model_tester.num_labels)) + + def test_llama_sequence_classification_model_for_multi_label(self): + config, input_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.num_labels = 3 + config.problem_type = "multi_label_classification" + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + sequence_labels = ids_tensor( + [self.model_tester.batch_size, config.num_labels], self.model_tester.type_sequence_label_size + ).to(torch.float) + model = LlamaForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model(input_ids, attention_mask=attention_mask, labels=sequence_labels) + self.assertEqual(result.logits.shape, (self.model_tester.batch_size, self.model_tester.num_labels)) + + @unittest.skip("LLaMA buffers include complex numbers, which breaks this test") + def test_save_load_fast_init_from_base(self): + pass diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_tokenization_llama.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_tokenization_llama.py new file mode 100644 index 0000000000000000000000000000000000000000..6ce1bb44c03db20406a8bf3e2471231950abe6f2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/llama/test_tokenization_llama.py @@ -0,0 +1,459 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import shutil +import tempfile +import unittest + +from datasets import load_dataset + +from transformers import ( + SPIECE_UNDERLINE, + AddedToken, + LlamaTokenizer, + LlamaTokenizerFast, + is_torch_available, +) +from transformers.convert_slow_tokenizer import convert_slow_tokenizer +from transformers.testing_utils import ( + get_tests_dir, + nested_simplify, + require_sentencepiece, + require_tokenizers, + require_torch, + slow, +) + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/test_sentencepiece.model") + + +if is_torch_available(): + pass + + +@require_sentencepiece +@require_tokenizers +class LlamaTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LlamaTokenizer + test_rust_tokenizer = False + test_sentencepiece = True + from_pretrained_kwargs = {} + + def setUp(self): + super().setUp() + + # We have a SentencePiece fixture for testing + tokenizer = LlamaTokenizer(SAMPLE_VOCAB, keep_accents=True) + tokenizer.pad_token = tokenizer.eos_token + tokenizer.save_pretrained(self.tmpdirname) + + def test_full_tokenizer(self): + tokenizer = LlamaTokenizer(SAMPLE_VOCAB, keep_accents=True) + + tokens = tokenizer.tokenize("This is a test") + self.assertListEqual(tokens, ["▁This", "▁is", "▁a", "▁t", "est"]) + + self.assertListEqual( + tokenizer.convert_tokens_to_ids(tokens), + [285, 46, 10, 170, 382], + ) + + tokens = tokenizer.tokenize("I was born in 92000, and this is falsé.") + self.assertListEqual( + tokens, + [ + SPIECE_UNDERLINE + "I", + SPIECE_UNDERLINE + "was", + SPIECE_UNDERLINE + "b", + "or", + "n", + SPIECE_UNDERLINE + "in", + SPIECE_UNDERLINE + "", + "9", + "2", + "0", + "0", + "0", + ",", + SPIECE_UNDERLINE + "and", + SPIECE_UNDERLINE + "this", + SPIECE_UNDERLINE + "is", + SPIECE_UNDERLINE + "f", + "al", + "s", + "é", + ".", + ], + ) + ids = tokenizer.convert_tokens_to_ids(tokens) + self.assertListEqual( + ids, + [8, 21, 84, 55, 24, 19, 7, 0, 602, 347, 347, 347, 3, 12, 66, 46, 72, 80, 6, 0, 4], + ) + + back_tokens = tokenizer.convert_ids_to_tokens(ids) + self.assertListEqual( + back_tokens, + [ + SPIECE_UNDERLINE + "I", + SPIECE_UNDERLINE + "was", + SPIECE_UNDERLINE + "b", + "or", + "n", + SPIECE_UNDERLINE + "in", + SPIECE_UNDERLINE + "", + "", + "2", + "0", + "0", + "0", + ",", + SPIECE_UNDERLINE + "and", + SPIECE_UNDERLINE + "this", + SPIECE_UNDERLINE + "is", + SPIECE_UNDERLINE + "f", + "al", + "s", + "", + ".", + ], + ) + + @unittest.skip("Let's wait for the fast tokenizer!") + def test_save_pretrained(self): + self.tokenizers_list += (self.rust_tokenizer_class, "hf-internal-testing/llama-tokenizer", {}) + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it save with the same files + the tokenizer.json file for the fast one + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + tokenizer_r_files = tuple(f for f in tokenizer_r_files if "tokenizer.json" not in f) + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=True + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=True) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it save with the same files + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=False + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=False) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it saved the tokenizer.json file + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + @require_torch + def test_batch_tokenization(self): + if not self.test_seq2seq: + return + + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Longer text that will definitely require truncation. + text = [ + " UN Chief Says There Is No Military Solution in Syria", + " Secretary-General Ban Ki-moon says his response to Russia's stepped up military support for" + " Syria is that 'there is no military solution' to the nearly five-year conflict and more weapons" + " will only worsen the violence and misery for millions of people.", + ] + try: + batch = tokenizer( + text=text, + max_length=3, + max_target_length=10, + return_tensors="pt", + ) + except NotImplementedError: + return + self.assertEqual(batch.input_ids.shape[1], 3) + # max_target_length will default to max_length if not specified + batch = tokenizer(text, max_length=3, return_tensors="pt") + self.assertEqual(batch.input_ids.shape[1], 3) + + batch_encoder_only = tokenizer(text=text, max_length=3, max_target_length=10, return_tensors="pt") + self.assertEqual(batch_encoder_only.input_ids.shape[1], 3) + self.assertEqual(batch_encoder_only.attention_mask.shape[1], 3) + self.assertNotIn("decoder_input_ids", batch_encoder_only) + + @unittest.skip("Unfortunately way too slow to build a BPE with SentencePiece.") + def test_save_slow_from_fast_and_reload_fast(self): + pass + + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + r_output = tokenizer_r.encode("Hey this is a token") + + special_token_id = tokenizer_r.encode("", add_special_tokens=False)[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_cr = self.rust_tokenizer_class.from_pretrained( + pretrained_name, + additional_special_tokens=added_tokens, + **kwargs, # , from_slow=True <- unfortunately too slow to convert + ) + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + p_output = tokenizer_p.encode("Hey this is a token") + + cr_output = tokenizer_cr.encode("Hey this is a token") + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + @slow + def test_tokenizer_integration(self): + # fmt: off + expected_encoding = {'input_ids': [[1, 4103, 689, 414, 313, 24784, 368, 2998, 408, 282, 3637, 25350, 29899, 9067, 414, 322, 282, 3637, 25350, 29899, 1457, 3018, 1312, 29899, 2151, 29897, 8128, 2498, 29899, 15503, 4220, 6956, 1973, 313, 13635, 29911, 29892, 402, 7982, 29899, 29906, 29892, 1528, 13635, 29911, 29874, 29892, 1060, 26369, 29892, 6652, 309, 29933, 814, 29892, 1060, 29931, 6779, 11410, 363, 18385, 17088, 7634, 11235, 313, 25103, 29965, 29897, 322, 18385, 17088, 28203, 313, 25103, 29954, 29897, 411, 975, 29871, 29941, 29906, 29974, 758, 3018, 1312, 4733, 297, 29871, 29896, 29900, 29900, 29974, 10276, 322, 6483, 1006, 3372, 3097, 1546, 435, 1165, 29892, 10772, 29911, 25350, 322, 323, 6073, 17907, 29889], [1, 350, 20161, 338, 8688, 304, 758, 29899, 14968, 6483, 21000, 8684, 284, 22540, 515, 443, 29880, 24025, 1426, 491, 14002, 368, 4195, 292, 373, 1716, 2175, 322, 1492, 3030, 297, 599, 15359, 29889], [1, 450, 4996, 17354, 1701, 29916, 432, 17204, 975, 278, 17366, 11203, 29889]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]} + # fmt: on + + self.tokenizer_integration_test_util( + expected_encoding=expected_encoding, + model_name="hf-internal-testing/llama-tokenizer", + revision="0984d03108b1a041ed679bd253b6519b7e1a4778", + padding=False, + ) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class LlamaIntegrationTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + checkpoint_name = "hf-internal-testing/llama-tokenizer" + cls.tokenizer: LlamaTokenizer = LlamaTokenizer.from_pretrained(checkpoint_name) + cls.rust_tokenizer = LlamaTokenizerFast.from_pretrained(checkpoint_name) + return cls + + @require_torch + def integration_tests(self): + inputs = self.tokenizer( + ["The following string should be properly encoded: Hello.", "But ird and ปี ird ด"], + return_tensors="pt", + ) + + self.assertEqual( + nested_simplify(inputs), + { + "input_ids": [ + [1, 450, 1494, 1347, 881, 367, 6284, 18511, 29901, 15043, 29889], + [1, 1205, 29871, 1823, 322, 29871, 31010, 30691, 1678, 1823, 1678, 30718], + ], + "attention_mask": [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], + }, + ) + + @slow + def test_conversion(self): + # This is excruciatingly slow since it has to recreate the entire merge + # list from the original vocabulary in spm + self.rust_tokenizer.save_pretrained("./out") + with tempfile.TemporaryDirectory() as dirname: + self.rust_tokenizer.save_pretrained(dirname) + + with open(os.path.join(dirname, "tokenizer.json"), "r") as f: + old_serialized = f.read() + + new_tokenizer = convert_slow_tokenizer(self.tokenizer) + with tempfile.NamedTemporaryFile() as f: + new_tokenizer.save(f.name) + # Re-opening since `f` is in bytes. + new_serialized = open(f.name, "r").read() + with open("out_tokenizer.json", "w") as g: + g.write(new_serialized) + + self.assertEqual(old_serialized, new_serialized) + + def test_simple_encode_decode(self): + pyth_tokenizer = self.tokenizer + rust_tokenizer = self.rust_tokenizer + + self.assertEqual(pyth_tokenizer.encode("This is a test"), [1, 910, 338, 263, 1243]) + self.assertEqual(rust_tokenizer.encode("This is a test"), [1, 910, 338, 263, 1243]) + self.assertEqual(pyth_tokenizer.decode([1, 910, 338, 263, 1243], skip_special_tokens=True), "This is a test") + self.assertEqual(rust_tokenizer.decode([1, 910, 338, 263, 1243], skip_special_tokens=True), "This is a test") + + # bytefallback showcase + self.assertEqual(pyth_tokenizer.encode("生活的真谛是"), [1, 29871, 30486, 31704, 30210, 30848, 235, 179, 158, 30392]) + self.assertEqual(rust_tokenizer.encode("生活的真谛是"), [1, 29871, 30486, 31704, 30210, 30848, 235, 179, 158, 30392]) + self.assertEqual( + pyth_tokenizer.decode( + [1, 29871, 30486, 31704, 30210, 30848, 235, 179, 158, 30392], skip_special_tokens=True + ), + "生活的真谛是", + ) + self.assertEqual( + rust_tokenizer.decode( + [1, 29871, 30486, 31704, 30210, 30848, 235, 179, 158, 30392], skip_special_tokens=True + ), + "生活的真谛是", + ) + + # Inner spaces showcase + self.assertEqual(pyth_tokenizer.encode("Hi Hello"), [1, 6324, 29871, 15043]) + self.assertEqual(rust_tokenizer.encode("Hi Hello"), [1, 6324, 29871, 15043]) + self.assertEqual(pyth_tokenizer.decode([1, 6324, 29871, 15043], skip_special_tokens=True), "Hi Hello") + self.assertEqual(rust_tokenizer.decode([1, 6324, 29871, 15043], skip_special_tokens=True), "Hi Hello") + + self.assertEqual(pyth_tokenizer.encode("Hi Hello"), [1, 6324, 259, 15043]) + self.assertEqual(rust_tokenizer.encode("Hi Hello"), [1, 6324, 259, 15043]) + self.assertEqual(pyth_tokenizer.decode([1, 6324, 259, 15043], skip_special_tokens=True), "Hi Hello") + self.assertEqual(rust_tokenizer.decode([1, 6324, 259, 15043], skip_special_tokens=True), "Hi Hello") + + self.assertEqual(pyth_tokenizer.encode(""), [1]) + self.assertEqual(rust_tokenizer.encode(""), [1]) + + self.assertEqual(pyth_tokenizer.encode(" "), [1, 259]) + self.assertEqual(rust_tokenizer.encode(" "), [1, 259]) + + self.assertEqual(pyth_tokenizer.encode(" "), [1, 1678]) + self.assertEqual(rust_tokenizer.encode(" "), [1, 1678]) + + self.assertEqual(pyth_tokenizer.encode(" Hello"), [1, 29871, 15043]) + self.assertEqual(rust_tokenizer.encode(" Hello"), [1, 29871, 15043]) + + def test_no_differences_showcase(self): + pyth_tokenizer = self.tokenizer + rust_tokenizer = self.rust_tokenizer + self.assertEqual(pyth_tokenizer.encode(""), [1]) + self.assertEqual(rust_tokenizer.encode(""), [1]) + + self.assertEqual(pyth_tokenizer.encode(" "), [1, 259]) + self.assertEqual(rust_tokenizer.encode(" "), [1, 259]) + + self.assertEqual(pyth_tokenizer.encode(" "), [1, 1678]) + self.assertEqual(rust_tokenizer.encode(" "), [1, 1678]) + + self.assertEqual(pyth_tokenizer.encode(" Hello"), [1, 29871, 15043]) + self.assertEqual(rust_tokenizer.encode(" Hello"), [1, 29871, 15043]) + + self.assertEqual(pyth_tokenizer.encode(""), [1, 1]) + self.assertEqual(rust_tokenizer.encode(""), [1, 1]) + + def test_no_differences_decode(self): + pyth_tokenizer = self.tokenizer + rust_tokenizer = self.rust_tokenizer + + self.assertEqual(pyth_tokenizer.decode([869]), ".") + self.assertEqual(rust_tokenizer.decode([869]), ".") + + self.assertEqual(pyth_tokenizer.decode([30112, 869]), "ا .") + self.assertEqual(rust_tokenizer.decode([30112, 869]), "ا .") + + def test_no_differences_special_tokens(self): + pyth_tokenizer = self.tokenizer + rust_tokenizer = self.rust_tokenizer + self.assertEqual(pyth_tokenizer.encode(""), [1]) + self.assertEqual(rust_tokenizer.encode(""), [1]) + + self.assertEqual(pyth_tokenizer.encode(""), [1, 1]) + self.assertEqual(rust_tokenizer.encode(""), [1, 1]) + + @unittest.skipIf( + os.getenv("RUN_TOKENIZER_INTEGRATION", "0") == "0", + "RUN_TOKENIZER_INTEGRATION=1 to run tokenizer integration tests", + ) + def test_integration_test_xnli(self): + import tqdm + + pyth_tokenizer = self.tokenizer + rust_tokenizer = self.rust_tokenizer + + dataset = load_dataset("code_x_glue_ct_code_to_text", "go") + for item in tqdm.tqdm(dataset["validation"]): + string = item["code"] + encoded1 = pyth_tokenizer.encode(string) + encoded2 = rust_tokenizer.encode(string) + + self.assertEqual(encoded1, encoded2) + + decoded1 = pyth_tokenizer.decode(encoded1, skip_special_tokens=True) + decoded2 = rust_tokenizer.decode(encoded2, skip_special_tokens=True) + + self.assertEqual(decoded1, decoded2) + + dataset = load_dataset("xnli", "all_languages") + + for item in tqdm.tqdm(dataset["train"]): + for string in item["premise"].values(): + encoded1 = pyth_tokenizer.encode(string) + encoded2 = rust_tokenizer.encode(string) + + self.assertEqual(encoded1, encoded2) + + decoded1 = pyth_tokenizer.decode(encoded1, skip_special_tokens=True) + decoded2 = rust_tokenizer.decode(encoded2, skip_special_tokens=True) + + self.assertEqual(decoded1, decoded2) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_modeling_tf_longformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_modeling_tf_longformer.py new file mode 100644 index 0000000000000000000000000000000000000000..b5452bc80ac5020246e28d4502d56c9d6f71695c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_modeling_tf_longformer.py @@ -0,0 +1,728 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers import is_tf_available +from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow, tooslow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers import ( + LongformerConfig, + TFLongformerForMaskedLM, + TFLongformerForMultipleChoice, + TFLongformerForQuestionAnswering, + TFLongformerForSequenceClassification, + TFLongformerForTokenClassification, + TFLongformerModel, + TFLongformerSelfAttention, + ) + from transformers.tf_utils import shape_list + + +class TFLongformerModelTester: + def __init__( + self, + parent, + ): + self.parent = parent + self.batch_size = 13 + self.seq_length = 7 + self.is_training = True + self.use_input_mask = True + self.use_token_type_ids = True + self.use_labels = True + self.vocab_size = 99 + self.hidden_size = 32 + self.num_hidden_layers = 5 + self.num_attention_heads = 4 + self.intermediate_size = 37 + self.hidden_act = "gelu" + self.hidden_dropout_prob = 0.1 + self.attention_probs_dropout_prob = 0.1 + self.max_position_embeddings = 512 + self.type_vocab_size = 16 + self.type_sequence_label_size = 2 + self.initializer_range = 0.02 + self.num_labels = 3 + self.num_choices = 4 + self.scope = None + self.attention_window = 4 + + # `ModelTesterMixin.test_attention_outputs` is expecting attention tensors to be of size + # [num_attention_heads, encoder_seq_length, encoder_key_length], but TFLongformerSelfAttention + # returns attention of shape [num_attention_heads, encoder_seq_length, self.attention_window + 1] + # because its local attention only attends to `self.attention_window` and one before and one after + self.key_length = self.attention_window + 2 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + input_mask = None + if self.use_input_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + sequence_labels = None + token_labels = None + choice_labels = None + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + config = LongformerConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + attention_window=self.attention_window, + ) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + def create_and_check_attention_mask_determinism( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + model = TFLongformerModel(config=config) + + attention_mask = tf.ones(input_ids.shape, dtype=tf.int64) + output_with_mask = model(input_ids, attention_mask=attention_mask)[0] + output_without_mask = model(input_ids)[0] + tf.debugging.assert_near(output_with_mask[0, 0, :5], output_without_mask[0, 0, :5], rtol=1e-4) + + def create_and_check_model( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.return_dict = True + model = TFLongformerModel(config=config) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids) + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + + self.parent.assertListEqual( + shape_list(result.last_hidden_state), [self.batch_size, self.seq_length, self.hidden_size] + ) + self.parent.assertListEqual(shape_list(result.pooler_output), [self.batch_size, self.hidden_size]) + + def create_and_check_model_with_global_attention_mask( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.return_dict = True + model = TFLongformerModel(config=config) + half_input_mask_length = shape_list(input_mask)[-1] // 2 + global_attention_mask = tf.concat( + [ + tf.zeros_like(input_mask)[:, :half_input_mask_length], + tf.ones_like(input_mask)[:, half_input_mask_length:], + ], + axis=-1, + ) + + result = model( + input_ids, + attention_mask=input_mask, + global_attention_mask=global_attention_mask, + token_type_ids=token_type_ids, + ) + result = model(input_ids, token_type_ids=token_type_ids, global_attention_mask=global_attention_mask) + result = model(input_ids, global_attention_mask=global_attention_mask) + + self.parent.assertListEqual( + shape_list(result.last_hidden_state), [self.batch_size, self.seq_length, self.hidden_size] + ) + self.parent.assertListEqual(shape_list(result.pooler_output), [self.batch_size, self.hidden_size]) + + def create_and_check_for_masked_lm( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.return_dict = True + model = TFLongformerForMaskedLM(config=config) + result = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels) + self.parent.assertListEqual(shape_list(result.logits), [self.batch_size, self.seq_length, self.vocab_size]) + + def create_and_check_for_question_answering( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.return_dict = True + model = TFLongformerForQuestionAnswering(config=config) + result = model( + input_ids, + attention_mask=input_mask, + token_type_ids=token_type_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + + self.parent.assertListEqual(shape_list(result.start_logits), [self.batch_size, self.seq_length]) + self.parent.assertListEqual(shape_list(result.end_logits), [self.batch_size, self.seq_length]) + + def create_and_check_for_sequence_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFLongformerForSequenceClassification(config=config) + output = model( + input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels + ).logits + self.parent.assertListEqual(shape_list(output), [self.batch_size, self.num_labels]) + + def create_and_check_for_token_classification( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_labels = self.num_labels + model = TFLongformerForTokenClassification(config=config) + output = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=token_labels).logits + self.parent.assertListEqual(shape_list(output), [self.batch_size, self.seq_length, self.num_labels]) + + def create_and_check_for_multiple_choice( + self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + ): + config.num_choices = self.num_choices + model = TFLongformerForMultipleChoice(config=config) + multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1)) + multiple_choice_token_type_ids = tf.tile(tf.expand_dims(token_type_ids, 1), (1, self.num_choices, 1)) + multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1)) + output = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_input_mask, + global_attention_mask=multiple_choice_input_mask, + token_type_ids=multiple_choice_token_type_ids, + labels=choice_labels, + ).logits + self.parent.assertListEqual(list(output.shape), [self.batch_size, self.num_choices]) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + # global attention mask has to be partly defined + # to trace all weights + global_attention_mask = tf.concat( + [tf.zeros_like(input_ids)[:, :-1], tf.ones_like(input_ids)[:, -1:]], + axis=-1, + ) + + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + "global_attention_mask": global_attention_mask, + } + return config, inputs_dict + + def prepare_config_and_inputs_for_question_answering(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + token_type_ids, + input_mask, + sequence_labels, + token_labels, + choice_labels, + ) = config_and_inputs + + # Replace sep_token_id by some random id + input_ids = tf.where(input_ids == config.sep_token_id, 0, input_ids) + # Make sure there are exactly three sep_token_id + input_ids = tf.concat([input_ids[:, :-3], tf.ones_like(input_ids)[:, -3:] * config.sep_token_id], axis=-1) + input_mask = tf.ones_like(input_ids) + + return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels + + +@require_tf +class TFLongformerModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + TFLongformerModel, + TFLongformerForMaskedLM, + TFLongformerForQuestionAnswering, + TFLongformerForSequenceClassification, + TFLongformerForMultipleChoice, + TFLongformerForTokenClassification, + ) + if is_tf_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": TFLongformerModel, + "fill-mask": TFLongformerForMaskedLM, + "question-answering": TFLongformerForQuestionAnswering, + "text-classification": TFLongformerForSequenceClassification, + "token-classification": TFLongformerForTokenClassification, + "zero-shot": TFLongformerForSequenceClassification, + } + if is_tf_available() + else {} + ) + test_head_masking = False + test_onnx = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if ( + pipeline_test_casse_name == "QAPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `QAPipelineTests` fails for a few models when the slower tokenizer are used. + # (The slower tokenizers were never used for pipeline tests before the pipeline testing rework) + # TODO: check (and possibly fix) the `QAPipelineTests` with slower tokenizer + return True + + return False + + def setUp(self): + self.model_tester = TFLongformerModelTester(self) + self.config_tester = ConfigTester(self, config_class=LongformerConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model_attention_mask_determinism(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_attention_mask_determinism(*config_and_inputs) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_global_attention_mask(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model_with_global_attention_mask(*config_and_inputs) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_question_answering() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + @tooslow + def test_saved_model_creation(self): + pass + + def test_xla_mode(self): + # TODO JP: Make Longformer XLA compliant + pass + + +@require_tf +@require_sentencepiece +@require_tokenizers +class TFLongformerModelIntegrationTest(unittest.TestCase): + def _get_hidden_states(self): + return tf.convert_to_tensor( + [ + [ + [ + 4.98332758e-01, + 2.69175139e00, + -7.08081422e-03, + 1.04915401e00, + -1.83476661e00, + 7.67220476e-01, + 2.98580543e-01, + 2.84803992e-02, + ], + [ + -7.58357372e-01, + 4.20635998e-01, + -4.04739919e-02, + 1.59924145e-01, + 2.05135748e00, + -1.15997978e00, + 5.37166397e-01, + 2.62873606e-01, + ], + [ + -1.69438001e00, + 4.17574660e-01, + -1.49196962e00, + -1.76483717e00, + -1.94566312e-01, + -1.71183858e00, + 7.72903565e-01, + -1.11557056e00, + ], + [ + 5.44028163e-01, + 2.05466114e-01, + -3.63045868e-01, + 2.41865062e-01, + 3.20348382e-01, + -9.05611176e-01, + -1.92690727e-01, + -1.19917547e00, + ], + ] + ], + dtype=tf.float32, + ) + + def test_diagonalize(self): + hidden_states = self._get_hidden_states() + hidden_states = tf.reshape(hidden_states, (1, 8, 4)) # set seq length = 8, hidden dim = 4 + chunked_hidden_states = TFLongformerSelfAttention._chunk(hidden_states, window_overlap=2) + window_overlap_size = shape_list(chunked_hidden_states)[2] + self.assertTrue(window_overlap_size == 4) + + padded_hidden_states = TFLongformerSelfAttention._pad_and_diagonalize(chunked_hidden_states) + + self.assertTrue( + shape_list(padded_hidden_states)[-1] == shape_list(chunked_hidden_states)[-1] + window_overlap_size - 1 + ) + + # first row => [0.4983, 2.6918, -0.0071, 1.0492, 0.0000, 0.0000, 0.0000] + tf.debugging.assert_near(padded_hidden_states[0, 0, 0, :4], chunked_hidden_states[0, 0, 0], rtol=1e-3) + tf.debugging.assert_near(padded_hidden_states[0, 0, 0, 4:], tf.zeros((3,), dtype=tf.float32), rtol=1e-3) + + # last row => [0.0000, 0.0000, 0.0000, 2.0514, -1.1600, 0.5372, 0.2629] + tf.debugging.assert_near(padded_hidden_states[0, 0, -1, 3:], chunked_hidden_states[0, 0, -1], rtol=1e-3) + tf.debugging.assert_near(padded_hidden_states[0, 0, -1, :3], tf.zeros((3,), dtype=tf.float32), rtol=1e-3) + + def test_pad_and_transpose_last_two_dims(self): + hidden_states = self._get_hidden_states() + self.assertEqual(shape_list(hidden_states), [1, 4, 8]) + + # pad along seq length dim + paddings = tf.constant([[0, 0], [0, 0], [0, 1], [0, 0]], dtype=tf.int64) + + hidden_states = TFLongformerSelfAttention._chunk(hidden_states, window_overlap=2) + padded_hidden_states = TFLongformerSelfAttention._pad_and_transpose_last_two_dims(hidden_states, paddings) + self.assertTrue(shape_list(padded_hidden_states) == [1, 1, 8, 5]) + + expected_added_dim = tf.zeros((5,), dtype=tf.float32) + tf.debugging.assert_near(expected_added_dim, padded_hidden_states[0, 0, -1, :], rtol=1e-6) + tf.debugging.assert_near( + hidden_states[0, 0, -1, :], tf.reshape(padded_hidden_states, (1, -1))[0, 24:32], rtol=1e-6 + ) + + def test_mask_invalid_locations(self): + hidden_states = self._get_hidden_states() + batch_size = 1 + seq_length = 8 + hidden_size = 4 + hidden_states = tf.reshape(hidden_states, (batch_size, seq_length, hidden_size)) + hidden_states = TFLongformerSelfAttention._chunk(hidden_states, window_overlap=2) + + hid_states_1 = TFLongformerSelfAttention._mask_invalid_locations(hidden_states, 1) + hid_states_2 = TFLongformerSelfAttention._mask_invalid_locations(hidden_states, 2) + hid_states_3 = TFLongformerSelfAttention._mask_invalid_locations(hidden_states[:, :, :, :3], 2) + hid_states_4 = TFLongformerSelfAttention._mask_invalid_locations(hidden_states[:, :, 2:, :], 2) + + self.assertTrue(tf.math.reduce_sum(tf.cast(tf.math.is_inf(hid_states_1), tf.int64)) == 8) + self.assertTrue(tf.math.reduce_sum(tf.cast(tf.math.is_inf(hid_states_2), tf.int64)) == 24) + self.assertTrue(tf.math.reduce_sum(tf.cast(tf.math.is_inf(hid_states_3), tf.int64)) == 24) + self.assertTrue(tf.math.reduce_sum(tf.cast(tf.math.is_inf(hid_states_4), tf.int64)) == 12) + + def test_chunk(self): + hidden_states = self._get_hidden_states() + batch_size = 1 + seq_length = 8 + hidden_size = 4 + hidden_states = tf.reshape(hidden_states, (batch_size, seq_length, hidden_size)) + + chunked_hidden_states = TFLongformerSelfAttention._chunk(hidden_states, window_overlap=2) + + # expected slices across chunk and seq length dim + expected_slice_along_seq_length = tf.convert_to_tensor([0.4983, -0.7584, -1.6944], dtype=tf.float32) + expected_slice_along_chunk = tf.convert_to_tensor([0.4983, -1.8348, -0.7584, 2.0514], dtype=tf.float32) + + self.assertTrue(shape_list(chunked_hidden_states) == [1, 3, 4, 4]) + tf.debugging.assert_near( + chunked_hidden_states[0, :, 0, 0], expected_slice_along_seq_length, rtol=1e-3, atol=1e-4 + ) + tf.debugging.assert_near(chunked_hidden_states[0, 0, :, 0], expected_slice_along_chunk, rtol=1e-3, atol=1e-4) + + def test_layer_local_attn(self): + model = TFLongformerModel.from_pretrained("patrickvonplaten/longformer-random-tiny") + layer = model.longformer.encoder.layer[0].attention.self_attention + hidden_states = self._get_hidden_states() + batch_size, seq_length, hidden_size = hidden_states.shape + + attention_mask = tf.zeros((batch_size, seq_length), dtype=tf.float32) + is_index_global_attn = tf.math.greater(attention_mask, 1) + is_global_attn = tf.math.reduce_any(is_index_global_attn) + + attention_mask = tf.where(tf.range(4)[None, :, None, None] > 1, -10000.0, attention_mask[:, :, None, None]) + is_index_masked = tf.math.less(attention_mask[:, :, 0, 0], 0) + + layer_head_mask = None + + output_hidden_states = layer( + [hidden_states, attention_mask, layer_head_mask, is_index_masked, is_index_global_attn, is_global_attn] + )[0] + + expected_slice = tf.convert_to_tensor( + [0.00188, 0.012196, -0.017051, -0.025571, -0.02996, 0.017297, -0.011521, 0.004848], dtype=tf.float32 + ) + + self.assertEqual(output_hidden_states.shape, (1, 4, 8)) + tf.debugging.assert_near(output_hidden_states[0, 1], expected_slice, rtol=1e-3, atol=1e-4) + + def test_layer_global_attn(self): + model = TFLongformerModel.from_pretrained("patrickvonplaten/longformer-random-tiny") + layer = model.longformer.encoder.layer[0].attention.self_attention + hidden_states = self._get_hidden_states() + + hidden_states = tf.concat([self._get_hidden_states(), self._get_hidden_states() - 0.5], axis=0) + batch_size, seq_length, hidden_size = hidden_states.shape + + # create attn mask + attention_mask_1 = tf.zeros((1, 1, 1, seq_length), dtype=tf.float32) + attention_mask_2 = tf.zeros((1, 1, 1, seq_length), dtype=tf.float32) + + attention_mask_1 = tf.where(tf.range(4)[None, :, None, None] > 1, 10000.0, attention_mask_1) + attention_mask_1 = tf.where(tf.range(4)[None, :, None, None] > 2, -10000.0, attention_mask_1) + attention_mask_2 = tf.where(tf.range(4)[None, :, None, None] > 0, 10000.0, attention_mask_2) + attention_mask = tf.concat([attention_mask_1, attention_mask_2], axis=0) + + is_index_masked = tf.math.less(attention_mask[:, :, 0, 0], 0) + is_index_global_attn = tf.math.greater(attention_mask[:, :, 0, 0], 0) + is_global_attn = tf.math.reduce_any(is_index_global_attn) + + layer_head_mask = None + + output_hidden_states = layer( + [ + hidden_states, + -tf.math.abs(attention_mask), + layer_head_mask, + is_index_masked, + is_index_global_attn, + is_global_attn, + ] + )[0] + + self.assertEqual(output_hidden_states.shape, (2, 4, 8)) + expected_slice_0 = tf.convert_to_tensor( + [-0.06508, -0.039306, 0.030934, -0.03417, -0.00656, -0.01553, -0.02088, -0.04938], dtype=tf.float32 + ) + + expected_slice_1 = tf.convert_to_tensor( + [-0.04055, -0.038399, 0.0396, -0.03735, -0.03415, 0.01357, 0.00145, -0.05709], dtype=tf.float32 + ) + + tf.debugging.assert_near(output_hidden_states[0, 2], expected_slice_0, rtol=1e-3, atol=1e-4) + tf.debugging.assert_near(output_hidden_states[1, -2], expected_slice_1, rtol=1e-3, atol=1e-4) + + def test_layer_attn_probs(self): + model = TFLongformerModel.from_pretrained("patrickvonplaten/longformer-random-tiny") + layer = model.longformer.encoder.layer[0].attention.self_attention + hidden_states = tf.concat([self._get_hidden_states(), self._get_hidden_states() - 0.5], axis=0) + batch_size, seq_length, hidden_size = hidden_states.shape + + # create attn mask + attention_mask_1 = tf.zeros((1, 1, 1, seq_length), dtype=tf.float32) + attention_mask_2 = tf.zeros((1, 1, 1, seq_length), dtype=tf.float32) + + attention_mask_1 = tf.where(tf.range(4)[None, :, None, None] > 1, 10000.0, attention_mask_1) + attention_mask_1 = tf.where(tf.range(4)[None, :, None, None] > 2, -10000.0, attention_mask_1) + attention_mask_2 = tf.where(tf.range(4)[None, :, None, None] > 0, 10000.0, attention_mask_2) + attention_mask = tf.concat([attention_mask_1, attention_mask_2], axis=0) + + is_index_masked = tf.math.less(attention_mask[:, :, 0, 0], 0) + is_index_global_attn = tf.math.greater(attention_mask[:, :, 0, 0], 0) + is_global_attn = tf.math.reduce_any(is_index_global_attn) + + layer_head_mask = None + + output_hidden_states, local_attentions, global_attentions = layer( + [ + hidden_states, + -tf.math.abs(attention_mask), + layer_head_mask, + is_index_masked, + is_index_global_attn, + is_global_attn, + ] + ) + + self.assertEqual(local_attentions.shape, (2, 4, 2, 8)) + self.assertEqual(global_attentions.shape, (2, 2, 3, 4)) + + self.assertTrue((local_attentions[0, 2:4, :, :] == 0).numpy().tolist()) + self.assertTrue((local_attentions[1, 1:4, :, :] == 0).numpy().tolist()) + + # + # The weight of all tokens with local attention must sum to 1. + self.assertTrue( + (tf.math.abs(tf.math.reduce_sum(global_attentions[0, :, :2, :], axis=-1) - 1) < 1e-6).numpy().tolist() + ) + self.assertTrue( + (tf.math.abs(tf.math.reduce_sum(global_attentions[1, :, :1, :], axis=-1) - 1) < 1e-6).numpy().tolist() + ) + + tf.debugging.assert_near( + local_attentions[0, 0, 0, :], + tf.convert_to_tensor([0.3328, 0.0000, 0.0000, 0.0000, 0.0000, 0.3355, 0.3318, 0.0000], dtype=tf.float32), + rtol=1e-3, + atol=1e-4, + ) + + tf.debugging.assert_near( + local_attentions[1, 0, 0, :], + tf.convert_to_tensor([0.2492, 0.2502, 0.2502, 0.0000, 0.0000, 0.2505, 0.0000, 0.0000], dtype=tf.float32), + rtol=1e-3, + atol=1e-4, + ) + + # All the global attention weights must sum to 1. + self.assertTrue((tf.math.abs(tf.math.reduce_sum(global_attentions, axis=-1) - 1) < 1e-6).numpy().tolist()) + + tf.debugging.assert_near( + global_attentions[0, 0, 1, :], + tf.convert_to_tensor([0.2500, 0.2500, 0.2500, 0.2500], dtype=tf.float32), + rtol=1e-3, + atol=1e-4, + ) + tf.debugging.assert_near( + global_attentions[1, 0, 0, :], + tf.convert_to_tensor([0.2497, 0.2500, 0.2499, 0.2504], dtype=tf.float32), + rtol=1e-3, + atol=1e-4, + ) + + @slow + def test_inference_no_head(self): + model = TFLongformerModel.from_pretrained("allenai/longformer-base-4096") + + # 'Hello world!' + input_ids = tf.convert_to_tensor([[0, 20920, 232, 328, 1437, 2]], dtype=tf.int64) + attention_mask = tf.ones(shape_list(input_ids), dtype=tf.int64) + + output = model(input_ids, attention_mask=attention_mask)[0] + output_without_mask = model(input_ids)[0] + + expected_output_slice = tf.convert_to_tensor([0.0549, 0.1087, -0.1119, -0.0368, 0.0250], dtype=tf.float32) + + tf.debugging.assert_near(output[0, 0, -5:], expected_output_slice, rtol=1e-3, atol=1e-4) + tf.debugging.assert_near(output_without_mask[0, 0, -5:], expected_output_slice, rtol=1e-3, atol=1e-4) + + @slow + def test_inference_no_head_long(self): + model = TFLongformerModel.from_pretrained("allenai/longformer-base-4096") + + # 'Hello world! ' repeated 1000 times + input_ids = tf.convert_to_tensor([[0] + [20920, 232, 328, 1437] * 1000 + [2]], dtype=tf.int64) + + attention_mask = tf.ones(shape_list(input_ids), dtype=tf.int64) + global_attention_mask = tf.zeros(shape_list(input_ids), dtype=tf.int64) + # Set global attention on a few random positions + global_attention_mask = tf.tensor_scatter_nd_update( + global_attention_mask, + tf.constant([[0, 1], [0, 4], [0, 21]], dtype=tf.int64), + tf.constant([1, 1, 1], dtype=tf.int64), + ) + + output = model(input_ids, attention_mask=attention_mask, global_attention_mask=global_attention_mask)[0] + + expected_output_sum = tf.constant(74585.875) + expected_output_mean = tf.constant(0.024267) + + # assert close + tf.debugging.assert_near(tf.reduce_sum(output), expected_output_sum, rtol=1e-4, atol=1e-4) + tf.debugging.assert_near(tf.reduce_mean(output), expected_output_mean, rtol=1e-4, atol=1e-4) + + @slow + def test_inference_masked_lm_long(self): + model = TFLongformerForMaskedLM.from_pretrained("allenai/longformer-base-4096") + + # 'Hello world! ' repeated 1000 times + input_ids = tf.convert_to_tensor([[0] + [20920, 232, 328, 1437] * 1000 + [2]], dtype=tf.int64) + + output = model(input_ids, labels=input_ids) + loss = output.loss + prediction_scores = output.logits + + expected_loss = tf.constant(0.0073798) + expected_prediction_scores_sum = tf.constant(-610476600.0) + expected_prediction_scores_mean = tf.constant(-3.03477) + + # assert close + tf.debugging.assert_near(tf.reduce_mean(loss), expected_loss, rtol=1e-4, atol=1e-4) + tf.debugging.assert_near( + tf.reduce_sum(prediction_scores), expected_prediction_scores_sum, rtol=1e-4, atol=1e-4 + ) + tf.debugging.assert_near( + tf.reduce_mean(prediction_scores), expected_prediction_scores_mean, rtol=1e-4, atol=1e-4 + ) + + @slow + def test_inference_masked_lm(self): + model = TFLongformerForMaskedLM.from_pretrained("lysandre/tiny-longformer-random") + input_ids = tf.constant([[0, 1, 2, 3, 4, 5]]) + output = model(input_ids)[0] + + expected_shape = [1, 6, 10] + self.assertEqual(output.shape, expected_shape) + + print(output[:, :3, :3]) + + expected_slice = tf.constant( + [ + [ + [-0.04926379, 0.0367098, 0.02099686], + [0.03940692, 0.01547744, -0.01448723], + [0.03495252, -0.05900355, -0.01675752], + ] + ] + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_tokenization_longformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_tokenization_longformer.py new file mode 100644 index 0000000000000000000000000000000000000000..2397a40bafa6b1fffe695593d1716cec32670c31 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longformer/test_tokenization_longformer.py @@ -0,0 +1,305 @@ +# coding=utf-8 +# Copyright 2022 Tsimur Hadeliya. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the Longformer tokenizer. """ + + +import itertools +import json +import os +import unittest + +from transformers import AddedToken, LongformerTokenizer, LongformerTokenizerFast +from transformers.models.longformer.tokenization_longformer import VOCAB_FILES_NAMES +from transformers.testing_utils import require_tokenizers, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +# Copied from transformers.tests.roberta.test_modeling_roberta.py with Roberta->Longformer +@require_tokenizers +class LongformerTokenizationTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LongformerTokenizer + test_slow_tokenizer = True + rust_tokenizer_class = LongformerTokenizerFast + test_rust_tokenizer = True + + def setUp(self): + super().setUp() + + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + vocab = [ + "l", + "o", + "w", + "e", + "r", + "s", + "t", + "i", + "d", + "n", + "\u0120", + "\u0120l", + "\u0120n", + "\u0120lo", + "\u0120low", + "er", + "\u0120lowest", + "\u0120newer", + "\u0120wider", + "", + ] + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + + def get_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs): + kwargs.update(self.special_tokens_map) + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.tokenizer_class(self.vocab_file, self.merges_file, **self.special_tokens_map) + text = "lower newer" + bpe_tokens = ["l", "o", "w", "er", "\u0120", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text) # , add_prefix_space=True) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [0, 1, 2, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + def longformer_dict_integration_testing(self): + tokenizer = self.get_tokenizer() + + self.assertListEqual(tokenizer.encode("Hello world!", add_special_tokens=False), [0, 31414, 232, 328, 2]) + self.assertListEqual( + tokenizer.encode("Hello world! cécé herlolip 418", add_special_tokens=False), + [0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2], + ) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("allenai/longformer-base-4096") + + text = tokenizer.encode("sequence builders", add_special_tokens=False) + text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False) + + encoded_text_from_decode = tokenizer.encode( + "sequence builders", add_special_tokens=True, add_prefix_space=False + ) + encoded_pair_from_decode = tokenizer.encode( + "sequence builders", "multi-sequence build", add_special_tokens=True, add_prefix_space=False + ) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + assert encoded_sentence == encoded_text_from_decode + assert encoded_pair == encoded_pair_from_decode + + def test_space_encoding(self): + tokenizer = self.get_tokenizer() + + sequence = "Encode this sequence." + space_encoding = tokenizer.byte_encoder[" ".encode("utf-8")[0]] + + # Testing encoder arguments + encoded = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=False) + first_char = tokenizer.convert_ids_to_tokens(encoded[0])[0] + self.assertNotEqual(first_char, space_encoding) + + encoded = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=True) + first_char = tokenizer.convert_ids_to_tokens(encoded[0])[0] + self.assertEqual(first_char, space_encoding) + + tokenizer.add_special_tokens({"bos_token": ""}) + encoded = tokenizer.encode(sequence, add_special_tokens=True) + first_char = tokenizer.convert_ids_to_tokens(encoded[1])[0] + self.assertNotEqual(first_char, space_encoding) + + # Testing spaces after special tokens + mask = "" + tokenizer.add_special_tokens( + {"mask_token": AddedToken(mask, lstrip=True, rstrip=False)} + ) # mask token has a left space + mask_ind = tokenizer.convert_tokens_to_ids(mask) + + sequence = "Encode sequence" + sequence_nospace = "Encode sequence" + + encoded = tokenizer.encode(sequence) + mask_loc = encoded.index(mask_ind) + first_char = tokenizer.convert_ids_to_tokens(encoded[mask_loc + 1])[0] + self.assertEqual(first_char, space_encoding) + + encoded = tokenizer.encode(sequence_nospace) + mask_loc = encoded.index(mask_ind) + first_char = tokenizer.convert_ids_to_tokens(encoded[mask_loc + 1])[0] + self.assertNotEqual(first_char, space_encoding) + + def test_pretokenized_inputs(self): + pass + + def test_embeded_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + sentence = "A, AllenNLP sentence." + tokens_r = tokenizer_r.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + tokens_p = tokenizer_p.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + + # token_type_ids should put 0 everywhere + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + # attention_mask should put 1 everywhere, so sum over length should be 1 + self.assertEqual( + sum(tokens_r["attention_mask"]) / len(tokens_r["attention_mask"]), + sum(tokens_p["attention_mask"]) / len(tokens_p["attention_mask"]), + ) + + tokens_r_str = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p_str = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + + # Rust correctly handles the space before the mask while python doesnt + self.assertSequenceEqual(tokens_p["input_ids"], [0, 250, 6, 50264, 3823, 487, 21992, 3645, 4, 2]) + self.assertSequenceEqual(tokens_r["input_ids"], [0, 250, 6, 50264, 3823, 487, 21992, 3645, 4, 2]) + + self.assertSequenceEqual( + tokens_p_str, ["", "A", ",", "", "ĠAllen", "N", "LP", "Ġsentence", ".", ""] + ) + self.assertSequenceEqual( + tokens_r_str, ["", "A", ",", "", "ĠAllen", "N", "LP", "Ġsentence", ".", ""] + ) + + def test_change_add_prefix_space_and_trim_offsets_args(self): + for trim_offsets, add_prefix_space in itertools.product([True, False], repeat=2): + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + self.tmpdirname, use_fast=True, add_prefix_space=add_prefix_space, trim_offsets=trim_offsets + ) + + pre_tokenizer_state = json.loads(tokenizer_r.backend_tokenizer.pre_tokenizer.__getstate__()) + post_processor_state = json.loads(tokenizer_r.backend_tokenizer.post_processor.__getstate__()) + + self.assertEqual(pre_tokenizer_state["add_prefix_space"], add_prefix_space) + + self.assertEqual(post_processor_state["add_prefix_space"], add_prefix_space) + self.assertEqual(post_processor_state["trim_offsets"], trim_offsets) + + def test_offsets_mapping_with_different_add_prefix_space_and_trim_space_arguments(self): + # Test which aims to verify that the offsets are well adapted to the argument `add_prefix_space` and + # `trim_offsets` + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + text_of_1_token = "hello" # `hello` is a token in the vocabulary of `pretrained_name` + text = f"{text_of_1_token} {text_of_1_token}" + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=True, trim_offsets=True + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (len(text_of_1_token) + 1, len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=False, trim_offsets=True + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (len(text_of_1_token) + 1, len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=True, trim_offsets=False + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (len(text_of_1_token), len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=False, trim_offsets=False + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (len(text_of_1_token), len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + text = f" {text}" + + # tokenizer_r = self.rust_tokenizer_class.from_pretrained( + # pretrained_name, use_fast=True, add_prefix_space=True, trim_offsets=True + # ) + # encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + # self.assertEqual(encoding.offset_mapping[0], (1, 1 + len(text_of_1_token))) + # self.assertEqual( + # encoding.offset_mapping[1], + # (1 + len(text_of_1_token) + 1, 1 + len(text_of_1_token) + 1 + len(text_of_1_token)), + # ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=False, trim_offsets=True + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (1, 1 + len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (1 + len(text_of_1_token) + 1, 1 + len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=True, trim_offsets=False + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, 1 + len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (1 + len(text_of_1_token), 1 + len(text_of_1_token) + 1 + len(text_of_1_token)), + ) + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, use_fast=True, add_prefix_space=False, trim_offsets=False + ) + encoding = tokenizer_r(text, return_offsets_mapping=True, add_special_tokens=False) + self.assertEqual(encoding.offset_mapping[0], (0, 1 + len(text_of_1_token))) + self.assertEqual( + encoding.offset_mapping[1], + (1 + len(text_of_1_token), 1 + len(text_of_1_token) + 1 + len(text_of_1_token)), + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_flax_longt5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_flax_longt5.py new file mode 100644 index 0000000000000000000000000000000000000000..2c262bef3092cdc28ac055d843646e6d247b531e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_flax_longt5.py @@ -0,0 +1,756 @@ +# coding=utf-8 +# Copyright 2022 Google LongT5 Authors and HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import tempfile +import unittest + +import numpy as np + +import transformers +from transformers import is_flax_available +from transformers.models.auto import get_values +from transformers.testing_utils import ( + is_pt_flax_cross_test, + require_flax, + require_sentencepiece, + require_tokenizers, + slow, +) + +from ...generation.test_flax_utils import FlaxGenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor + + +if is_flax_available(): + import os + + # The slow tests are often failing with OOM error on GPU + # This makes JAX allocate exactly what is needed on demand, and deallocate memory that is no longer needed + # but will be slower as stated here https://jax.readthedocs.io/en/latest/gpu_memory_allocation.html + os.environ["XLA_PYTHON_CLIENT_ALLOCATOR"] = "platform" + + import jax + import jax.numpy as jnp + from flax.core.frozen_dict import unfreeze + from flax.traverse_util import flatten_dict + + from transformers import FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING, FLAX_MODEL_MAPPING, AutoTokenizer, LongT5Config + from transformers.modeling_flax_pytorch_utils import load_flax_weights_in_pytorch_model + from transformers.models.longt5.modeling_flax_longt5 import ( + FlaxLongT5ForConditionalGeneration, + FlaxLongT5Model, + shift_tokens_right, + ) + + +class FlaxLongT5ModelTester: + def __init__( + self, + parent, + vocab_size=99, + batch_size=13, + encoder_seq_length=7, + decoder_seq_length=9, + local_radius=5, + encoder_attention_type="local", + global_block_size=3, + # For common tests + is_training=True, + use_attention_mask=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + d_ff=37, + relative_attention_num_buckets=8, + dropout_rate=0.1, + initializer_factor=0.002, + eos_token_id=1, + pad_token_id=0, + decoder_start_token_id=0, + scope=None, + decoder_layers=None, + ): + self.parent = parent + self.batch_size = batch_size + self.encoder_seq_length = encoder_seq_length + self.decoder_seq_length = decoder_seq_length + self.local_radius = local_radius + self.block_len = local_radius + 1 + self.encoder_attention_type = encoder_attention_type + self.global_block_size = global_block_size + # For common tests + self.seq_length = self.decoder_seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.d_ff = d_ff + self.relative_attention_num_buckets = relative_attention_num_buckets + self.dropout_rate = dropout_rate + self.initializer_factor = initializer_factor + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.decoder_start_token_id = decoder_start_token_id + self.scope = None + self.decoder_layers = decoder_layers + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.encoder_seq_length], self.vocab_size) + decoder_input_ids = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + attention_mask = None + decoder_attention_mask = None + if self.use_attention_mask: + attention_mask = ids_tensor([self.batch_size, self.encoder_seq_length], vocab_size=2) + decoder_attention_mask = ids_tensor([self.batch_size, self.decoder_seq_length], vocab_size=2) + + config = LongT5Config( + vocab_size=self.vocab_size, + d_model=self.hidden_size, + d_ff=self.d_ff, + d_kv=self.hidden_size // self.num_attention_heads, + num_layers=self.num_hidden_layers, + num_decoder_layers=self.decoder_layers, + num_heads=self.num_attention_heads, + relative_attention_num_buckets=self.relative_attention_num_buckets, + dropout_rate=self.dropout_rate, + initializer_factor=self.initializer_factor, + eos_token_id=self.eos_token_id, + bos_token_id=self.pad_token_id, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + local_radius=self.local_radius, + encoder_attention_type=self.encoder_attention_type, + global_block_size=self.global_block_size, + ) + + return ( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + ) + + def create_and_check_model( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + ): + model = FlaxLongT5Model(config=config) + result = model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + result = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) + decoder_output = result.last_hidden_state + encoder_output = result.encoder_last_hidden_state + + self.parent.assertEqual(encoder_output.shape, (self.batch_size, self.encoder_seq_length, self.hidden_size)) + self.parent.assertEqual(decoder_output.shape, (self.batch_size, self.decoder_seq_length, self.hidden_size)) + + def check_use_cache_forward_with_attn_mask( + self, + model_class_name, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + ): + max_decoder_length = 20 + model = model_class_name(config) + + encoder_outputs = model.encode(input_ids) + + # prevent fully zero'd out attention mask + decoder_attention_mask = jnp.ones_like(decoder_attention_mask) + + decoder_attention_mask_cache = jnp.concatenate( + [ + decoder_attention_mask, + jnp.zeros((decoder_attention_mask.shape[0], max_decoder_length - decoder_attention_mask.shape[1])), + ], + axis=-1, + ) + + past_key_values = model.init_cache(decoder_input_ids.shape[0], max_decoder_length, encoder_outputs) + + outputs_cache = model.decode( + decoder_input_ids[:, :-1], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask_cache, + past_key_values=past_key_values, + ) + outputs_cache_next = model.decode( + decoder_input_ids[:, -1:], + encoder_outputs, + past_key_values=outputs_cache.past_key_values, + decoder_attention_mask=decoder_attention_mask_cache, + ) + + outputs = model.decode(decoder_input_ids, encoder_outputs, decoder_attention_mask=decoder_attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + } + return config, inputs_dict + + +@require_flax +class FlaxLongT5ModelTest(FlaxModelTesterMixin, FlaxGenerationTesterMixin, unittest.TestCase): + all_model_classes = (FlaxLongT5Model, FlaxLongT5ForConditionalGeneration) if is_flax_available() else () + all_generative_model_classes = (FlaxLongT5ForConditionalGeneration,) if is_flax_available() else () + is_encoder_decoder = True + + def setUp(self): + self.model_tester = FlaxLongT5ModelTester(self) + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_model_v1_1(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + # check that gated gelu feed forward and different word embeddings work + config = config_and_inputs[0] + config.tie_word_embeddings = False + config.feed_forward_proj = "gated-gelu" + self.model_tester.create_and_check_model(config, *config_and_inputs[1:]) + + def test_use_cache_forward_with_attn_mask(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + self.model_tester.check_use_cache_forward_with_attn_mask(model_class, *config_and_inputs) + + def test_encode(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + @jax.jit + def encode_jitted(input_ids, attention_mask=None, **kwargs): + return model.encode(input_ids=input_ids, attention_mask=attention_mask) + + with self.subTest("JIT Enabled"): + jitted_outputs = encode_jitted(**prepared_inputs_dict).to_tuple() + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = encode_jitted(**prepared_inputs_dict).to_tuple() + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + def test_decode(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + model = model_class(config) + encoder_outputs = model.encode(inputs_dict["input_ids"], inputs_dict["attention_mask"]) + + prepared_inputs_dict = { + "decoder_input_ids": inputs_dict["decoder_input_ids"], + "decoder_attention_mask": inputs_dict["decoder_attention_mask"], + "encoder_outputs": encoder_outputs, + } + + @jax.jit + def decode_jitted(decoder_input_ids, decoder_attention_mask, encoder_outputs): + return model.decode( + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + encoder_outputs=encoder_outputs, + ) + + with self.subTest("JIT Enabled"): + jitted_outputs = decode_jitted(**prepared_inputs_dict).to_tuple() + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = decode_jitted(**prepared_inputs_dict).to_tuple() + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + def test_shift_right(self): + decoder_start_token_id = 0 + pad_token_id = 1 + labels = np.arange(2, 102).reshape(5, 20) + labels[:2, 15:] = -100 + + decoder_input_ids = shift_tokens_right(labels, pad_token_id, decoder_start_token_id) + np_decoder_input_ids = np.array(decoder_input_ids) + + padded_slice = np_decoder_input_ids[:2, (15 + 1) :] + self.assertTrue((padded_slice == 1).all()) + + not_padded_slice = np_decoder_input_ids[2:, 1:] + rolled_labels = np.roll(labels[2:], 1)[:, 1:] + self.assertTrue((not_padded_slice == rolled_labels).all()) + self.assertTrue((np_decoder_input_ids[:, 0] == 0).all()) + + # overwrite since special base model prefix is used + def test_save_load_from_base(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = base_class(config) + base_params = flatten_dict(unfreeze(model.params)) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + head_model = model_class.from_pretrained(tmpdirname) + + base_param_from_head = flatten_dict(unfreeze(head_model.params)) + + for key in base_param_from_head.keys(): + max_diff = (base_params[key] - base_param_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + # overwrite since special base model prefix is used + def test_save_load_to_base(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + base_params_from_head = flatten_dict(unfreeze(model.params)) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname) + + base_params = flatten_dict(unfreeze(base_model.params)) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_length = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_length) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_length) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + block_len = getattr(self.model_tester, "block_len", None) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # Question Answering model returns start_logits and end_logits + if model_class in get_values(FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + + # overwrite since special base model prefix is used + @is_pt_flax_cross_test + def test_save_load_from_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = base_class(config) + base_params = flatten_dict(unfreeze(model.params)) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, base_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + # save pt model + pt_model.save_pretrained(tmpdirname) + head_model = model_class.from_pretrained(tmpdirname, from_pt=True) + + base_param_from_head = flatten_dict(unfreeze(head_model.params)) + + for key in base_param_from_head.keys(): + max_diff = (base_params[key] - base_param_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + # overwrite since special base model prefix is used + @is_pt_flax_cross_test + def test_save_load_to_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + base_params_from_head = flatten_dict(unfreeze(model.params)) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, model_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname, from_pt=True) + + base_params = flatten_dict(unfreeze(base_model.params)) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + # overwrite since special base model prefix is used + @is_pt_flax_cross_test + def test_save_load_bf16_to_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + model.params = model.to_bf16(model.params) + base_params_from_head = flatten_dict(unfreeze(model.params)) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, model_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname, from_pt=True) + + base_params = flatten_dict(unfreeze(base_model.params)) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + +class FlaxLongT5TGlobalModelTest(FlaxLongT5ModelTest): + def setUp(self): + self.model_tester = FlaxLongT5ModelTester(self, encoder_attention_type="transient-global") + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_length = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_length) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_length) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + block_len = getattr(self.model_tester, "block_len", None) + global_block_size = getattr(self.model_tester, "global_block_size", None) + global_seq_len = encoder_seq_length // global_block_size + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # Question Answering model returns start_logits and end_logits + if model_class in get_values(FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + + +@require_sentencepiece +@require_tokenizers +@require_flax +class FlaxLongT5ModelIntegrationTests(unittest.TestCase): + model_path = "Stancld/longt5-tglobal-large-16384-pubmed-3k_steps" + + def expected_summary(self): + return [ + "background : coronary artery disease ( cad ) is the emerging cause of morbidity and mortality in" + " developing world . it provides an excellent resolution for visualization of the coronary arteries for" + " catheter - based or operating interventions . although the association of this technique with major" + " complications such as mortality is highly uncommon , it is frequently associated with various cardiac" + " and noncardiac complications . computed tomography coronary angiography is a promising technique for the" + " evaluation of cad noninvasively . it assesses disease within the coronary artery and provides" + " qualitative and quantitative information about nonobstructive atherosclerotic plaque" + ] + + @slow + def test_summarization(self): + model = FlaxLongT5ForConditionalGeneration.from_pretrained(self.model_path) + tok = AutoTokenizer.from_pretrained(self.model_path) + + ARTICLE = """coronary artery disease ( cad ) is the emerging cause of morbidity and mortality in developing world . \n it provides an excellent resolution for visualization of the coronary arteries for catheter - based or operating interventions . \n + although the association of this technique with major complications such as mortality is highly uncommon , it is frequently associated with various cardiac and noncardiac complications . computed tomography ( ct ) coronary angiography is + a promising technique for the evaluation of cad noninvasively . \n it assesses disease within the coronary artery and provides qualitative and quantitative information about nonobstructive atherosclerotic plaque burden within the vessel + wall . \n thus , ct angiography - based disease evaluation may provide clinically more significant information than conventional angiography . the introduction of multi - slice computed tomography ( msct ) technology such as 64-slice , 12 + 8-slice , 256-slice , and now 320-slice msct has produced a high diagnostic accuracy of ct coronary angiography . \n it has consistently showed to have a very high negative predictive value ( well above 90% ) in ruling out patients with s + ignificant cad defined as coronary luminal stenosis of > 50% . \n the american college of cardiology / american heart association recommends that coronary angiography should be performed before valve surgery in men aged > 40 years , women + aged > 35 years with coronary risk factors and in postmenopausal women . \n the prevalence of cad in patients undergoing valve replacement is 2040% in developed countries . in the previous studies , \n the incidence of angiographically p + roven cad in acquired valvular diseases has been shown to vary widely from 9% to 41% . in aortic stenosis , \n we aimed to report the diagnostic performance of 128-slice ct coronary angiography in 50 patients undergoing for major noncoron + ary cardiac surgery referred for diagnostic invasive coronary angiography to assess the extent and severity of coronary stenosis . \n during january 2013 to december 2014 , we enrolled fifty major noncoronary cardiac surgery patients sche + duled for invasive coronary angiography who fulfilled the following inclusion criteria of age 40 years , having low or intermediate probability of cad , left ventricular ejection fraction ( lvef ) > 35% , and patient giving informed conse + nt for undergoing msct and conventional coronary angiography . \n those having any contraindication for contrast injection , lvef < 35% , high pretest probability of cad , and hemodynamic instability were excluded from the study . \n pati + ents with heart rates of > 70 bpm received ( unless they had known overt heart failure or electrocardiogram ( ecg ) atrioventricular conduction abnormalities ) a single oral dose of 100 mg metoprolol 45 min before the scan . \n patients w + ith heart rates of > 80 bpm received an additional oral dose of metoprolol if not contraindicated . \n all patients were scanned with a 128-slice ct scanner ( siemens , somatom definition as ) equipped with a new feature in msct technolog + y , so - called z - axis flying - focus technology . \n the central 32 detector rows acquire 0.6-mm slices , and the flying - focus spot switches back and forth between 2 z positions between each reading . \n two slices per detector row a + re acquired , which results in a higher oversampling rate in the z - axis , thereby reducing artifacts related to the spiral acquisition and improving spatial resolution down to 0.4 mm . \n a bolus of 6580 ml contrast material ( omnipaque + ) was injected through an arm vein at a flow rate of 5 ml / s . \n a bolus tracking technique was used to synchronize the arrival of contrast in the coronary arteries with the initiation of the scan . to monitor the arrival of contrast m + aterial , \n axial scans were obtained at the level of the ascending aorta with a delay of 10 s after the start of the contrast injection . \n the scan was automatically started when a threshold of 150 hounsfield units was reached in a re + gion of interest positioned in the ascending aorta . \n images were reconstructed with ecg gating to obtain optimal , motion - free image quality . \n all scans were performed within 2 weeks of the msct coronary diagnostic angiogram . a s + ingle observer unaware of the multi - slice ct results identified coronary lesion as a single vessel , double vessel , or triple vessel disease . \n all lesion , regardless of size , were included for comparison with ct coronary angiograp + hy . \n lesions were classified as having nonsignificant disease ( luminal irregularities or < 50% stenosis ) or as having significant stenosis . \n stenosis was evaluated in two orthogonal views and classified as significant if the mean + lumen diameter reduction was 50% using a validated quantitative coronary angiography ( qca ) . \n all scans were analyzed independently by a radiologist and a cardiologist who were unaware of the results of conventional coronary angiograp + hy . \n total calcium scores of all patients were calculated with dedicated software and expressed as agatston scores . \n the agatston score is a commonly used scoring method that calculates the total amount of calcium on the basis of th + e number , areas , and peak hounsfield units of the detected calcified lesions . \n all available coronary segments were visually scored for the presence of > 50% considered as significant stenosis . \n maximum intensity projections were + used to identify coronary lesions and ( curved ) multiplanar reconstructions to classify lesions as significant or nonsignificant . \n data were analyzed using statistical system spss version 20 software ( chicago , il , usa ) . \n the di + agnostic performance of ct coronary angiography for the detection of significant lesions in coronary arteries with qca as the standard of reference is presented as sensitivity , specificity , positive and negative predictive values , and + positive and negative likelihood ratios with the corresponding exact 95% of confidence interval ( cis ) . \n comparison between ct and conventional coronary angiography was performed on the two level vessel by vessel ( no or any disease p + er vessel ) , and patient by patient ( no or any disease per patient ) . \n all scans were performed within 2 weeks of the msct coronary diagnostic angiogram . a single observer unaware of the multi - slice ct results identified coronary + lesion as a single vessel , double vessel , or triple vessel disease . \n all lesion , regardless of size , were included for comparison with ct coronary angiography . \n lesions were classified as having nonsignificant disease ( luminal + irregularities or < 50% stenosis ) or as having significant stenosis . \n stenosis was evaluated in two orthogonal views and classified as significant if the mean lumen diameter reduction was 50% using a validated quantitative coronary an + giography ( qca ) . \n all scans were analyzed independently by a radiologist and a cardiologist who were unaware of the results of conventional coronary angiography . \n total calcium scores of all patients were calculated with dedicated + software and expressed as agatston scores . \n the agatston score is a commonly used scoring method that calculates the total amount of calcium on the basis of the number , areas , and peak hounsfield units of the detected calcified lesi + ons . \n all available coronary segments were visually scored for the presence of > 50% considered as significant stenosis . \n maximum intensity projections were used to identify coronary lesions and ( curved ) multiplanar reconstruction + s to classify lesions as significant or nonsignificant . \n data were analyzed using statistical system spss version 20 software ( chicago , il , usa ) . \n the diagnostic performance of ct coronary angiography for the detection of signif + icant lesions in coronary arteries with qca as the standard of reference is presented as sensitivity , specificity , positive and negative predictive values , and positive and negative likelihood ratios with the corresponding exact 95% of + confidence interval ( cis ) . \n comparison between ct and conventional coronary angiography was performed on the two level vessel by vessel ( no or any disease per vessel ) , and patient by patient ( no or any disease per patient ) . \n + in this study , 29 ( 58% ) subjects were female , and 21 ( 42% ) were male showing an average age of 50.36 8.39 years . \n of fifty patients 24 ( 48% ) , 13 ( 26% ) , eight ( 16% ) , and five ( 10% ) underwent mitral valve replacement , + double valve replacement ( dvr ) , aortic valve replacement , and other surgeries , respectively . \n high distribution of cad risk factors such as hypertension ( 24% ) , smoking ( 22% ) , and dyslipidemia ( 18% ) was observed in the stu + dy group . \n the mean creatinine level was 0.766 0.17 and average dye used in conventional angiography was 48.5 26.6 whereas for ct angiography it was 72.8 6.32 . \n average radiation dose in conventional coronary angiography and msct + coronary angiography was 5.2 msv and 9.2 msv , respectively . \n the majority of the patients had sinus rhythm ( 68% ) , whereas atrial fibrillation was found in 32% of the subjects . \n patients included in the study had low to intermed + iate probability of cad . in this study , three patients had complications after conventional angiography . \n complications were of local site hematoma , acute kidney injury managed conservatively , and acute heart failure . \n a patient + who developed hematoma was obese female patients with body mass index > 30 kg / m . \n the patient suffered from pseudoaneurysm , had hospitalized for 9 days , which leads to increased morbidity and cost of hospital stay . \n the diagnos + tic accuracy of ct coronary angiography was evaluated regarding true positive , true negative values and is presented in table 1 . the overall sensitivity and \n specificity of ct angiography technique was 100% ( 95% ci : 39.76%100% ) and + 91.30% ( 95% ci : 79.21%97.58% ) , respectively [ table 2 ] . \n the positive predictive value ( 50% ; 95% ci : 15.70%84.30% ) and negative predictive value ( 100% ; 95% ci : 91.59%100% ) of ct angiography were also fairly high in these + patients . \n recent reports from multiple studies demonstrated that recent - generation msct scanners showed promise for noninvasive detection of coronary stenosis however , until now no studies were found regarding the clinical efficacy + or prognostic value of 128-slice ct coronary angiography versus conventional invasive coronary angiography in the diagnosis of patients planned for major noncoronary surgeries such as dvr , bentall , atrial septal defect closure , etc . + in our study , we reported 8% cad prevalence in patients planned for major noncoronary cardiac surgery . \n we performed conventional and msct coronary angiography in all patients and the results showed that ct coronary angiography with i + nvasive coronary angiography as the reference standard had a considerably high sensitivity ( 100% ) and specificity ( 95.65% ) . \n the health economic model using invasive coronary angiography as the reference standard showed that at a p + retest probability of cad of 70% or lower , ct coronary angiography resulted in lower cost per patient with a true positive diagnosis . at a pretest probability of cad of 70% or higher , invasive coronary angiography was associated with a + lower cost per patient with a true positive diagnosis . in our study population , \n two patients developed local site complications in the form of hematoma and pseudoaneurysm after conventional angiography . \n hence , msct coronary ang + iography will be more favorable in female obese patients with intermediate likelihood of cad . \n hence , msct coronary angiography will be cost - effective in patients of valvular heart diseases . \n however , ct angiography suffers from + a drawback that average amount of dye used in msct coronary angiography were 72.8 6.32 ml which is higher than average amount of dye required for conventional angiography ( 48.6 26.6 ml ) . \n hence , the use of ct coronary angiography + could not be used in patients with known renal dysfunction , where reduction of contrast dye load is highly advocated . \n our results show that 128-slice ct coronary angiography is a reliable technique to detect coronary stenosis in pat + ients planned for noncoronary cardiac surgery . \n although there has been important technological progress in the development of ct coronary angiography , its clinical application remains limited . \n a study wth large numbers of patient + s is required for the recommendation of only ct coronary angiography for the coronary evaluation in major non - cardiac surgeries . \n mehta institute of cardiology and research center ( affiliated to bj medical college , ahmedabad , guja + rat , india ) . \n u.n . mehta institute of cardiology and research center ( affiliated to bj medical college , ahmedabad , gujarat , india ) . \n """ + + dct = tok( + [ARTICLE], + max_length=1024, + padding="max_length", + truncation=True, + return_tensors="np", + ) + + hypotheses_batch = model.generate( + **dct, + num_beams=4, + length_penalty=2.0, + max_length=142, + min_length=56, + do_sample=False, + early_stopping=True, + ).sequences + + decoded = tok.batch_decode(hypotheses_batch, skip_special_tokens=True, clean_up_tokenization_spaces=False) + self.assertListEqual( + self.expected_summary(), + decoded, + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_longt5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_longt5.py new file mode 100644 index 0000000000000000000000000000000000000000..0f7ae0a27210a65a5fdd586198056f53e584d15a --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/longt5/test_modeling_longt5.py @@ -0,0 +1,1328 @@ +# coding=utf-8 +# Copyright 2022 Google LongT5 Authors and HuggingFace Inc. team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import tempfile +import unittest + +from transformers import LongT5Config, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + AutoTokenizer, + LongT5EncoderModel, + LongT5ForConditionalGeneration, + LongT5Model, + ) + from transformers.models.longt5.modeling_longt5 import LONGT5_PRETRAINED_MODEL_ARCHIVE_LIST + from transformers.pytorch_utils import is_torch_less_than_1_11 + + +class LongT5ModelTester: + def __init__( + self, + parent, + vocab_size=99, + batch_size=13, + encoder_seq_length=7, + decoder_seq_length=9, + local_radius=5, + encoder_attention_type="local", + global_block_size=3, + # For common tests + is_training=True, + use_attention_mask=True, + use_labels=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + d_ff=37, + relative_attention_num_buckets=8, + dropout_rate=0.1, + initializer_factor=0.002, + eos_token_id=1, + pad_token_id=0, + decoder_start_token_id=0, + scope=None, + decoder_layers=None, + large_model_config_path="google/long-t5-local-large", + ): + self.parent = parent + self.batch_size = batch_size + self.encoder_seq_length = encoder_seq_length + self.decoder_seq_length = decoder_seq_length + self.local_radius = local_radius + self.block_len = local_radius + 1 + self.encoder_attention_type = encoder_attention_type + self.global_block_size = global_block_size + # For common tests + self.seq_length = self.decoder_seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.d_ff = d_ff + self.relative_attention_num_buckets = relative_attention_num_buckets + self.dropout_rate = dropout_rate + self.initializer_factor = initializer_factor + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.decoder_start_token_id = decoder_start_token_id + self.scope = None + self.decoder_layers = decoder_layers + self.large_model_config_path = large_model_config_path + + def get_large_model_config(self): + return LongT5Config.from_pretrained(self.large_model_config_path) + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.encoder_seq_length], self.vocab_size) + decoder_input_ids = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + attention_mask = None + decoder_attention_mask = None + if self.use_attention_mask: + attention_mask = ids_tensor([self.batch_size, self.encoder_seq_length], vocab_size=2) + decoder_attention_mask = ids_tensor([self.batch_size, self.decoder_seq_length], vocab_size=2) + + lm_labels = None + if self.use_labels: + lm_labels = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + config = self.get_config() + + return ( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ) + + def get_pipeline_config(self): + return LongT5Config( + vocab_size=166, # longt5 forces 100 extra tokens + d_model=self.hidden_size, + d_ff=self.d_ff, + d_kv=self.hidden_size // self.num_attention_heads, + num_layers=self.num_hidden_layers, + num_decoder_layers=self.decoder_layers, + num_heads=self.num_attention_heads, + relative_attention_num_buckets=self.relative_attention_num_buckets, + dropout_rate=self.dropout_rate, + initializer_factor=self.initializer_factor, + eos_token_id=self.eos_token_id, + bos_token_id=self.pad_token_id, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + local_radius=self.local_radius, + encoder_attention_type=self.encoder_attention_type, + global_block_size=self.global_block_size, + ) + + def get_config(self): + return LongT5Config( + vocab_size=self.vocab_size, + d_model=self.hidden_size, + d_ff=self.d_ff, + d_kv=self.hidden_size // self.num_attention_heads, + num_layers=self.num_hidden_layers, + num_decoder_layers=self.decoder_layers, + num_heads=self.num_attention_heads, + relative_attention_num_buckets=self.relative_attention_num_buckets, + dropout_rate=self.dropout_rate, + initializer_factor=self.initializer_factor, + eos_token_id=self.eos_token_id, + bos_token_id=self.pad_token_id, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + local_radius=self.local_radius, + encoder_attention_type=self.encoder_attention_type, + global_block_size=self.global_block_size, + ) + + def check_prepare_lm_labels_via_shift_left( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5Model(config=config) + model.to(torch_device) + model.eval() + + # make sure that lm_labels are correctly padded from the right + lm_labels.masked_fill_((lm_labels == self.decoder_start_token_id), self.eos_token_id) + + # add casaul pad token mask + triangular_mask = torch.tril(lm_labels.new_ones(lm_labels.shape)).logical_not() + lm_labels.masked_fill_(triangular_mask, self.pad_token_id) + decoder_input_ids = model._shift_right(lm_labels) + + for i, (decoder_input_ids_slice, lm_labels_slice) in enumerate(zip(decoder_input_ids, lm_labels)): + # first item + self.parent.assertEqual(decoder_input_ids_slice[0].item(), self.decoder_start_token_id) + if i < decoder_input_ids_slice.shape[-1]: + if i < decoder_input_ids.shape[-1] - 1: + # items before diagonal + self.parent.assertListEqual( + decoder_input_ids_slice[1 : i + 1].tolist(), lm_labels_slice[:i].tolist() + ) + # pad items after diagonal + if i < decoder_input_ids.shape[-1] - 2: + self.parent.assertListEqual( + decoder_input_ids_slice[i + 2 :].tolist(), lm_labels_slice[i + 1 : -1].tolist() + ) + else: + # all items after square + self.parent.assertListEqual(decoder_input_ids_slice[1:].tolist(), lm_labels_slice[:-1].tolist()) + + def create_and_check_model( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5Model(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + result = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids) + decoder_output = result.last_hidden_state + decoder_past = result.past_key_values + encoder_output = result.encoder_last_hidden_state + + self.parent.assertEqual(encoder_output.size(), (self.batch_size, self.encoder_seq_length, self.hidden_size)) + self.parent.assertEqual(decoder_output.size(), (self.batch_size, self.decoder_seq_length, self.hidden_size)) + # There should be `num_layers` key value embeddings stored in decoder_past + self.parent.assertEqual(len(decoder_past), config.num_layers) + # There should be a self attn key, a self attn value, a cross attn key and a cross attn value stored in each decoder_past tuple + self.parent.assertEqual(len(decoder_past[0]), 4) + + def create_and_check_with_lm_head( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5ForConditionalGeneration(config=config).to(torch_device).eval() + outputs = model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + labels=lm_labels, + ) + self.parent.assertEqual(len(outputs), 4) + self.parent.assertEqual(outputs["logits"].size(), (self.batch_size, self.decoder_seq_length, self.vocab_size)) + self.parent.assertEqual(outputs["loss"].size(), ()) + + def create_and_check_decoder_model_past( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5Model(config=config).get_decoder().to(torch_device).eval() + # first forward pass + outputs = model(input_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids) + outputs_no_past = model(input_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + + output_from_no_past = model(next_input_ids)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_decoder_model_attention_mask_past( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5Model(config=config).get_decoder() + model.to(torch_device) + model.eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + + half_seq_length = input_ids.shape[-1] // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + output, past_key_values = model(input_ids, attention_mask=attn_mask, use_cache=True).to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values, attention_mask=attn_mask)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_decoder_model_past_large_inputs( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5Model(config=config).get_decoder().to(torch_device).eval() + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_mask = ids_tensor((self.batch_size, 3), vocab_size=2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([attention_mask, next_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def create_and_check_generate_with_past_key_values( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + model = LongT5ForConditionalGeneration(config=config).to(torch_device).eval() + torch.manual_seed(0) + output_without_past_cache = model.generate( + input_ids[:1], num_beams=2, max_length=5, do_sample=True, use_cache=False + ) + torch.manual_seed(0) + output_with_past_cache = model.generate(input_ids[:1], num_beams=2, max_length=5, do_sample=True) + self.parent.assertTrue(torch.all(output_with_past_cache == output_without_past_cache)) + + def create_and_check_encoder_decoder_shared_weights( + self, + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ): + for model_class in [LongT5Model, LongT5ForConditionalGeneration]: + torch.manual_seed(0) + model = model_class(config=config).to(torch_device).eval() + # load state dict copies weights but does not tie them + model.encoder.load_state_dict(model.decoder.state_dict(), strict=False) + + torch.manual_seed(0) + tied_config = copy.deepcopy(config) + tied_config.tie_encoder_decoder = True + tied_model = model_class(config=tied_config).to(torch_device).eval() + + model_result = model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + tied_model_result = tied_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + # check that models has less parameters + self.parent.assertLess( + sum(p.numel() for p in tied_model.parameters()), sum(p.numel() for p in model.parameters()) + ) + random_slice_idx = ids_tensor((1,), model_result[0].shape[-1]).item() + + # check that outputs are equal + self.parent.assertTrue( + torch.allclose( + model_result[0][0, :, random_slice_idx], tied_model_result[0][0, :, random_slice_idx], atol=1e-4 + ) + ) + + # check that outputs after saving and loading are equal + with tempfile.TemporaryDirectory() as tmpdirname: + tied_model.save_pretrained(tmpdirname) + tied_model = model_class.from_pretrained(tmpdirname) + tied_model.to(torch_device) + tied_model.eval() + + # check that models has less parameters + self.parent.assertLess( + sum(p.numel() for p in tied_model.parameters()), sum(p.numel() for p in model.parameters()) + ) + random_slice_idx = ids_tensor((1,), model_result[0].shape[-1]).item() + + tied_model_result = tied_model( + input_ids=input_ids, + decoder_input_ids=decoder_input_ids, + attention_mask=attention_mask, + decoder_attention_mask=decoder_attention_mask, + ) + + # check that outputs are equal + self.parent.assertTrue( + torch.allclose( + model_result[0][0, :, random_slice_idx], + tied_model_result[0][0, :, random_slice_idx], + atol=1e-4, + ) + ) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + "decoder_input_ids": decoder_input_ids, + "decoder_attention_mask": decoder_attention_mask, + "use_cache": False, + } + return config, inputs_dict + + +@require_torch +class LongT5ModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (LongT5Model, LongT5ForConditionalGeneration) if is_torch_available() else () + all_generative_model_classes = (LongT5ForConditionalGeneration,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": LongT5ForConditionalGeneration, + "feature-extraction": LongT5Model, + "summarization": LongT5ForConditionalGeneration, + "text2text-generation": LongT5ForConditionalGeneration, + "translation": LongT5ForConditionalGeneration, + } + if is_torch_available() + else {} + ) + fx_compatible = False + test_pruning = False + test_torchscript = True + test_resize_embeddings = True + test_model_parallel = False + is_encoder_decoder = True + + def setUp(self): + self.model_tester = LongT5ModelTester(self) + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_shift_right(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.check_prepare_lm_labels_via_shift_left(*config_and_inputs) + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_with_lm_head(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_with_lm_head(*config_and_inputs) + + def test_decoder_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past(*config_and_inputs) + + def test_decoder_model_past_with_attn_mask(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_attention_mask_past(*config_and_inputs) + + def test_decoder_model_past_with_3d_attn_mask(self): + ( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ) = self.model_tester.prepare_config_and_inputs() + + attention_mask = ids_tensor( + [self.model_tester.batch_size, self.model_tester.encoder_seq_length, self.model_tester.encoder_seq_length], + vocab_size=2, + ) + decoder_attention_mask = ids_tensor( + [self.model_tester.batch_size, self.model_tester.decoder_seq_length, self.model_tester.decoder_seq_length], + vocab_size=2, + ) + + self.model_tester.create_and_check_decoder_model_attention_mask_past( + config, + input_ids, + decoder_input_ids, + attention_mask, + decoder_attention_mask, + lm_labels, + ) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_generate_with_past_key_values(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_generate_with_past_key_values(*config_and_inputs) + + def test_encoder_decoder_shared_weights(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_encoder_decoder_shared_weights(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in LONGT5_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = LongT5Model.from_pretrained(model_name) + self.assertIsNotNone(model) + + @unittest.skipIf( + not is_torch_available() or is_torch_less_than_1_11, + "Test failed with torch < 1.11 with an exception in a C++ file.", + ) + @slow + def test_export_to_onnx(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + model = LongT5Model(config_and_inputs[0]).to(torch_device) + with tempfile.TemporaryDirectory() as tmpdirname: + torch.onnx.export( + model, + (config_and_inputs[1], config_and_inputs[3], config_and_inputs[2]), + f"{tmpdirname}/longt5_test.onnx", + export_params=True, + opset_version=13, + input_names=["input_ids", "decoder_input_ids"], + ) + + def test_generate_with_head_masking(self): + attention_names = ["encoder_attentions", "decoder_attentions", "cross_attentions"] + config_and_inputs = self.model_tester.prepare_config_and_inputs() + config = config_and_inputs[0] + max_length = config_and_inputs[1].shape[-1] + 3 + model = LongT5ForConditionalGeneration(config).eval() + model.to(torch_device) + + head_masking = { + "head_mask": torch.zeros(config.num_layers, config.num_heads, device=torch_device), + "decoder_head_mask": torch.zeros(config.num_decoder_layers, config.num_heads, device=torch_device), + "cross_attn_head_mask": torch.zeros(config.num_decoder_layers, config.num_heads, device=torch_device), + } + + for attn_name, (name, mask) in zip(attention_names, head_masking.items()): + head_masks = {name: mask} + # Explicitly pass decoder_head_mask as it is required from LONGT5 model when head_mask specified + if name == "head_mask": + head_masks["decoder_head_mask"] = torch.ones( + config.num_decoder_layers, config.num_heads, device=torch_device + ) + + out = model.generate( + config_and_inputs[1], + num_beams=1, + max_length=max_length, + output_attentions=True, + return_dict_in_generate=True, + **head_masks, + ) + # We check the state of decoder_attentions and cross_attentions just from the last step + attn_weights = out[attn_name] if attn_name == attention_names[0] else out[attn_name][-1] + self.assertEqual(sum([w.sum().item() for w in attn_weights]), 0.0) + + def test_attention_outputs(self): + if not self.has_attentions: + pass + + else: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + block_len = getattr(self.model_tester, "block_len", None) + + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Question Answering model returns start_logits and end_logits + if model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + + def _check_encoder_attention_for_generate(self, attentions, batch_size, config, seq_length): + block_len = getattr(self.model_tester, "block_len", None) + encoder_expected_shape = (batch_size, 1, config.num_attention_heads, block_len, 3 * block_len) + self.assertIsInstance(attentions, tuple) + self.assertListEqual( + [layer_attentions.shape for layer_attentions in attentions], + [encoder_expected_shape] * len(attentions), + ) + + +@require_torch +class LongT5TGlobalModelTest(LongT5ModelTest): + def setUp(self): + self.model_tester = LongT5ModelTester( + self, encoder_attention_type="transient-global", large_model_config_path="google/long-t5-tglobal-large" + ) + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_attention_outputs(self): + if not self.has_attentions: + pass + + else: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + block_len = getattr(self.model_tester, "block_len", None) + global_block_size = getattr(self.model_tester, "global_block_size", None) + global_seq_len = encoder_seq_length // global_block_size + + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Question Answering model returns start_logits and end_logits + if model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + + def _check_encoder_attention_for_generate(self, attentions, batch_size, config, seq_length): + block_len = getattr(self.model_tester, "block_len", None) + global_block_size = getattr(self.model_tester, "global_block_size", None) + global_seq_length = seq_length // global_block_size + encoder_expected_shape = ( + batch_size, + 1, + config.num_attention_heads, + block_len, + 3 * block_len + global_seq_length, + ) + self.assertIsInstance(attentions, tuple) + self.assertListEqual( + [layer_attentions.shape for layer_attentions in attentions], + [encoder_expected_shape] * len(attentions), + ) + + +class LongT5EncoderOnlyModelTester: + def __init__( + self, + parent, + vocab_size=99, + batch_size=13, + encoder_seq_length=7, + local_radius=5, + encoder_attention_type="local", + global_block_size=3, + # For common tests + use_attention_mask=True, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + d_ff=37, + relative_attention_num_buckets=8, + is_training=False, + dropout_rate=0.1, + initializer_factor=0.002, + is_encoder_decoder=False, + eos_token_id=1, + pad_token_id=0, + scope=None, + large_model_config_path="google/long-t5-local-large", + ): + self.parent = parent + self.batch_size = batch_size + self.encoder_seq_length = encoder_seq_length + self.local_radius = local_radius + self.block_len = local_radius + 1 + self.encoder_attention_type = encoder_attention_type + self.global_block_size = global_block_size + # For common tests + self.seq_length = self.encoder_seq_length + self.use_attention_mask = use_attention_mask + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.d_ff = d_ff + self.relative_attention_num_buckets = relative_attention_num_buckets + self.dropout_rate = dropout_rate + self.initializer_factor = initializer_factor + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.is_encoder_decoder = is_encoder_decoder + self.scope = None + self.is_training = is_training + self.large_model_config_path = large_model_config_path + + def get_large_model_config(self): + return LongT5Config.from_pretrained(self.large_model_config_path) + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.encoder_seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = ids_tensor([self.batch_size, self.encoder_seq_length], vocab_size=2) + + config = LongT5Config( + vocab_size=self.vocab_size, + d_model=self.hidden_size, + d_ff=self.d_ff, + d_kv=self.hidden_size // self.num_attention_heads, + num_layers=self.num_hidden_layers, + num_heads=self.num_attention_heads, + relative_attention_num_buckets=self.relative_attention_num_buckets, + dropout_rate=self.dropout_rate, + initializer_factor=self.initializer_factor, + eos_token_id=self.eos_token_id, + bos_token_id=self.pad_token_id, + pad_token_id=self.pad_token_id, + is_encoder_decoder=self.is_encoder_decoder, + local_radius=self.local_radius, + encoder_attention_type=self.encoder_attention_type, + global_block_size=self.global_block_size, + ) + + return ( + config, + input_ids, + attention_mask, + ) + + def create_and_check_model( + self, + config, + input_ids, + attention_mask, + ): + model = LongT5EncoderModel(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids=input_ids, + attention_mask=attention_mask, + ) + result = model(input_ids=input_ids) + encoder_output = result.last_hidden_state + + self.parent.assertEqual(encoder_output.size(), (self.batch_size, self.encoder_seq_length, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + attention_mask, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + } + return config, inputs_dict + + +class LongT5EncoderOnlyModelTest(ModelTesterMixin, unittest.TestCase): + all_model_classes = (LongT5EncoderModel,) if is_torch_available() else () + test_pruning = False + test_torchscript = True + test_resize_embeddings = False + test_model_parallel = False + + def setUp(self): + self.model_tester = LongT5EncoderOnlyModelTester(self) + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + def test_attention_outputs(self): + if not self.has_attentions: + pass + + else: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + block_len = getattr(self.model_tester, "block_len", 4) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len], + ) + + +class LongT5EncoderOnlyTGlobalModelTest(LongT5EncoderOnlyModelTest): + def setUp(self): + self.model_tester = LongT5EncoderOnlyModelTester( + self, encoder_attention_type="transient-global", large_model_config_path="google/long-t5-tglobal-large" + ) + self.config_tester = ConfigTester(self, config_class=LongT5Config, d_model=37) + + def test_attention_outputs(self): + if not self.has_attentions: + pass + + else: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + block_len = getattr(self.model_tester, "block_len", None) + seq_len = getattr(self.model_tester, "seq_length", None) + global_block_size = getattr(self.model_tester, "global_block_size", 4) + global_seq_len = seq_len // global_block_size + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, block_len, 3 * block_len + global_seq_len], + ) + + +def use_task_specific_params(model, task): + model.config.update(model.config.task_specific_params[task]) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class LongT5ModelIntegrationTests(unittest.TestCase): + @cached_property + def model(self): + return LongT5ForConditionalGeneration.from_pretrained("Stancld/longt5-tglobal-large-16384-pubmed-3k_steps").to( + torch_device + ) + + @cached_property + def tokenizer(self): + return AutoTokenizer.from_pretrained("Stancld/longt5-tglobal-large-16384-pubmed-3k_steps") + + def expected_summary(self): + return [ + "background : coronary artery disease ( cad ) is the emerging cause of morbidity and mortality in" + " developing world . it provides an excellent resolution for visualization of the coronaryarteries for" + " catheter - based or operating interventions . although the association of this technique with major" + " complications such as mortality is highly uncommon , it is frequently associated with various cardiac" + " and noncardiac complications.materials and methods : in aortic stenosis , we aimed to report the" + " diagnostic performance of 128-slice computed tomography coronary angiogram in 50 patients undergoing for" + " major noncoron ary cardiac surgery referred" + ] + + @slow + def test_summarization(self): + model = self.model + tok = self.tokenizer + + ARTICLE = """coronary artery disease ( cad ) is the emerging cause of morbidity and mortality in developing world . \n it provides an excellent resolution for visualization of the coronary arteries for catheter - based or operating interventions . \n + although the association of this technique with major complications such as mortality is highly uncommon , it is frequently associated with various cardiac and noncardiac complications . computed tomography ( ct ) coronary angiography is + a promising technique for the evaluation of cad noninvasively . \n it assesses disease within the coronary artery and provides qualitative and quantitative information about nonobstructive atherosclerotic plaque burden within the vessel + wall . \n thus , ct angiography - based disease evaluation may provide clinically more significant information than conventional angiography . the introduction of multi - slice computed tomography ( msct ) technology such as 64-slice , 12 + 8-slice , 256-slice , and now 320-slice msct has produced a high diagnostic accuracy of ct coronary angiography . \n it has consistently showed to have a very high negative predictive value ( well above 90% ) in ruling out patients with s + ignificant cad defined as coronary luminal stenosis of > 50% . \n the american college of cardiology / american heart association recommends that coronary angiography should be performed before valve surgery in men aged > 40 years , women + aged > 35 years with coronary risk factors and in postmenopausal women . \n the prevalence of cad in patients undergoing valve replacement is 2040% in developed countries . in the previous studies , \n the incidence of angiographically p + roven cad in acquired valvular diseases has been shown to vary widely from 9% to 41% . in aortic stenosis , \n we aimed to report the diagnostic performance of 128-slice ct coronary angiography in 50 patients undergoing for major noncoron + ary cardiac surgery referred for diagnostic invasive coronary angiography to assess the extent and severity of coronary stenosis . \n during january 2013 to december 2014 , we enrolled fifty major noncoronary cardiac surgery patients sche + duled for invasive coronary angiography who fulfilled the following inclusion criteria of age 40 years , having low or intermediate probability of cad , left ventricular ejection fraction ( lvef ) > 35% , and patient giving informed conse + nt for undergoing msct and conventional coronary angiography . \n those having any contraindication for contrast injection , lvef < 35% , high pretest probability of cad , and hemodynamic instability were excluded from the study . \n pati + ents with heart rates of > 70 bpm received ( unless they had known overt heart failure or electrocardiogram ( ecg ) atrioventricular conduction abnormalities ) a single oral dose of 100 mg metoprolol 45 min before the scan . \n patients w + ith heart rates of > 80 bpm received an additional oral dose of metoprolol if not contraindicated . \n all patients were scanned with a 128-slice ct scanner ( siemens , somatom definition as ) equipped with a new feature in msct technolog + y , so - called z - axis flying - focus technology . \n the central 32 detector rows acquire 0.6-mm slices , and the flying - focus spot switches back and forth between 2 z positions between each reading . \n two slices per detector row a + re acquired , which results in a higher oversampling rate in the z - axis , thereby reducing artifacts related to the spiral acquisition and improving spatial resolution down to 0.4 mm . \n a bolus of 6580 ml contrast material ( omnipaque + ) was injected through an arm vein at a flow rate of 5 ml / s . \n a bolus tracking technique was used to synchronize the arrival of contrast in the coronary arteries with the initiation of the scan . to monitor the arrival of contrast m + aterial , \n axial scans were obtained at the level of the ascending aorta with a delay of 10 s after the start of the contrast injection . \n the scan was automatically started when a threshold of 150 hounsfield units was reached in a re + gion of interest positioned in the ascending aorta . \n images were reconstructed with ecg gating to obtain optimal , motion - free image quality . \n all scans were performed within 2 weeks of the msct coronary diagnostic angiogram . a s + ingle observer unaware of the multi - slice ct results identified coronary lesion as a single vessel , double vessel , or triple vessel disease . \n all lesion , regardless of size , were included for comparison with ct coronary angiograp + hy . \n lesions were classified as having nonsignificant disease ( luminal irregularities or < 50% stenosis ) or as having significant stenosis . \n stenosis was evaluated in two orthogonal views and classified as significant if the mean + lumen diameter reduction was 50% using a validated quantitative coronary angiography ( qca ) . \n all scans were analyzed independently by a radiologist and a cardiologist who were unaware of the results of conventional coronary angiograp + hy . \n total calcium scores of all patients were calculated with dedicated software and expressed as agatston scores . \n the agatston score is a commonly used scoring method that calculates the total amount of calcium on the basis of th + e number , areas , and peak hounsfield units of the detected calcified lesions . \n all available coronary segments were visually scored for the presence of > 50% considered as significant stenosis . \n maximum intensity projections were + used to identify coronary lesions and ( curved ) multiplanar reconstructions to classify lesions as significant or nonsignificant . \n data were analyzed using statistical system spss version 20 software ( chicago , il , usa ) . \n the di + agnostic performance of ct coronary angiography for the detection of significant lesions in coronary arteries with qca as the standard of reference is presented as sensitivity , specificity , positive and negative predictive values , and + positive and negative likelihood ratios with the corresponding exact 95% of confidence interval ( cis ) . \n comparison between ct and conventional coronary angiography was performed on the two level vessel by vessel ( no or any disease p + er vessel ) , and patient by patient ( no or any disease per patient ) . \n all scans were performed within 2 weeks of the msct coronary diagnostic angiogram . a single observer unaware of the multi - slice ct results identified coronary + lesion as a single vessel , double vessel , or triple vessel disease . \n all lesion , regardless of size , were included for comparison with ct coronary angiography . \n lesions were classified as having nonsignificant disease ( luminal + irregularities or < 50% stenosis ) or as having significant stenosis . \n stenosis was evaluated in two orthogonal views and classified as significant if the mean lumen diameter reduction was 50% using a validated quantitative coronary an + giography ( qca ) . \n all scans were analyzed independently by a radiologist and a cardiologist who were unaware of the results of conventional coronary angiography . \n total calcium scores of all patients were calculated with dedicated + software and expressed as agatston scores . \n the agatston score is a commonly used scoring method that calculates the total amount of calcium on the basis of the number , areas , and peak hounsfield units of the detected calcified lesi + ons . \n all available coronary segments were visually scored for the presence of > 50% considered as significant stenosis . \n maximum intensity projections were used to identify coronary lesions and ( curved ) multiplanar reconstruction + s to classify lesions as significant or nonsignificant . \n data were analyzed using statistical system spss version 20 software ( chicago , il , usa ) . \n the diagnostic performance of ct coronary angiography for the detection of signif + icant lesions in coronary arteries with qca as the standard of reference is presented as sensitivity , specificity , positive and negative predictive values , and positive and negative likelihood ratios with the corresponding exact 95% of + confidence interval ( cis ) . \n comparison between ct and conventional coronary angiography was performed on the two level vessel by vessel ( no or any disease per vessel ) , and patient by patient ( no or any disease per patient ) . \n + in this study , 29 ( 58% ) subjects were female , and 21 ( 42% ) were male showing an average age of 50.36 8.39 years . \n of fifty patients 24 ( 48% ) , 13 ( 26% ) , eight ( 16% ) , and five ( 10% ) underwent mitral valve replacement , + double valve replacement ( dvr ) , aortic valve replacement , and other surgeries , respectively . \n high distribution of cad risk factors such as hypertension ( 24% ) , smoking ( 22% ) , and dyslipidemia ( 18% ) was observed in the stu + dy group . \n the mean creatinine level was 0.766 0.17 and average dye used in conventional angiography was 48.5 26.6 whereas for ct angiography it was 72.8 6.32 . \n average radiation dose in conventional coronary angiography and msct + coronary angiography was 5.2 msv and 9.2 msv , respectively . \n the majority of the patients had sinus rhythm ( 68% ) , whereas atrial fibrillation was found in 32% of the subjects . \n patients included in the study had low to intermed + iate probability of cad . in this study , three patients had complications after conventional angiography . \n complications were of local site hematoma , acute kidney injury managed conservatively , and acute heart failure . \n a patient + who developed hematoma was obese female patients with body mass index > 30 kg / m . \n the patient suffered from pseudoaneurysm , had hospitalized for 9 days , which leads to increased morbidity and cost of hospital stay . \n the diagnos + tic accuracy of ct coronary angiography was evaluated regarding true positive , true negative values and is presented in table 1 . the overall sensitivity and \n specificity of ct angiography technique was 100% ( 95% ci : 39.76%100% ) and + 91.30% ( 95% ci : 79.21%97.58% ) , respectively [ table 2 ] . \n the positive predictive value ( 50% ; 95% ci : 15.70%84.30% ) and negative predictive value ( 100% ; 95% ci : 91.59%100% ) of ct angiography were also fairly high in these + patients . \n recent reports from multiple studies demonstrated that recent - generation msct scanners showed promise for noninvasive detection of coronary stenosis however , until now no studies were found regarding the clinical efficacy + or prognostic value of 128-slice ct coronary angiography versus conventional invasive coronary angiography in the diagnosis of patients planned for major noncoronary surgeries such as dvr , bentall , atrial septal defect closure , etc . + in our study , we reported 8% cad prevalence in patients planned for major noncoronary cardiac surgery . \n we performed conventional and msct coronary angiography in all patients and the results showed that ct coronary angiography with i + nvasive coronary angiography as the reference standard had a considerably high sensitivity ( 100% ) and specificity ( 95.65% ) . \n the health economic model using invasive coronary angiography as the reference standard showed that at a p + retest probability of cad of 70% or lower , ct coronary angiography resulted in lower cost per patient with a true positive diagnosis . at a pretest probability of cad of 70% or higher , invasive coronary angiography was associated with a + lower cost per patient with a true positive diagnosis . in our study population , \n two patients developed local site complications in the form of hematoma and pseudoaneurysm after conventional angiography . \n hence , msct coronary ang + iography will be more favorable in female obese patients with intermediate likelihood of cad . \n hence , msct coronary angiography will be cost - effective in patients of valvular heart diseases . \n however , ct angiography suffers from + a drawback that average amount of dye used in msct coronary angiography were 72.8 6.32 ml which is higher than average amount of dye required for conventional angiography ( 48.6 26.6 ml ) . \n hence , the use of ct coronary angiography + could not be used in patients with known renal dysfunction , where reduction of contrast dye load is highly advocated . \n our results show that 128-slice ct coronary angiography is a reliable technique to detect coronary stenosis in pat + ients planned for noncoronary cardiac surgery . \n although there has been important technological progress in the development of ct coronary angiography , its clinical application remains limited . \n a study wth large numbers of patient + s is required for the recommendation of only ct coronary angiography for the coronary evaluation in major non - cardiac surgeries . \n mehta institute of cardiology and research center ( affiliated to bj medical college , ahmedabad , guja + rat , india ) . \n u.n . mehta institute of cardiology and research center ( affiliated to bj medical college , ahmedabad , gujarat , india ) . \n """ + + dct = tok( + [ARTICLE], + max_length=1024, + padding="max_length", + truncation=True, + return_tensors="pt", + ).to(torch_device) + + hypotheses_batch = model.generate( + **dct, + num_beams=4, + length_penalty=2.0, + max_length=142, + min_length=56, + no_repeat_ngram_size=3, + do_sample=False, + early_stopping=True, + ) + + decoded = tok.batch_decode(hypotheses_batch, skip_special_tokens=True, clean_up_tokenization_spaces=False) + self.assertListEqual( + self.expected_summary(), + decoded, + ) + + @slow + def test_inference_hidden_states(self): + model = self.model + + input_ids = torch.tensor( + [[100, 19, 3, 9, 7142, 1200, 145, 8, 1252, 14145, 2034, 812, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], + dtype=torch.long, + device=torch_device, + ) + decoder_input_ids = torch.tensor( + [[100, 19, 3, 9, 7142, 1200, 145, 8, 1252, 14145, 2034, 812, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], + dtype=torch.long, + device=torch_device, + ) + attention_mask = torch.tensor( + [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], + dtype=torch.long, + device=torch_device, + ) + + output = model( + input_ids, attention_mask=attention_mask, decoder_input_ids=decoder_input_ids, output_hidden_states=True + ) + + # check if encoder_outputs match + expected_output_slice = torch.tensor([0.0629, -0.1294, -0.0089, 0.0772, 0.0663], device=torch_device) + self.assertTrue(torch.allclose(output.encoder_hidden_states[-1][0, 0, :5], expected_output_slice, atol=1e-4)) + + # check if logits match + expected_output_slice = torch.tensor([5.5231, 6.1058, 3.1766, 8.2391, -5.9453], device=torch_device) + self.assertTrue(torch.allclose(output.logits[0, 0, :5], expected_output_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_modeling_luke.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_modeling_luke.py new file mode 100644 index 0000000000000000000000000000000000000000..35bdb6b6d5fa6acf379bd799d759e57671423fe9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_modeling_luke.py @@ -0,0 +1,929 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch LUKE model. """ +import unittest + +from transformers import LukeConfig, is_torch_available +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + LukeForEntityClassification, + LukeForEntityPairClassification, + LukeForEntitySpanClassification, + LukeForMaskedLM, + LukeForMultipleChoice, + LukeForQuestionAnswering, + LukeForSequenceClassification, + LukeForTokenClassification, + LukeModel, + LukeTokenizer, + ) + from transformers.models.luke.modeling_luke import LUKE_PRETRAINED_MODEL_ARCHIVE_LIST + + +class LukeModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + entity_length=3, + mention_length=5, + use_attention_mask=True, + use_token_type_ids=True, + use_entity_ids=True, + use_entity_attention_mask=True, + use_entity_token_type_ids=True, + use_entity_position_ids=True, + use_labels=True, + vocab_size=99, + entity_vocab_size=10, + entity_emb_size=6, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=16, + type_sequence_label_size=2, + initializer_range=0.02, + num_labels=3, + num_choices=4, + num_entity_classification_labels=9, + num_entity_pair_classification_labels=6, + num_entity_span_classification_labels=4, + use_entity_aware_attention=True, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.entity_length = entity_length + self.mention_length = mention_length + self.use_attention_mask = use_attention_mask + self.use_token_type_ids = use_token_type_ids + self.use_entity_ids = use_entity_ids + self.use_entity_attention_mask = use_entity_attention_mask + self.use_entity_token_type_ids = use_entity_token_type_ids + self.use_entity_position_ids = use_entity_position_ids + self.use_labels = use_labels + self.vocab_size = vocab_size + self.entity_vocab_size = entity_vocab_size + self.entity_emb_size = entity_emb_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.type_sequence_label_size = type_sequence_label_size + self.initializer_range = initializer_range + self.num_labels = num_labels + self.num_choices = num_choices + self.num_entity_classification_labels = num_entity_classification_labels + self.num_entity_pair_classification_labels = num_entity_pair_classification_labels + self.num_entity_span_classification_labels = num_entity_span_classification_labels + self.scope = scope + self.use_entity_aware_attention = use_entity_aware_attention + + self.encoder_seq_length = seq_length + self.key_length = seq_length + self.num_hidden_states_types = 2 # hidden_states and entity_hidden_states + + def prepare_config_and_inputs(self): + # prepare words + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = random_attention_mask([self.batch_size, self.seq_length]) + + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + + # prepare entities + entity_ids = ids_tensor([self.batch_size, self.entity_length], self.entity_vocab_size) + + entity_attention_mask = None + if self.use_entity_attention_mask: + entity_attention_mask = random_attention_mask([self.batch_size, self.entity_length]) + + entity_token_type_ids = None + if self.use_token_type_ids: + entity_token_type_ids = ids_tensor([self.batch_size, self.entity_length], self.type_vocab_size) + + entity_position_ids = None + if self.use_entity_position_ids: + entity_position_ids = ids_tensor( + [self.batch_size, self.entity_length, self.mention_length], self.mention_length + ) + + sequence_labels = None + token_labels = None + choice_labels = None + entity_labels = None + entity_classification_labels = None + entity_pair_classification_labels = None + entity_span_classification_labels = None + + if self.use_labels: + sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size) + token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels) + choice_labels = ids_tensor([self.batch_size], self.num_choices) + + entity_labels = ids_tensor([self.batch_size, self.entity_length], self.entity_vocab_size) + + entity_classification_labels = ids_tensor([self.batch_size], self.num_entity_classification_labels) + entity_pair_classification_labels = ids_tensor( + [self.batch_size], self.num_entity_pair_classification_labels + ) + entity_span_classification_labels = ids_tensor( + [self.batch_size, self.entity_length], self.num_entity_span_classification_labels + ) + + config = self.get_config() + + return ( + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ) + + def get_config(self): + return LukeConfig( + vocab_size=self.vocab_size, + entity_vocab_size=self.entity_vocab_size, + entity_emb_size=self.entity_emb_size, + hidden_size=self.hidden_size, + num_hidden_layers=self.num_hidden_layers, + num_attention_heads=self.num_attention_heads, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + is_decoder=False, + initializer_range=self.initializer_range, + use_entity_aware_attention=self.use_entity_aware_attention, + ) + + def create_and_check_model( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + model = LukeModel(config=config) + model.to(torch_device) + model.eval() + # test with words + entities + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + ) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual( + result.entity_last_hidden_state.shape, (self.batch_size, self.entity_length, self.hidden_size) + ) + + # test with words only + result = model(input_ids, token_type_ids=token_type_ids) + result = model(input_ids) + self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size)) + + def create_and_check_for_masked_lm( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_entity_classification_labels + model = LukeForMaskedLM(config) + model.to(torch_device) + model.eval() + + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + labels=token_labels, + entity_labels=entity_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + if entity_ids is not None: + self.parent.assertEqual( + result.entity_logits.shape, (self.batch_size, self.entity_length, self.entity_vocab_size) + ) + else: + self.parent.assertIsNone(result.entity_logits) + + def create_and_check_for_entity_classification( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_entity_classification_labels + model = LukeForEntityClassification(config) + model.to(torch_device) + model.eval() + + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + labels=entity_classification_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_entity_classification_labels)) + + def create_and_check_for_entity_pair_classification( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_entity_pair_classification_labels + model = LukeForEntityClassification(config) + model.to(torch_device) + model.eval() + + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + labels=entity_pair_classification_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_entity_pair_classification_labels)) + + def create_and_check_for_entity_span_classification( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_entity_span_classification_labels + model = LukeForEntitySpanClassification(config) + model.to(torch_device) + model.eval() + + entity_start_positions = ids_tensor([self.batch_size, self.entity_length], self.seq_length) + entity_end_positions = ids_tensor([self.batch_size, self.entity_length], self.seq_length) + + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + entity_start_positions=entity_start_positions, + entity_end_positions=entity_end_positions, + labels=entity_span_classification_labels, + ) + self.parent.assertEqual( + result.logits.shape, (self.batch_size, self.entity_length, self.num_entity_span_classification_labels) + ) + + def create_and_check_for_question_answering( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + model = LukeForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + start_positions=sequence_labels, + end_positions=sequence_labels, + ) + self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length)) + self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length)) + + def create_and_check_for_sequence_classification( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_labels + model = LukeForSequenceClassification(config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + labels=sequence_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels)) + + def create_and_check_for_token_classification( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_labels = self.num_labels + model = LukeForTokenClassification(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + attention_mask=attention_mask, + token_type_ids=token_type_ids, + entity_ids=entity_ids, + entity_attention_mask=entity_attention_mask, + entity_token_type_ids=entity_token_type_ids, + entity_position_ids=entity_position_ids, + labels=token_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels)) + + def create_and_check_for_multiple_choice( + self, + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ): + config.num_choices = self.num_choices + model = LukeForMultipleChoice(config=config) + model.to(torch_device) + model.eval() + multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_token_type_ids = token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_attention_mask = attention_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_entity_ids = entity_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + multiple_choice_entity_token_type_ids = ( + entity_token_type_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + ) + multiple_choice_entity_attention_mask = ( + entity_attention_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous() + ) + multiple_choice_entity_position_ids = ( + entity_position_ids.unsqueeze(1).expand(-1, self.num_choices, -1, -1).contiguous() + ) + result = model( + multiple_choice_inputs_ids, + attention_mask=multiple_choice_attention_mask, + token_type_ids=multiple_choice_token_type_ids, + entity_ids=multiple_choice_entity_ids, + entity_attention_mask=multiple_choice_entity_attention_mask, + entity_token_type_ids=multiple_choice_entity_token_type_ids, + entity_position_ids=multiple_choice_entity_position_ids, + labels=choice_labels, + ) + self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices)) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + attention_mask, + token_type_ids, + entity_ids, + entity_attention_mask, + entity_token_type_ids, + entity_position_ids, + sequence_labels, + token_labels, + choice_labels, + entity_labels, + entity_classification_labels, + entity_pair_classification_labels, + entity_span_classification_labels, + ) = config_and_inputs + inputs_dict = { + "input_ids": input_ids, + "token_type_ids": token_type_ids, + "attention_mask": attention_mask, + "entity_ids": entity_ids, + "entity_token_type_ids": entity_token_type_ids, + "entity_attention_mask": entity_attention_mask, + "entity_position_ids": entity_position_ids, + } + return config, inputs_dict + + +@require_torch +class LukeModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + LukeModel, + LukeForMaskedLM, + LukeForEntityClassification, + LukeForEntityPairClassification, + LukeForEntitySpanClassification, + LukeForQuestionAnswering, + LukeForSequenceClassification, + LukeForTokenClassification, + LukeForMultipleChoice, + ) + if is_torch_available() + else () + ) + pipeline_model_mapping = ( + { + "feature-extraction": LukeModel, + "fill-mask": LukeForMaskedLM, + "question-answering": LukeForQuestionAnswering, + "text-classification": LukeForSequenceClassification, + "token-classification": LukeForTokenClassification, + "zero-shot": LukeForSequenceClassification, + } + if is_torch_available() + else {} + ) + test_pruning = False + test_torchscript = False + test_resize_embeddings = True + test_head_masking = True + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name in ["QAPipelineTests", "ZeroShotClassificationPipelineTests"]: + return True + + return False + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + entity_inputs_dict = {k: v for k, v in inputs_dict.items() if k.startswith("entity")} + inputs_dict = {k: v for k, v in inputs_dict.items() if not k.startswith("entity")} + + inputs_dict = super()._prepare_for_class(inputs_dict, model_class, return_labels=return_labels) + if model_class == LukeForMultipleChoice: + entity_inputs_dict = { + k: v.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() + if v.ndim == 2 + else v.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1, -1).contiguous() + for k, v in entity_inputs_dict.items() + } + inputs_dict.update(entity_inputs_dict) + + if model_class == LukeForEntitySpanClassification: + inputs_dict["entity_start_positions"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.entity_length), dtype=torch.long, device=torch_device + ) + inputs_dict["entity_end_positions"] = torch.ones( + (self.model_tester.batch_size, self.model_tester.entity_length), dtype=torch.long, device=torch_device + ) + + if return_labels: + if model_class in ( + LukeForEntityClassification, + LukeForEntityPairClassification, + LukeForSequenceClassification, + LukeForMultipleChoice, + ): + inputs_dict["labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class == LukeForEntitySpanClassification: + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.entity_length), + dtype=torch.long, + device=torch_device, + ) + elif model_class == LukeForTokenClassification: + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), + dtype=torch.long, + device=torch_device, + ) + elif model_class == LukeForMaskedLM: + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), + dtype=torch.long, + device=torch_device, + ) + inputs_dict["entity_labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.entity_length), + dtype=torch.long, + device=torch_device, + ) + + return inputs_dict + + def setUp(self): + self.model_tester = LukeModelTester(self) + self.config_tester = ConfigTester(self, config_class=LukeConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_model(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in LUKE_PRETRAINED_MODEL_ARCHIVE_LIST: + model = LukeModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_for_masked_lm(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_masked_lm_with_word_only(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + config_and_inputs = (*config_and_inputs[:4], *((None,) * len(config_and_inputs[4:]))) + self.model_tester.create_and_check_for_masked_lm(*config_and_inputs) + + def test_for_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_question_answering(*config_and_inputs) + + def test_for_sequence_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_sequence_classification(*config_and_inputs) + + def test_for_token_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_token_classification(*config_and_inputs) + + def test_for_multiple_choice(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_multiple_choice(*config_and_inputs) + + def test_for_entity_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_entity_classification(*config_and_inputs) + + def test_for_entity_pair_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_entity_pair_classification(*config_and_inputs) + + def test_for_entity_span_classification(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_for_entity_span_classification(*config_and_inputs) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_length = self.model_tester.seq_length + entity_length = self.model_tester.entity_length + key_length = seq_length + entity_length + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length + entity_length, key_length], + ) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + added_hidden_states = self.model_tester.num_hidden_states_types + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, seq_length + entity_length, key_length], + ) + + def test_entity_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + entity_hidden_states = outputs.entity_hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(entity_hidden_states), expected_num_layers) + + entity_length = self.model_tester.entity_length + + self.assertListEqual( + list(entity_hidden_states[0].shape[-2:]), + [entity_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_retain_grad_entity_hidden_states(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + entity_hidden_states = outputs.entity_hidden_states[0] + entity_hidden_states.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(entity_hidden_states.grad) + + +@require_torch +class LukeModelIntegrationTests(unittest.TestCase): + @slow + def test_inference_base_model(self): + model = LukeModel.from_pretrained("studio-ousia/luke-base").eval() + model.to(torch_device) + + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", task="entity_classification") + text = ( + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck as a fortuitous netcord helped" + " the new world number one avoid a humiliating second- round exit at Wimbledon ." + ) + span = (39, 42) + encoding = tokenizer(text, entity_spans=[span], add_prefix_space=True, return_tensors="pt") + + # move all values to device + for key, value in encoding.items(): + encoding[key] = encoding[key].to(torch_device) + + outputs = model(**encoding) + + # Verify word hidden states + expected_shape = torch.Size((1, 42, 768)) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor( + [[0.0037, 0.1368, -0.0091], [0.1099, 0.3329, -0.1095], [0.0765, 0.5335, 0.1179]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) + + # Verify entity hidden states + expected_shape = torch.Size((1, 1, 768)) + self.assertEqual(outputs.entity_last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor([[0.1457, 0.1044, 0.0174]]).to(torch_device) + self.assertTrue(torch.allclose(outputs.entity_last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) + + @slow + def test_inference_large_model(self): + model = LukeModel.from_pretrained("studio-ousia/luke-large").eval() + model.to(torch_device) + + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-large", task="entity_classification") + text = ( + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck as a fortuitous netcord helped" + " the new world number one avoid a humiliating second- round exit at Wimbledon ." + ) + span = (39, 42) + encoding = tokenizer(text, entity_spans=[span], add_prefix_space=True, return_tensors="pt") + + # move all values to device + for key, value in encoding.items(): + encoding[key] = encoding[key].to(torch_device) + + outputs = model(**encoding) + + # Verify word hidden states + expected_shape = torch.Size((1, 42, 1024)) + self.assertEqual(outputs.last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor( + [[0.0133, 0.0865, 0.0095], [0.3093, -0.2576, -0.7418], [-0.1720, -0.2117, -0.2869]] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) + + # Verify entity hidden states + expected_shape = torch.Size((1, 1, 1024)) + self.assertEqual(outputs.entity_last_hidden_state.shape, expected_shape) + + expected_slice = torch.tensor([[0.0466, -0.0106, -0.0179]]).to(torch_device) + self.assertTrue(torch.allclose(outputs.entity_last_hidden_state[0, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_tokenization_luke.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_tokenization_luke.py new file mode 100644 index 0000000000000000000000000000000000000000..aa208f950bf3e2172aaa19b5227db4b621ca3bb5 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/luke/test_tokenization_luke.py @@ -0,0 +1,668 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from typing import Tuple + +from transformers import AddedToken, LukeTokenizer +from transformers.testing_utils import get_tests_dir, require_torch, slow + +from ...test_tokenization_common import TokenizerTesterMixin + + +SAMPLE_VOCAB = get_tests_dir("fixtures/vocab.json") +SAMPLE_MERGE_FILE = get_tests_dir("fixtures/merges.txt") +SAMPLE_ENTITY_VOCAB = get_tests_dir("fixtures/test_entity_vocab.json") + + +class LukeTokenizerTest(TokenizerTesterMixin, unittest.TestCase): + tokenizer_class = LukeTokenizer + test_rust_tokenizer = False + from_pretrained_kwargs = {"cls_token": ""} + + def setUp(self): + super().setUp() + + self.special_tokens_map = {"entity_token_1": "", "entity_token_2": ""} + + def get_tokenizer(self, task=None, **kwargs): + kwargs.update(self.special_tokens_map) + tokenizer = LukeTokenizer( + vocab_file=SAMPLE_VOCAB, + merges_file=SAMPLE_MERGE_FILE, + entity_vocab_file=SAMPLE_ENTITY_VOCAB, + task=task, + **kwargs, + ) + tokenizer.sanitize_special_tokens() + return tokenizer + + def get_input_output_texts(self, tokenizer): + input_text = "lower newer" + output_text = "lower newer" + return input_text, output_text + + def test_full_tokenizer(self): + tokenizer = self.get_tokenizer() + text = "lower newer" + bpe_tokens = ["l", "o", "w", "er", "Ġ", "n", "e", "w", "er"] + tokens = tokenizer.tokenize(text) # , add_prefix_space=True) + self.assertListEqual(tokens, bpe_tokens) + + input_tokens = tokens + [tokenizer.unk_token] + input_bpe_tokens = [0, 1, 2, 15, 10, 9, 3, 2, 15, 19] + self.assertListEqual(tokenizer.convert_tokens_to_ids(input_tokens), input_bpe_tokens) + + @slow + def test_sequence_builders(self): + tokenizer = self.tokenizer_class.from_pretrained("studio-ousia/luke-large") + + text = tokenizer.encode("sequence builders", add_special_tokens=False) + text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False) + + encoded_text_from_decode = tokenizer.encode( + "sequence builders", add_special_tokens=True, add_prefix_space=False + ) + encoded_pair_from_decode = tokenizer.encode( + "sequence builders", "multi-sequence build", add_special_tokens=True, add_prefix_space=False + ) + + encoded_sentence = tokenizer.build_inputs_with_special_tokens(text) + encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2) + + self.assertEqual(encoded_sentence, encoded_text_from_decode) + self.assertEqual(encoded_pair, encoded_pair_from_decode) + + def get_clean_sequence(self, tokenizer, max_length=20) -> Tuple[str, list]: + txt = "Beyonce lives in Los Angeles" + ids = tokenizer.encode(txt, add_special_tokens=False) + return txt, ids + + def test_space_encoding(self): + tokenizer = self.get_tokenizer() + + sequence = "Encode this sequence." + space_encoding = tokenizer.byte_encoder[" ".encode("utf-8")[0]] + + # Testing encoder arguments + encoded = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=False) + first_char = tokenizer.convert_ids_to_tokens(encoded[0])[0] + self.assertNotEqual(first_char, space_encoding) + + encoded = tokenizer.encode(sequence, add_special_tokens=False, add_prefix_space=True) + first_char = tokenizer.convert_ids_to_tokens(encoded[0])[0] + self.assertEqual(first_char, space_encoding) + + tokenizer.add_special_tokens({"bos_token": ""}) + encoded = tokenizer.encode(sequence, add_special_tokens=True) + first_char = tokenizer.convert_ids_to_tokens(encoded[1])[0] + self.assertNotEqual(first_char, space_encoding) + + # Testing spaces after special tokens + mask = "" + tokenizer.add_special_tokens( + {"mask_token": AddedToken(mask, lstrip=True, rstrip=False)} + ) # mask token has a left space + mask_ind = tokenizer.convert_tokens_to_ids(mask) + + sequence = "Encode sequence" + sequence_nospace = "Encode sequence" + + encoded = tokenizer.encode(sequence) + mask_loc = encoded.index(mask_ind) + first_char = tokenizer.convert_ids_to_tokens(encoded[mask_loc + 1])[0] + self.assertEqual(first_char, space_encoding) + + encoded = tokenizer.encode(sequence_nospace) + mask_loc = encoded.index(mask_ind) + first_char = tokenizer.convert_ids_to_tokens(encoded[mask_loc + 1])[0] + self.assertNotEqual(first_char, space_encoding) + + def test_pretokenized_inputs(self): + pass + + def test_embeded_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest("{} ({})".format(tokenizer.__class__.__name__, pretrained_name)): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + sentence = "A, AllenNLP sentence." + tokens_r = tokenizer_r.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + tokens_p = tokenizer_p.encode_plus(sentence, add_special_tokens=True, return_token_type_ids=True) + + # token_type_ids should put 0 everywhere + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + # token_type_ids should put 0 everywhere + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + # attention_mask should put 1 everywhere, so sum over length should be 1 + self.assertEqual( + sum(tokens_p["attention_mask"]) / len(tokens_p["attention_mask"]), + ) + + tokens_p_str = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + + # Rust correctly handles the space before the mask while python doesnt + self.assertSequenceEqual(tokens_p["input_ids"], [0, 250, 6, 50264, 3823, 487, 21992, 3645, 4, 2]) + + self.assertSequenceEqual( + tokens_p_str, ["", "A", ",", "", "ĠAllen", "N", "LP", "Ġsentence", ".", ""] + ) + + def test_padding_entity_inputs(self): + tokenizer = self.get_tokenizer() + + sentence = "Japanese is an East Asian language spoken by about 128 million people, primarily in Japan." + span = (15, 34) + pad_id = tokenizer.entity_vocab["[PAD]"] + mask_id = tokenizer.entity_vocab["[MASK]"] + + encoding = tokenizer([sentence, sentence], entity_spans=[[span], [span, span]], padding=True) + self.assertEqual(encoding["entity_ids"], [[mask_id, pad_id], [mask_id, mask_id]]) + + # test with a sentence with no entity + encoding = tokenizer([sentence, sentence], entity_spans=[[], [span, span]], padding=True) + self.assertEqual(encoding["entity_ids"], [[pad_id, pad_id], [mask_id, mask_id]]) + + def test_if_tokenize_single_text_raise_error_with_invalid_inputs(self): + tokenizer = self.get_tokenizer() + + sentence = "Japanese is an East Asian language spoken by about 128 million people, primarily in Japan." + spans = [(15, 34)] + entities = ["East Asian language"] + + with self.assertRaises(ValueError): + tokenizer(sentence, entities=tuple(entities), entity_spans=spans) + + with self.assertRaises(ValueError): + tokenizer(sentence, entities=entities, entity_spans=tuple(spans)) + + with self.assertRaises(ValueError): + tokenizer(sentence, entities=[0], entity_spans=spans) + + with self.assertRaises(ValueError): + tokenizer(sentence, entities=entities, entity_spans=[0]) + + with self.assertRaises(ValueError): + tokenizer(sentence, entities=entities, entity_spans=spans + [(0, 9)]) + + def test_if_tokenize_entity_classification_raise_error_with_invalid_inputs(self): + tokenizer = self.get_tokenizer(task="entity_classification") + + sentence = "Japanese is an East Asian language spoken by about 128 million people, primarily in Japan." + span = (15, 34) + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[]) + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[span, span]) + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[0]) + + def test_if_tokenize_entity_pair_classification_raise_error_with_invalid_inputs(self): + tokenizer = self.get_tokenizer(task="entity_pair_classification") + + sentence = "Japanese is an East Asian language spoken by about 128 million people, primarily in Japan." + # head and tail information + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[]) + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[0, 0]) + + def test_if_tokenize_entity_span_classification_raise_error_with_invalid_inputs(self): + tokenizer = self.get_tokenizer(task="entity_span_classification") + + sentence = "Japanese is an East Asian language spoken by about 128 million people, primarily in Japan." + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[]) + + with self.assertRaises(ValueError): + tokenizer(sentence, entity_spans=[0, 0, 0]) + + +@slow +@require_torch +class LukeTokenizerIntegrationTests(unittest.TestCase): + tokenizer_class = LukeTokenizer + from_pretrained_kwargs = {"cls_token": ""} + + def setUp(self): + super().setUp() + + def test_single_text_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + entities = ["Ana Ivanovic", "Thursday", "Dummy Entity"] + spans = [(9, 21), (30, 38), (39, 42)] + + encoding = tokenizer(sentence, entities=entities, entity_spans=spans, return_token_type_ids=True) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][3:6], spaces_between_special_tokens=False), " Ana Ivanovic" + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][8:9], spaces_between_special_tokens=False), " Thursday" + ) + self.assertEqual(tokenizer.decode(encoding["input_ids"][9:10], spaces_between_special_tokens=False), " she") + + self.assertEqual( + encoding["entity_ids"], + [ + tokenizer.entity_vocab["Ana Ivanovic"], + tokenizer.entity_vocab["Thursday"], + tokenizer.entity_vocab["[UNK]"], + ], + ) + self.assertEqual(encoding["entity_attention_mask"], [1, 1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + ] + ) + # fmt: on + + def test_single_text_only_entity_spans_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + spans = [(9, 21), (30, 38), (39, 42)] + + encoding = tokenizer(sentence, entity_spans=spans, return_token_type_ids=True) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][3:6], spaces_between_special_tokens=False), " Ana Ivanovic" + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][8:9], spaces_between_special_tokens=False), " Thursday" + ) + self.assertEqual(tokenizer.decode(encoding["input_ids"][9:10], spaces_between_special_tokens=False), " she") + + mask_id = tokenizer.entity_vocab["[MASK]"] + self.assertEqual(encoding["entity_ids"], [mask_id, mask_id, mask_id]) + self.assertEqual(encoding["entity_attention_mask"], [1, 1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ], + [9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ] + ] + ) + # fmt: on + + def test_single_text_padding_pytorch_tensors(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + entities = ["Ana Ivanovic", "Thursday", "Dummy Entity"] + spans = [(9, 21), (30, 38), (39, 42)] + + encoding = tokenizer( + sentence, + entities=entities, + entity_spans=spans, + return_token_type_ids=True, + padding="max_length", + max_length=30, + max_entity_length=16, + return_tensors="pt", + ) + + # test words + self.assertEqual(encoding["input_ids"].shape, (1, 30)) + self.assertEqual(encoding["attention_mask"].shape, (1, 30)) + self.assertEqual(encoding["token_type_ids"].shape, (1, 30)) + + # test entities + self.assertEqual(encoding["entity_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_attention_mask"].shape, (1, 16)) + self.assertEqual(encoding["entity_token_type_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_position_ids"].shape, (1, 16, tokenizer.max_mention_length)) + + def test_text_pair_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday" + sentence_pair = "She could hardly believe her luck." + entities = ["Ana Ivanovic", "Thursday"] + entities_pair = ["Dummy Entity"] + spans = [(9, 21), (30, 38)] + spans_pair = [(0, 3)] + + encoding = tokenizer( + sentence, + sentence_pair, + entities=entities, + entities_pair=entities_pair, + entity_spans=spans, + entity_spans_pair=spans_pair, + return_token_type_ids=True, + ) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on ThursdayShe could hardly believe her luck.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][3:6], spaces_between_special_tokens=False), " Ana Ivanovic" + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][8:9], spaces_between_special_tokens=False), " Thursday" + ) + self.assertEqual(tokenizer.decode(encoding["input_ids"][11:12], spaces_between_special_tokens=False), "She") + + self.assertEqual( + encoding["entity_ids"], + [ + tokenizer.entity_vocab["Ana Ivanovic"], + tokenizer.entity_vocab["Thursday"], + tokenizer.entity_vocab["[UNK]"], + ], + ) + self.assertEqual(encoding["entity_attention_mask"], [1, 1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + ] + ) + # fmt: on + + def test_text_pair_only_entity_spans_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday" + sentence_pair = "She could hardly believe her luck." + spans = [(9, 21), (30, 38)] + spans_pair = [(0, 3)] + + encoding = tokenizer( + sentence, + sentence_pair, + entity_spans=spans, + entity_spans_pair=spans_pair, + return_token_type_ids=True, + ) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on ThursdayShe could hardly believe her luck.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][3:6], spaces_between_special_tokens=False), " Ana Ivanovic" + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][8:9], spaces_between_special_tokens=False), " Thursday" + ) + self.assertEqual(tokenizer.decode(encoding["input_ids"][11:12], spaces_between_special_tokens=False), "She") + + mask_id = tokenizer.entity_vocab["[MASK]"] + self.assertEqual(encoding["entity_ids"], [mask_id, mask_id, mask_id]) + self.assertEqual(encoding["entity_attention_mask"], [1, 1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + ] + ) + # fmt: on + + def test_text_pair_padding_pytorch_tensors(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", return_token_type_ids=True) + sentence = "Top seed Ana Ivanovic said on Thursday" + sentence_pair = "She could hardly believe her luck." + entities = ["Ana Ivanovic", "Thursday"] + entities_pair = ["Dummy Entity"] + spans = [(9, 21), (30, 38)] + spans_pair = [(0, 3)] + + encoding = tokenizer( + sentence, + sentence_pair, + entities=entities, + entities_pair=entities_pair, + entity_spans=spans, + entity_spans_pair=spans_pair, + return_token_type_ids=True, + padding="max_length", + max_length=30, + max_entity_length=16, + return_tensors="pt", + ) + + # test words + self.assertEqual(encoding["input_ids"].shape, (1, 30)) + self.assertEqual(encoding["attention_mask"].shape, (1, 30)) + self.assertEqual(encoding["token_type_ids"].shape, (1, 30)) + + # test entities + self.assertEqual(encoding["entity_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_attention_mask"].shape, (1, 16)) + self.assertEqual(encoding["entity_token_type_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_position_ids"].shape, (1, 16, tokenizer.max_mention_length)) + + def test_entity_classification_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained("studio-ousia/luke-base", task="entity_classification") + sentence = ( + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck as a fortuitous netcord helped" + " the new world number one avoid a humiliating second- round exit at Wimbledon ." + ) + span = (39, 42) + + encoding = tokenizer(sentence, entity_spans=[span], return_token_type_ids=True) + + # test words + self.assertEqual(len(encoding["input_ids"]), 42) + self.assertEqual(len(encoding["attention_mask"]), 42) + self.assertEqual(len(encoding["token_type_ids"]), 42) + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck as a fortuitous" + " netcord helped the new world number one avoid a humiliating second- round exit at Wimbledon.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][9:12], spaces_between_special_tokens=False), " she" + ) + + # test entities + self.assertEqual(encoding["entity_ids"], [2]) + self.assertEqual(encoding["entity_attention_mask"], [1]) + self.assertEqual(encoding["entity_token_type_ids"], [0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] + ] + ) + # fmt: on + + def test_entity_classification_padding_pytorch_tensors(self): + tokenizer = LukeTokenizer.from_pretrained( + "studio-ousia/luke-base", task="entity_classification", return_token_type_ids=True + ) + sentence = ( + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck as a fortuitous netcord helped" + " the new world number one avoid a humiliating second- round exit at Wimbledon ." + ) + # entity information + span = (39, 42) + + encoding = tokenizer( + sentence, entity_spans=[span], return_token_type_ids=True, padding="max_length", return_tensors="pt" + ) + + # test words + self.assertEqual(encoding["input_ids"].shape, (1, 512)) + self.assertEqual(encoding["attention_mask"].shape, (1, 512)) + self.assertEqual(encoding["token_type_ids"].shape, (1, 512)) + + # test entities + self.assertEqual(encoding["entity_ids"].shape, (1, 1)) + self.assertEqual(encoding["entity_attention_mask"].shape, (1, 1)) + self.assertEqual(encoding["entity_token_type_ids"].shape, (1, 1)) + self.assertEqual( + encoding["entity_position_ids"].shape, (1, tokenizer.max_entity_length, tokenizer.max_mention_length) + ) + + def test_entity_pair_classification_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained( + "studio-ousia/luke-base", task="entity_pair_classification", return_token_type_ids=True + ) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + # head and tail information + spans = [(9, 21), (39, 42)] + + encoding = tokenizer(sentence, entity_spans=spans, return_token_type_ids=True) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck.", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][3:8], spaces_between_special_tokens=False), + " Ana Ivanovic", + ) + self.assertEqual( + tokenizer.decode(encoding["input_ids"][11:14], spaces_between_special_tokens=False), " she" + ) + + self.assertEqual(encoding["entity_ids"], [2, 3]) + self.assertEqual(encoding["entity_attention_mask"], [1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + ] + ) + # fmt: on + + def test_entity_pair_classification_padding_pytorch_tensors(self): + tokenizer = LukeTokenizer.from_pretrained( + "studio-ousia/luke-base", task="entity_pair_classification", return_token_type_ids=True + ) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + # head and tail information + spans = [(9, 21), (39, 42)] + + encoding = tokenizer( + sentence, + entity_spans=spans, + return_token_type_ids=True, + padding="max_length", + max_length=30, + return_tensors="pt", + ) + + # test words + self.assertEqual(encoding["input_ids"].shape, (1, 30)) + self.assertEqual(encoding["attention_mask"].shape, (1, 30)) + self.assertEqual(encoding["token_type_ids"].shape, (1, 30)) + + # test entities + self.assertEqual(encoding["entity_ids"].shape, (1, 2)) + self.assertEqual(encoding["entity_attention_mask"].shape, (1, 2)) + self.assertEqual(encoding["entity_token_type_ids"].shape, (1, 2)) + self.assertEqual( + encoding["entity_position_ids"].shape, (1, tokenizer.max_entity_length, tokenizer.max_mention_length) + ) + + def test_entity_span_classification_no_padding_or_truncation(self): + tokenizer = LukeTokenizer.from_pretrained( + "studio-ousia/luke-base", task="entity_span_classification", return_token_type_ids=True + ) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + spans = [(0, 8), (9, 21), (39, 42)] + + encoding = tokenizer(sentence, entity_spans=spans, return_token_type_ids=True) + + self.assertEqual( + tokenizer.decode(encoding["input_ids"], spaces_between_special_tokens=False), + "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck.", + ) + + self.assertEqual(encoding["entity_ids"], [2, 2, 2]) + self.assertEqual(encoding["entity_attention_mask"], [1, 1, 1]) + self.assertEqual(encoding["entity_token_type_ids"], [0, 0, 0]) + # fmt: off + self.assertEqual( + encoding["entity_position_ids"], + [ + [1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + ] + ) + # fmt: on + self.assertEqual(encoding["entity_start_positions"], [1, 3, 9]) + self.assertEqual(encoding["entity_end_positions"], [2, 5, 9]) + + def test_entity_span_classification_padding_pytorch_tensors(self): + tokenizer = LukeTokenizer.from_pretrained( + "studio-ousia/luke-base", task="entity_span_classification", return_token_type_ids=True + ) + sentence = "Top seed Ana Ivanovic said on Thursday she could hardly believe her luck." + spans = [(0, 8), (9, 21), (39, 42)] + + encoding = tokenizer( + sentence, + entity_spans=spans, + return_token_type_ids=True, + padding="max_length", + max_length=30, + max_entity_length=16, + return_tensors="pt", + ) + + # test words + self.assertEqual(encoding["input_ids"].shape, (1, 30)) + self.assertEqual(encoding["attention_mask"].shape, (1, 30)) + self.assertEqual(encoding["token_type_ids"].shape, (1, 30)) + + # test entities + self.assertEqual(encoding["entity_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_attention_mask"].shape, (1, 16)) + self.assertEqual(encoding["entity_token_type_ids"].shape, (1, 16)) + self.assertEqual(encoding["entity_position_ids"].shape, (1, 16, tokenizer.max_mention_length)) + self.assertEqual(encoding["entity_start_positions"].shape, (1, 16)) + self.assertEqual(encoding["entity_end_positions"].shape, (1, 16)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_lxmert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_lxmert.py new file mode 100644 index 0000000000000000000000000000000000000000..489d22d92efee6af68478e6685b30bc5d84dae0c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_lxmert.py @@ -0,0 +1,789 @@ +# coding=utf-8 +# Copyright 2018 LXMERT Authors, The Hugging Face Team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import unittest + +import numpy as np + +from transformers import LxmertConfig, is_tf_available, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import require_torch, slow, torch_device + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + MODEL_FOR_PRETRAINING_MAPPING, + MODEL_FOR_QUESTION_ANSWERING_MAPPING, + LxmertForPreTraining, + LxmertForQuestionAnswering, + LxmertModel, + ) + from transformers.models.lxmert.modeling_lxmert import LXMERT_PRETRAINED_MODEL_ARCHIVE_LIST + + +if is_tf_available(): + import tensorflow as tf + + +class LxmertModelTester: + def __init__( + self, + parent, + vocab_size=300, + hidden_size=28, + num_attention_heads=2, + num_labels=2, + intermediate_size=64, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=0, + num_qa_labels=30, + num_object_labels=16, + num_attr_labels=4, + num_visual_features=10, + l_layers=2, + x_layers=1, + r_layers=1, + visual_feat_dim=128, + visual_pos_dim=4, + visual_loss_normalizer=6.67, + seq_length=20, + batch_size=4, + is_training=True, + task_matched=True, + task_mask_lm=True, + task_obj_predict=True, + task_qa=True, + visual_obj_loss=True, + visual_attr_loss=True, + visual_feat_loss=True, + use_token_type_ids=True, + use_lang_mask=True, + output_attentions=False, + output_hidden_states=False, + scope=None, + ): + self.parent = parent + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_attention_heads = num_attention_heads + self.num_labels = num_labels + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.pad_token_id = pad_token_id + self.num_qa_labels = num_qa_labels + self.num_object_labels = num_object_labels + self.num_attr_labels = num_attr_labels + self.l_layers = l_layers + self.x_layers = x_layers + self.r_layers = r_layers + self.visual_feat_dim = visual_feat_dim + self.visual_pos_dim = visual_pos_dim + self.visual_loss_normalizer = visual_loss_normalizer + self.seq_length = seq_length + self.batch_size = batch_size + self.is_training = is_training + self.use_lang_mask = use_lang_mask + self.task_matched = task_matched + self.task_mask_lm = task_mask_lm + self.task_obj_predict = task_obj_predict + self.task_qa = task_qa + self.visual_obj_loss = visual_obj_loss + self.visual_attr_loss = visual_attr_loss + self.visual_feat_loss = visual_feat_loss + self.num_visual_features = num_visual_features + self.use_token_type_ids = use_token_type_ids + self.output_attentions = output_attentions + self.output_hidden_states = output_hidden_states + self.scope = scope + self.num_hidden_layers = {"vision": r_layers, "cross_encoder": x_layers, "language": l_layers} + + def prepare_config_and_inputs(self): + output_attentions = self.output_attentions + input_ids = ids_tensor([self.batch_size, self.seq_length], vocab_size=self.vocab_size) + visual_feats = torch.rand(self.batch_size, self.num_visual_features, self.visual_feat_dim, device=torch_device) + bounding_boxes = torch.rand(self.batch_size, self.num_visual_features, 4, device=torch_device) + + input_mask = None + if self.use_lang_mask: + input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2) + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + obj_labels = None + if self.task_obj_predict: + obj_labels = {} + if self.visual_attr_loss and self.task_obj_predict: + obj_labels["attr"] = ( + ids_tensor([self.batch_size, self.num_visual_features], self.num_attr_labels), + ids_tensor([self.batch_size, self.num_visual_features], self.num_attr_labels), + ) + if self.visual_feat_loss and self.task_obj_predict: + obj_labels["feat"] = ( + ids_tensor( + [self.batch_size, self.num_visual_features, self.visual_feat_dim], self.num_visual_features + ), + ids_tensor([self.batch_size, self.num_visual_features], self.num_visual_features), + ) + if self.visual_obj_loss and self.task_obj_predict: + obj_labels["obj"] = ( + ids_tensor([self.batch_size, self.num_visual_features], self.num_object_labels), + ids_tensor([self.batch_size, self.num_visual_features], self.num_object_labels), + ) + ans = None + if self.task_qa: + ans = ids_tensor([self.batch_size], self.num_qa_labels) + masked_lm_labels = None + if self.task_mask_lm: + masked_lm_labels = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + matched_label = None + if self.task_matched: + matched_label = ids_tensor([self.batch_size], self.num_labels) + + config = self.get_config() + + return ( + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ) + + def get_config(self): + return LxmertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_attention_heads=self.num_attention_heads, + num_labels=self.num_labels, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + pad_token_id=self.pad_token_id, + num_qa_labels=self.num_qa_labels, + num_object_labels=self.num_object_labels, + num_attr_labels=self.num_attr_labels, + l_layers=self.l_layers, + x_layers=self.x_layers, + r_layers=self.r_layers, + visual_feat_dim=self.visual_feat_dim, + visual_pos_dim=self.visual_pos_dim, + visual_loss_normalizer=self.visual_loss_normalizer, + task_matched=self.task_matched, + task_mask_lm=self.task_mask_lm, + task_obj_predict=self.task_obj_predict, + task_qa=self.task_qa, + visual_obj_loss=self.visual_obj_loss, + visual_attr_loss=self.visual_attr_loss, + visual_feat_loss=self.visual_feat_loss, + output_attentions=self.output_attentions, + output_hidden_states=self.output_hidden_states, + ) + + def create_and_check_lxmert_model( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + model = LxmertModel(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + output_attentions=output_attentions, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + output_attentions=not output_attentions, + ) + result = model(input_ids, visual_feats, bounding_boxes, return_dict=False) + result = model(input_ids, visual_feats, bounding_boxes, return_dict=True) + + self.parent.assertEqual(result.language_output.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual( + result.vision_output.shape, (self.batch_size, self.num_visual_features, self.hidden_size) + ) + self.parent.assertEqual(result.pooled_output.shape, (self.batch_size, self.hidden_size)) + + def create_and_check_lxmert_for_question_answering( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + model = LxmertForQuestionAnswering(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + labels=ans, + output_attentions=output_attentions, + ) + result = model(input_ids, visual_feats, bounding_boxes, labels=ans) + result = model( + input_ids, + visual_feats, + bounding_boxes, + labels=ans, + token_type_ids=token_type_ids, + attention_mask=input_mask, + output_attentions=output_attentions, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + labels=ans, + output_attentions=not output_attentions, + ) + + self.parent.assertEqual(result.question_answering_score.shape, (self.batch_size, self.num_qa_labels)) + + def create_and_check_lxmert_for_pretraining( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + model = LxmertForPreTraining(config=config) + model.to(torch_device) + model.eval() + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + obj_labels=obj_labels, + matched_label=matched_label, + ans=ans, + output_attentions=output_attentions, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + output_attentions=not output_attentions, + return_dict=False, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + obj_labels=obj_labels, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + matched_label=matched_label, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ans=ans, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + obj_labels=obj_labels, + matched_label=matched_label, + ans=ans, + output_attentions=not output_attentions, + ) + + self.parent.assertEqual(result.prediction_logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + def resize_lxmert_num_qa_labels( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + start_labels = config.num_qa_labels + num_large_labels = config.num_qa_labels * 2 + num_small_labels = int(config.num_qa_labels * 2) + less_labels_ans = ids_tensor([self.batch_size], num_small_labels) + more_labels_ans = ids_tensor([self.batch_size], num_large_labels) + model_pretrain = LxmertForPreTraining(config=config).to(torch_device) + model_qa = LxmertForQuestionAnswering(config=config).to(torch_device) + config.num_labels = num_small_labels + end_labels = config.num_labels + + result_pretrain = model_pretrain( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ans=ans, + ) + + result_qa = model_qa( + input_ids, + visual_feats, + bounding_boxes, + labels=ans, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ) + + model_pretrain.resize_num_qa_labels(num_small_labels) + model_qa.resize_num_qa_labels(num_small_labels) + + result_pretrain_less = model_pretrain( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ans=less_labels_ans, + ) + + result_qa_less = model_qa( + input_ids, + visual_feats, + bounding_boxes, + labels=less_labels_ans, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ) + + model_pretrain.resize_num_qa_labels(num_large_labels) + model_qa.resize_num_qa_labels(num_large_labels) + + result_pretrain_more = model_pretrain( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ans=more_labels_ans, + ) + + result_qa_more = model_qa( + input_ids, + visual_feats, + bounding_boxes, + labels=more_labels_ans, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ) + + model_qa_labels = model_qa.num_qa_labels + + self.parent.assertNotEqual(start_labels, end_labels) + self.parent.assertNotEqual(model_qa_labels, start_labels) + self.parent.assertEqual(result_qa.question_answering_score.shape, (self.batch_size, start_labels)) + self.parent.assertEqual(result_pretrain.question_answering_score.shape, (self.batch_size, start_labels)) + self.parent.assertEqual(result_qa_less.question_answering_score.shape, (self.batch_size, num_small_labels)) + self.parent.assertEqual( + result_pretrain_less.question_answering_score.shape, (self.batch_size, num_small_labels) + ) + self.parent.assertEqual(result_qa_more.question_answering_score.shape, (self.batch_size, num_large_labels)) + self.parent.assertEqual( + result_pretrain_more.question_answering_score.shape, (self.batch_size, num_large_labels) + ) + + def prepare_config_and_inputs_for_common(self, return_obj_labels=False): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "visual_feats": visual_feats, + "visual_pos": bounding_boxes, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + + if return_obj_labels: + inputs_dict["obj_labels"] = obj_labels + else: + config.task_obj_predict = False + + return config, inputs_dict + + +@require_torch +class LxmertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (LxmertModel, LxmertForPreTraining, LxmertForQuestionAnswering) if is_torch_available() else () + pipeline_model_mapping = ( + {"feature-extraction": LxmertModel, "question-answering": LxmertForQuestionAnswering} + if is_torch_available() + else {} + ) + + fx_compatible = True + test_head_masking = False + test_pruning = False + test_torchscript = False + + # overwrite function because qa models takes different input label shape + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = copy.deepcopy(inputs_dict) + + if return_labels: + if model_class in get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING): + inputs_dict["labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class in get_values(MODEL_FOR_PRETRAINING_MAPPING): + # special case for models like BERT that use multi-loss training for PreTraining + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + return inputs_dict + + def setUp(self): + self.model_tester = LxmertModelTester(self) + self.config_tester = ConfigTester(self, config_class=LxmertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_lxmert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lxmert_model(*config_and_inputs) + + def test_lxmert_question_answering(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lxmert_for_question_answering(*config_and_inputs) + + def test_lxmert_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lxmert_for_pretraining(*config_and_inputs) + + def test_lxmert_question_answering_labels_resize(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.resize_lxmert_num_qa_labels(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in LXMERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + model = LxmertModel.from_pretrained(model_name) + model.to(torch_device) + self.assertIsNotNone(model) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + seq_len = getattr(self.model_tester, "seq_length", None) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + language_attentions, vision_attentions, cross_encoder_attentions = (outputs[-3], outputs[-2], outputs[-1]) + + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + language_attentions, vision_attentions, cross_encoder_attentions = (outputs[-3], outputs[-2], outputs[-1]) + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + attentions = [language_attentions, vision_attentions, cross_encoder_attentions] + attention_shapes = [ + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + [ + self.model_tester.num_attention_heads, + self.model_tester.num_visual_features, + self.model_tester.num_visual_features, + ], + [self.model_tester.num_attention_heads, encoder_key_length, self.model_tester.num_visual_features], + ] + + for attention, attention_shape in zip(attentions, attention_shapes): + self.assertListEqual(list(attention[0].shape[-3:]), attention_shape) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + # 2 hidden states were added + self.assertEqual(out_len + 2, len(outputs)) + + language_attentions, vision_attentions, cross_encoder_attentions = (outputs[-3], outputs[-2], outputs[-1]) + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + attentions = [language_attentions, vision_attentions, cross_encoder_attentions] + attention_shapes = [ + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + [ + self.model_tester.num_attention_heads, + self.model_tester.num_visual_features, + self.model_tester.num_visual_features, + ], + [self.model_tester.num_attention_heads, encoder_key_length, self.model_tester.num_visual_features], + ] + + for attention, attention_shape in zip(attentions, attention_shapes): + self.assertListEqual(list(attention[0].shape[-3:]), attention_shape) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + language_hidden_states, vision_hidden_states = outputs[-2], outputs[-1] + + self.assertEqual(len(language_hidden_states), self.model_tester.num_hidden_layers["language"] + 1) + self.assertEqual(len(vision_hidden_states), self.model_tester.num_hidden_layers["vision"] + 1) + + seq_length = self.model_tester.seq_length + num_visual_features = self.model_tester.num_visual_features + + self.assertListEqual( + list(language_hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + self.assertListEqual( + list(vision_hidden_states[0].shape[-2:]), + [num_visual_features, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + hidden_states_lang = outputs.language_hidden_states[0] + attentions_lang = outputs.language_attentions[0] + + hidden_states_vision = outputs.vision_hidden_states[0] + attentions_vision = outputs.vision_attentions[0] + + hidden_states_lang.retain_grad() + attentions_lang.retain_grad() + hidden_states_vision.retain_grad() + attentions_vision.retain_grad() + + outputs.language_output.flatten()[0].backward(retain_graph=True) + outputs.vision_output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states_lang.grad) + self.assertIsNotNone(attentions_vision.grad) + self.assertIsNotNone(hidden_states_vision.grad) + self.assertIsNotNone(attentions_vision.grad) + + def prepare_tf_inputs_from_pt_inputs(self, pt_inputs_dict): + tf_inputs_dict = {} + for key, value in pt_inputs_dict.items(): + # skip key that does not exist in tf + if isinstance(value, dict): + tf_inputs_dict[key] = self.prepare_pt_inputs_from_tf_inputs(value) + elif isinstance(value, (list, tuple)): + tf_inputs_dict[key] = (self.prepare_pt_inputs_from_tf_inputs(iter_value) for iter_value in value) + elif type(value) == bool: + tf_inputs_dict[key] = value + elif key == "input_values": + tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) + elif key == "pixel_values": + tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) + elif key == "input_features": + tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) + # other general float inputs + elif value.is_floating_point(): + tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.float32) + else: + tf_inputs_dict[key] = tf.convert_to_tensor(value.cpu().numpy(), dtype=tf.int32) + + return tf_inputs_dict + + +@require_torch +class LxmertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_no_head_absolute_embedding(self): + model = LxmertModel.from_pretrained(LXMERT_PRETRAINED_MODEL_ARCHIVE_LIST[0]) + input_ids = torch.tensor([[101, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 102]]) + num_visual_features = 10 + _, visual_feats = np.random.seed(0), np.random.rand(1, num_visual_features, model.config.visual_feat_dim) + _, visual_pos = np.random.seed(0), np.random.rand(1, num_visual_features, 4) + visual_feats = torch.as_tensor(visual_feats, dtype=torch.float32) + visual_pos = torch.as_tensor(visual_pos, dtype=torch.float32) + output = model(input_ids, visual_feats=visual_feats, visual_pos=visual_pos)[0] + expected_shape = torch.Size([1, 11, 768]) + self.assertEqual(expected_shape, output.shape) + expected_slice = torch.tensor( + [[[0.2417, -0.9807, 0.1480], [1.2541, -0.8320, 0.5112], [1.4070, -1.1052, 0.6990]]] + ) + + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4)) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_tf_lxmert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_tf_lxmert.py new file mode 100644 index 0000000000000000000000000000000000000000..cd2095f693d62ae1b2f61977f41489f23aadc265 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/lxmert/test_modeling_tf_lxmert.py @@ -0,0 +1,695 @@ +# coding=utf-8 +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import tempfile +import unittest + +import numpy as np + +from transformers import LxmertConfig, is_tf_available +from transformers.testing_utils import require_tf, slow, tooslow + +from ...test_configuration_common import ConfigTester +from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_tf_available(): + import tensorflow as tf + + from transformers.models.lxmert.modeling_tf_lxmert import TFLxmertForPreTraining, TFLxmertModel + + +class TFLxmertModelTester(object): + def __init__( + self, + parent, + vocab_size=300, + hidden_size=28, + num_attention_heads=2, + num_labels=2, + intermediate_size=64, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=512, + type_vocab_size=2, + initializer_range=0.02, + layer_norm_eps=1e-12, + pad_token_id=0, + num_qa_labels=30, + num_object_labels=16, + num_attr_labels=4, + num_visual_features=10, + l_layers=2, + x_layers=1, + r_layers=1, + visual_feat_dim=128, + visual_pos_dim=4, + visual_loss_normalizer=6.67, + seq_length=20, + batch_size=8, + is_training=True, + task_matched=True, + task_mask_lm=True, + task_obj_predict=True, + task_qa=True, + visual_obj_loss=True, + visual_attr_loss=True, + visual_feat_loss=True, + use_token_type_ids=True, + use_lang_mask=True, + output_attentions=False, + output_hidden_states=False, + scope=None, + ): + self.parent = parent + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_attention_heads = num_attention_heads + self.num_labels = num_labels + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.type_vocab_size = type_vocab_size + self.initializer_range = initializer_range + self.layer_norm_eps = layer_norm_eps + self.pad_token_id = pad_token_id + self.num_qa_labels = num_qa_labels + self.num_object_labels = num_object_labels + self.num_attr_labels = num_attr_labels + self.l_layers = l_layers + self.x_layers = x_layers + self.r_layers = r_layers + self.visual_feat_dim = visual_feat_dim + self.visual_pos_dim = visual_pos_dim + self.visual_loss_normalizer = visual_loss_normalizer + self.seq_length = seq_length + self.batch_size = batch_size + self.is_training = is_training + self.use_lang_mask = use_lang_mask + self.task_matched = task_matched + self.task_mask_lm = task_mask_lm + self.task_obj_predict = task_obj_predict + self.task_qa = task_qa + self.visual_obj_loss = visual_obj_loss + self.visual_attr_loss = visual_attr_loss + self.visual_feat_loss = visual_feat_loss + self.num_visual_features = num_visual_features + self.use_token_type_ids = use_token_type_ids + self.output_attentions = output_attentions + self.output_hidden_states = output_hidden_states + self.scope = scope + self.num_hidden_layers = {"vision": r_layers, "cross_encoder": x_layers, "language": l_layers} + + def prepare_config_and_inputs(self): + output_attentions = self.output_attentions + input_ids = ids_tensor([self.batch_size, self.seq_length], vocab_size=self.vocab_size) + visual_feats = tf.random.uniform((self.batch_size, self.num_visual_features, self.visual_feat_dim)) + bounding_boxes = tf.random.uniform((self.batch_size, self.num_visual_features, 4)) + + input_mask = None + if self.use_lang_mask: + input_mask = random_attention_mask([self.batch_size, self.seq_length]) + token_type_ids = None + if self.use_token_type_ids: + token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size) + obj_labels = None + if self.task_obj_predict: + obj_labels = {} + if self.visual_attr_loss and self.task_obj_predict: + obj_labels["attr"] = ( + ids_tensor([self.batch_size, self.num_visual_features], self.num_attr_labels), + ids_tensor([self.batch_size, self.num_visual_features], self.num_attr_labels), + ) + if self.visual_feat_loss and self.task_obj_predict: + obj_labels["feat"] = ( + ids_tensor( + [self.batch_size, self.num_visual_features, self.visual_feat_dim], self.num_visual_features + ), + ids_tensor([self.batch_size, self.num_visual_features], self.num_visual_features), + ) + if self.visual_obj_loss and self.task_obj_predict: + obj_labels["obj"] = ( + ids_tensor([self.batch_size, self.num_visual_features], self.num_object_labels), + ids_tensor([self.batch_size, self.num_visual_features], self.num_object_labels), + ) + ans = None + if self.task_qa: + ans = ids_tensor([self.batch_size], self.num_qa_labels) + masked_lm_labels = None + if self.task_mask_lm: + masked_lm_labels = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + matched_label = None + if self.task_matched: + matched_label = ids_tensor([self.batch_size], self.num_labels) + + config = LxmertConfig( + vocab_size=self.vocab_size, + hidden_size=self.hidden_size, + num_attention_heads=self.num_attention_heads, + num_labels=self.num_labels, + intermediate_size=self.intermediate_size, + hidden_act=self.hidden_act, + hidden_dropout_prob=self.hidden_dropout_prob, + attention_probs_dropout_prob=self.attention_probs_dropout_prob, + max_position_embeddings=self.max_position_embeddings, + type_vocab_size=self.type_vocab_size, + initializer_range=self.initializer_range, + layer_norm_eps=self.layer_norm_eps, + pad_token_id=self.pad_token_id, + num_qa_labels=self.num_qa_labels, + num_object_labels=self.num_object_labels, + num_attr_labels=self.num_attr_labels, + l_layers=self.l_layers, + x_layers=self.x_layers, + r_layers=self.r_layers, + visual_feat_dim=self.visual_feat_dim, + visual_pos_dim=self.visual_pos_dim, + visual_loss_normalizer=self.visual_loss_normalizer, + task_matched=self.task_matched, + task_mask_lm=self.task_mask_lm, + task_obj_predict=self.task_obj_predict, + task_qa=self.task_qa, + visual_obj_loss=self.visual_obj_loss, + visual_attr_loss=self.visual_attr_loss, + visual_feat_loss=self.visual_feat_loss, + output_attentions=self.output_attentions, + output_hidden_states=self.output_hidden_states, + ) + + return ( + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ) + + def create_and_check_lxmert_model( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + model = TFLxmertModel(config=config) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + output_attentions=output_attentions, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + output_attentions=not output_attentions, + ) + result = model(input_ids, visual_feats, bounding_boxes, return_dict=False) + result = model(input_ids, visual_feats, bounding_boxes, return_dict=True) + + self.parent.assertEqual(result.language_output.shape, (self.batch_size, self.seq_length, self.hidden_size)) + self.parent.assertEqual( + result.vision_output.shape, (self.batch_size, self.num_visual_features, self.hidden_size) + ) + self.parent.assertEqual(result.pooled_output.shape, (self.batch_size, self.hidden_size)) + + def prepare_config_and_inputs_for_common(self, return_obj_labels=False): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "visual_feats": visual_feats, + "visual_pos": bounding_boxes, + "token_type_ids": token_type_ids, + "attention_mask": input_mask, + } + + if return_obj_labels: + inputs_dict["obj_labels"] = obj_labels + else: + config.task_obj_predict = False + + return config, inputs_dict + + def create_and_check_lxmert_for_pretraining( + self, + config, + input_ids, + visual_feats, + bounding_boxes, + token_type_ids, + input_mask, + obj_labels, + masked_lm_labels, + matched_label, + ans, + output_attentions, + ): + model = TFLxmertForPreTraining(config=config) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + obj_labels=obj_labels, + matched_label=matched_label, + ans=ans, + output_attentions=output_attentions, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + output_attentions=not output_attentions, + return_dict=False, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + obj_labels=obj_labels, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + matched_label=matched_label, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + ans=ans, + ) + result = model( + input_ids, + visual_feats, + bounding_boxes, + token_type_ids=token_type_ids, + attention_mask=input_mask, + masked_lm_labels=masked_lm_labels, + obj_labels=obj_labels, + matched_label=matched_label, + ans=ans, + output_attentions=not output_attentions, + ) + + self.parent.assertEqual(result.prediction_logits.shape, (self.batch_size, self.seq_length, self.vocab_size)) + + +@require_tf +class TFLxmertModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFLxmertModel, TFLxmertForPreTraining) if is_tf_available() else () + pipeline_model_mapping = {"feature-extraction": TFLxmertModel} if is_tf_available() else {} + test_head_masking = False + test_onnx = False + + def setUp(self): + self.model_tester = TFLxmertModelTester(self) + self.config_tester = ConfigTester(self, config_class=LxmertConfig, hidden_size=37) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_lxmert_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lxmert_model(*config_and_inputs) + + def test_lxmert_for_pretraining(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_lxmert_for_pretraining(*config_and_inputs) + + @slow + def test_model_from_pretrained(self): + for model_name in ["unc-nlp/lxmert-base-uncased"]: + model = TFLxmertModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_attention_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + encoder_seq_length = ( + self.model_tester.encoder_seq_length + if hasattr(self.model_tester, "encoder_seq_length") + else self.model_tester.seq_length + ) + encoder_key_length = ( + self.model_tester.key_length if hasattr(self.model_tester, "key_length") else encoder_seq_length + ) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + language_attentions, vision_attentions, cross_encoder_attentions = (outputs[-3], outputs[-2], outputs[-1]) + + self.assertEqual(model.config.output_hidden_states, False) + + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + attentions = [language_attentions, vision_attentions, cross_encoder_attentions] + attention_shapes = [ + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + [ + self.model_tester.num_attention_heads, + self.model_tester.num_visual_features, + self.model_tester.num_visual_features, + ], + [self.model_tester.num_attention_heads, encoder_key_length, self.model_tester.num_visual_features], + ] + + for attention, attention_shape in zip(attentions, attention_shapes): + self.assertListEqual(list(attention[0].shape[-3:]), attention_shape) + out_len = len(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + # 2 hidden states were added + self.assertEqual(out_len + 2, len(outputs)) + language_attentions, vision_attentions, cross_encoder_attentions = (outputs[-3], outputs[-2], outputs[-1]) + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + attentions = [language_attentions, vision_attentions, cross_encoder_attentions] + attention_shapes = [ + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + [ + self.model_tester.num_attention_heads, + self.model_tester.num_visual_features, + self.model_tester.num_visual_features, + ], + [self.model_tester.num_attention_heads, encoder_key_length, self.model_tester.num_visual_features], + ] + + for attention, attention_shape in zip(attentions, attention_shapes): + self.assertListEqual(list(attention[0].shape[-3:]), attention_shape) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_hidden_states_output(config, inputs_dict, model_class): + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + language_hidden_states, vision_hidden_states = outputs[-2], outputs[-1] + + self.assertEqual(len(language_hidden_states), self.model_tester.num_hidden_layers["language"] + 1) + self.assertEqual(len(vision_hidden_states), self.model_tester.num_hidden_layers["vision"] + 1) + + seq_length = self.model_tester.seq_length + num_visual_features = self.model_tester.num_visual_features + + self.assertListEqual( + list(language_hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + self.assertListEqual( + list(vision_hidden_states[0].shape[-2:]), + [num_visual_features, self.model_tester.hidden_size], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(config, inputs_dict, model_class) + + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + check_hidden_states_output(config, inputs_dict, model_class) + + def prepare_pt_inputs_from_tf_inputs(self, tf_inputs_dict): + import torch + + pt_inputs_dict = {} + for key, value in tf_inputs_dict.items(): + if isinstance(value, dict): + pt_inputs_dict[key] = self.prepare_pt_inputs_from_tf_inputs(value) + elif isinstance(value, (list, tuple)): + pt_inputs_dict[key] = (self.prepare_pt_inputs_from_tf_inputs(iter_value) for iter_value in value) + elif type(key) == bool: + pt_inputs_dict[key] = value + elif key == "input_values": + pt_inputs_dict[key] = torch.from_numpy(value.numpy()).to(torch.float32) + elif key == "pixel_values": + pt_inputs_dict[key] = torch.from_numpy(value.numpy()).to(torch.float32) + elif key == "input_features": + pt_inputs_dict[key] = torch.from_numpy(value.numpy()).to(torch.float32) + # other general float inputs + elif tf_inputs_dict[key].dtype.is_floating: + pt_inputs_dict[key] = torch.from_numpy(value.numpy()).to(torch.float32) + else: + pt_inputs_dict[key] = torch.from_numpy(value.numpy()).to(torch.long) + + return pt_inputs_dict + + def test_save_load(self): + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common( + return_obj_labels="PreTraining" in model_class.__name__ + ) + + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model = model_class.from_pretrained(tmpdirname) + after_outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + self.assert_outputs_same(after_outputs, outputs) + + def test_compile_tf_model(self): + optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0) + loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) + metric = tf.keras.metrics.SparseCategoricalAccuracy("accuracy") + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common( + return_obj_labels="PreTraining" in model_class.__name__ + ) + + input_ids = tf.keras.Input( + batch_shape=(self.model_tester.batch_size, self.model_tester.seq_length), + name="input_ids", + dtype="int32", + ) + visual_feats = tf.keras.Input( + batch_shape=( + self.model_tester.batch_size, + self.model_tester.num_visual_features, + self.model_tester.visual_feat_dim, + ), + name="visual_feats", + dtype="int32", + ) + visual_pos = tf.keras.Input( + batch_shape=(self.model_tester.batch_size, self.model_tester.num_visual_features, 4), + name="visual_pos", + dtype="int32", + ) + + # Prepare our model + model = model_class(config) + + # Let's load it from the disk to be sure we can use pretrained weights + with tempfile.TemporaryDirectory() as tmpdirname: + outputs = model(self._prepare_for_class(inputs_dict, model_class)) # build the model + model.save_pretrained(tmpdirname) + model = model_class.from_pretrained(tmpdirname) + + outputs_dict = model(input_ids, visual_feats, visual_pos) + hidden_states = outputs_dict[0] + + # Add a dense layer on top to test integration with other keras modules + outputs = tf.keras.layers.Dense(2, activation="softmax", name="outputs")(hidden_states) + + # Compile extended model + extended_model = tf.keras.Model(inputs=[input_ids, visual_feats, visual_pos], outputs=[outputs]) + extended_model.compile(optimizer=optimizer, loss=loss, metrics=[metric]) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + list_lm_models = [TFLxmertForPreTraining] + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in list_lm_models: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + @tooslow + def test_saved_model_creation(self): + pass + + @slow + def test_saved_model_creation_extended(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = True + + if hasattr(config, "use_cache"): + config.use_cache = True + + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", self.model_tester.seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + + for model_class in self.all_model_classes: + class_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + num_out = len(model(class_inputs_dict)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=True) + saved_model_dir = os.path.join(tmpdirname, "saved_model", "1") + model = tf.keras.models.load_model(saved_model_dir) + outputs = model(class_inputs_dict) + language_hidden_states = outputs["language_hidden_states"] + vision_hidden_states = outputs["vision_hidden_states"] + language_attentions = outputs["language_attentions"] + vision_attentions = outputs["vision_attentions"] + cross_encoder_attentions = outputs["cross_encoder_attentions"] + + self.assertEqual(len(outputs), num_out) + + self.assertEqual(len(language_hidden_states), self.model_tester.num_hidden_layers["language"] + 1) + self.assertEqual(len(vision_hidden_states), self.model_tester.num_hidden_layers["vision"] + 1) + + seq_length = self.model_tester.seq_length + num_visual_features = self.model_tester.num_visual_features + + self.assertListEqual( + list(language_hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + self.assertListEqual( + list(vision_hidden_states[0].shape[-2:]), + [num_visual_features, self.model_tester.hidden_size], + ) + + self.assertEqual(len(language_attentions), self.model_tester.num_hidden_layers["language"]) + self.assertEqual(len(vision_attentions), self.model_tester.num_hidden_layers["vision"]) + self.assertEqual(len(cross_encoder_attentions), self.model_tester.num_hidden_layers["cross_encoder"]) + + attentions = [language_attentions, vision_attentions, cross_encoder_attentions] + attention_shapes = [ + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + [ + self.model_tester.num_attention_heads, + self.model_tester.num_visual_features, + self.model_tester.num_visual_features, + ], + [self.model_tester.num_attention_heads, encoder_key_length, self.model_tester.num_visual_features], + ] + + for attention, attention_shape in zip(attentions, attention_shapes): + self.assertListEqual(list(attention[0].shape[-3:]), attention_shape) + + +@require_tf +class TFLxmertModelIntegrationTest(unittest.TestCase): + @slow + def test_inference_masked_lm(self): + model = TFLxmertModel.from_pretrained("unc-nlp/lxmert-base-uncased") + input_ids = tf.constant([[101, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 102]]) + + num_visual_features = 10 + _, visual_feats = np.random.seed(0), np.random.rand(1, num_visual_features, model.config.visual_feat_dim) + _, visual_pos = np.random.seed(0), np.random.rand(1, num_visual_features, 4) + visual_feats = tf.convert_to_tensor(visual_feats, dtype=tf.float32) + visual_pos = tf.convert_to_tensor(visual_pos, dtype=tf.float32) + output = model(input_ids, visual_feats=visual_feats, visual_pos=visual_pos)[0] + expected_shape = [1, 11, 768] + self.assertEqual(expected_shape, output.shape) + expected_slice = tf.constant( + [ + [ + [0.24170142, -0.98075, 0.14797261], + [1.2540525, -0.83198136, 0.5112344], + [1.4070463, -1.1051831, 0.6990401], + ] + ] + ) + tf.debugging.assert_near(output[:, :3, :3], expected_slice, atol=1e-4) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/m2m_100/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/m2m_100/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/m2m_100/test_modeling_m2m_100.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/m2m_100/test_modeling_m2m_100.py new file mode 100644 index 0000000000000000000000000000000000000000..d081041978c0b9ee6a626609c250be8a4d92622e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/m2m_100/test_modeling_m2m_100.py @@ -0,0 +1,407 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch M2M100 model. """ + + +import copy +import tempfile +import unittest + +from transformers import M2M100Config, is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import M2M100ForConditionalGeneration, M2M100Model, M2M100Tokenizer + from transformers.models.m2m_100.modeling_m2m_100 import M2M100Decoder, M2M100Encoder + + +def prepare_m2m_100_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = input_ids.ne(config.pad_token_id) + if decoder_attention_mask is None: + decoder_attention_mask = decoder_input_ids.ne(config.pad_token_id) + if head_mask is None: + head_mask = torch.ones(config.encoder_layers, config.encoder_attention_heads, device=torch_device) + if decoder_head_mask is None: + decoder_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + if cross_attn_head_mask is None: + cross_attn_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + return { + "input_ids": input_ids, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": attention_mask, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + "cross_attn_head_mask": cross_attn_head_mask, + } + + +class M2M100ModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="relu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + encoder_layerdrop=0.0, + decoder_layerdrop=0.0, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.encoder_layerdrop = encoder_layerdrop + self.decoder_layerdrop = decoder_layerdrop + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + input_ids[:, -1] = self.eos_token_id # Eos Token + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + # we need to clamp the input ids here to avoid having pad token in between + # this is because for M2M100 the position_ids are prepared such that + # all pad tokens have pos id = 2 and rest are between 2..seq_length + # and the seq_length here is seq_length - num_pad_tokens + # but when using past, there is no way of knowing if the past input ids had + # pad tokens in them, which results in incorrect seq_lenth and which in turn results in + # position_ids being off by num_pad_tokens in past input + input_ids = input_ids.clamp(self.pad_token_id + 1) + decoder_input_ids = decoder_input_ids.clamp(self.pad_token_id + 1) + + config = self.get_config() + inputs_dict = prepare_m2m_100_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def get_config(self): + return M2M100Config( + 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, + encoder_layerdrop=self.encoder_layerdrop, + decoder_layerdrop=self.decoder_layerdrop, + max_position_embeddings=self.max_position_embeddings, + eos_token_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + ) + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + def create_and_check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = M2M100Model(config=config).get_decoder().to(torch_device).eval() + input_ids = inputs_dict["input_ids"] + attention_mask = inputs_dict["attention_mask"] + head_mask = inputs_dict["head_mask"] + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, head_mask=head_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([attention_mask, next_attn_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-2)) + + def check_encoder_decoder_model_standalone(self, config, inputs_dict): + model = M2M100Model(config=config).to(torch_device).eval() + outputs = model(**inputs_dict) + + encoder_last_hidden_state = outputs.encoder_last_hidden_state + last_hidden_state = outputs.last_hidden_state + + with tempfile.TemporaryDirectory() as tmpdirname: + encoder = model.get_encoder() + encoder.save_pretrained(tmpdirname) + encoder = M2M100Encoder.from_pretrained(tmpdirname).to(torch_device) + + encoder_last_hidden_state_2 = encoder(inputs_dict["input_ids"], attention_mask=inputs_dict["attention_mask"])[ + 0 + ] + + self.parent.assertTrue((encoder_last_hidden_state_2 - encoder_last_hidden_state).abs().max().item() < 1e-3) + + with tempfile.TemporaryDirectory() as tmpdirname: + decoder = model.get_decoder() + decoder.save_pretrained(tmpdirname) + decoder = M2M100Decoder.from_pretrained(tmpdirname).to(torch_device) + + last_hidden_state_2 = decoder( + input_ids=inputs_dict["decoder_input_ids"], + attention_mask=inputs_dict["decoder_attention_mask"], + encoder_hidden_states=encoder_last_hidden_state, + encoder_attention_mask=inputs_dict["attention_mask"], + )[0] + + self.parent.assertTrue((last_hidden_state_2 - last_hidden_state).abs().max().item() < 1e-3) + + +@require_torch +class M2M100ModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = ( + ( + M2M100Model, + M2M100ForConditionalGeneration, + ) + if is_torch_available() + else () + ) + all_generative_model_classes = (M2M100ForConditionalGeneration,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": M2M100ForConditionalGeneration, + "feature-extraction": M2M100Model, + "summarization": M2M100ForConditionalGeneration, + "text2text-generation": M2M100ForConditionalGeneration, + "translation": M2M100ForConditionalGeneration, + } + if is_torch_available() + else {} + ) + is_encoder_decoder = True + fx_compatible = True + test_pruning = False + test_missing_keys = False + + # TODO: Fix the failed tests + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + if pipeline_test_casse_name == "TranslationPipelineTests": + # Get `ValueError: Translation requires a `src_lang` and a `tgt_lang` for this model`. + # `M2M100Config` was never used in pipeline tests: cannot create a simple tokenizer. + return True + + return False + + def setUp(self): + self.model_tester = M2M100ModelTester(self) + self.config_tester = ConfigTester(self, config_class=M2M100Config) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_save_load_strict(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_encoder_decoder_model_standalone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_encoder_decoder_model_standalone(*config_and_inputs) + + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in (M2M100Model, M2M100ForConditionalGeneration): + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + wte = model.get_input_embeddings() + if not self.is_encoder_decoder: + inputs["inputs_embeds"] = wte(input_ids) + else: + inputs["inputs_embeds"] = wte(encoder_input_ids) + inputs["decoder_inputs_embeds"] = wte(decoder_input_ids) + + with torch.no_grad(): + model(**inputs)[0] + + def test_generate_fp16(self): + config, input_dict = self.model_tester.prepare_config_and_inputs() + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + model = M2M100ForConditionalGeneration(config).eval().to(torch_device) + if torch_device == "cuda": + model.half() + model.generate(input_ids, attention_mask=attention_mask) + model.generate(num_beams=4, do_sample=True, early_stopping=False, num_return_sequences=3) + + +def _long_tensor(tok_lst): + return torch.tensor(tok_lst, dtype=torch.long, device=torch_device) + + +TOLERANCE = 1e-4 + + +@require_torch +@require_sentencepiece +@require_tokenizers +@slow +class M2M100ModelIntegrationTests(unittest.TestCase): + @cached_property + def default_tokenizer(self): + return M2M100Tokenizer.from_pretrained("facebook/m2m100_418M") + + def test_inference_no_head(self): + model = M2M100Model.from_pretrained("facebook/m2m100_418M").to(torch_device) + input_ids = _long_tensor([[128028, 98, 12, 30527, 2732, 159, 7755, 61904, 39144, 38, 2]]) + decoder_input_ids = _long_tensor([[2, 128028, 98, 12, 30527, 2732, 159, 7755, 61904, 39144, 38]]) + inputs_dict = prepare_m2m_100_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict)[0] + expected_shape = torch.Size((1, 11, 1024)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[-0.7780, -0.1676, 0.1038], [-6.7556, -1.3992, 0.0567], [-7.5383, -0.5920, -0.2779]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_inference_head(self): + model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M").to(torch_device) + + # change to intended input + input_ids = _long_tensor([[128028, 98, 12, 30527, 2732, 159, 7755, 61904, 39144, 38, 2]]) + decoder_input_ids = _long_tensor([[2, 128028, 98, 12, 30527, 2732, 159, 7755, 61904, 39144, 38]]) + inputs_dict = prepare_m2m_100_inputs_dict(model.config, input_ids, decoder_input_ids) + with torch.no_grad(): + output = model(**inputs_dict)[0] + expected_shape = torch.Size((1, 11, model.config.vocab_size)) + self.assertEqual(output.shape, expected_shape) + # change to expected output here + expected_slice = torch.tensor( + [[-1.0448, -1.0411, 3.7992], [-3.2191, -3.2386, -1.3451], [-3.6210, -3.5993, 0.4925]], device=torch_device + ) + self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_seq_to_seq_generation(self): + model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M").to(torch_device) + tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M", src_lang="fr", tgt_lang="en") + + src_fr = [ + "L'affaire NSA souligne l'absence totale de débat sur le renseignement", + "Selon moi, il y a deux niveaux de réponse de la part du gouvernement français.", + "Lorsque François Hollande téléphone à Barack Obama ou quand le ministre des affaires étrangères Laurent" + " Fabius convoque l'ambassadeur des Etats-Unis, ils réagissent à une vraie découverte, qui est celle de" + " l'ampleur de la surveillance américaine sur l'ensemble des communications en France.", + ] + + # The below article tests that we don't add any hypotheses outside of the top n_beams + dct = tokenizer(src_fr, padding=True, return_tensors="pt") + + hypotheses_batch = model.generate( + input_ids=dct["input_ids"].to(torch_device), + attention_mask=dct["attention_mask"].to(torch_device), + num_beams=5, + forced_bos_token_id=tokenizer.get_lang_id("en"), + ) + + expected_en = [ + "The NSA case highlights the total absence of intelligence debate", + "I think there are two levels of response from the French government.", + "When François Hollande calls Barack Obama or when Foreign Minister Laurent Fabius calls the U.S." + " Ambassador, they respond to a real discovery, which is that of the scale of U.S. surveillance on all" + " communications in France.", + ] + + generated = tokenizer.batch_decode( + hypotheses_batch.tolist(), clean_up_tokenization_spaces=True, skip_special_tokens=True + ) + assert generated == expected_en diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_flax_marian.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_flax_marian.py new file mode 100644 index 0000000000000000000000000000000000000000..6510c0d732d318aaca98b0d5d19bf69eb8bba5e2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_flax_marian.py @@ -0,0 +1,490 @@ +# Copyright 2021 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +import numpy as np +import timeout_decorator # noqa + +from transformers import MarianConfig, is_flax_available +from transformers.testing_utils import require_flax, require_sentencepiece, require_tokenizers, slow +from transformers.utils import cached_property + +from ...generation.test_flax_utils import FlaxGenerationTesterMixin +from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor + + +if is_flax_available(): + import os + + # The slow tests are often failing with OOM error on GPU + # This makes JAX allocate exactly what is needed on demand, and deallocate memory that is no longer needed + # but will be slower as stated here https://jax.readthedocs.io/en/latest/gpu_memory_allocation.html + os.environ["XLA_PYTHON_CLIENT_ALLOCATOR"] = "platform" + + import jax + import jax.numpy as jnp + + from transformers import MarianTokenizer + from transformers.models.marian.modeling_flax_marian import FlaxMarianModel, FlaxMarianMTModel, shift_tokens_right + + +def prepare_marian_inputs_dict( + config, + input_ids, + decoder_input_ids=None, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = np.where(input_ids != config.pad_token_id, 1, 0) + if decoder_attention_mask is None: + decoder_attention_mask = np.where(decoder_input_ids != config.pad_token_id, 1, 0) + if head_mask is None: + head_mask = np.ones((config.encoder_layers, config.encoder_attention_heads)) + if decoder_head_mask is None: + decoder_head_mask = np.ones((config.decoder_layers, config.decoder_attention_heads)) + if cross_attn_head_mask is None: + cross_attn_head_mask = np.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": attention_mask, + } + + +class FlaxMarianModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=32, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + initializer_range=0.02, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + self.initializer_range = initializer_range + + def prepare_config_and_inputs(self): + input_ids = np.clip(ids_tensor([self.batch_size, self.seq_length - 1], self.vocab_size), 3, self.vocab_size) + input_ids = np.concatenate((input_ids, 2 * np.ones((self.batch_size, 1), dtype=np.int64)), -1) + + decoder_input_ids = shift_tokens_right(input_ids, 1, 2) + + config = MarianConfig( + 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_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + initializer_range=self.initializer_range, + use_cache=False, + ) + inputs_dict = prepare_marian_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + def check_use_cache_forward(self, model_class_name, config, inputs_dict): + max_decoder_length = 20 + model = model_class_name(config) + + encoder_outputs = model.encode(inputs_dict["input_ids"]) + + decoder_input_ids, decoder_attention_mask = ( + inputs_dict["decoder_input_ids"], + inputs_dict["decoder_attention_mask"], + ) + + past_key_values = model.init_cache(decoder_input_ids.shape[0], max_decoder_length, encoder_outputs) + decoder_attention_mask = jnp.ones((decoder_input_ids.shape[0], max_decoder_length), dtype="i4") + + decoder_position_ids = jnp.broadcast_to( + jnp.arange(decoder_input_ids.shape[-1] - 1)[None, :], + (decoder_input_ids.shape[0], decoder_input_ids.shape[-1] - 1), + ) + outputs_cache = model.decode( + decoder_input_ids[:, :-1], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + past_key_values=past_key_values, + decoder_position_ids=decoder_position_ids, + ) + + decoder_position_ids = jnp.array(decoder_input_ids.shape[0] * [[decoder_input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model.decode( + decoder_input_ids[:, -1:], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask, + past_key_values=outputs_cache.past_key_values, + decoder_position_ids=decoder_position_ids, + ) + + outputs = model.decode(decoder_input_ids, encoder_outputs) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + def check_use_cache_forward_with_attn_mask(self, model_class_name, config, inputs_dict): + max_decoder_length = 20 + model = model_class_name(config) + + encoder_outputs = model.encode(inputs_dict["input_ids"]) + + decoder_input_ids, decoder_attention_mask = ( + inputs_dict["decoder_input_ids"], + inputs_dict["decoder_attention_mask"], + ) + + decoder_attention_mask_cache = jnp.concatenate( + [ + decoder_attention_mask, + jnp.zeros((decoder_attention_mask.shape[0], max_decoder_length - decoder_attention_mask.shape[1])), + ], + axis=-1, + ) + + past_key_values = model.init_cache(decoder_input_ids.shape[0], max_decoder_length, encoder_outputs) + decoder_position_ids = jnp.broadcast_to( + jnp.arange(decoder_input_ids.shape[-1] - 1)[None, :], + (decoder_input_ids.shape[0], decoder_input_ids.shape[-1] - 1), + ) + + outputs_cache = model.decode( + decoder_input_ids[:, :-1], + encoder_outputs, + decoder_attention_mask=decoder_attention_mask_cache, + past_key_values=past_key_values, + decoder_position_ids=decoder_position_ids, + ) + decoder_position_ids = jnp.array(decoder_input_ids.shape[0] * [[decoder_input_ids.shape[-1] - 1]], dtype="i4") + outputs_cache_next = model.decode( + decoder_input_ids[:, -1:], + encoder_outputs, + past_key_values=outputs_cache.past_key_values, + decoder_attention_mask=decoder_attention_mask_cache, + decoder_position_ids=decoder_position_ids, + ) + + outputs = model.decode(decoder_input_ids, encoder_outputs, decoder_attention_mask=decoder_attention_mask) + + diff = np.max(np.abs((outputs_cache_next[0][:, -1, :5] - outputs[0][:, -1, :5]))) + self.parent.assertTrue(diff < 1e-3, msg=f"Max diff is {diff}") + + +@require_flax +class FlaxMarianModelTest(FlaxModelTesterMixin, unittest.TestCase, FlaxGenerationTesterMixin): + is_encoder_decoder = True + all_model_classes = (FlaxMarianModel, FlaxMarianMTModel) if is_flax_available() else () + all_generative_model_classes = (FlaxMarianMTModel,) if is_flax_available() else () + + def setUp(self): + self.model_tester = FlaxMarianModelTester(self) + + def test_use_cache_forward(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + self.model_tester.check_use_cache_forward(model_class, config, inputs_dict) + + def test_use_cache_forward_with_attn_mask(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + self.model_tester.check_use_cache_forward_with_attn_mask(model_class, config, inputs_dict) + + def test_encode(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + @jax.jit + def encode_jitted(input_ids, attention_mask=None, **kwargs): + return model.encode(input_ids=input_ids, attention_mask=attention_mask) + + with self.subTest("JIT Enabled"): + jitted_outputs = encode_jitted(**prepared_inputs_dict).to_tuple() + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = encode_jitted(**prepared_inputs_dict).to_tuple() + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + def test_decode(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + model = model_class(config) + encoder_outputs = model.encode(inputs_dict["input_ids"], inputs_dict["attention_mask"]) + + prepared_inputs_dict = { + "decoder_input_ids": inputs_dict["decoder_input_ids"], + "decoder_attention_mask": inputs_dict["decoder_attention_mask"], + "encoder_outputs": encoder_outputs, + } + + @jax.jit + def decode_jitted(decoder_input_ids, decoder_attention_mask, encoder_outputs): + return model.decode( + decoder_input_ids=decoder_input_ids, + decoder_attention_mask=decoder_attention_mask, + encoder_outputs=encoder_outputs, + ) + + with self.subTest("JIT Enabled"): + jitted_outputs = decode_jitted(**prepared_inputs_dict).to_tuple() + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = decode_jitted(**prepared_inputs_dict).to_tuple() + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + @slow + def test_model_from_pretrained(self): + for model_class_name in self.all_model_classes: + model = model_class_name.from_pretrained("Helsinki-NLP/opus-mt-en-de") + # FlaxMarianForSequenceClassification expects eos token in input_ids + input_ids = np.ones((1, 1)) * model.config.eos_token_id + outputs = model(input_ids) + self.assertIsNotNone(outputs) + + +@require_flax +@require_sentencepiece +@require_tokenizers +class MarianIntegrationTest(unittest.TestCase): + src = None + tgt = None + + @classmethod + def setUpClass(cls) -> None: + cls.model_name = f"Helsinki-NLP/opus-mt-{cls.src}-{cls.tgt}" + return cls + + @cached_property + def tokenizer(self): + return MarianTokenizer.from_pretrained(self.model_name) + + @property + def eos_token_id(self) -> int: + return self.tokenizer.eos_token_id + + @cached_property + def model(self): + model: FlaxMarianMTModel = FlaxMarianMTModel.from_pretrained(self.model_name) + self.assertEqual(model.config.decoder_start_token_id, model.config.pad_token_id) + return model + + def _assert_generated_batch_equal_expected(self, **tokenizer_kwargs): + generated_words = self.translate_src_text(**tokenizer_kwargs) + self.assertListEqual(self.expected_text, generated_words) + + def translate_src_text(self, **tokenizer_kwargs): + model_inputs = self.tokenizer(self.src_text, padding=True, return_tensors="np", **tokenizer_kwargs) + generated_ids = self.model.generate( + model_inputs.input_ids, + attention_mask=model_inputs.attention_mask, + num_beams=2, + max_length=128, + ).sequences + generated_words = self.tokenizer.batch_decode(generated_ids, skip_special_tokens=True) + return generated_words + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_EN_FR(MarianIntegrationTest): + src = "en" + tgt = "fr" + src_text = [ + "I am a small frog.", + "Now I can forget the 100 words of german that I know.", + ] + expected_text = [ + "Je suis une petite grenouille.", + "Maintenant, je peux oublier les 100 mots d'allemand que je connais.", + ] + + @slow + def test_batch_generation_en_fr(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_FR_EN(MarianIntegrationTest): + src = "fr" + tgt = "en" + src_text = [ + "Donnez moi le micro.", + "Tom et Mary étaient assis à une table.", # Accents + ] + expected_text = [ + "Give me the microphone.", + "Tom and Mary were sitting at a table.", + ] + + @slow + def test_batch_generation_fr_en(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_MT_EN(MarianIntegrationTest): + """Cover low resource/high perplexity setting. This breaks without adjust_logits_generation overwritten""" + + src = "mt" + tgt = "en" + src_text = ["Billi messu b'mod ġentili, Ġesù fejjaq raġel li kien milqut bil - marda kerha tal - ġdiem."] + expected_text = ["Touching gently, Jesus healed a man who was affected by the sad disease of leprosy."] + + @slow + def test_batch_generation_mt_en(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_EN_DE(MarianIntegrationTest): + src = "en" + tgt = "de" + src_text = [ + "I am a small frog.", + "Now I can forget the 100 words of german that I know.", + "Tom asked his teacher for advice.", + "That's how I would do it.", + "Tom really admired Mary's courage.", + "Turn around and close your eyes.", + ] + expected_text = [ + "Ich bin ein kleiner Frosch.", + "Jetzt kann ich die 100 Wörter des Deutschen vergessen, die ich kenne.", + "Tom bat seinen Lehrer um Rat.", + "So würde ich das machen.", + "Tom bewunderte Marias Mut wirklich.", + "Drehen Sie sich um und schließen Sie die Augen.", + ] + + @slow + def test_batch_generation_en_de(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_en_zh(MarianIntegrationTest): + src = "en" + tgt = "zh" + src_text = ["My name is Wolfgang and I live in Berlin"] + expected_text = ["我叫沃尔夫冈 我住在柏林"] + + @slow + def test_batch_generation_eng_zho(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_RU_FR(MarianIntegrationTest): + src = "ru" + tgt = "fr" + src_text = ["Он показал мне рукопись своей новой пьесы."] + expected_text = ["Il m'a montré le manuscrit de sa nouvelle pièce."] + + @slow + def test_batch_generation_ru_fr(self): + self._assert_generated_batch_equal_expected() + + +@require_flax +@require_sentencepiece +@require_tokenizers +class TestMarian_en_ROMANCE(MarianIntegrationTest): + """Multilingual on target side.""" + + src = "en" + tgt = "ROMANCE" + src_text = [ + ">>fr<< Don't spend so much time watching TV.", + ">>pt<< Your message has been sent.", + ">>es<< He's two years older than me.", + ] + expected_text = [ + "Ne passez pas autant de temps à regarder la télé.", + "A sua mensagem foi enviada.", + "Es dos años más viejo que yo.", + ] + + @slow + def test_batch_generation_en_ROMANCE_multi(self): + self._assert_generated_batch_equal_expected() diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_marian.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_marian.py new file mode 100644 index 0000000000000000000000000000000000000000..fe5f8606521e8cbdd26de51673358b8d1def2ba2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_marian.py @@ -0,0 +1,864 @@ +# coding=utf-8 +# Copyright 2021, The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Marian model. """ + +import tempfile +import unittest + +from huggingface_hub.hf_api import list_models + +from transformers import MarianConfig, is_torch_available +from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device +from transformers.utils import cached_property + +from ...generation.test_utils import GenerationTesterMixin +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin, ids_tensor +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import ( + AutoConfig, + AutoModelWithLMHead, + AutoTokenizer, + MarianModel, + MarianMTModel, + TranslationPipeline, + ) + from transformers.models.marian.convert_marian_to_pytorch import ( + ORG_NAME, + convert_hf_name_to_opus_name, + convert_opus_name_to_hf_name, + ) + from transformers.models.marian.modeling_marian import ( + MarianDecoder, + MarianEncoder, + MarianForCausalLM, + shift_tokens_right, + ) + + +def prepare_marian_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = input_ids.ne(config.pad_token_id) + if decoder_attention_mask is None: + decoder_attention_mask = decoder_input_ids.ne(config.pad_token_id) + if head_mask is None: + head_mask = torch.ones(config.encoder_layers, config.encoder_attention_heads, device=torch_device) + if decoder_head_mask is None: + decoder_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + if cross_attn_head_mask is None: + cross_attn_head_mask = torch.ones(config.decoder_layers, config.decoder_attention_heads, device=torch_device) + return { + "input_ids": input_ids, + "decoder_input_ids": decoder_input_ids, + "attention_mask": attention_mask, + "decoder_attention_mask": attention_mask, + "head_mask": head_mask, + "decoder_head_mask": decoder_head_mask, + "cross_attn_head_mask": cross_attn_head_mask, + } + + +class MarianModelTester: + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=16, + num_hidden_layers=2, + num_attention_heads=4, + intermediate_size=4, + hidden_act="gelu", + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + decoder_start_token_id=3, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + self.hidden_act = hidden_act + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + self.decoder_start_token_id = decoder_start_token_id + + # forcing a certain token to be generated, sets all other tokens to -inf + # if however the token to be generated is already at -inf then it can lead token + # `nan` values and thus break generation + self.forced_bos_token_id = None + self.forced_eos_token_id = None + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size).clamp( + 3, + ) + input_ids[:, -1] = self.eos_token_id # Eos Token + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = self.get_config() + inputs_dict = prepare_marian_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def get_config(self): + return MarianConfig( + 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_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + forced_bos_token_id=self.forced_bos_token_id, + forced_eos_token_id=self.forced_eos_token_id, + ) + + def prepare_config_and_inputs_for_common(self): + config, inputs_dict = self.prepare_config_and_inputs() + return config, inputs_dict + + def create_and_check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = MarianModel(config=config).get_decoder().to(torch_device).eval() + input_ids = inputs_dict["input_ids"] + attention_mask = inputs_dict["attention_mask"] + head_mask = inputs_dict["head_mask"] + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, head_mask=head_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical multiple next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = ids_tensor((self.batch_size, 3), 2) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + next_attention_mask = torch.cat([attention_mask, next_attn_mask], dim=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, :, random_slice_idx].detach() + + self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1]) + + # test that outputs are equal for slice + self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3)) + + def check_encoder_decoder_model_standalone(self, config, inputs_dict): + model = MarianModel(config=config).to(torch_device).eval() + outputs = model(**inputs_dict) + + encoder_last_hidden_state = outputs.encoder_last_hidden_state + last_hidden_state = outputs.last_hidden_state + + with tempfile.TemporaryDirectory() as tmpdirname: + encoder = model.get_encoder() + encoder.save_pretrained(tmpdirname) + encoder = MarianEncoder.from_pretrained(tmpdirname).to(torch_device) + + encoder_last_hidden_state_2 = encoder(inputs_dict["input_ids"], attention_mask=inputs_dict["attention_mask"])[ + 0 + ] + + self.parent.assertTrue((encoder_last_hidden_state_2 - encoder_last_hidden_state).abs().max().item() < 1e-3) + + with tempfile.TemporaryDirectory() as tmpdirname: + decoder = model.get_decoder() + decoder.save_pretrained(tmpdirname) + decoder = MarianDecoder.from_pretrained(tmpdirname).to(torch_device) + + last_hidden_state_2 = decoder( + input_ids=inputs_dict["decoder_input_ids"], + attention_mask=inputs_dict["decoder_attention_mask"], + encoder_hidden_states=encoder_last_hidden_state, + encoder_attention_mask=inputs_dict["attention_mask"], + )[0] + + self.parent.assertTrue((last_hidden_state_2 - last_hidden_state).abs().max().item() < 1e-3) + + +@require_torch +class MarianModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (MarianModel, MarianMTModel) if is_torch_available() else () + all_generative_model_classes = (MarianMTModel,) if is_torch_available() else () + pipeline_model_mapping = ( + { + "conversational": MarianMTModel, + "feature-extraction": MarianModel, + "summarization": MarianMTModel, + "text-generation": MarianForCausalLM, + "text2text-generation": MarianMTModel, + "translation": MarianMTModel, + } + if is_torch_available() + else {} + ) + is_encoder_decoder = True + fx_compatible = True + test_pruning = False + test_missing_keys = False + + def setUp(self): + self.model_tester = MarianModelTester(self) + self.config_tester = ConfigTester(self, config_class=MarianConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_save_load_strict(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model2, info = model_class.from_pretrained(tmpdirname, output_loading_info=True) + self.assertEqual(info["missing_keys"], []) + + def test_decoder_model_past_with_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_encoder_decoder_model_standalone(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_encoder_decoder_model_standalone(*config_and_inputs) + + def test_generate_fp16(self): + config, input_dict = self.model_tester.prepare_config_and_inputs() + input_ids = input_dict["input_ids"] + attention_mask = input_ids.ne(1).to(torch_device) + model = MarianMTModel(config).eval().to(torch_device) + if torch_device == "cuda": + model.half() + model.generate(input_ids, attention_mask=attention_mask) + model.generate(num_beams=4, do_sample=True, early_stopping=False, num_return_sequences=3) + + def test_share_encoder_decoder_embeddings(self): + config, input_dict = self.model_tester.prepare_config_and_inputs() + + # check if embeddings are shared by default + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIs(model.get_encoder().embed_tokens, model.get_decoder().embed_tokens) + self.assertIs(model.get_encoder().embed_tokens.weight, model.get_decoder().embed_tokens.weight) + + # check if embeddings are not shared when config.share_encoder_decoder_embeddings = False + config.share_encoder_decoder_embeddings = False + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsNot(model.get_encoder().embed_tokens, model.get_decoder().embed_tokens) + self.assertIsNot(model.get_encoder().embed_tokens.weight, model.get_decoder().embed_tokens.weight) + + # check if a model with shared embeddings can be saved and loaded with share_encoder_decoder_embeddings = False + config, _ = self.model_tester.prepare_config_and_inputs() + for model_class in self.all_model_classes: + model = model_class(config) + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model = model_class.from_pretrained(tmpdirname, share_encoder_decoder_embeddings=False) + self.assertIsNot(model.get_encoder().embed_tokens, model.get_decoder().embed_tokens) + self.assertIsNot(model.get_encoder().embed_tokens.weight, model.get_decoder().embed_tokens.weight) + + def test_resize_decoder_token_embeddings(self): + config, _ = self.model_tester.prepare_config_and_inputs() + + # check if resize_decoder_token_embeddings raises an error when embeddings are shared + for model_class in self.all_model_classes: + model = model_class(config) + with self.assertRaises(ValueError): + model.resize_decoder_token_embeddings(config.vocab_size + 1) + + # check if decoder embeddings are resized when config.share_encoder_decoder_embeddings = False + config.share_encoder_decoder_embeddings = False + for model_class in self.all_model_classes: + model = model_class(config) + model.resize_decoder_token_embeddings(config.vocab_size + 1) + self.assertEqual(model.get_decoder().embed_tokens.weight.shape, (config.vocab_size + 1, config.d_model)) + + # check if lm_head is also resized + config, _ = self.model_tester.prepare_config_and_inputs() + config.share_encoder_decoder_embeddings = False + model = MarianMTModel(config) + model.resize_decoder_token_embeddings(config.vocab_size + 1) + self.assertEqual(model.lm_head.weight.shape, (config.vocab_size + 1, config.d_model)) + + def test_tie_word_embeddings_decoder(self): + pass + + +def assert_tensors_close(a, b, atol=1e-12, prefix=""): + """If tensors have different shapes, different values or a and b are not both tensors, raise a nice Assertion error.""" + if a is None and b is None: + return True + try: + if torch.allclose(a, b, atol=atol): + return True + raise + except Exception: + pct_different = (torch.gt((a - b).abs(), atol)).float().mean().item() + if a.numel() > 100: + msg = f"tensor values are {pct_different:.1%} percent different." + else: + msg = f"{a} != {b}" + if prefix: + msg = prefix + ": " + msg + raise AssertionError(msg) + + +def _long_tensor(tok_lst): + return torch.tensor(tok_lst, dtype=torch.long, device=torch_device) + + +class ModelManagementTests(unittest.TestCase): + @slow + @require_torch + def test_model_names(self): + model_list = list_models() + model_ids = [x.modelId for x in model_list if x.modelId.startswith(ORG_NAME)] + bad_model_ids = [mid for mid in model_ids if "+" in model_ids] + self.assertListEqual([], bad_model_ids) + self.assertGreater(len(model_ids), 500) + + +@require_torch +@require_sentencepiece +@require_tokenizers +class MarianIntegrationTest(unittest.TestCase): + src = "en" + tgt = "de" + src_text = [ + "I am a small frog.", + "Now I can forget the 100 words of german that I know.", + "Tom asked his teacher for advice.", + "That's how I would do it.", + "Tom really admired Mary's courage.", + "Turn around and close your eyes.", + ] + expected_text = [ + "Ich bin ein kleiner Frosch.", + "Jetzt kann ich die 100 Wörter des Deutschen vergessen, die ich kenne.", + "Tom bat seinen Lehrer um Rat.", + "So würde ich das machen.", + "Tom bewunderte Marias Mut wirklich.", + "Drehen Sie sich um und schließen Sie die Augen.", + ] + # ^^ actual C++ output differs slightly: (1) des Deutschen removed, (2) ""-> "O", (3) tun -> machen + + @classmethod + def setUpClass(cls) -> None: + cls.model_name = f"Helsinki-NLP/opus-mt-{cls.src}-{cls.tgt}" + return cls + + @cached_property + def tokenizer(self): + return AutoTokenizer.from_pretrained(self.model_name) + + @property + def eos_token_id(self) -> int: + return self.tokenizer.eos_token_id + + @cached_property + def model(self): + model: MarianMTModel = AutoModelWithLMHead.from_pretrained(self.model_name).to(torch_device) + c = 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) + + if torch_device == "cuda": + return model.half() + else: + return model + + def _assert_generated_batch_equal_expected(self, **tokenizer_kwargs): + generated_words = self.translate_src_text(**tokenizer_kwargs) + self.assertListEqual(self.expected_text, generated_words) + + def translate_src_text(self, **tokenizer_kwargs): + model_inputs = self.tokenizer(self.src_text, padding=True, return_tensors="pt", **tokenizer_kwargs).to( + torch_device + ) + self.assertEqual(self.model.device, model_inputs.input_ids.device) + generated_ids = self.model.generate( + model_inputs.input_ids, attention_mask=model_inputs.attention_mask, num_beams=2, max_length=128 + ) + generated_words = self.tokenizer.batch_decode(generated_ids, skip_special_tokens=True) + return generated_words + + +@require_sentencepiece +@require_tokenizers +class TestMarian_EN_DE_More(MarianIntegrationTest): + @slow + def test_forward(self): + src, tgt = ["I am a small frog"], ["Ich bin ein kleiner Frosch."] + expected_ids = [38, 121, 14, 697, 38848, 0] + + model_inputs = self.tokenizer(src, text_target=tgt, return_tensors="pt").to(torch_device) + + self.assertListEqual(expected_ids, model_inputs.input_ids[0].tolist()) + + desired_keys = { + "input_ids", + "attention_mask", + "labels", + } + self.assertSetEqual(desired_keys, set(model_inputs.keys())) + model_inputs["decoder_input_ids"] = shift_tokens_right( + model_inputs.labels, self.tokenizer.pad_token_id, self.model.config.decoder_start_token_id + ) + model_inputs["return_dict"] = True + model_inputs["use_cache"] = False + with torch.no_grad(): + outputs = self.model(**model_inputs) + max_indices = outputs.logits.argmax(-1) + self.tokenizer.batch_decode(max_indices) + + def test_unk_support(self): + t = self.tokenizer + ids = t(["||"], return_tensors="pt").to(torch_device).input_ids[0].tolist() + expected = [t.unk_token_id, t.unk_token_id, t.eos_token_id] + self.assertEqual(expected, ids) + + def test_pad_not_split(self): + input_ids_w_pad = self.tokenizer(["I am a small frog "], return_tensors="pt").input_ids[0].tolist() + expected_w_pad = [38, 121, 14, 697, 38848, self.tokenizer.pad_token_id, 0] # pad + self.assertListEqual(expected_w_pad, input_ids_w_pad) + + @slow + def test_batch_generation_en_de(self): + self._assert_generated_batch_equal_expected() + + def test_auto_config(self): + config = AutoConfig.from_pretrained(self.model_name) + self.assertIsInstance(config, MarianConfig) + + +@require_sentencepiece +@require_tokenizers +class TestMarian_EN_FR(MarianIntegrationTest): + src = "en" + tgt = "fr" + src_text = [ + "I am a small frog.", + "Now I can forget the 100 words of german that I know.", + ] + expected_text = [ + "Je suis une petite grenouille.", + "Maintenant, je peux oublier les 100 mots d'allemand que je connais.", + ] + + @slow + def test_batch_generation_en_fr(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +class TestMarian_FR_EN(MarianIntegrationTest): + src = "fr" + tgt = "en" + src_text = [ + "Donnez moi le micro.", + "Tom et Mary étaient assis à une table.", # Accents + ] + expected_text = [ + "Give me the microphone.", + "Tom and Mary were sitting at a table.", + ] + + @slow + def test_batch_generation_fr_en(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +class TestMarian_RU_FR(MarianIntegrationTest): + src = "ru" + tgt = "fr" + src_text = ["Он показал мне рукопись своей новой пьесы."] + expected_text = ["Il m'a montré le manuscrit de sa nouvelle pièce."] + + @slow + def test_batch_generation_ru_fr(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +class TestMarian_MT_EN(MarianIntegrationTest): + """Cover low resource/high perplexity setting. This breaks without adjust_logits_generation overwritten""" + + src = "mt" + tgt = "en" + src_text = ["Billi messu b'mod ġentili, Ġesù fejjaq raġel li kien milqut bil - marda kerha tal - ġdiem."] + expected_text = ["Touching gently, Jesus healed a man who was affected by the sad disease of leprosy."] + + @slow + def test_batch_generation_mt_en(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +class TestMarian_en_zh(MarianIntegrationTest): + src = "en" + tgt = "zh" + src_text = ["My name is Wolfgang and I live in Berlin"] + expected_text = ["我叫沃尔夫冈 我住在柏林"] + + @slow + def test_batch_generation_eng_zho(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +class TestMarian_en_ROMANCE(MarianIntegrationTest): + """Multilingual on target side.""" + + src = "en" + tgt = "ROMANCE" + src_text = [ + ">>fr<< Don't spend so much time watching TV.", + ">>pt<< Your message has been sent.", + ">>es<< He's two years older than me.", + ] + expected_text = [ + "Ne passez pas autant de temps à regarder la télé.", + "A sua mensagem foi enviada.", + "Es dos años más viejo que yo.", + ] + + @slow + def test_batch_generation_en_ROMANCE_multi(self): + self._assert_generated_batch_equal_expected() + + @slow + def test_pipeline(self): + device = 0 if torch_device == "cuda" else -1 + pipeline = TranslationPipeline(self.model, self.tokenizer, framework="pt", device=device) + output = pipeline(self.src_text) + self.assertEqual(self.expected_text, [x["translation_text"] for x in output]) + + +@require_sentencepiece +@require_tokenizers +class TestMarian_FI_EN_V2(MarianIntegrationTest): + src = "fi" + tgt = "en" + src_text = [ + "minä tykkään kirjojen lukemisesta", + "Pidän jalkapallon katsomisesta", + ] + expected_text = ["I like to read books", "I like watching football"] + + @classmethod + def setUpClass(cls) -> None: + cls.model_name = "hf-internal-testing/test-opus-tatoeba-fi-en-v2" + return cls + + @slow + def test_batch_generation_en_fr(self): + self._assert_generated_batch_equal_expected() + + +@require_torch +class TestConversionUtils(unittest.TestCase): + def test_renaming_multilingual(self): + old_names = [ + "opus-mt-cmn+cn+yue+ze_zh+zh_cn+zh_CN+zh_HK+zh_tw+zh_TW+zh_yue+zhs+zht+zh-fi", + "opus-mt-cmn+cn-fi", # no group + "opus-mt-en-de", # standard name + "opus-mt-en-de", # standard name + ] + expected = ["opus-mt-ZH-fi", "opus-mt-cmn_cn-fi", "opus-mt-en-de", "opus-mt-en-de"] + self.assertListEqual(expected, [convert_opus_name_to_hf_name(x) for x in old_names]) + + def test_undoing_renaming(self): + hf_names = ["opus-mt-ZH-fi", "opus-mt-cmn_cn-fi", "opus-mt-en-de", "opus-mt-en-de"] + converted_opus_names = [convert_hf_name_to_opus_name(x) for x in hf_names] + expected_opus_names = [ + "cmn+cn+yue+ze_zh+zh_cn+zh_CN+zh_HK+zh_tw+zh_TW+zh_yue+zhs+zht+zh-fi", + "cmn+cn-fi", + "en-de", # standard name + "en-de", + ] + self.assertListEqual(expected_opus_names, converted_opus_names) + + +class MarianStandaloneDecoderModelTester: + def __init__( + self, + parent, + vocab_size=99, + batch_size=13, + d_model=16, + decoder_seq_length=7, + is_training=True, + is_decoder=True, + use_attention_mask=True, + use_cache=False, + use_labels=True, + decoder_start_token_id=2, + decoder_ffn_dim=32, + decoder_layers=4, + encoder_attention_heads=4, + decoder_attention_heads=4, + max_position_embeddings=30, + is_encoder_decoder=False, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + scope=None, + ): + self.parent = parent + self.batch_size = batch_size + self.decoder_seq_length = decoder_seq_length + # For common tests + self.seq_length = self.decoder_seq_length + self.is_training = is_training + self.use_attention_mask = use_attention_mask + self.use_labels = use_labels + + self.vocab_size = vocab_size + self.d_model = d_model + self.hidden_size = d_model + self.num_hidden_layers = decoder_layers + self.decoder_layers = decoder_layers + self.decoder_ffn_dim = decoder_ffn_dim + self.encoder_attention_heads = encoder_attention_heads + self.decoder_attention_heads = decoder_attention_heads + self.num_attention_heads = decoder_attention_heads + self.eos_token_id = eos_token_id + self.bos_token_id = bos_token_id + self.pad_token_id = pad_token_id + self.decoder_start_token_id = decoder_start_token_id + self.use_cache = use_cache + self.max_position_embeddings = max_position_embeddings + self.is_encoder_decoder = is_encoder_decoder + + self.scope = None + self.decoder_key_length = decoder_seq_length + self.base_model_out_len = 2 + self.decoder_attention_idx = 1 + + def prepare_config_and_inputs(self): + input_ids = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + attention_mask = None + if self.use_attention_mask: + attention_mask = ids_tensor([self.batch_size, self.decoder_seq_length], vocab_size=2) + + lm_labels = None + if self.use_labels: + lm_labels = ids_tensor([self.batch_size, self.decoder_seq_length], self.vocab_size) + + config = MarianConfig( + vocab_size=self.vocab_size, + d_model=self.d_model, + decoder_layers=self.decoder_layers, + decoder_ffn_dim=self.decoder_ffn_dim, + encoder_attention_heads=self.encoder_attention_heads, + decoder_attention_heads=self.decoder_attention_heads, + eos_token_id=self.eos_token_id, + bos_token_id=self.bos_token_id, + use_cache=self.use_cache, + pad_token_id=self.pad_token_id, + decoder_start_token_id=self.decoder_start_token_id, + max_position_embeddings=self.max_position_embeddings, + is_encoder_decoder=self.is_encoder_decoder, + ) + + return ( + config, + input_ids, + attention_mask, + lm_labels, + ) + + def create_and_check_decoder_model_past( + self, + config, + input_ids, + attention_mask, + lm_labels, + ): + config.use_cache = True + model = MarianDecoder(config=config).to(torch_device).eval() + # first forward pass + outputs = model(input_ids, use_cache=True) + outputs_use_cache_conf = model(input_ids) + outputs_no_past = model(input_ids, use_cache=False) + + self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf)) + self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1) + + past_key_values = outputs["past_key_values"] + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # append to next input_ids and + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + + output_from_no_past = model(next_input_ids)["last_hidden_state"] + output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, next_input_ids.shape[-1] - 1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + assert torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3) + + def create_and_check_decoder_model_attention_mask_past( + self, + config, + input_ids, + attention_mask, + lm_labels, + ): + model = MarianDecoder(config=config).to(torch_device).eval() + + # create attention mask + attn_mask = torch.ones(input_ids.shape, dtype=torch.long, device=torch_device) + + half_seq_length = input_ids.shape[-1] // 2 + attn_mask[:, half_seq_length:] = 0 + + # first forward pass + past_key_values = model(input_ids, attention_mask=attn_mask, use_cache=True)["past_key_values"] + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size) + + # change a random masked slice from input_ids + random_seq_idx_to_change = ids_tensor((1,), half_seq_length).item() + 1 + random_other_next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size).squeeze(-1) + input_ids[:, -random_seq_idx_to_change] = random_other_next_tokens + + # append to next input_ids and attn_mask + next_input_ids = torch.cat([input_ids, next_tokens], dim=-1) + attn_mask = torch.cat( + [attn_mask, torch.ones((attn_mask.shape[0], 1), dtype=torch.long, device=torch_device)], + dim=1, + ) + + # get two different outputs + output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"] + output_from_past = model(next_tokens, attention_mask=attn_mask, past_key_values=past_key_values)[ + "last_hidden_state" + ] + + # select random slice + random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item() + output_from_no_past_slice = output_from_no_past[:, next_input_ids.shape[-1] - 1, random_slice_idx].detach() + output_from_past_slice = output_from_past[:, 0, random_slice_idx].detach() + + # test that outputs are equal for slice + assert torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3) + + def prepare_config_and_inputs_for_common(self): + config_and_inputs = self.prepare_config_and_inputs() + ( + config, + input_ids, + attention_mask, + lm_labels, + ) = config_and_inputs + + inputs_dict = { + "input_ids": input_ids, + "attention_mask": attention_mask, + } + return config, inputs_dict + + +@require_torch +class MarianStandaloneDecoderModelTest(ModelTesterMixin, GenerationTesterMixin, unittest.TestCase): + all_model_classes = (MarianDecoder, MarianForCausalLM) if is_torch_available() else () + all_generative_model_classes = (MarianForCausalLM,) if is_torch_available() else () + test_pruning = False + is_encoder_decoder = False + + def setUp( + self, + ): + self.model_tester = MarianStandaloneDecoderModelTester(self, is_training=False) + self.config_tester = ConfigTester(self, config_class=MarianConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_decoder_model_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_past(*config_and_inputs) + + def test_decoder_model_attn_mask_past(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_decoder_model_attention_mask_past(*config_and_inputs) + + def test_retain_grad_hidden_states_attentions(self): + # decoder cannot keep gradients + return diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_tf_marian.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_tf_marian.py new file mode 100644 index 0000000000000000000000000000000000000000..16b19b0f9763a20090e923afae021ccbf4813622 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/marian/test_modeling_tf_marian.py @@ -0,0 +1,368 @@ +# coding=utf-8 +# Copyright 2021 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import tempfile +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, tooslow +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 TFAutoModelForSeq2SeqLM, TFMarianModel, TFMarianMTModel + + +@require_tf +class TFMarianModelTester: + config_cls = MarianConfig + config_updates = {} + hidden_act = "gelu" + + def __init__( + self, + parent, + batch_size=13, + seq_length=7, + is_training=True, + use_labels=False, + vocab_size=99, + hidden_size=32, + num_hidden_layers=5, + num_attention_heads=4, + intermediate_size=37, + hidden_dropout_prob=0.1, + attention_probs_dropout_prob=0.1, + max_position_embeddings=20, + eos_token_id=2, + pad_token_id=1, + bos_token_id=0, + ): + self.parent = parent + self.batch_size = batch_size + self.seq_length = seq_length + self.is_training = is_training + self.use_labels = use_labels + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.intermediate_size = intermediate_size + + self.hidden_dropout_prob = hidden_dropout_prob + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.max_position_embeddings = max_position_embeddings + self.eos_token_id = eos_token_id + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + + def prepare_config_and_inputs_for_common(self): + input_ids = ids_tensor([self.batch_size, self.seq_length - 1], self.vocab_size) + eos_tensor = tf.expand_dims(tf.constant([self.eos_token_id] * self.batch_size), 1) + input_ids = tf.concat([input_ids, eos_tensor], axis=1) + + decoder_input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size) + + config = 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, + ) + inputs_dict = prepare_marian_inputs_dict(config, input_ids, decoder_input_ids) + return config, inputs_dict + + def check_decoder_model_past_large_inputs(self, config, inputs_dict): + model = TFMarianModel(config=config).get_decoder() + input_ids = inputs_dict["input_ids"] + + input_ids = input_ids[:1, :] + attention_mask = inputs_dict["attention_mask"][:1, :] + head_mask = inputs_dict["head_mask"] + self.batch_size = 1 + + # first forward pass + outputs = model(input_ids, attention_mask=attention_mask, head_mask=head_mask, use_cache=True) + + output, past_key_values = outputs.to_tuple() + + # create hypothetical next token and extent to next_input_ids + next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size) + next_attn_mask = tf.cast(ids_tensor((self.batch_size, 3), 2), tf.int8) + + # append to next input_ids and + next_input_ids = tf.concat([input_ids, next_tokens], axis=-1) + next_attention_mask = tf.concat([attention_mask, next_attn_mask], axis=-1) + + output_from_no_past = model(next_input_ids, attention_mask=next_attention_mask)[0] + output_from_past = model(next_tokens, attention_mask=next_attention_mask, past_key_values=past_key_values)[0] + + self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1]) + + # select random slice + random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1])) + output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx] + output_from_past_slice = output_from_past[:, :, random_slice_idx] + + # test that outputs are equal for slice + tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3) + + +def prepare_marian_inputs_dict( + config, + input_ids, + decoder_input_ids, + attention_mask=None, + decoder_attention_mask=None, + head_mask=None, + decoder_head_mask=None, + cross_attn_head_mask=None, +): + if attention_mask is None: + attention_mask = tf.cast(tf.math.not_equal(input_ids, config.pad_token_id), tf.int8) + if decoder_attention_mask is None: + decoder_attention_mask = tf.concat( + [ + tf.ones(decoder_input_ids[:, :1].shape, dtype=tf.int8), + tf.cast(tf.math.not_equal(decoder_input_ids[:, 1:], config.pad_token_id), tf.int8), + ], + axis=-1, + ) + if head_mask is None: + head_mask = tf.ones((config.encoder_layers, config.encoder_attention_heads)) + if decoder_head_mask is None: + decoder_head_mask = tf.ones((config.decoder_layers, config.decoder_attention_heads)) + if cross_attn_head_mask is None: + cross_attn_head_mask = 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 TFMarianModelTest(TFModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (TFMarianMTModel, TFMarianModel) if is_tf_available() else () + all_generative_model_classes = (TFMarianMTModel,) if is_tf_available() else () + pipeline_model_mapping = ( + { + "conversational": TFMarianMTModel, + "feature-extraction": TFMarianModel, + "summarization": TFMarianMTModel, + "text2text-generation": TFMarianMTModel, + "translation": TFMarianMTModel, + } + if is_tf_available() + else {} + ) + is_encoder_decoder = True + test_pruning = False + test_onnx = False + + def setUp(self): + self.model_tester = TFMarianModelTester(self) + self.config_tester = ConfigTester(self, config_class=MarianConfig) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_decoder_model_past_large_inputs(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.check_decoder_model_past_large_inputs(*config_and_inputs) + + def test_compile_tf_model(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0) + loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) + metric = tf.keras.metrics.SparseCategoricalAccuracy("accuracy") + + model_class = self.all_generative_model_classes[0] + input_ids = { + "decoder_input_ids": tf.keras.Input(batch_shape=(2, 2000), name="decoder_input_ids", dtype="int32"), + "input_ids": tf.keras.Input(batch_shape=(2, 2000), name="input_ids", dtype="int32"), + } + + # Prepare our model + model = model_class(config) + model(self._prepare_for_class(inputs_dict, model_class)) # Model must be called before saving. + # Let's load it from the disk to be sure we can use pre-trained weights + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model = model_class.from_pretrained(tmpdirname) + + outputs_dict = model(input_ids) + hidden_states = outputs_dict[0] + + # Add a dense layer on top to test integration with other keras modules + outputs = tf.keras.layers.Dense(2, activation="softmax", name="outputs")(hidden_states) + + # Compile extended model + extended_model = tf.keras.Model(inputs=[input_ids], outputs=[outputs]) + extended_model.compile(optimizer=optimizer, loss=loss, metrics=[metric]) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + + if model_class in self.all_generative_model_classes: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + @tooslow + def test_saved_model_creation(self): + pass + + +@require_tf +class AbstractMarianIntegrationTest(unittest.TestCase): + maxDiff = 1000 # show more chars for failing integration tests + + @classmethod + def setUpClass(cls) -> None: + cls.model_name = f"Helsinki-NLP/opus-mt-{cls.src}-{cls.tgt}" + return cls + + @cached_property + def tokenizer(self) -> MarianTokenizer: + return AutoTokenizer.from_pretrained(self.model_name) + + @property + def eos_token_id(self) -> int: + return self.tokenizer.eos_token_id + + @cached_property + def model(self): + warnings.simplefilter("error") + model: TFMarianMTModel = TFAutoModelForSeq2SeqLM.from_pretrained(self.model_name) + assert isinstance(model, TFMarianMTModel) + c = 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 _assert_generated_batch_equal_expected(self, **tokenizer_kwargs): + generated_words = self.translate_src_text(**tokenizer_kwargs) + self.assertListEqual(self.expected_text, generated_words) + + def translate_src_text(self, **tokenizer_kwargs): + model_inputs = self.tokenizer(self.src_text, **tokenizer_kwargs, padding=True, return_tensors="tf") + generated_ids = self.model.generate( + model_inputs.input_ids, attention_mask=model_inputs.attention_mask, num_beams=2, max_length=128 + ) + generated_words = self.tokenizer.batch_decode(generated_ids.numpy(), skip_special_tokens=True) + return generated_words + + +@require_sentencepiece +@require_tokenizers +@require_tf +class TestMarian_MT_EN(AbstractMarianIntegrationTest): + """Cover low resource/high perplexity setting. This breaks if pad_token_id logits not set to LARGE_NEGATIVE.""" + + src = "mt" + tgt = "en" + src_text = ["Billi messu b'mod ġentili, Ġesù fejjaq raġel li kien milqut bil - marda kerha tal - ġdiem."] + expected_text = ["Touching gently, Jesus healed a man who was affected by the sad disease of leprosy."] + + @unittest.skip("Skipping until #12647 is resolved.") + @slow + def test_batch_generation_mt_en(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +@require_tf +class TestMarian_en_zh(AbstractMarianIntegrationTest): + src = "en" + tgt = "zh" + src_text = ["My name is Wolfgang and I live in Berlin"] + expected_text = ["我叫沃尔夫冈 我住在柏林"] + + @unittest.skip("Skipping until #12647 is resolved.") + @slow + def test_batch_generation_en_zh(self): + self._assert_generated_batch_equal_expected() + + +@require_sentencepiece +@require_tokenizers +@require_tf +class TestMarian_en_ROMANCE(AbstractMarianIntegrationTest): + """Multilingual on target side.""" + + src = "en" + tgt = "ROMANCE" + src_text = [ + ">>fr<< Don't spend so much time watching TV.", + ">>pt<< Your message has been sent.", + ">>es<< He's two years older than me.", + ] + expected_text = [ + "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 test_batch_generation_en_ROMANCE_multi(self): + self._assert_generated_batch_equal_expected() + + @unittest.skip("Skipping until #12647 is resolved.") + @slow + def test_pipeline(self): + pipeline = TranslationPipeline(self.model, self.tokenizer, framework="tf") + output = pipeline(self.src_text) + self.assertEqual(self.expected_text, [x["translation_text"] for x in output]) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_feature_extraction_markuplm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_feature_extraction_markuplm.py new file mode 100644 index 0000000000000000000000000000000000000000..4541cb9480bbe81fd2e387180b35424cf274eb9e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_feature_extraction_markuplm.py @@ -0,0 +1,114 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import unittest + +from transformers.testing_utils import require_bs4 +from transformers.utils import is_bs4_available + +from ...test_feature_extraction_common import FeatureExtractionSavingTestMixin + + +if is_bs4_available(): + from transformers import MarkupLMFeatureExtractor + + +class MarkupLMFeatureExtractionTester(unittest.TestCase): + def __init__(self, parent): + self.parent = parent + + def prepare_feat_extract_dict(self): + return {} + + +def get_html_strings(): + html_string_1 = """ + + + sample document + + + +


+ Goog +

This is one header

+

This is a another Header

+

Travel from +

+ SFO to JFK +
+ on May 2, 2015 at 2:00 pm. For details go to confirm.com +


+
+

Traveler name is +

John Doe

+

""" + + html_string_2 = """ + + + + +

My First Heading

+

My first paragraph.

+ + + + """ + + return [html_string_1, html_string_2] + + +@require_bs4 +class MarkupLMFeatureExtractionTest(FeatureExtractionSavingTestMixin, unittest.TestCase): + feature_extraction_class = MarkupLMFeatureExtractor if is_bs4_available() else None + + def setUp(self): + self.feature_extract_tester = MarkupLMFeatureExtractionTester(self) + + @property + def feat_extract_dict(self): + return self.feature_extract_tester.prepare_feat_extract_dict() + + def test_call(self): + # Initialize feature_extractor + feature_extractor = self.feature_extraction_class() + + # Test not batched input + html_string = get_html_strings()[0] + encoding = feature_extractor(html_string) + + # fmt: off + expected_nodes = [['sample document', 'Goog', 'This is one header', 'This is a another Header', 'Travel from', 'SFO to JFK', 'on May 2, 2015 at 2:00 pm. For details go to confirm.com', 'Traveler', 'name', 'is', 'John Doe']] + expected_xpaths = [['/html/head/title', '/html/body/a', '/html/body/h1', '/html/body/h2', '/html/body/p', '/html/body/p/p/b[1]', '/html/body/p/p/b[2]/i', '/html/body/p/p/div/h3', '/html/body/p/p/div/h3/b', '/html/body/p/p/div/h3', '/html/body/p/p/div/h3/p']] + # fmt: on + + self.assertEqual(encoding.nodes, expected_nodes) + self.assertEqual(encoding.xpaths, expected_xpaths) + + # Test batched + html_strings = get_html_strings() + encoding = feature_extractor(html_strings) + + # fmt: off + expected_nodes = expected_nodes + [['My First Heading', 'My first paragraph.']] + expected_xpaths = expected_xpaths + [['/html/body/h1', '/html/body/p']] + + self.assertEqual(len(encoding.nodes), 2) + self.assertEqual(len(encoding.xpaths), 2) + + self.assertEqual(encoding.nodes, expected_nodes) + self.assertEqual(encoding.xpaths, expected_xpaths) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_processor_markuplm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_processor_markuplm.py new file mode 100644 index 0000000000000000000000000000000000000000..4bafc32335dcdfc89d67e613f29e38424e7c28ab --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_processor_markuplm.py @@ -0,0 +1,463 @@ +# Copyright 2022 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil +import tempfile +import unittest +from typing import List + +from transformers import ( + MarkupLMProcessor, + MarkupLMTokenizer, + PreTrainedTokenizer, + PreTrainedTokenizerBase, + PreTrainedTokenizerFast, +) +from transformers.models.markuplm.tokenization_markuplm import VOCAB_FILES_NAMES +from transformers.testing_utils import require_bs4, require_tokenizers, require_torch, slow +from transformers.utils import FEATURE_EXTRACTOR_NAME, cached_property, is_bs4_available, is_tokenizers_available + + +if is_bs4_available(): + from transformers import MarkupLMFeatureExtractor + +if is_tokenizers_available(): + from transformers import MarkupLMTokenizerFast + + +@require_bs4 +@require_tokenizers +class MarkupLMProcessorTest(unittest.TestCase): + tokenizer_class = MarkupLMTokenizer + rust_tokenizer_class = MarkupLMTokenizerFast + + def setUp(self): + # Adapted from Sennrich et al. 2015 and https://github.com/rsennrich/subword-nmt + # fmt: off + vocab = ["l", "o", "w", "e", "r", "s", "t", "i", "d", "n", "\u0120", "\u0120l", "\u0120n", "\u0120lo", "\u0120low", "er", "\u0120lowest", "\u0120newer", "\u0120wider", "\u0120hello", "\u0120world", "",] # noqa + # fmt: on + self.tmpdirname = tempfile.mkdtemp() + vocab_tokens = dict(zip(vocab, range(len(vocab)))) + merges = ["#version: 0.2", "\u0120 l", "\u0120l o", "\u0120lo w", "e r", ""] + self.tags_dict = {"a": 0, "abbr": 1, "acronym": 2, "address": 3} + self.special_tokens_map = {"unk_token": ""} + + self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"]) + self.merges_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["merges_file"]) + self.tokenizer_config_file = os.path.join(self.tmpdirname, "tokenizer_config.json") + + with open(self.vocab_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(vocab_tokens) + "\n") + with open(self.merges_file, "w", encoding="utf-8") as fp: + fp.write("\n".join(merges)) + with open(self.tokenizer_config_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps({"tags_dict": self.tags_dict})) + + feature_extractor_map = {"feature_extractor_type": "MarkupLMFeatureExtractor"} + self.feature_extraction_file = os.path.join(self.tmpdirname, FEATURE_EXTRACTOR_NAME) + with open(self.feature_extraction_file, "w", encoding="utf-8") as fp: + fp.write(json.dumps(feature_extractor_map) + "\n") + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs) -> PreTrainedTokenizerFast: + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_tokenizers(self, **kwargs) -> List[PreTrainedTokenizerBase]: + return [self.get_tokenizer(**kwargs), self.get_rust_tokenizer(**kwargs)] + + def get_feature_extractor(self, **kwargs): + return MarkupLMFeatureExtractor.from_pretrained(self.tmpdirname, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def test_save_load_pretrained_default(self): + feature_extractor = self.get_feature_extractor() + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + processor.save_pretrained(self.tmpdirname) + processor = MarkupLMProcessor.from_pretrained(self.tmpdirname) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer.get_vocab()) + self.assertIsInstance(processor.tokenizer, (MarkupLMTokenizer, MarkupLMTokenizerFast)) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor.to_json_string()) + self.assertIsInstance(processor.feature_extractor, MarkupLMFeatureExtractor) + + def test_save_load_pretrained_additional_features(self): + processor = MarkupLMProcessor(feature_extractor=self.get_feature_extractor(), tokenizer=self.get_tokenizer()) + processor.save_pretrained(self.tmpdirname) + + # slow tokenizer + tokenizer_add_kwargs = self.get_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + feature_extractor_add_kwargs = self.get_feature_extractor(do_resize=False, size=30) + + processor = MarkupLMProcessor.from_pretrained( + self.tmpdirname, use_fast=False, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, MarkupLMTokenizer) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.feature_extractor, MarkupLMFeatureExtractor) + + # fast tokenizer + tokenizer_add_kwargs = self.get_rust_tokenizer(bos_token="(BOS)", eos_token="(EOS)") + feature_extractor_add_kwargs = self.get_feature_extractor(do_resize=False, size=30) + + processor = MarkupLMProcessor.from_pretrained( + self.tmpdirname, bos_token="(BOS)", eos_token="(EOS)", do_resize=False, size=30 + ) + + self.assertEqual(processor.tokenizer.get_vocab(), tokenizer_add_kwargs.get_vocab()) + self.assertIsInstance(processor.tokenizer, MarkupLMTokenizerFast) + + self.assertEqual(processor.feature_extractor.to_json_string(), feature_extractor_add_kwargs.to_json_string()) + self.assertIsInstance(processor.feature_extractor, MarkupLMFeatureExtractor) + + def test_model_input_names(self): + feature_extractor = self.get_feature_extractor() + tokenizer = self.get_tokenizer() + + processor = MarkupLMProcessor(tokenizer=tokenizer, feature_extractor=feature_extractor) + + self.assertListEqual( + processor.model_input_names, + tokenizer.model_input_names, + msg="`processor` and `tokenizer` model input names do not match", + ) + + +# different use cases tests +@require_bs4 +@require_torch +class MarkupLMProcessorIntegrationTests(unittest.TestCase): + @cached_property + def get_html_strings(self): + html_string_1 = """ + + + + Hello world + + + +

Welcome

+

Here is my website.

+ + + """ + + html_string_2 = """ + + + + +

HTML Images

+

HTML images are defined with the img tag:

+ + W3Schools.com + + + + """ + + return [html_string_1, html_string_2] + + @cached_property + def get_tokenizers(self): + slow_tokenizer = MarkupLMTokenizer.from_pretrained("microsoft/markuplm-base") + fast_tokenizer = MarkupLMTokenizerFast.from_pretrained("microsoft/markuplm-base", from_slow=True) + return [slow_tokenizer, fast_tokenizer] + + @slow + def test_processor_case_1(self): + # case 1: web page classification (training, inference) + token classification (inference) + + feature_extractor = MarkupLMFeatureExtractor() + tokenizers = self.get_tokenizers + html_strings = self.get_html_strings + + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + inputs = processor(html_strings[0], return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected = [0, 31414, 232, 25194, 11773, 16, 127, 998, 4, 2] + self.assertSequenceEqual(inputs.input_ids.squeeze().tolist(), expected) + + # batched + inputs = processor(html_strings, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected = [0, 48085, 2209, 48085, 3156, 32, 6533, 19, 5, 48599, 6694, 35, 2] + self.assertSequenceEqual(inputs.input_ids[1].tolist(), expected) + + @slow + def test_processor_case_2(self): + # case 2: web page classification (training, inference) + token classification (inference), parse_html=False + + feature_extractor = MarkupLMFeatureExtractor() + tokenizers = self.get_tokenizers + + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + processor.parse_html = False + + # not batched + nodes = ["hello", "world", "how", "are"] + xpaths = ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span", "html/body", "html/body/div"] + inputs = processor(nodes=nodes, xpaths=xpaths, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = list(inputs.keys()) + for key in expected_keys: + self.assertIn(key, actual_keys) + + # verify input_ids + expected_decoding = "helloworldhoware" + decoding = processor.decode(inputs.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + nodes = [["hello", "world"], ["my", "name", "is"]] + xpaths = [ + ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span"], + ["html/body", "html/body/div", "html/body"], + ] + inputs = processor(nodes=nodes, xpaths=xpaths, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "helloworld" + decoding = processor.decode(inputs.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + @slow + def test_processor_case_3(self): + # case 3: token classification (training), parse_html=False + + feature_extractor = MarkupLMFeatureExtractor() + tokenizers = self.get_tokenizers + + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + processor.parse_html = False + + # not batched + nodes = ["hello", "world", "how", "are"] + xpaths = ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span", "html/body", "html/body/div"] + node_labels = [1, 2, 2, 1] + inputs = processor(nodes=nodes, xpaths=xpaths, node_labels=node_labels, return_tensors="pt") + + # verify keys + expected_keys = [ + "attention_mask", + "input_ids", + "labels", + "token_type_ids", + "xpath_subs_seq", + "xpath_tags_seq", + ] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_ids = [0, 42891, 8331, 9178, 1322, 2] + self.assertSequenceEqual(inputs.input_ids[0].tolist(), expected_ids) + + # verify labels + expected_labels = [-100, 1, 2, 2, 1, -100] + self.assertListEqual(inputs.labels.squeeze().tolist(), expected_labels) + + # batched + nodes = [["hello", "world"], ["my", "name", "is"]] + xpaths = [ + ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span"], + ["html/body", "html/body/div", "html/body"], + ] + node_labels = [[1, 2], [6, 3, 10]] + inputs = processor( + nodes=nodes, + xpaths=xpaths, + node_labels=node_labels, + padding="max_length", + max_length=20, + truncation=True, + return_tensors="pt", + ) + + # verify keys + expected_keys = [ + "attention_mask", + "input_ids", + "labels", + "token_type_ids", + "xpath_subs_seq", + "xpath_tags_seq", + ] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_ids = [0, 4783, 13650, 354, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + self.assertSequenceEqual(inputs.input_ids[1].tolist(), expected_ids) + + # verify xpath_tags_seq + # fmt: off + expected_xpaths_tags_seq = [[216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [109, 25, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [109, 25, 50, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [109, 25, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216], [216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216]] # noqa: + # fmt: on + self.assertSequenceEqual(inputs.xpath_tags_seq[1].tolist(), expected_xpaths_tags_seq) + + # verify labels + # fmt: off + expected_labels = [-100, 6, 3, 10, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100] + # fmt: on + self.assertListEqual(inputs.labels[1].tolist(), expected_labels) + + @slow + def test_processor_case_4(self): + # case 4: question answering (inference), parse_html=True + + feature_extractor = MarkupLMFeatureExtractor() + tokenizers = self.get_tokenizers + html_strings = self.get_html_strings + + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + + # not batched + question = "What's his name?" + inputs = processor(html_strings[0], questions=question, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + # fmt: off + expected_decoding = "What's his name?Hello worldWelcomeHere is my website." # noqa: E231 + # fmt: on + decoding = processor.decode(inputs.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + inputs = processor( + html_strings, + questions=questions, + padding="max_length", + max_length=20, + truncation=True, + return_tensors="pt", + ) + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = ( + "what's the timeHTML ImagesHTML images are defined with the img tag:" + ) + decoding = processor.decode(inputs.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify xpath_subs_seq + # fmt: off + expected_xpath_subs_seq = [[1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001]] + # fmt: on + self.assertListEqual(inputs.xpath_subs_seq[1].tolist(), expected_xpath_subs_seq) + + @slow + def test_processor_case_5(self): + # case 5: question answering (inference), parse_html=False + + feature_extractor = MarkupLMFeatureExtractor(parse_html=False) + tokenizers = self.get_tokenizers + + for tokenizer in tokenizers: + processor = MarkupLMProcessor(feature_extractor=feature_extractor, tokenizer=tokenizer) + processor.parse_html = False + + # not batched + question = "What's his name?" + nodes = ["hello", "world", "how", "are"] + xpaths = ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span", "html/body", "html/body/div"] + inputs = processor(nodes=nodes, xpaths=xpaths, questions=question, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "What's his name?helloworldhoware" + decoding = processor.decode(inputs.input_ids.squeeze().tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # batched + questions = ["How old is he?", "what's the time"] + nodes = [["hello", "world"], ["my", "name", "is"]] + xpaths = [ + ["/html/body/div/li[1]/div/span", "/html/body/div/li[1]/div/span"], + ["html/body", "html/body/div", "html/body"], + ] + inputs = processor(nodes=nodes, xpaths=xpaths, questions=questions, padding=True, return_tensors="pt") + + # verify keys + expected_keys = ["attention_mask", "input_ids", "token_type_ids", "xpath_subs_seq", "xpath_tags_seq"] + actual_keys = sorted(inputs.keys()) + self.assertListEqual(actual_keys, expected_keys) + + # verify input_ids + expected_decoding = "How old is he?helloworld" + decoding = processor.decode(inputs.input_ids[0].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + expected_decoding = "what's the timemynameis" + decoding = processor.decode(inputs.input_ids[1].tolist()) + self.assertSequenceEqual(decoding, expected_decoding) + + # verify xpath_subs_seq + # fmt: off + expected_xpath_subs_seq = [[1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [0, 0, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001], [1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001]] + # fmt: on + self.assertListEqual(inputs.xpath_subs_seq[1].tolist()[-5:], expected_xpath_subs_seq) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_tokenization_markuplm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/markuplm/test_tokenization_markuplm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mask2former/test_modeling_mask2former.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mask2former/test_modeling_mask2former.py new file mode 100644 index 0000000000000000000000000000000000000000..8d7cd52f0f7f4059bae87475c3a3886f7ce6290b --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mask2former/test_modeling_mask2former.py @@ -0,0 +1,426 @@ +# coding=utf-8 +# Copyright 2022 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" Testing suite for the PyTorch Mask2Former model. """ + +import inspect +import unittest + +import numpy as np + +from tests.test_modeling_common import floats_tensor +from transformers import Mask2FormerConfig, is_torch_available, is_vision_available +from transformers.testing_utils import require_torch, require_torch_multi_gpu, require_vision, slow, torch_device +from transformers.utils import cached_property + +from ...test_configuration_common import ConfigTester +from ...test_modeling_common import ModelTesterMixin +from ...test_pipeline_mixin import PipelineTesterMixin + + +if is_torch_available(): + import torch + + from transformers import Mask2FormerForUniversalSegmentation, Mask2FormerModel + + if is_vision_available(): + from transformers import Mask2FormerImageProcessor + +if is_vision_available(): + from PIL import Image + + +class Mask2FormerModelTester: + def __init__( + self, + parent, + batch_size=2, + is_training=True, + use_auxiliary_loss=False, + num_queries=10, + num_channels=3, + min_size=32 * 8, + max_size=32 * 8, + num_labels=4, + hidden_dim=64, + ): + self.parent = parent + self.batch_size = batch_size + self.is_training = is_training + self.use_auxiliary_loss = use_auxiliary_loss + self.num_queries = num_queries + self.num_channels = num_channels + self.min_size = min_size + self.max_size = max_size + self.num_labels = num_labels + self.hidden_dim = hidden_dim + self.mask_feature_size = hidden_dim + + def prepare_config_and_inputs(self): + pixel_values = floats_tensor([self.batch_size, self.num_channels, self.min_size, self.max_size]).to( + torch_device + ) + + pixel_mask = torch.ones([self.batch_size, self.min_size, self.max_size], device=torch_device) + + mask_labels = ( + torch.rand([self.batch_size, self.num_labels, self.min_size, self.max_size], device=torch_device) > 0.5 + ).float() + class_labels = (torch.rand((self.batch_size, self.num_labels), device=torch_device) > 0.5).long() + + config = self.get_config() + return config, pixel_values, pixel_mask, mask_labels, class_labels + + def get_config(self): + config = Mask2FormerConfig( + hidden_size=self.hidden_dim, + ) + config.num_queries = self.num_queries + config.num_labels = self.num_labels + + config.backbone_config.depths = [1, 1, 1, 1] + config.backbone_config.num_channels = self.num_channels + + config.encoder_feedforward_dim = 64 + config.dim_feedforward = 128 + config.hidden_dim = self.hidden_dim + config.mask_feature_size = self.hidden_dim + config.feature_size = self.hidden_dim + return config + + def prepare_config_and_inputs_for_common(self): + config, pixel_values, pixel_mask, _, _ = self.prepare_config_and_inputs() + inputs_dict = {"pixel_values": pixel_values, "pixel_mask": pixel_mask} + return config, inputs_dict + + def check_output_hidden_state(self, output, config): + encoder_hidden_states = output.encoder_hidden_states + pixel_decoder_hidden_states = output.pixel_decoder_hidden_states + transformer_decoder_hidden_states = output.transformer_decoder_hidden_states + + self.parent.assertTrue(len(encoder_hidden_states), len(config.backbone_config.depths)) + self.parent.assertTrue(len(pixel_decoder_hidden_states), len(config.backbone_config.depths)) + self.parent.assertTrue(len(transformer_decoder_hidden_states), config.decoder_layers) + + def create_and_check_mask2former_model(self, config, pixel_values, pixel_mask, output_hidden_states=False): + with torch.no_grad(): + model = Mask2FormerModel(config=config) + model.to(torch_device) + model.eval() + + output = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + output = model(pixel_values, output_hidden_states=True) + + self.parent.assertEqual( + output.transformer_decoder_last_hidden_state.shape, + (self.batch_size, self.num_queries, self.hidden_dim), + ) + # let's ensure the other two hidden state exists + self.parent.assertTrue(output.pixel_decoder_last_hidden_state is not None) + self.parent.assertTrue(output.encoder_last_hidden_state is not None) + + if output_hidden_states: + self.check_output_hidden_state(output, config) + + def create_and_check_mask2former_instance_segmentation_head_model( + self, config, pixel_values, pixel_mask, mask_labels, class_labels + ): + model = Mask2FormerForUniversalSegmentation(config=config) + model.to(torch_device) + model.eval() + + def comm_check_on_output(result): + # let's still check that all the required stuff is there + self.parent.assertTrue(result.transformer_decoder_last_hidden_state is not None) + self.parent.assertTrue(result.pixel_decoder_last_hidden_state is not None) + self.parent.assertTrue(result.encoder_last_hidden_state is not None) + # okay, now we need to check the logits shape + # due to the encoder compression, masks have a //4 spatial size + self.parent.assertEqual( + result.masks_queries_logits.shape, + (self.batch_size, self.num_queries, self.min_size // 4, self.max_size // 4), + ) + # + 1 for null class + self.parent.assertEqual( + result.class_queries_logits.shape, (self.batch_size, self.num_queries, self.num_labels + 1) + ) + + with torch.no_grad(): + result = model(pixel_values=pixel_values, pixel_mask=pixel_mask) + result = model(pixel_values) + + comm_check_on_output(result) + + result = model( + pixel_values=pixel_values, pixel_mask=pixel_mask, mask_labels=mask_labels, class_labels=class_labels + ) + + comm_check_on_output(result) + + self.parent.assertTrue(result.loss is not None) + self.parent.assertEqual(result.loss.shape, torch.Size([1])) + + +@require_torch +class Mask2FormerModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase): + all_model_classes = (Mask2FormerModel, Mask2FormerForUniversalSegmentation) if is_torch_available() else () + pipeline_model_mapping = {"feature-extraction": Mask2FormerModel} if is_torch_available() else {} + + is_encoder_decoder = False + test_pruning = False + test_head_masking = False + test_missing_keys = False + + def setUp(self): + self.model_tester = Mask2FormerModelTester(self) + self.config_tester = ConfigTester(self, config_class=Mask2FormerConfig, has_text_modality=False) + + def test_config(self): + self.config_tester.run_common_tests() + + def test_mask2former_model(self): + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.create_and_check_mask2former_model(config, **inputs, output_hidden_states=False) + + def test_mask2former_instance_segmentation_head_model(self): + config_and_inputs = self.model_tester.prepare_config_and_inputs() + self.model_tester.create_and_check_mask2former_instance_segmentation_head_model(*config_and_inputs) + + @unittest.skip(reason="Mask2Former does not use inputs_embeds") + def test_inputs_embeds(self): + pass + + @unittest.skip(reason="Mask2Former does not have a get_input_embeddings method") + def test_model_common_attributes(self): + pass + + @unittest.skip(reason="Mask2Former is not a generative model") + def test_generate_without_input_ids(self): + pass + + @unittest.skip(reason="Mask2Former does not use token embeddings") + def test_resize_tokens_embeddings(self): + pass + + @require_torch_multi_gpu + @unittest.skip( + reason="Mask2Former has some layers using `add_module` which doesn't work well with `nn.DataParallel`" + ) + def test_multi_gpu_data_parallel_forward(self): + pass + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + @slow + def test_model_from_pretrained(self): + for model_name in ["facebook/mask2former-swin-small-coco-instance"]: + model = Mask2FormerModel.from_pretrained(model_name) + self.assertIsNotNone(model) + + def test_model_with_labels(self): + size = (self.model_tester.min_size,) * 2 + inputs = { + "pixel_values": torch.randn((2, 3, *size), device=torch_device), + "mask_labels": torch.randn((2, 10, *size), device=torch_device), + "class_labels": torch.zeros(2, 10, device=torch_device).long(), + } + config = self.model_tester.get_config() + + model = Mask2FormerForUniversalSegmentation(config).to(torch_device) + outputs = model(**inputs) + self.assertTrue(outputs.loss is not None) + + def test_hidden_states_output(self): + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + self.model_tester.create_and_check_mask2former_model(config, **inputs, output_hidden_states=True) + + def test_attention_outputs(self): + config, inputs = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config).to(torch_device) + outputs = model(**inputs, output_attentions=True) + self.assertTrue(outputs.attentions is not None) + + def test_training(self): + if not self.model_tester.is_training: + return + + model_class = self.all_model_classes[1] + config, pixel_values, pixel_mask, mask_labels, class_labels = self.model_tester.prepare_config_and_inputs() + + model = model_class(config) + model.to(torch_device) + model.train() + + loss = model(pixel_values, mask_labels=mask_labels, class_labels=class_labels).loss + loss.backward() + + def test_retain_grad_hidden_states_attentions(self): + model_class = self.all_model_classes[1] + config, pixel_values, pixel_mask, mask_labels, class_labels = self.model_tester.prepare_config_and_inputs() + config.output_hidden_states = True + config.output_attentions = True + + model = model_class(config).to(torch_device) + model.train() + + outputs = model(pixel_values, mask_labels=mask_labels, class_labels=class_labels) + + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_hidden_states.retain_grad() + + pixel_decoder_hidden_states = outputs.pixel_decoder_hidden_states[0] + pixel_decoder_hidden_states.retain_grad() + + transformer_decoder_hidden_states = outputs.transformer_decoder_hidden_states[0] + transformer_decoder_hidden_states.retain_grad() + + attentions = outputs.attentions[0] + attentions.retain_grad() + + outputs.loss.backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(pixel_decoder_hidden_states.grad) + self.assertIsNotNone(transformer_decoder_hidden_states.grad) + self.assertIsNotNone(attentions.grad) + + +TOLERANCE = 1e-4 + + +# We will verify our results on an image of cute cats +def prepare_img(): + image = Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png") + return image + + +@require_vision +@slow +class Mask2FormerModelIntegrationTest(unittest.TestCase): + @cached_property + def model_checkpoints(self): + return "facebook/mask2former-swin-small-coco-instance" + + @cached_property + def default_feature_extractor(self): + return Mask2FormerImageProcessor.from_pretrained(self.model_checkpoints) if is_vision_available() else None + + def test_inference_no_head(self): + model = Mask2FormerModel.from_pretrained(self.model_checkpoints).to(torch_device) + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(image, return_tensors="pt").to(torch_device) + inputs_shape = inputs["pixel_values"].shape + # check size is divisible by 32 + self.assertTrue((inputs_shape[-1] % 32) == 0 and (inputs_shape[-2] % 32) == 0) + # check size + self.assertEqual(inputs_shape, (1, 3, 384, 384)) + + with torch.no_grad(): + outputs = model(**inputs) + + expected_slice_hidden_state = torch.tensor( + [[-0.2790, -1.0717, -1.1668], [-0.5128, -0.3128, -0.4987], [-0.5832, 0.1971, -0.0197]] + ).to(torch_device) + self.assertTrue( + torch.allclose( + outputs.encoder_last_hidden_state[0, 0, :3, :3], expected_slice_hidden_state, atol=TOLERANCE + ) + ) + + expected_slice_hidden_state = torch.tensor( + [[0.8973, 1.1847, 1.1776], [1.1934, 1.5040, 1.5128], [1.1153, 1.4486, 1.4951]] + ).to(torch_device) + self.assertTrue( + torch.allclose( + outputs.pixel_decoder_last_hidden_state[0, 0, :3, :3], expected_slice_hidden_state, atol=TOLERANCE + ) + ) + + expected_slice_hidden_state = torch.tensor( + [[2.1152, 1.7000, -0.8603], [1.5808, 1.8004, -0.9353], [1.6043, 1.7495, -0.5999]] + ).to(torch_device) + self.assertTrue( + torch.allclose( + outputs.transformer_decoder_last_hidden_state[0, :3, :3], expected_slice_hidden_state, atol=TOLERANCE + ) + ) + + def test_inference_universal_segmentation_head(self): + model = Mask2FormerForUniversalSegmentation.from_pretrained(self.model_checkpoints).to(torch_device).eval() + feature_extractor = self.default_feature_extractor + image = prepare_img() + inputs = feature_extractor(image, return_tensors="pt").to(torch_device) + inputs_shape = inputs["pixel_values"].shape + # check size is divisible by 32 + self.assertTrue((inputs_shape[-1] % 32) == 0 and (inputs_shape[-2] % 32) == 0) + # check size + self.assertEqual(inputs_shape, (1, 3, 384, 384)) + + with torch.no_grad(): + outputs = model(**inputs) + # masks_queries_logits + masks_queries_logits = outputs.masks_queries_logits + self.assertEqual( + masks_queries_logits.shape, (1, model.config.num_queries, inputs_shape[-2] // 4, inputs_shape[-1] // 4) + ) + expected_slice = [ + [-8.7839, -9.0056, -8.8121], + [-7.4104, -7.0313, -6.5401], + [-6.6105, -6.3427, -6.4675], + ] + expected_slice = torch.tensor(expected_slice).to(torch_device) + self.assertTrue(torch.allclose(masks_queries_logits[0, 0, :3, :3], expected_slice, atol=TOLERANCE)) + # class_queries_logits + class_queries_logits = outputs.class_queries_logits + self.assertEqual(class_queries_logits.shape, (1, model.config.num_queries, model.config.num_labels + 1)) + expected_slice = torch.tensor( + [ + [1.8324, -8.0835, -4.1922], + [0.8450, -9.0050, -3.6053], + [0.3045, -7.7293, -3.0275], + ] + ).to(torch_device) + self.assertTrue(torch.allclose(outputs.class_queries_logits[0, :3, :3], expected_slice, atol=TOLERANCE)) + + def test_with_segmentation_maps_and_loss(self): + model = Mask2FormerForUniversalSegmentation.from_pretrained(self.model_checkpoints).to(torch_device).eval() + feature_extractor = self.default_feature_extractor + + inputs = feature_extractor( + [np.zeros((3, 800, 1333)), np.zeros((3, 800, 1333))], + segmentation_maps=[np.zeros((384, 384)).astype(np.float32), np.zeros((384, 384)).astype(np.float32)], + return_tensors="pt", + ) + + inputs["pixel_values"] = inputs["pixel_values"].to(torch_device) + inputs["mask_labels"] = [el.to(torch_device) for el in inputs["mask_labels"]] + inputs["class_labels"] = [el.to(torch_device) for el in inputs["class_labels"]] + + with torch.no_grad(): + outputs = model(**inputs) + + self.assertTrue(outputs.loss is not None) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/maskformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/maskformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mobilevit/test_image_processing_mobilevit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mobilevit/test_image_processing_mobilevit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mpnet/test_modeling_mpnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mpnet/test_modeling_mpnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mt5/test_modeling_mt5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mt5/test_modeling_mt5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mt5/test_modeling_tf_mt5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mt5/test_modeling_tf_mt5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mvp/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/mvp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nat/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nat/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nat/test_modeling_nat.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nat/test_modeling_nat.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb_moe/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb_moe/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb_moe/test_modeling_nllb_moe.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nllb_moe/test_modeling_nllb_moe.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nystromformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/nystromformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/test_image_processing_oneformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/test_image_processing_oneformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/test_processor_oneformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/oneformer/test_processor_oneformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/open_llama/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/open_llama/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/open_llama/test_modeling_open_llama.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/open_llama/test_modeling_open_llama.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_modeling_openai.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_modeling_openai.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_modeling_tf_openai.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_modeling_tf_openai.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_tokenization_openai.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/openai/test_tokenization_openai.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_flax_opt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_flax_opt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_opt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_opt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_tf_opt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/opt/test_modeling_tf_opt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_image_processing_owlvit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_image_processing_owlvit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_modeling_owlvit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_modeling_owlvit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_processor_owlvit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/owlvit/test_processor_owlvit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_flax_pegasus.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_flax_pegasus.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_pegasus.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_pegasus.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_tf_pegasus.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_modeling_tf_pegasus.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_tokenization_pegasus.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus/test_tokenization_pegasus.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus_x/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus_x/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus_x/test_modeling_pegasus_x.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pegasus_x/test_modeling_pegasus_x.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/test_modeling_perceiver.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/test_modeling_perceiver.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/test_tokenization_perceiver.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/perceiver/test_tokenization_perceiver.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/phobert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/phobert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/phobert/test_tokenization_phobert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/phobert/test_tokenization_phobert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_image_processing_pix2struct.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_image_processing_pix2struct.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_modeling_pix2struct.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_modeling_pix2struct.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_processor_pix2struct.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/pix2struct/test_processor_pix2struct.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/test_modeling_plbart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/test_modeling_plbart.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/test_tokenization_plbart.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/plbart/test_tokenization_plbart.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/test_image_processing_poolformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/test_image_processing_poolformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/test_modeling_poolformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/poolformer/test_modeling_poolformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/test_modeling_prophetnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/test_modeling_prophetnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/test_tokenization_prophetnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/prophetnet/test_tokenization_prophetnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/qdqbert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/qdqbert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/qdqbert/test_modeling_qdqbert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/qdqbert/test_modeling_qdqbert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_modeling_rag.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_modeling_rag.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_modeling_tf_rag.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_modeling_tf_rag.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_retrieval_rag.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_retrieval_rag.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_tokenization_rag.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rag/test_tokenization_rag.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_modeling_realm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_modeling_realm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_retrieval_realm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_retrieval_realm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_tokenization_realm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/realm/test_tokenization_realm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/test_modeling_reformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/test_modeling_reformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/test_tokenization_reformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/reformer/test_tokenization_reformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_flax_regnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_flax_regnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_regnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_regnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_tf_regnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/regnet/test_modeling_tf_regnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/test_modeling_rembert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/test_modeling_rembert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/test_modeling_tf_rembert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rembert/test_modeling_tf_rembert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_flax_resnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_flax_resnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_resnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_resnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_tf_resnet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/resnet/test_modeling_tf_resnet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/retribert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/retribert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/retribert/test_tokenization_retribert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/retribert/test_tokenization_retribert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_flax_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_flax_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_tf_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_modeling_tf_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_tokenization_roberta.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta/test_tokenization_roberta.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_flax_roberta_prelayernorm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_flax_roberta_prelayernorm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_roberta_prelayernorm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_tf_roberta_prelayernorm.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roberta_prelayernorm/test_modeling_tf_roberta_prelayernorm.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/test_modeling_roc_bert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/test_modeling_roc_bert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/test_tokenization_roc_bert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roc_bert/test_tokenization_roc_bert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_flax_roformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_flax_roformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_roformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_roformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_tf_roformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_modeling_tf_roformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_tokenization_roformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/roformer/test_tokenization_roformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rwkv/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rwkv/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rwkv/test_modeling_rwkv.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/rwkv/test_modeling_rwkv.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/test_modeling_sam.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/test_modeling_sam.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/test_processor_sam.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sam/test_processor_sam.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_image_processing_segformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_image_processing_segformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_modeling_segformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_modeling_segformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_modeling_tf_segformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/segformer/test_modeling_tf_segformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew/test_modeling_sew.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew/test_modeling_sew.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew_d/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew_d/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew_d/test_modeling_sew_d.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/sew_d/test_modeling_sew_d.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/test_modeling_flax_speech_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/test_modeling_flax_speech_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/test_modeling_speech_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_encoder_decoder/test_modeling_speech_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_feature_extraction_speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_feature_extraction_speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_modeling_speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_modeling_speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_modeling_tf_speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_modeling_tf_speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_processor_speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_processor_speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_tokenization_speech_to_text.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text/test_tokenization_speech_to_text.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/test_modeling_speech_to_text_2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/test_modeling_speech_to_text_2.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/test_tokenization_speech_to_text_2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speech_to_text_2/test_tokenization_speech_to_text_2.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_feature_extraction_speecht5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_feature_extraction_speecht5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_modeling_speecht5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_modeling_speecht5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_processor_speecht5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_processor_speecht5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_tokenization_speecht5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/speecht5/test_tokenization_speecht5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/splinter/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/splinter/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/splinter/test_modeling_splinter.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/splinter/test_modeling_splinter.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/test_modeling_squeezebert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/test_modeling_squeezebert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/test_tokenization_squeezebert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/squeezebert/test_tokenization_squeezebert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/test_modeling_swin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/test_modeling_swin.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/test_modeling_tf_swin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin/test_modeling_tf_swin.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/test_image_processing_swin2sr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/test_image_processing_swin2sr.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/test_modeling_swin2sr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swin2sr/test_modeling_swin2sr.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swinv2/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swinv2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swinv2/test_modeling_swinv2.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/swinv2/test_modeling_swinv2.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/switch_transformers/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/switch_transformers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/switch_transformers/test_modeling_switch_transformers.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/switch_transformers/test_modeling_switch_transformers.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_flax_t5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_flax_t5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_t5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_t5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_tf_t5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_modeling_tf_t5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_tokenization_t5.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/t5/test_tokenization_t5.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/table_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/table_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/table_transformer/test_modeling_table_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/table_transformer/test_modeling_table_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_modeling_tapas.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_modeling_tapas.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_modeling_tf_tapas.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_modeling_tf_tapas.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_tokenization_tapas.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapas/test_tokenization_tapas.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapex/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapex/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapex/test_tokenization_tapex.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tapex/test_tokenization_tapex.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/time_series_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/time_series_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/time_series_transformer/test_modeling_time_series_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/time_series_transformer/test_modeling_time_series_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/timesformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/timesformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/timesformer/test_modeling_timesformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/timesformer/test_modeling_timesformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trajectory_transformer/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trajectory_transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trajectory_transformer/test_modeling_trajectory_transformer.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trajectory_transformer/test_modeling_trajectory_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_modeling_tf_transfo_xl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_modeling_tf_transfo_xl.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_modeling_transfo_xl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_modeling_transfo_xl.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_tokenization_transfo_xl.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/transfo_xl/test_tokenization_transfo_xl.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trocr/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trocr/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trocr/test_modeling_trocr.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/trocr/test_modeling_trocr.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_feature_extraction_tvlt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_feature_extraction_tvlt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_image_processor_tvlt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_image_processor_tvlt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_modeling_tvlt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_modeling_tvlt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_processor_tvlt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/tvlt/test_processor_tvlt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech/test_modeling_unispeech.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech/test_modeling_unispeech.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech_sat/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech_sat/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech_sat/test_modeling_unispeech_sat.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/unispeech_sat/test_modeling_unispeech_sat.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/upernet/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/upernet/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/upernet/test_modeling_upernet.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/upernet/test_modeling_upernet.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/van/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/van/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/van/test_modeling_van.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/van/test_modeling_van.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/test_image_processing_videomae.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/test_image_processing_videomae.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/test_modeling_videomae.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/videomae/test_modeling_videomae.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vilt/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vilt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vilt/test_modeling_vilt.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vilt/test_modeling_vilt.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/test_modeling_flax_vision_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/test_modeling_flax_vision_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/test_modeling_tf_vision_encoder_decoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_encoder_decoder/test_modeling_tf_vision_encoder_decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/test_modeling_vision_text_dual_encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/test_processor_vision_text_dual_encoder.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vision_text_dual_encoder/test_processor_vision_text_dual_encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/visual_bert/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/visual_bert/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/visual_bert/test_modeling_visual_bert.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/visual_bert/test_modeling_visual_bert.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_image_processing_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_image_processing_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_modeling_flax_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_modeling_flax_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_modeling_tf_vit.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit/test_modeling_tf_vit.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_hybrid/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_hybrid/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_hybrid/test_modeling_vit_hybrid.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_hybrid/test_modeling_vit_hybrid.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_mae/__init__.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_mae/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_mae/test_modeling_tf_vit_mae.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/models/vit_mae/test_modeling_tf_vit_mae.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_backbone_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_backbone_common.py new file mode 100644 index 0000000000000000000000000000000000000000..fd9bbe3bfbfe7c8c9984077bf37f6ed5b788dbe2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_backbone_common.py @@ -0,0 +1,186 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import inspect + +from transformers.testing_utils import require_torch, torch_device + + +@require_torch +class BackboneTesterMixin: + all_model_classes = () + has_attentions = True + + def test_config(self): + config_class = self.config_class + + # test default config + config = config_class() + self.assertIsNotNone(config) + expected_stage_names = ["stem"] + [f"stage{idx}" for idx in range(1, len(config.depths) + 1)] + self.assertEqual(config.stage_names, expected_stage_names) + self.assertTrue(set(config.out_features).issubset(set(config.stage_names))) + + # Test out_features and out_indices are correctly set + # out_features and out_indices both None + config = config_class(out_features=None, out_indices=None) + self.assertEqual(config.out_features, [config.stage_names[-1]]) + self.assertEqual(config.out_indices, [len(config.stage_names) - 1]) + + # out_features and out_indices both set + config = config_class(out_features=["stem", "stage1"], out_indices=[0, 1]) + self.assertEqual(config.out_features, ["stem", "stage1"]) + self.assertEqual(config.out_indices, [0, 1]) + + # Only out_features set + config = config_class(out_features=["stage1", "stage3"]) + self.assertEqual(config.out_features, ["stage1", "stage3"]) + self.assertEqual(config.out_indices, [1, 3]) + + # Only out_indices set + config = config_class(out_indices=[0, 2]) + self.assertEqual(config.out_features, [config.stage_names[0], config.stage_names[2]]) + self.assertEqual(config.out_indices, [0, 2]) + + # Error raised when out_indices do not correspond to out_features + with self.assertRaises(ValueError): + config = config_class(out_features=["stage1", "stage2"], out_indices=[0, 2]) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + expected_arg_names = ["pixel_values"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_channels(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertEqual(len(model.channels), len(config.out_features)) + num_features = model.num_features + out_indices = [config.stage_names.index(feat) for feat in config.out_features] + out_channels = [num_features[idx] for idx in out_indices] + self.assertListEqual(model.channels, out_channels) + + new_config = copy.deepcopy(config) + new_config.out_features = None + model = model_class(new_config) + self.assertEqual(len(model.channels), 1) + self.assertListEqual(model.channels, [num_features[-1]]) + + new_config = copy.deepcopy(config) + new_config.out_indices = None + model = model_class(new_config) + self.assertEqual(len(model.channels), 1) + self.assertListEqual(model.channels, [num_features[-1]]) + + def test_create_from_modified_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + result = model(**inputs_dict) + + self.assertEqual(len(result.feature_maps), len(config.out_features)) + self.assertEqual(len(model.channels), len(config.out_features)) + + # Check output of last stage is taken if out_features=None, out_indices=None + modified_config = copy.deepcopy(config) + modified_config.out_features = None + model = model_class(modified_config) + model.to(torch_device) + model.eval() + result = model(**inputs_dict) + + self.assertEqual(len(result.feature_maps), 1) + self.assertEqual(len(model.channels), 1) + + modified_config = copy.deepcopy(config) + modified_config.out_indices = None + model = model_class(modified_config) + model.to(torch_device) + model.eval() + result = model(**inputs_dict) + + self.assertEqual(len(result.feature_maps), 1) + self.assertEqual(len(model.channels), 1) + + # Check backbone can be initialized with fresh weights + modified_config = copy.deepcopy(config) + modified_config.use_pretrained_backbone = False + model = model_class(modified_config) + model.to(torch_device) + model.eval() + result = model(**inputs_dict) + + def test_backbone_common_attributes(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for backbone_class in self.all_model_classes: + backbone = backbone_class(config) + + self.assertTrue(hasattr(backbone, "stage_names")) + self.assertTrue(hasattr(backbone, "num_features")) + self.assertTrue(hasattr(backbone, "out_indices")) + self.assertTrue(hasattr(backbone, "out_features")) + self.assertTrue(hasattr(backbone, "out_feature_channels")) + self.assertTrue(hasattr(backbone, "channels")) + + # Verify num_features has been initialized in the backbone init + self.assertIsNotNone(backbone.num_features) + self.assertTrue(len(backbone.channels) == len(backbone.out_indices)) + self.assertTrue(len(backbone.stage_names) == len(backbone.num_features)) + self.assertTrue(len(backbone.channels) <= len(backbone.num_features)) + self.assertTrue(len(backbone.out_feature_channels) == len(backbone.stage_names)) + + def test_backbone_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + batch_size = inputs_dict["pixel_values"].shape[0] + + for backbone_class in self.all_model_classes: + backbone = backbone_class(config) + backbone.to(torch_device) + backbone.eval() + + outputs = backbone(**inputs_dict) + + # Test default outputs and verify feature maps + self.assertIsInstance(outputs.feature_maps, tuple) + self.assertTrue(len(outputs.feature_maps) == len(backbone.channels)) + for feature_map, n_channels in zip(outputs.feature_maps, backbone.channels): + self.assertTrue(feature_map.shape[:2], (batch_size, n_channels)) + self.assertIsNone(outputs.hidden_states) + self.assertIsNone(outputs.attentions) + + # Test output_hidden_states=True + outputs = backbone(**inputs_dict, output_hidden_states=True) + self.assertIsNotNone(outputs.hidden_states) + self.assertTrue(len(outputs.hidden_states), len(backbone.stage_names)) + for hidden_state, n_channels in zip(outputs.hidden_states, backbone.channels): + self.assertTrue(hidden_state.shape[:2], (batch_size, n_channels)) + + # Test output_attentions=True + if self.has_attentions: + outputs = backbone(**inputs_dict, output_attentions=True) + self.assertIsNotNone(outputs.attentions) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_configuration_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_configuration_common.py new file mode 100644 index 0000000000000000000000000000000000000000..fdb679529d2b415112eb3dffe9d334fb83c9d940 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_configuration_common.py @@ -0,0 +1,419 @@ +# coding=utf-8 +# Copyright 2019 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import json +import os +import shutil +import sys +import tempfile +import unittest +import unittest.mock as mock +from pathlib import Path + +from huggingface_hub import HfFolder, delete_repo +from requests.exceptions import HTTPError + +from transformers import AutoConfig, BertConfig, GPT2Config, is_torch_available +from transformers.configuration_utils import PretrainedConfig +from transformers.testing_utils import TOKEN, USER, is_staging_test + + +sys.path.append(str(Path(__file__).parent.parent / "utils")) + +from test_module.custom_configuration import CustomConfig # noqa E402 + + +config_common_kwargs = { + "return_dict": False, + "output_hidden_states": True, + "output_attentions": True, + "torchscript": True, + "torch_dtype": "float16", + "use_bfloat16": True, + "tf_legacy_loss": True, + "pruned_heads": {"a": 1}, + "tie_word_embeddings": False, + "is_decoder": True, + "cross_attention_hidden_size": 128, + "add_cross_attention": True, + "tie_encoder_decoder": True, + "max_length": 50, + "min_length": 3, + "do_sample": True, + "early_stopping": True, + "num_beams": 3, + "num_beam_groups": 3, + "diversity_penalty": 0.5, + "temperature": 2.0, + "top_k": 10, + "top_p": 0.7, + "typical_p": 0.2, + "repetition_penalty": 0.8, + "length_penalty": 0.8, + "no_repeat_ngram_size": 5, + "encoder_no_repeat_ngram_size": 5, + "bad_words_ids": [1, 2, 3], + "num_return_sequences": 3, + "chunk_size_feed_forward": 5, + "output_scores": True, + "return_dict_in_generate": True, + "forced_bos_token_id": 2, + "forced_eos_token_id": 3, + "remove_invalid_values": True, + "architectures": ["BertModel"], + "finetuning_task": "translation", + "id2label": {0: "label"}, + "label2id": {"label": "0"}, + "tokenizer_class": "BertTokenizerFast", + "prefix": "prefix", + "bos_token_id": 6, + "pad_token_id": 7, + "eos_token_id": 8, + "sep_token_id": 9, + "decoder_start_token_id": 10, + "exponential_decay_length_penalty": (5, 1.01), + "suppress_tokens": [0, 1], + "begin_suppress_tokens": 2, + "task_specific_params": {"translation": "some_params"}, + "problem_type": "regression", +} + + +class ConfigTester(object): + def __init__(self, parent, config_class=None, has_text_modality=True, common_properties=None, **kwargs): + self.parent = parent + self.config_class = config_class + self.has_text_modality = has_text_modality + self.inputs_dict = kwargs + self.common_properties = common_properties + + def create_and_test_config_common_properties(self): + config = self.config_class(**self.inputs_dict) + common_properties = ( + ["hidden_size", "num_attention_heads", "num_hidden_layers"] + if self.common_properties is None + else self.common_properties + ) + + # Add common fields for text models + if self.has_text_modality: + common_properties.extend(["vocab_size"]) + + # Test that config has the common properties as getters + for prop in common_properties: + self.parent.assertTrue(hasattr(config, prop), msg=f"`{prop}` does not exist") + + # Test that config has the common properties as setter + for idx, name in enumerate(common_properties): + try: + setattr(config, name, idx) + self.parent.assertEqual( + getattr(config, name), idx, msg=f"`{name} value {idx} expected, but was {getattr(config, name)}" + ) + except NotImplementedError: + # Some models might not be able to implement setters for common_properties + # In that case, a NotImplementedError is raised + pass + + # Test if config class can be called with Config(prop_name=..) + for idx, name in enumerate(common_properties): + try: + config = self.config_class(**{name: idx}) + self.parent.assertEqual( + getattr(config, name), idx, msg=f"`{name} value {idx} expected, but was {getattr(config, name)}" + ) + except NotImplementedError: + # Some models might not be able to implement setters for common_properties + # In that case, a NotImplementedError is raised + pass + + def create_and_test_config_to_json_string(self): + config = self.config_class(**self.inputs_dict) + obj = json.loads(config.to_json_string()) + for key, value in self.inputs_dict.items(): + self.parent.assertEqual(obj[key], value) + + def create_and_test_config_to_json_file(self): + config_first = self.config_class(**self.inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + json_file_path = os.path.join(tmpdirname, "config.json") + config_first.to_json_file(json_file_path) + config_second = self.config_class.from_json_file(json_file_path) + + self.parent.assertEqual(config_second.to_dict(), config_first.to_dict()) + + def create_and_test_config_from_and_save_pretrained(self): + config_first = self.config_class(**self.inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + config_first.save_pretrained(tmpdirname) + config_second = self.config_class.from_pretrained(tmpdirname) + + self.parent.assertEqual(config_second.to_dict(), config_first.to_dict()) + + def create_and_test_config_from_and_save_pretrained_subfolder(self): + config_first = self.config_class(**self.inputs_dict) + + subfolder = "test" + with tempfile.TemporaryDirectory() as tmpdirname: + sub_tmpdirname = os.path.join(tmpdirname, subfolder) + config_first.save_pretrained(sub_tmpdirname) + config_second = self.config_class.from_pretrained(tmpdirname, subfolder=subfolder) + + self.parent.assertEqual(config_second.to_dict(), config_first.to_dict()) + + def create_and_test_config_with_num_labels(self): + config = self.config_class(**self.inputs_dict, num_labels=5) + self.parent.assertEqual(len(config.id2label), 5) + self.parent.assertEqual(len(config.label2id), 5) + + config.num_labels = 3 + self.parent.assertEqual(len(config.id2label), 3) + self.parent.assertEqual(len(config.label2id), 3) + + def check_config_can_be_init_without_params(self): + if self.config_class.is_composition: + return + config = self.config_class() + self.parent.assertIsNotNone(config) + + def check_config_arguments_init(self): + kwargs = copy.deepcopy(config_common_kwargs) + config = self.config_class(**kwargs) + wrong_values = [] + for key, value in config_common_kwargs.items(): + if key == "torch_dtype": + if not is_torch_available(): + continue + else: + import torch + + if config.torch_dtype != torch.float16: + wrong_values.append(("torch_dtype", config.torch_dtype, torch.float16)) + elif getattr(config, key) != value: + wrong_values.append((key, getattr(config, key), value)) + + if len(wrong_values) > 0: + errors = "\n".join([f"- {v[0]}: got {v[1]} instead of {v[2]}" for v in wrong_values]) + raise ValueError(f"The following keys were not properly set in the config:\n{errors}") + + def run_common_tests(self): + self.create_and_test_config_common_properties() + self.create_and_test_config_to_json_string() + self.create_and_test_config_to_json_file() + self.create_and_test_config_from_and_save_pretrained() + self.create_and_test_config_from_and_save_pretrained_subfolder() + self.create_and_test_config_with_num_labels() + self.check_config_can_be_init_without_params() + self.check_config_arguments_init() + + +@is_staging_test +class ConfigPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-config") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-config-org") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-dynamic-config") + except HTTPError: + pass + + def test_push_to_hub(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + config.push_to_hub("test-config", use_auth_token=self._token) + + new_config = BertConfig.from_pretrained(f"{USER}/test-config") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="test-config") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + config.save_pretrained(tmp_dir, repo_id="test-config", push_to_hub=True, use_auth_token=self._token) + + new_config = BertConfig.from_pretrained(f"{USER}/test-config") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + def test_push_to_hub_in_organization(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + config.push_to_hub("valid_org/test-config-org", use_auth_token=self._token) + + new_config = BertConfig.from_pretrained("valid_org/test-config-org") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-config-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + config.save_pretrained( + tmp_dir, repo_id="valid_org/test-config-org", push_to_hub=True, use_auth_token=self._token + ) + + new_config = BertConfig.from_pretrained("valid_org/test-config-org") + for k, v in config.to_dict().items(): + if k != "transformers_version": + self.assertEqual(v, getattr(new_config, k)) + + def test_push_to_hub_dynamic_config(self): + CustomConfig.register_for_auto_class() + config = CustomConfig(attribute=42) + + config.push_to_hub("test-dynamic-config", use_auth_token=self._token) + + # This has added the proper auto_map field to the config + self.assertDictEqual(config.auto_map, {"AutoConfig": "custom_configuration.CustomConfig"}) + + new_config = AutoConfig.from_pretrained(f"{USER}/test-dynamic-config", trust_remote_code=True) + # Can't make an isinstance check because the new_config is from the FakeConfig class of a dynamic module + self.assertEqual(new_config.__class__.__name__, "CustomConfig") + self.assertEqual(new_config.attribute, 42) + + +class ConfigTestUtils(unittest.TestCase): + def test_config_from_string(self): + c = GPT2Config() + + # attempt to modify each of int/float/bool/str config records and verify they were updated + n_embd = c.n_embd + 1 # int + resid_pdrop = c.resid_pdrop + 1.0 # float + scale_attn_weights = not c.scale_attn_weights # bool + summary_type = c.summary_type + "foo" # str + c.update_from_string( + f"n_embd={n_embd},resid_pdrop={resid_pdrop},scale_attn_weights={scale_attn_weights},summary_type={summary_type}" + ) + self.assertEqual(n_embd, c.n_embd, "mismatch for key: n_embd") + self.assertEqual(resid_pdrop, c.resid_pdrop, "mismatch for key: resid_pdrop") + self.assertEqual(scale_attn_weights, c.scale_attn_weights, "mismatch for key: scale_attn_weights") + self.assertEqual(summary_type, c.summary_type, "mismatch for key: summary_type") + + def test_config_common_kwargs_is_complete(self): + base_config = PretrainedConfig() + missing_keys = [key for key in base_config.__dict__ if key not in config_common_kwargs] + # If this part of the test fails, you have arguments to addin config_common_kwargs above. + self.assertListEqual( + missing_keys, ["is_encoder_decoder", "_name_or_path", "_commit_hash", "transformers_version"] + ) + keys_with_defaults = [key for key, value in config_common_kwargs.items() if value == getattr(base_config, key)] + if len(keys_with_defaults) > 0: + raise ValueError( + "The following keys are set with the default values in" + " `test_configuration_common.config_common_kwargs` pick another value for them:" + f" {', '.join(keys_with_defaults)}." + ) + + def test_from_pretrained_subfolder(self): + with self.assertRaises(OSError): + # config is in subfolder, the following should not work without specifying the subfolder + _ = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert-subfolder") + + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert-subfolder", subfolder="bert") + + self.assertIsNotNone(config) + + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Under the mock environment we get a 500 error when trying to reach the model. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + # This check we did call the fake head request + mock_head.assert_called() + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + _ = BertConfig.from_pretrained( + "https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/config.json" + ) + + +class ConfigurationVersioningTest(unittest.TestCase): + def test_local_versioning(self): + configuration = AutoConfig.from_pretrained("bert-base-cased") + configuration.configuration_files = ["config.4.0.0.json"] + + with tempfile.TemporaryDirectory() as tmp_dir: + configuration.save_pretrained(tmp_dir) + configuration.hidden_size = 2 + json.dump(configuration.to_dict(), open(os.path.join(tmp_dir, "config.4.0.0.json"), "w")) + + # This should pick the new configuration file as the version of Transformers is > 4.0.0 + new_configuration = AutoConfig.from_pretrained(tmp_dir) + self.assertEqual(new_configuration.hidden_size, 2) + + # Will need to be adjusted if we reach v42 and this test is still here. + # Should pick the old configuration file as the version of Transformers is < 4.42.0 + configuration.configuration_files = ["config.42.0.0.json"] + configuration.hidden_size = 768 + configuration.save_pretrained(tmp_dir) + shutil.move(os.path.join(tmp_dir, "config.4.0.0.json"), os.path.join(tmp_dir, "config.42.0.0.json")) + new_configuration = AutoConfig.from_pretrained(tmp_dir) + self.assertEqual(new_configuration.hidden_size, 768) + + def test_repo_versioning_before(self): + # This repo has two configuration files, one for v4.0.0 and above with a different hidden size. + repo = "hf-internal-testing/test-two-configs" + + import transformers as new_transformers + + new_transformers.configuration_utils.__version__ = "v4.0.0" + new_configuration, kwargs = new_transformers.models.auto.AutoConfig.from_pretrained( + repo, return_unused_kwargs=True + ) + self.assertEqual(new_configuration.hidden_size, 2) + # This checks `_configuration_file` ia not kept in the kwargs by mistake. + self.assertDictEqual(kwargs, {}) + + # Testing an older version by monkey-patching the version in the module it's used. + import transformers as old_transformers + + old_transformers.configuration_utils.__version__ = "v3.0.0" + old_configuration = old_transformers.models.auto.AutoConfig.from_pretrained(repo) + self.assertEqual(old_configuration.hidden_size, 768) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_feature_extraction_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_feature_extraction_common.py new file mode 100644 index 0000000000000000000000000000000000000000..6ffec669133c8f292d2c7f6f1a0c1a133a8c0cec --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_feature_extraction_common.py @@ -0,0 +1,180 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import sys +import tempfile +import unittest +import unittest.mock as mock +from pathlib import Path + +from huggingface_hub import HfFolder, delete_repo +from requests.exceptions import HTTPError + +from transformers import AutoFeatureExtractor, Wav2Vec2FeatureExtractor +from transformers.testing_utils import TOKEN, USER, check_json_file_has_correct_format, get_tests_dir, is_staging_test + + +sys.path.append(str(Path(__file__).parent.parent / "utils")) + +from test_module.custom_feature_extraction import CustomFeatureExtractor # noqa E402 + + +SAMPLE_FEATURE_EXTRACTION_CONFIG_DIR = get_tests_dir("fixtures") + + +class FeatureExtractionSavingTestMixin: + test_cast_dtype = None + + def test_feat_extract_to_json_string(self): + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + obj = json.loads(feat_extract.to_json_string()) + for key, value in self.feat_extract_dict.items(): + self.assertEqual(obj[key], value) + + def test_feat_extract_to_json_file(self): + feat_extract_first = self.feature_extraction_class(**self.feat_extract_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + json_file_path = os.path.join(tmpdirname, "feat_extract.json") + feat_extract_first.to_json_file(json_file_path) + feat_extract_second = self.feature_extraction_class.from_json_file(json_file_path) + + self.assertEqual(feat_extract_second.to_dict(), feat_extract_first.to_dict()) + + def test_feat_extract_from_and_save_pretrained(self): + feat_extract_first = self.feature_extraction_class(**self.feat_extract_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + saved_file = feat_extract_first.save_pretrained(tmpdirname)[0] + check_json_file_has_correct_format(saved_file) + feat_extract_second = self.feature_extraction_class.from_pretrained(tmpdirname) + + self.assertEqual(feat_extract_second.to_dict(), feat_extract_first.to_dict()) + + def test_init_without_params(self): + feat_extract = self.feature_extraction_class() + self.assertIsNotNone(feat_extract) + + +class FeatureExtractorUtilTester(unittest.TestCase): + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = Wav2Vec2FeatureExtractor.from_pretrained("hf-internal-testing/tiny-random-wav2vec2") + # Under the mock environment we get a 500 error when trying to reach the model. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = Wav2Vec2FeatureExtractor.from_pretrained("hf-internal-testing/tiny-random-wav2vec2") + # This check we did call the fake head request + mock_head.assert_called() + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + _ = Wav2Vec2FeatureExtractor.from_pretrained( + "https://huggingface.co/hf-internal-testing/tiny-random-wav2vec2/resolve/main/preprocessor_config.json" + ) + + +@is_staging_test +class FeatureExtractorPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-feature-extractor") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-feature-extractor-org") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-dynamic-feature-extractor") + except HTTPError: + pass + + def test_push_to_hub(self): + feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(SAMPLE_FEATURE_EXTRACTION_CONFIG_DIR) + feature_extractor.push_to_hub("test-feature-extractor", use_auth_token=self._token) + + new_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(f"{USER}/test-feature-extractor") + for k, v in feature_extractor.__dict__.items(): + self.assertEqual(v, getattr(new_feature_extractor, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="test-feature-extractor") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + feature_extractor.save_pretrained( + tmp_dir, repo_id="test-feature-extractor", push_to_hub=True, use_auth_token=self._token + ) + + new_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(f"{USER}/test-feature-extractor") + for k, v in feature_extractor.__dict__.items(): + self.assertEqual(v, getattr(new_feature_extractor, k)) + + def test_push_to_hub_in_organization(self): + feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(SAMPLE_FEATURE_EXTRACTION_CONFIG_DIR) + feature_extractor.push_to_hub("valid_org/test-feature-extractor", use_auth_token=self._token) + + new_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained("valid_org/test-feature-extractor") + for k, v in feature_extractor.__dict__.items(): + self.assertEqual(v, getattr(new_feature_extractor, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-feature-extractor") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + feature_extractor.save_pretrained( + tmp_dir, repo_id="valid_org/test-feature-extractor-org", push_to_hub=True, use_auth_token=self._token + ) + + new_feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained("valid_org/test-feature-extractor-org") + for k, v in feature_extractor.__dict__.items(): + self.assertEqual(v, getattr(new_feature_extractor, k)) + + def test_push_to_hub_dynamic_feature_extractor(self): + CustomFeatureExtractor.register_for_auto_class() + feature_extractor = CustomFeatureExtractor.from_pretrained(SAMPLE_FEATURE_EXTRACTION_CONFIG_DIR) + + feature_extractor.push_to_hub("test-dynamic-feature-extractor", use_auth_token=self._token) + + # This has added the proper auto_map field to the config + self.assertDictEqual( + feature_extractor.auto_map, + {"AutoFeatureExtractor": "custom_feature_extraction.CustomFeatureExtractor"}, + ) + + new_feature_extractor = AutoFeatureExtractor.from_pretrained( + f"{USER}/test-dynamic-feature-extractor", trust_remote_code=True + ) + # Can't make an isinstance check because the new_feature_extractor is from the CustomFeatureExtractor class of a dynamic module + self.assertEqual(new_feature_extractor.__class__.__name__, "CustomFeatureExtractor") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_processing_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_processing_common.py new file mode 100644 index 0000000000000000000000000000000000000000..15a6688fbb9c4b0620cc540de0d110a806338ef2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_processing_common.py @@ -0,0 +1,323 @@ +# coding=utf-8 +# Copyright 2023 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import json +import os +import sys +import tempfile +import unittest +import unittest.mock as mock +from pathlib import Path + +from huggingface_hub import HfFolder, delete_repo +from requests.exceptions import HTTPError + +from transformers import AutoImageProcessor, ViTImageProcessor +from transformers.testing_utils import ( + TOKEN, + USER, + check_json_file_has_correct_format, + get_tests_dir, + is_staging_test, + require_torch, + require_vision, +) +from transformers.utils import is_torch_available, is_vision_available + + +sys.path.append(str(Path(__file__).parent.parent / "utils")) + +from test_module.custom_image_processing import CustomImageProcessor # noqa E402 + + +if is_torch_available(): + import numpy as np + import torch + +if is_vision_available(): + from PIL import Image + + +SAMPLE_IMAGE_PROCESSING_CONFIG_DIR = get_tests_dir("fixtures") + + +def prepare_image_inputs(image_processor_tester, equal_resolution=False, numpify=False, torchify=False): + """This function prepares a list of PIL images, or a list of numpy arrays if one specifies numpify=True, + or a list of PyTorch tensors if one specifies torchify=True. + + One can specify whether the images are of the same resolution or not. + """ + + assert not (numpify and torchify), "You cannot specify both numpy and PyTorch tensors at the same time" + + image_inputs = [] + for i in range(image_processor_tester.batch_size): + if equal_resolution: + width = height = image_processor_tester.max_resolution + else: + # To avoid getting image width/height 0 + min_resolution = image_processor_tester.min_resolution + if getattr(image_processor_tester, "size_divisor", None): + # If `size_divisor` is defined, the image needs to have width/size >= `size_divisor` + min_resolution = max(image_processor_tester.size_divisor, min_resolution) + width, height = np.random.choice(np.arange(min_resolution, image_processor_tester.max_resolution), 2) + image_inputs.append( + np.random.randint(255, size=(image_processor_tester.num_channels, width, height), dtype=np.uint8) + ) + + if not numpify and not torchify: + # PIL expects the channel dimension as last dimension + image_inputs = [Image.fromarray(np.moveaxis(image, 0, -1)) for image in image_inputs] + + if torchify: + image_inputs = [torch.from_numpy(image) for image in image_inputs] + + return image_inputs + + +def prepare_video(image_processor_tester, width=10, height=10, numpify=False, torchify=False): + """This function prepares a video as a list of PIL images/NumPy arrays/PyTorch tensors.""" + + video = [] + for i in range(image_processor_tester.num_frames): + video.append(np.random.randint(255, size=(image_processor_tester.num_channels, width, height), dtype=np.uint8)) + + if not numpify and not torchify: + # PIL expects the channel dimension as last dimension + video = [Image.fromarray(np.moveaxis(frame, 0, -1)) for frame in video] + + if torchify: + video = [torch.from_numpy(frame) for frame in video] + + return video + + +def prepare_video_inputs(image_processor_tester, equal_resolution=False, numpify=False, torchify=False): + """This function prepares a batch of videos: a list of list of PIL images, or a list of list of numpy arrays if + one specifies numpify=True, or a list of list of PyTorch tensors if one specifies torchify=True. + + One can specify whether the videos are of the same resolution or not. + """ + + assert not (numpify and torchify), "You cannot specify both numpy and PyTorch tensors at the same time" + + video_inputs = [] + for i in range(image_processor_tester.batch_size): + if equal_resolution: + width = height = image_processor_tester.max_resolution + else: + width, height = np.random.choice( + np.arange(image_processor_tester.min_resolution, image_processor_tester.max_resolution), 2 + ) + video = prepare_video( + image_processor_tester=image_processor_tester, + width=width, + height=height, + numpify=numpify, + torchify=torchify, + ) + video_inputs.append(video) + + return video_inputs + + +class ImageProcessingSavingTestMixin: + test_cast_dtype = None + + def test_image_processor_to_json_string(self): + image_processor = self.image_processing_class(**self.image_processor_dict) + obj = json.loads(image_processor.to_json_string()) + for key, value in self.image_processor_dict.items(): + self.assertEqual(obj[key], value) + + def test_image_processor_to_json_file(self): + image_processor_first = self.image_processing_class(**self.image_processor_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + json_file_path = os.path.join(tmpdirname, "image_processor.json") + image_processor_first.to_json_file(json_file_path) + image_processor_second = self.image_processing_class.from_json_file(json_file_path) + + self.assertEqual(image_processor_second.to_dict(), image_processor_first.to_dict()) + + def test_image_processor_from_and_save_pretrained(self): + image_processor_first = self.image_processing_class(**self.image_processor_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + saved_file = image_processor_first.save_pretrained(tmpdirname)[0] + check_json_file_has_correct_format(saved_file) + image_processor_second = self.image_processing_class.from_pretrained(tmpdirname) + + self.assertEqual(image_processor_second.to_dict(), image_processor_first.to_dict()) + + def test_init_without_params(self): + image_processor = self.image_processing_class() + self.assertIsNotNone(image_processor) + + @require_torch + @require_vision + def test_cast_dtype_device(self): + if self.test_cast_dtype is not None: + # Initialize image_processor + image_processor = self.image_processing_class(**self.image_processor_dict) + + # create random PyTorch tensors + image_inputs = prepare_image_inputs(self.image_processor_tester, equal_resolution=False, torchify=True) + + encoding = image_processor(image_inputs, return_tensors="pt") + # for layoutLM compatiblity + self.assertEqual(encoding.pixel_values.device, torch.device("cpu")) + self.assertEqual(encoding.pixel_values.dtype, torch.float32) + + encoding = image_processor(image_inputs, return_tensors="pt").to(torch.float16) + self.assertEqual(encoding.pixel_values.device, torch.device("cpu")) + self.assertEqual(encoding.pixel_values.dtype, torch.float16) + + encoding = image_processor(image_inputs, return_tensors="pt").to("cpu", torch.bfloat16) + self.assertEqual(encoding.pixel_values.device, torch.device("cpu")) + self.assertEqual(encoding.pixel_values.dtype, torch.bfloat16) + + with self.assertRaises(TypeError): + _ = image_processor(image_inputs, return_tensors="pt").to(torch.bfloat16, "cpu") + + # Try with text + image feature + encoding = image_processor(image_inputs, return_tensors="pt") + encoding.update({"input_ids": torch.LongTensor([[1, 2, 3], [4, 5, 6]])}) + encoding = encoding.to(torch.float16) + + self.assertEqual(encoding.pixel_values.device, torch.device("cpu")) + self.assertEqual(encoding.pixel_values.dtype, torch.float16) + self.assertEqual(encoding.input_ids.dtype, torch.long) + + +class ImageProcessorUtilTester(unittest.TestCase): + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = ViTImageProcessor.from_pretrained("hf-internal-testing/tiny-random-vit") + # Under the mock environment we get a 500 error when trying to reach the model. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = ViTImageProcessor.from_pretrained("hf-internal-testing/tiny-random-vit") + # This check we did call the fake head request + mock_head.assert_called() + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + _ = ViTImageProcessor.from_pretrained( + "https://huggingface.co/hf-internal-testing/tiny-random-vit/resolve/main/preprocessor_config.json" + ) + + +@is_staging_test +class ImageProcessorPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-image-processor") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-image-processor-org") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-dynamic-image-processor") + except HTTPError: + pass + + def test_push_to_hub(self): + image_processor = ViTImageProcessor.from_pretrained(SAMPLE_IMAGE_PROCESSING_CONFIG_DIR) + image_processor.push_to_hub("test-image-processor", use_auth_token=self._token) + + new_image_processor = ViTImageProcessor.from_pretrained(f"{USER}/test-image-processor") + for k, v in image_processor.__dict__.items(): + self.assertEqual(v, getattr(new_image_processor, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="test-image-processor") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + image_processor.save_pretrained( + tmp_dir, repo_id="test-image-processor", push_to_hub=True, use_auth_token=self._token + ) + + new_image_processor = ViTImageProcessor.from_pretrained(f"{USER}/test-image-processor") + for k, v in image_processor.__dict__.items(): + self.assertEqual(v, getattr(new_image_processor, k)) + + def test_push_to_hub_in_organization(self): + image_processor = ViTImageProcessor.from_pretrained(SAMPLE_IMAGE_PROCESSING_CONFIG_DIR) + image_processor.push_to_hub("valid_org/test-image-processor", use_auth_token=self._token) + + new_image_processor = ViTImageProcessor.from_pretrained("valid_org/test-image-processor") + for k, v in image_processor.__dict__.items(): + self.assertEqual(v, getattr(new_image_processor, k)) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-image-processor") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + image_processor.save_pretrained( + tmp_dir, repo_id="valid_org/test-image-processor-org", push_to_hub=True, use_auth_token=self._token + ) + + new_image_processor = ViTImageProcessor.from_pretrained("valid_org/test-image-processor-org") + for k, v in image_processor.__dict__.items(): + self.assertEqual(v, getattr(new_image_processor, k)) + + def test_push_to_hub_dynamic_image_processor(self): + CustomImageProcessor.register_for_auto_class() + image_processor = CustomImageProcessor.from_pretrained(SAMPLE_IMAGE_PROCESSING_CONFIG_DIR) + + image_processor.push_to_hub("test-dynamic-image-processor", use_auth_token=self._token) + + # This has added the proper auto_map field to the config + self.assertDictEqual( + image_processor.auto_map, + {"ImageProcessor": "custom_image_processing.CustomImageProcessor"}, + ) + + new_image_processor = AutoImageProcessor.from_pretrained( + f"{USER}/test-dynamic-image-processor", trust_remote_code=True + ) + # Can't make an isinstance check because the new_image_processor is from the CustomImageProcessor class of a dynamic module + self.assertEqual(new_image_processor.__class__.__name__, "CustomImageProcessor") + + def test_image_processor_from_pretrained_subfolder(self): + with self.assertRaises(OSError): + # config is in subfolder, the following should not work without specifying the subfolder + _ = AutoImageProcessor.from_pretrained("hf-internal-testing/stable-diffusion-all-variants") + + config = AutoImageProcessor.from_pretrained( + "hf-internal-testing/stable-diffusion-all-variants", subfolder="feature_extractor" + ) + + self.assertIsNotNone(config) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_transforms.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_transforms.py new file mode 100644 index 0000000000000000000000000000000000000000..cb1524ac12cfc16b962147a0a05ac4ae9d40d4c9 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_image_transforms.py @@ -0,0 +1,522 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +import numpy as np +from parameterized import parameterized + +from transformers.testing_utils import require_flax, require_tf, require_torch, require_vision +from transformers.utils.import_utils import is_flax_available, is_tf_available, is_torch_available, is_vision_available + + +if is_torch_available(): + import torch + +if is_tf_available(): + import tensorflow as tf + +if is_flax_available(): + import jax + +if is_vision_available(): + import PIL.Image + + from transformers.image_transforms import ( + center_crop, + center_to_corners_format, + convert_to_rgb, + corners_to_center_format, + get_resize_output_image_size, + id_to_rgb, + normalize, + pad, + resize, + rgb_to_id, + to_channel_dimension_format, + to_pil_image, + ) + + +def get_random_image(height, width, num_channels=3, channels_first=True): + shape = (num_channels, height, width) if channels_first else (height, width, num_channels) + random_array = np.random.randint(0, 256, shape, dtype=np.uint8) + return random_array + + +@require_vision +class ImageTransformsTester(unittest.TestCase): + @parameterized.expand( + [ + ("numpy_float_channels_first", (3, 4, 5), np.float32), + ("numpy_float_channels_last", (4, 5, 3), np.float32), + ("numpy_float_channels_first", (3, 4, 5), np.float64), + ("numpy_float_channels_last", (4, 5, 3), np.float64), + ("numpy_int_channels_first", (3, 4, 5), np.int32), + ("numpy_uint_channels_first", (3, 4, 5), np.uint8), + ] + ) + @require_vision + def test_to_pil_image(self, name, image_shape, dtype): + image = np.random.randint(0, 256, image_shape).astype(dtype) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + # make sure image is correctly rescaled + self.assertTrue(np.abs(np.asarray(pil_image)).sum() > 0) + + @parameterized.expand( + [ + ("numpy_float_channels_first", (3, 4, 5), np.float32), + ("numpy_float_channels_first", (3, 4, 5), np.float64), + ("numpy_float_channels_last", (4, 5, 3), np.float32), + ("numpy_float_channels_last", (4, 5, 3), np.float64), + ] + ) + @require_vision + def test_to_pil_image_from_float(self, name, image_shape, dtype): + image = np.random.rand(*image_shape).astype(dtype) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + # make sure image is correctly rescaled + self.assertTrue(np.abs(np.asarray(pil_image)).sum() > 0) + + # Make sure that an exception is raised if image is not in [0, 1] + image = np.random.randn(*image_shape).astype(dtype) + with self.assertRaises(ValueError): + to_pil_image(image) + + @require_vision + def test_to_pil_image_from_mask(self): + # Make sure binary mask remains a binary mask + image = np.random.randint(0, 2, (3, 4, 5)).astype(np.uint8) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + np_img = np.asarray(pil_image) + self.assertTrue(np_img.min() == 0) + self.assertTrue(np_img.max() == 1) + + image = np.random.randint(0, 2, (3, 4, 5)).astype(np.float32) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + np_img = np.asarray(pil_image) + self.assertTrue(np_img.min() == 0) + self.assertTrue(np_img.max() == 1) + + @require_tf + def test_to_pil_image_from_tensorflow(self): + # channels_first + image = tf.random.uniform((3, 4, 5)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + # channels_last + image = tf.random.uniform((4, 5, 3)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + @require_torch + def test_to_pil_image_from_torch(self): + # channels first + image = torch.rand((3, 4, 5)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + # channels last + image = torch.rand((4, 5, 3)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + @require_flax + def test_to_pil_image_from_jax(self): + key = jax.random.PRNGKey(0) + # channel first + image = jax.random.uniform(key, (3, 4, 5)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + # channel last + image = jax.random.uniform(key, (4, 5, 3)) + pil_image = to_pil_image(image) + self.assertIsInstance(pil_image, PIL.Image.Image) + self.assertEqual(pil_image.size, (5, 4)) + + def test_to_channel_dimension_format(self): + # Test that function doesn't reorder if channel dim matches the input. + image = np.random.rand(3, 4, 5) + image = to_channel_dimension_format(image, "channels_first") + self.assertEqual(image.shape, (3, 4, 5)) + + image = np.random.rand(4, 5, 3) + image = to_channel_dimension_format(image, "channels_last") + self.assertEqual(image.shape, (4, 5, 3)) + + # Test that function reorders if channel dim doesn't match the input. + image = np.random.rand(3, 4, 5) + image = to_channel_dimension_format(image, "channels_last") + self.assertEqual(image.shape, (4, 5, 3)) + + image = np.random.rand(4, 5, 3) + image = to_channel_dimension_format(image, "channels_first") + self.assertEqual(image.shape, (3, 4, 5)) + + def test_get_resize_output_image_size(self): + image = np.random.randint(0, 256, (3, 224, 224)) + + # Test the output size defaults to (x, x) if an int is given. + self.assertEqual(get_resize_output_image_size(image, 10), (10, 10)) + self.assertEqual(get_resize_output_image_size(image, [10]), (10, 10)) + self.assertEqual(get_resize_output_image_size(image, (10,)), (10, 10)) + + # Test the output size is the same as the input if a two element tuple/list is given. + self.assertEqual(get_resize_output_image_size(image, (10, 20)), (10, 20)) + self.assertEqual(get_resize_output_image_size(image, [10, 20]), (10, 20)) + self.assertEqual(get_resize_output_image_size(image, (10, 20), default_to_square=True), (10, 20)) + # To match pytorch behaviour, max_size is only relevant if size is an int + self.assertEqual(get_resize_output_image_size(image, (10, 20), max_size=5), (10, 20)) + + # Test output size = (int(size * height / width), size) if size is an int and height > width + image = np.random.randint(0, 256, (3, 50, 40)) + self.assertEqual(get_resize_output_image_size(image, 20, default_to_square=False), (25, 20)) + + # Test output size = (size, int(size * width / height)) if size is an int and width <= height + image = np.random.randint(0, 256, (3, 40, 50)) + self.assertEqual(get_resize_output_image_size(image, 20, default_to_square=False), (20, 25)) + + # Test size is resized if longer size > max_size + image = np.random.randint(0, 256, (3, 50, 40)) + self.assertEqual(get_resize_output_image_size(image, 20, default_to_square=False, max_size=22), (22, 17)) + + # Test correct channel dimension is returned if output size if height == 3 + # Defaults to input format - channels first + image = np.random.randint(0, 256, (3, 18, 97)) + resized_image = resize(image, (3, 20)) + self.assertEqual(resized_image.shape, (3, 3, 20)) + + # Defaults to input format - channels last + image = np.random.randint(0, 256, (18, 97, 3)) + resized_image = resize(image, (3, 20)) + self.assertEqual(resized_image.shape, (3, 20, 3)) + + image = np.random.randint(0, 256, (3, 18, 97)) + resized_image = resize(image, (3, 20), data_format="channels_last") + self.assertEqual(resized_image.shape, (3, 20, 3)) + + image = np.random.randint(0, 256, (18, 97, 3)) + resized_image = resize(image, (3, 20), data_format="channels_first") + self.assertEqual(resized_image.shape, (3, 3, 20)) + + def test_resize(self): + image = np.random.randint(0, 256, (3, 224, 224)) + + # Check the channel order is the same by default + resized_image = resize(image, (30, 40)) + self.assertIsInstance(resized_image, np.ndarray) + self.assertEqual(resized_image.shape, (3, 30, 40)) + + # Check channel order is changed if specified + resized_image = resize(image, (30, 40), data_format="channels_last") + self.assertIsInstance(resized_image, np.ndarray) + self.assertEqual(resized_image.shape, (30, 40, 3)) + + # Check PIL.Image.Image is returned if return_numpy=False + resized_image = resize(image, (30, 40), return_numpy=False) + self.assertIsInstance(resized_image, PIL.Image.Image) + # PIL size is in (width, height) order + self.assertEqual(resized_image.size, (40, 30)) + + # Check an image with float values between 0-1 is returned with values in this range + image = np.random.rand(3, 224, 224) + resized_image = resize(image, (30, 40)) + self.assertIsInstance(resized_image, np.ndarray) + self.assertEqual(resized_image.shape, (3, 30, 40)) + self.assertTrue(np.all(resized_image >= 0)) + self.assertTrue(np.all(resized_image <= 1)) + + def test_normalize(self): + image = np.random.randint(0, 256, (224, 224, 3)) / 255 + + # Test that exception is raised if inputs are incorrect + # Not a numpy array image + with self.assertRaises(ValueError): + normalize(5, 5, 5) + + # Number of mean values != number of channels + with self.assertRaises(ValueError): + normalize(image, mean=(0.5, 0.6), std=1) + + # Number of std values != number of channels + with self.assertRaises(ValueError): + normalize(image, mean=1, std=(0.5, 0.6)) + + # Test result is correct - output data format is channels_first and normalization + # correctly computed + mean = (0.5, 0.6, 0.7) + std = (0.1, 0.2, 0.3) + expected_image = ((image - mean) / std).transpose((2, 0, 1)) + + normalized_image = normalize(image, mean=mean, std=std, data_format="channels_first") + self.assertIsInstance(normalized_image, np.ndarray) + self.assertEqual(normalized_image.shape, (3, 224, 224)) + self.assertTrue(np.allclose(normalized_image, expected_image)) + + def test_center_crop(self): + image = np.random.randint(0, 256, (3, 224, 224)) + + # Test that exception is raised if inputs are incorrect + with self.assertRaises(ValueError): + center_crop(image, 10) + + # Test result is correct - output data format is channels_first and center crop + # correctly computed + expected_image = image[:, 52:172, 82:142].transpose(1, 2, 0) + cropped_image = center_crop(image, (120, 60), data_format="channels_last") + self.assertIsInstance(cropped_image, np.ndarray) + self.assertEqual(cropped_image.shape, (120, 60, 3)) + self.assertTrue(np.allclose(cropped_image, expected_image)) + + # Test that image is padded with zeros if crop size is larger than image size + expected_image = np.zeros((300, 260, 3)) + expected_image[38:262, 18:242, :] = image.transpose((1, 2, 0)) + cropped_image = center_crop(image, (300, 260), data_format="channels_last") + self.assertIsInstance(cropped_image, np.ndarray) + self.assertEqual(cropped_image.shape, (300, 260, 3)) + self.assertTrue(np.allclose(cropped_image, expected_image)) + + def test_center_to_corners_format(self): + bbox_center = np.array([[10, 20, 4, 8], [15, 16, 3, 4]]) + expected = np.array([[8, 16, 12, 24], [13.5, 14, 16.5, 18]]) + self.assertTrue(np.allclose(center_to_corners_format(bbox_center), expected)) + + # Check that the function and inverse function are inverse of each other + self.assertTrue(np.allclose(corners_to_center_format(center_to_corners_format(bbox_center)), bbox_center)) + + def test_corners_to_center_format(self): + bbox_corners = np.array([[8, 16, 12, 24], [13.5, 14, 16.5, 18]]) + expected = np.array([[10, 20, 4, 8], [15, 16, 3, 4]]) + self.assertTrue(np.allclose(corners_to_center_format(bbox_corners), expected)) + + # Check that the function and inverse function are inverse of each other + self.assertTrue(np.allclose(center_to_corners_format(corners_to_center_format(bbox_corners)), bbox_corners)) + + def test_rgb_to_id(self): + # test list input + rgb = [125, 4, 255] + self.assertEqual(rgb_to_id(rgb), 16712829) + + # test numpy array input + color = np.array( + [ + [ + [213, 54, 165], + [88, 207, 39], + [156, 108, 128], + ], + [ + [183, 194, 46], + [137, 58, 88], + [114, 131, 233], + ], + ] + ) + expected = np.array([[10827477, 2608984, 8416412], [3064503, 5782153, 15303538]]) + self.assertTrue(np.allclose(rgb_to_id(color), expected)) + + def test_id_to_rgb(self): + # test int input + self.assertEqual(id_to_rgb(16712829), [125, 4, 255]) + + # test array input + id_array = np.array([[10827477, 2608984, 8416412], [3064503, 5782153, 15303538]]) + color = np.array( + [ + [ + [213, 54, 165], + [88, 207, 39], + [156, 108, 128], + ], + [ + [183, 194, 46], + [137, 58, 88], + [114, 131, 233], + ], + ] + ) + self.assertTrue(np.allclose(id_to_rgb(id_array), color)) + + def test_pad(self): + # fmt: off + image = np.array([[ + [0, 1], + [2, 3], + ]]) + # fmt: on + + # Test that exception is raised if unknown padding mode is specified + with self.assertRaises(ValueError): + pad(image, 10, mode="unknown") + + # Test that exception is raised if invalid padding is specified + with self.assertRaises(ValueError): + # Cannot pad on channel dimension + pad(image, (5, 10, 10)) + + # Test image is padded equally on all sides is padding is an int + # fmt: off + expected_image = np.array([ + [[0, 0, 0, 0], + [0, 0, 1, 0], + [0, 2, 3, 0], + [0, 0, 0, 0]], + ]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, 1))) + + # Test the left and right of each axis is padded (pad_left, pad_right) + # fmt: off + expected_image = np.array( + [[0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 2, 3, 0], + [0, 0, 0, 0, 0]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, (2, 1)))) + + # Test only one axis is padded (pad_left, pad_right) + # fmt: off + expected_image = np.array([[ + [9, 9], + [9, 9], + [0, 1], + [2, 3], + [9, 9] + ]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, ((2, 1), (0, 0)), constant_values=9))) + + # Test padding with a constant value + # fmt: off + expected_image = np.array([[ + [8, 8, 0, 1, 9], + [8, 8, 2, 3, 9], + [8, 8, 7, 7, 9], + [8, 8, 7, 7, 9] + ]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, ((0, 2), (2, 1)), constant_values=((6, 7), (8, 9))))) + + # fmt: off + image = np.array([[ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + ]]) + # fmt: on + + # Test padding with PaddingMode.REFLECT + # fmt: off + expected_image = np.array([[ + [2, 1, 0, 1, 2, 1], + [5, 4, 3, 4, 5, 4], + [8, 7, 6, 7, 8, 7], + [5, 4, 3, 4, 5, 4], + [2, 1, 0, 1, 2, 1], + ]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, ((0, 2), (2, 1)), mode="reflect"))) + + # Test padding with PaddingMode.REPLICATE + # fmt: off + expected_image = np.array([[ + [0, 0, 0, 1, 2, 2], + [3, 3, 3, 4, 5, 5], + [6, 6, 6, 7, 8, 8], + [6, 6, 6, 7, 8, 8], + [6, 6, 6, 7, 8, 8], + ]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, ((0, 2), (2, 1)), mode="replicate"))) + + # Test padding with PaddingMode.SYMMETRIC + # fmt: off + expected_image = np.array([[ + [1, 0, 0, 1, 2, 2], + [4, 3, 3, 4, 5, 5], + [7, 6, 6, 7, 8, 8], + [7, 6, 6, 7, 8, 8], + [4, 3, 3, 4, 5, 5], + ]]) + # fmt: on + self.assertTrue(np.allclose(expected_image, pad(image, ((0, 2), (2, 1)), mode="symmetric"))) + + # Test we can specify the output data format + # Test padding with PaddingMode.REFLECT + # fmt: off + image = np.array([[ + [0, 1], + [2, 3], + ]]) + expected_image = np.array([ + [[0], [1], [0], [1], [0]], + [[2], [3], [2], [3], [2]], + [[0], [1], [0], [1], [0]], + [[2], [3], [2], [3], [2]] + ]) + # fmt: on + self.assertTrue( + np.allclose(expected_image, pad(image, ((0, 2), (2, 1)), mode="reflect", data_format="channels_last")) + ) + + @require_vision + def test_convert_to_rgb(self): + # Test that an RGBA image is converted to RGB + image = np.array([[[1, 2, 3, 4], [5, 6, 7, 8]]], dtype=np.uint8) + pil_image = PIL.Image.fromarray(image) + self.assertEqual(pil_image.mode, "RGBA") + self.assertEqual(pil_image.size, (2, 1)) + + # For the moment, numpy images are returned as is + rgb_image = convert_to_rgb(image) + self.assertEqual(rgb_image.shape, (1, 2, 4)) + self.assertTrue(np.allclose(rgb_image, image)) + + # And PIL images are converted + rgb_image = convert_to_rgb(pil_image) + self.assertEqual(rgb_image.mode, "RGB") + self.assertEqual(rgb_image.size, (2, 1)) + self.assertTrue(np.allclose(np.array(rgb_image), np.array([[[1, 2, 3], [5, 6, 7]]], dtype=np.uint8))) + + # Test that a grayscale image is converted to RGB + image = np.array([[0, 255]], dtype=np.uint8) + pil_image = PIL.Image.fromarray(image) + self.assertEqual(pil_image.mode, "L") + self.assertEqual(pil_image.size, (2, 1)) + rgb_image = convert_to_rgb(pil_image) + self.assertEqual(rgb_image.mode, "RGB") + self.assertEqual(rgb_image.size, (2, 1)) + self.assertTrue(np.allclose(np.array(rgb_image), np.array([[[0, 0, 0], [255, 255, 255]]], dtype=np.uint8))) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_common.py new file mode 100644 index 0000000000000000000000000000000000000000..43e06e906797a87ca62095b470c77c89f2eb4c49 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_common.py @@ -0,0 +1,3608 @@ +# coding=utf-8 +# Copyright 2019 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import gc +import glob +import inspect +import json +import os +import os.path +import pickle +import random +import sys +import tempfile +import unittest +import unittest.mock as mock +import warnings +from collections import defaultdict +from pathlib import Path +from typing import Dict, List, Tuple + +import numpy as np +from huggingface_hub import HfFolder, delete_repo +from huggingface_hub.file_download import http_get +from pytest import mark +from requests.exceptions import HTTPError + +import transformers +from transformers import ( + AutoConfig, + AutoModel, + AutoModelForSequenceClassification, + PretrainedConfig, + is_torch_available, + logging, +) +from transformers.models.auto import get_values +from transformers.models.auto.modeling_auto import ( + MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES, + MODEL_FOR_BACKBONE_MAPPING_NAMES, + MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES, + MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, + MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES, + MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES, + MODEL_FOR_MASKED_LM_MAPPING_NAMES, + MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES, + MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES, + MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES, + MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES, + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES, + MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES, + MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES, + MODEL_MAPPING_NAMES, +) +from transformers.testing_utils import ( + TOKEN, + USER, + CaptureLogger, + TestCasePlus, + is_pt_flax_cross_test, + is_pt_tf_cross_test, + is_staging_test, + require_accelerate, + require_safetensors, + require_torch, + require_torch_gpu, + require_torch_multi_gpu, + require_usr_bin_time, + slow, + torch_device, +) +from transformers.utils import ( + CONFIG_NAME, + GENERATION_CONFIG_NAME, + SAFE_WEIGHTS_INDEX_NAME, + SAFE_WEIGHTS_NAME, + WEIGHTS_INDEX_NAME, + WEIGHTS_NAME, + is_accelerate_available, + is_flax_available, + is_tf_available, + is_torch_fx_available, +) +from transformers.utils.generic import ModelOutput + + +sys.path.append(str(Path(__file__).parent.parent / "utils")) + +from test_module.custom_configuration import CustomConfig, NoSuperInitConfig # noqa E402 + + +if is_accelerate_available(): + from accelerate.utils import compute_module_sizes + + +if is_torch_available(): + import torch + from test_module.custom_modeling import CustomModel, NoSuperInitModel + from torch import nn + + from transformers import ( + BERT_PRETRAINED_MODEL_ARCHIVE_LIST, + MODEL_MAPPING, + AdaptiveEmbedding, + AutoModelForCausalLM, + AutoTokenizer, + BertConfig, + BertModel, + CLIPTextModel, + PreTrainedModel, + T5Config, + T5ForConditionalGeneration, + ) + from transformers.modeling_utils import shard_checkpoint + + # Fake pretrained models for tests + class BaseModel(PreTrainedModel): + config_class = PretrainedConfig + + def __init__(self, config): + super().__init__(config) + self.linear = nn.Linear(4, 5) + self.linear_2 = nn.Linear(5, 6) + + def forward(self, x): + return self.linear_2(self.linear(x)) + + class ModelWithHead(PreTrainedModel): + base_model_prefix = "base" + config_class = PretrainedConfig + + def _init_weights(self, module): + pass + + def __init__(self, config): + super().__init__(config) + self.base = BaseModel(config) + # linear is a common name between Base and Head on purpose. + self.linear = nn.Linear(6, 3) + self.linear2 = nn.Linear(3, 5) + + def forward(self, x): + return self.linear2(self.linear(self.base(x))) + + +if is_tf_available(): + import tensorflow as tf + +if is_flax_available(): + import jax.numpy as jnp + + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + +if is_torch_fx_available(): + from transformers.utils.fx import symbolic_trace + + +def _config_zero_init(config): + configs_no_init = copy.deepcopy(config) + for key in configs_no_init.__dict__.keys(): + if "_range" in key or "_std" in key or "initializer_factor" in key or "layer_scale" in key: + setattr(configs_no_init, key, 1e-10) + if isinstance(getattr(configs_no_init, key, None), PretrainedConfig): + no_init_subconfig = _config_zero_init(getattr(configs_no_init, key)) + setattr(configs_no_init, key, no_init_subconfig) + return configs_no_init + + +TINY_T5 = "patrickvonplaten/t5-tiny-random" +TINY_BERT_FOR_TOKEN_CLASSIFICATION = "hf-internal-testing/tiny-bert-for-token-classification" + + +def _mock_init_weights(self, module): + for name, param in module.named_parameters(recurse=False): + # Use the first letter of the name to get a value and go from a <> -13 to z <> 12 + value = ord(name[0].lower()) - 110 + param.data.fill_(value) + + +def _mock_all_init_weights(self): + # Prune heads if needed + if self.config.pruned_heads: + self.prune_heads(self.config.pruned_heads) + + import transformers.modeling_utils + + if transformers.modeling_utils._init_weights: + for module in self.modules(): + module._is_hf_initialized = False + # Initialize weights + self.apply(self._initialize_weights) + + # Tie weights should be skipped when not initializing all weights + # since from_pretrained(...) calls tie weights anyways + self.tie_weights() + + +@require_torch +class ModelTesterMixin: + model_tester = None + all_model_classes = () + all_generative_model_classes = () + fx_compatible = False + test_torchscript = True + test_pruning = True + test_resize_embeddings = True + test_resize_position_embeddings = False + test_head_masking = True + test_mismatched_shapes = True + test_missing_keys = True + test_model_parallel = False + is_encoder_decoder = False + has_attentions = True + model_split_percents = [0.5, 0.7, 0.9] + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False): + inputs_dict = copy.deepcopy(inputs_dict) + if model_class.__name__ in get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES): + inputs_dict = { + k: v.unsqueeze(1).expand(-1, self.model_tester.num_choices, -1).contiguous() + if isinstance(v, torch.Tensor) and v.ndim > 1 + else v + for k, v in inputs_dict.items() + } + elif model_class.__name__ in get_values(MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES): + inputs_dict.pop("attention_mask") + + if return_labels: + if model_class.__name__ in get_values(MODEL_FOR_MULTIPLE_CHOICE_MAPPING_NAMES): + inputs_dict["labels"] = torch.ones(self.model_tester.batch_size, dtype=torch.long, device=torch_device) + elif model_class.__name__ in [ + *get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES), + *get_values(MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES), + ]: + inputs_dict["start_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + inputs_dict["end_positions"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class.__name__ in [ + *get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING_NAMES), + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_AUDIO_CLASSIFICATION_MAPPING_NAMES), + ]: + inputs_dict["labels"] = torch.zeros( + self.model_tester.batch_size, dtype=torch.long, device=torch_device + ) + elif model_class.__name__ in [ + *get_values(MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_CAUSAL_LM_MAPPING_NAMES), + *get_values(MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING_NAMES), + *get_values(MODEL_FOR_MASKED_LM_MAPPING_NAMES), + *get_values(MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING_NAMES), + ]: + inputs_dict["labels"] = torch.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=torch.long, device=torch_device + ) + elif model_class.__name__ in get_values(MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING_NAMES): + num_patches = self.model_tester.image_size // self.model_tester.patch_size + inputs_dict["bool_masked_pos"] = torch.zeros( + (self.model_tester.batch_size, num_patches**2), dtype=torch.long, device=torch_device + ) + elif model_class.__name__ in get_values(MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING_NAMES): + batch_size, num_channels, height, width = inputs_dict["pixel_values"].shape + inputs_dict["labels"] = torch.zeros( + [self.model_tester.batch_size, height, width], device=torch_device + ).long() + + return inputs_dict + + def test_save_load(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_save_load(out1, out2): + # make sure we don't have nans + out_2 = out2.cpu().numpy() + out_2[np.isnan(out_2)] = 0 + + out_1 = out1.cpu().numpy() + out_1[np.isnan(out_1)] = 0 + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + first = model(**self._prepare_for_class(inputs_dict, model_class))[0] + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # the config file (and the generation config file, if it can generate) should be saved + self.assertTrue(os.path.exists(os.path.join(tmpdirname, CONFIG_NAME))) + self.assertEqual( + model.can_generate(), os.path.exists(os.path.join(tmpdirname, GENERATION_CONFIG_NAME)) + ) + + model = model_class.from_pretrained(tmpdirname) + model.to(torch_device) + with torch.no_grad(): + second = model(**self._prepare_for_class(inputs_dict, model_class))[0] + + if isinstance(first, tuple) and isinstance(second, tuple): + for tensor1, tensor2 in zip(first, second): + check_save_load(tensor1, tensor2) + else: + check_save_load(first, second) + + def test_from_pretrained_no_checkpoint(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + state_dict = model.state_dict() + + new_model = model_class.from_pretrained( + pretrained_model_name_or_path=None, config=config, state_dict=state_dict + ) + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + def test_save_load_keys_to_ignore_on_save(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + _keys_to_ignore_on_save = getattr(model, "_keys_to_ignore_on_save", None) + if _keys_to_ignore_on_save is None: + continue + + # check the keys are in the original state_dict + for k in _keys_to_ignore_on_save: + self.assertIn(k, model.state_dict().keys(), "\n".join(model.state_dict().keys())) + + # check that certain keys didn't get saved with the model + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + output_model_file = os.path.join(tmpdirname, WEIGHTS_NAME) + state_dict_saved = torch.load(output_model_file) + for k in _keys_to_ignore_on_save: + self.assertNotIn(k, state_dict_saved.keys(), "\n".join(state_dict_saved.keys())) + + # Test we can load the state dict in the model, necessary for the checkpointing API in Trainer. + load_result = model.load_state_dict(state_dict_saved, strict=False) + self.assertTrue( + len(load_result.missing_keys) == 0 + or set(load_result.missing_keys) == set(model._keys_to_ignore_on_save) + ) + self.assertTrue(len(load_result.unexpected_keys) == 0) + + def test_gradient_checkpointing_backward_compatibility(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if not model_class.supports_gradient_checkpointing: + continue + + config.gradient_checkpointing = True + model = model_class(config) + self.assertTrue(model.is_gradient_checkpointing) + + def test_gradient_checkpointing_enable_disable(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if not model_class.supports_gradient_checkpointing: + continue + + # at init model should have gradient checkpointing disabled + model = model_class(config) + self.assertFalse(model.is_gradient_checkpointing) + + # check enable works + model.gradient_checkpointing_enable() + self.assertTrue(model.is_gradient_checkpointing) + + # check disable works + model.gradient_checkpointing_disable() + self.assertFalse(model.is_gradient_checkpointing) + + def test_save_load_fast_init_from_base(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.__class__ not in MODEL_MAPPING: + return + base_class = MODEL_MAPPING[config.__class__] + + if isinstance(base_class, tuple): + base_class = base_class[0] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + # make a copy of model class to not break future tests + # from https://stackoverflow.com/questions/9541025/how-to-copy-a-python-class + class CopyClass(model_class): + pass + + model_class_copy = CopyClass + + # make sure that all keys are expected for test + model_class_copy._keys_to_ignore_on_load_missing = [] + + # make init deterministic, but make sure that + # non-initialized weights throw errors nevertheless + model_class_copy._init_weights = _mock_init_weights + model_class_copy.init_weights = _mock_all_init_weights + + model = base_class(config) + state_dict = model.state_dict() + + # this will often delete a single weight of a multi-weight module + # to test an edge case + random_key_to_del = random.choice(list(state_dict.keys())) + del state_dict[random_key_to_del] + + # check that certain keys didn't get saved with the model + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + torch.save(state_dict, os.path.join(tmpdirname, "pytorch_model.bin")) + + model_fast_init = model_class_copy.from_pretrained(tmpdirname) + model_slow_init = model_class_copy.from_pretrained(tmpdirname, _fast_init=False) + # Before we test anything + + for key in model_fast_init.state_dict().keys(): + if isinstance(model_slow_init.state_dict()[key], torch.BoolTensor): + max_diff = (model_slow_init.state_dict()[key] ^ model_fast_init.state_dict()[key]).sum().item() + else: + max_diff = (model_slow_init.state_dict()[key] - model_fast_init.state_dict()[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_save_load_fast_init_to_base(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + if config.__class__ not in MODEL_MAPPING: + return + base_class = MODEL_MAPPING[config.__class__] + + if isinstance(base_class, tuple): + base_class = base_class[0] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + # make a copy of model class to not break future tests + # from https://stackoverflow.com/questions/9541025/how-to-copy-a-python-class + class CopyClass(base_class): + pass + + base_class_copy = CopyClass + + # make sure that all keys are expected for test + base_class_copy._keys_to_ignore_on_load_missing = [] + + # make init deterministic, but make sure that + # non-initialized weights throw errors nevertheless + base_class_copy._init_weights = _mock_init_weights + base_class_copy.init_weights = _mock_all_init_weights + + model = model_class(config) + state_dict = model.state_dict() + + # this will often delete a single weight of a multi-weight module + # to test an edge case + random_key_to_del = random.choice(list(state_dict.keys())) + del state_dict[random_key_to_del] + + # check that certain keys didn't get saved with the model + with tempfile.TemporaryDirectory() as tmpdirname: + model.config.save_pretrained(tmpdirname) + torch.save(state_dict, os.path.join(tmpdirname, "pytorch_model.bin")) + + model_fast_init = base_class_copy.from_pretrained(tmpdirname) + model_slow_init = base_class_copy.from_pretrained(tmpdirname, _fast_init=False) + + for key in model_fast_init.state_dict().keys(): + if isinstance(model_slow_init.state_dict()[key], torch.BoolTensor): + max_diff = torch.max( + model_slow_init.state_dict()[key] ^ model_fast_init.state_dict()[key] + ).item() + else: + max_diff = torch.max( + torch.abs(model_slow_init.state_dict()[key] - model_fast_init.state_dict()[key]) + ).item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_initialization(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + configs_no_init = _config_zero_init(config) + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + for name, param in model.named_parameters(): + if param.requires_grad: + self.assertIn( + ((param.data.mean() * 1e9).round() / 1e9).item(), + [0.0, 1.0], + msg=f"Parameter {name} of model {model_class} seems not properly initialized", + ) + + def test_determinism(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_determinism(first, second): + out_1 = first.cpu().numpy() + out_2 = second.cpu().numpy() + out_1 = out_1[~np.isnan(out_1)] + out_2 = out_2[~np.isnan(out_2)] + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + first = model(**self._prepare_for_class(inputs_dict, model_class))[0] + second = model(**self._prepare_for_class(inputs_dict, model_class))[0] + + if isinstance(first, tuple) and isinstance(second, tuple): + for tensor1, tensor2 in zip(first, second): + check_determinism(tensor1, tensor2) + else: + check_determinism(first, second) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.forward) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = [ + "input_ids", + "attention_mask", + "decoder_input_ids", + "decoder_attention_mask", + ] + expected_arg_names.extend( + ["head_mask", "decoder_head_mask", "cross_attn_head_mask", "encoder_outputs"] + if "head_mask" and "decoder_head_mask" and "cross_attn_head_mask" in arg_names + else ["encoder_outputs"] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["input_ids"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_training(self): + if not self.model_tester.is_training: + return + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + if model_class.__name__ in [ + *get_values(MODEL_MAPPING_NAMES), + *get_values(MODEL_FOR_BACKBONE_MAPPING_NAMES), + ]: + continue + + model = model_class(config) + model.to(torch_device) + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_training_gradient_checkpointing(self): + if not self.model_tester.is_training: + return + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.use_cache = False + config.return_dict = True + + if ( + model_class.__name__ + in [*get_values(MODEL_MAPPING_NAMES), *get_values(MODEL_FOR_BACKBONE_MAPPING_NAMES)] + or not model_class.supports_gradient_checkpointing + ): + continue + model = model_class(config) + model.to(torch_device) + model.gradient_checkpointing_enable() + model.train() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + loss = model(**inputs).loss + loss.backward() + + def test_attention_outputs(self): + if not self.has_attentions: + self.skipTest(reason="Model does not output attentions") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_len) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + chunk_length = getattr(self.model_tester, "chunk_length", None) + if chunk_length is not None and hasattr(self.model_tester, "num_hashes"): + encoder_seq_length = encoder_seq_length * self.model_tester.num_hashes + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + config.return_dict = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + if chunk_length is not None: + self.assertListEqual( + list(attentions[0].shape[-4:]), + [self.model_tester.num_attention_heads, encoder_seq_length, chunk_length, encoder_key_length], + ) + else: + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # loss is at first position + if "labels" in inputs_dict: + correct_outlen += 1 # loss is added to beginning + # Question Answering model returns start_logits and end_logits + if model_class.__name__ in [ + *get_values(MODEL_FOR_QUESTION_ANSWERING_MAPPING_NAMES), + *get_values(MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING_NAMES), + ]: + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + if "past_key_values" in outputs: + correct_outlen += 1 # past_key_values have been returned + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + model.to(torch_device) + model.eval() + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + if chunk_length is not None: + self.assertListEqual( + list(self_attentions[0].shape[-4:]), + [self.model_tester.num_attention_heads, encoder_seq_length, chunk_length, encoder_key_length], + ) + else: + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + @slow + def test_torchscript_simple(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + self._create_and_check_torchscript(config, inputs_dict) + + @slow + def test_torchscript_output_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_attentions = True + self._create_and_check_torchscript(config, inputs_dict) + + @slow + def test_torchscript_output_hidden_state(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + self._create_and_check_torchscript(config, inputs_dict) + + # This is copied from `torch/testing/_internal/jit_utils.py::clear_class_registry` + def clear_torch_jit_class_registry(self): + torch._C._jit_clear_class_registry() + torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() + # torch 1.8 has no `_clear_class_state` in `torch.jit._state` + if hasattr(torch.jit._state, "_clear_class_state"): + torch.jit._state._clear_class_state() + + def _create_and_check_torchscript(self, config, inputs_dict): + if not self.test_torchscript: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.torchscript = True + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + inputs = self._prepare_for_class(inputs_dict, model_class) + + main_input_name = model_class.main_input_name + + try: + if model.config.is_encoder_decoder: + model.config.use_cache = False # FSTM still requires this hack -> FSTM should probably be refactored similar to BART afterward + main_input = inputs[main_input_name] + attention_mask = inputs["attention_mask"] + decoder_input_ids = inputs["decoder_input_ids"] + decoder_attention_mask = inputs["decoder_attention_mask"] + model(main_input, attention_mask, decoder_input_ids, decoder_attention_mask) + traced_model = torch.jit.trace( + model, (main_input, attention_mask, decoder_input_ids, decoder_attention_mask) + ) + elif "bbox" in inputs and "image" in inputs: # LayoutLMv2 requires additional inputs + input_ids = inputs["input_ids"] + bbox = inputs["bbox"] + image = inputs["image"].tensor + model(input_ids, bbox, image) + traced_model = torch.jit.trace( + model, (input_ids, bbox, image), check_trace=False + ) # when traced model is checked, an error is produced due to name mangling + else: + main_input = inputs[main_input_name] + model(main_input) + traced_model = torch.jit.trace(model, main_input) + except RuntimeError: + self.fail("Couldn't trace module.") + + with tempfile.TemporaryDirectory() as tmp_dir_name: + pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt") + + try: + torch.jit.save(traced_model, pt_file_name) + except Exception: + self.fail("Couldn't save module.") + + try: + loaded_model = torch.jit.load(pt_file_name) + except Exception: + self.fail("Couldn't load module.") + + model.to(torch_device) + model.eval() + + loaded_model.to(torch_device) + loaded_model.eval() + + model_state_dict = model.state_dict() + loaded_model_state_dict = loaded_model.state_dict() + + non_persistent_buffers = {} + for key in loaded_model_state_dict.keys(): + if key not in model_state_dict.keys(): + non_persistent_buffers[key] = loaded_model_state_dict[key] + + loaded_model_state_dict = { + key: value for key, value in loaded_model_state_dict.items() if key not in non_persistent_buffers + } + + self.assertEqual(set(model_state_dict.keys()), set(loaded_model_state_dict.keys())) + + model_buffers = list(model.buffers()) + for non_persistent_buffer in non_persistent_buffers.values(): + found_buffer = False + for i, model_buffer in enumerate(model_buffers): + if torch.equal(non_persistent_buffer, model_buffer): + found_buffer = True + break + + self.assertTrue(found_buffer) + model_buffers.pop(i) + + models_equal = True + for layer_name, p1 in model_state_dict.items(): + if layer_name in loaded_model_state_dict: + p2 = loaded_model_state_dict[layer_name] + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + # Avoid memory leak. Without this, each call increase RAM usage by ~20MB. + # (Even with this call, there are still memory leak by ~0.04MB) + self.clear_torch_jit_class_registry() + + def test_torch_fx(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + self._create_and_check_torch_fx_tracing(config, inputs_dict) + + def test_torch_fx_output_loss(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + self._create_and_check_torch_fx_tracing(config, inputs_dict, output_loss=True) + + def _create_and_check_torch_fx_tracing(self, config, inputs_dict, output_loss=False): + if not is_torch_fx_available() or not self.fx_compatible: + return + + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + configs_no_init.return_dict = False + + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=output_loss) + + try: + if model.config.is_encoder_decoder: + model.config.use_cache = False # FSTM still requires this hack -> FSTM should probably be refactored similar to BART afterward + labels = inputs.get("labels", None) + input_names = [ + "attention_mask", + "decoder_attention_mask", + "decoder_input_ids", + "input_features", + "input_ids", + "input_values", + ] + if labels is not None: + input_names.append("labels") + + filtered_inputs = {k: v for (k, v) in inputs.items() if k in input_names} + input_names = list(filtered_inputs.keys()) + + model_output = model(**filtered_inputs) + + traced_model = symbolic_trace(model, input_names) + traced_output = traced_model(**filtered_inputs) + else: + input_names = [ + "attention_mask", + "bbox", + "input_features", + "input_ids", + "input_values", + "pixel_values", + "token_type_ids", + "visual_feats", + "visual_pos", + ] + + labels = inputs.get("labels", None) + start_positions = inputs.get("start_positions", None) + end_positions = inputs.get("end_positions", None) + if labels is not None: + input_names.append("labels") + if start_positions is not None: + input_names.append("start_positions") + if end_positions is not None: + input_names.append("end_positions") + + filtered_inputs = {k: v for (k, v) in inputs.items() if k in input_names} + input_names = list(filtered_inputs.keys()) + + if model.__class__.__name__ in set(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES.values()) and ( + not hasattr(model.config, "problem_type") or model.config.problem_type is None + ): + model.config.problem_type = "single_label_classification" + + traced_model = symbolic_trace(model, input_names) + traced_output = traced_model(**filtered_inputs) + model_output = model(**filtered_inputs) + + except Exception as e: + self.fail(f"Couldn't trace module: {e}") + + def flatten_output(output): + flatten = [] + for x in output: + if isinstance(x, (tuple, list)): + flatten += flatten_output(x) + elif not isinstance(x, torch.Tensor): + continue + else: + flatten.append(x) + return flatten + + model_output = flatten_output(model_output) + traced_output = flatten_output(traced_output) + num_outputs = len(model_output) + + for i in range(num_outputs): + self.assertTrue( + torch.allclose(model_output[i], traced_output[i]), + f"traced {i}th output doesn't match model {i}th output for {model_class}", + ) + + # Test that the model can be serialized and restored properly + with tempfile.TemporaryDirectory() as tmp_dir_name: + pkl_file_name = os.path.join(tmp_dir_name, "model.pkl") + try: + with open(pkl_file_name, "wb") as f: + pickle.dump(traced_model, f) + with open(pkl_file_name, "rb") as f: + loaded = pickle.load(f) + except Exception as e: + self.fail(f"Couldn't serialize / deserialize the traced model: {e}") + + loaded_output = loaded(**filtered_inputs) + loaded_output = flatten_output(loaded_output) + + for i in range(num_outputs): + self.assertTrue( + torch.allclose(model_output[i], loaded_output[i]), + f"serialized model {i}th output doesn't match model {i}th output for {model_class}", + ) + + # Avoid memory leak. Without this, each call increase RAM usage by ~20MB. + # (Even with this call, there are still memory leak by ~0.04MB) + self.clear_torch_jit_class_registry() + + def test_headmasking(self): + if not self.test_head_masking: + return + + global_rng.seed(42) + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + global_rng.seed() + + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + model.to(torch_device) + model.eval() + + # Prepare head_mask + # Set require_grad after having prepared the tensor to avoid error (leaf variable has been moved into the graph interior) + head_mask = torch.ones( + self.model_tester.num_hidden_layers, + self.model_tester.num_attention_heads, + device=torch_device, + ) + head_mask[0, 0] = 0 + head_mask[-1, :-1] = 0 + head_mask.requires_grad_(requires_grad=True) + inputs = self._prepare_for_class(inputs_dict, model_class).copy() + inputs["head_mask"] = head_mask + if model.config.is_encoder_decoder: + signature = inspect.signature(model.forward) + arg_names = [*signature.parameters.keys()] + if "decoder_head_mask" in arg_names: # necessary diferentiation because of T5 model + inputs["decoder_head_mask"] = head_mask + if "cross_attn_head_mask" in arg_names: + inputs["cross_attn_head_mask"] = head_mask + outputs = model(**inputs, return_dict=True) + + # Test that we can get a gradient back for importance score computation + output = sum(t.sum() for t in outputs[0]) + output = output.sum() + output.backward() + multihead_outputs = head_mask.grad + + self.assertIsNotNone(multihead_outputs) + self.assertEqual(len(multihead_outputs), self.model_tester.num_hidden_layers) + + def check_attentions_validity(attentions): + # Remove Nan + for t in attentions: + self.assertLess( + torch.sum(torch.isnan(t)), t.numel() / 4 + ) # Check we don't have more than 25% nans (arbitrary) + attentions = [ + t.masked_fill(torch.isnan(t), 0.0) for t in attentions + ] # remove them (the test is less complete) + + self.assertAlmostEqual(attentions[0][..., 0, :, :].flatten().sum().item(), 0.0) + self.assertNotEqual(attentions[0][..., -1, :, :].flatten().sum().item(), 0.0) + if len(attentions) > 2: # encoder-decoder models have only 2 layers in each module + self.assertNotEqual(attentions[1][..., 0, :, :].flatten().sum().item(), 0.0) + self.assertAlmostEqual(attentions[-1][..., -2, :, :].flatten().sum().item(), 0.0) + self.assertNotEqual(attentions[-1][..., -1, :, :].flatten().sum().item(), 0.0) + + if model.config.is_encoder_decoder: + check_attentions_validity(outputs.encoder_attentions) + check_attentions_validity(outputs.decoder_attentions) + check_attentions_validity(outputs.cross_attentions) + else: + check_attentions_validity(outputs.attentions) + + def test_head_pruning(self): + if not self.test_pruning: + return + + for model_class in self.all_model_classes: + ( + config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + + if "head_mask" in inputs_dict: + del inputs_dict["head_mask"] + + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + model = model_class(config=config) + model.to(torch_device) + model.eval() + heads_to_prune = { + 0: list(range(1, self.model_tester.num_attention_heads)), + -1: [0], + } + model.prune_heads(heads_to_prune) + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + attentions = outputs[-1] + + self.assertEqual(attentions[0].shape[-3], 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads) + self.assertEqual(attentions[-1].shape[-3], self.model_tester.num_attention_heads - 1) + + def test_head_pruning_save_load_from_pretrained(self): + if not self.test_pruning: + return + + for model_class in self.all_model_classes: + ( + config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + + if "head_mask" in inputs_dict: + del inputs_dict["head_mask"] + + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + model = model_class(config=config) + model.to(torch_device) + model.eval() + heads_to_prune = { + 0: list(range(1, self.model_tester.num_attention_heads)), + -1: [0], + } + model.prune_heads(heads_to_prune) + + with tempfile.TemporaryDirectory() as temp_dir_name: + model.save_pretrained(temp_dir_name) + model = model_class.from_pretrained(temp_dir_name) + model.to(torch_device) + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs[-1] + self.assertEqual(attentions[0].shape[-3], 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads) + self.assertEqual(attentions[-1].shape[-3], self.model_tester.num_attention_heads - 1) + + def test_head_pruning_save_load_from_config_init(self): + if not self.test_pruning: + return + + for model_class in self.all_model_classes: + ( + config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + + if "head_mask" in inputs_dict: + del inputs_dict["head_mask"] + + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + + heads_to_prune = { + 0: list(range(1, self.model_tester.num_attention_heads)), + -1: [0], + } + config.pruned_heads = heads_to_prune + + model = model_class(config=config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs[-1] + + self.assertEqual(attentions[0].shape[-3], 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads) + self.assertEqual(attentions[-1].shape[-3], self.model_tester.num_attention_heads - 1) + + def test_head_pruning_integration(self): + if not self.test_pruning: + return + + for model_class in self.all_model_classes: + ( + config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + + if "head_mask" in inputs_dict: + del inputs_dict["head_mask"] + + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + + heads_to_prune = {0: [0], 1: [1, 2]} + config.pruned_heads = heads_to_prune + + model = model_class(config=config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs[-1] + + self.assertEqual(attentions[0].shape[-3], self.model_tester.num_attention_heads - 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads - 2) + self.assertEqual(attentions[2].shape[-3], self.model_tester.num_attention_heads) + self.assertEqual(attentions[3].shape[-3], self.model_tester.num_attention_heads) + + with tempfile.TemporaryDirectory() as temp_dir_name: + model.save_pretrained(temp_dir_name) + model = model_class.from_pretrained(temp_dir_name) + model.to(torch_device) + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs[-1] + + self.assertEqual(attentions[0].shape[-3], self.model_tester.num_attention_heads - 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads - 2) + self.assertEqual(attentions[2].shape[-3], self.model_tester.num_attention_heads) + self.assertEqual(attentions[3].shape[-3], self.model_tester.num_attention_heads) + + heads_to_prune = {0: [0], 2: [1, 2]} + model.prune_heads(heads_to_prune) + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs[-1] + + self.assertEqual(attentions[0].shape[-3], self.model_tester.num_attention_heads - 1) + self.assertEqual(attentions[1].shape[-3], self.model_tester.num_attention_heads - 2) + self.assertEqual(attentions[2].shape[-3], self.model_tester.num_attention_heads - 2) + self.assertEqual(attentions[3].shape[-3], self.model_tester.num_attention_heads) + + self.assertDictEqual(model.config.pruned_heads, {0: [0], 1: [1, 2], 2: [1, 2]}) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + model.to(torch_device) + model.eval() + + with torch.no_grad(): + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + if hasattr(self.model_tester, "encoder_seq_length"): + seq_length = self.model_tester.encoder_seq_length + if hasattr(self.model_tester, "chunk_length") and self.model_tester.chunk_length > 1: + seq_length = seq_length * self.model_tester.chunk_length + else: + seq_length = self.model_tester.seq_length + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + if config.is_encoder_decoder: + hidden_states = outputs.decoder_hidden_states + + self.assertIsInstance(hidden_states, (list, tuple)) + self.assertEqual(len(hidden_states), expected_num_layers) + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [decoder_seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_retain_grad_hidden_states_attentions(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # no need to test all models as different heads yield the same functionality + model_class = self.all_model_classes[0] + model = model_class(config) + model.to(torch_device) + + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs = model(**inputs) + + output = outputs[0] + + if config.is_encoder_decoder: + # Seq2Seq models + encoder_hidden_states = outputs.encoder_hidden_states[0] + encoder_hidden_states.retain_grad() + + decoder_hidden_states = outputs.decoder_hidden_states[0] + decoder_hidden_states.retain_grad() + + if self.has_attentions: + encoder_attentions = outputs.encoder_attentions[0] + encoder_attentions.retain_grad() + + decoder_attentions = outputs.decoder_attentions[0] + decoder_attentions.retain_grad() + + cross_attentions = outputs.cross_attentions[0] + cross_attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(encoder_hidden_states.grad) + self.assertIsNotNone(decoder_hidden_states.grad) + + if self.has_attentions: + self.assertIsNotNone(encoder_attentions.grad) + self.assertIsNotNone(decoder_attentions.grad) + self.assertIsNotNone(cross_attentions.grad) + else: + # Encoder-/Decoder-only models + hidden_states = outputs.hidden_states[0] + hidden_states.retain_grad() + + if self.has_attentions: + attentions = outputs.attentions[0] + attentions.retain_grad() + + output.flatten()[0].backward(retain_graph=True) + + self.assertIsNotNone(hidden_states.grad) + + if self.has_attentions: + self.assertIsNotNone(attentions.grad) + + def test_feed_forward_chunking(self): + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + torch.manual_seed(0) + config = copy.deepcopy(original_config) + model = model_class(config) + model.to(torch_device) + model.eval() + + hidden_states_no_chunk = model(**self._prepare_for_class(inputs_dict, model_class))[0] + + torch.manual_seed(0) + config.chunk_size_feed_forward = 1 + model = model_class(config) + model.to(torch_device) + model.eval() + + hidden_states_with_chunk = model(**self._prepare_for_class(inputs_dict, model_class))[0] + self.assertTrue(torch.allclose(hidden_states_no_chunk, hidden_states_with_chunk, atol=1e-3)) + + def test_resize_position_vector_embeddings(self): + if not self.test_resize_position_embeddings: + return + + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + config = copy.deepcopy(original_config) + model = model_class(config) + model.to(torch_device) + + if self.model_tester.is_training is False: + model.eval() + + max_position_embeddings = config.max_position_embeddings + + # Retrieve the embeddings and clone theme + if model.config.is_encoder_decoder: + encoder_model_embed, decoder_model_embed = model.get_position_embeddings() + encoder_cloned_embeddings = encoder_model_embed.weight.clone() + decoder_cloned_embeddings = decoder_model_embed.weight.clone() + else: + model_embed = model.get_position_embeddings() + cloned_embeddings = model_embed.weight.clone() + + # Check that resizing the position embeddings with a larger max_position_embeddings increases + # the model's postion embeddings size + model.resize_position_embeddings(max_position_embeddings + 10) + self.assertEqual(model.config.max_position_embeddings, max_position_embeddings + 10) + + # Check that it actually resizes the embeddings matrix + if model.config.is_encoder_decoder: + encoder_model_embed, decoder_model_embed = model.get_position_embeddings() + self.assertEqual(encoder_model_embed.weight.shape[0], encoder_cloned_embeddings.shape[0] + 10) + self.assertEqual(decoder_model_embed.weight.shape[0], decoder_cloned_embeddings.shape[0] + 10) + else: + model_embed = model.get_position_embeddings() + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] + 10) + + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that resizing the position embeddings with a smaller max_position_embeddings decreases + # the model's max_position_embeddings + model.resize_position_embeddings(max_position_embeddings - 5) + self.assertEqual(model.config.max_position_embeddings, max_position_embeddings - 5) + + # Check that it actually resizes the embeddings matrix + if model.config.is_encoder_decoder: + encoder_model_embed, decoder_model_embed = model.get_position_embeddings() + self.assertEqual(encoder_model_embed.weight.shape[0], encoder_cloned_embeddings.shape[0] - 5) + self.assertEqual(decoder_model_embed.weight.shape[0], decoder_cloned_embeddings.shape[0] - 5) + else: + model_embed = model.get_position_embeddings() + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] - 5) + + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that adding and removing tokens has not modified the first part of the embedding matrix. + models_equal = True + + if model.config.is_encoder_decoder: + for p1, p2 in zip(encoder_cloned_embeddings, encoder_model_embed.weight): + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + for p1, p2 in zip(decoder_cloned_embeddings, decoder_model_embed.weight): + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + else: + for p1, p2 in zip(cloned_embeddings, model_embed.weight): + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_resize_tokens_embeddings(self): + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + if not self.test_resize_embeddings: + return + + for model_class in self.all_model_classes: + config = copy.deepcopy(original_config) + model = model_class(config) + model.to(torch_device) + + if self.model_tester.is_training is False: + model.eval() + + model_vocab_size = config.vocab_size + # Retrieve the embeddings and clone theme + model_embed = model.resize_token_embeddings(model_vocab_size) + cloned_embeddings = model_embed.weight.clone() + + # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size + model_embed = model.resize_token_embeddings(model_vocab_size + 10) + self.assertEqual(model.config.vocab_size, model_vocab_size + 10) + # Check that it actually resizes the embeddings matrix + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] + 10) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that resizing the token embeddings with a smaller vocab size decreases the model's vocab size + model_embed = model.resize_token_embeddings(model_vocab_size - 15) + self.assertEqual(model.config.vocab_size, model_vocab_size - 15) + # Check that it actually resizes the embeddings matrix + self.assertEqual(model_embed.weight.shape[0], cloned_embeddings.shape[0] - 15) + + # Check that the model can still do a forward pass successfully (every parameter should be resized) + # Input ids should be clamped to the maximum size of the vocabulary + inputs_dict["input_ids"].clamp_(max=model_vocab_size - 15 - 1) + + # make sure that decoder_input_ids are resized as well + if "decoder_input_ids" in inputs_dict: + inputs_dict["decoder_input_ids"].clamp_(max=model_vocab_size - 15 - 1) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that adding and removing tokens has not modified the first part of the embedding matrix. + models_equal = True + for p1, p2 in zip(cloned_embeddings, model_embed.weight): + if p1.data.ne(p2.data).sum() > 0: + models_equal = False + + self.assertTrue(models_equal) + + def test_resize_embeddings_untied(self): + ( + original_config, + inputs_dict, + ) = self.model_tester.prepare_config_and_inputs_for_common() + if not self.test_resize_embeddings: + return + + original_config.tie_word_embeddings = False + + # if model cannot untied embeddings -> leave test + if original_config.tie_word_embeddings: + return + + for model_class in self.all_model_classes: + config = copy.deepcopy(original_config) + model = model_class(config).to(torch_device) + + # if no output embeddings -> leave test + if model.get_output_embeddings() is None: + continue + + # Check that resizing the token embeddings with a larger vocab size increases the model's vocab size + model_vocab_size = config.vocab_size + model.resize_token_embeddings(model_vocab_size + 10) + self.assertEqual(model.config.vocab_size, model_vocab_size + 10) + output_embeds = model.get_output_embeddings() + self.assertEqual(output_embeds.weight.shape[0], model_vocab_size + 10) + # Check bias if present + if output_embeds.bias is not None: + self.assertEqual(output_embeds.bias.shape[0], model_vocab_size + 10) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + # Check that resizing the token embeddings with a smaller vocab size decreases the model's vocab size + model.resize_token_embeddings(model_vocab_size - 15) + self.assertEqual(model.config.vocab_size, model_vocab_size - 15) + # Check that it actually resizes the embeddings matrix + output_embeds = model.get_output_embeddings() + self.assertEqual(output_embeds.weight.shape[0], model_vocab_size - 15) + # Check bias if present + if output_embeds.bias is not None: + self.assertEqual(output_embeds.bias.shape[0], model_vocab_size - 15) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + # Input ids should be clamped to the maximum size of the vocabulary + inputs_dict["input_ids"].clamp_(max=model_vocab_size - 15 - 1) + if "decoder_input_ids" in inputs_dict: + inputs_dict["decoder_input_ids"].clamp_(max=model_vocab_size - 15 - 1) + # Check that the model can still do a forward pass successfully (every parameter should be resized) + model(**self._prepare_for_class(inputs_dict, model_class)) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + self.assertIsInstance(model.get_input_embeddings(), (nn.Embedding, AdaptiveEmbedding)) + model.set_input_embeddings(nn.Embedding(10, 10)) + x = model.get_output_embeddings() + self.assertTrue(x is None or isinstance(x, nn.Linear)) + + def test_model_main_input_name(self): + for model_class in self.all_model_classes: + model_signature = inspect.signature(getattr(model_class, "forward")) + # The main input is the name of the argument after `self` + observed_main_input_name = list(model_signature.parameters.keys())[1] + self.assertEqual(model_class.main_input_name, observed_main_input_name) + + def test_correct_missing_keys(self): + if not self.test_missing_keys: + return + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + base_model_prefix = model.base_model_prefix + + if hasattr(model, base_model_prefix): + extra_params = {k: v for k, v in model.named_parameters() if not k.startswith(base_model_prefix)} + extra_params.update({k: v for k, v in model.named_buffers() if not k.startswith(base_model_prefix)}) + # Some models define this as None + if model._keys_to_ignore_on_load_missing: + for key in model._keys_to_ignore_on_load_missing: + extra_params.pop(key, None) + + if not extra_params: + # In that case, we *are* on a head model, but every + # single key is not actual parameters and this is + # tested in `test_tied_model_weights_key_ignore` test. + continue + + with tempfile.TemporaryDirectory() as temp_dir_name: + model.base_model.save_pretrained(temp_dir_name) + model, loading_info = model_class.from_pretrained(temp_dir_name, output_loading_info=True) + self.assertGreater(len(loading_info["missing_keys"]), 0, model.__class__.__name__) + + def test_tie_model_weights(self): + if not self.test_torchscript: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_same_values(layer_1, layer_2): + equal = True + for p1, p2 in zip(layer_1.weight, layer_2.weight): + if p1.data.ne(p2.data).sum() > 0: + equal = False + return equal + + for model_class in self.all_model_classes: + config.torchscript = True + model_not_tied = model_class(config) + if model_not_tied.get_output_embeddings() is None: + continue + + config_tied = copy.deepcopy(config) + config_tied.torchscript = False + model_tied = model_class(config_tied) + params_tied = list(model_tied.parameters()) + # Check that the embedding layer and decoding layer are the same in size and in value + # self.assertTrue(check_same_values(embeddings, decoding)) + + # # Check that after modification, they remain the same. + # embeddings.weight.data.div_(2) + # # Check that the embedding layer and decoding layer are the same in size and in value + # self.assertTrue(embeddings.weight.shape, decoding.weight.shape) + # self.assertTrue(check_same_values(embeddings, decoding)) + + # # Check that after modification, they remain the same. + # decoding.weight.data.div_(4) + # # Check that the embedding layer and decoding layer are the same in size and in value + # self.assertTrue(embeddings.weight.shape, decoding.weight.shape) + # self.assertTrue(check_same_values(embeddings, decoding)) + + # Check that after resize they remain tied. + model_tied.resize_token_embeddings(config.vocab_size + 10) + params_tied_2 = list(model_tied.parameters()) + self.assertEqual(len(params_tied_2), len(params_tied)) + + # decoding.weight.data.mul_(20) + # # Check that the embedding layer and decoding layer are the same in size and in value + # self.assertTrue(model.transformer.wte.weight.shape, model.lm_head.weight.shape) + # self.assertTrue(check_same_values(model.transformer.wte, model.lm_head)) + + @require_safetensors + def test_can_use_safetensors(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model_tied = model_class(config) + with tempfile.TemporaryDirectory() as d: + try: + model_tied.save_pretrained(d, safe_serialization=True) + except Exception as e: + raise Exception(f"Class {model_class.__name__} cannot be saved using safetensors: {e}") + + model_reloaded, infos = model_class.from_pretrained(d, output_loading_info=True) + # Checking the state dicts are correct + reloaded_state = model_reloaded.state_dict() + for k, v in model_tied.state_dict().items(): + self.assertIn(k, reloaded_state, f"Key {k} is missing from reloaded") + torch.testing.assert_close( + v, reloaded_state[k], msg=lambda x: f"{model_class.__name__}: Tensor {k}: {x}" + ) + + # Checking the tensor sharing are correct + ptrs = defaultdict(list) + for k, v in model_tied.state_dict().items(): + ptrs[v.data_ptr()].append(k) + + shared_ptrs = {k: v for k, v in ptrs.items() if len(v) > 1} + + for _, shared_names in shared_ptrs.items(): + reloaded_ptrs = {reloaded_state[k].data_ptr() for k in shared_names} + self.assertEqual( + len(reloaded_ptrs), + 1, + f"The shared pointers are incorrect, found different pointers for keys {shared_names}", + ) + + def test_tied_model_weights_key_ignore(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model_tied = model_class(config) + with tempfile.TemporaryDirectory() as d: + model_tied.save_pretrained(d) + + # We are nuking ALL weights on file, so every parameter should + # yell on load. We're going to detect if we yell too much, or too little. + with open(os.path.join(d, "pytorch_model.bin"), "wb") as f: + torch.save({}, f) + model_reloaded, infos = model_class.from_pretrained(d, output_loading_info=True) + + # ! Actually we could use `state_dict()` and check iteratively the tensors which are the same (for instance using `tensor.data_ptr()`). to detect the duplicates. + # ```python + # model = GPT2LMHeadModel.from_pretrained("gpt2") + # "lm_head.weight" in model.state_dict().keys() # True + # "lm_head.weight" in model.named_parameters() # False + # In [6]: model.lm_head.weight.data_ptr() + # Out[6]: 139901378371648 + # In [9]: model.transformer.wte.weight.data_ptr() + # Out[9]: 139901378371648 # Same PTR, it's the same DATA ! we would need to check for stride too to be 100% accurate. + # ``` + + prefix = f"{model_reloaded.base_model_prefix}." + params = dict(model_reloaded.named_parameters()) + params.update(dict(model_reloaded.named_buffers())) + # param_names = set(k[len(prefix) :] if k.startswith(prefix) else k for k in params.keys()) + param_names = {k[len(prefix) :] if k.startswith(prefix) else k for k in params.keys()} + + missing_keys = set(infos["missing_keys"]) + + extra_missing = missing_keys - param_names + # missed_missing = param_names - missing_keys + + self.assertEqual( + extra_missing, + set(), + f"This model {model_class.__name__} might be missing some `keys_to_ignore`: {extra_missing}", + ) + + # self.assertEqual( + # missed_missing, + # set(), + # f"This model {model_class.__name__} ignores keys {missed_missing} but they look like real" + # " parameters", + # ) + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def set_nan_tensor_to_zero(t): + t[t != t] = 0 + return t + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + with torch.no_grad(): + tuple_output = model(**tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(**dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif isinstance(tuple_object, Dict): + for tuple_iterable_value, dict_iterable_value in zip( + tuple_object.values(), dict_object.values() + ): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + torch.allclose( + set_nan_tensor_to_zero(tuple_object), set_nan_tensor_to_zero(dict_object), atol=1e-5 + ), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {torch.max(torch.abs(tuple_object - dict_object))}. Tuple has `nan`:" + f" {torch.isnan(tuple_object).any()} and `inf`: {torch.isinf(tuple_object)}. Dict has" + f" `nan`: {torch.isnan(dict_object).any()} and `inf`: {torch.isinf(dict_object)}." + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + if self.has_attentions: + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence( + model, tuple_inputs, dict_inputs, {"output_hidden_states": True, "output_attentions": True} + ) + + # Don't copy this method to model specific test file! + # TODO: remove this method once the issues are all fixed! + def _make_attention_mask_non_null(self, inputs_dict): + """Make sure no sequence has all zeros as attention mask""" + + for k in ["attention_mask", "encoder_attention_mask", "decoder_attention_mask"]: + if k in inputs_dict: + attention_mask = inputs_dict[k] + + # Make sure no all 0s attention masks - to avoid failure at this moment. + # Put `1` at the beginning of sequences to make it still work when combining causal attention masks. + # TODO: remove this line once a fix regarding large negative values for attention mask is done. + attention_mask = torch.cat( + [torch.ones_like(attention_mask[:, :1], dtype=attention_mask.dtype), attention_mask[:, 1:]], dim=-1 + ) + + # Here we make the first sequence with all 0s as attention mask. + # Currently, this will fail for `TFWav2Vec2Model`. This is caused by the different large negative + # values, like `1e-4`, `1e-9`, `1e-30` and `-inf` for attention mask across models/frameworks. + # TODO: enable this block once the large negative values thing is cleaned up. + # (see https://github.com/huggingface/transformers/issues/14859) + # attention_mask = torch.cat( + # [torch.zeros_like(attention_mask[:1], dtype=attention_mask.dtype), attention_mask[1:]], + # dim=0 + # ) + + inputs_dict[k] = attention_mask + + # Don't copy this method to model specific test file! + # TODO: remove this method once the issues are all fixed! + def _postprocessing_to_ignore_test_cases(self, tf_outputs, pt_outputs, model_class): + """For temporarily ignoring some failed test cases (issues to be fixed)""" + + tf_keys = {k for k, v in tf_outputs.items() if v is not None} + pt_keys = {k for k, v in pt_outputs.items() if v is not None} + + key_differences = tf_keys.symmetric_difference(pt_keys) + + if model_class.__name__ in [ + "FlaubertWithLMHeadModel", + "FunnelForPreTraining", + "ElectraForPreTraining", + "XLMWithLMHeadModel", + "TransfoXLLMHeadModel", + ]: + for k in key_differences: + if k in ["loss", "losses"]: + tf_keys.discard(k) + pt_keys.discard(k) + elif model_class.__name__.startswith("GPT2"): + # `TFGPT2` has `past_key_values` as a tensor while `GPT2` has it as a tuple. + tf_keys.discard("past_key_values") + pt_keys.discard("past_key_values") + + # create new outputs from the remaining fields + new_tf_outputs = type(tf_outputs)(**{k: tf_outputs[k] for k in tf_keys}) + new_pt_outputs = type(pt_outputs)(**{k: pt_outputs[k] for k in pt_keys}) + + return new_tf_outputs, new_pt_outputs + + # Copied from tests.test_modeling_tf_common.TFModelTesterMixin.check_pt_tf_outputs + def check_pt_tf_outputs(self, tf_outputs, pt_outputs, model_class, tol=1e-5, name="outputs", attributes=None): + """Check the outputs from PyTorch and TensorFlow models are close enough. Checks are done in a recursive way. + + Args: + model_class: The class of the model that is currently testing. For example, `TFBertModel`, + TFBertForMaskedLM`, `TFBertForSequenceClassification`, etc. Mainly used for providing more informative + error messages. + name (`str`): The name of the output. For example, `output.hidden_states`, `output.attentions`, etc. + attributes (`Tuple[str]`): The names of the output's element if the output is a tuple/list with each element + being a named field in the output. + """ + + self.assertEqual(type(name), str) + if attributes is not None: + self.assertEqual(type(attributes), tuple, f"{name}: The argument `attributes` should be a `tuple`") + + # Allow `ModelOutput` (e.g. `CLIPOutput` has `text_model_output` and `vision_model_output`). + if isinstance(tf_outputs, ModelOutput): + self.assertTrue( + isinstance(pt_outputs, ModelOutput), + f"{name}: `pt_outputs` should an instance of `ModelOutput` when `tf_outputs` is", + ) + + # Don't copy this block to model specific test file! + # TODO: remove this method and this line after issues are fixed + tf_outputs, pt_outputs = self._postprocessing_to_ignore_test_cases(tf_outputs, pt_outputs, model_class) + + tf_keys = [k for k, v in tf_outputs.items() if v is not None] + pt_keys = [k for k, v in pt_outputs.items() if v is not None] + + self.assertEqual(tf_keys, pt_keys, f"{name}: Output keys differ between TF and PyTorch") + + # convert to the case of `tuple` + # appending each key to the current (string) `name` + attributes = tuple([f"{name}.{k}" for k in tf_keys]) + self.check_pt_tf_outputs( + tf_outputs.to_tuple(), pt_outputs.to_tuple(), model_class, tol=tol, name=name, attributes=attributes + ) + + # Allow `list` (e.g. `TransfoXLModelOutput.mems` is a list of tensors.) + elif type(tf_outputs) in [tuple, list]: + self.assertEqual(type(tf_outputs), type(pt_outputs), f"{name}: Output types differ between TF and PyTorch") + self.assertEqual(len(tf_outputs), len(pt_outputs), f"{name}: Output lengths differ between TF and PyTorch") + + if attributes is not None: + # case 1: each output has assigned name (e.g. a tuple form of a `ModelOutput`) + self.assertEqual( + len(attributes), + len(tf_outputs), + f"{name}: The tuple `attributes` should have the same length as `tf_outputs`", + ) + else: + # case 2: each output has no assigned name (e.g. hidden states of each layer) -> add an index to `name` + attributes = tuple([f"{name}_{idx}" for idx in range(len(tf_outputs))]) + + for tf_output, pt_output, attr in zip(tf_outputs, pt_outputs, attributes): + self.check_pt_tf_outputs(tf_output, pt_output, model_class, tol=tol, name=attr) + + elif isinstance(tf_outputs, tf.Tensor): + self.assertTrue( + isinstance(pt_outputs, torch.Tensor), f"{name}: `pt_outputs` should a tensor when `tf_outputs` is" + ) + + tf_outputs = tf_outputs.numpy() + pt_outputs = pt_outputs.detach().to("cpu").numpy() + + self.assertEqual( + tf_outputs.shape, pt_outputs.shape, f"{name}: Output shapes differ between TF and PyTorch" + ) + + # deal with NumPy's scalars to make replacing nan values by 0 work. + if np.isscalar(tf_outputs): + tf_outputs = np.array([tf_outputs]) + pt_outputs = np.array([pt_outputs]) + + tf_nans = np.isnan(tf_outputs) + pt_nans = np.isnan(pt_outputs) + + pt_outputs[tf_nans] = 0 + tf_outputs[tf_nans] = 0 + pt_outputs[pt_nans] = 0 + tf_outputs[pt_nans] = 0 + + max_diff = np.amax(np.abs(tf_outputs - pt_outputs)) + self.assertLessEqual(max_diff, tol, f"{name}: Difference between PyTorch and TF is {max_diff} (>= {tol}).") + else: + raise ValueError( + "`tf_outputs` should be an instance of `ModelOutput`, a `tuple`, or an instance of `tf.Tensor`. Got" + f" {type(tf_outputs)} instead." + ) + + def prepare_tf_inputs_from_pt_inputs(self, pt_inputs_dict): + tf_inputs_dict = {} + for key, tensor in pt_inputs_dict.items(): + # skip key that does not exist in tf + if type(tensor) == bool: + tf_inputs_dict[key] = tensor + elif key == "input_values": + tf_inputs_dict[key] = tf.convert_to_tensor(tensor.cpu().numpy(), dtype=tf.float32) + elif key == "pixel_values": + tf_inputs_dict[key] = tf.convert_to_tensor(tensor.cpu().numpy(), dtype=tf.float32) + elif key == "input_features": + tf_inputs_dict[key] = tf.convert_to_tensor(tensor.cpu().numpy(), dtype=tf.float32) + # other general float inputs + elif tensor.is_floating_point(): + tf_inputs_dict[key] = tf.convert_to_tensor(tensor.cpu().numpy(), dtype=tf.float32) + else: + tf_inputs_dict[key] = tf.convert_to_tensor(tensor.cpu().numpy(), dtype=tf.int32) + + return tf_inputs_dict + + def check_pt_tf_models(self, tf_model, pt_model, pt_inputs_dict): + tf_inputs_dict = self.prepare_tf_inputs_from_pt_inputs(pt_inputs_dict) + + # send pytorch inputs to the correct device + pt_inputs_dict = { + k: v.to(device=torch_device) if isinstance(v, torch.Tensor) else v for k, v in pt_inputs_dict.items() + } + + # send pytorch model to the correct device + pt_model.to(torch_device) + + # Check predictions on first output (logits/hidden-states) are close enough given low-level computational differences + pt_model.eval() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs_dict) + tf_outputs = tf_model(tf_inputs_dict) + + # tf models returned loss is usually a tensor rather than a scalar. + # (see `hf_compute_loss`: it uses `tf.keras.losses.Reduction.NONE`) + # Change it here to a scalar to match PyTorch models' loss + tf_loss = getattr(tf_outputs, "loss", None) + if tf_loss is not None: + tf_outputs.loss = tf.math.reduce_mean(tf_loss) + + self.check_pt_tf_outputs(tf_outputs, pt_outputs, type(pt_model)) + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self, allow_missing_keys=False): + import transformers + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + tf_model_class_name = "TF" + model_class.__name__ # Add the "TF" at the beginning + if not hasattr(transformers, tf_model_class_name): + # transformers does not have this model in TF version yet + return + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # Make sure no sequence has all zeros as attention mask, otherwise some tests fail due to the inconsistency + # of the usage `1e-4`, `1e-9`, `1e-30`, `-inf`. + # TODO: Use a uniform value for all models, make sure all tests pass without this processing, and remove it. + self._make_attention_mask_non_null(inputs_dict) + + tf_model_class = getattr(transformers, tf_model_class_name) + + pt_model = model_class(config) + tf_model = tf_model_class(config) + + pt_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs_dict_with_labels = self._prepare_for_class( + inputs_dict, + model_class, + # Not all models accept "labels" in the forward pass (yet :) ) + return_labels=True if "labels" in inspect.signature(model_class.forward).parameters.keys() else False, + ) + + # make sure only tf inputs are forward that actually exist in function args + tf_input_keys = set(inspect.signature(tf_model.call).parameters.keys()) + + # remove all head masks + tf_input_keys.discard("head_mask") + tf_input_keys.discard("cross_attn_head_mask") + tf_input_keys.discard("decoder_head_mask") + + pt_inputs_dict = {k: v for k, v in pt_inputs_dict.items() if k in tf_input_keys} + pt_inputs_dict_with_labels = {k: v for k, v in pt_inputs_dict_with_labels.items() if k in tf_input_keys} + + # For some models (e.g. base models), there is no label returned. + # Set the input dict to `None` to avoid check outputs twice for the same input dicts. + if not set(pt_inputs_dict_with_labels.keys()).symmetric_difference(pt_inputs_dict.keys()): + pt_inputs_dict_with_labels = None + + # Check we can load pt model in tf and vice-versa with model => model functions + # Here requires `tf_inputs_dict` to build `tf_model` + tf_inputs_dict = self.prepare_tf_inputs_from_pt_inputs(pt_inputs_dict) + tf_model = transformers.load_pytorch_model_in_tf2_model( + tf_model, pt_model, tf_inputs=tf_inputs_dict, allow_missing_keys=allow_missing_keys + ) + pt_model = transformers.load_tf2_model_in_pytorch_model( + pt_model, tf_model, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, pt_inputs_dict) + # check with `labels` + if pt_inputs_dict_with_labels: + self.check_pt_tf_models(tf_model, pt_model, pt_inputs_dict_with_labels) + + # Check we can load pt model in tf and vice-versa with checkpoint => model functions + with tempfile.TemporaryDirectory() as tmpdirname: + pt_checkpoint_path = os.path.join(tmpdirname, "pt_model.bin") + torch.save(pt_model.state_dict(), pt_checkpoint_path) + tf_model = transformers.load_pytorch_checkpoint_in_tf2_model( + tf_model, pt_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + tf_checkpoint_path = os.path.join(tmpdirname, "tf_model.h5") + tf_model.save_weights(tf_checkpoint_path) + pt_model = transformers.load_tf2_checkpoint_in_pytorch_model( + pt_model, tf_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, pt_inputs_dict) + # check with `labels` + if pt_inputs_dict_with_labels: + self.check_pt_tf_models(tf_model, pt_model, pt_inputs_dict_with_labels) + + def assert_almost_equals(self, a: np.ndarray, b: np.ndarray, tol: float): + diff = np.abs((a - b)).max() + self.assertLessEqual(diff, tol, f"Difference between torch and flax is {diff} (>= {tol}).") + + def check_pt_flax_outputs(self, fx_outputs, pt_outputs, model_class, tol=1e-5, name="outputs", attributes=None): + """ + Args: + model_class: The class of the model that is currently testing. For example, ..., etc. + Currently unused, but it could make debugging easier and faster. + + names: A string, or a list of strings. These specify what fx_outputs/pt_outputs represent in the model outputs. + Currently unused, but in the future, we could use this information to make the error message clearer + by giving the name(s) of the output tensor(s) with large difference(s) between PT and Flax. + """ + + self.assertEqual(type(name), str) + if attributes is not None: + self.assertEqual(type(attributes), tuple, f"{name}: The argument `attributes` should be a `tuple`") + + # Allow `ModelOutput` (e.g. `CLIPOutput` has `text_model_output` and `vision_model_output`). + if isinstance(fx_outputs, ModelOutput): + self.assertTrue( + isinstance(pt_outputs, ModelOutput), + f"{name}: `pt_outputs` should an instance of `ModelOutput` when `fx_outputs` is", + ) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys, f"{name}: Output keys differ between Flax and PyTorch") + + # convert to the case of `tuple` + # appending each key to the current (string) `name` + attributes = tuple([f"{name}.{k}" for k in fx_keys]) + self.check_pt_flax_outputs( + fx_outputs.to_tuple(), pt_outputs.to_tuple(), model_class, tol=tol, name=name, attributes=attributes + ) + + # Allow `list` (e.g. `TransfoXLModelOutput.mems` is a list of tensors.) + elif type(fx_outputs) in [tuple, list]: + self.assertEqual( + type(fx_outputs), type(pt_outputs), f"{name}: Output types differ between Flax and PyTorch" + ) + self.assertEqual( + len(fx_outputs), len(pt_outputs), f"{name}: Output lengths differ between Flax and PyTorch" + ) + + if attributes is not None: + # case 1: each output has assigned name (e.g. a tuple form of a `ModelOutput`) + self.assertEqual( + len(attributes), + len(fx_outputs), + f"{name}: The tuple `attributes` should have the same length as `fx_outputs`", + ) + else: + # case 2: each output has no assigned name (e.g. hidden states of each layer) -> add an index to `name` + attributes = tuple([f"{name}_{idx}" for idx in range(len(fx_outputs))]) + + for fx_output, pt_output, attr in zip(fx_outputs, pt_outputs, attributes): + self.check_pt_flax_outputs(fx_output, pt_output, model_class, tol=tol, name=attr) + + elif isinstance(fx_outputs, jnp.ndarray): + self.assertTrue( + isinstance(pt_outputs, torch.Tensor), f"{name}: `pt_outputs` should a tensor when `fx_outputs` is" + ) + + # Using `np.asarray` gives `ValueError: assignment destination is read-only` at the line `fx_outputs[fx_nans] = 0`. + fx_outputs = np.array(fx_outputs) + pt_outputs = pt_outputs.detach().to("cpu").numpy() + + self.assertEqual( + fx_outputs.shape, pt_outputs.shape, f"{name}: Output shapes differ between Flax and PyTorch" + ) + + # deal with NumPy's scalars to make replacing nan values by 0 work. + if np.isscalar(fx_outputs): + fx_outputs = np.array([fx_outputs]) + pt_outputs = np.array([pt_outputs]) + + fx_nans = np.isnan(fx_outputs) + pt_nans = np.isnan(pt_outputs) + + pt_outputs[fx_nans] = 0 + fx_outputs[fx_nans] = 0 + pt_outputs[pt_nans] = 0 + fx_outputs[pt_nans] = 0 + + max_diff = np.amax(np.abs(fx_outputs - pt_outputs)) + self.assertLessEqual( + max_diff, tol, f"{name}: Difference between PyTorch and Flax is {max_diff} (>= {tol})." + ) + else: + raise ValueError( + "`fx_outputs` should be an instance of `ModelOutput`, a `tuple`, or an instance of `jnp.ndarray`. Got" + f" {type(fx_outputs)} instead." + ) + + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + # no flax model exists for this class + return + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load PyTorch class + pt_model = model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + # send pytorch inputs to the correct device + pt_inputs = { + k: v.to(device=torch_device) if isinstance(v, torch.Tensor) else v for k, v in pt_inputs.items() + } + + # convert inputs to Flax + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + # send pytorch model to the correct device + pt_model.to(torch_device) + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs) + fx_outputs = fx_model(**fx_inputs) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs, model_class) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = fx_model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**fx_inputs) + + fx_keys = tuple([k for k, v in fx_outputs_loaded.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs_loaded, pt_outputs, model_class) + + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + fx_model_class_name = "Flax" + model_class.__name__ + + if not hasattr(transformers, fx_model_class_name): + # no flax model exists for this class + return + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + fx_model_class = getattr(transformers, fx_model_class_name) + + # load PyTorch class + pt_model = model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + + # load Flax class + fx_model = fx_model_class(config, dtype=jnp.float32) + + # make sure only flax inputs are forward that actually exist in function args + fx_input_keys = inspect.signature(fx_model.__call__).parameters.keys() + + # prepare inputs + pt_inputs = self._prepare_for_class(inputs_dict, model_class) + + # remove function args that don't exist in Flax + pt_inputs = {k: v for k, v in pt_inputs.items() if k in fx_input_keys} + + # send pytorch inputs to the correct device + pt_inputs = { + k: v.to(device=torch_device) if isinstance(v, torch.Tensor) else v for k, v in pt_inputs.items() + } + + # convert inputs to Flax + fx_inputs = {k: np.array(v) for k, v in pt_inputs.items() if torch.is_tensor(v)} + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + # send pytorch model to the correct device + pt_model.to(torch_device) + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs) + fx_outputs = fx_model(**fx_inputs) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs, model_class) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = model_class.from_pretrained(tmpdirname, from_flax=True) + + # send pytorch model to the correct device + pt_model_loaded.to(torch_device) + pt_model_loaded.eval() + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs_loaded.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs_loaded, model_class) + + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + model.to(torch_device) + model.eval() + + inputs = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + wte = model.get_input_embeddings() + if not self.is_encoder_decoder: + inputs["inputs_embeds"] = wte(input_ids) + else: + inputs["inputs_embeds"] = wte(encoder_input_ids) + inputs["decoder_inputs_embeds"] = wte(decoder_input_ids) + + with torch.no_grad(): + model(**inputs)[0] + + @require_torch_multi_gpu + def test_multi_gpu_data_parallel_forward(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # some params shouldn't be scattered by nn.DataParallel + # so just remove them if they are present. + blacklist_non_batched_params = ["head_mask", "decoder_head_mask", "cross_attn_head_mask"] + for k in blacklist_non_batched_params: + inputs_dict.pop(k, None) + + # move input tensors to cuda:O + for k, v in inputs_dict.items(): + if torch.is_tensor(v): + inputs_dict[k] = v.to(0) + + for model_class in self.all_model_classes: + model = model_class(config=config) + model.to(0) + model.eval() + + # Wrap model in nn.DataParallel + model = nn.DataParallel(model) + with torch.no_grad(): + _ = model(**self._prepare_for_class(inputs_dict, model_class)) + + @require_torch_multi_gpu + def test_model_parallelization(self): + if not self.test_model_parallel: + return + + # a candidate for testing_utils + def get_current_gpu_memory_use(): + """returns a list of cuda memory allocations per GPU in MBs""" + + per_device_memory = [] + for id in range(torch.cuda.device_count()): + with torch.cuda.device(id): + per_device_memory.append(torch.cuda.memory_allocated() >> 20) + + return per_device_memory + + # Needs a large model to see the difference. + config = self.model_tester.get_large_model_config() + + for model_class in self.all_parallelizable_model_classes: + torch.cuda.empty_cache() + + # 1. single gpu memory load + unload + memory measurements + # Retrieve initial memory usage (can easily be ~0.6-1.5GB if cuda-kernels have been preloaded by previous tests) + memory_at_start = get_current_gpu_memory_use() + + # Put model on device 0 and take a memory snapshot + model = model_class(config) + model.to("cuda:0") + memory_after_model_load = get_current_gpu_memory_use() + + # The memory use on device 0 should be higher than it was initially. + self.assertGreater(memory_after_model_load[0], memory_at_start[0]) + + del model + gc.collect() + torch.cuda.empty_cache() + + # 2. MP test + # it's essential to re-calibrate the usage before the next stage + memory_at_start = get_current_gpu_memory_use() + + # Spread model layers over multiple devices + model = model_class(config) + model.parallelize() + memory_after_parallelization = get_current_gpu_memory_use() + + # Assert that the memory use on all devices is higher than it was when loaded only on CPU + for n in range(len(model.device_map.keys())): + self.assertGreater(memory_after_parallelization[n], memory_at_start[n]) + + # Assert that the memory use of device 0 is lower than it was when the entire model was loaded on it + self.assertLess(memory_after_parallelization[0], memory_after_model_load[0]) + + # Assert that the memory use of device 1 is higher than it was when the entire model was loaded + # on device 0 and device 1 wasn't used at all + self.assertGreater(memory_after_parallelization[1], memory_after_model_load[1]) + + del model + gc.collect() + torch.cuda.empty_cache() + + @require_torch_multi_gpu + def test_model_parallel_equal_results(self): + if not self.test_model_parallel: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_parallelizable_model_classes: + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + + def cast_to_device(dictionary, device): + output = {} + for k, v in dictionary.items(): + if isinstance(v, torch.Tensor): + output[k] = v.to(device) + else: + output[k] = v + + return output + + model = model_class(config) + output = model(**cast_to_device(inputs_dict, "cpu")) + + model.parallelize() + + parallel_output = model(**cast_to_device(inputs_dict, "cuda:0")) + + for value, parallel_value in zip(output, parallel_output): + if isinstance(value, torch.Tensor): + self.assertTrue(torch.allclose(value, parallel_value.to("cpu"), atol=1e-7)) + elif isinstance(value, (Tuple, List)): + for value_, parallel_value_ in zip(value, parallel_value): + self.assertTrue(torch.allclose(value_, parallel_value_.to("cpu"), atol=1e-7)) + + @require_torch_multi_gpu + def test_model_parallel_beam_search(self): + if not self.test_model_parallel: + return + + all_generative_and_parallelizable_model_classes = tuple( + set(self.all_generative_model_classes).intersection(self.all_parallelizable_model_classes) + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in all_generative_and_parallelizable_model_classes: + inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + def cast_to_device(dictionary, device): + output = {} + for k, v in dictionary.items(): + if isinstance(v, torch.Tensor): + output[k] = v.to(device) + else: + output[k] = v + + return output + + model.parallelize() + model.generate(**cast_to_device(inputs_dict, "cuda:0"), num_beams=2) + + def check_device_map_is_respected(self, model, device_map): + for param_name, param in model.named_parameters(): + # Find device in device_map + while len(param_name) > 0 and param_name not in device_map: + param_name = ".".join(param_name.split(".")[:-1]) + if param_name not in device_map: + raise ValueError("device map is incomplete, it does not contain any device for `param_name`.") + + param_device = device_map[param_name] + if param_device in ["cpu", "disk"]: + self.assertEqual(param.device, torch.device("meta")) + else: + self.assertEqual(param.device, torch.device(param_device)) + + @require_accelerate + @mark.accelerate_tests + @require_torch_gpu + def test_disk_offload(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class._no_split_modules is None: + continue + + inputs_dict_class = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config).eval() + model = model.to(torch_device) + torch.manual_seed(0) + base_output = model(**inputs_dict_class) + + model_size = compute_module_sizes(model)[""] + max_size = int(self.model_split_percents[0] * model_size) + with tempfile.TemporaryDirectory() as tmp_dir: + model.cpu().save_pretrained(tmp_dir) + + max_memory = {0: max_size, "cpu": max_size} + with self.assertRaises(ValueError): + # This errors out cause it's missing an offload folder + new_model = model_class.from_pretrained(tmp_dir, device_map="auto", max_memory=max_memory) + + new_model = model_class.from_pretrained( + tmp_dir, device_map="auto", max_memory=max_memory, offload_folder=tmp_dir + ) + + self.check_device_map_is_respected(new_model, new_model.hf_device_map) + torch.manual_seed(0) + new_output = new_model(**inputs_dict_class) + + self.assertTrue(torch.allclose(base_output[0], new_output[0], atol=1e-5)) + + @require_accelerate + @mark.accelerate_tests + @require_torch_gpu + def test_cpu_offload(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class._no_split_modules is None: + continue + + inputs_dict_class = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config).eval() + model = model.to(torch_device) + + torch.manual_seed(0) + base_output = model(**inputs_dict_class) + + model_size = compute_module_sizes(model)[""] + # We test several splits of sizes to make sure it works. + max_gpu_sizes = [int(p * model_size) for p in self.model_split_percents] + with tempfile.TemporaryDirectory() as tmp_dir: + model.cpu().save_pretrained(tmp_dir) + + for max_size in max_gpu_sizes: + max_memory = {0: max_size, "cpu": model_size * 2} + new_model = model_class.from_pretrained(tmp_dir, device_map="auto", max_memory=max_memory) + # Making sure part of the model will actually end up offloaded + self.assertSetEqual(set(new_model.hf_device_map.values()), {0, "cpu"}) + + self.check_device_map_is_respected(new_model, new_model.hf_device_map) + + torch.manual_seed(0) + new_output = new_model(**inputs_dict_class) + + self.assertTrue(torch.allclose(base_output[0], new_output[0], atol=1e-5)) + + @require_accelerate + @mark.accelerate_tests + @require_torch_multi_gpu + def test_model_parallelism(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class._no_split_modules is None: + continue + + inputs_dict_class = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config).eval() + model = model.to(torch_device) + + torch.manual_seed(0) + base_output = model(**inputs_dict_class) + + model_size = compute_module_sizes(model)[""] + # We test several splits of sizes to make sure it works. + max_gpu_sizes = [int(p * model_size) for p in self.model_split_percents] + with tempfile.TemporaryDirectory() as tmp_dir: + model.cpu().save_pretrained(tmp_dir) + + for max_size in max_gpu_sizes: + max_memory = {0: max_size, 1: model_size * 2, "cpu": model_size * 2} + new_model = model_class.from_pretrained(tmp_dir, device_map="auto", max_memory=max_memory) + # Making sure part of the model will actually end up offloaded + self.assertSetEqual(set(new_model.hf_device_map.values()), {0, 1}) + + self.check_device_map_is_respected(new_model, new_model.hf_device_map) + + torch.manual_seed(0) + new_output = new_model(**inputs_dict_class) + + self.assertTrue(torch.allclose(base_output[0], new_output[0], atol=1e-5)) + + def test_problem_types(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + problem_types = [ + {"title": "multi_label_classification", "num_labels": 2, "dtype": torch.float}, + {"title": "single_label_classification", "num_labels": 1, "dtype": torch.long}, + {"title": "regression", "num_labels": 1, "dtype": torch.float}, + ] + + for model_class in self.all_model_classes: + if model_class.__name__ not in [ + *get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES), + *get_values(MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING_NAMES), + ]: + continue + + for problem_type in problem_types: + with self.subTest(msg=f"Testing {model_class} with {problem_type['title']}"): + config.problem_type = problem_type["title"] + config.num_labels = problem_type["num_labels"] + + model = model_class(config) + model.to(torch_device) + model.train() + + inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + + if problem_type["num_labels"] > 1: + inputs["labels"] = inputs["labels"].unsqueeze(1).repeat(1, problem_type["num_labels"]) + + inputs["labels"] = inputs["labels"].to(problem_type["dtype"]) + + # This tests that we do not trigger the warning form PyTorch "Using a target size that is different + # to the input size. This will likely lead to incorrect results due to broadcasting. Please ensure + # they have the same size." which is a symptom something in wrong for the regression problem. + # See https://github.com/huggingface/transformers/issues/11780 + with warnings.catch_warnings(record=True) as warning_list: + loss = model(**inputs).loss + for w in warning_list: + if "Using a target size that is different to the input size" in str(w.message): + raise ValueError( + f"Something is going wrong in the regression problem: intercepted {w.message}" + ) + + loss.backward() + + def test_load_with_mismatched_shapes(self): + if not self.test_mismatched_shapes: + return + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class.__name__ not in get_values(MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING_NAMES): + continue + + with self.subTest(msg=f"Testing {model_class}"): + with tempfile.TemporaryDirectory() as tmp_dir: + model = model_class(config) + model.save_pretrained(tmp_dir) + + # Fails when we don't set ignore_mismatched_sizes=True + with self.assertRaises(RuntimeError): + new_model = AutoModelForSequenceClassification.from_pretrained(tmp_dir, num_labels=42) + with self.assertRaises(RuntimeError): + new_model_without_prefix = AutoModel.from_pretrained(tmp_dir, vocab_size=10) + + logger = logging.get_logger("transformers.modeling_utils") + + with CaptureLogger(logger) as cl: + new_model = AutoModelForSequenceClassification.from_pretrained( + tmp_dir, num_labels=42, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + new_model.to(torch_device) + inputs = self._prepare_for_class(inputs_dict, model_class) + logits = new_model(**inputs).logits + self.assertEqual(logits.shape[1], 42) + + with CaptureLogger(logger) as cl: + new_model_without_prefix = AutoModel.from_pretrained( + tmp_dir, vocab_size=10, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + input_ids = ids_tensor((2, 8), 10) + new_model_without_prefix.to(torch_device) + if self.is_encoder_decoder: + new_model_without_prefix(input_ids, decoder_input_ids=input_ids) + else: + new_model_without_prefix(input_ids) + + +global_rng = random.Random() + + +def ids_tensor(shape, vocab_size, rng=None, name=None): + # Creates a random int32 tensor of the shape within the vocab size + if rng is None: + rng = global_rng + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.randint(0, vocab_size - 1)) + + return torch.tensor(data=values, dtype=torch.long, device=torch_device).view(shape).contiguous() + + +def random_attention_mask(shape, rng=None, name=None): + attn_mask = ids_tensor(shape, vocab_size=2, rng=None, name=None) + # make sure that at least one token is attended to for each batch + attn_mask[:, -1] = 1 + return attn_mask + + +def floats_tensor(shape, scale=1.0, rng=None, name=None): + """Creates a random float32 tensor""" + if rng is None: + rng = global_rng + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.random() * scale) + + return torch.tensor(data=values, dtype=torch.float, device=torch_device).view(shape).contiguous() + + +def check_models_equal(model1, model2): + models_are_equal = True + for model1_p, model2_p in zip(model1.parameters(), model2.parameters()): + if model1_p.data.ne(model2_p.data).sum() > 0: + models_are_equal = False + + return models_are_equal + + +@require_torch +class ModelUtilsTest(TestCasePlus): + @slow + def test_model_from_pretrained(self): + for model_name in BERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]: + config = BertConfig.from_pretrained(model_name) + self.assertIsNotNone(config) + self.assertIsInstance(config, PretrainedConfig) + + model = BertModel.from_pretrained(model_name) + model, loading_info = BertModel.from_pretrained(model_name, output_loading_info=True) + self.assertIsNotNone(model) + self.assertIsInstance(model, PreTrainedModel) + + self.assertEqual(len(loading_info["missing_keys"]), 0) + self.assertEqual(len(loading_info["unexpected_keys"]), 8) + self.assertEqual(len(loading_info["mismatched_keys"]), 0) + self.assertEqual(len(loading_info["error_msgs"]), 0) + + config = BertConfig.from_pretrained(model_name, output_attentions=True, output_hidden_states=True) + + # Not sure this is the intended behavior. TODO fix Lysandre & Thom + config.name_or_path = model_name + + model = BertModel.from_pretrained(model_name, output_attentions=True, output_hidden_states=True) + self.assertEqual(model.config.output_hidden_states, True) + self.assertEqual(model.config, config) + + def test_model_from_pretrained_subfolder(self): + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + model = BertModel(config) + + subfolder = "bert" + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(os.path.join(tmp_dir, subfolder)) + + with self.assertRaises(OSError): + _ = BertModel.from_pretrained(tmp_dir) + + model_loaded = BertModel.from_pretrained(tmp_dir, subfolder=subfolder) + + self.assertTrue(check_models_equal(model, model_loaded)) + + def test_model_from_pretrained_subfolder_sharded(self): + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + model = BertModel(config) + + subfolder = "bert" + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(os.path.join(tmp_dir, subfolder), max_shard_size="10KB") + + with self.assertRaises(OSError): + _ = BertModel.from_pretrained(tmp_dir) + + model_loaded = BertModel.from_pretrained(tmp_dir, subfolder=subfolder) + + self.assertTrue(check_models_equal(model, model_loaded)) + + def test_model_from_pretrained_hub_subfolder(self): + subfolder = "bert" + model_id = "hf-internal-testing/tiny-random-bert-subfolder" + with self.assertRaises(OSError): + _ = BertModel.from_pretrained(model_id) + + model = BertModel.from_pretrained(model_id, subfolder=subfolder) + + self.assertIsNotNone(model) + + def test_model_from_pretrained_hub_subfolder_sharded(self): + subfolder = "bert" + model_id = "hf-internal-testing/tiny-random-bert-sharded-subfolder" + with self.assertRaises(OSError): + _ = BertModel.from_pretrained(model_id) + + model = BertModel.from_pretrained(model_id, subfolder=subfolder) + + self.assertIsNotNone(model) + + def test_model_from_pretrained_with_different_pretrained_model_name(self): + model = T5ForConditionalGeneration.from_pretrained(TINY_T5) + self.assertIsNotNone(model) + + logger = logging.get_logger("transformers.configuration_utils") + with CaptureLogger(logger) as cl: + BertModel.from_pretrained(TINY_T5) + self.assertTrue("You are using a model of type t5 to instantiate a model of type bert" in cl.out) + + def test_model_from_config_torch_dtype(self): + # test that the model can be instantiated with dtype of user's choice - as long as it's a + # float dtype. To make it happen config.torch_dtype needs to be set before instantiating the + # model from the config object. + + config = T5Config.from_pretrained(TINY_T5) + model = AutoModel.from_config(config) + # XXX: isn't supported + # model = T5ForConditionalGeneration.from_config(config) + self.assertEqual(model.dtype, torch.float32) + + model = AutoModel.from_config(config, torch_dtype=torch.float16) + self.assertEqual(model.dtype, torch.float16) + + # torch.set_default_dtype() supports only float dtypes, so will fail with non-float type + with self.assertRaises(ValueError): + model = AutoModel.from_config(config, torch_dtype=torch.int64) + + def test_model_from_pretrained_torch_dtype(self): + # test that the model can be instantiated with dtype of either + # 1. explicit from_pretrained's torch_dtype argument + # 2. via autodiscovery by looking at model weights (torch_dtype="auto") + # so if a model.half() was saved, we want it to be instantiated as such. + # + # test an explicit model class, but also AutoModel separately as the latter goes through a different code path + model_path = self.get_auto_remove_tmp_dir() + + # baseline - we know TINY_T5 is fp32 model + model = T5ForConditionalGeneration.from_pretrained(TINY_T5) + self.assertEqual(model.dtype, torch.float32) + + def remove_torch_dtype(model_path): + file = f"{model_path}/config.json" + with open(file, "r", encoding="utf-8") as f: + s = json.load(f) + s.pop("torch_dtype") + with open(file, "w", encoding="utf-8") as f: + json.dump(s, f) + + # test the default fp32 save_pretrained => from_pretrained cycle + model.save_pretrained(model_path) + model = T5ForConditionalGeneration.from_pretrained(model_path) + self.assertEqual(model.dtype, torch.float32) + # 1. test torch_dtype="auto" via `config.torch_dtype` + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype="auto") + self.assertEqual(model.dtype, torch.float32) + # 2. test torch_dtype="auto" via auto-derivation + # now remove the torch_dtype entry from config.json and try "auto" again which should + # perform auto-derivation from weights + remove_torch_dtype(model_path) + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype="auto") + self.assertEqual(model.dtype, torch.float32) + + # test forced loading in fp16 (even though the weights are in fp32) + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype=torch.float16) + self.assertEqual(model.dtype, torch.float16) + + # test fp16 save_pretrained, loaded with auto-detection + model = model.half() + model.save_pretrained(model_path) + # 1. test torch_dtype="auto" via `config.torch_dtype` + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype="auto") + self.assertEqual(model.config.torch_dtype, torch.float16) + self.assertEqual(model.dtype, torch.float16) + # tests `config.torch_dtype` saving + with open(f"{model_path}/config.json") as f: + config_dict = json.load(f) + self.assertEqual(config_dict["torch_dtype"], "float16") + # 2. test torch_dtype="auto" via auto-derivation + # now same with using config info + remove_torch_dtype(model_path) + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype="auto") + self.assertEqual(model.dtype, torch.float16) + + # test fp16 save_pretrained, loaded with the explicit fp16 + model = T5ForConditionalGeneration.from_pretrained(model_path, torch_dtype=torch.float16) + self.assertEqual(model.dtype, torch.float16) + + # test AutoModel separately as it goes through a different path + # test auto-detection - as currently TINY_T5 doesn't have torch_dtype entry + model = AutoModel.from_pretrained(TINY_T5, torch_dtype="auto") + # test that the config object didn't get polluted with torch_dtype="auto" + # there was a bug that after this call we ended up with config.torch_dtype=="auto" + self.assertNotEqual(model.config.torch_dtype, "auto") + # now test the outcome + self.assertEqual(model.dtype, torch.float32) + model = AutoModel.from_pretrained(TINY_T5, torch_dtype=torch.float16) + self.assertEqual(model.dtype, torch.float16) + + # test model whose first param is not of a floating type, but int + model = AutoModel.from_pretrained(TINY_BERT_FOR_TOKEN_CLASSIFICATION, torch_dtype="auto") + self.assertEqual(model.dtype, torch.float32) + + def test_no_super_init_config_and_model(self): + config = NoSuperInitConfig(attribute=32) + model = NoSuperInitModel(config) + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir) + + new_model = NoSuperInitModel.from_pretrained(tmp_dir) + + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + def test_shard_checkpoint(self): + # This is the model we will use, total size 340,000 bytes. + model = torch.nn.Sequential( + torch.nn.Linear(100, 200, bias=False), # size 80,000 + torch.nn.Linear(200, 200, bias=False), # size 160,000 + torch.nn.Linear(200, 100, bias=False), # size 80,000 + torch.nn.Linear(100, 50, bias=False), # size 20,000 + ) + state_dict = model.state_dict() + + with self.subTest("No shard when max size is bigger than model size"): + shards, index = shard_checkpoint(state_dict) + self.assertIsNone(index) + self.assertDictEqual(shards, {WEIGHTS_NAME: state_dict}) + + with self.subTest("Test sharding, no weights bigger than max size"): + shards, index = shard_checkpoint(state_dict, max_shard_size="300kB") + # Split is first two layers then last two. + self.assertDictEqual( + index, + { + "metadata": {"total_size": 340000}, + "weight_map": { + "0.weight": "pytorch_model-00001-of-00002.bin", + "1.weight": "pytorch_model-00001-of-00002.bin", + "2.weight": "pytorch_model-00002-of-00002.bin", + "3.weight": "pytorch_model-00002-of-00002.bin", + }, + }, + ) + + shard1 = {"0.weight": state_dict["0.weight"], "1.weight": state_dict["1.weight"]} + shard2 = {"2.weight": state_dict["2.weight"], "3.weight": state_dict["3.weight"]} + self.assertDictEqual( + shards, {"pytorch_model-00001-of-00002.bin": shard1, "pytorch_model-00002-of-00002.bin": shard2} + ) + + with self.subTest("Test sharding with weights bigger than max size"): + shards, index = shard_checkpoint(state_dict, max_shard_size="100kB") + # Split is first layer, second layer then last 2. + self.assertDictEqual( + index, + { + "metadata": {"total_size": 340000}, + "weight_map": { + "0.weight": "pytorch_model-00001-of-00003.bin", + "1.weight": "pytorch_model-00002-of-00003.bin", + "2.weight": "pytorch_model-00003-of-00003.bin", + "3.weight": "pytorch_model-00003-of-00003.bin", + }, + }, + ) + + shard1 = {"0.weight": state_dict["0.weight"]} + shard2 = {"1.weight": state_dict["1.weight"]} + shard3 = {"2.weight": state_dict["2.weight"], "3.weight": state_dict["3.weight"]} + self.assertDictEqual( + shards, + { + "pytorch_model-00001-of-00003.bin": shard1, + "pytorch_model-00002-of-00003.bin": shard2, + "pytorch_model-00003-of-00003.bin": shard3, + }, + ) + + def test_checkpoint_sharding_local(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + # We use the same folder for various sizes to make sure a new save erases the old checkpoint. + for max_size in ["50kB", "50kiB", "100kB", "100kiB", "200kB", "200kiB"]: + model.save_pretrained(tmp_dir, max_shard_size=max_size) + + # Get each shard file and its size + shard_to_size = {} + for shard in os.listdir(tmp_dir): + if shard.endswith(".bin"): + shard_file = os.path.join(tmp_dir, shard) + shard_to_size[shard_file] = os.path.getsize(shard_file) + + index_file = os.path.join(tmp_dir, WEIGHTS_INDEX_NAME) + # Check there is an index but no regular weight file + self.assertTrue(os.path.isfile(index_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_NAME))) + + # Check a file is bigger than max_size only when it has a single weight + for shard_file, size in shard_to_size.items(): + if max_size.endswith("kiB"): + max_size_int = int(max_size[:-3]) * 2**10 + else: + max_size_int = int(max_size[:-2]) * 10**3 + # Note: pickle adds some junk so the weight of the file can end up being slightly bigger than + # the size asked for (since we count parameters) + if size >= max_size_int + 50000: + state_dict = torch.load(shard_file) + self.assertEqual(len(state_dict), 1) + + # Check the index and the shard files found match + with open(index_file, "r", encoding="utf-8") as f: + index = json.loads(f.read()) + + all_shards = set(index["weight_map"].values()) + shards_found = {f for f in os.listdir(tmp_dir) if f.endswith(".bin")} + self.assertSetEqual(all_shards, shards_found) + + # Finally, check the model can be reloaded + new_model = BertModel.from_pretrained(tmp_dir) + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + def test_checkpoint_sharding_from_hub(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded") + # the model above is the same as the model below, just a sharded version. + ref_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + for p1, p2 in zip(model.parameters(), ref_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + def test_checkpoint_variant_local(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, variant="v2") + + weights_name = ".".join(WEIGHTS_NAME.split(".")[:-1] + ["v2"] + ["bin"]) + + weights_file = os.path.join(tmp_dir, weights_name) + self.assertTrue(os.path.isfile(weights_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_NAME))) + + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained(tmp_dir) + + new_model = BertModel.from_pretrained(tmp_dir, variant="v2") + + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + def test_checkpoint_variant_local_sharded(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, variant="v2", max_shard_size="50kB") + + weights_index_name = ".".join(WEIGHTS_INDEX_NAME.split(".")[:-1] + ["v2"] + ["json"]) + weights_index_file = os.path.join(tmp_dir, weights_index_name) + self.assertTrue(os.path.isfile(weights_index_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_INDEX_NAME))) + + for i in range(1, 6): + weights_name = ".".join(WEIGHTS_NAME.split(".")[:-1] + [f"v2-0000{i}-of-00006"] + ["bin"]) + weights_name_file = os.path.join(tmp_dir, weights_name) + self.assertTrue(os.path.isfile(weights_name_file)) + + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained(tmp_dir) + + new_model = BertModel.from_pretrained(tmp_dir, variant="v2") + + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + @require_safetensors + def test_checkpoint_variant_local_safe(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, variant="v2", safe_serialization=True) + + weights_name = ".".join(SAFE_WEIGHTS_NAME.split(".")[:-1] + ["v2"] + ["safetensors"]) + + weights_file = os.path.join(tmp_dir, weights_name) + self.assertTrue(os.path.isfile(weights_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME))) + + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained(tmp_dir) + + new_model = BertModel.from_pretrained(tmp_dir, variant="v2") + + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + @require_safetensors + def test_checkpoint_variant_local_sharded_safe(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, variant="v2", max_shard_size="50kB", safe_serialization=True) + + weights_index_name = ".".join(SAFE_WEIGHTS_INDEX_NAME.split(".")[:-1] + ["v2"] + ["json"]) + weights_index_file = os.path.join(tmp_dir, weights_index_name) + self.assertTrue(os.path.isfile(weights_index_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_INDEX_NAME))) + + for i in range(1, 6): + weights_name = ".".join(SAFE_WEIGHTS_NAME.split(".")[:-1] + [f"v2-0000{i}-of-00006"] + ["safetensors"]) + weights_name_file = os.path.join(tmp_dir, weights_name) + self.assertTrue(os.path.isfile(weights_name_file)) + + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained(tmp_dir) + + new_model = BertModel.from_pretrained(tmp_dir, variant="v2") + + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + def test_checkpoint_variant_hub(self): + with tempfile.TemporaryDirectory() as tmp_dir: + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-variant", cache_dir=tmp_dir) + model = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant", cache_dir=tmp_dir, variant="v2" + ) + self.assertIsNotNone(model) + + def test_checkpoint_variant_hub_sharded(self): + with tempfile.TemporaryDirectory() as tmp_dir: + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant-sharded", cache_dir=tmp_dir + ) + model = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant-sharded", cache_dir=tmp_dir, variant="v2" + ) + self.assertIsNotNone(model) + + @require_safetensors + def test_checkpoint_variant_hub_safe(self): + with tempfile.TemporaryDirectory() as tmp_dir: + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-variant-safe", cache_dir=tmp_dir) + model = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant-safe", cache_dir=tmp_dir, variant="v2" + ) + self.assertIsNotNone(model) + + @require_safetensors + def test_checkpoint_variant_hub_sharded_safe(self): + with tempfile.TemporaryDirectory() as tmp_dir: + with self.assertRaises(EnvironmentError): + _ = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant-sharded-safe", cache_dir=tmp_dir + ) + model = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant-sharded-safe", cache_dir=tmp_dir, variant="v2" + ) + self.assertIsNotNone(model) + + def test_checkpoint_variant_save_load(self): + with tempfile.TemporaryDirectory() as tmp_dir: + model = BertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert-variant", cache_dir=tmp_dir, variant="v2" + ) + weights_name = ".".join(WEIGHTS_NAME.split(".")[:-1] + ["v2"] + ["bin"]) + + model.save_pretrained(tmp_dir, variant="v2") + # saving will create a variant checkpoint + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, weights_name))) + + model.save_pretrained(tmp_dir) + # saving shouldn't delete variant checkpoints + weights_name = ".".join(WEIGHTS_NAME.split(".")[:-1] + ["v2"] + ["bin"]) + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, weights_name))) + + # there should be a normal checkpoint + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_NAME))) + + self.assertIsNotNone(model) + + @require_accelerate + @mark.accelerate_tests + def test_from_pretrained_low_cpu_mem_usage_functional(self): + # test that we can use `from_pretrained(..., low_cpu_mem_usage=True)` with normal and + # sharded models + + mnames = [ + "hf-internal-testing/tiny-random-bert-sharded", + "hf-internal-testing/tiny-random-bert", + ] + for mname in mnames: + _ = BertModel.from_pretrained(mname, low_cpu_mem_usage=True) + + @require_usr_bin_time + @require_accelerate + @mark.accelerate_tests + def test_from_pretrained_low_cpu_mem_usage_measured(self): + # test that `from_pretrained(..., low_cpu_mem_usage=True)` uses less cpu memory than default + + mname = "bert-base-cased" + + preamble = "from transformers import AutoModel" + one_liner_str = f'{preamble}; AutoModel.from_pretrained("{mname}", low_cpu_mem_usage=False)' + max_rss_normal = self.python_one_liner_max_rss(one_liner_str) + # print(f"{max_rss_normal=}") + + one_liner_str = f'{preamble}; AutoModel.from_pretrained("{mname}", low_cpu_mem_usage=True)' + max_rss_low_mem = self.python_one_liner_max_rss(one_liner_str) + # print(f"{max_rss_low_mem=}") + + diff_bytes = max_rss_normal - max_rss_low_mem + diff_percent = diff_bytes / max_rss_low_mem + # print(f"{diff_bytes=}, {diff_percent=}") + # ideally we would compare that the diff is close to ~1x checkpoint size in bytes, but + # measuring cpu memory on linux is very tricky and inconsistent, so instead let's check that + # it's at least 15% less cpu memory consumed + + self.assertGreater( + diff_percent, + 0.15, + "should use less CPU memory for low_cpu_mem_usage=True, " + f"but got max_rss_normal={max_rss_normal} and max_rss_low_mem={max_rss_low_mem}", + ) + + # if you want to compare things manually, let's first look at the size of the model in bytes + # model = BertModel.from_pretrained(mname, low_cpu_mem_usage=False) + # total_numel = sum(dict((p.data_ptr(), p.numel()) for p in model.parameters()).values()) + # total_bytes = total_numel * 4 # 420MB + # Now the diff_bytes should be very close to total_bytes, but the reports are inconsistent. + # The easiest way to test this is to switch the model and torch.load to do all the work on + # gpu - that way one can measure exactly the total and peak memory used. Perhaps once we add + # functionality to load models directly on gpu, this test can be rewritten to use torch's + # cuda memory tracking and then we should be able to do a much more precise test. + + @require_accelerate + @mark.accelerate_tests + @require_torch_multi_gpu + @slow + def test_model_parallelism_gpt2(self): + device_map = {"transformer.wte": 0, "transformer.wpe": 0, "lm_head": 0, "transformer.ln_f": 1} + for i in range(12): + device_map[f"transformer.h.{i}"] = 0 if i <= 5 else 1 + + model = AutoModelForCausalLM.from_pretrained("gpt2", device_map=device_map) + + tokenizer = AutoTokenizer.from_pretrained("gpt2") + inputs = tokenizer("Hello, my name is", return_tensors="pt") + output = model.generate(inputs["input_ids"].to(0)) + + text_output = tokenizer.decode(output[0].tolist()) + self.assertEqual(text_output, "Hello, my name is John. I'm a writer, and I'm a writer. I'm") + + @require_accelerate + @mark.accelerate_tests + @require_torch_gpu + def test_from_pretrained_disk_offload_task_model(self): + model = AutoModel.from_pretrained("hf-internal-testing/tiny-random-gpt2") + device_map = { + "transformer.wte": 0, + "transformer.wpe": 0, + "transformer.h.0": "cpu", + "transformer.h.1": "cpu", + "transformer.h.2": "cpu", + "transformer.h.3": "disk", + "transformer.h.4": "disk", + "transformer.ln_f": 0, + "lm_head": 0, + } + with tempfile.TemporaryDirectory() as tmp_dir: + inputs = torch.tensor([[1, 2, 3]]).to(0) + + model.save_pretrained(tmp_dir) + new_model = AutoModelForCausalLM.from_pretrained(tmp_dir).to(0) + outputs1 = new_model.to(0)(inputs) + + offload_folder = os.path.join(tmp_dir, "offload") + new_model_with_offload = AutoModelForCausalLM.from_pretrained( + tmp_dir, device_map=device_map, offload_folder=offload_folder + ) + outputs2 = new_model_with_offload(inputs) + + self.assertTrue(torch.allclose(outputs1.logits.cpu(), outputs2.logits.cpu())) + + # With state dict temp offload + offload_folder = os.path.join(tmp_dir, "offload") + new_model_with_offload = AutoModelForCausalLM.from_pretrained( + tmp_dir, + device_map=device_map, + offload_folder=offload_folder, + offload_state_dict=True, + ) + outputs2 = new_model_with_offload(inputs) + + self.assertTrue(torch.allclose(outputs1.logits.cpu(), outputs2.logits.cpu())) + + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Under the mock environment we get a 500 error when trying to reach the model. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + # This check we did call the fake head request + mock_head.assert_called() + + def test_load_from_one_file(self): + try: + tmp_file = tempfile.mktemp() + with open(tmp_file, "wb") as f: + http_get( + "https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/pytorch_model.bin", f + ) + + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + _ = BertModel.from_pretrained(tmp_file, config=config) + finally: + os.remove(tmp_file) + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + _ = BertModel.from_pretrained( + "https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/pytorch_model.bin", config=config + ) + + @require_safetensors + def test_use_safetensors(self): + # test nice error message if no safetensor files available + with self.assertRaises(OSError) as env_error: + AutoModel.from_pretrained("hf-internal-testing/tiny-random-RobertaModel", use_safetensors=True) + + self.assertTrue( + "model.safetensors or model.safetensors.index.json and thus cannot be loaded with `safetensors`" + in str(env_error.exception) + ) + + # test that error if only safetensors is available + with self.assertRaises(OSError) as env_error: + BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors", use_safetensors=False) + + self.assertTrue("does not appear to have a file named pytorch_model.bin" in str(env_error.exception)) + + # test that only safetensors if both available and use_safetensors=False + with tempfile.TemporaryDirectory() as tmp_dir: + CLIPTextModel.from_pretrained( + "hf-internal-testing/diffusers-stable-diffusion-tiny-all", + subfolder="text_encoder", + use_safetensors=False, + cache_dir=tmp_dir, + ) + + all_downloaded_files = glob.glob(os.path.join(tmp_dir, "*", "snapshots", "*", "*", "*")) + self.assertTrue(any(f.endswith("bin") for f in all_downloaded_files)) + self.assertFalse(any(f.endswith("safetensors") for f in all_downloaded_files)) + + # test that no safetensors if both available and use_safetensors=True + with tempfile.TemporaryDirectory() as tmp_dir: + CLIPTextModel.from_pretrained( + "hf-internal-testing/diffusers-stable-diffusion-tiny-all", + subfolder="text_encoder", + use_safetensors=True, + cache_dir=tmp_dir, + ) + + all_downloaded_files = glob.glob(os.path.join(tmp_dir, "*", "snapshots", "*", "*", "*")) + self.assertTrue(any(f.endswith("safetensors") for f in all_downloaded_files)) + self.assertFalse(any(f.endswith("bin") for f in all_downloaded_files)) + + @require_safetensors + def test_safetensors_save_and_load(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, safe_serialization=True) + # No pytorch_model.bin file, only a model.safetensors + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME))) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_NAME))) + + new_model = BertModel.from_pretrained(tmp_dir) + + # Check models are equal + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + @require_safetensors + def test_safetensors_load_from_hub(self): + safetensors_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors") + pytorch_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Check models are equal + for p1, p2 in zip(safetensors_model.parameters(), pytorch_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + @require_safetensors + def test_safetensors_save_and_load_sharded(self): + model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, safe_serialization=True, max_shard_size="100kB") + # No pytorch_model.bin index file, only a model.safetensors index + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_INDEX_NAME))) + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_INDEX_NAME))) + # No regular weights file + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, WEIGHTS_NAME))) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME))) + + new_model = BertModel.from_pretrained(tmp_dir) + + # Check models are equal + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + @require_safetensors + def test_safetensors_load_from_hub_sharded(self): + safetensors_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded-safetensors") + pytorch_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded") + + # Check models are equal + for p1, p2 in zip(safetensors_model.parameters(), pytorch_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + def test_base_model_to_head_model_load(self): + base_model = BaseModel(PretrainedConfig()) + with tempfile.TemporaryDirectory() as tmp_dir: + base_model.save_pretrained(tmp_dir) + + # Can load a base model in a model with head + model = ModelWithHead.from_pretrained(tmp_dir) + for p1, p2 in zip(model.base.parameters(), base_model.parameters()): + self.assertTrue(torch.allclose(p1, p2)) + + # It doesn't work if the state dict has a mix of keys of the head and base without prefix though. + base_state_dict = base_model.state_dict() + head_state_dict = model.state_dict() + base_state_dict["linear2.weight"] = head_state_dict["linear2.weight"] + base_state_dict["linear2.bias"] = head_state_dict["linear2.bias"] + torch.save(base_state_dict, os.path.join(tmp_dir, WEIGHTS_NAME)) + + with self.assertRaisesRegex( + ValueError, "The state dictionary of the model you are trying to load is corrupted." + ): + _ = ModelWithHead.from_pretrained(tmp_dir) + + @require_torch_gpu + @slow + def test_pretrained_low_mem_new_config(self): + # Checking for 1 model(the same one which was described in the issue) . + model_ids = ["gpt2"] + + for model_id in model_ids: + model_config = AutoConfig.from_pretrained(pretrained_model_name_or_path=model_id) + model_config.n_layer = 48 + model_config.n_head = 25 + model_config.n_embd = 1600 + model = AutoModelForCausalLM.from_pretrained( + pretrained_model_name_or_path=model_id, + config=model_config, + ignore_mismatched_sizes=True, + torch_dtype=torch.float16, + low_cpu_mem_usage=True, + ) + model_ref = AutoModelForCausalLM.from_pretrained(pretrained_model_name_or_path=model_id) + + self.assertEqual(model.__class__.__name__, model_ref.__class__.__name__) + + +@require_torch +@is_staging_test +class ModelPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-model") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-model-org") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-dynamic-model") + except HTTPError: + pass + + def test_push_to_hub(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = BertModel(config) + model.push_to_hub("test-model", use_auth_token=self._token) + + new_model = BertModel.from_pretrained(f"{USER}/test-model") + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + # Reset repo + delete_repo(token=self._token, repo_id="test-model") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, repo_id="test-model", push_to_hub=True, use_auth_token=self._token) + + new_model = BertModel.from_pretrained(f"{USER}/test-model") + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + def test_push_to_hub_in_organization(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = BertModel(config) + model.push_to_hub("valid_org/test-model-org", use_auth_token=self._token) + + new_model = BertModel.from_pretrained("valid_org/test-model-org") + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-model-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained( + tmp_dir, push_to_hub=True, use_auth_token=self._token, repo_id="valid_org/test-model-org" + ) + + new_model = BertModel.from_pretrained("valid_org/test-model-org") + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + def test_push_to_hub_dynamic_model(self): + CustomConfig.register_for_auto_class() + CustomModel.register_for_auto_class() + + config = CustomConfig(hidden_size=32) + model = CustomModel(config) + + model.push_to_hub("test-dynamic-model", use_auth_token=self._token) + # checks + self.assertDictEqual( + config.auto_map, + {"AutoConfig": "custom_configuration.CustomConfig", "AutoModel": "custom_modeling.CustomModel"}, + ) + + new_model = AutoModel.from_pretrained(f"{USER}/test-dynamic-model", trust_remote_code=True) + # Can't make an isinstance check because the new_model is from the CustomModel class of a dynamic module + self.assertEqual(new_model.__class__.__name__, "CustomModel") + for p1, p2 in zip(model.parameters(), new_model.parameters()): + self.assertTrue(torch.equal(p1, p2)) + + config = AutoConfig.from_pretrained(f"{USER}/test-dynamic-model", trust_remote_code=True) + new_model = AutoModel.from_config(config, trust_remote_code=True) + self.assertEqual(new_model.__class__.__name__, "CustomModel") diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_flax_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_flax_common.py new file mode 100644 index 0000000000000000000000000000000000000000..058d7906113dcddb8c8fda93833f7f0f2e6cc50c --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_flax_common.py @@ -0,0 +1,1318 @@ +# Copyright 2020 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import inspect +import json +import random +import tempfile +import unittest +from typing import List, Tuple + +import numpy as np +from huggingface_hub import HfFolder, delete_repo +from requests.exceptions import HTTPError + +import transformers +from transformers import BertConfig, is_flax_available, is_torch_available +from transformers.models.auto import get_values +from transformers.testing_utils import ( + TOKEN, + USER, + CaptureLogger, + is_pt_flax_cross_test, + is_staging_test, + require_flax, + torch_device, +) +from transformers.utils import CONFIG_NAME, GENERATION_CONFIG_NAME, logging +from transformers.utils.generic import ModelOutput + + +if is_flax_available(): + import os + + import jax + import jax.numpy as jnp + from flax.core.frozen_dict import FrozenDict, freeze, unfreeze + from flax.serialization import from_bytes + from flax.traverse_util import flatten_dict, unflatten_dict + + from transformers import ( + FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + FLAX_MODEL_MAPPING, + FlaxAutoModel, + FlaxAutoModelForSequenceClassification, + FlaxBertModel, + ) + from transformers.modeling_flax_pytorch_utils import ( + convert_pytorch_state_dict_to_flax, + load_flax_weights_in_pytorch_model, + ) + from transformers.modeling_flax_utils import FLAX_WEIGHTS_INDEX_NAME, FLAX_WEIGHTS_NAME + + os.environ["XLA_PYTHON_CLIENT_MEM_FRACTION"] = "0.12" # assumed parallelism: 8 + +if is_torch_available(): + import torch + + +def _config_zero_init(config): + configs_no_init = copy.deepcopy(config) + for key in configs_no_init.__dict__.keys(): + if "_range" in key or "_std" in key or "initializer_factor" in key: + setattr(configs_no_init, key, 1e-10) + return configs_no_init + + +def ids_tensor(shape, vocab_size, rng=None): + """Creates a random int32 tensor of the shape within the vocab size.""" + if rng is None: + rng = random.Random() + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.randint(0, vocab_size - 1)) + + output = np.array(values, dtype=jnp.int32).reshape(shape) + + return output + + +def floats_tensor(shape, scale=1.0, rng=None, name=None): + """Creates a random float32 tensor""" + if rng is None: + rng = random.Random() + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.random() * scale) + + return np.array(values, dtype=jnp.float32).reshape(shape) + + +def random_attention_mask(shape, rng=None): + attn_mask = ids_tensor(shape, vocab_size=2, rng=rng) + # make sure that at least one token is attended to for each batch + attn_mask[:, -1] = 1 + return attn_mask + + +def get_params(params, from_head_prefix=None): + """Function extracts relevant parameters into flatten dict from model params, + appends batch normalization statistics if present""" + + # If Both parameters and batch normalization statistics are present + if "batch_stats" in params: + # Extract only parameters for the specified head prefix (if specified) and add batch statistics + if from_head_prefix is not None: + extracted_params = flatten_dict(unfreeze(params["params"][from_head_prefix])) + extracted_params.update(flatten_dict(params["batch_stats"][from_head_prefix])) + else: + extracted_params = flatten_dict(unfreeze(params["params"])) + extracted_params.update(flatten_dict(params["batch_stats"])) + + # Only parameters are present + else: + if from_head_prefix is not None: + extracted_params = flatten_dict(unfreeze(params[from_head_prefix])) + else: + extracted_params = flatten_dict(unfreeze(params)) + + return extracted_params + + +@require_flax +class FlaxModelTesterMixin: + model_tester = None + all_model_classes = () + test_mismatched_shapes = True + is_encoder_decoder = False + test_head_masking = False + has_attentions = True + + def _prepare_for_class(self, inputs_dict, model_class): + inputs_dict = copy.deepcopy(inputs_dict) + + # hack for now until we have AutoModel classes + if "ForMultipleChoice" in model_class.__name__: + inputs_dict = { + k: jnp.broadcast_to(v[:, None], (v.shape[0], self.model_tester.num_choices, v.shape[-1])) + if isinstance(v, (jnp.ndarray, np.ndarray)) and k != "indices_prng_key" + else v + for k, v in inputs_dict.items() + } + + return inputs_dict + + def assert_almost_equals(self, a: np.ndarray, b: np.ndarray, tol: float): + diff = np.abs((a - b)).max() + self.assertLessEqual(diff, tol, f"Difference between torch and flax is {diff} (>= {tol}).") + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + tuple_output = model(**tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(**dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assert_almost_equals(jnp.nan_to_num(tuple_object), jnp.nan_to_num(dict_object), 1e-5) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + model = model_class(config) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + # (Copied from tests.test_modeling_common.ModelTesterMixin.check_pt_flax_outputs) + def check_pt_flax_outputs(self, fx_outputs, pt_outputs, model_class, tol=1e-5, name="outputs", attributes=None): + """ + Args: + model_class: The class of the model that is currently testing. For example, ..., etc. + Currently unused, but it could make debugging easier and faster. + + names: A string, or a list of strings. These specify what fx_outputs/pt_outputs represent in the model outputs. + Currently unused, but in the future, we could use this information to make the error message clearer + by giving the name(s) of the output tensor(s) with large difference(s) between PT and Flax. + """ + + self.assertEqual(type(name), str) + if attributes is not None: + self.assertEqual(type(attributes), tuple, f"{name}: The argument `attributes` should be a `tuple`") + + # Allow `ModelOutput` (e.g. `CLIPOutput` has `text_model_output` and `vision_model_output`). + if isinstance(fx_outputs, ModelOutput): + self.assertTrue( + isinstance(pt_outputs, ModelOutput), + f"{name}: `pt_outputs` should an instance of `ModelOutput` when `fx_outputs` is", + ) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys, f"{name}: Output keys differ between Flax and PyTorch") + + # convert to the case of `tuple` + # appending each key to the current (string) `name` + attributes = tuple([f"{name}.{k}" for k in fx_keys]) + self.check_pt_flax_outputs( + fx_outputs.to_tuple(), pt_outputs.to_tuple(), model_class, tol=tol, name=name, attributes=attributes + ) + + # Allow `list` (e.g. `TransfoXLModelOutput.mems` is a list of tensors.) + elif type(fx_outputs) in [tuple, list]: + self.assertEqual( + type(fx_outputs), type(pt_outputs), f"{name}: Output types differ between Flax and PyTorch" + ) + self.assertEqual( + len(fx_outputs), len(pt_outputs), f"{name}: Output lengths differ between Flax and PyTorch" + ) + + if attributes is not None: + # case 1: each output has assigned name (e.g. a tuple form of a `ModelOutput`) + self.assertEqual( + len(attributes), + len(fx_outputs), + f"{name}: The tuple `attributes` should have the same length as `fx_outputs`", + ) + else: + # case 2: each output has no assigned name (e.g. hidden states of each layer) -> add an index to `name` + attributes = tuple([f"{name}_{idx}" for idx in range(len(fx_outputs))]) + + for fx_output, pt_output, attr in zip(fx_outputs, pt_outputs, attributes): + self.check_pt_flax_outputs(fx_output, pt_output, model_class, tol=tol, name=attr) + + elif isinstance(fx_outputs, jnp.ndarray): + self.assertTrue( + isinstance(pt_outputs, torch.Tensor), f"{name}: `pt_outputs` should a tensor when `fx_outputs` is" + ) + + # Using `np.asarray` gives `ValueError: assignment destination is read-only` at the line `fx_outputs[fx_nans] = 0`. + fx_outputs = np.array(fx_outputs) + pt_outputs = pt_outputs.detach().to("cpu").numpy() + + self.assertEqual( + fx_outputs.shape, pt_outputs.shape, f"{name}: Output shapes differ between Flax and PyTorch" + ) + + # deal with NumPy's scalars to make replacing nan values by 0 work. + if np.isscalar(fx_outputs): + fx_outputs = np.array([fx_outputs]) + pt_outputs = np.array([pt_outputs]) + + fx_nans = np.isnan(fx_outputs) + pt_nans = np.isnan(pt_outputs) + + pt_outputs[fx_nans] = 0 + fx_outputs[fx_nans] = 0 + pt_outputs[pt_nans] = 0 + fx_outputs[pt_nans] = 0 + + max_diff = np.amax(np.abs(fx_outputs - pt_outputs)) + self.assertLessEqual( + max_diff, tol, f"{name}: Difference between PyTorch and Flax is {max_diff} (>= {tol})." + ) + else: + raise ValueError( + "`fx_outputs` should be an instance of `ModelOutput`, a `tuple`, or an instance of `jnp.ndarray`. Got" + f" {type(fx_outputs)} instead." + ) + + @is_pt_flax_cross_test + def test_equivalence_pt_to_flax(self): + # It might be better to put this inside the for loop below (because we modify the config there). + # But logically, it is fine. + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist(), device=torch_device) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + fx_model = model_class(config, dtype=jnp.float32) + + fx_state = convert_pytorch_state_dict_to_flax(pt_model.state_dict(), fx_model) + fx_model.params = fx_state + + # send pytorch model to the correct device + pt_model.to(torch_device) + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs) + fx_outputs = fx_model(**prepared_inputs_dict) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs, model_class) + + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + fx_model_loaded = model_class.from_pretrained(tmpdirname, from_pt=True) + + fx_outputs_loaded = fx_model_loaded(**prepared_inputs_dict) + + fx_keys = tuple([k for k, v in fx_outputs_loaded.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs_loaded, pt_outputs, model_class) + + @is_pt_flax_cross_test + def test_equivalence_flax_to_pt(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + pt_inputs = {k: torch.tensor(v.tolist(), device=torch_device) for k, v in prepared_inputs_dict.items()} + + # load corresponding PyTorch class + pt_model_class_name = model_class.__name__[4:] # Skip the "Flax" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + pt_model = pt_model_class(config).eval() + # Flax models don't use the `use_cache` option and cache is not returned as a default. + # So we disable `use_cache` here for PyTorch model. + pt_model.config.use_cache = False + fx_model = model_class(config, dtype=jnp.float32) + + pt_model = load_flax_weights_in_pytorch_model(pt_model, fx_model.params) + + # make sure weights are tied in PyTorch + pt_model.tie_weights() + + # send pytorch model to the correct device + pt_model.to(torch_device) + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs) + fx_outputs = fx_model(**prepared_inputs_dict) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs, model_class) + + with tempfile.TemporaryDirectory() as tmpdirname: + fx_model.save_pretrained(tmpdirname) + pt_model_loaded = pt_model_class.from_pretrained(tmpdirname, from_flax=True) + + # send pytorch model to the correct device + pt_model_loaded.to(torch_device) + pt_model_loaded.eval() + + with torch.no_grad(): + pt_outputs_loaded = pt_model_loaded(**pt_inputs) + + fx_keys = tuple([k for k, v in fx_outputs.items() if v is not None]) + pt_keys = tuple([k for k, v in pt_outputs_loaded.items() if v is not None]) + + self.assertEqual(fx_keys, pt_keys) + self.check_pt_flax_outputs(fx_outputs, pt_outputs_loaded, model_class) + + def test_from_pretrained_save_pretrained(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + model = model_class(config) + + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + outputs = model(**prepared_inputs_dict).to_tuple() + + # verify that normal save_pretrained works as expected + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + + # the config file (and the generation config file, if it can generate) should be saved + self.assertTrue(os.path.exists(os.path.join(tmpdirname, CONFIG_NAME))) + self.assertEqual( + model.can_generate(), os.path.exists(os.path.join(tmpdirname, GENERATION_CONFIG_NAME)) + ) + + model_loaded = model_class.from_pretrained(tmpdirname) + + outputs_loaded = model_loaded(**prepared_inputs_dict).to_tuple() + for output_loaded, output in zip(outputs_loaded, outputs): + self.assert_almost_equals(output_loaded, output, 1e-3) + + # verify that save_pretrained for distributed training + # with `params=params` works as expected + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, params=model.params) + model_loaded = model_class.from_pretrained(tmpdirname) + + outputs_loaded = model_loaded(**prepared_inputs_dict).to_tuple() + for output_loaded, output in zip(outputs_loaded, outputs): + self.assert_almost_equals(output_loaded, output, 1e-3) + + def test_save_load_from_base(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = base_class(config) + base_params = get_params(model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + head_model = model_class.from_pretrained(tmpdirname) + + base_param_from_head = get_params(head_model.params, from_head_prefix=head_model.base_model_prefix) + + for key in base_param_from_head.keys(): + max_diff = (base_params[key] - base_param_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_save_load_to_base(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + base_params_from_head = get_params(model.params, from_head_prefix=model.base_model_prefix) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname) + + base_params = get_params(base_model.params) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + @is_pt_flax_cross_test + def test_save_load_from_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = base_class(config) + base_params = get_params(model.params) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, base_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + # save pt model + pt_model.save_pretrained(tmpdirname) + head_model = model_class.from_pretrained(tmpdirname, from_pt=True) + + base_param_from_head = get_params(head_model.params, from_head_prefix=head_model.base_model_prefix) + + for key in base_param_from_head.keys(): + max_diff = (base_params[key] - base_param_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + @is_pt_flax_cross_test + def test_save_load_to_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + base_params_from_head = get_params(model.params, from_head_prefix=model.base_model_prefix) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, model_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname, from_pt=True) + + base_params = get_params(base_model.params) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + @is_pt_flax_cross_test + def test_save_load_bf16_to_base_pt(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + base_class = FLAX_MODEL_MAPPING[config.__class__] + + for model_class in self.all_model_classes: + if model_class == base_class: + continue + + model = model_class(config) + model.params = model.to_bf16(model.params) + base_params_from_head = get_params(model.params, from_head_prefix=model.base_model_prefix) + + # convert Flax model to PyTorch model + pt_model_class = getattr(transformers, model_class.__name__[4:]) # Skip the "Flax" at the beginning + pt_model = pt_model_class(config).eval() + pt_model = load_flax_weights_in_pytorch_model(pt_model, model.params) + + # check that all base model weights are loaded correctly + with tempfile.TemporaryDirectory() as tmpdirname: + pt_model.save_pretrained(tmpdirname) + base_model = base_class.from_pretrained(tmpdirname, from_pt=True) + + base_params = get_params(base_model.params) + + for key in base_params_from_head.keys(): + max_diff = (base_params[key] - base_params_from_head[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_jit_compilation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + with self.subTest(model_class.__name__): + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + @jax.jit + def model_jitted(input_ids, attention_mask=None, **kwargs): + return model(input_ids=input_ids, attention_mask=attention_mask, **kwargs) + + with self.subTest("JIT Enabled"): + jitted_outputs = model_jitted(**prepared_inputs_dict).to_tuple() + + with self.subTest("JIT Disabled"): + with jax.disable_jit(): + outputs = model_jitted(**prepared_inputs_dict).to_tuple() + + self.assertEqual(len(outputs), len(jitted_outputs)) + for jitted_output, output in zip(jitted_outputs, outputs): + self.assertEqual(jitted_output.shape, output.shape) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.__call__) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = [ + "input_ids", + "attention_mask", + "decoder_input_ids", + "decoder_attention_mask", + ] + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + else: + expected_arg_names = ["input_ids", "attention_mask"] + self.assertListEqual(arg_names[:2], expected_arg_names) + + def test_naming_convention(self): + for model_class in self.all_model_classes: + model_class_name = model_class.__name__ + module_class_name = ( + model_class_name[:-5] + "Module" if model_class_name[-5:] == "Model" else model_class_name + "Module" + ) + bert_modeling_flax_module = __import__(model_class.__module__, fromlist=[module_class_name]) + module_cls = getattr(bert_modeling_flax_module, module_class_name) + + self.assertIsNotNone(module_cls) + + def test_hidden_states_output(self): + def check_hidden_states_output(inputs_dict, config, model_class): + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + hidden_states = outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states + + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + self.assertEqual(len(hidden_states), expected_num_layers) + + if hasattr(self.model_tester, "encoder_seq_length"): + seq_length = self.model_tester.encoder_seq_length + else: + seq_length = self.model_tester.seq_length + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [seq_length, self.model_tester.hidden_size], + ) + + if config.is_encoder_decoder: + hidden_states = outputs.decoder_hidden_states + + self.assertIsInstance(hidden_states, (list, tuple)) + self.assertEqual(len(hidden_states), expected_num_layers) + seq_len = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_len) + + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [decoder_seq_length, self.model_tester.hidden_size], + ) + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(inputs_dict, config, model_class) + + # check that output_hidden_states also work using config + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + + check_hidden_states_output(inputs_dict, config, model_class) + + def test_attention_outputs(self): + if not self.has_attentions: + self.skipTest(reason="Model does not output attentions") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + seq_length = getattr(self.model_tester, "seq_length", None) + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", seq_length) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", seq_length) + decoder_key_length = getattr(self.model_tester, "decoder_key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + # check that output_attentions also work using config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + out_len = len(outputs) + + if self.is_encoder_decoder: + correct_outlen = 5 + + # Question Answering model returns start_logits and end_logits + if model_class in get_values(FLAX_MODEL_FOR_QUESTION_ANSWERING_MAPPING): + correct_outlen += 1 # start_logits and end_logits instead of only 1 output + + self.assertEqual(out_len, correct_outlen) + + # decoder attentions + decoder_attentions = outputs.decoder_attentions + self.assertIsInstance(decoder_attentions, (list, tuple)) + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + # cross attentions + cross_attentions = outputs.cross_attentions + self.assertIsInstance(cross_attentions, (list, tuple)) + self.assertEqual(len(cross_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(cross_attentions[0].shape[-3:]), + [ + self.model_tester.num_attention_heads, + decoder_seq_length, + encoder_key_length, + ], + ) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = True + model = model_class(config) + outputs = model(**self._prepare_for_class(inputs_dict, model_class)) + + if hasattr(self.model_tester, "num_hidden_states_types"): + added_hidden_states = self.model_tester.num_hidden_states_types + elif self.is_encoder_decoder: + added_hidden_states = 2 + else: + added_hidden_states = 1 + self.assertEqual(out_len + added_hidden_states, len(outputs)) + + self_attentions = outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions + self.assertEqual(len(self_attentions), self.model_tester.num_hidden_layers) + + self.assertListEqual( + list(self_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + def test_load_with_mismatched_shapes(self): + if not self.test_mismatched_shapes: + return + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class not in get_values(FLAX_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING): + continue + + with self.subTest(msg=f"Testing {model_class}"): + with tempfile.TemporaryDirectory() as tmp_dir: + model = model_class(config) + model.save_pretrained(tmp_dir) + + # Fails when we don't set ignore_mismatched_sizes=True + with self.assertRaises(ValueError): + new_model = FlaxAutoModelForSequenceClassification.from_pretrained(tmp_dir, num_labels=42) + with self.assertRaises(ValueError): + new_model_without_prefix = FlaxAutoModel.from_pretrained(tmp_dir, vocab_size=10) + + logger = logging.get_logger("transformers.modeling_flax_utils") + with CaptureLogger(logger) as cl: + new_model = FlaxAutoModelForSequenceClassification.from_pretrained( + tmp_dir, num_labels=42, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + + logits = new_model(**inputs_dict)["logits"] + self.assertEqual(logits.shape[1], 42) + + with CaptureLogger(logger) as cl: + new_model_without_prefix = FlaxAutoModel.from_pretrained( + tmp_dir, vocab_size=10, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + input_ids = ids_tensor((2, 8), 10) + if self.is_encoder_decoder: + new_model_without_prefix(input_ids, decoder_input_ids=input_ids) + else: + new_model_without_prefix(input_ids) + + def test_default_params_dtype(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + # check if all params are still in float32 when dtype of computation is half-precision + model = model_class(config, dtype=jnp.float16) + types = jax.tree_util.tree_map(lambda x: x.dtype, model.params) + types = flatten_dict(types) + + for name, type_ in types.items(): + self.assertEquals(type_, jnp.float32, msg=f"param {name} is not initialized in fp32.") + + def test_to_bf16(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + # cast all params to bf16 + params = model.to_bf16(model.params) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + # test if all params are in bf16 + for name, type_ in types.items(): + self.assertEqual(type_, jnp.bfloat16, msg=f"param {name} is not in bf16.") + + # test masking + flat_params = flatten_dict(params) + key = random.choice(list(flat_params.keys())) # choose a random param + mask = {path: path != key for path in flat_params} # don't cast the key + mask = unflatten_dict(mask) + + params = model.to_bf16(model.params, mask) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + # test if all params are in bf16 except key + for name, type_ in types.items(): + if name == key: + self.assertEqual(type_, jnp.float32, msg=f"param {name} should be in fp32.") + else: + self.assertEqual(type_, jnp.bfloat16, msg=f"param {name} is not in bf16.") + + def test_to_fp16(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + # cast all params to fp16 + params = model.to_fp16(model.params) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + # test if all params are in fp16 + for name, type_ in types.items(): + self.assertEqual(type_, jnp.float16, msg=f"param {name} is not in fp16.") + + # test masking + flat_params = flatten_dict(params) + key = random.choice(list(flat_params.keys())) # choose a random param + mask = {path: path != key for path in flat_params} # don't cast the key + mask = unflatten_dict(mask) + + params = model.to_fp16(model.params, mask) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + # test if all params are in fp16 except key + for name, type_ in types.items(): + if name == key: + self.assertEqual(type_, jnp.float32, msg=f"param {name} should be in fp32.") + else: + self.assertEqual(type_, jnp.float16, msg=f"param {name} is not in fp16.") + + def test_to_fp32(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + # cast all params to fp16 and back to fp32 + params = model.to_fp16(model.params) + params = model.to_fp32(params) + + # test if all params are in fp32 + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + for name, type_ in types.items(): + self.assertEqual(type_, jnp.float32, msg=f"param {name} is not in fp32.") + + # test masking + flat_params = flatten_dict(params) + key = random.choice(list(flat_params.keys())) # choose a random param + mask = {path: path != key for path in flat_params} # don't cast the key + mask = unflatten_dict(mask) + + # cast to fp16 and back to fp32 with mask + params = model.to_fp16(model.params) + params = model.to_fp32(params, mask) + + # test if all params are in fp32 except key + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, params)) + for name, type_ in types.items(): + if name == key: + self.assertEqual(type_, jnp.float16, msg=f"param {name} should be in fp16.") + else: + self.assertEqual(type_, jnp.float32, msg=f"param {name} is not in fp32.") + + def test_save_load_in_fp16(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + # convert weights to fp16 and save + params = model.to_fp16(model.params) + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, params=params) + + # load the weights again and check if they are still in fp16 + model = model_class.from_pretrained(tmpdirname) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, model.params)) + for name, type_ in types.items(): + self.assertEqual(type_, jnp.float16, msg=f"param {name} is not in fp16.") + + def test_save_load_in_bf16(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + # convert weights to bf16 and save + params = model.to_bf16(model.params) + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, params=params) + + # load the weights again and check if they are still in fp16 + model = model_class.from_pretrained(tmpdirname) + types = flatten_dict(jax.tree_util.tree_map(lambda x: x.dtype, model.params)) + for name, type_ in types.items(): + self.assertEqual(type_, jnp.bfloat16, msg=f"param {name} is not in bf16.") + + def test_model_main_input_name(self): + for model_class in self.all_model_classes: + model_signature = inspect.signature(getattr(model_class, "__call__")) + # The main input is the name of the argument after `self` + observed_main_input_name = list(model_signature.parameters.keys())[1] + self.assertEqual(model_class.main_input_name, observed_main_input_name) + + def test_headmasking(self): + if not self.test_head_masking: + return + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + def _prepare_layer_head_mask(i, attention_heads, num_hidden_layers): + if i == 0: + return np.concatenate([np.zeros(1, dtype=jnp.int32), np.ones(attention_heads - 1, dtype=jnp.int32)]) + if i == num_hidden_layers - 1: + return np.concatenate([np.zeros(attention_heads - 1, dtype=jnp.int32), np.ones(1, dtype=jnp.int32)]) + return np.ones(attention_heads, dtype=jnp.int32) + + for model_class in self.all_model_classes: + model = model_class(config) + + inputs_dict["output_attentions"] = True + inputs_dict["output_hidden_states"] = False + inputs = self._prepare_for_class(inputs_dict, model_class).copy() + # Prepare head mask + inputs["head_mask"] = np.stack( + [ + _prepare_layer_head_mask(i, config.num_attention_heads, config.num_hidden_layers) + for i in range(config.num_hidden_layers) + ] + ) + outputs = model(**inputs) + + def _check_attentions_validity(attentions): + # Remove NaN + for t in attentions: + # Check we don't have more than 25% nans (arbitrary) + self.assertLess(np.isnan(t).sum(), t.size / 4) + attentions = [np.where(np.isnan(t), 0.0, t) for t in attentions] + + self.assertAlmostEqual(attentions[0][..., 0, :, :].sum(), 0.0) + self.assertNotEqual(attentions[0][..., -1, :, :].sum(), 0.0) + if len(attentions) > 2: # encoder-decodere models have only 2 layers in each modules + self.assertNotEqual(attentions[1][..., 0, :, :].sum(), 0.0) + self.assertAlmostEqual(attentions[-1][..., -2, :, :].sum(), 0.0) + self.assertNotEqual(attentions[-1][..., -1, :, :].sum(), 0.0) + + if model.config.is_encoder_decoder: + raise NotImplementedError("The test has not been implemented for encoder-decoder models yet.") + else: + _check_attentions_validity(outputs.attentions) + + def test_no_automatic_init(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + for model_class in self.all_model_classes: + model = model_class(config, _do_init=False) + + # Check that accesing parmas raises an ValueError when _do_init is False + with self.assertRaises(ValueError): + params = model.params + + # Check if we params can be properly initialized when calling init_weights + params = model.init_weights(model.key, model.input_shape) + self.assertIsInstance(params, FrozenDict) + # Check if all required parmas are initialized + keys = set(flatten_dict(unfreeze(params)).keys()) + self.assertTrue(all(k in keys for k in model.required_params)) + # Check if the shapes match + flat_params = flatten_dict(unfreeze(params)) + for k, v in flatten_dict(unfreeze(model.params_shape_tree)).items(): + self.assertEqual( + v.shape, + flat_params[k].shape, + "Shapes of {} do not match. Expecting {}, got {}.".format(k, v.shape, flat_params[k].shape), + ) + + # Check that setting params raises an ValueError when _do_init is False + with self.assertRaises(ValueError): + model.params = params + + # Check if we can do a forward pass + inputs_dict["output_hidden_states"] = True + inputs = self._prepare_for_class(inputs_dict, model_class).copy() + model(**inputs, params=params) + + def test_from_pretrained_with_no_automatic_init(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + + def _assert_all_params_initialised(model, params): + # Check if all required parmas are loaded + keys = set(flatten_dict(unfreeze(params)).keys()) + self.assertTrue(all(k in keys for k in model.required_params)) + # Check if the shapes match + flat_params = flatten_dict(unfreeze(params)) + for k, v in flatten_dict(unfreeze(model.params_shape_tree)).items(): + self.assertEqual( + v.shape, + flat_params[k].shape, + "Shapes of {} do not match. Expecting {}, got {}.".format(k, v.shape, flat_params[k].shape), + ) + + for model_class in self.all_model_classes: + # init the model + model = model_class(config) + + # save the model in the temporary directory + # load the saved model with _do_init=False + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname) + model, params = model_class.from_pretrained(tmpdirname, _do_init=False) + + # Check that accesing parmas raises an ValueError when _do_init is False + with self.assertRaises(ValueError): + params = model.params + + # Check if all required parmas are loaded + _assert_all_params_initialised(model, params) + + # Check that setting params raises an ValueError when _do_init is False + with self.assertRaises(ValueError): + model.params = params + + # Check if init_weights initializes missing keys from from_pretrained + flat_params = flatten_dict(unfreeze(params)) + random_key = random.choice(list(flat_params.keys())) + flat_params.pop(random_key) + params = freeze(unflatten_dict(flat_params)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, params=params) + model, params = model_class.from_pretrained(tmpdirname, _do_init=False) + + params = model.init_weights(model.key, model.input_shape, params=params) + # Check if all required parmas are loaded + _assert_all_params_initialised(model, params) + + def test_checkpoint_sharding_from_hub(self): + model = FlaxBertModel.from_pretrained("ArthurZ/flax-tiny-random-bert-sharded") + # the model above is the same as the model below, just a sharded version. + ref_model = FlaxBertModel.from_pretrained("hf-internal-testing/tiny-bert-flax-only") + for p1, p2 in zip(flatten_dict(model.params).values(), flatten_dict(ref_model.params).values()): + assert np.allclose(np.array(p1), np.array(p2)) + + def test_checkpoint_sharding_local(self): + model = FlaxBertModel.from_pretrained("hf-internal-testing/tiny-bert-flax-only") + + with tempfile.TemporaryDirectory() as tmp_dir: + # We use the same folder for various sizes to make sure a new save erases the old checkpoint. + for max_size in ["150kB", "150kiB", "200kB", "200kiB"]: + model.save_pretrained(tmp_dir, max_shard_size=max_size) + + # Get each shard file and its size + shard_to_size = {} + for shard in os.listdir(tmp_dir): + if shard.endswith(".msgpack"): + shard_file = os.path.join(tmp_dir, shard) + shard_to_size[shard_file] = os.path.getsize(shard_file) + + index_file = os.path.join(tmp_dir, FLAX_WEIGHTS_INDEX_NAME) + # Check there is an index but no regular weight file + self.assertTrue(os.path.isfile(index_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, FLAX_WEIGHTS_NAME))) + + # Check a file is bigger than max_size only when it has a single weight + for shard_file, size in shard_to_size.items(): + if max_size.endswith("kiB"): + max_size_int = int(max_size[:-3]) * 2**10 + else: + max_size_int = int(max_size[:-2]) * 10**3 + # Note: pickle adds some junk so the weight of the file can end up being slightly bigger than + # the size asked for (since we count parameters) + if size >= max_size_int + 50000: + with open(shard_file, "rb") as state_f: + state_file = from_bytes(FlaxBertModel, state_f.read()) + self.assertEqual(len(state_file), 1) + + # Check the index and the shard files found match + with open(index_file, "r", encoding="utf-8") as f: + index = json.loads(f.read()) + + all_shards = set(index["weight_map"].values()) + shards_found = {f for f in os.listdir(tmp_dir) if f.endswith(".msgpack")} + self.assertSetEqual(all_shards, shards_found) + + # Finally, check the model can be reloaded + new_model = FlaxBertModel.from_pretrained(tmp_dir) + for p1, p2 in zip(flatten_dict(model.params).values(), flatten_dict(new_model.params).values()): + self.assertTrue(np.allclose(np.array(p1), np.array(p2))) + + @is_pt_flax_cross_test + def test_from_sharded_pt(self): + model = FlaxBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded", from_pt=True) + ref_model = FlaxBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-fx-only") + for key, ref_val in flatten_dict(ref_model.params).items(): + val = flatten_dict(model.params)[key] + assert np.allclose(np.array(val), np.array(ref_val)) + + def test_gradient_checkpointing(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + # prepare inputs + prepared_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + remat_model = model_class(config) + + try: + remat_model.enable_gradient_checkpointing() + except NotImplementedError: + continue + + outputs = model(**prepared_inputs_dict) + remat_outputs = remat_model(**prepared_inputs_dict) + + # ensure that the dicts of outputs contain the same keys + self.assertEqual(outputs.keys(), remat_outputs.keys()) + + outputs = outputs.to_tuple() + remat_outputs = remat_outputs.to_tuple() + + # ensure that the outputs remain precisely equal + for output, remat_output in zip(outputs, remat_outputs): + self.assertTrue((output == remat_output).all()) + + +@require_flax +@is_staging_test +class FlaxModelPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-model-flax") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-model-flax-org") + except HTTPError: + pass + + def test_push_to_hub(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = FlaxBertModel(config) + model.push_to_hub("test-model-flax", use_auth_token=self._token) + + new_model = FlaxBertModel.from_pretrained(f"{USER}/test-model-flax") + + base_params = flatten_dict(unfreeze(model.params)) + new_params = flatten_dict(unfreeze(new_model.params)) + + for key in base_params.keys(): + max_diff = (base_params[key] - new_params[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + # Reset repo + delete_repo(token=self._token, repo_id="test-model-flax") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, repo_id="test-model-flax", push_to_hub=True, use_auth_token=self._token) + + new_model = FlaxBertModel.from_pretrained(f"{USER}/test-model-flax") + + base_params = flatten_dict(unfreeze(model.params)) + new_params = flatten_dict(unfreeze(new_model.params)) + + for key in base_params.keys(): + max_diff = (base_params[key] - new_params[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + def test_push_to_hub_in_organization(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = FlaxBertModel(config) + model.push_to_hub("valid_org/test-model-flax-org", use_auth_token=self._token) + + new_model = FlaxBertModel.from_pretrained("valid_org/test-model-flax-org") + + base_params = flatten_dict(unfreeze(model.params)) + new_params = flatten_dict(unfreeze(new_model.params)) + + for key in base_params.keys(): + max_diff = (base_params[key] - new_params[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-model-flax-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained( + tmp_dir, repo_id="valid_org/test-model-flax-org", push_to_hub=True, use_auth_token=self._token + ) + + new_model = FlaxBertModel.from_pretrained("valid_org/test-model-flax-org") + + base_params = flatten_dict(unfreeze(model.params)) + new_params = flatten_dict(unfreeze(new_model.params)) + + for key in base_params.keys(): + max_diff = (base_params[key] - new_params[key]).sum().item() + self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical") + + +def check_models_equal(model1, model2): + models_are_equal = True + flat_params_1 = flatten_dict(model1.params) + flat_params_2 = flatten_dict(model2.params) + for key in flat_params_1.keys(): + if np.sum(np.abs(flat_params_1[key] - flat_params_2[key])) > 1e-4: + models_are_equal = False + + return models_are_equal + + +@require_flax +class FlaxModelUtilsTest(unittest.TestCase): + def test_model_from_pretrained_subfolder(self): + config = BertConfig.from_pretrained("hf-internal-testing/tiny-bert-flax-only") + model = FlaxBertModel(config) + + subfolder = "bert" + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(os.path.join(tmp_dir, subfolder)) + + with self.assertRaises(OSError): + _ = FlaxBertModel.from_pretrained(tmp_dir) + + model_loaded = FlaxBertModel.from_pretrained(tmp_dir, subfolder=subfolder) + + self.assertTrue(check_models_equal(model, model_loaded)) + + def test_model_from_pretrained_subfolder_sharded(self): + config = BertConfig.from_pretrained("hf-internal-testing/tiny-bert-flax-only") + model = FlaxBertModel(config) + + subfolder = "bert" + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(os.path.join(tmp_dir, subfolder), max_shard_size="10KB") + + with self.assertRaises(OSError): + _ = FlaxBertModel.from_pretrained(tmp_dir) + + model_loaded = FlaxBertModel.from_pretrained(tmp_dir, subfolder=subfolder) + + self.assertTrue(check_models_equal(model, model_loaded)) + + def test_model_from_pretrained_hub_subfolder(self): + subfolder = "bert" + model_id = "hf-internal-testing/tiny-random-bert-subfolder" + + with self.assertRaises(OSError): + _ = FlaxBertModel.from_pretrained(model_id) + + model = FlaxBertModel.from_pretrained(model_id, subfolder=subfolder) + + self.assertIsNotNone(model) + + def test_model_from_pretrained_hub_subfolder_sharded(self): + subfolder = "bert" + model_id = "hf-internal-testing/tiny-random-bert-sharded-subfolder" + with self.assertRaises(OSError): + _ = FlaxBertModel.from_pretrained(model_id) + + model = FlaxBertModel.from_pretrained(model_id, subfolder=subfolder) + + self.assertIsNotNone(model) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_tf_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_tf_common.py new file mode 100644 index 0000000000000000000000000000000000000000..220560d9238a90ec3c8966f93965f2a73e62c949 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_modeling_tf_common.py @@ -0,0 +1,2554 @@ +# coding=utf-8 +# Copyright 2019 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import copy +import inspect +import json +import os +import random +import tempfile +import unittest +import unittest.mock as mock +from dataclasses import fields +from importlib import import_module +from math import isnan +from typing import List, Tuple, get_type_hints + +from datasets import Dataset +from huggingface_hub import HfFolder, Repository, delete_repo +from huggingface_hub.file_download import http_get +from requests.exceptions import HTTPError + +from transformers import is_tf_available, is_torch_available +from transformers.configuration_utils import PretrainedConfig +from transformers.models.auto import get_values +from transformers.testing_utils import ( # noqa: F401 + TOKEN, + USER, + CaptureLogger, + CaptureStdout, + _tf_gpu_memory_limit, + is_pt_tf_cross_test, + is_staging_test, + require_safetensors, + require_tf, + require_tf2onnx, + slow, + tooslow, + torch_device, +) +from transformers.utils import ( + CONFIG_NAME, + GENERATION_CONFIG_NAME, + SAFE_WEIGHTS_NAME, + TF2_WEIGHTS_INDEX_NAME, + TF2_WEIGHTS_NAME, + logging, +) +from transformers.utils.generic import ModelOutput + + +logger = logging.get_logger(__name__) + + +if is_tf_available(): + import h5py + import numpy as np + import tensorflow as tf + + from transformers import ( + TF_MODEL_FOR_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING, + TF_MODEL_FOR_MASKED_LM_MAPPING, + TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING, + TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING, + TF_MODEL_FOR_PRETRAINING_MAPPING, + TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING, + TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING, + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING, + TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING, + TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING, + TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING, + BertConfig, + PreTrainedModel, + PushToHubCallback, + RagRetriever, + TFAutoModel, + TFAutoModelForSequenceClassification, + TFBertForMaskedLM, + TFBertForSequenceClassification, + TFBertModel, + TFPreTrainedModel, + TFRagModel, + TFSharedEmbeddings, + ) + from transformers.generation import ( + TFBeamSampleDecoderOnlyOutput, + TFBeamSampleEncoderDecoderOutput, + TFBeamSearchDecoderOnlyOutput, + TFBeamSearchEncoderDecoderOutput, + TFGreedySearchDecoderOnlyOutput, + TFGreedySearchEncoderDecoderOutput, + TFSampleDecoderOnlyOutput, + TFSampleEncoderDecoderOutput, + ) + from transformers.modeling_tf_utils import tf_shard_checkpoint, unpack_inputs + from transformers.tf_utils import stable_softmax + + tf.config.experimental.enable_tensor_float_32_execution(False) + + if _tf_gpu_memory_limit is not None: + gpus = tf.config.list_physical_devices("GPU") + for gpu in gpus: + # Restrict TensorFlow to only allocate x GB of memory on the GPUs + try: + tf.config.set_logical_device_configuration( + gpu, [tf.config.LogicalDeviceConfiguration(memory_limit=_tf_gpu_memory_limit)] + ) + logical_gpus = tf.config.list_logical_devices("GPU") + print("Logical GPUs", logical_gpus) + except RuntimeError as e: + # Virtual devices must be set before GPUs have been initialized + print(e) + +if is_torch_available(): + import torch + + from transformers import BertModel + + +def _config_zero_init(config): + configs_no_init = copy.deepcopy(config) + for key in configs_no_init.__dict__.keys(): + if "_range" in key or "_std" in key: + setattr(configs_no_init, key, 0.0) + return configs_no_init + + +def _return_type_has_loss(model): + return_type = get_type_hints(model.call) + if "return" not in return_type: + return False + return_type = return_type["return"] + if hasattr(return_type, "__args__"): # Awkward check for union because UnionType only turns up in 3.10 + for type_annotation in return_type.__args__: + if inspect.isclass(type_annotation) and issubclass(type_annotation, ModelOutput): + field_names = [field.name for field in fields(type_annotation)] + if "loss" in field_names: + return True + return False + elif isinstance(return_type, tuple): + return False + elif isinstance(return_type, ModelOutput): + class_fields = fields(return_type) + return "loss" in class_fields + return False + + +@require_tf +class TFModelTesterMixin: + model_tester = None + all_model_classes = () + all_generative_model_classes = () + test_mismatched_shapes = True + test_resize_embeddings = True + test_head_masking = True + is_encoder_decoder = False + has_attentions = True + + def _prepare_for_class(self, inputs_dict, model_class, return_labels=False) -> dict: + inputs_dict = copy.deepcopy(inputs_dict) + + if model_class in get_values(TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict = { + k: tf.tile(tf.expand_dims(v, 1), (1, self.model_tester.num_choices) + (1,) * (v.ndim - 1)) + if isinstance(v, tf.Tensor) and v.ndim > 0 + else v + for k, v in inputs_dict.items() + } + + if return_labels: + if model_class in get_values(TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs_dict["labels"] = tf.ones(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in [ + *get_values(TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING), + *get_values(TF_MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING), + ]: + inputs_dict["start_positions"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + inputs_dict["end_positions"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in [ + *get_values(TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING), + *get_values(TF_MODEL_FOR_IMAGE_CLASSIFICATION_MAPPING), + ]: + inputs_dict["labels"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in get_values(TF_MODEL_FOR_NEXT_SENTENCE_PREDICTION_MAPPING): + inputs_dict["next_sentence_label"] = tf.zeros(self.model_tester.batch_size, dtype=tf.int32) + elif model_class in [ + *get_values(TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING), + *get_values(TF_MODEL_FOR_CAUSAL_LM_MAPPING), + *get_values(TF_MODEL_FOR_MASKED_LM_MAPPING), + *get_values(TF_MODEL_FOR_PRETRAINING_MAPPING), + *get_values(TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING), + *get_values(TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING), + ] and "labels" in dict(inspect.signature(model_class.call).parameters): + inputs_dict["labels"] = tf.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=tf.int32 + ) + elif model_class in get_values(TF_MODEL_FOR_MASKED_IMAGE_MODELING_MAPPING): + num_patches = self.model_tester.image_size // self.model_tester.patch_size + inputs_dict["bool_masked_pos"] = tf.zeros( + (self.model_tester.batch_size, num_patches**2), dtype=tf.int32 + ) + elif model_class in get_values(TF_MODEL_FOR_SEMANTIC_SEGMENTATION_MAPPING): + batch_size, num_channels, height, width = inputs_dict["pixel_values"].shape + inputs_dict["labels"] = tf.zeros((self.model_tester.batch_size, height, width), dtype=tf.int32) + elif model_class.__name__.endswith("ForCTC"): + # When we have enough CTC models for an AutoClass, we should use their mapping instead of name checks + inputs_dict["labels"] = tf.zeros( + (self.model_tester.batch_size, self.model_tester.seq_length), dtype=tf.int32 + ) + + return inputs_dict + + def test_initialization(self): + pass + + def test_save_load(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=False) + + # the config file (and the generation config file, if it can generate) should be saved + self.assertTrue(os.path.exists(os.path.join(tmpdirname, CONFIG_NAME))) + self.assertEqual( + model.can_generate(), os.path.exists(os.path.join(tmpdirname, GENERATION_CONFIG_NAME)) + ) + + model = model_class.from_pretrained(tmpdirname) + after_outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + self.assert_outputs_same(after_outputs, outputs) + + def test_save_load_config(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + model_config = model.get_config() + # make sure that returned config is jsonifiable, which is required by keras + json.dumps(model_config) + new_model = model_class.from_config(model.get_config()) + # make sure it also accepts a normal config + _ = model_class.from_config(model.config) + _ = new_model(self._prepare_for_class(inputs_dict, model_class)) # Build model + new_model.set_weights(model.get_weights()) + after_outputs = new_model(self._prepare_for_class(inputs_dict, model_class)) + + self.assert_outputs_same(after_outputs, outputs) + + @slow + def test_saved_model_creation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = False + config.output_attentions = False + + if hasattr(config, "use_cache"): + config.use_cache = False + + model_class = self.all_model_classes[0] + + class_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + model = model_class(config) + + model(class_inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=True) + saved_model_dir = os.path.join(tmpdirname, "saved_model", "1") + self.assertTrue(os.path.exists(saved_model_dir)) + + def test_prepare_serving_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + for model_class in self.all_model_classes: + model = model_class(config) + inputs = self._prepare_for_class(inputs_dict, model_class) + outputs = model(inputs) + serving_outputs = model.serving_output(outputs) + + for k, v in serving_outputs.items(): + # Check that we have one of three possible outputs: None, tuple of tensors or a tensor + if isinstance(v, tuple): + self.assertTrue(all(isinstance(elem, tf.Tensor) for elem in v)) + elif v is not None: + self.assertIsInstance(v, tf.Tensor) + else: + self.assertIsNone(v) + + def test_forward_signature(self): + config, _ = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + signature = inspect.signature(model.call) + # signature.parameters is an OrderedDict => so arg_names order is deterministic + arg_names = [*signature.parameters.keys()] + + if model.config.is_encoder_decoder: + expected_arg_names = [ + "input_ids", + "attention_mask", + "decoder_input_ids", + "decoder_attention_mask", + ] + expected_arg_names.extend(["decoder_position_ids"] if "decoder_position_ids" in arg_names else []) + expected_arg_names.extend( + ["head_mask", "decoder_head_mask"] if "head_mask" and "decoder_head_mask" in arg_names else [] + ) + expected_arg_names.extend( + ["cross_attn_head_mask", "encoder_outputs"] + if "cross_attn_head_mask" in arg_names + else ["encoder_outputs"] + ) + self.assertListEqual(arg_names[: len(expected_arg_names)], expected_arg_names) + + else: + expected_arg_names = ["input_ids"] + self.assertListEqual(arg_names[:1], expected_arg_names) + + def test_onnx_compliancy(self): + if not self.test_onnx: + return + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + INTERNAL_OPS = [ + "Assert", + "AssignVariableOp", + "EmptyTensorList", + "ReadVariableOp", + "ResourceGather", + "TruncatedNormal", + "VarHandleOp", + "VarIsInitializedOp", + ] + onnx_ops = [] + + with open(os.path.join(".", "utils", "tf_ops", "onnx.json")) as f: + onnx_opsets = json.load(f)["opsets"] + + for i in range(1, self.onnx_min_opset + 1): + onnx_ops.extend(onnx_opsets[str(i)]) + + for model_class in self.all_model_classes: + model_op_names = set() + + with tf.Graph().as_default() as g: + model = model_class(config) + model(model.dummy_inputs) + + for op in g.get_operations(): + model_op_names.add(op.node_def.op) + + model_op_names = sorted(model_op_names) + incompatible_ops = [] + + for op in model_op_names: + if op not in onnx_ops and op not in INTERNAL_OPS: + incompatible_ops.append(op) + + self.assertEqual(len(incompatible_ops), 0, incompatible_ops) + + @require_tf2onnx + @slow + def test_onnx_runtime_optimize(self): + if not self.test_onnx: + return + + import onnxruntime + import tf2onnx + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + model(model.dummy_inputs) + + onnx_model_proto, _ = tf2onnx.convert.from_keras(model, opset=self.onnx_min_opset) + + onnxruntime.InferenceSession(onnx_model_proto.SerializeToString()) + + def test_keras_save_load(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + tf_main_layer_classes = { + module_member + for model_class in self.all_model_classes + for module in (import_module(model_class.__module__),) + for module_member_name in dir(module) + if module_member_name.endswith("MainLayer") + # This condition is required, since `modeling_tf_clip.py` has 3 classes whose names end with `MainLayer`. + and module_member_name[: -len("MainLayer")] == model_class.__name__[: -len("Model")] + for module_member in (getattr(module, module_member_name),) + if isinstance(module_member, type) + and tf.keras.layers.Layer in module_member.__bases__ + and getattr(module_member, "_keras_serializable", False) + } + for main_layer_class in tf_main_layer_classes: + # T5MainLayer needs an embed_tokens parameter when called without the inputs_embeds parameter + if "T5" in main_layer_class.__name__: + # Take the same values than in TFT5ModelTester for this shared layer + shared = TFSharedEmbeddings(99, 32, name="shared") + config.use_cache = inputs_dict.pop("use_cache", None) + main_layer = main_layer_class(config, embed_tokens=shared) + else: + main_layer = main_layer_class(config) + + symbolic_inputs = { + name: tf.keras.Input(tensor.shape[1:], dtype=tensor.dtype) for name, tensor in inputs_dict.items() + } + + model = tf.keras.Model(symbolic_inputs, outputs=main_layer(symbolic_inputs)) + outputs = model(inputs_dict) + + with tempfile.TemporaryDirectory() as tmpdirname: + filepath = os.path.join(tmpdirname, "keras_model.h5") + model.save(filepath) + if "T5" in main_layer_class.__name__: + model = tf.keras.models.load_model( + filepath, + custom_objects={ + main_layer_class.__name__: main_layer_class, + "TFSharedEmbeddings": TFSharedEmbeddings, + }, + ) + else: + model = tf.keras.models.load_model( + filepath, custom_objects={main_layer_class.__name__: main_layer_class} + ) + assert isinstance(model, tf.keras.Model) + after_outputs = model(inputs_dict) + self.assert_outputs_same(after_outputs, outputs) + + def assert_outputs_same(self, after_outputs, outputs): + # Make sure we don't have nans + if isinstance(after_outputs, tf.Tensor): + out_1 = after_outputs.numpy() + elif isinstance(after_outputs, dict): + out_1 = after_outputs[list(after_outputs.keys())[0]].numpy() + else: + out_1 = after_outputs[0].numpy() + out_2 = outputs[0].numpy() + self.assertEqual(out_1.shape, out_2.shape) + out_1 = out_1[~np.isnan(out_1)] + out_2 = out_2[~np.isnan(out_2)] + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + # Don't copy this method to model specific test file! + # TODO: remove this method once the issues are all fixed! + def _make_attention_mask_non_null(self, inputs_dict): + """Make sure no sequence has all zeros as attention mask""" + + for k in ["attention_mask", "encoder_attention_mask", "decoder_attention_mask"]: + if k in inputs_dict: + attention_mask = inputs_dict[k] + + # Make sure no all 0s attention masks - to avoid failure at this moment. + # Put `1` at the beginning of sequences to make it still work when combining causal attention masks. + # TODO: remove this line once a fix regarding large negative values for attention mask is done. + attention_mask = tf.concat( + [tf.ones_like(attention_mask[:, :1], dtype=attention_mask.dtype), attention_mask[:, 1:]], axis=-1 + ) + + # Here we make the first sequence with all 0s as attention mask. + # Currently, this will fail for `TFWav2Vec2Model`. This is caused by the different large negative + # values, like `1e-4`, `1e-9`, `1e-30` and `-inf` for attention mask across models/frameworks. + # TODO: enable this block once the large negative values thing is cleaned up. + # (see https://github.com/huggingface/transformers/issues/14859) + # attention_mask = tf.concat( + # [ + # tf.zeros_like(attention_mask[:1], dtype=tf.int32), + # tf.cast(attention_mask[1:], dtype=tf.int32) + # ], + # axis=0 + # ) + + inputs_dict[k] = attention_mask + + # Don't copy this method to model specific test file! + # TODO: remove this method once the issues are all fixed! + def _postprocessing_to_ignore_test_cases(self, tf_outputs, pt_outputs, model_class): + """For temporarily ignoring some failed test cases (issues to be fixed)""" + + tf_keys = {k for k, v in tf_outputs.items() if v is not None} + pt_keys = {k for k, v in pt_outputs.items() if v is not None} + + key_differences = tf_keys.symmetric_difference(pt_keys) + + if model_class.__name__ in [ + "TFFlaubertWithLMHeadModel", + "TFFunnelForPreTraining", + "TFElectraForPreTraining", + "TFXLMWithLMHeadModel", + "TFTransfoXLLMHeadModel", + ]: + for k in key_differences: + if k in ["loss", "losses"]: + tf_keys.discard(k) + pt_keys.discard(k) + elif model_class.__name__.startswith("TFGPT2"): + # `TFGPT2` has `past_key_values` as a tensor while `GPT2` has it as a tuple. + tf_keys.discard("past_key_values") + pt_keys.discard("past_key_values") + + # create new outputs from the remaining fields + new_tf_outputs = type(tf_outputs)(**{k: tf_outputs[k] for k in tf_keys}) + new_pt_outputs = type(pt_outputs)(**{k: pt_outputs[k] for k in pt_keys}) + + return new_tf_outputs, new_pt_outputs + + def check_pt_tf_outputs(self, tf_outputs, pt_outputs, model_class, tol=1e-5, name="outputs", attributes=None): + """Check the outputs from PyTorch and TensorFlow models are close enough. Checks are done in a recursive way. + + Args: + model_class: The class of the model that is currently testing. For example, `TFBertModel`, + TFBertForMaskedLM`, `TFBertForSequenceClassification`, etc. Mainly used for providing more informative + error messages. + name (`str`): The name of the output. For example, `output.hidden_states`, `output.attentions`, etc. + attributes (`Tuple[str]`): The names of the output's element if the output is a tuple/list with each element + being a named field in the output. + """ + + self.assertEqual(type(name), str) + if attributes is not None: + self.assertEqual(type(attributes), tuple, f"{name}: The argument `attributes` should be a `tuple`") + + # Allow `ModelOutput` (e.g. `CLIPOutput` has `text_model_output` and `vision_model_output`). + if isinstance(tf_outputs, ModelOutput): + self.assertTrue( + isinstance(pt_outputs, ModelOutput), + f"{name}: `pt_outputs` should an instance of `ModelOutput` when `tf_outputs` is", + ) + + # Don't copy this block to model specific test file! + # TODO: remove this method and this line after issues are fixed + tf_outputs, pt_outputs = self._postprocessing_to_ignore_test_cases(tf_outputs, pt_outputs, model_class) + + tf_keys = [k for k, v in tf_outputs.items() if v is not None] + pt_keys = [k for k, v in pt_outputs.items() if v is not None] + + self.assertEqual(tf_keys, pt_keys, f"{name}: Output keys differ between TF and PyTorch") + + # convert to the case of `tuple` + # appending each key to the current (string) `names` + attributes = tuple([f"{name}.{k}" for k in tf_keys]) + self.check_pt_tf_outputs( + tf_outputs.to_tuple(), pt_outputs.to_tuple(), model_class, tol=tol, name=name, attributes=attributes + ) + + # Allow `list` (e.g. `TransfoXLModelOutput.mems` is a list of tensors.) + elif type(tf_outputs) in [tuple, list]: + self.assertEqual(type(tf_outputs), type(pt_outputs), f"{name}: Output types differ between TF and PyTorch") + self.assertEqual(len(tf_outputs), len(pt_outputs), f"{name}: Output lengths differ between TF and PyTorch") + + if attributes is not None: + # case 1: each output has assigned name (e.g. a tuple form of a `ModelOutput`) + self.assertEqual( + len(attributes), + len(tf_outputs), + f"{name}: The tuple `names` should have the same length as `tf_outputs`", + ) + else: + # case 2: each output has no assigned name (e.g. hidden states of each layer) -> add an index to `names` + attributes = tuple([f"{name}_{idx}" for idx in range(len(tf_outputs))]) + + for tf_output, pt_output, attr in zip(tf_outputs, pt_outputs, attributes): + self.check_pt_tf_outputs(tf_output, pt_output, model_class, tol=tol, name=attr) + + elif isinstance(tf_outputs, tf.Tensor): + self.assertTrue( + isinstance(pt_outputs, torch.Tensor), f"{name}: `pt_outputs` should a tensor when `tf_outputs` is" + ) + + tf_outputs = tf_outputs.numpy() + pt_outputs = pt_outputs.detach().to("cpu").numpy() + + self.assertEqual( + tf_outputs.shape, pt_outputs.shape, f"{name}: Output shapes differ between TF and PyTorch" + ) + + # deal with NumPy's scalars to make replacing nan values by 0 work. + if np.isscalar(tf_outputs): + tf_outputs = np.array([tf_outputs]) + pt_outputs = np.array([pt_outputs]) + + tf_nans = np.isnan(tf_outputs) + pt_nans = np.isnan(pt_outputs) + + pt_outputs[tf_nans] = 0 + tf_outputs[tf_nans] = 0 + pt_outputs[pt_nans] = 0 + tf_outputs[pt_nans] = 0 + + max_diff = np.amax(np.abs(tf_outputs - pt_outputs)) + self.assertLessEqual(max_diff, tol, f"{name}: Difference between torch and tf is {max_diff} (>= {tol}).") + else: + raise ValueError( + "`tf_outputs` should be an instance of `tf.Tensor`, a `tuple`, or an instance of `tf.Tensor`. Got" + f" {type(tf_outputs)} instead." + ) + + def prepare_pt_inputs_from_tf_inputs(self, tf_inputs_dict): + pt_inputs_dict = {} + for name, key in tf_inputs_dict.items(): + if type(key) == bool: + pt_inputs_dict[name] = key + elif name == "input_values": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + elif name == "pixel_values": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + elif name == "input_features": + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + # other general float inputs + elif tf_inputs_dict[name].dtype.is_floating: + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.float32) + else: + pt_inputs_dict[name] = torch.from_numpy(key.numpy()).to(torch.long) + + return pt_inputs_dict + + def check_pt_tf_models(self, tf_model, pt_model, tf_inputs_dict): + pt_inputs_dict = self.prepare_pt_inputs_from_tf_inputs(tf_inputs_dict) + + # send pytorch inputs to the correct device + pt_inputs_dict = { + k: v.to(device=torch_device) if isinstance(v, torch.Tensor) else v for k, v in pt_inputs_dict.items() + } + + # send pytorch model to the correct device + pt_model.to(torch_device) + + # Check predictions on first output (logits/hidden-states) are close enough given low-level computational differences + pt_model.eval() + + with torch.no_grad(): + pt_outputs = pt_model(**pt_inputs_dict) + tf_outputs = tf_model(tf_inputs_dict) + + # tf models returned loss is usually a tensor rather than a scalar. + # (see `hf_compute_loss`: it uses `tf.keras.losses.Reduction.NONE`) + # Change it here to a scalar to match PyTorch models' loss + tf_loss = getattr(tf_outputs, "loss", None) + if tf_loss is not None: + tf_outputs.loss = tf.math.reduce_mean(tf_loss) + + self.check_pt_tf_outputs(tf_outputs, pt_outputs, type(tf_model)) + + @is_pt_tf_cross_test + def test_pt_tf_model_equivalence(self, allow_missing_keys=False): + import transformers + + for model_class in self.all_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + # Output all for aggressive testing + config.output_hidden_states = True + config.output_attentions = self.has_attentions + + # Make sure no sequence has all zeros as attention mask, otherwise some tests fail due to the inconsistency + # of the usage `1e-4`, `1e-9`, `1e-30`, `-inf`. + # TODO: Use a uniform value for all models, make sure all tests pass without this processing, and remove it. + self._make_attention_mask_non_null(inputs_dict) + + pt_model_class_name = model_class.__name__[2:] # Skip the "TF" at the beginning + pt_model_class = getattr(transformers, pt_model_class_name) + + tf_model = model_class(config) + pt_model = pt_model_class(config) + + tf_inputs_dict = self._prepare_for_class(inputs_dict, model_class) + tf_inputs_dict_with_labels = self._prepare_for_class( + inputs_dict, + model_class, + # Not all models accept "labels" in the forward pass (yet :) ) + return_labels=True if "labels" in inspect.signature(model_class.call).parameters.keys() else False, + ) + + # For some models (e.g. base models), there is no label returned. + # Set the input dict to `None` to avoid check outputs twice for the same input dicts. + if not set(tf_inputs_dict_with_labels.keys()).symmetric_difference(tf_inputs_dict.keys()): + tf_inputs_dict_with_labels = None + + # Check we can load pt model in tf and vice-versa with model => model functions + tf_model = transformers.load_pytorch_model_in_tf2_model( + tf_model, pt_model, tf_inputs=tf_inputs_dict, allow_missing_keys=allow_missing_keys + ) + pt_model = transformers.load_tf2_model_in_pytorch_model( + pt_model, tf_model, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + # check with `labels` + if tf_inputs_dict_with_labels: + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict_with_labels) + + # Check we can load pt model in tf and vice-versa with checkpoint => model functions + with tempfile.TemporaryDirectory() as tmpdirname: + pt_checkpoint_path = os.path.join(tmpdirname, "pt_model.bin") + torch.save(pt_model.state_dict(), pt_checkpoint_path) + tf_model = transformers.load_pytorch_checkpoint_in_tf2_model( + tf_model, pt_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + tf_checkpoint_path = os.path.join(tmpdirname, "tf_model.h5") + tf_model.save_weights(tf_checkpoint_path) + pt_model = transformers.load_tf2_checkpoint_in_pytorch_model( + pt_model, tf_checkpoint_path, allow_missing_keys=allow_missing_keys + ) + + # Original test: check without `labels` + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict) + # check with `labels` + if tf_inputs_dict_with_labels: + self.check_pt_tf_models(tf_model, pt_model, tf_inputs_dict_with_labels) + + def test_compile_tf_model(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + max_input = getattr(self.model_tester, "max_position_embeddings", 512) + optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0) + loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) + metric = tf.keras.metrics.SparseCategoricalAccuracy("accuracy") + + for model_class in self.all_model_classes: + if model_class.__name__ in ["TFSpeech2TextModel", "TFSpeech2TextForConditionalGeneration"]: + inputs = { + "decoder_input_ids": tf.keras.Input( + batch_shape=(2, max_input), + name="decoder_input_ids", + dtype="int32", + ), + "input_features": tf.keras.Input( + batch_shape=( + 2, + max_input, + self.model_tester.input_feat_per_channel * self.model_tester.input_channels, + ), + name="input_features", + dtype="float32", + ), + } + elif model_class.__name__ in ["TFWhisperModel", "TFWhisperForConditionalGeneration"]: + inputs = { + "decoder_input_ids": tf.keras.Input( + batch_shape=(2, max_input), + name="decoder_input_ids", + dtype="int32", + ), + "input_features": tf.keras.Input( + batch_shape=( + 2, + self.model_tester.num_mel_bins, + self.model_tester.seq_length, + ), + name="input_features", + dtype="float32", + ), + } + elif self.is_encoder_decoder: + inputs = { + "decoder_input_ids": tf.keras.Input( + batch_shape=(2, max_input), + name="decoder_input_ids", + dtype="int32", + ), + "input_ids": tf.keras.Input(batch_shape=(2, max_input), name="input_ids", dtype="int32"), + } + # `pixel_values` implies that the input is an image + elif model_class.main_input_name == "pixel_values": + inputs = tf.keras.Input( + batch_shape=( + 3, + self.model_tester.num_channels, + self.model_tester.image_size, + self.model_tester.image_size, + ), + name="pixel_values", + dtype="float32", + ) + elif model_class.__name__ in ["TFCLIPModel", "TFGroupViTModel", "TFBlipModel"]: + inputs = { + "input_ids": tf.keras.Input(batch_shape=(3, max_input), name="input_ids", dtype="int32"), + "pixel_values": tf.keras.Input( + batch_shape=( + 3, + self.model_tester.vision_model_tester.num_channels, + self.model_tester.vision_model_tester.image_size, + self.model_tester.vision_model_tester.image_size, + ), + name="pixel_values", + dtype="float32", + ), + } + elif model_class in get_values(TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING): + inputs = tf.keras.Input(batch_shape=(4, 2, max_input), name="input_ids", dtype="int32") + else: + inputs = tf.keras.Input(batch_shape=(2, max_input), name="input_ids", dtype="int32") + + # Prepare our model + model = model_class(config) + model(self._prepare_for_class(inputs_dict, model_class)) # Model must be called before saving. + # Let's load it from the disk to be sure we can use pretrained weights + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=False) + model = model_class.from_pretrained(tmpdirname) + + outputs_dict = model(inputs) + hidden_states = outputs_dict[0] + + # Add a dense layer on top to test integration with other keras modules + outputs = tf.keras.layers.Dense(2, activation="softmax", name="outputs")(hidden_states) + + # Compile extended model + extended_model = tf.keras.Model(inputs=[inputs], outputs=[outputs]) + extended_model.compile(optimizer=optimizer, loss=loss, metrics=[metric]) + + def test_keyword_and_dict_args(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + inputs = self._prepare_for_class(inputs_dict, model_class) + + outputs_dict = model(inputs) + + inputs_keywords = copy.deepcopy(self._prepare_for_class(inputs_dict, model_class)) + outputs_keywords = model(**inputs_keywords) + output_dict = outputs_dict[0].numpy() + output_keywords = outputs_keywords[0].numpy() + + self.assertLess(np.sum(np.abs(output_dict - output_keywords)), 1e-6) + + def test_attention_outputs(self): + if not self.has_attentions: + self.skipTest(reason="Model does not output attentions") + + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.return_dict = True + decoder_seq_length = getattr(self.model_tester, "decoder_seq_length", self.model_tester.seq_length) + encoder_seq_length = getattr(self.model_tester, "encoder_seq_length", self.model_tester.seq_length) + decoder_key_length = getattr(self.model_tester, "key_length", decoder_seq_length) + encoder_key_length = getattr(self.model_tester, "key_length", encoder_seq_length) + + def check_decoder_attentions_output(outputs): + out_len = len(outputs) + self.assertEqual(min(out_len % 2, out_len % 5), 0) # differentiation due to newly added cross_attentions + decoder_attentions = outputs.decoder_attentions + self.assertEqual(len(decoder_attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(decoder_attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, decoder_seq_length, decoder_key_length], + ) + + def check_encoder_attentions_output(outputs): + attentions = [ + t.numpy() for t in (outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions) + ] + self.assertEqual(len(attentions), self.model_tester.num_hidden_layers) + self.assertListEqual( + list(attentions[0].shape[-3:]), + [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_attentions"] = True + config.output_hidden_states = False + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + out_len = len(outputs) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + if self.is_encoder_decoder: + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_decoder_attentions_output(outputs) + + # Check that output attentions can also be changed via the config + del inputs_dict["output_attentions"] + config.output_attentions = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + self.assertEqual(config.output_hidden_states, False) + check_encoder_attentions_output(outputs) + + # Check attention is always last and order is fine + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + + self.assertEqual(out_len + (2 if self.is_encoder_decoder else 1), len(outputs)) + self.assertEqual(model.config.output_hidden_states, True) + check_encoder_attentions_output(outputs) + + def test_headmasking(self): + if not self.test_head_masking: + return + + random.Random().seed(42) + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + random.Random().seed() + + inputs_dict["output_attentions"] = True + config.output_hidden_states = True + configs_no_init = _config_zero_init(config) # To be sure we have no Nan + for model_class in self.all_model_classes: + model = model_class(config=configs_no_init) + + # Prepare head_mask + def prepare_layer_head_mask(i, attention_heads, num_hidden_layers): + if i == 0: + return tf.concat( + (tf.zeros(1, dtype=tf.float32), tf.ones(attention_heads - 1, dtype=tf.float32)), 0 + ) + elif i == num_hidden_layers - 1: + return tf.concat( + (tf.zeros(attention_heads - 1, dtype=tf.float32), tf.ones(1, dtype=tf.float32)), 0 + ) + else: + return tf.ones(attention_heads, dtype=tf.float32) + + head_mask = tf.stack( + [ + prepare_layer_head_mask(i, config.num_attention_heads, config.num_hidden_layers) + for i in range(config.num_hidden_layers) + ], + 0, + ) + + inputs = self._prepare_for_class(inputs_dict, model_class).copy() + inputs["head_mask"] = head_mask + if model.config.is_encoder_decoder: + signature = inspect.signature(model.call) + arg_names = [*signature.parameters.keys()] + if "decoder_head_mask" in arg_names: # necessary diferentiation because of T5 model + inputs["decoder_head_mask"] = head_mask + if "cross_attn_head_mask" in arg_names: + inputs["cross_attn_head_mask"] = head_mask + + outputs = model(**inputs, return_dict=True) + + def check_attentions_validity(attentions): + # Remove Nan + for t in attentions: + self.assertLess( + (tf.math.reduce_sum(tf.cast(tf.math.is_nan(t), tf.float32))).numpy(), (tf.size(t) / 4).numpy() + ) # Check we don't have more than 25% nans (arbitrary) + + attentions = [ + tf.where(tf.math.is_nan(t), 0.0, t) for t in attentions + ] # remove them (the test is less complete) + + self.assertAlmostEqual(tf.math.reduce_sum(attentions[0][..., 0, :, :]).numpy(), 0.0) + self.assertNotEqual(tf.math.reduce_sum(attentions[0][..., -1, :, :]).numpy(), 0.0) + if len(attentions) > 2: # encoder-decodere models have only 2 layers in each modules + self.assertNotEqual(tf.math.reduce_sum(attentions[1][..., 0, :, :]).numpy(), 0.0) + self.assertAlmostEqual(tf.math.reduce_sum(attentions[-1][..., -2, :, :]).numpy(), 0.0) + self.assertNotEqual(tf.math.reduce_sum(attentions[-1][..., -1, :, :]).numpy(), 0.0) + + if model.config.is_encoder_decoder: + check_attentions_validity(outputs.encoder_attentions) + check_attentions_validity(outputs.decoder_attentions) + if "cross_attn_head_mask" in arg_names: + check_attentions_validity(outputs.cross_attentions) + else: + check_attentions_validity(outputs.attentions) + + def test_hidden_states_output(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_hidden_states_output(config, inputs_dict, model_class): + model = model_class(config) + outputs = model(self._prepare_for_class(inputs_dict, model_class)) + expected_num_layers = getattr( + self.model_tester, "expected_num_hidden_layers", self.model_tester.num_hidden_layers + 1 + ) + + if model.config.is_encoder_decoder: + encoder_hidden_states = outputs.encoder_hidden_states + decoder_hidden_states = outputs.decoder_hidden_states + + self.assertEqual(config.output_attentions, False) + self.assertEqual(len(encoder_hidden_states), expected_num_layers) + self.assertListEqual( + list(encoder_hidden_states[0].shape[-2:]), + [self.model_tester.seq_length, self.model_tester.hidden_size], + ) + self.assertEqual(len(decoder_hidden_states), expected_num_layers) + self.assertListEqual( + list(decoder_hidden_states[0].shape[-2:]), + [self.model_tester.seq_length, self.model_tester.hidden_size], + ) + else: + hidden_states = outputs.hidden_states + self.assertEqual(config.output_attentions, False) + self.assertEqual(len(hidden_states), expected_num_layers) + self.assertListEqual( + list(hidden_states[0].shape[-2:]), + [self.model_tester.seq_length, self.model_tester.hidden_size], + ) + + for model_class in self.all_model_classes: + inputs_dict["output_hidden_states"] = True + check_hidden_states_output(config, inputs_dict, model_class) + + del inputs_dict["output_hidden_states"] + config.output_hidden_states = True + check_hidden_states_output(config, inputs_dict, model_class) + + def test_model_common_attributes(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + text_in_text_out_models = ( + get_values(TF_MODEL_FOR_CAUSAL_LM_MAPPING) + + get_values(TF_MODEL_FOR_MASKED_LM_MAPPING) + + get_values(TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING) + ) + speech_in_text_out_models = get_values(TF_MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING) + + for model_class in self.all_model_classes: + model = model_class(config) + assert isinstance(model.get_input_embeddings(), tf.keras.layers.Layer) + if model_class in text_in_text_out_models: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert isinstance(name, dict) + for k, v in name.items(): + assert isinstance(v, tf.Variable) + elif model_class in speech_in_text_out_models: + x = model.get_output_embeddings() + assert isinstance(x, tf.keras.layers.Layer) + name = model.get_bias() + assert name is None + else: + x = model.get_output_embeddings() + assert x is None + name = model.get_bias() + assert name is None + + def test_determinism(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + first, second = ( + model(self._prepare_for_class(inputs_dict, model_class), training=False)[0], + model(self._prepare_for_class(inputs_dict, model_class), training=False)[0], + ) + out_1 = first.numpy() + out_2 = second.numpy() + out_1 = out_1[~np.isnan(out_1)] + out_2 = out_2[~np.isnan(out_2)] + max_diff = np.amax(np.abs(out_1 - out_2)) + self.assertLessEqual(max_diff, 1e-5) + + def test_model_outputs_equivalence(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def check_equivalence(model, tuple_inputs, dict_inputs, additional_kwargs={}): + tuple_output = model(tuple_inputs, return_dict=False, **additional_kwargs) + dict_output = model(dict_inputs, return_dict=True, **additional_kwargs).to_tuple() + + def recursive_check(tuple_object, dict_object): + if isinstance(tuple_object, (List, Tuple)): + for tuple_iterable_value, dict_iterable_value in zip(tuple_object, dict_object): + recursive_check(tuple_iterable_value, dict_iterable_value) + elif tuple_object is None: + return + else: + self.assertTrue( + all(tf.equal(tuple_object, dict_object)), + msg=( + "Tuple and dict output are not equal. Difference:" + f" {tf.math.reduce_max(tf.abs(tuple_object - dict_object))}" + ), + ) + + recursive_check(tuple_output, dict_output) + + for model_class in self.all_model_classes: + model = model_class(config) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + if self.has_attentions: + tuple_inputs = self._prepare_for_class(inputs_dict, model_class) + dict_inputs = self._prepare_for_class(inputs_dict, model_class) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + # Not all models accept "labels" in the forward pass (yet :) ) + if "labels" in inspect.signature(model.call).parameters.keys(): + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True}) + + if self.has_attentions: + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence(model, tuple_inputs, dict_inputs, {"output_attentions": True}) + + tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + check_equivalence( + model, tuple_inputs, dict_inputs, {"output_hidden_states": True, "output_attentions": True} + ) + + def test_inputs_embeds(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config) + + inputs = copy.deepcopy(inputs_dict) + + if not self.is_encoder_decoder: + input_ids = inputs["input_ids"] + del inputs["input_ids"] + else: + encoder_input_ids = inputs["input_ids"] + decoder_input_ids = inputs.get("decoder_input_ids", encoder_input_ids) + del inputs["input_ids"] + inputs.pop("decoder_input_ids", None) + + if not self.is_encoder_decoder: + inputs["inputs_embeds"] = model.get_input_embeddings()(input_ids) + else: + inputs["inputs_embeds"] = model.get_input_embeddings()(encoder_input_ids) + inputs["decoder_inputs_embeds"] = model.get_input_embeddings()(decoder_input_ids) + + inputs = self._prepare_for_class(inputs, model_class) + + model(inputs) + + def test_numpy_arrays_inputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def prepare_numpy_arrays(inputs_dict): + inputs_np_dict = {} + for k, v in inputs_dict.items(): + if tf.is_tensor(v): + inputs_np_dict[k] = v.numpy() + else: + inputs_np_dict[k] = np.array(k) + + return inputs_np_dict + + for model_class in self.all_model_classes: + model = model_class(config) + + inputs = self._prepare_for_class(inputs_dict, model_class) + inputs_np = prepare_numpy_arrays(inputs) + + output_for_dict_input = model(inputs_np) + output_for_kw_input = model(**inputs_np) + self.assert_outputs_same(output_for_dict_input, output_for_kw_input) + + def test_resize_token_embeddings(self): + # TODO (joao): after the embeddings refactor is complete, rework this test so as to rely exclusively on + # tf.keras.layers.Embedding + + if not self.test_resize_embeddings: + return + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + def _get_word_embedding_weight(model, embedding_layer): + if isinstance(embedding_layer, tf.keras.layers.Embedding): + # builds the embeddings layer + model(model.dummy_inputs) + return embedding_layer.embeddings + else: + return model._get_word_embedding_weight(embedding_layer) + + for model_class in self.all_model_classes: + for size in [config.vocab_size - 10, config.vocab_size + 10, None]: + # build the embeddings + model = model_class(config=copy.deepcopy(config)) # `resize_token_embeddings` mutates `config` + old_input_embeddings = _get_word_embedding_weight(model, model.get_input_embeddings()) + old_bias = model.get_bias() + old_output_embeddings = _get_word_embedding_weight(model, model.get_output_embeddings()) + # reshape the embeddings + model.resize_token_embeddings(size) + new_input_embeddings = _get_word_embedding_weight(model, model.get_input_embeddings()) + new_bias = model.get_bias() + new_output_embeddings = _get_word_embedding_weight(model, model.get_output_embeddings()) + + # check that the resized embeddings size matches the desired size. + assert_size = size if size is not None else config.vocab_size + self.assertEqual(new_input_embeddings.shape[0], assert_size) + + # check that weights remain the same after resizing + models_equal = True + for p1, p2 in zip(old_input_embeddings.value(), new_input_embeddings.value()): + if tf.math.reduce_sum(tf.math.abs(p1 - p2)) > 0: + models_equal = False + self.assertTrue(models_equal) + + if old_bias is not None and new_bias is not None: + for old_weight, new_weight in zip(old_bias.values(), new_bias.values()): + self.assertEqual(new_weight.shape[-1], assert_size) + + models_equal = True + for p1, p2 in zip(tf.squeeze(old_weight), tf.squeeze(new_weight)): + if tf.math.reduce_sum(tf.math.abs(p1 - p2)) > 0: + models_equal = False + self.assertTrue(models_equal) + + if old_output_embeddings is not None and new_output_embeddings is not None: + self.assertEqual(new_output_embeddings.shape[0], assert_size) + self.assertEqual(new_output_embeddings.shape[1], old_output_embeddings.shape[1]) + + models_equal = True + for p1, p2 in zip(old_output_embeddings.value(), new_output_embeddings.value()): + if tf.math.reduce_sum(tf.math.abs(p1 - p2)) > 0: + models_equal = False + self.assertTrue(models_equal) + + # TODO (Joao): this test is not slow, but it's tagged as such to keep track of failures on the scheduled CI runs, + # while passing push CI. Fix the underlying issues and remove the tag. + @slow + def test_save_load_after_resize_token_embeddings(self): + if not self.test_resize_embeddings: + return + config, original_inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + # create a model with resized (expended) embeddings + new_tokens_size = 10 + old_total_size = config.vocab_size + new_total_size = old_total_size + new_tokens_size + model = model_class(config=copy.deepcopy(config)) # `resize_token_embeddings` mutates `config` + model(model.dummy_inputs) # builds the embeddings layer + model.resize_token_embeddings(new_total_size) + + # fetch the output for an input exclusively made of new members of the vocabulary + inputs_dict = copy.deepcopy(original_inputs_dict) + ids_feat_name = None + if "input_ids" in inputs_dict: + ids_feat_name = "input_ids" + elif "decoder_input_ids" in inputs_dict: + ids_feat_name = "decoder_input_ids" + else: + assert False, "No input ids feature found in the inputs dict" + + new_vocab_input_ids = ids_tensor(inputs_dict[ids_feat_name].shape, new_tokens_size) + new_vocab_input_ids += old_total_size + inputs_dict[ids_feat_name] = new_vocab_input_ids + if "input_ids" in inputs_dict: + inputs_dict["input_ids"] = new_vocab_input_ids + if "decoder_input_ids" in inputs_dict: + inputs_dict["decoder_input_ids"] = new_vocab_input_ids + prepared_inputs = self._prepare_for_class(inputs_dict, model_class) + outputs = model(**prepared_inputs) + + # save and load the model + with tempfile.TemporaryDirectory() as tmpdirname: + model.save_pretrained(tmpdirname, saved_model=False) + model = model_class.from_pretrained(tmpdirname) + restored_model_outputs = model(**prepared_inputs) + + # check that the output for the restored model is the same + self.assert_outputs_same(restored_model_outputs, outputs) + + @unittest.skipIf( + not is_tf_available() or len(tf.config.list_physical_devices("GPU")) == 0, + reason="This test always passes on CPU.", + ) + def test_embeddings_out_of_bounds_raise_exception(self): + # TF embeddings layers don't raise an exception when an index is out of bounds on GPU, so we manually raise it. + # This test should only fail on GPU for models where we haven't added the safety check. + if not self.test_resize_embeddings: + return + config, original_inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + model = model_class(config=config) + inputs_dict = copy.deepcopy(original_inputs_dict) + if "input_ids" in inputs_dict: + inputs_dict["input_ids"] = inputs_dict["input_ids"] * int(1e9) + if "decoder_input_ids" in inputs_dict: + inputs_dict["decoder_input_ids"] = inputs_dict["decoder_input_ids"] * int(1e9) + prepared_inputs = self._prepare_for_class(inputs_dict, model_class) + with self.assertRaises(tf.errors.InvalidArgumentError): + model(**prepared_inputs) + + def test_lm_head_model_random_no_beam_search_generate(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + input_ids = inputs_dict.get("input_ids", None) + + # iterate over all generative models + for model_class in self.all_generative_model_classes: + model = model_class(config) + + if config.bos_token_id is None: + # if bos token id is not defined model needs input_ids + with self.assertRaises(ValueError): + model.generate(do_sample=True, max_length=5) + # num_return_sequences = 1 + self._check_generated_ids(model.generate(input_ids, do_sample=True)) + elif model_class.__name__ not in ["TFSpeech2TextForConditionalGeneration"]: + # Models with non-text inputs won't work here; num_return_sequences = 1 + self._check_generated_ids(model.generate(do_sample=True, max_length=5)) + + with self.assertRaises(ValueError): + # generating multiple sequences when no beam search generation + # is not allowed as it would always generate the same sequences + model.generate(input_ids, do_sample=False, num_return_sequences=2) + + # num_return_sequences > 1, sample + self._check_generated_ids(model.generate(input_ids, do_sample=True, num_return_sequences=2)) + + # check bad words tokens language generation + # create list of 1-seq bad token and list of 2-seq of bad tokens + bad_words_ids = [self._generate_random_bad_tokens(1, model), self._generate_random_bad_tokens(2, model)] + output_tokens = model.generate( + input_ids, do_sample=True, bad_words_ids=bad_words_ids, num_return_sequences=2 + ) + # only count generated tokens + generated_ids = output_tokens[:, input_ids.shape[-1] :] + self.assertFalse(self._check_match_tokens(generated_ids.numpy().tolist(), bad_words_ids)) + + def test_lm_head_model_no_beam_search_generate_dict_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + input_ids = inputs_dict.get("input_ids", None) + if input_ids is None: + input_ids = inputs_dict.get("input_features", None) + + # iterate over all generative models + for model_class in self.all_generative_model_classes: + model = model_class(config) + output_greedy = model.generate( + input_ids, + do_sample=False, + output_scores=True, + output_hidden_states=True, + output_attentions=True, + return_dict_in_generate=True, + ) + output_sample = model.generate( + input_ids, + do_sample=True, + output_scores=True, + output_hidden_states=True, + output_attentions=True, + return_dict_in_generate=True, + ) + + if model.config.is_encoder_decoder: + self.assertIsInstance(output_greedy, TFGreedySearchEncoderDecoderOutput) + self.assertIsInstance(output_sample, TFSampleEncoderDecoderOutput) + else: + self.assertIsInstance(output_greedy, TFGreedySearchDecoderOnlyOutput) + self.assertIsInstance(output_sample, TFSampleDecoderOnlyOutput) + + def test_lm_head_model_random_beam_search_generate(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + input_ids = inputs_dict.get("input_ids", None) + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + if config.bos_token_id is None: + # if bos token id is not defined model needs input_ids, num_return_sequences = 1 + self._check_generated_ids(model.generate(input_ids, do_sample=True, num_beams=2)) + else: + # num_return_sequences = 1 + self._check_generated_ids(model.generate(do_sample=True, max_length=5, num_beams=2)) + + with self.assertRaises(ValueError): + # generating more sequences than having beams leads is not possible + model.generate(input_ids, do_sample=False, num_return_sequences=3, num_beams=2) + + # num_return_sequences > 1, sample + self._check_generated_ids( + model.generate( + input_ids, + do_sample=True, + num_beams=2, + num_return_sequences=2, + ) + ) + # num_return_sequences > 1, greedy + self._check_generated_ids(model.generate(input_ids, do_sample=False, num_beams=2, num_return_sequences=2)) + + # check bad words tokens language generation + # create list of 1-seq bad token and list of 2-seq of bad tokens + bad_words_ids = [self._generate_random_bad_tokens(1, model), self._generate_random_bad_tokens(2, model)] + output_tokens = model.generate( + input_ids, do_sample=False, bad_words_ids=bad_words_ids, num_beams=2, num_return_sequences=2 + ) + # only count generated tokens + generated_ids = output_tokens[:, input_ids.shape[-1] :] + self.assertFalse(self._check_match_tokens(generated_ids.numpy().tolist(), bad_words_ids)) + + def test_lm_head_model_beam_search_generate_dict_outputs(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + input_ids = inputs_dict.get("input_ids", None) + if input_ids is None: + input_ids = inputs_dict.get("input_features", None) + + # iterate over all generative models + for model_class in self.all_generative_model_classes: + model = model_class(config) + output_beam_search = model.generate( + input_ids, + num_beams=2, + do_sample=False, + output_scores=True, + output_hidden_states=True, + output_attentions=True, + return_dict_in_generate=True, + ) + output_beam_sample = model.generate( + input_ids, + num_beams=2, + do_sample=True, + output_scores=True, + output_hidden_states=True, + output_attentions=True, + return_dict_in_generate=True, + ) + + if model.config.is_encoder_decoder: + self.assertIsInstance(output_beam_search, TFBeamSearchEncoderDecoderOutput) + self.assertIsInstance(output_beam_sample, TFBeamSampleEncoderDecoderOutput) + else: + self.assertIsInstance(output_beam_search, TFBeamSearchDecoderOnlyOutput) + self.assertIsInstance(output_beam_sample, TFBeamSampleDecoderOnlyOutput) + + def test_loss_computation(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + if not getattr(model, "hf_compute_loss", None) and not _return_type_has_loss(model): + continue + # The number of elements in the loss should be the same as the number of elements in the label + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + added_label_names = sorted(prepared_for_class.keys() - inputs_dict.keys(), reverse=True) + if not added_label_names: + continue # This test is only for models with easily-separable labels + added_label = prepared_for_class[added_label_names[0]] + expected_loss_size = added_label.shape.as_list()[:1] + + # Test that model correctly compute the loss with kwargs + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + possible_input_names = {"input_ids", "pixel_values", "input_features", "input_values"} + input_name = possible_input_names.intersection(set(prepared_for_class)).pop() + model_input = prepared_for_class.pop(input_name) + + loss = model(model_input, **prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + # Test that model correctly compute the loss when we mask some positions + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + possible_input_names = {"input_ids", "pixel_values", "input_features", "input_values"} + input_name = possible_input_names.intersection(set(prepared_for_class)).pop() + model_input = prepared_for_class.pop(input_name) + if "labels" in prepared_for_class: + labels = prepared_for_class["labels"].numpy() + if len(labels.shape) > 1 and labels.shape[1] != 1: + labels[0] = -100 + prepared_for_class["labels"] = tf.convert_to_tensor(labels) + loss = model(model_input, **prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + self.assertTrue(not np.any(np.isnan(loss.numpy()))) + + # Test that model correctly compute the loss with a dict + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + loss = model(prepared_for_class)[0] + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + # Test that model correctly compute the loss with a tuple + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + + # Get keys that were added with the _prepare_for_class function + label_keys = prepared_for_class.keys() - inputs_dict.keys() + signature = inspect.signature(model.call).parameters + signature_names = list(signature.keys()) + + # Create a dictionary holding the location of the tensors in the tuple + tuple_index_mapping = {0: input_name} + for label_key in label_keys: + label_key_index = signature_names.index(label_key) + tuple_index_mapping[label_key_index] = label_key + sorted_tuple_index_mapping = sorted(tuple_index_mapping.items()) + # Initialize a list with their default values, update the values and convert to a tuple + list_input = [] + + for name in signature_names: + if name != "kwargs": + list_input.append(signature[name].default) + + for index, value in sorted_tuple_index_mapping: + list_input[index] = prepared_for_class[value] + + tuple_input = tuple(list_input) + + # Send to model + loss = model(tuple_input[:-1])[0] + + self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]) + + def check_keras_fit_results(self, val_loss1, val_loss2, atol=1e-2, rtol=1e-3): + self.assertTrue(np.allclose(val_loss1, val_loss2, atol=atol, rtol=rtol)) + + def test_keras_fit(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + if not getattr(model, "hf_compute_loss", False) and not _return_type_has_loss(model): + continue + # Test that model correctly compute the loss with kwargs + prepared_for_class = self._prepare_for_class(inputs_dict.copy(), model_class, return_labels=True) + # Is there a better way to remove these decoder inputs? + # We also remove "return_loss" as this is covered by the train_step when using fit() + prepared_for_class = { + key: val + for key, val in prepared_for_class.items() + if key + not in ("head_mask", "decoder_head_mask", "cross_attn_head_mask", "decoder_input_ids", "return_loss") + } + + accuracy_classes = [ + "ForPreTraining", + "ForCausalLM", + "ForMaskedLM", + "ForQuestionAnswering", + "ForMultipleChoice", + "ForSequenceClassification", + "ForTokenClassification", + "ForNextSentencePrediction", + "LMHeadModel", + ] + for accuracy_class in accuracy_classes: + if model.__class__.__name__.endswith(accuracy_class): + metrics = [tf.keras.metrics.SparseCategoricalAccuracy()] + break + else: + metrics = [] + + if hasattr(self.model_tester, "batch_size"): + sample_weight = tf.convert_to_tensor([0.5] * self.model_tester.batch_size, dtype=tf.float32) + else: + sample_weight = None + + model(model.dummy_inputs) # Build the model so we can get some constant weights + model_weights = model.get_weights() + + # Run eagerly to save some expensive compilation times + model.compile(optimizer=tf.keras.optimizers.SGD(0.0), run_eagerly=True, metrics=metrics) + # Make sure the model fits without crashing regardless of where we pass the labels + history1 = model.fit( + prepared_for_class, + validation_data=prepared_for_class, + sample_weight=sample_weight, + steps_per_epoch=1, + validation_steps=1, + shuffle=False, + ) + val_loss1 = history1.history["val_loss"][0] + self.assertTrue(not isnan(val_loss1)) + accuracy1 = {key: val[0] for key, val in history1.history.items() if key.endswith("accuracy")} + + possible_label_cols = { + "labels", + "label", + "label_ids", + "start_positions", + "start_position", + "end_positions", + "end_position", + "next_sentence_label", + } + label_names = possible_label_cols.intersection(set(prepared_for_class)) + if len(label_names) == 0: + # The next tests only make sense for models with separate inputs and labels, and do not make + # sense for models that don't clearly distinguish between the two (e.g. CLIP) + return + labels = {key: val for key, val in prepared_for_class.items() if key in label_names} + inputs_minus_labels = {key: val for key, val in prepared_for_class.items() if key not in label_names} + self.assertGreater(len(inputs_minus_labels), 0) + + # We reinitialize the model here even though our learning rate was zero + # because BatchNorm updates weights by means other than gradient descent. + model.set_weights(model_weights) + + history2 = model.fit( + inputs_minus_labels, + labels, + validation_data=(inputs_minus_labels, labels), + sample_weight=sample_weight, + steps_per_epoch=1, + validation_steps=1, + shuffle=False, + ) + val_loss2 = history2.history["val_loss"][0] + self.assertTrue(not isnan(val_loss2)) + accuracy2 = {key: val[0] for key, val in history2.history.items() if key.endswith("accuracy")} + self.check_keras_fit_results(val_loss1, val_loss2) + self.assertEqual(history1.history.keys(), history2.history.keys()) + for key in history1.history.keys(): + if not key.startswith("val_"): + self.assertTrue("val_" + key in history1.history.keys(), "Outputs differ in train/test step!") + if metrics: + self.assertTrue(len(accuracy1) == len(accuracy2) > 0, "Missing metrics!") + + # Make sure fit works with tf.data.Dataset and results are consistent + dataset = tf.data.Dataset.from_tensor_slices(prepared_for_class) + + if sample_weight is not None: + # Add in the sample weight + weighted_dataset = dataset.map(lambda x: (x, None, tf.convert_to_tensor(0.5, dtype=tf.float32))) + else: + weighted_dataset = dataset + # Pass in all samples as a batch to match other `fit` calls + weighted_dataset = weighted_dataset.batch(len(dataset)) + dataset = dataset.batch(len(dataset)) + + # Reinitialize to fix batchnorm again + model.set_weights(model_weights) + + # To match the other calls, don't pass sample weights in the validation data + history3 = model.fit( + weighted_dataset, + validation_data=dataset, + steps_per_epoch=1, + validation_steps=1, + shuffle=False, + ) + val_loss3 = history3.history["val_loss"][0] + self.assertTrue(not isnan(val_loss3)) + accuracy3 = {key: val[0] for key, val in history3.history.items() if key.endswith("accuracy")} + self.check_keras_fit_results(val_loss1, val_loss3) + self.assertEqual(history1.history.keys(), history3.history.keys()) + if metrics: + self.assertTrue(len(accuracy1) == len(accuracy3) > 0, "Missing metrics!") + + def test_int_support(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + prepared_for_class = self._prepare_for_class( + inputs_dict.copy(), + model_class, + return_labels=True if "labels" in inspect.signature(model_class.call).parameters.keys() else False, + ) + if not any( + [tensor.dtype.is_integer for tensor in prepared_for_class.values() if isinstance(tensor, tf.Tensor)] + ): + return # No integer inputs means no need for this test + + prepared_for_class = { + key: tf.cast(tensor, tf.int64) if isinstance(tensor, tf.Tensor) and tensor.dtype.is_integer else tensor + for key, tensor in prepared_for_class.items() + } + model = model_class(config) + model(**prepared_for_class) # No assertion, we're just checking this doesn't throw an error + int32_prepared_for_class = { + key: tf.cast(tensor, tf.int32) if isinstance(tensor, tf.Tensor) and tensor.dtype.is_integer else tensor + for key, tensor in prepared_for_class.items() + } + model(**int32_prepared_for_class) # No assertion, we're just checking this doesn't throw an error + + # After testing that the model accepts all int inputs, confirm that its dummies are int32 + for key, tensor in model.dummy_inputs.items(): + self.assertTrue(isinstance(tensor, tf.Tensor), "Dummy inputs should be tf.Tensor!") + if tensor.dtype.is_integer: + self.assertTrue(tensor.dtype == tf.int32, "Integer dummy inputs should be tf.int32!") + + # Also confirm that the serving sig uses int32 + if hasattr(model, "serving"): + serving_sig = model.serving.input_signature + for key, tensor_spec in serving_sig[0].items(): + if tensor_spec.dtype.is_integer: + self.assertTrue( + tensor_spec.dtype == tf.int32, "Serving signatures should use tf.int32 for ints!" + ) + + def test_generate_with_headmasking(self): + attention_names = ["encoder_attentions", "decoder_attentions", "cross_attentions"] + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_generative_model_classes: + model = model_class(config) + + # We want to test only encoder-decoder models + if not config.is_encoder_decoder: + continue + + head_masking = { + "head_mask": tf.zeros((config.encoder_layers, config.encoder_attention_heads)), + "decoder_head_mask": tf.zeros((config.decoder_layers, config.decoder_attention_heads)), + "cross_attn_head_mask": tf.zeros((config.decoder_layers, config.decoder_attention_heads)), + } + + signature = inspect.signature(model.call) + if set(head_masking.keys()) < {*signature.parameters.keys()}: + continue + + for attn_name, (name, mask) in zip(attention_names, head_masking.items()): + out = model.generate( + inputs_dict["input_ids"], + num_beams=1, + max_length=inputs_dict["input_ids"] + 5, + output_attentions=True, + return_dict_in_generate=True, + **{name: mask}, + ) + # We check the state of decoder_attentions and cross_attentions just from the last step + attn_weights = out[attn_name] if attn_name == attention_names[0] else out[attn_name][-1] + self.assertEqual(sum([tf.reduce_sum(w).numpy() for w in attn_weights]), 0.0) + + def test_load_with_mismatched_shapes(self): + if not self.test_mismatched_shapes: + return + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + + for model_class in self.all_model_classes: + if model_class not in get_values(TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING): + continue + + with self.subTest(msg=f"Testing {model_class}"): + with tempfile.TemporaryDirectory() as tmp_dir: + model = model_class(config) + inputs = self._prepare_for_class(inputs_dict, model_class) + _ = model(**inputs) + model.save_pretrained(tmp_dir) + + # Fails when we don't set ignore_mismatched_sizes=True + with self.assertRaises(ValueError): + new_model = TFAutoModelForSequenceClassification.from_pretrained(tmp_dir, num_labels=42) + with self.assertRaises(ValueError): + new_model_without_prefix = TFAutoModel.from_pretrained(tmp_dir, vocab_size=10) + + logger = logging.get_logger("transformers.modeling_tf_utils") + with CaptureLogger(logger) as cl: + new_model = TFAutoModelForSequenceClassification.from_pretrained( + tmp_dir, num_labels=42, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + + logits = new_model(**inputs).logits + self.assertEqual(logits.shape[1], 42) + + with CaptureLogger(logger) as cl: + new_model_without_prefix = TFAutoModel.from_pretrained( + tmp_dir, vocab_size=10, ignore_mismatched_sizes=True + ) + self.assertIn("the shapes did not match", cl.out) + + # Although Tf models always have a prefix pointing to `MainLayer`, + # we still add this "without prefix" test to keep a consistency between tf and pt tests. + input_ids = ids_tensor((2, 8), 10) + if self.is_encoder_decoder: + new_model_without_prefix(input_ids, decoder_input_ids=input_ids) + else: + new_model_without_prefix(input_ids) + + def test_model_main_input_name(self): + for model_class in self.all_model_classes: + model_signature = inspect.signature(getattr(model_class, "call")) + # The main input is the name of the argument after `self` + observed_main_input_name = list(model_signature.parameters.keys())[1] + self.assertEqual(model_class.main_input_name, observed_main_input_name) + + def test_dataset_conversion(self): + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + for model_class in self.all_model_classes: + model = model_class(config) + tf_inputs_dict = self._prepare_for_class(inputs_dict, model_class, return_labels=False) + if "labels" in tf_inputs_dict: + return # This is some kinda funky decoder model that needs labels in its forward pass + tf_inputs_dict = { + key: val + for key, val in tf_inputs_dict.items() + if "head_mask" not in key and isinstance(val, tf.Tensor) + } + tf_inputs_dict["extra_unwanted_column"] = list(tf_inputs_dict.values())[0] # Use a random other tensor + input_dataset = Dataset.from_dict(tf_inputs_dict) + tf_dataset = model.prepare_tf_dataset( + input_dataset, batch_size=len(input_dataset), drop_remainder=False, shuffle=False + ) + test_batch = next(iter(tf_dataset)) + if isinstance(test_batch, tf.Tensor): + self.assertEqual(len(test_batch), len(input_dataset)) # Assert we didn't lose any data + elif isinstance(test_batch, dict): + # Assert we discarded the unwanted extra column but kept everything else + self.assertEqual(len(test_batch), len(input_dataset.features) - 1) + self.assertNotIn("extra_unwanted_column", test_batch) + for tensor in test_batch.values(): + self.assertTrue(isinstance(tensor, tf.Tensor)) + self.assertEqual(len(tensor), len(input_dataset)) # Assert we didn't lose any data + model(test_batch, training=False) + + if "labels" in inspect.signature(model_class.call).parameters.keys(): + tf_inputs_dict = self._prepare_for_class(inputs_dict, model_class, return_labels=True) + if "labels" not in tf_inputs_dict: + return # This model isn't giving us labels after all, don't try training with it + tf_inputs_dict = {key: val for key, val in tf_inputs_dict.items() if "head_mask" not in key} + tf_inputs_dict["extra_unwanted_column"] = list(tf_inputs_dict.values())[0] # Use a random other tensor + input_dataset = Dataset.from_dict(tf_inputs_dict) + tf_dataset = model.prepare_tf_dataset( + input_dataset, batch_size=len(input_dataset), drop_remainder=False, shuffle=False + ) + test_batch, test_batch_labels = next(iter(tf_dataset)) + self.assertGreater(len(test_batch_labels), 0) # Assert the labels are present + feature_columns = 1 if isinstance(test_batch, tf.Tensor) else len(test_batch) + label_columns = 1 if isinstance(test_batch_labels, tf.Tensor) else len(test_batch_labels) + # Assert we discarded the unwanted extra column but kept everything else + self.assertEqual(feature_columns + label_columns, len(input_dataset.features) - 1) + if isinstance(test_batch, dict): + self.assertNotIn("extra_unwanted_column", test_batch) + if isinstance(test_batch_labels, dict): + self.assertNotIn("extra_unwanted_column", test_batch_labels) + model.compile(optimizer="sgd", run_eagerly=True) + model.train_on_batch(test_batch, test_batch_labels) + + def _test_xla_generate(self, **generate_kwargs): + def _generate_and_check_results(model, inputs_dict): + if "input_ids" in inputs_dict: + inputs = inputs_dict["input_ids"] + # make sure there are no pad tokens in prompt, which may trigger unwanted behavior + if model.generation_config.pad_token_id is not None: + if config.pad_token_id == 0: + new_pad_token = model.generation_config.pad_token_id + 1 + else: + new_pad_token = model.generation_config.pad_token_id - 1 + else: + new_pad_token = None + inputs = tf.where(inputs != model.generation_config.pad_token_id, inputs, new_pad_token) + elif "input_features" in inputs_dict: + inputs = inputs_dict["input_features"] + else: + raise ValueError("No valid generate input found in inputs_dict") + + generated = model.generate(inputs, **generate_kwargs).numpy() + generate_xla = tf.function(model.generate, jit_compile=True) + generated_xla = generate_xla(inputs, **generate_kwargs).numpy() + + # Due to numerical instability, let's fail the test only if there are more than 10% of input sequences give + # different outputs between XLA and non-XLA versions. If there are less than 10 examples, let's be strict + # and not allow any difference. + diff = [[], []] + for _generated, _generated_xla in zip(generated.tolist(), generated_xla.tolist()): + if _generated != _generated_xla: + diff[0].append(_generated) + diff[1].append(_generated_xla) + ratio = len(diff[0]) / len(generated) + if ratio > 0.1 or (len(diff[0]) > 0 and len(generated) < 10): + self.assertListEqual(diff[0], diff[1]) + + for model_class in self.all_generative_model_classes: + config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() + config.eos_token_id = None # Generate until max length + config.do_sample = False + + # fix config for models with additional sequence-length limiting settings + for var_name in ["max_position_embeddings", "max_target_positions"]: + attr = getattr(config, var_name, None) + if attr is not None and attr < generate_kwargs["max_new_tokens"]: + try: + setattr(config, var_name, generate_kwargs["max_new_tokens"]) + except NotImplementedError: + # xlnet will raise an exception when trying to set + # max_position_embeddings. + pass + + model = model_class(config) + + if model.supports_xla_generation: + _generate_and_check_results(model, inputs_dict) + else: + with self.assertRaises(ValueError): + _generate_and_check_results(model, inputs_dict) + + def test_xla_generate_fast(self): + """ + Basic quick test for generate-compatible classes that confirms that XLA-generated tokens are the same as their + non XLA counterparts. + + Either the model supports XLA generation and passes the inner test, or it raises an appropriate exception + """ + self._test_xla_generate(num_beams=1, num_return_sequences=1, max_new_tokens=3) + + @slow + def test_xla_generate_contrastive(self): + """ + Slow and challenging version of `test_xla_generate_fast` for contrastive search -- contrastive search directly + manipulates the model cache and other outputs, and this test ensures that they are in a valid format that is + also supported by XLA. + + Either the model supports XLA generation and passes the inner test, or it raises an appropriate exception + """ + self._test_xla_generate(num_beams=1, num_return_sequences=1, max_new_tokens=16, penalty_alpha=0.5, top_k=4) + + @slow + def test_xla_generate_slow(self): + """ + Slow and challenging version of `test_xla_generate_fast` -- this test asks for several long sequences using + beam search, with and without XLA. The two outputs should match, and a failure in this test indicates that the + model may need further analysis if it is to be used for XLA generation. + + Either the model supports XLA generation and passes the inner test, or it raises an appropriate exception + """ + self._test_xla_generate(num_beams=8, num_return_sequences=2, max_new_tokens=128) + + def _generate_random_bad_tokens(self, num_bad_tokens, model): + # special tokens cannot be bad tokens + special_tokens = [] + if model.config.bos_token_id is not None: + special_tokens.append(model.config.bos_token_id) + if model.config.pad_token_id is not None: + special_tokens.append(model.config.pad_token_id) + if model.config.eos_token_id is not None: + special_tokens.append(model.config.eos_token_id) + + # create random bad tokens that are not special tokens + bad_tokens = [] + while len(bad_tokens) < num_bad_tokens: + token = tf.squeeze(ids_tensor((1, 1), self.model_tester.vocab_size), 0).numpy()[0] + if token not in special_tokens: + bad_tokens.append(token) + return bad_tokens + + def _check_generated_ids(self, output_ids): + for token_id in output_ids[0].numpy().tolist(): + self.assertGreaterEqual(token_id, 0) + self.assertLess(token_id, self.model_tester.vocab_size) + + def _check_match_tokens(self, generated_ids, bad_words_ids): + # for all bad word tokens + for bad_word_ids in bad_words_ids: + # for all slices in batch + for generated_ids_slice in generated_ids: + # for all word idx + for i in range(len(bad_word_ids), len(generated_ids_slice)): + # if tokens match + if generated_ids_slice[i - len(bad_word_ids) : i] == bad_word_ids: + return True + return False + + +def ids_tensor(shape, vocab_size, rng=None, name=None, dtype=None): + """Creates a random int32 tensor of the shape within the vocab size.""" + if rng is None: + rng = random.Random() + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.randint(0, vocab_size - 1)) + + output = tf.constant(values, shape=shape, dtype=dtype if dtype is not None else tf.int32) + + return output + + +def random_attention_mask(shape, rng=None, name=None, dtype=None): + attn_mask = ids_tensor(shape, vocab_size=2, rng=None, name=None, dtype=dtype) + # make sure that at least one token is attended to for each batch + attn_mask = tf.concat([attn_mask[:, :-1], tf.ones_like(attn_mask[:, -1:], dtype=dtype)], axis=-1) + return attn_mask + + +def floats_tensor(shape, scale=1.0, rng=None, name=None, dtype=None): + """Creates a random float32 tensor""" + if rng is None: + rng = random.Random() + + total_dims = 1 + for dim in shape: + total_dims *= dim + + values = [] + for _ in range(total_dims): + values.append(rng.random() * scale) + + return tf.reshape(tf.constant(values, dtype=dtype if dtype is not None else tf.float32), shape=shape) + + +@require_tf +class UtilsFunctionsTest(unittest.TestCase): + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Under the mock environment we get a 500 error when trying to reach the model. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + # This check we did call the fake head request + mock_head.assert_called() + + def test_load_from_one_file(self): + try: + tmp_file = tempfile.mktemp() + with open(tmp_file, "wb") as f: + http_get("https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/tf_model.h5", f) + + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + _ = TFBertModel.from_pretrained(tmp_file, config=config) + finally: + os.remove(tmp_file) + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + config = BertConfig.from_pretrained("hf-internal-testing/tiny-random-bert") + _ = TFBertModel.from_pretrained( + "https://huggingface.co/hf-internal-testing/tiny-random-bert/resolve/main/tf_model.h5", config=config + ) + + # tests whether the unpack_inputs function behaves as expected + def test_unpack_inputs(self): + class DummyModel: + def __init__(self): + config_kwargs = {"output_attentions": False, "output_hidden_states": False, "return_dict": False} + self.config = PretrainedConfig(**config_kwargs) + self.main_input_name = "input_ids" + + @unpack_inputs + def call( + self, + input_ids=None, + past_key_values=None, + output_attentions=None, + output_hidden_states=None, + return_dict=None, + ): + return input_ids, past_key_values, output_attentions, output_hidden_states, return_dict + + @unpack_inputs + def foo(self, pixel_values, output_attentions=None, output_hidden_states=None, return_dict=None): + return pixel_values, output_attentions, output_hidden_states, return_dict + + dummy_model = DummyModel() + input_ids = tf.constant([0, 1, 2, 3], dtype=tf.int32) + past_key_values = tf.constant([4, 5, 6, 7], dtype=tf.int32) + pixel_values = tf.constant([8, 9, 10, 11], dtype=tf.int32) + + # test case 1: Pass inputs as keyword arguments; Booleans are inherited from the config. + output = dummy_model.call(input_ids=input_ids, past_key_values=past_key_values) + tf.debugging.assert_equal(output[0], input_ids) + tf.debugging.assert_equal(output[1], past_key_values) + self.assertFalse(output[2]) + self.assertFalse(output[3]) + self.assertFalse(output[4]) + + # test case 2: Same as above, but with positional arguments. + output = dummy_model.call(input_ids, past_key_values) + tf.debugging.assert_equal(output[0], input_ids) + tf.debugging.assert_equal(output[1], past_key_values) + self.assertFalse(output[2]) + self.assertFalse(output[3]) + self.assertFalse(output[4]) + + # test case 3: We can also pack everything in the first input. + output = dummy_model.call(input_ids={"input_ids": input_ids, "past_key_values": past_key_values}) + tf.debugging.assert_equal(output[0], input_ids) + tf.debugging.assert_equal(output[1], past_key_values) + self.assertFalse(output[2]) + self.assertFalse(output[3]) + self.assertFalse(output[4]) + + # test case 4: Explicit boolean arguments should override the config. + output = dummy_model.call( + input_ids=input_ids, past_key_values=past_key_values, output_attentions=False, return_dict=True + ) + tf.debugging.assert_equal(output[0], input_ids) + tf.debugging.assert_equal(output[1], past_key_values) + self.assertFalse(output[2]) + self.assertFalse(output[3]) + self.assertTrue(output[4]) + + # test case 5: Unexpected arguments should raise an exception. + with self.assertRaises(ValueError): + output = dummy_model.call(input_ids=input_ids, past_key_values=past_key_values, foo="bar") + + # test case 6: the decorator is independent from `main_input_name` -- it treats the first argument of the + # decorated function as its main input. + output = dummy_model.foo(pixel_values=pixel_values) + tf.debugging.assert_equal(output[0], pixel_values) + self.assertFalse(output[1]) + self.assertFalse(output[2]) + self.assertFalse(output[3]) + + # Tests whether the stable softmax is stable on CPU, with and without XLA + def test_xla_stable_softmax(self): + large_penalty = -1e9 + n_tokens = 10 + batch_size = 8 + + def masked_softmax(x, boolean_mask): + numerical_mask = (1.0 - tf.cast(boolean_mask, dtype=tf.float32)) * large_penalty + masked_x = x + numerical_mask + return stable_softmax(masked_x) + + xla_masked_softmax = tf.function(masked_softmax, jit_compile=True) + xla_stable_softmax = tf.function(stable_softmax, jit_compile=True) + x = tf.random.normal((batch_size, n_tokens)) + + # Same outcome regardless of the boolean mask here + masked_tokens = random.randint(0, n_tokens) + boolean_mask = tf.convert_to_tensor([[1] * (n_tokens - masked_tokens) + [0] * masked_tokens], dtype=tf.int32) + + # We can randomly mask a random numerical input OUTSIDE XLA + numerical_mask = (1.0 - tf.cast(boolean_mask, dtype=tf.float32)) * large_penalty + masked_x = x + numerical_mask + xla_out = xla_stable_softmax(masked_x) + out = stable_softmax(masked_x) + assert tf.experimental.numpy.allclose(xla_out, out) + + # The stable softmax has the same output as the original softmax + unstable_out = tf.nn.softmax(masked_x) + assert tf.experimental.numpy.allclose(unstable_out, out) + + # We can randomly mask a random numerical input INSIDE XLA + xla_out = xla_masked_softmax(x, boolean_mask) + out = masked_softmax(x, boolean_mask) + assert tf.experimental.numpy.allclose(xla_out, out) + + def test_checkpoint_sharding_from_hub(self): + model = TFBertModel.from_pretrained("ArthurZ/tiny-random-bert-sharded") + # the model above is the same as the model below, just a sharded version. + ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + for p1, p2 in zip(model.weights, ref_model.weights): + assert np.allclose(p1.numpy(), p2.numpy()) + + def test_sharded_checkpoint_with_prefix(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert", load_weight_prefix="a/b") + sharded_model = TFBertModel.from_pretrained("ArthurZ/tiny-random-bert-sharded", load_weight_prefix="a/b") + for p1, p2 in zip(model.weights, sharded_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + self.assertTrue(p1.name.startswith("a/b/")) + self.assertTrue(p2.name.startswith("a/b/")) + + def test_sharded_checkpoint_transfer(self): + # If this doesn't throw an error then the test passes + TFBertForSequenceClassification.from_pretrained("ArthurZ/tiny-random-bert-sharded") + + @is_pt_tf_cross_test + def test_checkpoint_sharding_local_from_pt(self): + with tempfile.TemporaryDirectory() as tmp_dir: + _ = Repository(local_dir=tmp_dir, clone_from="hf-internal-testing/tiny-random-bert-sharded") + model = TFBertModel.from_pretrained(tmp_dir, from_pt=True) + # the model above is the same as the model below, just a sharded pytorch version. + ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + for p1, p2 in zip(model.weights, ref_model.weights): + assert np.allclose(p1.numpy(), p2.numpy()) + + @is_pt_tf_cross_test + def test_checkpoint_loading_with_prefix_from_pt(self): + model = TFBertModel.from_pretrained( + "hf-internal-testing/tiny-random-bert", from_pt=True, load_weight_prefix="a/b" + ) + ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert", from_pt=True) + for p1, p2 in zip(model.weights, ref_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + self.assertTrue(p1.name.startswith("a/b/")) + + @is_pt_tf_cross_test + def test_checkpoint_sharding_hub_from_pt(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-sharded", from_pt=True) + # the model above is the same as the model below, just a sharded pytorch version. + ref_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + for p1, p2 in zip(model.weights, ref_model.weights): + assert np.allclose(p1.numpy(), p2.numpy()) + + def test_shard_checkpoint(self): + # This is the model we will use, total size 340,000 bytes. + model = tf.keras.Sequential( + [ + tf.keras.layers.Dense(200, use_bias=False), # size 80,000 + tf.keras.layers.Dense(200, use_bias=False), # size 160,000 + tf.keras.layers.Dense(100, use_bias=False), # size 80,000 + tf.keras.layers.Dense(50, use_bias=False), # size 20,000 + ] + ) + inputs = tf.zeros((1, 100), dtype=tf.float32) + model(inputs) + weights = model.weights + weights_dict = {w.name: w for w in weights} + with self.subTest("No shard when max size is bigger than model size"): + shards, index = tf_shard_checkpoint(weights) + self.assertIsNone(index) + self.assertDictEqual(shards, {TF2_WEIGHTS_NAME: weights}) + + with self.subTest("Test sharding, no weights bigger than max size"): + shards, index = tf_shard_checkpoint(weights, max_shard_size="300kB") + # Split is first two layers then last two. + self.assertDictEqual( + index, + { + "metadata": {"total_size": 340000}, + "weight_map": { + "dense/kernel:0": "tf_model-00001-of-00002.h5", + "dense_1/kernel:0": "tf_model-00001-of-00002.h5", + "dense_2/kernel:0": "tf_model-00002-of-00002.h5", + "dense_3/kernel:0": "tf_model-00002-of-00002.h5", + }, + }, + ) + + shard1 = [weights_dict["dense/kernel:0"], weights_dict["dense_1/kernel:0"]] + shard2 = [weights_dict["dense_2/kernel:0"], weights_dict["dense_3/kernel:0"]] + self.assertDictEqual(shards, {"tf_model-00001-of-00002.h5": shard1, "tf_model-00002-of-00002.h5": shard2}) + + with self.subTest("Test sharding with weights bigger than max size"): + shards, index = tf_shard_checkpoint(weights, max_shard_size="100kB") + # Split is first layer, second layer then last 2. + self.assertDictEqual( + index, + { + "metadata": {"total_size": 340000}, + "weight_map": { + "dense/kernel:0": "tf_model-00001-of-00003.h5", + "dense_1/kernel:0": "tf_model-00002-of-00003.h5", + "dense_2/kernel:0": "tf_model-00003-of-00003.h5", + "dense_3/kernel:0": "tf_model-00003-of-00003.h5", + }, + }, + ) + + shard1 = [weights_dict["dense/kernel:0"]] + shard2 = [weights_dict["dense_1/kernel:0"]] + shard3 = [weights_dict["dense_2/kernel:0"], weights_dict["dense_3/kernel:0"]] + self.assertDictEqual( + shards, + { + "tf_model-00001-of-00003.h5": shard1, + "tf_model-00002-of-00003.h5": shard2, + "tf_model-00003-of-00003.h5": shard3, + }, + ) + + @slow + def test_special_layer_name_sharding(self): + retriever = RagRetriever.from_pretrained("facebook/rag-token-nq", index_name="exact", use_dummy_dataset=True) + model = TFRagModel.from_pretrained("facebook/rag-token-nq", retriever=retriever) + + with tempfile.TemporaryDirectory() as tmp_dir: + for max_size in ["150kB", "150kiB", "200kB", "200kiB"]: + model.save_pretrained(tmp_dir, max_shard_size=max_size) + ref_model = TFRagModel.from_pretrained(tmp_dir, retriever=retriever) + for p1, p2 in zip(model.weights, ref_model.weights): + assert np.allclose(p1.numpy(), p2.numpy()) + + def test_checkpoint_sharding_local(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + with tempfile.TemporaryDirectory() as tmp_dir: + # We use the same folder for various sizes to make sure a new save erases the old checkpoint. + for max_size in ["150kB", "150kiB", "200kB", "200kiB"]: + model.save_pretrained(tmp_dir, max_shard_size=max_size) + + # Get each shard file and its size + shard_to_size = {} + for shard in os.listdir(tmp_dir): + if shard.endswith(".h5"): + shard_file = os.path.join(tmp_dir, shard) + shard_to_size[shard_file] = os.path.getsize(shard_file) + + index_file = os.path.join(tmp_dir, TF2_WEIGHTS_INDEX_NAME) + # Check there is an index but no regular weight file + self.assertTrue(os.path.isfile(index_file)) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, TF2_WEIGHTS_NAME))) + + # Check a file is bigger than max_size only when it has a single weight + for shard_file, size in shard_to_size.items(): + if max_size.endswith("kiB"): + max_size_int = int(max_size[:-3]) * 2**10 + else: + max_size_int = int(max_size[:-2]) * 10**3 + # Note: pickle adds some junk so the weight of the file can end up being slightly bigger than + # the size asked for (since we count parameters) + if size >= max_size_int + 50000: + with h5py.File(shard_file, "r") as state_file: + self.assertEqual(len(state_file), 1) + + # Check the index and the shard files found match + with open(index_file, "r", encoding="utf-8") as f: + index = json.loads(f.read()) + + all_shards = set(index["weight_map"].values()) + shards_found = {f for f in os.listdir(tmp_dir) if f.endswith(".h5")} + self.assertSetEqual(all_shards, shards_found) + + # Finally, check the model can be reloaded + new_model = TFBertModel.from_pretrained(tmp_dir) + + model(model.dummy_inputs) + new_model(model.dummy_inputs) + + for p1, p2 in zip(model.weights, new_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + + @slow + def test_save_pretrained_signatures(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Short custom TF signature function. + # `input_signature` is specific to BERT. + @tf.function( + input_signature=[ + [ + tf.TensorSpec([None, None], tf.int32, name="input_ids"), + tf.TensorSpec([None, None], tf.int32, name="token_type_ids"), + tf.TensorSpec([None, None], tf.int32, name="attention_mask"), + ] + ] + ) + def serving_fn(input): + return model(input) + + # Using default signature (default behavior) overrides 'serving_default' + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, saved_model=True, signatures=None) + model_loaded = tf.keras.models.load_model(f"{tmp_dir}/saved_model/1") + self.assertTrue("serving_default" in list(model_loaded.signatures.keys())) + + # Providing custom signature function + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, saved_model=True, signatures={"custom_signature": serving_fn}) + model_loaded = tf.keras.models.load_model(f"{tmp_dir}/saved_model/1") + self.assertTrue("custom_signature" in list(model_loaded.signatures.keys())) + + # Providing multiple custom signature function + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained( + tmp_dir, + saved_model=True, + signatures={"custom_signature_1": serving_fn, "custom_signature_2": serving_fn}, + ) + model_loaded = tf.keras.models.load_model(f"{tmp_dir}/saved_model/1") + self.assertTrue("custom_signature_1" in list(model_loaded.signatures.keys())) + self.assertTrue("custom_signature_2" in list(model_loaded.signatures.keys())) + + @require_safetensors + def test_safetensors_save_and_load(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, safe_serialization=True) + # No tf_model.h5 file, only a model.safetensors + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME))) + self.assertFalse(os.path.isfile(os.path.join(tmp_dir, TF2_WEIGHTS_NAME))) + + new_model = TFBertModel.from_pretrained(tmp_dir) + + # Check models are equal + for p1, p2 in zip(model.weights, new_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + + @is_pt_tf_cross_test + def test_safetensors_save_and_load_pt_to_tf(self): + model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + pt_model = BertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + with tempfile.TemporaryDirectory() as tmp_dir: + pt_model.save_pretrained(tmp_dir, safe_serialization=True) + # Check we have a model.safetensors file + self.assertTrue(os.path.isfile(os.path.join(tmp_dir, SAFE_WEIGHTS_NAME))) + + new_model = TFBertModel.from_pretrained(tmp_dir) + + # Check models are equal + for p1, p2 in zip(model.weights, new_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + + @require_safetensors + def test_safetensors_load_from_hub(self): + tf_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Can load from the TF-formatted checkpoint + safetensors_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors-tf") + + # Check models are equal + for p1, p2 in zip(safetensors_model.weights, tf_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + + # Can load from the PyTorch-formatted checkpoint + safetensors_model = TFBertModel.from_pretrained("hf-internal-testing/tiny-random-bert-safetensors") + + # Check models are equal + for p1, p2 in zip(safetensors_model.weights, tf_model.weights): + self.assertTrue(np.allclose(p1.numpy(), p2.numpy())) + + +@require_tf +@is_staging_test +class TFModelPushToHubTester(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-model-tf") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-model-tf-callback") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-model-tf-org") + except HTTPError: + pass + + def test_push_to_hub(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = TFBertModel(config) + # Make sure model is properly initialized + _ = model(model.dummy_inputs) + + logging.set_verbosity_info() + logger = logging.get_logger("transformers.utils.hub") + with CaptureLogger(logger) as cl: + model.push_to_hub("test-model-tf", use_auth_token=self._token) + logging.set_verbosity_warning() + # Check the model card was created and uploaded. + self.assertIn("Uploading the following files to __DUMMY_TRANSFORMERS_USER__/test-model-tf", cl.out) + + new_model = TFBertModel.from_pretrained(f"{USER}/test-model-tf") + models_equal = True + for p1, p2 in zip(model.weights, new_model.weights): + if not tf.math.reduce_all(p1 == p2): + models_equal = False + break + self.assertTrue(models_equal) + + # Reset repo + delete_repo(token=self._token, repo_id="test-model-tf") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained(tmp_dir, repo_id="test-model-tf", push_to_hub=True, use_auth_token=self._token) + + new_model = TFBertModel.from_pretrained(f"{USER}/test-model-tf") + models_equal = True + for p1, p2 in zip(model.weights, new_model.weights): + if not tf.math.reduce_all(p1 == p2): + models_equal = False + break + self.assertTrue(models_equal) + + @is_pt_tf_cross_test + def test_push_to_hub_callback(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = TFBertForMaskedLM(config) + model.compile() + + with tempfile.TemporaryDirectory() as tmp_dir: + push_to_hub_callback = PushToHubCallback( + output_dir=tmp_dir, + hub_model_id="test-model-tf-callback", + hub_token=self._token, + ) + model.fit(model.dummy_inputs, model.dummy_inputs, epochs=1, callbacks=[push_to_hub_callback]) + + new_model = TFBertForMaskedLM.from_pretrained(f"{USER}/test-model-tf-callback") + models_equal = True + for p1, p2 in zip(model.weights, new_model.weights): + if not tf.math.reduce_all(p1 == p2): + models_equal = False + break + self.assertTrue(models_equal) + + tf_push_to_hub_params = dict(inspect.signature(TFPreTrainedModel.push_to_hub).parameters) + tf_push_to_hub_params.pop("base_model_card_args") + pt_push_to_hub_params = dict(inspect.signature(PreTrainedModel.push_to_hub).parameters) + pt_push_to_hub_params.pop("deprecated_kwargs") + self.assertDictEaual(tf_push_to_hub_params, pt_push_to_hub_params) + + def test_push_to_hub_in_organization(self): + config = BertConfig( + vocab_size=99, hidden_size=32, num_hidden_layers=5, num_attention_heads=4, intermediate_size=37 + ) + model = TFBertModel(config) + # Make sure model is properly initialized + _ = model(model.dummy_inputs) + + model.push_to_hub("valid_org/test-model-tf-org", use_auth_token=self._token) + + new_model = TFBertModel.from_pretrained("valid_org/test-model-tf-org") + models_equal = True + for p1, p2 in zip(model.weights, new_model.weights): + if not tf.math.reduce_all(p1 == p2): + models_equal = False + break + self.assertTrue(models_equal) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-model-tf-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + model.save_pretrained( + tmp_dir, push_to_hub=True, use_auth_token=self._token, repo_id="valid_org/test-model-tf-org" + ) + + new_model = TFBertModel.from_pretrained("valid_org/test-model-tf-org") + models_equal = True + for p1, p2 in zip(model.weights, new_model.weights): + if not tf.math.reduce_all(p1 == p2): + models_equal = False + break + self.assertTrue(models_equal) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_pipeline_mixin.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_pipeline_mixin.py new file mode 100644 index 0000000000000000000000000000000000000000..904d94e4b2c97f451291da0f0fc665f5b4e1511e --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_pipeline_mixin.py @@ -0,0 +1,473 @@ +# coding=utf-8 +# Copyright 2023 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +import json +import os +import random +from pathlib import Path + +from transformers.testing_utils import ( + is_pipeline_test, + require_decord, + require_pytesseract, + require_timm, + require_torch, + require_torch_or_tf, + require_vision, +) +from transformers.utils import direct_transformers_import, logging + +from .pipelines.test_pipelines_audio_classification import AudioClassificationPipelineTests +from .pipelines.test_pipelines_automatic_speech_recognition import AutomaticSpeechRecognitionPipelineTests +from .pipelines.test_pipelines_conversational import ConversationalPipelineTests +from .pipelines.test_pipelines_depth_estimation import DepthEstimationPipelineTests +from .pipelines.test_pipelines_document_question_answering import DocumentQuestionAnsweringPipelineTests +from .pipelines.test_pipelines_feature_extraction import FeatureExtractionPipelineTests +from .pipelines.test_pipelines_fill_mask import FillMaskPipelineTests +from .pipelines.test_pipelines_image_classification import ImageClassificationPipelineTests +from .pipelines.test_pipelines_image_segmentation import ImageSegmentationPipelineTests +from .pipelines.test_pipelines_image_to_text import ImageToTextPipelineTests +from .pipelines.test_pipelines_mask_generation import MaskGenerationPipelineTests +from .pipelines.test_pipelines_object_detection import ObjectDetectionPipelineTests +from .pipelines.test_pipelines_question_answering import QAPipelineTests +from .pipelines.test_pipelines_summarization import SummarizationPipelineTests +from .pipelines.test_pipelines_table_question_answering import TQAPipelineTests +from .pipelines.test_pipelines_text2text_generation import Text2TextGenerationPipelineTests +from .pipelines.test_pipelines_text_classification import TextClassificationPipelineTests +from .pipelines.test_pipelines_text_generation import TextGenerationPipelineTests +from .pipelines.test_pipelines_token_classification import TokenClassificationPipelineTests +from .pipelines.test_pipelines_translation import TranslationPipelineTests +from .pipelines.test_pipelines_video_classification import VideoClassificationPipelineTests +from .pipelines.test_pipelines_visual_question_answering import VisualQuestionAnsweringPipelineTests +from .pipelines.test_pipelines_zero_shot import ZeroShotClassificationPipelineTests +from .pipelines.test_pipelines_zero_shot_audio_classification import ZeroShotAudioClassificationPipelineTests +from .pipelines.test_pipelines_zero_shot_image_classification import ZeroShotImageClassificationPipelineTests +from .pipelines.test_pipelines_zero_shot_object_detection import ZeroShotObjectDetectionPipelineTests + + +pipeline_test_mapping = { + "audio-classification": {"test": AudioClassificationPipelineTests}, + "automatic-speech-recognition": {"test": AutomaticSpeechRecognitionPipelineTests}, + "conversational": {"test": ConversationalPipelineTests}, + "depth-estimation": {"test": DepthEstimationPipelineTests}, + "document-question-answering": {"test": DocumentQuestionAnsweringPipelineTests}, + "feature-extraction": {"test": FeatureExtractionPipelineTests}, + "fill-mask": {"test": FillMaskPipelineTests}, + "image-classification": {"test": ImageClassificationPipelineTests}, + "image-segmentation": {"test": ImageSegmentationPipelineTests}, + "image-to-text": {"test": ImageToTextPipelineTests}, + "mask-generation": {"test": MaskGenerationPipelineTests}, + "object-detection": {"test": ObjectDetectionPipelineTests}, + "question-answering": {"test": QAPipelineTests}, + "summarization": {"test": SummarizationPipelineTests}, + "table-question-answering": {"test": TQAPipelineTests}, + "text2text-generation": {"test": Text2TextGenerationPipelineTests}, + "text-classification": {"test": TextClassificationPipelineTests}, + "text-generation": {"test": TextGenerationPipelineTests}, + "token-classification": {"test": TokenClassificationPipelineTests}, + "translation": {"test": TranslationPipelineTests}, + "video-classification": {"test": VideoClassificationPipelineTests}, + "visual-question-answering": {"test": VisualQuestionAnsweringPipelineTests}, + "zero-shot": {"test": ZeroShotClassificationPipelineTests}, + "zero-shot-audio-classification": {"test": ZeroShotAudioClassificationPipelineTests}, + "zero-shot-image-classification": {"test": ZeroShotImageClassificationPipelineTests}, + "zero-shot-object-detection": {"test": ZeroShotObjectDetectionPipelineTests}, +} + +for task, task_info in pipeline_test_mapping.items(): + test = task_info["test"] + task_info["mapping"] = { + "pt": getattr(test, "model_mapping", None), + "tf": getattr(test, "tf_model_mapping", None), + } + + +# The default value `hf-internal-testing` is for running the pipeline testing against the tiny models on the Hub. +# For debugging purpose, we can specify a local path which is the `output_path` argument of a previous run of +# `utils/create_dummy_models.py`. +TRANSFORMERS_TINY_MODEL_PATH = os.environ.get("TRANSFORMERS_TINY_MODEL_PATH", "hf-internal-testing") +if TRANSFORMERS_TINY_MODEL_PATH == "hf-internal-testing": + TINY_MODEL_SUMMARY_FILE_PATH = os.path.join(Path(__file__).parent.parent, "tests/utils/tiny_model_summary.json") +else: + TINY_MODEL_SUMMARY_FILE_PATH = os.path.join(TRANSFORMERS_TINY_MODEL_PATH, "reports", "tiny_model_summary.json") +with open(TINY_MODEL_SUMMARY_FILE_PATH) as fp: + tiny_model_summary = json.load(fp) + + +PATH_TO_TRANSFORMERS = os.path.join(Path(__file__).parent.parent, "src/transformers") + + +# Dynamically import the Transformers module to grab the attribute classes of the processor form their names. +transformers_module = direct_transformers_import(PATH_TO_TRANSFORMERS) + +logger = logging.get_logger(__name__) + + +class PipelineTesterMixin: + model_tester = None + pipeline_model_mapping = None + supported_frameworks = ["pt", "tf"] + + def run_task_tests(self, task): + """Run pipeline tests for a specific `task` + + Args: + task (`str`): + A task name. This should be a key in the mapping `pipeline_test_mapping`. + """ + if task not in self.pipeline_model_mapping: + self.skipTest( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: `{task}` is not in " + f"`self.pipeline_model_mapping` for `{self.__class__.__name__}`." + ) + + model_architectures = self.pipeline_model_mapping[task] + if not isinstance(model_architectures, tuple): + model_architectures = (model_architectures,) + if not isinstance(model_architectures, tuple): + raise ValueError(f"`model_architectures` must be a tuple. Got {type(model_architectures)} instead.") + + for model_architecture in model_architectures: + model_arch_name = model_architecture.__name__ + + # Get the canonical name + for _prefix in ["Flax", "TF"]: + if model_arch_name.startswith(_prefix): + model_arch_name = model_arch_name[len(_prefix) :] + break + + tokenizer_names = [] + processor_names = [] + commit = None + if model_arch_name in tiny_model_summary: + tokenizer_names = tiny_model_summary[model_arch_name]["tokenizer_classes"] + processor_names = tiny_model_summary[model_arch_name]["processor_classes"] + if "sha" in tiny_model_summary[model_arch_name]: + commit = tiny_model_summary[model_arch_name]["sha"] + # Adding `None` (if empty) so we can generate tests + tokenizer_names = [None] if len(tokenizer_names) == 0 else tokenizer_names + processor_names = [None] if len(processor_names) == 0 else processor_names + + repo_name = f"tiny-random-{model_arch_name}" + if TRANSFORMERS_TINY_MODEL_PATH != "hf-internal-testing": + repo_name = model_arch_name + + self.run_model_pipeline_tests( + task, repo_name, model_architecture, tokenizer_names, processor_names, commit + ) + + def run_model_pipeline_tests(self, task, repo_name, model_architecture, tokenizer_names, processor_names, commit): + """Run pipeline tests for a specific `task` with the give model class and tokenizer/processor class names + + Args: + task (`str`): + A task name. This should be a key in the mapping `pipeline_test_mapping`. + repo_name (`str`): + A model repository id on the Hub. + model_architecture (`type`): + A subclass of `PretrainedModel` or `PretrainedModel`. + tokenizer_names (`List[str]`): + A list of names of a subclasses of `PreTrainedTokenizerFast` or `PreTrainedTokenizer`. + processor_names (`List[str]`): + A list of names of subclasses of `BaseImageProcessor` or `FeatureExtractionMixin`. + """ + # Get an instance of the corresponding class `XXXPipelineTests` in order to use `get_test_pipeline` and + # `run_pipeline_test`. + pipeline_test_class_name = pipeline_test_mapping[task]["test"].__name__ + + for tokenizer_name in tokenizer_names: + for processor_name in processor_names: + if self.is_pipeline_test_to_skip( + pipeline_test_class_name, + model_architecture.config_class, + model_architecture, + tokenizer_name, + processor_name, + ): + logger.warning( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: test is " + f"currently known to fail for: model `{model_architecture.__name__}` | tokenizer " + f"`{tokenizer_name}` | processor `{processor_name}`." + ) + continue + self.run_pipeline_test(task, repo_name, model_architecture, tokenizer_name, processor_name, commit) + + def run_pipeline_test(self, task, repo_name, model_architecture, tokenizer_name, processor_name, commit): + """Run pipeline tests for a specific `task` with the give model class and tokenizer/processor class name + + The model will be loaded from a model repository on the Hub. + + Args: + task (`str`): + A task name. This should be a key in the mapping `pipeline_test_mapping`. + repo_name (`str`): + A model repository id on the Hub. + model_architecture (`type`): + A subclass of `PretrainedModel` or `PretrainedModel`. + tokenizer_name (`str`): + The name of a subclass of `PreTrainedTokenizerFast` or `PreTrainedTokenizer`. + processor_name (`str`): + The name of a subclass of `BaseImageProcessor` or `FeatureExtractionMixin`. + """ + repo_id = f"{TRANSFORMERS_TINY_MODEL_PATH}/{repo_name}" + if TRANSFORMERS_TINY_MODEL_PATH != "hf-internal-testing": + model_type = model_architecture.config_class.model_type + repo_id = os.path.join(TRANSFORMERS_TINY_MODEL_PATH, model_type, repo_name) + + tokenizer = None + if tokenizer_name is not None: + tokenizer_class = getattr(transformers_module, tokenizer_name) + tokenizer = tokenizer_class.from_pretrained(repo_id, revision=commit) + + processor = None + if processor_name is not None: + processor_class = getattr(transformers_module, processor_name) + # If the required packages (like `Pillow` or `torchaudio`) are not installed, this will fail. + try: + processor = processor_class.from_pretrained(repo_id, revision=commit) + except Exception: + logger.warning( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: Could not load the " + f"processor from `{repo_id}` with `{processor_name}`." + ) + return + + # TODO: Maybe not upload such problematic tiny models to Hub. + if tokenizer is None and processor is None: + logger.warning( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: Could not find or load " + f"any tokenizer / processor from `{repo_id}`." + ) + return + + # TODO: We should check if a model file is on the Hub repo. instead. + try: + model = model_architecture.from_pretrained(repo_id, revision=commit) + except Exception: + logger.warning( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: Could not find or load " + f"the model from `{repo_id}` with `{model_architecture}`." + ) + return + + # validate + validate_test_components(self, task, model, tokenizer, processor) + + if hasattr(model, "eval"): + model = model.eval() + + # Get an instance of the corresponding class `XXXPipelineTests` in order to use `get_test_pipeline` and + # `run_pipeline_test`. + task_test = pipeline_test_mapping[task]["test"]() + + pipeline, examples = task_test.get_test_pipeline(model, tokenizer, processor) + if pipeline is None: + # The test can disable itself, but it should be very marginal + # Concerns: Wav2Vec2ForCTC without tokenizer test (FastTokenizer don't exist) + logger.warning( + f"{self.__class__.__name__}::test_pipeline_{task.replace('-', '_')} is skipped: Could not get the " + "pipeline for testing." + ) + return + + task_test.run_pipeline_test(pipeline, examples) + + def run_batch_test(pipeline, examples): + # Need to copy because `Conversation` are stateful + if pipeline.tokenizer is not None and pipeline.tokenizer.pad_token_id is None: + return # No batching for this and it's OK + + # 10 examples with batch size 4 means there needs to be a unfinished batch + # which is important for the unbatcher + def data(n): + for _ in range(n): + # Need to copy because Conversation object is mutated + yield copy.deepcopy(random.choice(examples)) + + out = [] + for item in pipeline(data(10), batch_size=4): + out.append(item) + self.assertEqual(len(out), 10) + + run_batch_test(pipeline, examples) + + @is_pipeline_test + @require_torch + def test_pipeline_audio_classification(self): + self.run_task_tests(task="audio-classification") + + @is_pipeline_test + def test_pipeline_automatic_speech_recognition(self): + self.run_task_tests(task="automatic-speech-recognition") + + @is_pipeline_test + def test_pipeline_conversational(self): + self.run_task_tests(task="conversational") + + @is_pipeline_test + @require_vision + @require_timm + @require_torch + def test_pipeline_depth_estimation(self): + self.run_task_tests(task="depth-estimation") + + @is_pipeline_test + @require_pytesseract + @require_torch + @require_vision + def test_pipeline_document_question_answering(self): + self.run_task_tests(task="document-question-answering") + + @is_pipeline_test + def test_pipeline_feature_extraction(self): + self.run_task_tests(task="feature-extraction") + + @is_pipeline_test + def test_pipeline_fill_mask(self): + self.run_task_tests(task="fill-mask") + + @is_pipeline_test + @require_torch_or_tf + @require_vision + def test_pipeline_image_classification(self): + self.run_task_tests(task="image-classification") + + @is_pipeline_test + @require_vision + @require_timm + @require_torch + def test_pipeline_image_segmentation(self): + self.run_task_tests(task="image-segmentation") + + @is_pipeline_test + @require_vision + def test_pipeline_image_to_text(self): + self.run_task_tests(task="image-to-text") + + @is_pipeline_test + @require_vision + @require_torch + def test_pipeline_mask_generation(self): + self.run_task_tests(task="mask-generation") + + @is_pipeline_test + @require_vision + @require_timm + @require_torch + def test_pipeline_object_detection(self): + self.run_task_tests(task="object-detection") + + @is_pipeline_test + def test_pipeline_question_answering(self): + self.run_task_tests(task="question-answering") + + @is_pipeline_test + def test_pipeline_summarization(self): + self.run_task_tests(task="summarization") + + @is_pipeline_test + def test_pipeline_table_question_answering(self): + self.run_task_tests(task="table-question-answering") + + @is_pipeline_test + def test_pipeline_text2text_generation(self): + self.run_task_tests(task="text2text-generation") + + @is_pipeline_test + def test_pipeline_text_classification(self): + self.run_task_tests(task="text-classification") + + @is_pipeline_test + @require_torch_or_tf + def test_pipeline_text_generation(self): + self.run_task_tests(task="text-generation") + + @is_pipeline_test + def test_pipeline_token_classification(self): + self.run_task_tests(task="token-classification") + + @is_pipeline_test + def test_pipeline_translation(self): + self.run_task_tests(task="translation") + + @is_pipeline_test + @require_torch_or_tf + @require_vision + @require_decord + def test_pipeline_video_classification(self): + self.run_task_tests(task="video-classification") + + @is_pipeline_test + @require_torch + @require_vision + def test_pipeline_visual_question_answering(self): + self.run_task_tests(task="visual-question-answering") + + @is_pipeline_test + def test_pipeline_zero_shot(self): + self.run_task_tests(task="zero-shot") + + @is_pipeline_test + @require_torch + def test_pipeline_zero_shot_audio_classification(self): + self.run_task_tests(task="zero-shot-audio-classification") + + @is_pipeline_test + @require_vision + def test_pipeline_zero_shot_image_classification(self): + self.run_task_tests(task="zero-shot-image-classification") + + @is_pipeline_test + @require_vision + @require_torch + def test_pipeline_zero_shot_object_detection(self): + self.run_task_tests(task="zero-shot-object-detection") + + # This contains the test cases to be skipped without model architecture being involved. + def is_pipeline_test_to_skip( + self, pipeline_test_casse_name, config_class, model_architecture, tokenizer_name, processor_name + ): + # No fix is required for this case. + if ( + pipeline_test_casse_name == "DocumentQuestionAnsweringPipelineTests" + and tokenizer_name is not None + and not tokenizer_name.endswith("Fast") + ): + # `DocumentQuestionAnsweringPipelineTests` requires a fast tokenizer. + return True + + return False + + +def validate_test_components(test_case, task, model, tokenizer, processor): + # TODO: Move this to tiny model creation script + # head-specific (within a model type) necessary changes to the config + # 1. for `BlenderbotForCausalLM` + if model.__class__.__name__ == "BlenderbotForCausalLM": + model.config.encoder_no_repeat_ngram_size = 0 + + # TODO: Change the tiny model creation script: don't create models with problematic tokenizers + # Avoid `IndexError` in embedding layers + CONFIG_WITHOUT_VOCAB_SIZE = ["CanineConfig"] + if tokenizer is not None: + config_vocab_size = getattr(model.config, "vocab_size", None) + # For CLIP-like models + if config_vocab_size is None and hasattr(model.config, "text_config"): + config_vocab_size = getattr(model.config.text_config, "vocab_size", None) + if config_vocab_size is None and model.config.__class__.__name__ not in CONFIG_WITHOUT_VOCAB_SIZE: + raise ValueError( + "Could not determine `vocab_size` from model configuration while `tokenizer` is not `None`." + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_sequence_feature_extraction_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_sequence_feature_extraction_common.py new file mode 100644 index 0000000000000000000000000000000000000000..4c09c1c2629f4db0da29a077bfadbd7eaf0c2ab2 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_sequence_feature_extraction_common.py @@ -0,0 +1,424 @@ +# coding=utf-8 +# Copyright 2021 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import numpy as np + +from transformers import BatchFeature +from transformers.testing_utils import require_tf, require_torch + +from .test_feature_extraction_common import FeatureExtractionSavingTestMixin + + +class SequenceFeatureExtractionTestMixin(FeatureExtractionSavingTestMixin): + # to overwrite at feature extractactor specific tests + feat_extract_tester = None + feature_extraction_class = None + + @property + def feat_extract_dict(self): + return self.feat_extract_tester.prepare_feat_extract_dict() + + def test_feat_extract_common_properties(self): + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + self.assertTrue(hasattr(feat_extract, "feature_size")) + self.assertTrue(hasattr(feat_extract, "sampling_rate")) + self.assertTrue(hasattr(feat_extract, "padding_value")) + + def test_batch_feature(self): + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common() + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}) + + self.assertTrue(all(len(x) == len(y) for x, y in zip(speech_inputs, processed_features[input_name]))) + + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common(equal_length=True) + processed_features = BatchFeature({input_name: speech_inputs}, tensor_type="np") + + batch_features_input = processed_features[input_name] + + if len(batch_features_input.shape) < 3: + batch_features_input = batch_features_input[:, :, None] + + self.assertTrue( + batch_features_input.shape + == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size) + ) + + @require_torch + def test_batch_feature_pt(self): + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common(equal_length=True) + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}, tensor_type="pt") + + batch_features_input = processed_features[input_name] + + if len(batch_features_input.shape) < 3: + batch_features_input = batch_features_input[:, :, None] + + self.assertTrue( + batch_features_input.shape + == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size) + ) + + @require_tf + def test_batch_feature_tf(self): + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common(equal_length=True) + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}, tensor_type="tf") + + batch_features_input = processed_features[input_name] + + if len(batch_features_input.shape) < 3: + batch_features_input = batch_features_input[:, :, None] + + self.assertTrue( + batch_features_input.shape + == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size) + ) + + def _check_padding(self, numpify=False): + def _inputs_have_equal_length(input): + length = len(input[0]) + for input_slice in input[1:]: + if len(input_slice) != length: + return False + return True + + def _inputs_are_equal(input_1, input_2): + if len(input_1) != len(input_2): + return False + + for input_slice_1, input_slice_2 in zip(input_1, input_2): + if not np.allclose(np.asarray(input_slice_1), np.asarray(input_slice_2), atol=1e-3): + return False + return True + + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common(numpify=numpify) + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}) + + pad_diff = self.feat_extract_tester.seq_length_diff + pad_max_length = self.feat_extract_tester.max_seq_length + pad_diff + pad_min_length = self.feat_extract_tester.min_seq_length + batch_size = self.feat_extract_tester.batch_size + feature_size = self.feat_extract_tester.feature_size + + # test padding for List[int] + numpy + input_1 = feat_extract.pad(processed_features, padding=False) + input_1 = input_1[input_name] + + input_2 = feat_extract.pad(processed_features, padding="longest") + input_2 = input_2[input_name] + + input_3 = feat_extract.pad(processed_features, padding="max_length", max_length=len(speech_inputs[-1])) + input_3 = input_3[input_name] + + input_4 = feat_extract.pad(processed_features, padding="longest", return_tensors="np") + input_4 = input_4[input_name] + + # max_length parameter has to be provided when setting `padding="max_length"` + with self.assertRaises(ValueError): + feat_extract.pad(processed_features, padding="max_length")[input_name] + + input_5 = feat_extract.pad( + processed_features, padding="max_length", max_length=pad_max_length, return_tensors="np" + ) + input_5 = input_5[input_name] + + self.assertFalse(_inputs_have_equal_length(input_1)) + self.assertTrue(_inputs_have_equal_length(input_2)) + self.assertTrue(_inputs_have_equal_length(input_3)) + self.assertTrue(_inputs_are_equal(input_2, input_3)) + self.assertTrue(len(input_1[0]) == pad_min_length) + self.assertTrue(len(input_1[1]) == pad_min_length + pad_diff) + self.assertTrue(input_4.shape[:2] == (batch_size, len(input_3[0]))) + self.assertTrue(input_5.shape[:2] == (batch_size, pad_max_length)) + + if feature_size > 1: + self.assertTrue(input_4.shape[2] == input_5.shape[2] == feature_size) + + # test padding for `pad_to_multiple_of` for List[int] + numpy + input_6 = feat_extract.pad(processed_features, pad_to_multiple_of=10) + input_6 = input_6[input_name] + + input_7 = feat_extract.pad(processed_features, padding="longest", pad_to_multiple_of=10) + input_7 = input_7[input_name] + + input_8 = feat_extract.pad( + processed_features, padding="max_length", pad_to_multiple_of=10, max_length=pad_max_length + ) + input_8 = input_8[input_name] + + input_9 = feat_extract.pad( + processed_features, + padding="max_length", + pad_to_multiple_of=10, + max_length=pad_max_length, + return_tensors="np", + ) + input_9 = input_9[input_name] + + self.assertTrue(all(len(x) % 10 == 0 for x in input_6)) + self.assertTrue(_inputs_are_equal(input_6, input_7)) + + expected_mult_pad_length = pad_max_length if pad_max_length % 10 == 0 else (pad_max_length // 10 + 1) * 10 + self.assertTrue(all(len(x) == expected_mult_pad_length for x in input_8)) + self.assertEqual(input_9.shape[:2], (batch_size, expected_mult_pad_length)) + + if feature_size > 1: + self.assertTrue(input_9.shape[2] == feature_size) + + # Check padding value is correct + padding_vector_sum = (np.ones(self.feat_extract_tester.feature_size) * feat_extract.padding_value).sum() + self.assertTrue( + abs(np.asarray(input_2[0])[pad_min_length:].sum() - padding_vector_sum * (pad_max_length - pad_min_length)) + < 1e-3 + ) + self.assertTrue( + abs( + np.asarray(input_2[1])[pad_min_length + pad_diff :].sum() + - padding_vector_sum * (pad_max_length - pad_min_length - pad_diff) + ) + < 1e-3 + ) + self.assertTrue( + abs( + np.asarray(input_2[2])[pad_min_length + 2 * pad_diff :].sum() + - padding_vector_sum * (pad_max_length - pad_min_length - 2 * pad_diff) + ) + < 1e-3 + ) + self.assertTrue( + abs(input_5[0, pad_min_length:].sum() - padding_vector_sum * (pad_max_length - pad_min_length)) < 1e-3 + ) + self.assertTrue( + abs(input_9[0, pad_min_length:].sum() - padding_vector_sum * (expected_mult_pad_length - pad_min_length)) + < 1e-3 + ) + + def _check_truncation(self, numpify=False): + def _inputs_have_equal_length(input): + length = len(input[0]) + for input_slice in input[1:]: + if len(input_slice) != length: + return False + return True + + def _inputs_are_equal(input_1, input_2): + if len(input_1) != len(input_2): + return False + + for input_slice_1, input_slice_2 in zip(input_1, input_2): + if not np.allclose(np.asarray(input_slice_1), np.asarray(input_slice_2), atol=1e-3): + return False + return True + + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common(numpify=numpify) + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}) + + # truncate to smallest + input_1 = feat_extract.pad( + processed_features, padding="max_length", max_length=len(speech_inputs[0]), truncation=True + ) + input_1 = input_1[input_name] + + input_2 = feat_extract.pad(processed_features, padding="max_length", max_length=len(speech_inputs[0])) + input_2 = input_2[input_name] + + self.assertTrue(_inputs_have_equal_length(input_1)) + self.assertFalse(_inputs_have_equal_length(input_2)) + + # truncate to smallest with np + input_3 = feat_extract.pad( + processed_features, + padding="max_length", + max_length=len(speech_inputs[0]), + return_tensors="np", + truncation=True, + ) + input_3 = input_3[input_name] + + input_4 = feat_extract.pad( + processed_features, padding="max_length", max_length=len(speech_inputs[0]), return_tensors="np" + ) + input_4 = input_4[input_name] + + self.assertTrue(_inputs_have_equal_length(input_3)) + self.assertTrue(input_3.shape[1] == len(speech_inputs[0])) + + # since truncation forces padding to be smaller than longest input + # function can't return `np.ndarray`, but has to return list + self.assertFalse(_inputs_have_equal_length(input_4)) + + # truncate to middle + input_5 = feat_extract.pad( + processed_features, + padding="max_length", + max_length=len(speech_inputs[1]), + truncation=True, + return_tensors="np", + ) + input_5 = input_5[input_name] + + input_6 = feat_extract.pad( + processed_features, padding="max_length", max_length=len(speech_inputs[1]), truncation=True + ) + input_6 = input_6[input_name] + + input_7 = feat_extract.pad( + processed_features, padding="max_length", max_length=len(speech_inputs[1]), return_tensors="np" + ) + input_7 = input_7[input_name] + + self.assertTrue(input_5.shape[1] == len(speech_inputs[1])) + self.assertTrue(_inputs_have_equal_length(input_5)) + self.assertTrue(_inputs_have_equal_length(input_6)) + self.assertTrue(_inputs_are_equal(input_5, input_6)) + + # since truncation forces padding to be smaller than longest input + # function can't return `np.ndarray`, but has to return list + self.assertFalse(_inputs_have_equal_length(input_7)) + self.assertTrue(len(input_7[-1]) == len(speech_inputs[-1])) + + # padding has to be max_length when setting `truncation=True` + with self.assertRaises(ValueError): + feat_extract.pad(processed_features, truncation=True)[input_name] + + # padding has to be max_length when setting `truncation=True` + with self.assertRaises(ValueError): + feat_extract.pad(processed_features, padding="longest", truncation=True)[input_name] + + # padding has to be max_length when setting `truncation=True` + with self.assertRaises(ValueError): + feat_extract.pad(processed_features, padding="longest", truncation=True)[input_name] + + # max_length parameter has to be provided when setting `truncation=True` and padding="max_length" + with self.assertRaises(ValueError): + feat_extract.pad(processed_features, padding="max_length", truncation=True)[input_name] + + # test truncation for `pad_to_multiple_of` for List[int] + numpy + pad_to_multiple_of = 12 + input_8 = feat_extract.pad( + processed_features, + padding="max_length", + max_length=len(speech_inputs[0]), + pad_to_multiple_of=pad_to_multiple_of, + truncation=True, + ) + input_8 = input_8[input_name] + + input_9 = feat_extract.pad( + processed_features, + padding="max_length", + max_length=len(speech_inputs[0]), + pad_to_multiple_of=pad_to_multiple_of, + ) + input_9 = input_9[input_name] + + # retrieve expected_length as multiple of pad_to_multiple_of + expected_length = len(speech_inputs[0]) + if expected_length % pad_to_multiple_of != 0: + expected_length = ((len(speech_inputs[0]) // pad_to_multiple_of) + 1) * pad_to_multiple_of + + self.assertTrue(len(input_8[0]) == expected_length) + self.assertTrue(_inputs_have_equal_length(input_8)) + self.assertFalse(_inputs_have_equal_length(input_9)) + + def test_padding_from_list(self): + self._check_padding(numpify=False) + + def test_padding_from_array(self): + self._check_padding(numpify=True) + + def test_truncation_from_list(self): + self._check_truncation(numpify=False) + + def test_truncation_from_array(self): + self._check_truncation(numpify=True) + + @require_torch + def test_padding_accepts_tensors_pt(self): + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common() + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}) + + input_np = feat_extract.pad(processed_features, padding="longest", return_tensors="np")[input_name] + input_pt = feat_extract.pad(processed_features, padding="longest", return_tensors="pt")[input_name] + + self.assertTrue(abs(input_np.astype(np.float32).sum() - input_pt.numpy().astype(np.float32).sum()) < 1e-2) + + @require_tf + def test_padding_accepts_tensors_tf(self): + feat_extract = self.feature_extraction_class(**self.feat_extract_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common() + input_name = feat_extract.model_input_names[0] + + processed_features = BatchFeature({input_name: speech_inputs}) + + input_np = feat_extract.pad(processed_features, padding="longest", return_tensors="np")[input_name] + input_tf = feat_extract.pad(processed_features, padding="longest", return_tensors="tf")[input_name] + + self.assertTrue(abs(input_np.astype(np.float32).sum() - input_tf.numpy().astype(np.float32).sum()) < 1e-2) + + def test_attention_mask(self): + feat_dict = self.feat_extract_dict + feat_dict["return_attention_mask"] = True + feat_extract = self.feature_extraction_class(**feat_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common() + input_lenghts = [len(x) for x in speech_inputs] + input_name = feat_extract.model_input_names[0] + + processed = BatchFeature({input_name: speech_inputs}) + + processed = feat_extract.pad(processed, padding="longest", return_tensors="np") + self.assertIn("attention_mask", processed) + self.assertListEqual(list(processed.attention_mask.shape), list(processed[input_name].shape[:2])) + self.assertListEqual(processed.attention_mask.sum(-1).tolist(), input_lenghts) + + def test_attention_mask_with_truncation(self): + feat_dict = self.feat_extract_dict + feat_dict["return_attention_mask"] = True + feat_extract = self.feature_extraction_class(**feat_dict) + speech_inputs = self.feat_extract_tester.prepare_inputs_for_common() + input_lenghts = [len(x) for x in speech_inputs] + input_name = feat_extract.model_input_names[0] + + processed = BatchFeature({input_name: speech_inputs}) + max_length = min(input_lenghts) + + processed_pad = feat_extract.pad( + processed, padding="max_length", max_length=max_length, truncation=True, return_tensors="np" + ) + self.assertIn("attention_mask", processed_pad) + self.assertListEqual( + list(processed_pad.attention_mask.shape), [processed_pad[input_name].shape[0], max_length] + ) + self.assertListEqual( + processed_pad.attention_mask[:, :max_length].sum(-1).tolist(), [max_length for x in speech_inputs] + ) diff --git a/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_tokenization_common.py b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_tokenization_common.py new file mode 100644 index 0000000000000000000000000000000000000000..84f6886db667702dd6a6033eb2d694f5b8f9f373 --- /dev/null +++ b/SupplementaryMaterial_Code/OPERA/transformers-4.29.2/tests/test_tokenization_common.py @@ -0,0 +1,4176 @@ +# coding=utf-8 +# Copyright 2019 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import inspect +import itertools +import json +import os +import pickle +import re +import shutil +import sys +import tempfile +import unittest +import unittest.mock as mock +from collections import OrderedDict +from itertools import takewhile +from pathlib import Path +from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Union + +from huggingface_hub import HfFolder, delete_repo +from huggingface_hub.file_download import http_get +from parameterized import parameterized +from requests.exceptions import HTTPError + +from transformers import ( + AlbertTokenizer, + AlbertTokenizerFast, + AutoTokenizer, + BertTokenizer, + BertTokenizerFast, + GPT2TokenizerFast, + PreTrainedTokenizer, + PreTrainedTokenizerBase, + PreTrainedTokenizerFast, + SpecialTokensMixin, + Trainer, + TrainingArguments, + is_flax_available, + is_tf_available, + is_tokenizers_available, + is_torch_available, + logging, +) +from transformers.testing_utils import ( + TOKEN, + USER, + check_json_file_has_correct_format, + get_tests_dir, + is_pt_tf_cross_test, + is_staging_test, + require_tf, + require_tokenizers, + require_torch, + slow, +) +from transformers.tokenization_utils import AddedToken, Trie + + +if is_torch_available(): + import torch.nn as nn + + +if TYPE_CHECKING: + from transformers import PretrainedConfig, PreTrainedModel, TFPreTrainedModel + + +sys.path.append(str(Path(__file__).parent.parent / "utils")) + +from test_module.custom_tokenization import CustomTokenizer # noqa E402 + + +if is_tokenizers_available(): + from test_module.custom_tokenization_fast import CustomTokenizerFast + + +logger = logging.get_logger(__name__) + +NON_ENGLISH_TAGS = ["chinese", "dutch", "french", "finnish", "german", "multilingual"] + +SMALL_TRAINING_CORPUS = [ + ["This is the first sentence.", "This is the second one."], + ["This sentence (contains #) over symbols and numbers 12 3.", "But not this one."], +] + + +def filter_non_english(_, pretrained_name: str): + """Filter all the model for non-english language""" + return not any([lang in pretrained_name for lang in NON_ENGLISH_TAGS]) + + +def filter_roberta_detectors(_, pretrained_name: str): + return "detector" not in pretrained_name + + +def merge_model_tokenizer_mappings( + model_mapping: Dict["PretrainedConfig", Union["PreTrainedModel", "TFPreTrainedModel"]], + tokenizer_mapping: Dict["PretrainedConfig", Tuple["PreTrainedTokenizer", "PreTrainedTokenizerFast"]], +) -> Dict[ + Union["PreTrainedTokenizer", "PreTrainedTokenizerFast"], + Tuple["PretrainedConfig", Union["PreTrainedModel", "TFPreTrainedModel"]], +]: + configurations = list(model_mapping.keys()) + model_tokenizer_mapping = OrderedDict([]) + + for configuration in configurations: + if configuration in model_mapping and configuration in tokenizer_mapping: + model = model_mapping[configuration] + tokenizer = tokenizer_mapping[configuration][0] + tokenizer_fast = tokenizer_mapping[configuration][1] + + if tokenizer is not None: + if configuration.__name__.startswith(tokenizer.__name__.replace("Tokenizer", "")): + model_tokenizer_mapping.update({tokenizer: (configuration, model)}) + if tokenizer_fast is not None: + if configuration.__name__.startswith(tokenizer_fast.__name__.replace("TokenizerFast", "")): + model_tokenizer_mapping.update({tokenizer_fast: (configuration, model)}) + + return model_tokenizer_mapping + + +class TokenizerTesterMixin: + tokenizer_class = None + rust_tokenizer_class = None + test_slow_tokenizer = True + test_rust_tokenizer = True + space_between_special_tokens = False + from_pretrained_kwargs = None + from_pretrained_filter = None + from_pretrained_vocab_key = "vocab_file" + test_seq2seq = True + + # set to True to test a sentencepiece tokenizer + test_sentencepiece = False + + # set to True to ignore casing when testing a sentencepiece tokenizer + # test_sentencepiece must also be set to True + test_sentencepiece_ignore_case = False + + def setUp(self) -> None: + # Tokenizer.filter makes it possible to filter which Tokenizer to case based on all the + # information available in Tokenizer (name, rust class, python class, vocab key name) + if self.test_rust_tokenizer: + tokenizers_list = [ + ( + self.rust_tokenizer_class, + pretrained_name, + self.from_pretrained_kwargs if self.from_pretrained_kwargs is not None else {}, + ) + for pretrained_name in self.rust_tokenizer_class.pretrained_vocab_files_map[ + self.from_pretrained_vocab_key + ].keys() + if self.from_pretrained_filter is None + or (self.from_pretrained_filter is not None and self.from_pretrained_filter(pretrained_name)) + ] + self.tokenizers_list = tokenizers_list[:1] # Let's just test the first pretrained vocab for speed + else: + self.tokenizers_list = [] + with open(f"{get_tests_dir()}/fixtures/sample_text.txt", encoding="utf-8") as f_data: + self._data = f_data.read().replace("\n\n", "\n").strip() + + self.tmpdirname = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdirname) + + def get_input_output_texts(self, tokenizer): + input_txt = self.get_clean_sequence(tokenizer)[0] + return input_txt, input_txt + + def get_clean_sequence(self, tokenizer, with_prefix_space=False, max_length=20, min_length=5) -> Tuple[str, list]: + toks = [(i, tokenizer.decode([i], clean_up_tokenization_spaces=False)) for i in range(len(tokenizer))] + toks = list(filter(lambda t: re.match(r"^[ a-zA-Z]+$", t[1]), toks)) + toks = list(filter(lambda t: [t[0]] == tokenizer.encode(t[1], add_special_tokens=False), toks)) + if max_length is not None and len(toks) > max_length: + toks = toks[:max_length] + if min_length is not None and len(toks) < min_length and len(toks) > 0: + while len(toks) < min_length: + toks = toks + toks + # toks_str = [t[1] for t in toks] + toks_ids = [t[0] for t in toks] + + # Ensure consistency + output_txt = tokenizer.decode(toks_ids, clean_up_tokenization_spaces=False) + if " " not in output_txt and len(toks_ids) > 1: + output_txt = ( + tokenizer.decode([toks_ids[0]], clean_up_tokenization_spaces=False) + + " " + + tokenizer.decode(toks_ids[1:], clean_up_tokenization_spaces=False) + ) + if with_prefix_space: + output_txt = " " + output_txt + output_ids = tokenizer.encode(output_txt, add_special_tokens=False) + return output_txt, output_ids + + def get_tokenizers(self, fast=True, **kwargs) -> List[PreTrainedTokenizerBase]: + if fast and self.test_rust_tokenizer and self.test_slow_tokenizer: + return [self.get_tokenizer(**kwargs), self.get_rust_tokenizer(**kwargs)] + elif fast and self.test_rust_tokenizer: + return [self.get_rust_tokenizer(**kwargs)] + elif self.test_slow_tokenizer: + return [self.get_tokenizer(**kwargs)] + else: + raise ValueError("This tokenizer class has no tokenizer to be tested.") + + def get_tokenizer(self, **kwargs) -> PreTrainedTokenizer: + return self.tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def get_rust_tokenizer(self, **kwargs) -> PreTrainedTokenizerFast: + return self.rust_tokenizer_class.from_pretrained(self.tmpdirname, **kwargs) + + def tokenizer_integration_test_util( + self, + expected_encoding: Dict, + model_name: str, + revision: str = None, + sequences: List[str] = None, + decode_kwargs: Dict[str, Any] = None, + padding: bool = True, + ): + """ + Util for integration test. + + Text is tokenized and then reverted back to text. Both results are then checked. + + Args: + expected_encoding: + The expected result of the tokenizer output. + model_name: + The model name of the tokenizer to load and use. + revision: + The full git revision number of the model. This is to pin the + tokenizer config and to avoid that tests start to fail if the + config gets changed upstream. + sequences: + Can overwrite the texts that are used to check the tokenizer. + This is useful if the tokenizer supports non english languages + like france. + decode_kwargs: + Additional args for the ``decode`` function which reverts the + tokenized text back to a string. + padding: + Activates and controls padding of the tokenizer. + """ + decode_kwargs = {} if decode_kwargs is None else decode_kwargs + + if sequences is None: + sequences = [ + "Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides " + "general-purpose architectures (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet...) for Natural " + "Language Understanding (NLU) and Natural Language Generation (NLG) with over 32+ pretrained " + "models in 100+ languages and deep interoperability between Jax, PyTorch and TensorFlow.", + "BERT is designed to pre-train deep bidirectional representations from unlabeled text by jointly " + "conditioning on both left and right context in all layers.", + "The quick brown fox jumps over the lazy dog.", + ] + + if self.test_sentencepiece_ignore_case: + sequences = [sequence.lower() for sequence in sequences] + + tokenizer_classes = [self.tokenizer_class] + if self.test_rust_tokenizer: + tokenizer_classes.append(self.rust_tokenizer_class) + + for tokenizer_class in tokenizer_classes: + tokenizer = tokenizer_class.from_pretrained( + model_name, + revision=revision, # to pin the tokenizer version + ) + + encoding = tokenizer(sequences, padding=padding) + decoded_sequences = [ + tokenizer.decode(seq, skip_special_tokens=True, **decode_kwargs) for seq in encoding["input_ids"] + ] + + encoding_data = encoding.data + self.assertDictEqual(encoding_data, expected_encoding) + + for expected, decoded in zip(sequences, decoded_sequences): + if self.test_sentencepiece_ignore_case: + expected = expected.lower() + self.assertEqual(expected, decoded) + + def assert_padded_input_match(self, input_r: list, input_p: list, max_length: int, pad_token_id: int): + # Ensure we match max_length + self.assertEqual(len(input_r), max_length) + self.assertEqual(len(input_p), max_length) + + # Ensure the number of padded tokens is the same + padded_tokens_r = list(takewhile(lambda i: i == pad_token_id, reversed(input_r))) + padded_tokens_p = list(takewhile(lambda i: i == pad_token_id, reversed(input_p))) + self.assertSequenceEqual(padded_tokens_r, padded_tokens_p) + + def assert_batch_padded_input_match( + self, + input_r: dict, + input_p: dict, + max_length: int, + pad_token_id: int, + model_main_input_name: str = "input_ids", + ): + for i_r in input_r.values(): + self.assertEqual(len(i_r), 2), self.assertEqual(len(i_r[0]), max_length), self.assertEqual( + len(i_r[1]), max_length + ) + self.assertEqual(len(i_r), 2), self.assertEqual(len(i_r[0]), max_length), self.assertEqual( + len(i_r[1]), max_length + ) + + for i_r, i_p in zip(input_r[model_main_input_name], input_p[model_main_input_name]): + self.assert_padded_input_match(i_r, i_p, max_length, pad_token_id) + + for i_r, i_p in zip(input_r["attention_mask"], input_p["attention_mask"]): + self.assertSequenceEqual(i_r, i_p) + + @staticmethod + def convert_batch_encode_plus_format_to_encode_plus(batch_encode_plus_sequences): + # Switch from batch_encode_plus format: {'input_ids': [[...], [...]], ...} + # to the list of examples/ encode_plus format: [{'input_ids': [...], ...}, {'input_ids': [...], ...}] + return [ + {value: batch_encode_plus_sequences[value][i] for value in batch_encode_plus_sequences.keys()} + for i in range(len(batch_encode_plus_sequences["input_ids"])) + ] + + # TODO: this test can be combined with `test_sentencepiece_tokenize_and_convert_tokens_to_string` after the latter is extended to all tokenizers. + def test_tokenize_special_tokens(self): + """Test `tokenize` with special tokens.""" + tokenizers = self.get_tokenizers(fast=True, do_lower_case=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + SPECIAL_TOKEN_1 = "[SPECIAL_TOKEN_1]" + SPECIAL_TOKEN_2 = "[SPECIAL_TOKEN_2]" + + # TODO: + # Can we combine `unique_no_split_tokens` and `all_special_tokens`(and properties related to it) + # with one variable(property) for a better maintainability? + + # `add_tokens` method stores special tokens only in `tokenizer.unique_no_split_tokens`. (in tokenization_utils.py) + tokenizer.add_tokens([SPECIAL_TOKEN_1], special_tokens=True) + # `add_special_tokens` method stores special tokens in `tokenizer.additional_special_tokens`, + # which also occur in `tokenizer.all_special_tokens`. (in tokenization_utils_base.py) + tokenizer.add_special_tokens({"additional_special_tokens": [SPECIAL_TOKEN_2]}) + + token_1 = tokenizer.tokenize(SPECIAL_TOKEN_1) + token_2 = tokenizer.tokenize(SPECIAL_TOKEN_2) + + self.assertEqual(len(token_1), 1) + self.assertEqual(len(token_2), 1) + self.assertEqual(token_1[0], SPECIAL_TOKEN_1) + self.assertEqual(token_2[0], SPECIAL_TOKEN_2) + + # TODO: this test could be extended to all tokenizers - not just the sentencepiece + def test_sentencepiece_tokenize_and_convert_tokens_to_string(self): + """Test ``_tokenize`` and ``convert_tokens_to_string``.""" + if not self.test_sentencepiece: + return + + tokenizer = self.get_tokenizer() + text = "This is text to test the tokenizer." + + if self.test_sentencepiece_ignore_case: + text = text.lower() + + tokens = tokenizer.tokenize(text) + + self.assertTrue(len(tokens) > 0) + + # check if converting back to original text works + reverse_text = tokenizer.convert_tokens_to_string(tokens) + + if self.test_sentencepiece_ignore_case: + reverse_text = reverse_text.lower() + + self.assertEqual(reverse_text, text) + + special_tokens = tokenizer.all_special_tokens + special_tokens_string = tokenizer.convert_tokens_to_string(special_tokens) + for special_token in special_tokens: + self.assertIn(special_token, special_tokens_string) + + if self.test_rust_tokenizer: + rust_tokenizer = self.get_rust_tokenizer() + special_tokens_string_rust = rust_tokenizer.convert_tokens_to_string(special_tokens) + self.assertEqual(special_tokens_string, special_tokens_string_rust) + + def test_sentencepiece_tokenize_and_decode(self): + if not self.test_sentencepiece: + return + + text = "This is text to test the tokenizer." + if self.test_rust_tokenizer: + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + slow_ids = tokenizer(text).input_ids + fast_ids = rust_tokenizer(text).input_ids + self.assertEqual(slow_ids, fast_ids) + + slow_decoded = tokenizer.decode(slow_ids) + fast_decoded = rust_tokenizer.decode(slow_ids) + self.assertEqual(slow_decoded, fast_decoded) + + def test_subword_regularization_tokenizer(self) -> None: + if not self.test_sentencepiece: + return + + # Subword regularization is only available for the slow tokenizer. + sp_model_kwargs = {"enable_sampling": True, "alpha": 0.1, "nbest_size": -1} + tokenizer = self.get_tokenizer(sp_model_kwargs=sp_model_kwargs) + + self.assertTrue(hasattr(tokenizer, "sp_model_kwargs")) + self.assertIsNotNone(tokenizer.sp_model_kwargs) + self.assertTrue(isinstance(tokenizer.sp_model_kwargs, dict)) + self.assertEqual(tokenizer.sp_model_kwargs, sp_model_kwargs) + self.check_subword_sampling(tokenizer) + + def test_pickle_subword_regularization_tokenizer(self) -> None: + if not self.test_sentencepiece: + return + + """Google pickle __getstate__ __setstate__ if you are struggling with this.""" + # Subword regularization is only available for the slow tokenizer. + sp_model_kwargs = {"enable_sampling": True, "alpha": 0.1, "nbest_size": -1} + tokenizer = self.get_tokenizer(sp_model_kwargs=sp_model_kwargs) + tokenizer_bin = pickle.dumps(tokenizer) + del tokenizer + tokenizer_new = pickle.loads(tokenizer_bin) + + self.assertTrue(hasattr(tokenizer_new, "sp_model_kwargs")) + self.assertIsNotNone(tokenizer_new.sp_model_kwargs) + self.assertTrue(isinstance(tokenizer_new.sp_model_kwargs, dict)) + self.assertEqual(tokenizer_new.sp_model_kwargs, sp_model_kwargs) + self.check_subword_sampling(tokenizer_new) + + def test_save_sentencepiece_tokenizer(self) -> None: + if not self.test_sentencepiece or not self.test_slow_tokenizer: + return + # We want to verify that we will be able to save the tokenizer even if the original files that were used to + # build the tokenizer have been deleted in the meantime. + text = "This is text to test the tokenizer." + + tokenizer_slow_1 = self.get_tokenizer() + encoding_tokenizer_slow_1 = tokenizer_slow_1(text) + + tmpdirname_1 = tempfile.mkdtemp() + tmpdirname_2 = tempfile.mkdtemp() + + tokenizer_slow_1.save_pretrained(tmpdirname_1) + tokenizer_slow_2 = self.tokenizer_class.from_pretrained(tmpdirname_1) + encoding_tokenizer_slow_2 = tokenizer_slow_2(text) + + shutil.rmtree(tmpdirname_1) + tokenizer_slow_2.save_pretrained(tmpdirname_2) + + tokenizer_slow_3 = self.tokenizer_class.from_pretrained(tmpdirname_2) + encoding_tokenizer_slow_3 = tokenizer_slow_3(text) + shutil.rmtree(tmpdirname_2) + + self.assertEqual(encoding_tokenizer_slow_1, encoding_tokenizer_slow_2) + self.assertEqual(encoding_tokenizer_slow_1, encoding_tokenizer_slow_3) + + def test_model_input_names_signature(self): + accepted_model_main_input_names = [ + "input_ids", # nlp models + "input_values", # speech models + ] + + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + # first name of model_input_names has to correspond to main model input name + # to make sure `tokenizer.pad(...)` works correctly + self.assertTrue(tokenizer.model_input_names[0] in accepted_model_main_input_names) + + def test_rust_tokenizer_signature(self): + if not self.test_rust_tokenizer: + return + + signature = inspect.signature(self.rust_tokenizer_class.__init__) + + self.assertIn("tokenizer_file", signature.parameters) + self.assertIsNone(signature.parameters["tokenizer_file"].default) + + def test_tokenizer_slow_store_full_signature(self): + if not self.test_slow_tokenizer: + return + + signature = inspect.signature(self.tokenizer_class.__init__) + tokenizer = self.get_tokenizer() + + for parameter_name, parameter in signature.parameters.items(): + if parameter.default != inspect.Parameter.empty: + self.assertIn(parameter_name, tokenizer.init_kwargs) + + def test_tokenizer_fast_store_full_signature(self): + if not self.test_rust_tokenizer: + return + + signature = inspect.signature(self.rust_tokenizer_class.__init__) + tokenizer = self.get_rust_tokenizer() + + for parameter_name, parameter in signature.parameters.items(): + if parameter.default != inspect.Parameter.empty and parameter_name not in [ + "vocab_file", + "merges_file", + "tokenizer_file", + ]: + self.assertIn(parameter_name, tokenizer.init_kwargs) + + def test_rust_and_python_full_tokenizers(self): + if not self.test_rust_tokenizer: + return + + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + tokenizer = self.get_tokenizer() + rust_tokenizer = self.get_rust_tokenizer() + + sequence, _ = self.get_input_output_texts(tokenizer) + + # We don't have an exact equivalence on `tokenize()` between Rust and Slow + # Slow tokenizer only split tokens, Rust tokenizers will replace with + # tokens = tokenizer.tokenize(sequence) + # rust_tokens = rust_tokenizer.tokenize(sequence) + # self.assertListEqual(tokens, rust_tokens) + + ids = tokenizer.encode(sequence, add_special_tokens=False) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=False) + self.assertListEqual(ids, rust_ids) + + ids = tokenizer.encode(sequence, add_special_tokens=True) + rust_ids = rust_tokenizer.encode(sequence, add_special_tokens=True) + self.assertListEqual(ids, rust_ids) + + def test_tokenizers_common_properties(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + attributes_list = [ + "bos_token", + "eos_token", + "unk_token", + "sep_token", + "pad_token", + "cls_token", + "mask_token", + ] + for attr in attributes_list: + self.assertTrue(hasattr(tokenizer, attr)) + self.assertTrue(hasattr(tokenizer, attr + "_id")) + + self.assertTrue(hasattr(tokenizer, "additional_special_tokens")) + self.assertTrue(hasattr(tokenizer, "additional_special_tokens_ids")) + + attributes_list = [ + "model_max_length", + "init_inputs", + "init_kwargs", + ] + if not isinstance(tokenizer, PreTrainedTokenizerFast): + attributes_list += [ + "added_tokens_encoder", + "added_tokens_decoder", + ] + for attr in attributes_list: + self.assertTrue(hasattr(tokenizer, attr)) + + def test_tokenizers_common_ids_setters(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + attributes_list = [ + "bos_token", + "eos_token", + "unk_token", + "sep_token", + "pad_token", + "cls_token", + "mask_token", + ] + + vocab = tokenizer.get_vocab() + token_id_to_test_setters = next(iter(vocab.values())) + token_to_test_setters = tokenizer.convert_ids_to_tokens( + token_id_to_test_setters, skip_special_tokens=False + ) + + for attr in attributes_list: + setattr(tokenizer, attr + "_id", None) + self.assertEqual(getattr(tokenizer, attr), None) + self.assertEqual(getattr(tokenizer, attr + "_id"), None) + + setattr(tokenizer, attr + "_id", token_id_to_test_setters) + self.assertEqual(getattr(tokenizer, attr), token_to_test_setters) + self.assertEqual(getattr(tokenizer, attr + "_id"), token_id_to_test_setters) + + setattr(tokenizer, "additional_special_tokens_ids", []) + self.assertListEqual(getattr(tokenizer, "additional_special_tokens"), []) + self.assertListEqual(getattr(tokenizer, "additional_special_tokens_ids"), []) + + setattr(tokenizer, "additional_special_tokens_ids", [token_id_to_test_setters]) + self.assertListEqual(getattr(tokenizer, "additional_special_tokens"), [token_to_test_setters]) + self.assertListEqual(getattr(tokenizer, "additional_special_tokens_ids"), [token_id_to_test_setters]) + + @parameterized.expand([(True,), (False,)]) + def test_tokenizers_special_tokens_properties_unset(self, verbose): + tokenizers = self.get_tokenizers(verbose=verbose) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + attributes_list = [ + "bos_token", + "eos_token", + "unk_token", + "sep_token", + "pad_token", + "cls_token", + "mask_token", + "additional_special_tokens", + ] + for attr in attributes_list: + setattr(tokenizer, attr, None) + self.assertIsNone(getattr(tokenizer, attr)) + + def test_save_and_load_tokenizer(self): + # safety check on max_len default value so we are sure the test works + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertNotEqual(tokenizer.model_max_length, 42) + + # Now let's start the test + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + tmpdirname = tempfile.mkdtemp() + + sample_text = " He is very happy, UNwant\u00E9d,running" + before_tokens = tokenizer.encode(sample_text, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(sample_text, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + + shutil.rmtree(tmpdirname) + + tokenizers = self.get_tokenizers(model_max_length=42) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + tmpdirname = tempfile.mkdtemp() + + sample_text = " He is very happy, UNwant\u00E9d,running" + tokenizer.add_tokens(["bim", "bambam"]) + additional_special_tokens = tokenizer.additional_special_tokens + additional_special_tokens.append("new_additional_special_token") + tokenizer.add_special_tokens({"additional_special_tokens": additional_special_tokens}) + before_tokens = tokenizer.encode(sample_text, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(sample_text, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + self.assertIn("bim", after_vocab) + self.assertIn("bambam", after_vocab) + self.assertIn("new_additional_special_token", after_tokenizer.additional_special_tokens) + self.assertEqual(after_tokenizer.model_max_length, 42) + + tokenizer = tokenizer.__class__.from_pretrained(tmpdirname, model_max_length=43) + self.assertEqual(tokenizer.model_max_length, 43) + + shutil.rmtree(tmpdirname) + + # Test that we can also use the non-legacy saving format for fast tokenizers + tokenizers = self.get_tokenizers(model_max_length=42) + for tokenizer in tokenizers: + if not tokenizer.is_fast: + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Isolate this from the other tests because we save additional tokens/etc + tmpdirname = tempfile.mkdtemp() + + sample_text = " He is very happy, UNwant\u00E9d,running" + tokenizer.add_tokens(["bim", "bambam"]) + additional_special_tokens = tokenizer.additional_special_tokens + additional_special_tokens.append("new_additional_special_token") + tokenizer.add_special_tokens({"additional_special_tokens": additional_special_tokens}) + before_tokens = tokenizer.encode(sample_text, add_special_tokens=False) + before_vocab = tokenizer.get_vocab() + tokenizer.save_pretrained(tmpdirname) + + after_tokenizer = tokenizer.__class__.from_pretrained(tmpdirname) + after_tokens = after_tokenizer.encode(sample_text, add_special_tokens=False) + after_vocab = after_tokenizer.get_vocab() + self.assertListEqual(before_tokens, after_tokens) + self.assertDictEqual(before_vocab, after_vocab) + self.assertIn("bim", after_vocab) + self.assertIn("bambam", after_vocab) + self.assertIn("new_additional_special_token", after_tokenizer.additional_special_tokens) + self.assertEqual(after_tokenizer.model_max_length, 42) + + tokenizer = tokenizer.__class__.from_pretrained(tmpdirname, model_max_length=43) + self.assertEqual(tokenizer.model_max_length, 43) + + shutil.rmtree(tmpdirname) + + def test_pickle_tokenizer(self): + """Google pickle __getstate__ __setstate__ if you are struggling with this.""" + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertIsNotNone(tokenizer) + + text = "Munich and Berlin are nice cities" + subwords = tokenizer.tokenize(text) + + filename = os.path.join(self.tmpdirname, "tokenizer.bin") + with open(filename, "wb") as handle: + pickle.dump(tokenizer, handle) + + with open(filename, "rb") as handle: + tokenizer_new = pickle.load(handle) + + subwords_loaded = tokenizer_new.tokenize(text) + + self.assertListEqual(subwords, subwords_loaded) + + @require_tokenizers + def test_pickle_added_tokens(self): + tok1 = AddedToken("", rstrip=True, lstrip=True, normalized=False, single_word=True) + tok2 = pickle.loads(pickle.dumps(tok1)) + + self.assertEqual(tok1.__getstate__(), tok2.__getstate__()) + + def test_added_tokens_do_lower_case(self): + tokenizers = self.get_tokenizers(do_lower_case=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if not hasattr(tokenizer, "do_lower_case") or not tokenizer.do_lower_case: + continue + + special_token = tokenizer.all_special_tokens[0] + + text = special_token + " aaaaa bbbbbb low cccccccccdddddddd l " + special_token + text2 = special_token + " AAAAA BBBBBB low CCCCCCCCCDDDDDDDD l " + special_token + + toks_before_adding = tokenizer.tokenize(text) # toks before adding new_toks + + new_toks = ["aaaaa bbbbbb", "cccccccccdddddddd", "AAAAA BBBBBB", "CCCCCCCCCDDDDDDDD"] + added = tokenizer.add_tokens([AddedToken(tok, lstrip=True, rstrip=True) for tok in new_toks]) + + toks_after_adding = tokenizer.tokenize(text) + toks_after_adding2 = tokenizer.tokenize(text2) + + # Rust tokenizers dont't lowercase added tokens at the time calling `tokenizer.add_tokens`, + # while python tokenizers do, so new_toks 0 and 2 would be treated as the same, so do new_toks 1 and 3. + self.assertIn(added, [2, 4]) + + self.assertListEqual(toks_after_adding, toks_after_adding2) + self.assertTrue( + len(toks_before_adding) > len(toks_after_adding), # toks_before_adding should be longer + ) + + # Check that none of the special tokens are lowercased + sequence_with_special_tokens = "A " + " yEs ".join(tokenizer.all_special_tokens) + " B" + # Convert the tokenized list to str as some special tokens are tokenized like normal tokens + # which have a prefix spacee e.g. the mask token of Albert, and cannot match the original + # special tokens exactly. + tokenized_sequence = "".join(tokenizer.tokenize(sequence_with_special_tokens)) + + for special_token in tokenizer.all_special_tokens: + self.assertTrue(special_token in tokenized_sequence) + + tokenizers = self.get_tokenizers(do_lower_case=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if hasattr(tokenizer, "do_lower_case") and tokenizer.do_lower_case: + continue + + special_token = tokenizer.all_special_tokens[0] + + text = special_token + " aaaaa bbbbbb low cccccccccdddddddd l " + special_token + text2 = special_token + " AAAAA BBBBBB low CCCCCCCCCDDDDDDDD l " + special_token + + toks_before_adding = tokenizer.tokenize(text) # toks before adding new_toks + + new_toks = ["aaaaa bbbbbb", "cccccccccdddddddd", "AAAAA BBBBBB", "CCCCCCCCCDDDDDDDD"] + added = tokenizer.add_tokens([AddedToken(tok, lstrip=True, rstrip=True) for tok in new_toks]) + self.assertIn(added, [2, 4]) + + toks_after_adding = tokenizer.tokenize(text) + toks_after_adding2 = tokenizer.tokenize(text2) + + self.assertEqual(len(toks_after_adding), len(toks_after_adding2)) # Length should still be the same + self.assertNotEqual( + toks_after_adding[1], toks_after_adding2[1] + ) # But at least the first non-special tokens should differ + self.assertTrue( + len(toks_before_adding) > len(toks_after_adding), # toks_before_adding should be longer + ) + + def test_add_tokens_tokenizer(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab_size = tokenizer.vocab_size + all_size = len(tokenizer) + + self.assertNotEqual(vocab_size, 0) + + # We usually have added tokens from the start in tests because our vocab fixtures are + # smaller than the original vocabs - let's not assert this + # self.assertEqual(vocab_size, all_size) + + new_toks = ["aaaaa bbbbbb", "cccccccccdddddddd"] + added_toks = tokenizer.add_tokens(new_toks) + vocab_size_2 = tokenizer.vocab_size + all_size_2 = len(tokenizer) + + self.assertNotEqual(vocab_size_2, 0) + self.assertEqual(vocab_size, vocab_size_2) + self.assertEqual(added_toks, len(new_toks)) + self.assertEqual(all_size_2, all_size + len(new_toks)) + + tokens = tokenizer.encode("aaaaa bbbbbb low cccccccccdddddddd l", add_special_tokens=False) + + self.assertGreaterEqual(len(tokens), 4) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + + new_toks_2 = {"eos_token": ">>>>|||<||<<|<<", "pad_token": "<<<<<|||>|>>>>|>"} + added_toks_2 = tokenizer.add_special_tokens(new_toks_2) + vocab_size_3 = tokenizer.vocab_size + all_size_3 = len(tokenizer) + + self.assertNotEqual(vocab_size_3, 0) + self.assertEqual(vocab_size, vocab_size_3) + self.assertEqual(added_toks_2, len(new_toks_2)) + self.assertEqual(all_size_3, all_size_2 + len(new_toks_2)) + + tokens = tokenizer.encode( + ">>>>|||<||<<|<< aaaaabbbbbb low cccccccccdddddddd <<<<<|||>|>>>>|> l", add_special_tokens=False + ) + + self.assertGreaterEqual(len(tokens), 6) + self.assertGreater(tokens[0], tokenizer.vocab_size - 1) + self.assertGreater(tokens[0], tokens[1]) + self.assertGreater(tokens[-2], tokenizer.vocab_size - 1) + self.assertGreater(tokens[-2], tokens[-3]) + self.assertEqual(tokens[0], tokenizer.eos_token_id) + self.assertEqual(tokens[-2], tokenizer.pad_token_id) + + def test_add_special_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + input_text, ids = self.get_clean_sequence(tokenizer) + + special_token = "[SPECIAL_TOKEN]" + + tokenizer.add_special_tokens({"cls_token": special_token}) + encoded_special_token = tokenizer.encode(special_token, add_special_tokens=False) + self.assertEqual(len(encoded_special_token), 1) + + text = tokenizer.decode(ids + encoded_special_token, clean_up_tokenization_spaces=False) + encoded = tokenizer.encode(text, add_special_tokens=False) + + input_encoded = tokenizer.encode(input_text, add_special_tokens=False) + special_token_id = tokenizer.encode(special_token, add_special_tokens=False) + self.assertEqual(encoded, input_encoded + special_token_id) + + decoded = tokenizer.decode(encoded, skip_special_tokens=True) + self.assertTrue(special_token not in decoded) + + def test_internal_consistency(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + input_text, output_text = self.get_input_output_texts(tokenizer) + + tokens = tokenizer.tokenize(input_text) + ids = tokenizer.convert_tokens_to_ids(tokens) + ids_2 = tokenizer.encode(input_text, add_special_tokens=False) + self.assertListEqual(ids, ids_2) + + tokens_2 = tokenizer.convert_ids_to_tokens(ids) + self.assertNotEqual(len(tokens_2), 0) + text_2 = tokenizer.decode(ids) + self.assertIsInstance(text_2, str) + + self.assertEqual(text_2, output_text) + + @require_tokenizers + def test_encode_decode_with_spaces(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + new_toks = [ + AddedToken("[ABC]", normalized=False), + AddedToken("[DEF]", normalized=False), + AddedToken("GHI IHG", normalized=False), + ] + tokenizer.add_tokens(new_toks) + input = "[ABC][DEF][ABC]GHI IHG[DEF]" + if self.space_between_special_tokens: + output = "[ABC] [DEF] [ABC] GHI IHG [DEF]" + else: + output = input + encoded = tokenizer.encode(input, add_special_tokens=False) + decoded = tokenizer.decode(encoded, spaces_between_special_tokens=self.space_between_special_tokens) + self.assertIn(decoded, [output, output.lower()]) + + def test_pretrained_model_lists(self): + # We should have at least one default checkpoint for each tokenizer + # We should specify the max input length as well (used in some part to list the pretrained checkpoints) + self.assertGreaterEqual(len(self.tokenizer_class.pretrained_vocab_files_map), 1) + self.assertGreaterEqual(len(list(self.tokenizer_class.pretrained_vocab_files_map.values())[0]), 1) + self.assertEqual( + len(list(self.tokenizer_class.pretrained_vocab_files_map.values())[0]), + len(self.tokenizer_class.max_model_input_sizes), + ) + + weights_list = list(self.tokenizer_class.max_model_input_sizes.keys()) + weights_lists_2 = [] + for file_id, map_list in self.tokenizer_class.pretrained_vocab_files_map.items(): + weights_lists_2.append(list(map_list.keys())) + + for weights_list_2 in weights_lists_2: + self.assertListEqual(weights_list, weights_list_2) + + def test_mask_output(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if ( + tokenizer.build_inputs_with_special_tokens.__qualname__.split(".")[0] != "PreTrainedTokenizer" + and "token_type_ids" in tokenizer.model_input_names + ): + seq_0 = "Test this method." + seq_1 = "With these inputs." + information = tokenizer.encode_plus(seq_0, seq_1, add_special_tokens=True) + sequences, mask = information["input_ids"], information["token_type_ids"] + self.assertEqual(len(sequences), len(mask)) + + def test_token_type_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + + # We want to have sequence 0 and sequence 1 are tagged + # respectively with 0 and 1 token_ids + # (regardless of whether the model use token type ids) + # We use this assumption in the QA pipeline among other place + output = tokenizer(seq_0, return_token_type_ids=True) + self.assertIn(0, output["token_type_ids"]) + + def test_sequence_ids(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + if not tokenizer.is_fast: + continue + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + seq_1 = "With these inputs." + + # We want to have sequence 0 and sequence 1 are tagged + # respectively with 0 and 1 token_ids + # (regardless of whether the model use token type ids) + # We use this assumption in the QA pipeline among other place + output = tokenizer(seq_0) + self.assertIn(0, output.sequence_ids()) + + output = tokenizer(seq_0, seq_1) + self.assertIn(0, output.sequence_ids()) + self.assertIn(1, output.sequence_ids()) + + if tokenizer.num_special_tokens_to_add(pair=True): + self.assertIn(None, output.sequence_ids()) + + def test_number_of_added_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0 = "Test this method." + seq_1 = "With these inputs." + + sequences = tokenizer.encode(seq_0, seq_1, add_special_tokens=False) + attached_sequences = tokenizer.encode(seq_0, seq_1, add_special_tokens=True) + + # Method is implemented (e.g. not GPT-2) + if len(attached_sequences) != 2: + self.assertEqual( + tokenizer.num_special_tokens_to_add(pair=True), len(attached_sequences) - len(sequences) + ) + + def test_maximum_encoding_length_single_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + seq_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + + sequence = tokenizer.encode(seq_0, add_special_tokens=False) + total_length = len(sequence) + + self.assertGreater( + total_length, 4, "Issue with the testing sequence, please update it, it's too short" + ) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_1 = seq_0 * model_max_length + + sequence1 = tokenizer(seq_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + self.assertGreater( + total_length1, + model_max_length, + "Issue with the testing sequence, please update it, it's too short", + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"Truncation: {truncation_state}"): + output = tokenizer(seq_1, padding=padding_state, truncation=truncation_state) + self.assertEqual(len(output["input_ids"]), model_max_length) + + output = tokenizer([seq_1], padding=padding_state, truncation=truncation_state) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer(seq_1, padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer([seq_1], padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + # Overflowing tokens + stride = 2 + information = tokenizer( + seq_0, + max_length=total_length - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, PreTrainedTokenizerFast): + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence[:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence[-(2 + stride) :]) + else: + truncated_sequence = information["input_ids"] + overflowing_tokens = information["overflowing_tokens"] + + self.assertEqual(len(truncated_sequence), total_length - 2) + self.assertEqual(truncated_sequence, sequence[:-2]) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, sequence[-(2 + stride) :]) + + def test_maximum_encoding_length_pair_input(self): + tokenizers = self.get_tokenizers(do_lower_case=False, model_max_length=100) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Build a sequence from our model's vocabulary + stride = 2 + seq_0, ids = self.get_clean_sequence(tokenizer, max_length=20) + if len(ids) <= 2 + stride: + seq_0 = (seq_0 + " ") * (2 + stride) + ids = None + + seq0_tokens = tokenizer.encode(seq_0, add_special_tokens=False) + self.assertGreater(len(seq0_tokens), 2 + stride) + + seq_1 = "This is another sentence to be encoded." + seq1_tokens = tokenizer.encode(seq_1, add_special_tokens=False) + if abs(len(seq0_tokens) - len(seq1_tokens)) <= 2: + seq1_tokens = seq1_tokens + seq1_tokens + seq_1 = tokenizer.decode(seq1_tokens, clean_up_tokenization_spaces=False) + seq1_tokens = tokenizer.encode(seq_1, add_special_tokens=False) + + self.assertGreater(len(seq1_tokens), 2 + stride) + + smallest = seq1_tokens if len(seq0_tokens) > len(seq1_tokens) else seq0_tokens + + # We are not using the special tokens - a bit too hard to test all the tokenizers with this + # TODO try this again later + sequence = tokenizer.encode(seq_0, seq_1, add_special_tokens=False) # , add_prefix_space=False) + + # Test with max model input length + model_max_length = tokenizer.model_max_length + self.assertEqual(model_max_length, 100) + seq_2 = seq_0 * model_max_length + self.assertGreater(len(seq_2), model_max_length) + + sequence1 = tokenizer(seq_1, add_special_tokens=False) + total_length1 = len(sequence1["input_ids"]) + sequence2 = tokenizer(seq_2, seq_1, add_special_tokens=False) + total_length2 = len(sequence2["input_ids"]) + self.assertLess( + total_length1, model_max_length - 10, "Issue with the testing sequence, please update it." + ) + self.assertGreater( + total_length2, model_max_length, "Issue with the testing sequence, please update it." + ) + + # Simple + padding_strategies = ( + [False, True, "longest"] if tokenizer.pad_token and tokenizer.pad_token_id >= 0 else [False] + ) + for padding_state in padding_strategies: + with self.subTest(f"{tokenizer.__class__.__name__} Padding: {padding_state}"): + for truncation_state in [True, "longest_first", "only_first"]: + with self.subTest(f"{tokenizer.__class__.__name__} Truncation: {truncation_state}"): + output = tokenizer(seq_2, seq_1, padding=padding_state, truncation=truncation_state) + self.assertEqual(len(output["input_ids"]), model_max_length) + + output = tokenizer( + [seq_2], [seq_1], padding=padding_state, truncation=truncation_state + ) + self.assertEqual(len(output["input_ids"][0]), model_max_length) + + # Simple + output = tokenizer(seq_1, seq_2, padding=padding_state, truncation="only_second") + self.assertEqual(len(output["input_ids"]), model_max_length) + + output = tokenizer([seq_1], [seq_2], padding=padding_state, truncation="only_second") + self.assertEqual(len(output["input_ids"][0]), model_max_length) + + # Simple with no truncation + # Reset warnings + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer(seq_1, seq_2, padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + tokenizer.deprecation_warnings = {} + with self.assertLogs("transformers", level="WARNING") as cm: + output = tokenizer([seq_1], [seq_2], padding=padding_state, truncation=False) + self.assertNotEqual(len(output["input_ids"][0]), model_max_length) + self.assertEqual(len(cm.records), 1) + self.assertTrue( + cm.records[0].message.startswith( + "Token indices sequence length is longer than the specified maximum sequence length" + " for this model" + ) + ) + + truncated_first_sequence = tokenizer.encode(seq_0, add_special_tokens=False)[:-2] + tokenizer.encode( + seq_1, add_special_tokens=False + ) + truncated_second_sequence = ( + tokenizer.encode(seq_0, add_special_tokens=False) + + tokenizer.encode(seq_1, add_special_tokens=False)[:-2] + ) + truncated_longest_sequence = ( + truncated_first_sequence if len(seq0_tokens) > len(seq1_tokens) else truncated_second_sequence + ) + + overflow_first_sequence = tokenizer.encode(seq_0, add_special_tokens=False)[ + -(2 + stride) : + ] + tokenizer.encode(seq_1, add_special_tokens=False) + overflow_second_sequence = ( + tokenizer.encode(seq_0, add_special_tokens=False) + + tokenizer.encode(seq_1, add_special_tokens=False)[-(2 + stride) :] + ) + overflow_longest_sequence = ( + overflow_first_sequence if len(seq0_tokens) > len(seq1_tokens) else overflow_second_sequence + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, PreTrainedTokenizerFast): + information = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation="longest_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, PreTrainedTokenizerFast): + information = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + truncated_sequence = information["input_ids"][0] + overflowing_tokens = information["input_ids"][1] + self.assertEqual(len(information["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_longest_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(smallest)) + self.assertEqual(overflowing_tokens, overflow_longest_sequence) + else: + # No overflowing tokens when using 'longest' in python tokenizers + with self.assertRaises(ValueError) as context: + information = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation=True, + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + + self.assertTrue( + context.exception.args[0].startswith( + "Not possible to return overflowing tokens for pair of sequences with the " + "`longest_first`. Please select another truncation strategy than `longest_first`, " + "for instance `only_second` or `only_first`." + ) + ) + + information_first_truncated = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_first", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, PreTrainedTokenizerFast): + truncated_sequence = information_first_truncated["input_ids"][0] + overflowing_tokens = information_first_truncated["input_ids"][1] + self.assertEqual(len(information_first_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq1_tokens)) + self.assertEqual(overflowing_tokens, overflow_first_sequence) + else: + truncated_sequence = information_first_truncated["input_ids"] + overflowing_tokens = information_first_truncated["overflowing_tokens"] + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_first_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq0_tokens[-(2 + stride) :]) + + information_second_truncated = tokenizer( + seq_0, + seq_1, + max_length=len(sequence) - 2, + add_special_tokens=False, + stride=stride, + truncation="only_second", + return_overflowing_tokens=True, + # add_prefix_space=False, + ) + # Overflowing tokens are handled quite differently in slow and fast tokenizers + if isinstance(tokenizer, PreTrainedTokenizerFast): + truncated_sequence = information_second_truncated["input_ids"][0] + overflowing_tokens = information_second_truncated["input_ids"][1] + self.assertEqual(len(information_second_truncated["input_ids"]), 2) + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride + len(seq0_tokens)) + self.assertEqual(overflowing_tokens, overflow_second_sequence) + else: + truncated_sequence = information_second_truncated["input_ids"] + overflowing_tokens = information_second_truncated["overflowing_tokens"] + + self.assertEqual(len(truncated_sequence), len(sequence) - 2) + self.assertEqual(truncated_sequence, truncated_second_sequence) + + self.assertEqual(len(overflowing_tokens), 2 + stride) + self.assertEqual(overflowing_tokens, seq1_tokens[-(2 + stride) :]) + + # def test_encode_input_type(self): + # tokenizers = self.get_tokenizers(do_lower_case=False) + # for tokenizer in tokenizers: + # with self.subTest(f"{tokenizer.__class__.__name__}"): + # sequence = "Let's encode this sequence" + + # tokens = sequence.split() # tokenizer.tokenize(sequence) + # # input_ids = tokenizer.convert_tokens_to_ids(tokens) + # formatted_input = tokenizer.encode(sequence, add_special_tokens=True, add_prefix_space=False) + + # self.assertEqual( + # tokenizer.encode(tokens, is_split_into_words=True, add_special_tokens=True), formatted_input + # ) + # # This is not supported with the Rust tokenizers + # # self.assertEqual(tokenizer.encode(input_ids, add_special_tokens=True), formatted_input) + + # def test_swap_special_token(self): + # tokenizers = self.get_tokenizers(do_lower_case=False) + # for tokenizer in tokenizers: + # with self.subTest(f"{tokenizer.__class__.__name__}"): + # # Our mask token + # mask = "" + # # We take a single word in the middle of the vocabulary + # all_tokens = sorted(tokenizer.get_vocab().keys()) + # word = tokenizer.decode(tokenizer.encode(all_tokens[len(all_tokens)//2], add_special_tokens=False)[:1]) + + # sequence_0 = "Encode " + word + " sequence" + # sequence_masked_0 = "Encode " + mask + " sequence" + + # sequence_1 = word + " this sequence" + # sequence_masked_1 = mask + " this sequence" + + # # Add tokens so that masked token isn't split + # # tokens = [AddedToken(t, lstrip=True, normalized=False) for t in sequence.split()] + # # tokenizer.add_tokens(tokens) + # tokenizer.add_special_tokens( + # {"mask_token": AddedToken(mask, normalized=False)} + # ) # Eat left space on Byte-level BPE tokenizers + # mask_ind = tokenizer.convert_tokens_to_ids(mask) + + # # Test first masked sequence + # encoded_0 = tokenizer.encode(sequence_0, add_special_tokens=False) + # encoded_masked = tokenizer.encode(sequence_masked_0, add_special_tokens=False) + # self.assertEqual(len(encoded_masked), len(encoded_0)) + # mask_loc = encoded_masked.index(mask_ind) + # encoded_masked[mask_loc] = encoded_0[mask_loc] + + # self.assertEqual(encoded_masked, encoded_0) + + # # Test second masked sequence + # encoded_1 = tokenizer.encode(sequence_1, add_special_tokens=False) + # encoded_masked = tokenizer.encode(sequence_masked_1, add_special_tokens=False) + # self.assertEqual(len(encoded_masked), len(encoded_1)) + # mask_loc = encoded_masked.index(mask_ind) + # encoded_masked[mask_loc] = encoded_1[mask_loc] + + # self.assertEqual(encoded_masked, encoded_1) + + def test_special_tokens_mask(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence_0 = "Encode this." + # Testing single inputs + encoded_sequence = tokenizer.encode(sequence_0, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + sequence_0, add_special_tokens=True, return_special_tokens_mask=True # , add_prefix_space=False + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [x for i, x in enumerate(encoded_sequence_w_special) if not special_tokens_mask[i]] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_special_tokens_mask_input_pairs(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence_0 = "Encode this." + sequence_1 = "This one too please." + encoded_sequence = tokenizer.encode(sequence_0, add_special_tokens=False) + encoded_sequence += tokenizer.encode(sequence_1, add_special_tokens=False) + encoded_sequence_dict = tokenizer.encode_plus( + sequence_0, + sequence_1, + add_special_tokens=True, + return_special_tokens_mask=True, + # add_prefix_space=False, + ) + encoded_sequence_w_special = encoded_sequence_dict["input_ids"] + special_tokens_mask = encoded_sequence_dict["special_tokens_mask"] + self.assertEqual(len(special_tokens_mask), len(encoded_sequence_w_special)) + + filtered_sequence = [ + (x if not special_tokens_mask[i] else None) for i, x in enumerate(encoded_sequence_w_special) + ] + filtered_sequence = [x for x in filtered_sequence if x is not None] + self.assertEqual(encoded_sequence, filtered_sequence) + + def test_padding_side_in_kwargs(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + if self.test_rust_tokenizer: + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, padding_side="left", **kwargs + ) + self.assertEqual(tokenizer_r.padding_side, "left") + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, padding_side="right", **kwargs + ) + self.assertEqual(tokenizer_r.padding_side, "right") + + self.assertRaises( + ValueError, + self.rust_tokenizer_class.from_pretrained, + pretrained_name, + padding_side="unauthorized", + **kwargs, + ) + + if self.test_slow_tokenizer: + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, padding_side="left", **kwargs) + self.assertEqual(tokenizer_p.padding_side, "left") + + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, padding_side="right", **kwargs) + self.assertEqual(tokenizer_p.padding_side, "right") + + self.assertRaises( + ValueError, + self.tokenizer_class.from_pretrained, + pretrained_name, + padding_side="unauthorized", + **kwargs, + ) + + def test_truncation_side_in_kwargs(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + if self.test_rust_tokenizer: + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, truncation_side="left", **kwargs + ) + self.assertEqual(tokenizer_r.truncation_side, "left") + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, truncation_side="right", **kwargs + ) + self.assertEqual(tokenizer_r.truncation_side, "right") + + self.assertRaises( + ValueError, + self.rust_tokenizer_class.from_pretrained, + pretrained_name, + truncation_side="unauthorized", + **kwargs, + ) + + if self.test_slow_tokenizer: + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, truncation_side="left", **kwargs + ) + self.assertEqual(tokenizer_p.truncation_side, "left") + + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, truncation_side="right", **kwargs + ) + self.assertEqual(tokenizer_p.truncation_side, "right") + + self.assertRaises( + ValueError, + self.tokenizer_class.from_pretrained, + pretrained_name, + truncation_side="unauthorized", + **kwargs, + ) + + def test_right_and_left_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence = "Sequence" + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_idx = tokenizer.pad_token_id + + # RIGHT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(sequence) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + sequence, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + self.assertEqual(sequence_length + padding_size, padded_sequence_length) + self.assertEqual(encoded_sequence + [padding_idx] * padding_size, padded_sequence) + + # LEFT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "left" + encoded_sequence = tokenizer.encode(sequence) + sequence_length = len(encoded_sequence) + padded_sequence = tokenizer.encode( + sequence, max_length=sequence_length + padding_size, padding="max_length" + ) + padded_sequence_length = len(padded_sequence) + self.assertEqual(sequence_length + padding_size, padded_sequence_length) + self.assertEqual([padding_idx] * padding_size + encoded_sequence, padded_sequence) + + # RIGHT & LEFT PADDING - Check that nothing is done for 'longest' and 'no_padding' + encoded_sequence = tokenizer.encode(sequence) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(sequence, padding=True) + padded_sequence_right_length = len(padded_sequence_right) + self.assertEqual(sequence_length, padded_sequence_right_length) + self.assertEqual(encoded_sequence, padded_sequence_right) + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(sequence, padding="longest") + padded_sequence_left_length = len(padded_sequence_left) + self.assertEqual(sequence_length, padded_sequence_left_length) + self.assertEqual(encoded_sequence, padded_sequence_left) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(sequence) + padded_sequence_right_length = len(padded_sequence_right) + self.assertEqual(sequence_length, padded_sequence_right_length) + self.assertEqual(encoded_sequence, padded_sequence_right) + + tokenizer.padding_side = "left" + padded_sequence_left = tokenizer.encode(sequence, padding=False) + padded_sequence_left_length = len(padded_sequence_left) + self.assertEqual(sequence_length, padded_sequence_left_length) + self.assertEqual(encoded_sequence, padded_sequence_left) + + def test_right_and_left_truncation(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence = "This is a test sequence" + + # RIGHT PADDING - Check that it correctly pads when a maximum length is specified along with the padding flag set to True + truncation_size = 3 + tokenizer.truncation_side = "right" + encoded_sequence = tokenizer.encode(sequence, add_special_tokens=False) + sequence_length = len(encoded_sequence) + # Remove EOS/BOS tokens + truncated_sequence = tokenizer.encode( + sequence, max_length=sequence_length - truncation_size, truncation=True, add_special_tokens=False + ) + truncated_sequence_length = len(truncated_sequence) + self.assertEqual(sequence_length, truncated_sequence_length + truncation_size) + self.assertEqual(encoded_sequence[:-truncation_size], truncated_sequence) + + # LEFT PADDING - Check that it correctly pads when a maximum length is specified along with the truncation flag set to True + tokenizer.truncation_side = "left" + sequence_length = len(encoded_sequence) + truncated_sequence = tokenizer.encode( + sequence, max_length=sequence_length - truncation_size, truncation=True, add_special_tokens=False + ) + truncated_sequence_length = len(truncated_sequence) + self.assertEqual(sequence_length, truncated_sequence_length + truncation_size) + self.assertEqual(encoded_sequence[truncation_size:], truncated_sequence) + + # RIGHT & LEFT PADDING - Check that nothing is done for 'longest' and 'no_truncation' + sequence_length = len(encoded_sequence) + + tokenizer.truncation_side = "right" + truncated_sequence_right = tokenizer.encode(sequence, truncation=True, add_special_tokens=False) + truncated_sequence_right_length = len(truncated_sequence_right) + self.assertEqual(sequence_length, truncated_sequence_right_length) + self.assertEqual(encoded_sequence, truncated_sequence_right) + + tokenizer.truncation_side = "left" + truncated_sequence_left = tokenizer.encode( + sequence, truncation="longest_first", add_special_tokens=False + ) + truncated_sequence_left_length = len(truncated_sequence_left) + self.assertEqual(sequence_length, truncated_sequence_left_length) + self.assertEqual(encoded_sequence, truncated_sequence_left) + + tokenizer.truncation_side = "right" + truncated_sequence_right = tokenizer.encode(sequence, add_special_tokens=False) + truncated_sequence_right_length = len(truncated_sequence_right) + self.assertEqual(sequence_length, truncated_sequence_right_length) + self.assertEqual(encoded_sequence, truncated_sequence_right) + + tokenizer.truncation_side = "left" + truncated_sequence_left = tokenizer.encode(sequence, truncation=False, add_special_tokens=False) + truncated_sequence_left_length = len(truncated_sequence_left) + self.assertEqual(sequence_length, truncated_sequence_left_length) + self.assertEqual(encoded_sequence, truncated_sequence_left) + + def test_padding_to_max_length(self): + """We keep this test for backward compatibility but it should be remove when `pad_to_max_length` is deprecated.""" + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence = "Sequence" + padding_size = 10 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_idx = tokenizer.pad_token_id + + # Check that it correctly pads when a maximum length is specified along with the padding flag set to True + tokenizer.padding_side = "right" + encoded_sequence = tokenizer.encode(sequence) + sequence_length = len(encoded_sequence) + # FIXME: the next line should be padding(max_length) to avoid warning + padded_sequence = tokenizer.encode( + sequence, max_length=sequence_length + padding_size, pad_to_max_length=True + ) + padded_sequence_length = len(padded_sequence) + self.assertEqual(sequence_length + padding_size, padded_sequence_length) + self.assertEqual(encoded_sequence + [padding_idx] * padding_size, padded_sequence) + + # Check that nothing is done when a maximum length is not specified + encoded_sequence = tokenizer.encode(sequence) + sequence_length = len(encoded_sequence) + + tokenizer.padding_side = "right" + padded_sequence_right = tokenizer.encode(sequence, pad_to_max_length=True) + padded_sequence_right_length = len(padded_sequence_right) + self.assertEqual(sequence_length, padded_sequence_right_length) + self.assertEqual(encoded_sequence, padded_sequence_right) + + def test_padding_to_multiple_of(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.pad_token is None: + self.skipTest("No padding token.") + else: + empty_tokens = tokenizer("", padding=True, pad_to_multiple_of=8) + normal_tokens = tokenizer("This is a sample input", padding=True, pad_to_multiple_of=8) + for key, value in empty_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + normal_tokens = tokenizer("This", pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertNotEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # Should also work with truncation + normal_tokens = tokenizer("This", padding=True, truncation=True, pad_to_multiple_of=8) + for key, value in normal_tokens.items(): + self.assertEqual(len(value) % 8, 0, f"BatchEncoding.{key} is not multiple of 8") + + # truncation to something which is not a multiple of pad_to_multiple_of raises an error + self.assertRaises( + ValueError, + tokenizer.__call__, + "This", + padding=True, + truncation=True, + max_length=12, + pad_to_multiple_of=8, + ) + + def test_padding_with_attention_mask(self): + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.pad_token is None: + self.skipTest("No padding token.") + if "attention_mask" not in tokenizer.model_input_names: + self.skipTest("This model does not use attention mask.") + + features = [ + {"input_ids": [1, 2, 3, 4, 5, 6], "attention_mask": [1, 1, 1, 1, 1, 0]}, + {"input_ids": [1, 2, 3], "attention_mask": [1, 1, 0]}, + ] + padded_features = tokenizer.pad(features) + if tokenizer.padding_side == "right": + self.assertListEqual(padded_features["attention_mask"], [[1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0]]) + else: + self.assertListEqual(padded_features["attention_mask"], [[1, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 0]]) + + def test_encode_plus_with_padding(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequence = "Sequence" + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequence) + + padding_size = 10 + padding_idx = tokenizer.pad_token_id + token_type_padding_idx = tokenizer.pad_token_type_id + + encoded_sequence = tokenizer.encode_plus(sequence, return_special_tokens_mask=True) + input_ids = encoded_sequence["input_ids"] + special_tokens_mask = encoded_sequence["special_tokens_mask"] + sequence_length = len(input_ids) + + # Test 'longest' and 'no_padding' don't do anything + tokenizer.padding_side = "right" + + not_padded_sequence = tokenizer.encode_plus( + sequence, + padding=True, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertEqual(sequence_length, not_padded_sequence_length) + self.assertEqual(input_ids, not_padded_input_ids) + self.assertEqual(special_tokens_mask, not_padded_special_tokens_mask) + + not_padded_sequence = tokenizer.encode_plus( + sequence, + padding=False, + return_special_tokens_mask=True, + ) + not_padded_input_ids = not_padded_sequence["input_ids"] + + not_padded_special_tokens_mask = not_padded_sequence["special_tokens_mask"] + not_padded_sequence_length = len(not_padded_input_ids) + + self.assertEqual(sequence_length, not_padded_sequence_length) + self.assertEqual(input_ids, not_padded_input_ids) + self.assertEqual(special_tokens_mask, not_padded_special_tokens_mask) + + # Test right padding + tokenizer.padding_side = "right" + + right_padded_sequence = tokenizer.encode_plus( + sequence, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + right_padded_input_ids = right_padded_sequence["input_ids"] + + right_padded_special_tokens_mask = right_padded_sequence["special_tokens_mask"] + right_padded_sequence_length = len(right_padded_input_ids) + + self.assertEqual(sequence_length + padding_size, right_padded_sequence_length) + self.assertEqual(input_ids + [padding_idx] * padding_size, right_padded_input_ids) + self.assertEqual(special_tokens_mask + [1] * padding_size, right_padded_special_tokens_mask) + + # Test left padding + tokenizer.padding_side = "left" + left_padded_sequence = tokenizer.encode_plus( + sequence, + max_length=sequence_length + padding_size, + padding="max_length", + return_special_tokens_mask=True, + ) + left_padded_input_ids = left_padded_sequence["input_ids"] + left_padded_special_tokens_mask = left_padded_sequence["special_tokens_mask"] + left_padded_sequence_length = len(left_padded_input_ids) + + self.assertEqual(sequence_length + padding_size, left_padded_sequence_length) + self.assertEqual([padding_idx] * padding_size + input_ids, left_padded_input_ids) + self.assertEqual([1] * padding_size + special_tokens_mask, left_padded_special_tokens_mask) + + if "token_type_ids" in tokenizer.model_input_names: + token_type_ids = encoded_sequence["token_type_ids"] + left_padded_token_type_ids = left_padded_sequence["token_type_ids"] + right_padded_token_type_ids = right_padded_sequence["token_type_ids"] + + self.assertEqual( + token_type_ids + [token_type_padding_idx] * padding_size, right_padded_token_type_ids + ) + self.assertEqual( + [token_type_padding_idx] * padding_size + token_type_ids, left_padded_token_type_ids + ) + + if "attention_mask" in tokenizer.model_input_names: + attention_mask = encoded_sequence["attention_mask"] + right_padded_attention_mask = right_padded_sequence["attention_mask"] + left_padded_attention_mask = left_padded_sequence["attention_mask"] + + self.assertEqual(attention_mask + [0] * padding_size, right_padded_attention_mask) + self.assertEqual([0] * padding_size + attention_mask, left_padded_attention_mask) + + def test_padding_warning_message_fast_tokenizer(self): + if not self.test_rust_tokenizer: + return + + sequence = "This is a text" + + tokenizer_fast = self.get_rust_tokenizer() + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer_fast, sequence) + + encoding_fast = tokenizer_fast(sequence) + + with self.assertLogs("transformers", level="WARNING") as cm: + tokenizer_fast.pad(encoding_fast) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to" + " encode the text followed by a call to the `pad` method to get a padded encoding.", + cm.records[0].message, + ) + + if not self.test_slow_tokenizer: + return + + tokenizer_slow = self.get_tokenizer() + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer_slow, sequence) + + encoding_slow = tokenizer_slow(sequence) + + with self.assertLogs(level="WARNING") as cm: + # We want to assert there are no warnings, but the 'assertLogs' method does not support that. + # Therefore, we are adding a dummy warning, and then we will assert it is the only warning. + logger.warning("Dummy warning") + tokenizer_slow.pad(encoding_slow) + self.assertEqual(len(cm.records), 1) + self.assertIn( + "Dummy warning", + cm.records[0].message, + ) + + def test_separate_tokenizers(self): + # This tests that tokenizers don't impact others. Unfortunately the case where it fails is when + # we're loading an S3 configuration from a pre-trained identifier, and we have no way of testing those today. + + tokenizers = self.get_tokenizers(random_argument=True) + new_tokenizers = self.get_tokenizers(random_argument=False) + + for tokenizer, new_tokenizer in zip(tokenizers, new_tokenizers): + with self.subTest(f"{tokenizer.__class__.__name__}"): + self.assertTrue(tokenizer.init_kwargs["random_argument"]) + self.assertTrue(tokenizer.init_kwargs["random_argument"]) + self.assertFalse(new_tokenizer.init_kwargs["random_argument"]) + + def test_get_vocab(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab_dict = tokenizer.get_vocab() + self.assertIsInstance(vocab_dict, dict) + self.assertGreaterEqual(len(tokenizer), len(vocab_dict)) + + vocab = [tokenizer.convert_ids_to_tokens(i) for i in range(len(tokenizer))] + self.assertEqual(len(vocab), len(tokenizer)) + + tokenizer.add_tokens(["asdfasdfasdfasdf"]) + vocab = [tokenizer.convert_ids_to_tokens(i) for i in range(len(tokenizer))] + self.assertEqual(len(vocab), len(tokenizer)) + + def test_conversion_reversible(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + vocab = tokenizer.get_vocab() + for word, ind in vocab.items(): + if word == tokenizer.unk_token: + continue + self.assertEqual(tokenizer.convert_tokens_to_ids(word), ind) + self.assertEqual(tokenizer.convert_ids_to_tokens(ind), word) + + def test_call(self): + # Tests that all call wrap to encode_plus and batch_encode_plus + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequences = [ + "Testing batch encode plus", + "Testing batch encode plus with different sequence lengths", + "Testing batch encode plus with different sequence lengths correctly pads", + ] + + # Test not batched + encoded_sequences_1 = tokenizer.encode_plus(sequences[0]) + encoded_sequences_2 = tokenizer(sequences[0]) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test not batched pairs + encoded_sequences_1 = tokenizer.encode_plus(sequences[0], sequences[1]) + encoded_sequences_2 = tokenizer(sequences[0], sequences[1]) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test batched + encoded_sequences_1 = tokenizer.batch_encode_plus(sequences) + encoded_sequences_2 = tokenizer(sequences) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + # Test batched pairs + encoded_sequences_1 = tokenizer.batch_encode_plus(list(zip(sequences, sequences))) + encoded_sequences_2 = tokenizer(sequences, sequences) + self.assertEqual(encoded_sequences_1, encoded_sequences_2) + + def test_batch_encode_plus_batch_sequence_length(self): + # Tests that all encoded values have the correct size + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequences = [ + "Testing batch encode plus", + "Testing batch encode plus with different sequence lengths", + "Testing batch encode plus with different sequence lengths correctly pads", + ] + + encoded_sequences = [tokenizer.encode_plus(sequence) for sequence in sequences] + encoded_sequences_batch = tokenizer.batch_encode_plus(sequences, padding=False) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + maximum_length = len( + max([encoded_sequence["input_ids"] for encoded_sequence in encoded_sequences], key=len) + ) + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequences) + + encoded_sequences_padded = [ + tokenizer.encode_plus(sequence, max_length=maximum_length, padding="max_length") + for sequence in sequences + ] + + encoded_sequences_batch_padded = tokenizer.batch_encode_plus(sequences, padding=True) + self.assertListEqual( + encoded_sequences_padded, + self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch_padded), + ) + + # check 'longest' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus(sequences, padding=True) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + sequences, max_length=maximum_length + 10, padding="longest" + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + # check 'no_padding' is unsensitive to a max length + encoded_sequences_batch_padded_1 = tokenizer.batch_encode_plus(sequences, padding=False) + encoded_sequences_batch_padded_2 = tokenizer.batch_encode_plus( + sequences, max_length=maximum_length + 10, padding=False + ) + for key in encoded_sequences_batch_padded_1.keys(): + self.assertListEqual( + encoded_sequences_batch_padded_1[key], + encoded_sequences_batch_padded_2[key], + ) + + @require_tokenizers + def test_added_token_are_matched_longest_first(self): + if not self.test_slow_tokenizer: + self.skipTest("This test is only for slow tokenizers") + return + tokenizers = self.get_tokenizers(fast=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + try: + tokenizer.add_tokens([AddedToken("extra_id_1")]) + tokenizer.add_tokens([AddedToken("extra_id_100")]) + except Exception: + # Canine cannot add tokens which are not codepoints + self.skipTest("Cannot add those Added tokens") + + # XXX: This used to split on `extra_id_1` first we're matching + # longest first now. + tokens = tokenizer.tokenize("This is some extra_id_100") + self.assertIn("extra_id_100", tokens) + + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokenizer.add_tokens([AddedToken("extra_id_100")]) + tokenizer.add_tokens([AddedToken("extra_id_1")]) + + tokens = tokenizer.tokenize("This is some extra_id_100") + self.assertIn("extra_id_100", tokens) + + @require_tokenizers + def test_added_token_serializable(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + new_token = AddedToken("new_token", lstrip=True) + tokenizer.add_special_tokens({"additional_special_tokens": [new_token]}) + + with tempfile.TemporaryDirectory() as tmp_dir_name: + tokenizer.save_pretrained(tmp_dir_name) + tokenizer.from_pretrained(tmp_dir_name) + + def test_batch_encode_plus_padding(self): + # Test that padded sequences are equivalent between batch_encode_plus and encode_plus + + # Right padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequences = [ + "Testing batch encode plus", + "Testing batch encode plus with different sequence lengths", + "Testing batch encode plus with different sequence lengths correctly pads", + ] + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequences) + + encoded_sequences = [ + tokenizer.encode_plus(sequence, max_length=max_length, padding="max_length") + for sequence in sequences + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + sequences, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + # Left padding tests + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokenizer.padding_side = "left" + sequences = [ + "Testing batch encode plus", + "Testing batch encode plus with different sequence lengths", + "Testing batch encode plus with different sequence lengths correctly pads", + ] + + max_length = 100 + + # check correct behaviour if no pad_token_id exists and add it eventually + self._check_no_pad_token_padding(tokenizer, sequences) + + encoded_sequences = [ + tokenizer.encode_plus(sequence, max_length=max_length, padding="max_length") + for sequence in sequences + ] + encoded_sequences_batch = tokenizer.batch_encode_plus( + sequences, max_length=max_length, padding="max_length" + ) + self.assertListEqual( + encoded_sequences, self.convert_batch_encode_plus_format_to_encode_plus(encoded_sequences_batch) + ) + + def test_pretokenized_inputs(self): + # Test when inputs are pretokenized + + tokenizers = self.get_tokenizers(do_lower_case=False) # , add_prefix_space=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if hasattr(tokenizer, "add_prefix_space") and not tokenizer.add_prefix_space: + continue + + # Prepare a sequence from our tokenizer vocabulary + sequence, ids = self.get_clean_sequence(tokenizer, with_prefix_space=True, max_length=20) + # sequence = " " + sequence # To be sure the byte-level tokenizers are feeling good + token_sequence = sequence.split() + # sequence_no_prefix_space = sequence.strip() + + # Test encode for pretokenized inputs + output = tokenizer.encode(token_sequence, is_split_into_words=True, add_special_tokens=False) + output_sequence = tokenizer.encode(sequence, add_special_tokens=False) + self.assertEqual(output, output_sequence) + + output = tokenizer.encode(token_sequence, is_split_into_words=True, add_special_tokens=True) + output_sequence = tokenizer.encode(sequence, add_special_tokens=True) + self.assertEqual(output, output_sequence) + + # Test encode_plus for pretokenized inputs + output = tokenizer.encode_plus(token_sequence, is_split_into_words=True, add_special_tokens=False) + output_sequence = tokenizer.encode_plus(sequence, add_special_tokens=False) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + output = tokenizer.encode_plus(token_sequence, is_split_into_words=True, add_special_tokens=True) + output_sequence = tokenizer.encode_plus(sequence, add_special_tokens=True) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + + # Test batch_encode_plus for pretokenized inputs + sequence_batch = [sequence.strip()] * 2 + [sequence.strip() + " " + sequence.strip()] + token_sequence_batch = [s.split() for s in sequence_batch] + sequence_batch_cleaned_up_spaces = [" " + " ".join(s) for s in token_sequence_batch] + + output = tokenizer.batch_encode_plus( + token_sequence_batch, is_split_into_words=True, add_special_tokens=False + ) + output_sequence = tokenizer.batch_encode_plus( + sequence_batch_cleaned_up_spaces, add_special_tokens=False + ) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + output = tokenizer.batch_encode_plus( + token_sequence_batch, is_split_into_words=True, add_special_tokens=True + ) + output_sequence = tokenizer.batch_encode_plus( + sequence_batch_cleaned_up_spaces, add_special_tokens=True + ) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + + # Test encode for pretokenized inputs pairs + output = tokenizer.encode( + token_sequence, token_sequence, is_split_into_words=True, add_special_tokens=False + ) + output_sequence = tokenizer.encode(sequence, sequence, add_special_tokens=False) + self.assertEqual(output, output_sequence) + output = tokenizer.encode( + token_sequence, token_sequence, is_split_into_words=True, add_special_tokens=True + ) + output_sequence = tokenizer.encode(sequence, sequence, add_special_tokens=True) + self.assertEqual(output, output_sequence) + + # Test encode_plus for pretokenized inputs pairs + output = tokenizer.encode_plus( + token_sequence, token_sequence, is_split_into_words=True, add_special_tokens=False + ) + output_sequence = tokenizer.encode_plus(sequence, sequence, add_special_tokens=False) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + output = tokenizer.encode_plus( + token_sequence, token_sequence, is_split_into_words=True, add_special_tokens=True + ) + output_sequence = tokenizer.encode_plus(sequence, sequence, add_special_tokens=True) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + + # Test batch_encode_plus for pretokenized inputs pairs + sequence_pair_batch = [(sequence.strip(), sequence.strip())] * 2 + [ + (sequence.strip() + " " + sequence.strip(), sequence.strip()) + ] + token_sequence_pair_batch = [tuple(s.split() for s in pair) for pair in sequence_pair_batch] + sequence_pair_batch_cleaned_up_spaces = [ + tuple(" " + " ".join(s) for s in pair) for pair in token_sequence_pair_batch + ] + + output = tokenizer.batch_encode_plus( + token_sequence_pair_batch, is_split_into_words=True, add_special_tokens=False + ) + output_sequence = tokenizer.batch_encode_plus( + sequence_pair_batch_cleaned_up_spaces, add_special_tokens=False + ) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + output = tokenizer.batch_encode_plus( + token_sequence_pair_batch, is_split_into_words=True, add_special_tokens=True + ) + output_sequence = tokenizer.batch_encode_plus( + sequence_pair_batch_cleaned_up_spaces, add_special_tokens=True + ) + for key in output.keys(): + self.assertEqual(output[key], output_sequence[key]) + + def test_prepare_for_model(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + string_sequence = "Testing the prepare_for_model method." + ids = tokenizer.encode(string_sequence, add_special_tokens=False) + prepared_input_dict = tokenizer.prepare_for_model(ids, add_special_tokens=True) + + input_dict = tokenizer.encode_plus(string_sequence, add_special_tokens=True) + + self.assertEqual(input_dict, prepared_input_dict) + + def test_batch_encode_plus_overflowing_tokens(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + string_sequences = ["Testing the prepare_for_model method.", "Test"] + + if tokenizer.pad_token is None: + tokenizer.add_special_tokens({"pad_token": "[PAD]"}) + + tokenizer.batch_encode_plus( + string_sequences, return_overflowing_tokens=True, truncation=True, padding=True, max_length=3 + ) + + @is_pt_tf_cross_test + def test_batch_encode_plus_tensors(self): + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + sequences = [ + "Testing batch encode plus", + "Testing batch encode plus with different sequence lengths", + "Testing batch encode plus with different sequence lengths correctly pads", + ] + + # A Tensor cannot be build by sequences which are not the same size + self.assertRaises(ValueError, tokenizer.batch_encode_plus, sequences, return_tensors="pt") + self.assertRaises(ValueError, tokenizer.batch_encode_plus, sequences, return_tensors="tf") + + if tokenizer.pad_token_id is None: + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + sequences, + padding=True, + return_tensors="pt", + ) + self.assertRaises( + ValueError, + tokenizer.batch_encode_plus, + sequences, + padding="longest", + return_tensors="tf", + ) + else: + pytorch_tensor = tokenizer.batch_encode_plus(sequences, padding=True, return_tensors="pt") + tensorflow_tensor = tokenizer.batch_encode_plus(sequences, padding="longest", return_tensors="tf") + encoded_sequences = tokenizer.batch_encode_plus(sequences, padding=True) + + for key in encoded_sequences.keys(): + pytorch_value = pytorch_tensor[key].tolist() + tensorflow_value = tensorflow_tensor[key].numpy().tolist() + encoded_value = encoded_sequences[key] + + self.assertEqual(pytorch_value, tensorflow_value, encoded_value) + + def _check_no_pad_token_padding(self, tokenizer, sequences): + # if tokenizer does not have pad_token_id, an error should be thrown + if tokenizer.pad_token_id is None: + with self.assertRaises(ValueError): + if isinstance(sequences, list): + tokenizer.batch_encode_plus(sequences, padding="longest") + else: + tokenizer.encode_plus(sequences, padding=True) + + # add pad_token_id to pass subsequent tests + tokenizer.add_special_tokens({"pad_token": ""}) + + def check_subword_sampling( + self, + tokenizer: PreTrainedTokenizer, + text: str = None, + ) -> None: + """ + Check if the tokenizer generates different results when subword regularization is enabled. + + Subword regularization augments training data with subword sampling. + This has a random component. + + Args: + tokenizer: The tokenizer to check. + text: The text to use for the checks. + """ + text = "This is a test for subword regularization." if text is None else text + if self.test_sentencepiece_ignore_case: + text = text.lower() + + tokens_list = [] + for _ in range(5): + tokens_list.append(tokenizer.tokenize(text)) + + # the list of different pairs of tokens_list + combinations = itertools.combinations(tokens_list, 2) + + # check of sampling is done + subword_sampling_found = False + for combination in combinations: + if combination[0] != combination[1]: + subword_sampling_found = True + self.assertTrue(subword_sampling_found) + + # check if converting back to original text works + for tokens in tokens_list: + if self.test_sentencepiece_ignore_case: + self.assertEqual(text, tokenizer.convert_tokens_to_string(tokens).lower()) + else: + self.assertEqual(text, tokenizer.convert_tokens_to_string(tokens)) + + @require_torch + @slow + def test_torch_encode_plus_sent_to_model(self): + import torch + + from transformers import MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + is_using_common_embeddings = hasattr(model.get_input_embeddings(), "weight") + if is_using_common_embeddings: + self.assertGreaterEqual(model.get_input_embeddings().weight.shape[0], len(tokenizer)) + + # Build sequence + first_ten_tokens = list(tokenizer.get_vocab().keys())[:10] + sequence = " ".join(first_ten_tokens) + encoded_sequence = tokenizer.encode_plus(sequence, return_tensors="pt") + + # Ensure that the BatchEncoding.to() method works. + encoded_sequence.to(model.device) + + batch_encoded_sequence = tokenizer.batch_encode_plus([sequence, sequence], return_tensors="pt") + # This should not fail + + with torch.no_grad(): # saves some time + model(**encoded_sequence) + model(**batch_encoded_sequence) + + # if self.test_rust_tokenizer: + # fast_tokenizer = self.get_rust_tokenizer() + # encoded_sequence_fast = fast_tokenizer.encode_plus(sequence, return_tensors="pt") + # batch_encoded_sequence_fast = fast_tokenizer.batch_encode_plus([sequence, sequence], return_tensors="pt") + # # This should not fail + # model(**encoded_sequence_fast) + # model(**batch_encoded_sequence_fast) + + @require_tf + @slow + def test_tf_encode_plus_sent_to_model(self): + from transformers import TF_MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(TF_MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers(do_lower_case=False) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + model = model_class(config) + + # Make sure the model contains at least the full vocabulary size in its embedding matrix + self.assertGreaterEqual(model.config.vocab_size, len(tokenizer)) + + # Build sequence + first_ten_tokens = list(tokenizer.get_vocab().keys())[:10] + sequence = " ".join(first_ten_tokens) + encoded_sequence = tokenizer.encode_plus(sequence, return_tensors="tf") + batch_encoded_sequence = tokenizer.batch_encode_plus([sequence, sequence], return_tensors="tf") + + # This should not fail + model(encoded_sequence) + model(batch_encoded_sequence) + + # TODO: Check if require_torch is the best to test for numpy here ... Maybe move to require_flax when available + @require_torch + @slow + def test_np_encode_plus_sent_to_model(self): + from transformers import MODEL_MAPPING, TOKENIZER_MAPPING + + MODEL_TOKENIZER_MAPPING = merge_model_tokenizer_mappings(MODEL_MAPPING, TOKENIZER_MAPPING) + + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + if tokenizer.__class__ not in MODEL_TOKENIZER_MAPPING: + return + + config_class, model_class = MODEL_TOKENIZER_MAPPING[tokenizer.__class__] + config = config_class() + + if config.is_encoder_decoder or config.pad_token_id is None: + return + + # Build sequence + first_ten_tokens = list(tokenizer.get_vocab().keys())[:10] + sequence = " ".join(first_ten_tokens) + encoded_sequence = tokenizer.encode_plus(sequence, return_tensors="np") + batch_encoded_sequence = tokenizer.batch_encode_plus([sequence, sequence], return_tensors="np") + + # TODO: add forward through JAX/Flax when PR is merged + # This is currently here to make ruff happy ! + if encoded_sequence is None: + raise ValueError("Cannot convert list to numpy tensor on encode_plus()") + + if batch_encoded_sequence is None: + raise ValueError("Cannot convert list to numpy tensor on batch_encode_plus()") + + if self.test_rust_tokenizer: + fast_tokenizer = self.get_rust_tokenizer() + encoded_sequence_fast = fast_tokenizer.encode_plus(sequence, return_tensors="np") + batch_encoded_sequence_fast = fast_tokenizer.batch_encode_plus( + [sequence, sequence], return_tensors="np" + ) + + # TODO: add forward through JAX/Flax when PR is merged + # This is currently here to make ruff happy ! + if encoded_sequence_fast is None: + raise ValueError("Cannot convert list to numpy tensor on encode_plus() (fast)") + + if batch_encoded_sequence_fast is None: + raise ValueError("Cannot convert list to numpy tensor on batch_encode_plus() (fast)") + + @require_torch + def test_prepare_seq2seq_batch(self): + if not self.test_seq2seq: + return + + tokenizers = self.get_tokenizers() + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + # Longer text that will definitely require truncation. + src_text = [ + " UN Chief Says There Is No Military Solution in Syria", + " Secretary-General Ban Ki-moon says his response to Russia's stepped up military support for" + " Syria is that 'there is no military solution' to the nearly five-year conflict and more weapons" + " will only worsen the violence and misery for millions of people.", + ] + tgt_text = [ + "Şeful ONU declară că nu există o soluţie militară în Siria", + "Secretarul General Ban Ki-moon declară că răspunsul său la intensificarea sprijinului militar al" + ' Rusiei pentru Siria este că "nu există o soluţie militară" la conflictul de aproape cinci ani şi' + " că noi arme nu vor face decât să înrăutăţească violenţele şi mizeria pentru milioane de oameni.", + ] + try: + batch = tokenizer.prepare_seq2seq_batch( + src_texts=src_text, + tgt_texts=tgt_text, + max_length=3, + max_target_length=10, + return_tensors="pt", + src_lang="en_XX", # this should be ignored (for all but mbart) but not cause an error + ) + except NotImplementedError: + return + self.assertEqual(batch.input_ids.shape[1], 3) + self.assertEqual(batch.labels.shape[1], 10) + # max_target_length will default to max_length if not specified + batch = tokenizer.prepare_seq2seq_batch( + src_text, tgt_texts=tgt_text, max_length=3, return_tensors="pt" + ) + self.assertEqual(batch.input_ids.shape[1], 3) + self.assertEqual(batch.labels.shape[1], 3) + + batch_encoder_only = tokenizer.prepare_seq2seq_batch( + src_texts=src_text, max_length=3, max_target_length=10, return_tensors="pt" + ) + self.assertEqual(batch_encoder_only.input_ids.shape[1], 3) + self.assertEqual(batch_encoder_only.attention_mask.shape[1], 3) + self.assertNotIn("decoder_input_ids", batch_encoder_only) + + def test_is_fast(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + # Check is_fast is set correctly + self.assertTrue(tokenizer_r.is_fast) + + if self.test_slow_tokenizer: + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + self.assertFalse(tokenizer_p.is_fast) + + def test_fast_only_inputs(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Ensure None raise an error + self.assertRaises(TypeError, tokenizer_r.tokenize, None) + self.assertRaises(TypeError, tokenizer_r.encode, None) + self.assertRaises(TypeError, tokenizer_r.encode_plus, None) + self.assertRaises(TypeError, tokenizer_r.batch_encode_plus, None) + + def test_alignement_methods(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + words = ["Wonderful", "no", "inspiration", "example", "with", "subtoken"] + text = " ".join(words) + batch_size = 3 + + encoding = tokenizer_r.encode_plus(text, add_special_tokens=False) + + batch_encoding = tokenizer_r.batch_encode_plus([text] * batch_size, add_special_tokens=False) + num_tokens = len(encoding["input_ids"]) + + last_word_index = len(words) - 1 + last_token_index = num_tokens - 1 + last_batch_index = batch_size - 1 + last_char_index = len(text) - 1 + + # words, tokens + self.assertEqual(len(encoding.words(0)), num_tokens) + self.assertEqual(max(encoding.words(0)), last_word_index) + self.assertEqual(min(encoding.words(0)), 0) + self.assertEqual(len(batch_encoding.words(last_batch_index)), num_tokens) + self.assertEqual(max(batch_encoding.words(last_batch_index)), last_word_index) + self.assertEqual(min(batch_encoding.words(last_batch_index)), 0) + self.assertEqual(len(encoding.tokens(0)), num_tokens) + + # Assert token_to_word + self.assertEqual(encoding.token_to_word(0), 0) + self.assertEqual(encoding.token_to_word(0, 0), 0) + self.assertEqual(encoding.token_to_word(last_token_index), last_word_index) + self.assertEqual(encoding.token_to_word(0, last_token_index), last_word_index) + self.assertEqual(batch_encoding.token_to_word(1, 0), 0) + self.assertEqual(batch_encoding.token_to_word(0, last_token_index), last_word_index) + self.assertEqual(batch_encoding.token_to_word(last_batch_index, last_token_index), last_word_index) + + # Assert word_to_tokens + self.assertEqual(encoding.word_to_tokens(0).start, 0) + self.assertEqual(encoding.word_to_tokens(0, 0).start, 0) + self.assertEqual(encoding.word_to_tokens(last_word_index).end, last_token_index + 1) + self.assertEqual(encoding.word_to_tokens(0, last_word_index).end, last_token_index + 1) + self.assertEqual(batch_encoding.word_to_tokens(1, 0).start, 0) + self.assertEqual(batch_encoding.word_to_tokens(0, last_word_index).end, last_token_index + 1) + self.assertEqual( + batch_encoding.word_to_tokens(last_batch_index, last_word_index).end, last_token_index + 1 + ) + + # Assert token_to_chars + self.assertEqual(encoding.token_to_chars(0).start, 0) + self.assertEqual(encoding.token_to_chars(0, 0).start, 0) + self.assertEqual(encoding.token_to_chars(last_token_index).end, last_char_index + 1) + self.assertEqual(encoding.token_to_chars(0, last_token_index).end, last_char_index + 1) + self.assertEqual(batch_encoding.token_to_chars(1, 0).start, 0) + self.assertEqual(batch_encoding.token_to_chars(0, last_token_index).end, last_char_index + 1) + self.assertEqual( + batch_encoding.token_to_chars(last_batch_index, last_token_index).end, last_char_index + 1 + ) + + # Assert char_to_token + self.assertEqual(encoding.char_to_token(0), 0) + self.assertEqual(encoding.char_to_token(0, 0), 0) + self.assertEqual(encoding.char_to_token(last_char_index), last_token_index) + self.assertEqual(encoding.char_to_token(0, last_char_index), last_token_index) + self.assertEqual(batch_encoding.char_to_token(1, 0), 0) + self.assertEqual(batch_encoding.char_to_token(0, last_char_index), last_token_index) + self.assertEqual(batch_encoding.char_to_token(last_batch_index, last_char_index), last_token_index) + + # Assert char_to_word + self.assertEqual(encoding.char_to_word(0), 0) + self.assertEqual(encoding.char_to_word(0, 0), 0) + self.assertEqual(encoding.char_to_word(last_char_index), last_word_index) + self.assertEqual(encoding.char_to_word(0, last_char_index), last_word_index) + self.assertEqual(batch_encoding.char_to_word(1, 0), 0) + self.assertEqual(batch_encoding.char_to_word(0, last_char_index), last_word_index) + self.assertEqual(batch_encoding.char_to_word(last_batch_index, last_char_index), last_word_index) + + # Assert word_to_chars + self.assertEqual(encoding.word_to_chars(0).start, 0) + self.assertEqual(encoding.word_to_chars(0, 0).start, 0) + self.assertEqual(encoding.word_to_chars(last_word_index).end, last_char_index + 1) + self.assertEqual(encoding.word_to_chars(0, last_word_index).end, last_char_index + 1) + self.assertEqual(batch_encoding.word_to_chars(1, 0).start, 0) + self.assertEqual(batch_encoding.word_to_chars(0, last_word_index).end, last_char_index + 1) + self.assertEqual( + batch_encoding.word_to_chars(last_batch_index, last_word_index).end, last_char_index + 1 + ) + + # Assert token_to_sequence + self.assertEqual(encoding.token_to_sequence(num_tokens // 2), 0) + self.assertEqual(encoding.token_to_sequence(0, num_tokens // 2), 0) + self.assertEqual(batch_encoding.token_to_sequence(1, num_tokens // 2), 0) + self.assertEqual(batch_encoding.token_to_sequence(0, num_tokens // 2), 0) + self.assertEqual(batch_encoding.token_to_sequence(last_batch_index, num_tokens // 2), 0) + + # Pair of input sequences + + words = ["Wonderful", "no", "inspiration", "example", "with", "subtoken"] + text = " ".join(words) + pair_words = ["Amazing", "example", "full", "of", "inspiration"] + pair_text = " ".join(pair_words) + batch_size = 3 + index_word_in_first_seq = words.index("inspiration") + index_word_in_pair_seq = pair_words.index("inspiration") + index_char_in_first_seq = text.find("inspiration") + index_char_in_pair_seq = pair_text.find("inspiration") + + pair_encoding = tokenizer_r.encode_plus(text, pair_text, add_special_tokens=False) + + pair_batch_encoding = tokenizer_r.batch_encode_plus( + [(text, pair_text)] * batch_size, add_special_tokens=False + ) + num_tokens = len(encoding["input_ids"]) + + last_word_index = len(words) - 1 + last_token_index = num_tokens - 1 + last_batch_index = batch_size - 1 + last_char_index = len(text) - 1 + + # Assert word_to_tokens + self.assertNotEqual( + pair_encoding.word_to_tokens(index_word_in_first_seq, sequence_index=0).start, + pair_encoding.word_to_tokens(index_word_in_pair_seq, sequence_index=1).start, + ) + self.assertEqual( + pair_encoding["input_ids"][ + pair_encoding.word_to_tokens(index_word_in_first_seq, sequence_index=0).start + ], + pair_encoding["input_ids"][ + pair_encoding.word_to_tokens(index_word_in_pair_seq, sequence_index=1).start + ], + ) + self.assertNotEqual( + pair_batch_encoding.word_to_tokens(1, index_word_in_first_seq, sequence_index=0).start, + pair_batch_encoding.word_to_tokens(1, index_word_in_pair_seq, sequence_index=1).start, + ) + self.assertEqual( + pair_batch_encoding["input_ids"][1][ + pair_batch_encoding.word_to_tokens(1, index_word_in_first_seq, sequence_index=0).start + ], + pair_batch_encoding["input_ids"][1][ + pair_batch_encoding.word_to_tokens(1, index_word_in_pair_seq, sequence_index=1).start + ], + ) + + # Assert char_to_token + self.assertNotEqual( + pair_encoding.char_to_token(index_char_in_first_seq, sequence_index=0), + pair_encoding.char_to_token(index_char_in_pair_seq, sequence_index=1), + ) + self.assertEqual( + pair_encoding["input_ids"][pair_encoding.char_to_token(index_char_in_first_seq, sequence_index=0)], + pair_encoding["input_ids"][pair_encoding.char_to_token(index_char_in_pair_seq, sequence_index=1)], + ) + self.assertNotEqual( + pair_batch_encoding.char_to_token(1, index_char_in_first_seq, sequence_index=0), + pair_batch_encoding.char_to_token(1, index_char_in_pair_seq, sequence_index=1), + ) + self.assertEqual( + pair_batch_encoding["input_ids"][1][ + pair_batch_encoding.char_to_token(1, index_char_in_first_seq, sequence_index=0) + ], + pair_batch_encoding["input_ids"][1][ + pair_batch_encoding.char_to_token(1, index_char_in_pair_seq, sequence_index=1) + ], + ) + + # Assert char_to_word + self.assertNotEqual( + pair_encoding.char_to_word(index_char_in_first_seq, sequence_index=0), + pair_encoding.char_to_word(index_char_in_pair_seq, sequence_index=1), + ) + self.assertEqual( + words[pair_encoding.char_to_word(index_char_in_first_seq, sequence_index=0)], + pair_words[pair_encoding.char_to_word(index_char_in_pair_seq, sequence_index=1)], + ) + self.assertNotEqual( + pair_batch_encoding.char_to_word(1, index_char_in_first_seq, sequence_index=0), + pair_batch_encoding.char_to_word(1, index_char_in_pair_seq, sequence_index=1), + ) + self.assertEqual( + words[pair_batch_encoding.char_to_word(1, index_char_in_first_seq, sequence_index=0)], + pair_words[pair_batch_encoding.char_to_word(1, index_char_in_pair_seq, sequence_index=1)], + ) + + # Assert word_to_chars + self.assertNotEqual( + pair_encoding.word_to_chars(index_word_in_first_seq, sequence_index=0).start, + pair_encoding.word_to_chars(index_word_in_pair_seq, sequence_index=1).start, + ) + self.assertEqual( + text[pair_encoding.word_to_chars(index_word_in_first_seq, sequence_index=0).start], + pair_text[pair_encoding.word_to_chars(index_word_in_pair_seq, sequence_index=1).start], + ) + self.assertNotEqual( + pair_batch_encoding.word_to_chars(1, index_word_in_first_seq, sequence_index=0).start, + pair_batch_encoding.word_to_chars(1, index_word_in_pair_seq, sequence_index=1).start, + ) + self.assertEqual( + text[pair_batch_encoding.word_to_chars(1, index_word_in_first_seq, sequence_index=0).start], + pair_text[pair_batch_encoding.word_to_chars(1, index_word_in_pair_seq, sequence_index=1).start], + ) + + # Assert token_to_sequence + pair_encoding = tokenizer_r.encode_plus(text, pair_text, add_special_tokens=True) + + pair_sequence_ids = [ + pair_encoding.token_to_sequence(i) for i in range(len(pair_encoding["input_ids"])) + ] + self.assertIn(0, pair_sequence_ids) + self.assertIn(1, pair_sequence_ids) + if tokenizer_r.num_special_tokens_to_add(pair=True): + self.assertIn(None, pair_sequence_ids) + + pair_batch_encoding = tokenizer_r.batch_encode_plus( + [(text, pair_text)] * batch_size, add_special_tokens=True + ) + pair_batch_sequence_ids = [ + pair_batch_encoding.token_to_sequence(1, i) + for i in range(len(pair_batch_encoding["input_ids"][0])) + ] + self.assertIn(0, pair_batch_sequence_ids) + self.assertIn(1, pair_batch_sequence_ids) + if tokenizer_r.num_special_tokens_to_add(pair=True): + self.assertIn(None, pair_batch_sequence_ids) + + def test_tokenization_python_rust_equals(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Ensure basic input match + input_p = tokenizer_p.encode_plus(self._data) + input_r = tokenizer_r.encode_plus(self._data) + + for key in filter(lambda x: x in ["input_ids", "token_type_ids", "attention_mask"], input_p.keys()): + self.assertSequenceEqual(input_p[key], input_r[key]) + + input_pairs_p = tokenizer_p.encode_plus(self._data, self._data) + input_pairs_r = tokenizer_r.encode_plus(self._data, self._data) + + for key in filter(lambda x: x in ["input_ids", "token_type_ids", "attention_mask"], input_p.keys()): + self.assertSequenceEqual(input_pairs_p[key], input_pairs_r[key]) + + # Ensure truncation match + input_p = tokenizer_p.encode_plus(self._data, max_length=512, truncation=True) + input_r = tokenizer_r.encode_plus(self._data, max_length=512, truncation=True) + + for key in filter(lambda x: x in ["input_ids", "token_type_ids", "attention_mask"], input_p.keys()): + self.assertSequenceEqual(input_p[key], input_r[key]) + + # Ensure truncation with stride match + input_p = tokenizer_p.encode_plus( + self._data, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + input_r = tokenizer_r.encode_plus( + self._data, max_length=512, truncation=True, stride=3, return_overflowing_tokens=True + ) + + for key in filter(lambda x: x in ["input_ids", "token_type_ids", "attention_mask"], input_p.keys()): + self.assertSequenceEqual(input_p[key], input_r[key][0]) + + def test_num_special_tokens_to_add_equal(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Check we have the same number of added_tokens for both pair and non-pair inputs. + self.assertEqual( + tokenizer_r.num_special_tokens_to_add(False), tokenizer_p.num_special_tokens_to_add(False) + ) + self.assertEqual( + tokenizer_r.num_special_tokens_to_add(True), tokenizer_p.num_special_tokens_to_add(True) + ) + + def test_max_length_equal(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Check we have the correct max_length for both pair and non-pair inputs. + self.assertEqual(tokenizer_r.max_len_single_sentence, tokenizer_p.max_len_single_sentence) + self.assertEqual(tokenizer_r.max_len_sentences_pair, tokenizer_p.max_len_sentences_pair) + + def test_special_tokens_map_equal(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + # Assert the set of special tokens match. + self.assertSequenceEqual( + tokenizer_p.special_tokens_map.items(), + tokenizer_r.special_tokens_map.items(), + ) + + def test_add_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + vocab_size = len(tokenizer_r) + self.assertEqual(tokenizer_r.add_tokens(""), 0) + self.assertEqual(tokenizer_r.add_tokens("testoken"), 1) + self.assertEqual(tokenizer_r.add_tokens(["testoken1", "testtoken2"]), 2) + self.assertEqual(len(tokenizer_r), vocab_size + 3) + + self.assertEqual(tokenizer_r.add_special_tokens({}), 0) + self.assertEqual(tokenizer_r.add_special_tokens({"bos_token": "[BOS]", "eos_token": "[EOS]"}), 2) + self.assertRaises( + AssertionError, tokenizer_r.add_special_tokens, {"additional_special_tokens": ""} + ) + self.assertEqual(tokenizer_r.add_special_tokens({"additional_special_tokens": [""]}), 1) + self.assertEqual( + tokenizer_r.add_special_tokens({"additional_special_tokens": ["", ""]}), 2 + ) + self.assertIn("", tokenizer_r.special_tokens_map["additional_special_tokens"]) + self.assertIsInstance(tokenizer_r.special_tokens_map["additional_special_tokens"], list) + self.assertGreaterEqual(len(tokenizer_r.special_tokens_map["additional_special_tokens"]), 2) + + self.assertEqual(len(tokenizer_r), vocab_size + 8) + + def test_offsets_mapping(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + text = "Wonderful no inspiration example with subtoken" + pair = "Along with an awesome pair" + + # No pair + tokens_with_offsets = tokenizer_r.encode_plus( + text, return_special_tokens_mask=True, return_offsets_mapping=True, add_special_tokens=True + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(False) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + # Pairs + tokens_with_offsets = tokenizer_r.encode_plus( + text, pair, return_special_tokens_mask=True, return_offsets_mapping=True, add_special_tokens=True + ) + added_tokens = tokenizer_r.num_special_tokens_to_add(True) + offsets = tokens_with_offsets["offset_mapping"] + + # Assert there is the same number of tokens and offsets + self.assertEqual(len(offsets), len(tokens_with_offsets["input_ids"])) + + # Assert there is online added_tokens special_tokens + self.assertEqual(sum(tokens_with_offsets["special_tokens_mask"]), added_tokens) + + def test_batch_encode_dynamic_overflowing(self): + """ + When calling batch_encode with multiple sequence it can returns different number of + overflowing encoding for each sequence: + [ + Sequence 1: [Encoding 1, Encoding 2], + Sequence 2: [Encoding 1], + Sequence 3: [Encoding 1, Encoding 2, ... Encoding N] + ] + This needs to be padded so that it can represented as a tensor + """ + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + tokenizer = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name}, {tokenizer.__class__.__name__})"): + if is_torch_available(): + returned_tensor = "pt" + elif is_tf_available(): + returned_tensor = "tf" + elif is_flax_available(): + returned_tensor = "jax" + else: + return + + if not tokenizer.pad_token or tokenizer.pad_token_id < 0: + return + + tokens = tokenizer.encode_plus( + "HuggingFace is solving NLP one commit at a time", + max_length=6, + padding=True, + truncation=True, + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + self.assertEqual(len(tokens[key].shape), 2) + + # Mono sample + tokens = tokenizer.batch_encode_plus( + ["HuggingFace is solving NLP one commit at a time"], + max_length=6, + padding=True, + truncation="only_first", + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + self.assertEqual(len(tokens[key].shape), 2) + self.assertEqual(tokens[key].shape[-1], 6) + + # Multi sample + tokens = tokenizer.batch_encode_plus( + ["HuggingFace is solving NLP one commit at a time", "Very tiny input"], + max_length=6, + padding=True, + truncation="only_first", + return_tensors=returned_tensor, + return_overflowing_tokens=True, + ) + + for key in filter(lambda x: "overflow_to_sample_mapping" not in x, tokens.keys()): + self.assertEqual(len(tokens[key].shape), 2) + self.assertEqual(tokens[key].shape[-1], 6) + + def test_compare_pretokenized_inputs(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + if hasattr(tokenizer_p, "add_prefix_space") and not tokenizer_p.add_prefix_space: + continue # Too hard to test for now + + # Input string + pretokenized_input_simple = "This is a sample input".split() + pretokenized_input_pair = "This is a sample pair".split() + + # Test encode for pretokenized inputs + output_r = tokenizer_r.encode( + pretokenized_input_simple, is_split_into_words=True, add_special_tokens=False + ) + output_p = tokenizer_p.encode( + pretokenized_input_simple, is_split_into_words=True, add_special_tokens=False + ) + self.assertEqual(output_p, output_r) + + kwargs = { + "is_split_into_words": True, + # "return_token_type_ids": True, # Use the defaults for each tokenizers + # "return_attention_mask": True, # Use the defaults for each tokenizers + "return_overflowing_tokens": False, + "return_special_tokens_mask": True, + "return_offsets_mapping": False, # Not implemented in python tokenizers + # "add_special_tokens": False, + } + batch_kwargs = { + "is_split_into_words": True, + # "return_token_type_ids": True, # Use the defaults for each tokenizers + # "return_attention_mask": True, # Use the defaults for each tokenizers + "return_overflowing_tokens": False, + "return_special_tokens_mask": True, + "return_offsets_mapping": False, # Not implemented in python tokenizers + # "add_special_tokens": False, + } + # Test encode_plus for pretokenized inputs + output_r = tokenizer_r.encode_plus(pretokenized_input_simple, **kwargs) + output_p = tokenizer_p.encode_plus(pretokenized_input_simple, **kwargs) + for key in output_p.keys(): + self.assertEqual(output_p[key], output_r[key]) + + # Test batch_encode_plus for pretokenized inputs + input_batch = ([pretokenized_input_simple] * 2) + [pretokenized_input_simple + pretokenized_input_pair] + output_r = tokenizer_r.batch_encode_plus(input_batch, **batch_kwargs) + output_p = tokenizer_p.batch_encode_plus(input_batch, **batch_kwargs) + for key in output_p.keys(): + self.assertEqual(output_p[key], output_r[key]) + + # Test encode for pretokenized inputs pairs + output_r = tokenizer_r.encode( + pretokenized_input_simple, pretokenized_input_pair, is_split_into_words=True + ) + output_p = tokenizer_p.encode( + pretokenized_input_simple, pretokenized_input_pair, is_split_into_words=True + ) + self.assertEqual(output_p, output_r) + + # Test encode_plus for pretokenized inputs + output_r = tokenizer_r.encode_plus(pretokenized_input_simple, pretokenized_input_pair, **kwargs) + output_p = tokenizer_p.encode_plus(pretokenized_input_simple, pretokenized_input_pair, **kwargs) + for key in output_p.keys(): + self.assertEqual(output_p[key], output_r[key]) + + # Test batch_encode_plus for pretokenized inputs + input_batch_pair = ([pretokenized_input_simple, pretokenized_input_pair] * 2) + [ + pretokenized_input_simple + pretokenized_input_pair, + pretokenized_input_pair, + ] + output_r = tokenizer_r.batch_encode_plus(input_batch_pair, **batch_kwargs) + output_p = tokenizer_p.batch_encode_plus(input_batch_pair, **batch_kwargs) + for key in output_p.keys(): + self.assertEqual(output_p[key], output_r[key]) + + def test_create_token_type_ids(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + input_simple = [1, 2, 3] + input_pair = [1, 2, 3] + + # Generate output + output_r = tokenizer_r.create_token_type_ids_from_sequences(input_simple) + output_p = tokenizer_p.create_token_type_ids_from_sequences(input_simple) + self.assertEqual(output_p, output_r) + + # Generate pair output + output_r = tokenizer_r.create_token_type_ids_from_sequences(input_simple, input_pair) + output_p = tokenizer_p.create_token_type_ids_from_sequences(input_simple, input_pair) + self.assertEqual(output_p, output_r) + + def test_build_inputs_with_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + # # Input string + # input_simple = tokenizer_p.tokenize("This is a sample input", add_special_tokens=False) + # input_pair = tokenizer_p.tokenize("This is a sample pair", add_special_tokens=False) + + # # Generate output + # output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple) + # output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple) + # self.assertEqual(output_p, output_r) + + # # Generate pair output + # output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple, input_pair) + # output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple, input_pair) + # self.assertEqual(output_p, output_r) + + # Input tokens id + input_simple = tokenizer_p.encode("This is a sample input", add_special_tokens=False) + input_pair = tokenizer_p.encode("This is a sample pair", add_special_tokens=False) + + # Generate output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple) + self.assertEqual(output_p, output_r) + + # Generate pair output + output_r = tokenizer_r.build_inputs_with_special_tokens(input_simple, input_pair) + output_p = tokenizer_p.build_inputs_with_special_tokens(input_simple, input_pair) + self.assertEqual(output_p, output_r) + + def test_padding(self, max_length=50): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + # Encode - Simple input + input_r = tokenizer_r.encode("This is a simple input", max_length=max_length, pad_to_max_length=True) + input_p = tokenizer_p.encode("This is a simple input", max_length=max_length, pad_to_max_length=True) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode("This is a simple input", max_length=max_length, padding="max_length") + input_p = tokenizer_p.encode("This is a simple input", max_length=max_length, padding="max_length") + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.encode("This is a simple input", padding="longest") + input_p = tokenizer_p.encode("This is a simple input", padding=True) + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode - Pair input + input_r = tokenizer_r.encode( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r, input_p, max_length, pad_token_id) + input_r = tokenizer_r.encode("This is a simple input", "This is a pair", padding=True) + input_p = tokenizer_p.encode("This is a simple input", "This is a pair", padding="longest") + self.assert_padded_input_match(input_r, input_p, len(input_r), pad_token_id) + + # Encode_plus - Simple input + input_r = tokenizer_r.encode_plus( + "This is a simple input", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus( + "This is a simple input", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + input_r = tokenizer_r.encode_plus("This is a simple input", padding="longest") + input_p = tokenizer_p.encode_plus("This is a simple input", padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Encode_plus - Pair input + input_r = tokenizer_r.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, pad_to_max_length=True + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + input_p = tokenizer_p.encode_plus( + "This is a simple input", "This is a pair", max_length=max_length, padding="max_length" + ) + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + input_r = tokenizer_r.encode_plus("This is a simple input", "This is a pair", padding="longest") + input_p = tokenizer_p.encode_plus("This is a simple input", "This is a pair", padding=True) + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + self.assertSequenceEqual(input_r["attention_mask"], input_p["attention_mask"]) + + # Batch_encode_plus - Simple input + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + pad_to_max_length=True, + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + pad_to_max_length=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding="longest", + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], + max_length=max_length, + padding=True, + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], padding="longest" + ) + input_p = tokenizer_p.batch_encode_plus( + ["This is a simple input 1", "This is a simple input 2"], padding=True + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Batch_encode_plus - Pair input + input_r = tokenizer_r.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + max_length=max_length, + truncation=True, + padding="max_length", + ) + input_p = tokenizer_p.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + max_length=max_length, + truncation=True, + padding="max_length", + ) + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + input_r = tokenizer_r.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + padding=True, + ) + input_p = tokenizer_p.batch_encode_plus( + [ + ("This is a simple input 1", "This is a simple input 2"), + ("This is a simple pair 1", "This is a simple pair 2"), + ], + padding="longest", + ) + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus("This is a input 1") + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_p.encode_plus("This is a input 1") + input_p = tokenizer_p.pad(input_p) + + self.assert_padded_input_match( + input_r["input_ids"], input_p["input_ids"], len(input_r["input_ids"]), pad_token_id + ) + + # Using pad on single examples after tokenization + input_r = tokenizer_r.encode_plus("This is a input 1") + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_p.encode_plus("This is a input 1") + input_p = tokenizer_p.pad(input_p, max_length=max_length, padding="max_length") + + self.assert_padded_input_match(input_r["input_ids"], input_p["input_ids"], max_length, pad_token_id) + + # Using pad after tokenization + input_r = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_r = tokenizer_r.pad(input_r) + + input_p = tokenizer_p.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_p = tokenizer_p.pad(input_p) + + self.assert_batch_padded_input_match(input_r, input_p, len(input_r["input_ids"][0]), pad_token_id) + + # Using pad after tokenization + input_r = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_r = tokenizer_r.pad(input_r, max_length=max_length, padding="max_length") + + input_p = tokenizer_p.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_p = tokenizer_p.pad(input_p, max_length=max_length, padding="max_length") + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + # Test padding nested empty lists (in some use-cases, there is no any token id in the `input_ids` list). + input_r = tokenizer_r.pad({"input_ids": [[], []]}, max_length=max_length, padding="max_length") + input_p = tokenizer_p.pad({"input_ids": [[], []]}, max_length=max_length, padding="max_length") + self.assert_batch_padded_input_match(input_r, input_p, max_length, pad_token_id) + + def test_padding_different_model_input_name(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + self.assertEqual(tokenizer_p.pad_token_id, tokenizer_r.pad_token_id) + pad_token_id = tokenizer_p.pad_token_id + + input_r = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + input_p = tokenizer_r.batch_encode_plus( + ["This is a input 1", "This is a much longer input whilch should be padded"] + ) + + # rename encoded batch to "inputs" + input_r["inputs"] = input_r[tokenizer_r.model_input_names[0]] + del input_r[tokenizer_r.model_input_names[0]] + + input_p["inputs"] = input_p[tokenizer_p.model_input_names[0]] + del input_p[tokenizer_p.model_input_names[0]] + + # Renaming `input_ids` to `inputs` + tokenizer_r.model_input_names = ["inputs"] + tokenizer_r.model_input_names[1:] + tokenizer_p.model_input_names = ["inputs"] + tokenizer_p.model_input_names[1:] + + input_r = tokenizer_r.pad(input_r, padding="longest") + input_p = tokenizer_r.pad(input_p, padding="longest") + + max_length = len(input_p["inputs"][0]) + self.assert_batch_padded_input_match( + input_r, input_p, max_length, pad_token_id, model_main_input_name="inputs" + ) + + def test_save_pretrained(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # make sure that all ".json" files are saved in the correct format + for file_path in tokenizer_r_files + tokenizer_p_files: + if os.path.exists(file_path) and file_path.endswith(".json"): + check_json_file_has_correct_format(file_path) + + # Checks it save with the same files + the tokenizer.json file for the fast one + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + tokenizer_r_files = tuple(f for f in tokenizer_r_files if "tokenizer.json" not in f) + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + # self.assertEqual(getattr(tokenizer_rp, key), getattr(tokenizer_pp, key)) + # self.assertEqual(getattr(tokenizer_rp, key + "_id"), getattr(tokenizer_pp, key + "_id")) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=True + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=True) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it save with the same files + self.assertSequenceEqual(tokenizer_r_files, tokenizer_p_files) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + # Save tokenizer rust, legacy_format=False + tmpdirname2 = tempfile.mkdtemp() + + tokenizer_r_files = tokenizer_r.save_pretrained(tmpdirname2, legacy_format=False) + tokenizer_p_files = tokenizer_p.save_pretrained(tmpdirname2) + + # Checks it saved the tokenizer.json file + self.assertTrue(any("tokenizer.json" in f for f in tokenizer_r_files)) + + # Checks everything loads correctly in the same way + tokenizer_rp = tokenizer_r.from_pretrained(tmpdirname2) + tokenizer_pp = tokenizer_p.from_pretrained(tmpdirname2) + + # Check special tokens are set accordingly on Rust and Python + for key in tokenizer_pp.special_tokens_map: + self.assertTrue(hasattr(tokenizer_rp, key)) + + shutil.rmtree(tmpdirname2) + + def test_embeded_special_tokens(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + sentence = "A, AllenNLP sentence." + tokens_r = tokenizer_r.encode_plus( + sentence, + add_special_tokens=True, + ) + tokens_p = tokenizer_p.encode_plus( + sentence, + add_special_tokens=True, + ) + + for key in tokens_p.keys(): + self.assertEqual(tokens_r[key], tokens_p[key]) + + if "token_type_ids" in tokens_r: + self.assertEqual(sum(tokens_r["token_type_ids"]), sum(tokens_p["token_type_ids"])) + + tokens_r = tokenizer_r.convert_ids_to_tokens(tokens_r["input_ids"]) + tokens_p = tokenizer_p.convert_ids_to_tokens(tokens_p["input_ids"]) + self.assertSequenceEqual(tokens_r, tokens_p) + + def test_compare_add_special_tokens(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + + simple_num_special_tokens_to_add = tokenizer_r.num_special_tokens_to_add(pair=False) + # pair_num_special_tokens_to_add = tokenizer_r.num_special_tokens_to_add(pair=True) + + for text in ["", " "]: + # tokenize() + no_special_tokens = tokenizer_r.tokenize(text, add_special_tokens=False) + with_special_tokens = tokenizer_r.tokenize(text, add_special_tokens=True) + self.assertEqual( + len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add + ) + + # encode() + no_special_tokens = tokenizer_r.encode(text, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode(text, add_special_tokens=True) + self.assertEqual( + len(no_special_tokens), len(with_special_tokens) - simple_num_special_tokens_to_add + ) + + # encode_plus() + no_special_tokens = tokenizer_r.encode_plus(text, add_special_tokens=False) + with_special_tokens = tokenizer_r.encode_plus(text, add_special_tokens=True) + for key in no_special_tokens.keys(): + self.assertEqual( + len(no_special_tokens[key]), + len(with_special_tokens[key]) - simple_num_special_tokens_to_add, + ) + + # # batch_encode_plus + no_special_tokens = tokenizer_r.batch_encode_plus([text, text], add_special_tokens=False) + with_special_tokens = tokenizer_r.batch_encode_plus([text, text], add_special_tokens=True) + for key in no_special_tokens.keys(): + for i_no, i_with in zip(no_special_tokens[key], with_special_tokens[key]): + self.assertEqual(len(i_no), len(i_with) - simple_num_special_tokens_to_add) + + def test_compare_prepare_for_model(self): + if not self.test_slow_tokenizer: + # as we don't have a slow version, we can't compare the outputs between slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + tokenizer_r = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs) + tokenizer_p = self.tokenizer_class.from_pretrained(pretrained_name, **kwargs) + string_sequence = "Asserting that both tokenizers are equal" + python_output = tokenizer_p.prepare_for_model( + tokenizer_p.encode(string_sequence, add_special_tokens=False) + ) + rust_output = tokenizer_r.prepare_for_model( + tokenizer_r.encode(string_sequence, add_special_tokens=False) + ) + for key in python_output: + self.assertEqual(python_output[key], rust_output[key]) + + def test_special_tokens_initialization(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + added_tokens = [AddedToken("", lstrip=True)] + + tokenizer_r = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + r_output = tokenizer_r.encode("Hey this is a token") + + special_token_id = tokenizer_r.encode("", add_special_tokens=False)[0] + + self.assertTrue(special_token_id in r_output) + + if self.test_slow_tokenizer: + tokenizer_cr = self.rust_tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs, from_slow=True + ) + tokenizer_p = self.tokenizer_class.from_pretrained( + pretrained_name, additional_special_tokens=added_tokens, **kwargs + ) + + p_output = tokenizer_p.encode("Hey this is a token") + + cr_output = tokenizer_cr.encode("Hey this is a token") + + self.assertEqual(p_output, r_output) + self.assertEqual(cr_output, r_output) + self.assertTrue(special_token_id in p_output) + self.assertTrue(special_token_id in cr_output) + + def test_special_tokens_initialization_with_non_empty_additional_special_tokens(self): + tokenizer_list = [] + if self.test_slow_tokenizer: + tokenizer_list.append((self.tokenizer_class, self.get_tokenizer())) + + if self.test_rust_tokenizer: + tokenizer_list.append((self.rust_tokenizer_class, self.get_rust_tokenizer())) + + for tokenizer_class, tokenizer_utils in tokenizer_list: + with tempfile.TemporaryDirectory() as tmp_dir: + tokenizer_utils.save_pretrained(tmp_dir) + + with open(os.path.join(tmp_dir, "special_tokens_map.json"), encoding="utf-8") as json_file: + special_tokens_map = json.load(json_file) + + with open(os.path.join(tmp_dir, "tokenizer_config.json"), encoding="utf-8") as json_file: + tokenizer_config = json.load(json_file) + + special_tokens_map["additional_special_tokens"] = ["an_additional_special_token"] + tokenizer_config["additional_special_tokens"] = ["an_additional_special_token"] + + with open(os.path.join(tmp_dir, "special_tokens_map.json"), "w", encoding="utf-8") as outfile: + json.dump(special_tokens_map, outfile) + with open(os.path.join(tmp_dir, "tokenizer_config.json"), "w", encoding="utf-8") as outfile: + json.dump(tokenizer_config, outfile) + + # the following checks allow us to verify that our test works as expected, i.e. that the tokenizer takes + # into account the new value of additional_special_tokens given in the "tokenizer_config.json" and + # "special_tokens_map.json" files + tokenizer_without_change_in_init = tokenizer_class.from_pretrained( + tmp_dir, + ) + self.assertIn( + "an_additional_special_token", tokenizer_without_change_in_init.additional_special_tokens + ) + self.assertIn("an_additional_special_token", tokenizer_without_change_in_init.get_vocab()) + self.assertEqual( + ["an_additional_special_token"], + tokenizer_without_change_in_init.convert_ids_to_tokens( + tokenizer_without_change_in_init.convert_tokens_to_ids(["an_additional_special_token"]) + ), + ) + + # Now we test that we can change the value of additional_special_tokens in the from_pretrained + new_added_tokens = [AddedToken("a_new_additional_special_token", lstrip=True)] + tokenizer = tokenizer_class.from_pretrained( + tmp_dir, + additional_special_tokens=new_added_tokens, + ) + + self.assertIn("a_new_additional_special_token", tokenizer.additional_special_tokens) + self.assertEqual( + ["a_new_additional_special_token"], + tokenizer.convert_ids_to_tokens( + tokenizer.convert_tokens_to_ids(["a_new_additional_special_token"]) + ), + ) + + def test_training_new_tokenizer(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + new_tokenizer = tokenizer.train_new_from_iterator(SMALL_TRAINING_CORPUS, 100) + + # Test we can use the new tokenizer with something not seen during training + inputs = new_tokenizer(["This is the first sentence", "This sentence is different 🤗."]) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "This is the first sentence" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + # We check that the parameters of the tokenizer remained the same + # Check we have the same number of added_tokens for both pair and non-pair inputs. + self.assertEqual(tokenizer.num_special_tokens_to_add(False), new_tokenizer.num_special_tokens_to_add(False)) + self.assertEqual(tokenizer.num_special_tokens_to_add(True), new_tokenizer.num_special_tokens_to_add(True)) + + # Check we have the correct max_length for both pair and non-pair inputs. + self.assertEqual(tokenizer.max_len_single_sentence, new_tokenizer.max_len_single_sentence) + self.assertEqual(tokenizer.max_len_sentences_pair, new_tokenizer.max_len_sentences_pair) + + # Assert the set of special tokens match as we didn't ask to change them + self.assertSequenceEqual( + tokenizer.all_special_tokens_extended, + new_tokenizer.all_special_tokens_extended, + ) + + self.assertDictEqual(tokenizer.special_tokens_map, new_tokenizer.special_tokens_map) + + def test_training_new_tokenizer_with_special_tokens_change(self): + # This feature only exists for fast tokenizers + if not self.test_rust_tokenizer: + return + + tokenizer = self.get_rust_tokenizer() + # Test with a special tokens map + class_signature = inspect.signature(tokenizer.__class__) + if "cls_token" in class_signature.parameters: + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map={tokenizer.cls_token: ""} + ) + cls_id = new_tokenizer.get_vocab()[""] + self.assertEqual(new_tokenizer.cls_token, "") + self.assertEqual(new_tokenizer.cls_token_id, cls_id) + + # Create a new mapping from the special tokens defined in the original tokenizer + special_tokens_list = SpecialTokensMixin.SPECIAL_TOKENS_ATTRIBUTES.copy() + special_tokens_list.remove("additional_special_tokens") + special_tokens_map = {} + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is not None: + special_token = getattr(tokenizer, token) + special_tokens_map[special_token] = f"{special_token}a" + + # Train new tokenizer + new_tokenizer = tokenizer.train_new_from_iterator( + SMALL_TRAINING_CORPUS, 100, special_tokens_map=special_tokens_map + ) + + # Check the changes + for token in special_tokens_list: + # Get the private one to avoid unnecessary warnings. + if getattr(tokenizer, f"_{token}") is None: + continue + special_token = getattr(tokenizer, token) + if special_token in special_tokens_map: + new_special_token = getattr(new_tokenizer, token) + self.assertEqual(special_tokens_map[special_token], new_special_token) + + new_id = new_tokenizer.get_vocab()[new_special_token] + self.assertEqual(getattr(new_tokenizer, f"{token}_id"), new_id) + + # Check if the AddedToken / string format has been kept + for special_token in tokenizer.all_special_tokens_extended: + if isinstance(special_token, AddedToken) and special_token.content not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + elif isinstance(special_token, AddedToken): + # The special token must appear in the list of the new tokenizer as an object of type AddedToken with + # the same parameters as the old AddedToken except the content that the user has requested to change. + special_token_str = special_token.content + new_special_token_str = special_tokens_map[special_token_str] + + find = False + for candidate in new_tokenizer.all_special_tokens_extended: + if ( + isinstance(candidate, AddedToken) + and candidate.content == new_special_token_str + and candidate.lstrip == special_token.lstrip + and candidate.rstrip == special_token.rstrip + and candidate.normalized == special_token.normalized + and candidate.single_word == special_token.single_word + ): + find = True + break + self.assertTrue( + find, + f"'{new_special_token_str}' doesn't appear in the list " + f"'{new_tokenizer.all_special_tokens_extended}' as an AddedToken with the same parameters as " + f"'{special_token}' in the list {tokenizer.all_special_tokens_extended}", + ) + elif special_token not in special_tokens_map: + # The special token must appear identically in the list of the new tokenizer. + self.assertTrue( + special_token in new_tokenizer.all_special_tokens_extended, + f"'{special_token}' should be in {new_tokenizer.all_special_tokens_extended}", + ) + + else: + # The special token must appear in the list of the new tokenizer as an object of type string. + self.assertTrue(special_tokens_map[special_token] in new_tokenizer.all_special_tokens_extended) + + # Test we can use the new tokenizer with something not seen during training + inputs = new_tokenizer(["This is the first sentence", "This sentence is different 🤗."]) + self.assertEqual(len(inputs["input_ids"]), 2) + decoded_input = new_tokenizer.decode(inputs["input_ids"][0], skip_special_tokens=True) + expected_result = "This is the first sentence" + + if tokenizer.backend_tokenizer.normalizer is not None: + expected_result = tokenizer.backend_tokenizer.normalizer.normalize_str(expected_result) + self.assertEqual(expected_result, decoded_input) + + def test_tokenizer_mismatch_warning(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + with self.assertLogs("transformers", level="WARNING") as cm: + try: + if self.tokenizer_class == BertTokenizer: + AlbertTokenizer.from_pretrained(pretrained_name) + else: + BertTokenizer.from_pretrained(pretrained_name) + except EnvironmentError as e: + # Some tokenizer will raised an error before reaching the logged warning because there are no + # corresponding files to load + error_message = str(e) + except (TypeError, AttributeError): + # Some tokenizers cannot be loaded into the target tokenizer at all and errors are returned, + # here we just check that the warning has been logged before the error is raised + pass + finally: + logged_msg_target = ( + "The tokenizer class you load from this checkpoint is not the same type as the class " + "this function is called from." + ) + raised_error_msg_target = "Can't load tokenizer for" + self.assertTrue( + cm.records[0].message.startswith(logged_msg_target) + if len(cm.records) > 0 + else False or raised_error_msg_target in error_message + ) + try: + if self.rust_tokenizer_class == BertTokenizerFast: + AlbertTokenizerFast.from_pretrained(pretrained_name) + else: + BertTokenizerFast.from_pretrained(pretrained_name) + except (TypeError, AttributeError): + # Some tokenizers cannot be loaded into the target tokenizer at all and errors are returned, + # here we just check that the warning has been logged before the error is raised + pass + finally: + self.assertTrue( + cm.records[0].message.startswith( + "The tokenizer class you load from this checkpoint is not the same type as the class" + " this function is called from." + ) + ) + + @require_torch + def test_saving_tokenizer_trainer(self): + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + with tempfile.TemporaryDirectory() as tmp_dir: + # Save the fast tokenizer files in a temporary directory + tokenizer_old = self.rust_tokenizer_class.from_pretrained(pretrained_name, **kwargs, use_fast=True) + tokenizer_old.save_pretrained(tmp_dir, legacy_format=False) # save only fast version + + # Initialize toy model for the trainer + model = nn.Module() + + # Load tokenizer from a folder without legacy files + tokenizer = self.rust_tokenizer_class.from_pretrained(tmp_dir) + training_args = TrainingArguments(output_dir=tmp_dir, do_train=True, no_cuda=True) + trainer = Trainer(model=model, args=training_args, tokenizer=tokenizer) + + # Should not raise an error + trainer.save_model(os.path.join(tmp_dir, "checkpoint")) + self.assertIn("tokenizer.json", os.listdir(os.path.join(tmp_dir, "checkpoint"))) + + def test_convert_tokens_to_string_format(self): + tokenizers = self.get_tokenizers(fast=True, do_lower_case=True) + for tokenizer in tokenizers: + with self.subTest(f"{tokenizer.__class__.__name__}"): + tokens = ["this", "is", "a", "test"] + string = tokenizer.convert_tokens_to_string(tokens) + + self.assertIsInstance(string, str) + + def test_save_slow_from_fast_and_reload_fast(self): + if not self.test_slow_tokenizer or not self.test_rust_tokenizer: + # we need both slow and fast versions + return + + for tokenizer, pretrained_name, kwargs in self.tokenizers_list: + with self.subTest(f"{tokenizer.__class__.__name__} ({pretrained_name})"): + with tempfile.TemporaryDirectory() as tmp_dir_1: + # Here we check that even if we have initialized a fast tokenizer with a tokenizer_file we can + # still save only the slow version and use these saved files to rebuild a tokenizer + tokenizer_fast_old_1 = self.rust_tokenizer_class.from_pretrained( + pretrained_name, **kwargs, use_fast=True + ) + tokenizer_file = os.path.join(tmp_dir_1, "tokenizer.json") + tokenizer_fast_old_1.backend_tokenizer.save(tokenizer_file) + + tokenizer_fast_old_2 = self.rust_tokenizer_class.from_pretrained( + pretrained_name, **kwargs, use_fast=True, tokenizer_file=tokenizer_file + ) + + tokenizer_fast_old_2.save_pretrained(tmp_dir_1, legacy_format=True) # save only slow version + + tokenizer_slow = self.tokenizer_class.from_pretrained(tmp_dir_1) + with tempfile.TemporaryDirectory() as tmp_dir_2: + tokenizer_slow.save_pretrained(tmp_dir_2) + + # Should not raise an error + self.rust_tokenizer_class.from_pretrained(tmp_dir_2) + + def test_clean_up_tokenization_spaces(self): + tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") + assert tokenizer.clean_up_tokenization_spaces is True + + tokens = tokenizer.encode("This shouldn't be! He'll go.") + decoded = tokenizer.decode(tokens) + assert decoded == "[CLS] this shouldn't be! he'll go. [SEP]" + + tokenizer.clean_up_tokenization_spaces = False + decoded = tokenizer.decode(tokens) + assert decoded == "[CLS] this shouldn ' t be ! he ' ll go . [SEP]" + assert decoded == tokenizer.decode(tokens, clean_up_tokenization_spaces=False) + + # Fast from slow + with tempfile.TemporaryDirectory() as tmp_dir_2: + tokenizer.save_pretrained(tmp_dir_2) + tokenizer_fast = BertTokenizerFast.from_pretrained(tmp_dir_2) + del tokenizer + + assert tokenizer_fast.clean_up_tokenization_spaces is False + decoded = tokenizer_fast.decode(tokens) + # fast and slow don't have the same output when we don't cleanup + # tokenization space. Here `be!` vs `be !` and `go.` vs `go .` + assert decoded == "[CLS] this shouldn ' t be! he ' ll go. [SEP]" + + tokenizer_fast.clean_up_tokenization_spaces = True + assert tokenizer_fast.clean_up_tokenization_spaces is True + + decoded = tokenizer_fast.decode(tokens) + assert decoded == "[CLS] this shouldn't be! he'll go. [SEP]" + + # Slow from fast + with tempfile.TemporaryDirectory() as tmp_dir_2: + tokenizer_fast.clean_up_tokenization_spaces = False + tokenizer_fast.save_pretrained(tmp_dir_2) + tokenizer = BertTokenizer.from_pretrained(tmp_dir_2) + + assert tokenizer.clean_up_tokenization_spaces is False + decoded = tokenizer.decode(tokens) + assert decoded == "[CLS] this shouldn ' t be ! he ' ll go . [SEP]" + + tokenizer.clean_up_tokenization_spaces = True + decoded = tokenizer.decode(tokens) + assert decoded == "[CLS] this shouldn't be! he'll go. [SEP]" + + +class TokenizerUtilTester(unittest.TestCase): + def test_cached_files_are_used_when_internet_is_down(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = BertTokenizer.from_pretrained("hf-internal-testing/tiny-random-bert") + + # Under the mock environment we get a 500 error when trying to reach the tokenizer. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = BertTokenizer.from_pretrained("hf-internal-testing/tiny-random-bert") + # This check we did call the fake head request + mock_head.assert_called() + + @require_tokenizers + def test_cached_files_are_used_when_internet_is_down_missing_files(self): + # A mock response for an HTTP head request to emulate server down + response_mock = mock.Mock() + response_mock.status_code = 500 + response_mock.headers = {} + response_mock.raise_for_status.side_effect = HTTPError + response_mock.json.return_value = {} + + # Download this model to make sure it's in the cache. + _ = GPT2TokenizerFast.from_pretrained("gpt2") + + # Under the mock environment we get a 500 error when trying to reach the tokenizer. + with mock.patch("requests.Session.request", return_value=response_mock) as mock_head: + _ = GPT2TokenizerFast.from_pretrained("gpt2") + # This check we did call the fake head request + mock_head.assert_called() + + def test_legacy_load_from_one_file(self): + # This test is for deprecated behavior and can be removed in v5 + try: + tmp_file = tempfile.mktemp() + with open(tmp_file, "wb") as f: + http_get("https://huggingface.co/albert-base-v1/resolve/main/spiece.model", f) + + _ = AlbertTokenizer.from_pretrained(tmp_file) + finally: + os.remove(tmp_file) + + # Supporting this legacy load introduced a weird bug where the tokenizer would load local files if they are in + # the current folder and have the right name. + if os.path.isfile("tokenizer.json"): + # We skip the test if the user has a `tokenizer.json` in this folder to avoid deleting it. + return + try: + with open("tokenizer.json", "wb") as f: + http_get("https://huggingface.co/hf-internal-testing/tiny-random-bert/blob/main/tokenizer.json", f) + tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/tiny-random-gpt2") + # The tiny random BERT has a vocab size of 1024, tiny gpt2 as a vocab size of 1000 + self.assertEqual(tokenizer.vocab_size, 1000) + # Tokenizer should depend on the remote checkpoint, not the local tokenizer.json file. + + finally: + os.remove("tokenizer.json") + + def test_legacy_load_from_url(self): + # This test is for deprecated behavior and can be removed in v5 + _ = AlbertTokenizer.from_pretrained("https://huggingface.co/albert-base-v1/resolve/main/spiece.model") + + +@is_staging_test +class TokenizerPushToHubTester(unittest.TestCase): + vocab_tokens = ["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]", "bla", "blou"] + + @classmethod + def setUpClass(cls): + cls._token = TOKEN + HfFolder.save_token(TOKEN) + + @classmethod + def tearDownClass(cls): + try: + delete_repo(token=cls._token, repo_id="test-tokenizer") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="valid_org/test-tokenizer-org") + except HTTPError: + pass + + try: + delete_repo(token=cls._token, repo_id="test-dynamic-tokenizer") + except HTTPError: + pass + + def test_push_to_hub(self): + with tempfile.TemporaryDirectory() as tmp_dir: + vocab_file = os.path.join(tmp_dir, "vocab.txt") + with open(vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in self.vocab_tokens])) + tokenizer = BertTokenizer(vocab_file) + + tokenizer.push_to_hub("test-tokenizer", use_auth_token=self._token) + new_tokenizer = BertTokenizer.from_pretrained(f"{USER}/test-tokenizer") + self.assertDictEqual(new_tokenizer.vocab, tokenizer.vocab) + + # Reset repo + delete_repo(token=self._token, repo_id="test-tokenizer") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + tokenizer.save_pretrained(tmp_dir, repo_id="test-tokenizer", push_to_hub=True, use_auth_token=self._token) + + new_tokenizer = BertTokenizer.from_pretrained(f"{USER}/test-tokenizer") + self.assertDictEqual(new_tokenizer.vocab, tokenizer.vocab) + + def test_push_to_hub_in_organization(self): + with tempfile.TemporaryDirectory() as tmp_dir: + vocab_file = os.path.join(tmp_dir, "vocab.txt") + with open(vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in self.vocab_tokens])) + tokenizer = BertTokenizer(vocab_file) + + tokenizer.push_to_hub("valid_org/test-tokenizer-org", use_auth_token=self._token) + new_tokenizer = BertTokenizer.from_pretrained("valid_org/test-tokenizer-org") + self.assertDictEqual(new_tokenizer.vocab, tokenizer.vocab) + + # Reset repo + delete_repo(token=self._token, repo_id="valid_org/test-tokenizer-org") + + # Push to hub via save_pretrained + with tempfile.TemporaryDirectory() as tmp_dir: + tokenizer.save_pretrained( + tmp_dir, repo_id="valid_org/test-tokenizer-org", push_to_hub=True, use_auth_token=self._token + ) + + new_tokenizer = BertTokenizer.from_pretrained("valid_org/test-tokenizer-org") + self.assertDictEqual(new_tokenizer.vocab, tokenizer.vocab) + + @require_tokenizers + def test_push_to_hub_dynamic_tokenizer(self): + CustomTokenizer.register_for_auto_class() + with tempfile.TemporaryDirectory() as tmp_dir: + vocab_file = os.path.join(tmp_dir, "vocab.txt") + with open(vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in self.vocab_tokens])) + tokenizer = CustomTokenizer(vocab_file) + + # No fast custom tokenizer + tokenizer.push_to_hub("test-dynamic-tokenizer", use_auth_token=self._token) + + tokenizer = AutoTokenizer.from_pretrained(f"{USER}/test-dynamic-tokenizer", trust_remote_code=True) + # Can't make an isinstance check because the new_model.config is from the CustomTokenizer class of a dynamic module + self.assertEqual(tokenizer.__class__.__name__, "CustomTokenizer") + + # Fast and slow custom tokenizer + CustomTokenizerFast.register_for_auto_class() + with tempfile.TemporaryDirectory() as tmp_dir: + vocab_file = os.path.join(tmp_dir, "vocab.txt") + with open(vocab_file, "w", encoding="utf-8") as vocab_writer: + vocab_writer.write("".join([x + "\n" for x in self.vocab_tokens])) + + bert_tokenizer = BertTokenizerFast.from_pretrained(tmp_dir) + bert_tokenizer.save_pretrained(tmp_dir) + tokenizer = CustomTokenizerFast.from_pretrained(tmp_dir) + + tokenizer.push_to_hub("test-dynamic-tokenizer", use_auth_token=self._token) + + tokenizer = AutoTokenizer.from_pretrained(f"{USER}/test-dynamic-tokenizer", trust_remote_code=True) + # Can't make an isinstance check because the new_model.config is from the FakeConfig class of a dynamic module + self.assertEqual(tokenizer.__class__.__name__, "CustomTokenizerFast") + tokenizer = AutoTokenizer.from_pretrained( + f"{USER}/test-dynamic-tokenizer", use_fast=False, trust_remote_code=True + ) + # Can't make an isinstance check because the new_model.config is from the FakeConfig class of a dynamic module + self.assertEqual(tokenizer.__class__.__name__, "CustomTokenizer") + + +class TrieTest(unittest.TestCase): + def test_trie(self): + trie = Trie() + trie.add("Hello 友達") + self.assertEqual(trie.data, {"H": {"e": {"l": {"l": {"o": {" ": {"友": {"達": {"": 1}}}}}}}}}) + trie.add("Hello") + trie.data + self.assertEqual(trie.data, {"H": {"e": {"l": {"l": {"o": {"": 1, " ": {"友": {"達": {"": 1}}}}}}}}}) + + def test_trie_split(self): + trie = Trie() + self.assertEqual(trie.split("[CLS] This is a extra_id_100"), ["[CLS] This is a extra_id_100"]) + trie.add("[CLS]") + trie.add("extra_id_1") + trie.add("extra_id_100") + self.assertEqual(trie.split("[CLS] This is a extra_id_100"), ["[CLS]", " This is a ", "extra_id_100"]) + + def test_trie_single(self): + trie = Trie() + trie.add("A") + self.assertEqual(trie.split("ABC"), ["A", "BC"]) + self.assertEqual(trie.split("BCA"), ["BC", "A"]) + + def test_trie_final(self): + trie = Trie() + trie.add("TOKEN]") + trie.add("[SPECIAL_TOKEN]") + self.assertEqual(trie.split("This is something [SPECIAL_TOKEN]"), ["This is something ", "[SPECIAL_TOKEN]"]) + + def test_trie_subtokens(self): + trie = Trie() + trie.add("A") + trie.add("P") + trie.add("[SPECIAL_TOKEN]") + self.assertEqual(trie.split("This is something [SPECIAL_TOKEN]"), ["This is something ", "[SPECIAL_TOKEN]"]) + + def test_trie_suffix_tokens(self): + trie = Trie() + trie.add("AB") + trie.add("B") + trie.add("C") + self.assertEqual(trie.split("ABC"), ["AB", "C"]) + + def test_trie_skip(self): + trie = Trie() + trie.add("ABC") + trie.add("B") + trie.add("CD") + self.assertEqual(trie.split("ABCD"), ["ABC", "D"]) + + def test_cut_text_hardening(self): + # Even if the offsets are wrong, we necessarily output correct string + # parts. + trie = Trie() + parts = trie.cut_text("ABC", [0, 0, 2, 1, 2, 3]) + self.assertEqual(parts, ["AB", "C"]) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_seed_for_submission.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_seed_for_submission.py new file mode 100644 index 0000000000000000000000000000000000000000..ae903e63087516bc8ae77142532196be6a85589c --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_seed_for_submission.py @@ -0,0 +1,74 @@ +import os +import json +import argparse + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--annotation-file", type=str) + parser.add_argument("--result-file", type=str) + parser.add_argument("--result-upload-file", type=str) + return parser.parse_args() + + +def eval_single(result_file, eval_only_type=None): + results = {} + for line in open(result_file): + row = json.loads(line) + results[row['question_id']] = row + + type_counts = {} + correct_counts = {} + for question_data in data['questions']: + if eval_only_type is not None and question_data['data_type'] != eval_only_type: continue + data_type = question_data['question_type_id'] + type_counts[data_type] = type_counts.get(data_type, 0) + 1 + try: + question_id = int(question_data['question_id']) + except: + question_id = question_data['question_id'] + if question_id not in results: + correct_counts[data_type] = correct_counts.get(data_type, 0) + continue + row = results[question_id] + if row['text'] == question_data['answer']: + correct_counts[data_type] = correct_counts.get(data_type, 0) + 1 + + total_count = 0 + total_correct = 0 + for data_type in sorted(type_counts.keys()): + accuracy = correct_counts[data_type] / type_counts[data_type] * 100 + if eval_only_type is None: + print(f"{ques_type_id_to_name[data_type]}: {accuracy:.2f}%") + + total_count += type_counts[data_type] + total_correct += correct_counts[data_type] + + total_accuracy = total_correct / total_count * 100 + if eval_only_type is None: + print(f"Total accuracy: {total_accuracy:.2f}%") + else: + print(f"{eval_only_type} accuracy: {total_accuracy:.2f}%") + + return results + +if __name__ == "__main__": + args = get_args() + data = json.load(open(args.annotation_file)) + ques_type_id_to_name = {id:n for n,id in data['question_type'].items()} + + results = eval_single(args.result_file) + eval_single(args.result_file, eval_only_type='image') + eval_single(args.result_file, eval_only_type='video') + + with open(args.result_upload_file, 'w') as fp: + for question in data['questions']: + qid = question['question_id'] + if qid in results: + result = results[qid] + else: + result = results[int(qid)] + fp.write(json.dumps({ + 'question_id': qid, + 'prediction': result['text'] + }) + '\n') diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava.py new file mode 100644 index 0000000000000000000000000000000000000000..26fe3002413a23b5029e540c8b338ebb14307bf6 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava.py @@ -0,0 +1,88 @@ +import json +import os +import fire +import re +from convert_sqa_to_llava_base_prompt import build_prompt_chatbot + + +def convert_to_llava(base_dir, split, prompt_format="QCM-LEA"): + split_indices = json.load(open(os.path.join(base_dir, "pid_splits.json")))[split] + problems = json.load(open(os.path.join(base_dir, "problems.json"))) + + split_problems = build_prompt_chatbot( + problems, split_indices, prompt_format, + use_caption=False, is_test=False) + + target_format = [] + for prob_id, (input, output) in split_problems.items(): + if input.startswith('Question: '): + input = input.replace('Question: ', '') + if output.startswith('Answer: '): + output = output.replace('Answer: ', '') + + raw_prob_data = problems[prob_id] + if raw_prob_data['image'] is None: + target_format.append({ + "id": prob_id, + "conversations": [ + {'from': 'human', 'value': f"{input}"}, + {'from': 'gpt', 'value': f"{output}"}, + ], + }) + + else: + target_format.append({ + "id": prob_id, + "image": os.path.join(prob_id, raw_prob_data['image']), + "conversations": [ + {'from': 'human', 'value': f"{input}\n"}, + {'from': 'gpt', 'value': f"{output}"}, + ], + }) + + print(f'Number of samples: {len(target_format)}') + + with open(os.path.join(base_dir, f"llava_{split}_{prompt_format}.json"), "w") as f: + json.dump(target_format, f, indent=2) + + +def convert_to_jsonl(base_dir, split, prompt_format="QCM-LEPA"): + split_indices = json.load(open(os.path.join(base_dir, "pid_splits.json")))[split] + problems = json.load(open(os.path.join(base_dir, "problems.json"))) + + split_problems = build_prompt_chatbot( + problems, split_indices, prompt_format, + use_caption=False, is_test=False) + + writer = open(os.path.join(base_dir, f"scienceqa_{split}_{prompt_format}.jsonl"), "w") + for prob_id, (input, output) in split_problems.items(): + if input.startswith('Question: '): + input = input.replace('Question: ', '') + if output.startswith('Answer: '): + output = output.replace('Answer: ', '') + + raw_prob_data = problems[prob_id] + if raw_prob_data['image'] is None: + data = { + "id": prob_id, + "instruction": f"{input}", + "output": f"{output}", + } + + else: + data = { + "id": prob_id, + "image": os.path.join(prob_id, raw_prob_data['image']), + "instruction": f"{input}\n", + "output": f"{output}", + } + writer.write(json.dumps(data) + '\n') + writer.close() + + +def main(task, **kwargs): + globals()[task](**kwargs) + + +if __name__ == "__main__": + fire.Fire(main) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava_base_prompt.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava_base_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..b327fcc29eb44d7fe68be35da25bafa0e1d6feba --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_sqa_to_llava_base_prompt.py @@ -0,0 +1,334 @@ +def get_question_text(problem): + question = problem['question'] + return question + + +def get_context_text(problem, use_caption): + txt_context = problem['hint'] + img_context = problem['caption'] if use_caption else "" + context = " ".join([txt_context, img_context]).strip() + if context == "": + context = "N/A" + return context + + +def get_choice_text(probelm, options): + choices = probelm['choices'] + choice_list = [] + for i, c in enumerate(choices): + choice_list.append("({}) {}".format(options[i], c)) + choice_txt = " ".join(choice_list) + #print(choice_txt) + return choice_txt + + +def get_answer(problem, options): + return options[problem['answer']] + + +def get_lecture_text(problem): + # \\n: GPT-3 can generate the lecture with more tokens. + lecture = problem['lecture'].replace("\n", "\\n") + return lecture + + +def get_solution_text(problem): + # \\n: GPT-3 can generate the solution with more tokens + solution = problem['solution'].replace("\n", "\\n") + return solution + + +def create_one_example_chatbot(format, question, context, choice, answer, lecture, solution, test_example=True): + + input_format, output_format = format.split("-") + + ## Inputs + if input_format == "CQM": + input = f"Context: {context}\nQuestion: {question}\nOptions: {choice}\n" + elif input_format == "QCM": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\n" + # upper bound experiment + elif input_format == "QCML": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture}\n" + elif input_format == "QCME": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {solution}\n" + elif input_format == "QCMLE": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture} {solution}\n" + + elif input_format == "QCLM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture}\nOptions: {choice}\n" + elif input_format == "QCEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {solution}\nOptions: {choice}\n" + elif input_format == "QCLEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture} {solution}\nOptions: {choice}\n" + + # Outputs + if test_example: + output = "Answer:" + elif output_format == 'A': + output = f"Answer: The answer is {answer}." + + elif output_format == 'AL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution}" + elif output_format == 'AE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture}" + elif output_format == 'ALE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture} {solution}" + elif output_format == 'AEL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution} {lecture}" + + elif output_format == 'LA': + output = f"Answer: {lecture} The answer is {answer}." + elif output_format == 'EA': + output = f"Answer: {solution} The answer is {answer}." + elif output_format == 'LEA': + output = f"Answer: {lecture} {solution} The answer is {answer}." + elif output_format == 'ELA': + output = f"Answer: {solution} {lecture} The answer is {answer}." + elif output_format == 'LEPA': + output = '' + if len(lecture.strip()) > 0: + output += f"LECTURE: {lecture}\n" + if len(solution.strip()) > 0: + output += f"SOLUTION: {solution}\n" + output += '###\n' + output += f"ANSWER: {answer}." + + input = input.replace(" ", " ").strip() + output = output.replace(" ", " ").strip() + if input.endswith("BECAUSE:"): + input = input.replace("BECAUSE:", "").strip() + if output.endswith("BECAUSE:"): + output = output.replace("BECAUSE:", "").strip() + return input, output + + +def create_one_example(format, question, context, choice, answer, lecture, solution, test_example=True): + + input_format, output_format = format.split("-") + + ## Inputs + if input_format == "CQM": + input = f"Context: {context}\nQuestion: {question}\nOptions: {choice}\n" + elif input_format == "QCM": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\n" + # upper bound experiment + elif input_format == "QCML": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture}\n" + elif input_format == "QCME": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {solution}\n" + elif input_format == "QCMLE": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture} {solution}\n" + + elif input_format == "QCLM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture}\nOptions: {choice}\n" + elif input_format == "QCEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {solution}\nOptions: {choice}\n" + elif input_format == "QCLEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture} {solution}\nOptions: {choice}\n" + + # Outputs + if test_example: + output = "Answer:" + elif output_format == 'A': + output = f"Answer: The answer is {answer}." + + elif output_format == 'AL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution}" + elif output_format == 'AE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture}" + elif output_format == 'ALE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture} {solution}" + elif output_format == 'AEL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution} {lecture}" + + elif output_format == 'LA': + output = f"Answer: {lecture} The answer is {answer}." + elif output_format == 'EA': + output = f"Answer: {solution} The answer is {answer}." + elif output_format == 'LEA': + output = f"Answer: {lecture} {solution} The answer is {answer}." + elif output_format == 'ELA': + output = f"Answer: {solution} {lecture} The answer is {answer}." + + text = input + output + text = text.replace(" ", " ").strip() + if text.endswith("BECAUSE:"): + text = text.replace("BECAUSE:", "").strip() + return text + + + +def create_one_example_gpt4(format, question, context, choice, answer, lecture, solution, test_example=True): + + input_format, output_format = format.split("-") + + ## Inputs + if input_format == "CQM": + input = f"Context: {context}\nQuestion: {question}\nOptions: {choice}\n" + elif input_format == "QCM": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\n" + # upper bound experiment + elif input_format == "QCML": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture}\n" + elif input_format == "QCME": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {solution}\n" + elif input_format == "QCMLE": + input = f"Question: {question}\nContext: {context}\nOptions: {choice}\nBECAUSE: {lecture} {solution}\n" + + elif input_format == "QCLM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture}\nOptions: {choice}\n" + elif input_format == "QCEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {solution}\nOptions: {choice}\n" + elif input_format == "QCLEM": + input = f"Question: {question}\nContext: {context}\nBECAUSE: {lecture} {solution}\nOptions: {choice}\n" + + # Outputs + if test_example: + output = "Answer:" + elif output_format == 'A': + output = f"Answer: The answer is {answer}." + + elif output_format == 'AL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution}" + elif output_format == 'AE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture}" + elif output_format == 'ALE': + output = f"Answer: The answer is {answer}. BECAUSE: {lecture} {solution}" + elif output_format == 'AEL': + output = f"Answer: The answer is {answer}. BECAUSE: {solution} {lecture}" + + elif output_format == 'LA': + output = f"Answer: {lecture} The answer is {answer}." + elif output_format == 'EA': + output = f"Answer: {solution} The answer is {answer}." + elif output_format == 'LEA': + output = f"Answer: {lecture} {solution} The answer is {answer}." + elif output_format == 'ELA': + output = f"Answer: {solution} {lecture} The answer is {answer}." + + input = input.replace(" ", " ").strip() + output = output.replace(" ", " ").strip() + if output.endswith("BECAUSE:"): + output = output.replace("BECAUSE:", "").strip() + + user_prompt = {"role": "user", "content": f"Can you explain {input}?"} + assistant_prompt = {"role": "assistant", "content": f"{output}"} + + return user_prompt, assistant_prompt + + +def build_prompt_chatbot(problems, shot_qids, prompt_format, use_caption=False, options=["A", "B", "C", "D", "E"], is_test=False): + examples = {} + + for qid in shot_qids: + question = get_question_text(problems[qid]) + context = get_context_text(problems[qid], use_caption) + choice = get_choice_text(problems[qid], options) + answer = get_answer(problems[qid], options) + lecture = get_lecture_text(problems[qid]).replace('\\n', '\n') + solution = get_solution_text(problems[qid]).replace('\\n', '\n') + + train_example = create_one_example_chatbot(prompt_format, + question, + context, + choice, + answer, + lecture, + solution, + test_example=is_test) + examples[qid] = train_example + return examples + + +def build_prompt(problems, shot_qids, test_qid, args): + + examples = [] + + # n-shot training examples + for qid in shot_qids: + question = get_question_text(problems[qid]) + context = get_context_text(problems[qid], args.use_caption) + choice = get_choice_text(problems[qid], args.options) + answer = get_answer(problems[qid], args.options) + lecture = get_lecture_text(problems[qid]) + solution = get_solution_text(problems[qid]) + + train_example = create_one_example(args.prompt_format, + question, + context, + choice, + answer, + lecture, + solution, + test_example=False) + examples.append(train_example) + + # test example + question = get_question_text(problems[test_qid]) + context = get_context_text(problems[test_qid], args.use_caption) + choice = get_choice_text(problems[test_qid], args.options) + answer = get_answer(problems[test_qid], args.options) + lecture = get_lecture_text(problems[test_qid]) + solution = get_solution_text(problems[test_qid]) + + test_example = create_one_example(args.prompt_format, + question, + context, + choice, + answer, + lecture, + solution, + test_example=True) + examples.append(test_example) + + # create the prompt input + prompt_input = '\n\n'.join(examples) + + return prompt_input + + +def build_prompt_gpt4(problems, shot_qids, test_qid, args): + + prompt_array = [{"role": "system", "content": "You are a helpful assistant."}] + + # n-shot training examples + for qid in shot_qids: + question = get_question_text(problems[qid]) + context = get_context_text(problems[qid], args.use_caption) + choice = get_choice_text(problems[qid], args.options) + answer = get_answer(problems[qid], args.options) + lecture = get_lecture_text(problems[qid]) + solution = get_solution_text(problems[qid]) + + user_prompt, assistant_prompt = create_one_example_gpt4(args.prompt_format, + question, + context, + choice, + answer, + lecture, + solution, + test_example=False) + prompt_array.append(user_prompt) + prompt_array.append(assistant_prompt) + + # test example + question = get_question_text(problems[test_qid]) + context = get_context_text(problems[test_qid], args.use_caption) + choice = get_choice_text(problems[test_qid], args.options) + answer = get_answer(problems[test_qid], args.options) + lecture = get_lecture_text(problems[test_qid]) + solution = get_solution_text(problems[test_qid]) + + user_prompt, assistant_prompt = create_one_example_gpt4(args.prompt_format, + question, + context, + choice, + answer, + lecture, + solution, + test_example=True) + prompt_array.append(user_prompt) + prompt_array.append(assistant_prompt) + + return prompt_array \ No newline at end of file diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vizwiz_for_submission.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vizwiz_for_submission.py new file mode 100644 index 0000000000000000000000000000000000000000..7836d19f573d30e4224f2f89a53104acf03efb91 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vizwiz_for_submission.py @@ -0,0 +1,47 @@ +import os +import argparse +import json + +from llava.eval.m4c_evaluator import EvalAIAnswerProcessor + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--annotation-file', type=str, required=True) + parser.add_argument('--result-file', type=str, required=True) + parser.add_argument('--result-upload-file', type=str, required=True) + return parser.parse_args() + + +if __name__ == '__main__': + + args = parse_args() + + os.makedirs(os.path.dirname(args.result_upload_file), exist_ok=True) + + results = [] + error_line = 0 + for line_idx, line in enumerate(open(args.result_file)): + try: + results.append(json.loads(line)) + except: + error_line += 1 + results = {x['question_id']: x['text'] for x in results} + test_split = [json.loads(line) for line in open(args.annotation_file)] + split_ids = set([x['question_id'] for x in test_split]) + + print(f'total results: {len(results)}, total split: {len(test_split)}, error_line: {error_line}') + + all_answers = [] + + answer_processor = EvalAIAnswerProcessor() + + for x in test_split: + assert x['question_id'] in results + all_answers.append({ + 'image': x['image'], + 'answer': answer_processor(results[x['question_id']]) + }) + + with open(args.result_upload_file, 'w') as f: + json.dump(all_answers, f) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vqav2_for_submission.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vqav2_for_submission.py new file mode 100644 index 0000000000000000000000000000000000000000..05f67b33a73e17c683dbf9c09f84bacd10f285f5 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/convert_vqav2_for_submission.py @@ -0,0 +1,56 @@ +import os +import argparse +import json + +from llava.eval.m4c_evaluator import EvalAIAnswerProcessor + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--dir', type=str, default="./playground/data/eval/vqav2") + parser.add_argument('--ckpt', type=str, required=True) + parser.add_argument('--split', type=str, required=True) + return parser.parse_args() + + +if __name__ == '__main__': + + args = parse_args() + + src = os.path.join(args.dir, 'answers', args.split, args.ckpt, 'merge.jsonl') + test_split = os.path.join(args.dir, 'llava_vqav2_mscoco_test2015.jsonl') + dst = os.path.join(args.dir, 'answers_upload', args.split, f'{args.ckpt}.json') + os.makedirs(os.path.dirname(dst), exist_ok=True) + + results = [] + error_line = 0 + for line_idx, line in enumerate(open(src)): + try: + results.append(json.loads(line)) + except: + error_line += 1 + + results = {x['question_id']: x['text'] for x in results} + test_split = [json.loads(line) for line in open(test_split)] + split_ids = set([x['question_id'] for x in test_split]) + + print(f'total results: {len(results)}, total split: {len(test_split)}, error_line: {error_line}') + + all_answers = [] + + answer_processor = EvalAIAnswerProcessor() + + for x in test_split: + if x['question_id'] not in results: + all_answers.append({ + 'question_id': x['question_id'], + 'answer': '' + }) + else: + all_answers.append({ + 'question_id': x['question_id'], + 'answer': answer_processor(results[x['question_id']]) + }) + + with open(dst, 'w') as f: + json.dump(all_answers, open(dst, 'w')) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/extract_mm_projector.py b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/extract_mm_projector.py new file mode 100644 index 0000000000000000000000000000000000000000..45be31e896e9c087093bd9bcb6d355ec6dfd11ab --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/extract_mm_projector.py @@ -0,0 +1,47 @@ +""" +This is just a utility that I use to extract the projector for quantized models. +It is NOT necessary at all to train, or run inference/serve demos. +Use this script ONLY if you fully understand its implications. +""" + + +import os +import argparse +import torch +import json +from collections import defaultdict + + +def parse_args(): + parser = argparse.ArgumentParser(description='Extract MMProjector weights') + parser.add_argument('--model-path', type=str, help='model folder') + parser.add_argument('--output', type=str, help='output file') + args = parser.parse_args() + return args + + +if __name__ == '__main__': + args = parse_args() + + keys_to_match = ['mm_projector'] + ckpt_to_key = defaultdict(list) + try: + model_indices = json.load(open(os.path.join(args.model_path, 'pytorch_model.bin.index.json'))) + for k, v in model_indices['weight_map'].items(): + if any(key_match in k for key_match in keys_to_match): + ckpt_to_key[v].append(k) + except FileNotFoundError: + # Smaller models or model checkpoints saved by DeepSpeed. + v = 'pytorch_model.bin' + for k in torch.load(os.path.join(args.model_path, v), map_location='cpu').keys(): + if any(key_match in k for key_match in keys_to_match): + ckpt_to_key[v].append(k) + + loaded_weights = {} + + for ckpt_name, weight_keys in ckpt_to_key.items(): + ckpt = torch.load(os.path.join(args.model_path, ckpt_name), map_location='cpu') + for k in weight_keys: + loaded_weights[k] = ckpt[k] + + torch.save(loaded_weights, args.output) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune.sh new file mode 100644 index 0000000000000000000000000000000000000000..c14f770b481a548c978daca4b42fc0f74aeebe13 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# IMPORTANT: this is the training script for the original LLaVA, NOT FOR LLaVA V1.5! + +# Uncomment and set the following variables correspondingly to run this script: + +################## VICUNA ################## +# PROMPT_VERSION=v1 +# MODEL_VERSION="vicuna-v1-3-7b" +################## VICUNA ################## + +################## LLaMA-2 ################## +# PROMPT_VERSION="llava_llama_2" +# MODEL_VERSION="llama-2-7b-chat" +################## LLaMA-2 ################## + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero2.json \ + --model_name_or_path ./checkpoints/$MODEL_VERSION \ + --version $PROMPT_VERSION \ + --data_path ./playground/data/llava_instruct_80k.json \ + --image_folder /path/to/coco/train2017 \ + --vision_tower openai/clip-vit-large-patch14 \ + --pretrain_mm_mlp_adapter ./checkpoints/llava-$MODEL_VERSION-pretrain/mm_projector.bin \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 True \ + --output_dir ./checkpoints/llava-$MODEL_VERSION-finetune \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-5 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_lora.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_lora.sh new file mode 100644 index 0000000000000000000000000000000000000000..fc02e09d7792eb6a13ec32447b5e7f59ce141c8e --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_lora.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# IMPORTANT: this is the training script for the original LLaVA, NOT FOR LLaVA V1.5! + +# Uncomment and set the following variables correspondingly to run this script: + +################## VICUNA ################## +# PROMPT_VERSION=v1 +# MODEL_VERSION="vicuna-v1-3-7b" +################## VICUNA ################## + +################## LLaMA-2 ################## +# PROMPT_VERSION="llava_llama_2" +# MODEL_VERSION="llama-2-7b-chat" +################## LLaMA-2 ################## + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero2.json \ + --lora_enable True \ + --model_name_or_path ./checkpoints/$MODEL_VERSION \ + --version $PROMPT_VERSION \ + --data_path ./playground/data/llava_instruct_80k.json \ + --image_folder /path/to/coco/train2017 \ + --vision_tower openai/clip-vit-large-patch14 \ + --pretrain_mm_mlp_adapter ./checkpoints/llava-$MODEL_VERSION-pretrain/mm_projector.bin \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 True \ + --output_dir ./checkpoints/llava-$MODEL_VERSION-finetune_lora \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-5 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --lazy_preprocess True \ + --dataloader_num_workers 4 \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_sqa.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_sqa.sh new file mode 100644 index 0000000000000000000000000000000000000000..3ed50288c31c118cab22312ad02a559d45725490 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/finetune_sqa.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# IMPORTANT: this is the training script for the original LLaVA, NOT FOR LLaVA V1.5! + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero2.json \ + --model_name_or_path lmsys/vicuna-13b-v1.3 \ + --version $PROMPT_VERSION \ + --data_path /Data/ScienceQA/data/scienceqa/llava_train_QCM-LEA.json \ + --image_folder /Data/ScienceQA/data/scienceqa/images/train \ + --vision_tower openai/clip-vit-large-patch14 \ + --pretrain_mm_mlp_adapter ./checkpoints/huggingface/liuhaotian/llava-pretrain-vicuna-13b-v1.3/mm_projector.bin \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 True \ + --output_dir ./checkpoints/llava-vicuna-13b-v1.3-pretrain_lcs558k_plain-ScienceQA_QCM_LEA-12e \ + --num_train_epochs 12 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-5 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain.sh new file mode 100644 index 0000000000000000000000000000000000000000..83f263dd570e447b3b009542d26688ce936436af --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# IMPORTANT: this is the training script for the original LLaVA, NOT FOR LLaVA V1.5! + +# Uncomment and set the following variables correspondingly to run this script: + +# MODEL_VERSION=vicuna-v1-3-7b +# MODEL_VERSION=llama-2-7b-chat + +########### DO NOT CHANGE ########### +########### USE THIS FOR BOTH ########### +PROMPT_VERSION=plain +########### DO NOT CHANGE ########### + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero2.json \ + --model_name_or_path ./checkpoints/$MODEL_VERSION \ + --version $PROMPT_VERSION \ + --data_path /path/to/pretrain_data.json \ + --image_folder /path/to/images \ + --vision_tower openai/clip-vit-large-patch14 \ + --tune_mm_mlp_adapter True \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 True \ + --output_dir ./checkpoints/llava-$MODEL_VERSION-pretrain \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 24000 \ + --save_total_limit 1 \ + --learning_rate 2e-3 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain_xformers.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain_xformers.sh new file mode 100644 index 0000000000000000000000000000000000000000..ecba9c1ce714d481638e269ee4857fbe6a8de2fd --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/pretrain_xformers.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Uncomment and set the following variables correspondingly to run this script: + +# MODEL_VERSION=vicuna-v1-3-7b +# MODEL_VERSION=llama-2-7b-chat + +########### DO NOT CHANGE ########### +########### USE THIS FOR BOTH ########### +PROMPT_VERSION=plain +########### DO NOT CHANGE ########### + +deepspeed llava/train/train_xformers.py \ + --deepspeed ./scripts/zero2.json \ + --model_name_or_path ./checkpoints/$MODEL_VERSION \ + --version $PROMPT_VERSION \ + --data_path /path/to/pretrain_data.json \ + --image_folder /path/to/images \ + --vision_tower openai/clip-vit-large-patch14 \ + --tune_mm_mlp_adapter True \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 False \ + --output_dir ./checkpoints/llava-$MODEL_VERSION-pretrain \ + --num_train_epochs 1 \ + --per_device_train_batch_size 4 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 4 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 24000 \ + --save_total_limit 1 \ + --learning_rate 2e-3 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 False \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/sqa_eval_gather.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/sqa_eval_gather.sh new file mode 100644 index 0000000000000000000000000000000000000000..525bd43b850e9f6a923158abd23bca6f8d15650e --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/sqa_eval_gather.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +CHUNKS=8 +output_file="test_llava-13b.jsonl" + +# Clear out the output file if it exists. +> "$output_file" + +# Loop through the indices and concatenate each file. +for idx in $(seq 0 $((CHUNKS-1))); do + cat "./test_llava-13b-chunk${idx}.jsonl" >> "$output_file" +done + +python llava/eval/eval_science_qa.py \ + --base-dir ~/haotian/datasets/ScienceQA/data/scienceqa \ + --result-file ./test_llava-13b.jsonl \ + --output-file ./test_llava-13b_output.json \ + --output-result ./test_llava-13b_result.json diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/upload_pypi.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/upload_pypi.sh new file mode 100644 index 0000000000000000000000000000000000000000..c46597a2cdf85da52b4b109ddf2a103bea72364b --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/upload_pypi.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Step 0: Clean up +rm -rf dist + +# Step 1: Change the package name to "llava-torch" +sed -i 's/name = "llava"/name = "llava-torch"/' pyproject.toml + +# Step 2: Build the package +python -m build + +# Step 3: Revert the changes in pyproject.toml to the original +sed -i 's/name = "llava-torch"/name = "llava"/' pyproject.toml + +# Step 4: Upload to PyPI +python -m twine upload dist/* diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/gqa.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/gqa.sh new file mode 100644 index 0000000000000000000000000000000000000000..5c3c2c31fc35377a926739e8e4bfd4c23fb39e7f --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/gqa.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +gpu_list="${CUDA_VISIBLE_DEVICES:-0}" +IFS=',' read -ra GPULIST <<< "$gpu_list" + +CHUNKS=${#GPULIST[@]} + +CKPT="llava-v1.5-13b" +SPLIT="llava_gqa_testdev_balanced" +GQADIR="./playground/data/eval/gqa/data" + +for IDX in $(seq 0 $((CHUNKS-1))); do + CUDA_VISIBLE_DEVICES=${GPULIST[$IDX]} python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/gqa/$SPLIT.jsonl \ + --image-folder ./playground/data/eval/gqa/data/images \ + --answers-file ./playground/data/eval/gqa/answers/$SPLIT/$CKPT/${CHUNKS}_${IDX}.jsonl \ + --num-chunks $CHUNKS \ + --chunk-idx $IDX \ + --temperature 0 \ + --conv-mode vicuna_v1 & +done + +wait + +output_file=./playground/data/eval/gqa/answers/$SPLIT/$CKPT/merge.jsonl + +# Clear out the output file if it exists. +> "$output_file" + +# Loop through the indices and concatenate each file. +for IDX in $(seq 0 $((CHUNKS-1))); do + cat ./playground/data/eval/gqa/answers/$SPLIT/$CKPT/${CHUNKS}_${IDX}.jsonl >> "$output_file" +done + +python scripts/convert_gqa_for_eval.py --src $output_file --dst $GQADIR/testdev_balanced_predictions.json + +cd $GQADIR +python eval/eval.py --tier testdev_balanced diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/llavabench.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/llavabench.sh new file mode 100644 index 0000000000000000000000000000000000000000..ed236e4e3cee3105edd8d2c0bcee8e1ce22d4614 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/llavabench.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +python -m llava.eval.model_vqa \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/llava-bench-in-the-wild/questions.jsonl \ + --image-folder ./playground/data/eval/llava-bench-in-the-wild/images \ + --answers-file ./playground/data/eval/llava-bench-in-the-wild/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +mkdir -p playground/data/eval/llava-bench-in-the-wild/reviews + +python llava/eval/eval_gpt_review_bench.py \ + --question playground/data/eval/llava-bench-in-the-wild/questions.jsonl \ + --context playground/data/eval/llava-bench-in-the-wild/context.jsonl \ + --rule llava/eval/table/rule.json \ + --answer-list \ + playground/data/eval/llava-bench-in-the-wild/answers_gpt4.jsonl \ + playground/data/eval/llava-bench-in-the-wild/answers/llava-v1.5-13b.jsonl \ + --output \ + playground/data/eval/llava-bench-in-the-wild/reviews/llava-v1.5-13b.jsonl + +python llava/eval/summarize_gpt_review.py -f playground/data/eval/llava-bench-in-the-wild/reviews/llava-v1.5-13b.jsonl diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench.sh new file mode 100644 index 0000000000000000000000000000000000000000..d0b3a5c63bc7c8bb022ea2be41275cb921e8755d --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +SPLIT="mmbench_dev_20230712" + +python -m llava.eval.model_vqa_mmbench \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/mmbench/$SPLIT.tsv \ + --answers-file ./playground/data/eval/mmbench/answers/$SPLIT/llava-v1.5-13b.jsonl \ + --single-pred-prompt \ + --temperature 0 \ + --conv-mode vicuna_v1 + +mkdir -p playground/data/eval/mmbench/answers_upload/$SPLIT + +python scripts/convert_mmbench_for_submission.py \ + --annotation-file ./playground/data/eval/mmbench/$SPLIT.tsv \ + --result-dir ./playground/data/eval/mmbench/answers/$SPLIT \ + --upload-dir ./playground/data/eval/mmbench/answers_upload/$SPLIT \ + --experiment llava-v1.5-13b diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench_cn.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench_cn.sh new file mode 100644 index 0000000000000000000000000000000000000000..ce27c93aa1ea8a667a4bdd894be6db1d352ad7f5 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmbench_cn.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +SPLIT="mmbench_dev_cn_20231003" + +python -m llava.eval.model_vqa_mmbench \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/mmbench_cn/$SPLIT.tsv \ + --answers-file ./playground/data/eval/mmbench_cn/answers/$SPLIT/llava-v1.5-13b.jsonl \ + --lang cn \ + --single-pred-prompt \ + --temperature 0 \ + --conv-mode vicuna_v1 + +mkdir -p playground/data/eval/mmbench/answers_upload/$SPLIT + +python scripts/convert_mmbench_for_submission.py \ + --annotation-file ./playground/data/eval/mmbench_cn/$SPLIT.tsv \ + --result-dir ./playground/data/eval/mmbench_cn/answers/$SPLIT \ + --upload-dir ./playground/data/eval/mmbench_cn/answers_upload/$SPLIT \ + --experiment llava-v1.5-13b diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mme.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mme.sh new file mode 100644 index 0000000000000000000000000000000000000000..9b0f8ca657a429d92c233aaa404d9637d7500cc5 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mme.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/MME/llava_mme.jsonl \ + --image-folder ./playground/data/eval/MME/MME_Benchmark_release_version \ + --answers-file ./playground/data/eval/MME/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +cd ./playground/data/eval/MME + +python convert_answer_to_mme.py --experiment llava-v1.5-13b + +cd eval_tool + +python calculation.py --results_dir answers/llava-v1.5-13b diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmvet.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmvet.sh new file mode 100644 index 0000000000000000000000000000000000000000..9ff31ed469bb95e40116e66ad249c38770ba3735 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/mmvet.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +python -m llava.eval.model_vqa \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/mm-vet/llava-mm-vet.jsonl \ + --image-folder ./playground/data/eval/mm-vet/images \ + --answers-file ./playground/data/eval/mm-vet/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +mkdir -p ./playground/data/eval/mm-vet/results + +python scripts/convert_mmvet_for_eval.py \ + --src ./playground/data/eval/mm-vet/answers/llava-v1.5-13b.jsonl \ + --dst ./playground/data/eval/mm-vet/results/llava-v1.5-13b.json + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/pope.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/pope.sh new file mode 100644 index 0000000000000000000000000000000000000000..93fe449d943b36780341ce00638c94eba2e1f37b --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/pope.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/pope/llava_pope_test.jsonl \ + --image-folder ./playground/data/eval/pope/val2014 \ + --answers-file ./playground/data/eval/pope/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +python llava/eval/eval_pope.py \ + --annotation-dir ./playground/data/eval/pope/coco \ + --question-file ./playground/data/eval/pope/llava_pope_test.jsonl \ + --result-file ./playground/data/eval/pope/answers/llava-v1.5-13b.jsonl diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench.sh new file mode 100644 index 0000000000000000000000000000000000000000..46b8e029bbb02ccaf8cae1a7025867553fbd6c6c --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [ "$1" = "dev" ]; then + echo "Evaluating in 'dev' split." +elif [ "$1" = "test" ]; then + echo "Evaluating in 'test' split." +else + echo "Unknown split, please choose between 'dev' and 'test'." + exit 1 +fi + +python -m llava.eval.model_vqa_qbench \ + --model-path liuhaotian/llava-v1.5-13b \ + --image-folder ./playground/data/eval/qbench/images_llvisionqa/ \ + --questions-file ./playground/data/eval/qbench/llvisionqa_$1.json \ + --answers-file ./playground/data/eval/qbench/llvisionqa_$1_answers.jsonl \ + --conv-mode llava_v1 \ + --lang en diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench_zh.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench_zh.sh new file mode 100644 index 0000000000000000000000000000000000000000..7bfc17088cda577b6f25ec09b20ee8cb2664fec8 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/qbench_zh.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +if [ "$1" = "dev" ]; then + ZH_SPLIT="验证集" + echo "Evaluating in 'dev' split." +elif [ "$1" = "test" ]; then + ZH_SPLIT="测试集" + echo "Evaluating in 'test' split." +else + echo "Unknown split, please choose between 'dev' and 'test'." + exit 1 +fi + +python -m llava.eval.model_vqa_qbench \ + --model-path liuhaotian/llava-v1.5-13b \ + --image-folder ./playground/data/eval/qbench/images_llvisionqa/ \ + --questions-file ./playground/data/eval/qbench/质衡-问答-$ZH_SPLIT.json \ + --answers-file ./playground/data/eval/qbench/llvisionqa_zh_$1_answers.jsonl \ + --conv-mode llava_v1 \ + --lang zh diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/seed.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/seed.sh new file mode 100644 index 0000000000000000000000000000000000000000..565e54d1d4d35791d5ed22ad4e60c43fbdd877ed --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/seed.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +gpu_list="${CUDA_VISIBLE_DEVICES:-0}" +IFS=',' read -ra GPULIST <<< "$gpu_list" + +CHUNKS=${#GPULIST[@]} + +CKPT="llava-v1.5-13b" + +for IDX in $(seq 0 $((CHUNKS-1))); do + CUDA_VISIBLE_DEVICES=${GPULIST[$IDX]} python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/seed_bench/llava-seed-bench.jsonl \ + --image-folder ./playground/data/eval/seed_bench \ + --answers-file ./playground/data/eval/seed_bench/answers/$CKPT/${CHUNKS}_${IDX}.jsonl \ + --num-chunks $CHUNKS \ + --chunk-idx $IDX \ + --temperature 0 \ + --conv-mode vicuna_v1 & +done + +wait + +output_file=./playground/data/eval/seed_bench/answers/$CKPT/merge.jsonl + +# Clear out the output file if it exists. +> "$output_file" + +# Loop through the indices and concatenate each file. +for IDX in $(seq 0 $((CHUNKS-1))); do + cat ./playground/data/eval/seed_bench/answers/$CKPT/${CHUNKS}_${IDX}.jsonl >> "$output_file" +done + +# Evaluate +python scripts/convert_seed_for_submission.py \ + --annotation-file ./playground/data/eval/seed_bench/SEED-Bench.json \ + --result-file $output_file \ + --result-upload-file ./playground/data/eval/seed_bench/answers_upload/llava-v1.5-13b.jsonl + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/sqa.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/sqa.sh new file mode 100644 index 0000000000000000000000000000000000000000..8c82dbc256bd610c5ef2564ed2449b6a91857968 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/sqa.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +python -m llava.eval.model_vqa_science \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/scienceqa/llava_test_CQM-A.json \ + --image-folder ./playground/data/eval/scienceqa/images/test \ + --answers-file ./playground/data/eval/scienceqa/answers/llava-v1.5-13b.jsonl \ + --single-pred-prompt \ + --temperature 0 \ + --conv-mode vicuna_v1 + +python llava/eval/eval_science_qa.py \ + --base-dir ./playground/data/eval/scienceqa \ + --result-file ./playground/data/eval/scienceqa/answers/llava-v1.5-13b.jsonl \ + --output-file ./playground/data/eval/scienceqa/answers/llava-v1.5-13b_output.jsonl \ + --output-result ./playground/data/eval/scienceqa/answers/llava-v1.5-13b_result.json diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/textvqa.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/textvqa.sh new file mode 100644 index 0000000000000000000000000000000000000000..12311c3ccc3511446298c8e829216266e702ec16 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/textvqa.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/textvqa/llava_textvqa_val_v051_ocr.jsonl \ + --image-folder ./playground/data/eval/textvqa/train_images \ + --answers-file ./playground/data/eval/textvqa/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +python -m llava.eval.eval_textvqa \ + --annotation-file ./playground/data/eval/textvqa/TextVQA_0.5.1_val.json \ + --result-file ./playground/data/eval/textvqa/answers/llava-v1.5-13b.jsonl diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vizwiz.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vizwiz.sh new file mode 100644 index 0000000000000000000000000000000000000000..16cf35ce1b77834d9d8888d53e6cd0f7c2c4ccc6 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vizwiz.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/vizwiz/llava_test.jsonl \ + --image-folder ./playground/data/eval/vizwiz/test \ + --answers-file ./playground/data/eval/vizwiz/answers/llava-v1.5-13b.jsonl \ + --temperature 0 \ + --conv-mode vicuna_v1 + +python scripts/convert_vizwiz_for_submission.py \ + --annotation-file ./playground/data/eval/vizwiz/llava_test.jsonl \ + --result-file ./playground/data/eval/vizwiz/answers/llava-v1.5-13b.jsonl \ + --result-upload-file ./playground/data/eval/vizwiz/answers_upload/llava-v1.5-13b.json diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vqav2.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vqav2.sh new file mode 100644 index 0000000000000000000000000000000000000000..696efe53340f4abe5ad3ba8b9578df056e6c897d --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/eval/vqav2.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +gpu_list="${CUDA_VISIBLE_DEVICES:-0}" +IFS=',' read -ra GPULIST <<< "$gpu_list" + +CHUNKS=${#GPULIST[@]} + +CKPT="llava-v1.5-13b" +SPLIT="llava_vqav2_mscoco_test-dev2015" + +for IDX in $(seq 0 $((CHUNKS-1))); do + CUDA_VISIBLE_DEVICES=${GPULIST[$IDX]} python -m llava.eval.model_vqa_loader \ + --model-path liuhaotian/llava-v1.5-13b \ + --question-file ./playground/data/eval/vqav2/$SPLIT.jsonl \ + --image-folder ./playground/data/eval/vqav2/test2015 \ + --answers-file ./playground/data/eval/vqav2/answers/$SPLIT/$CKPT/${CHUNKS}_${IDX}.jsonl \ + --num-chunks $CHUNKS \ + --chunk-idx $IDX \ + --temperature 0 \ + --conv-mode vicuna_v1 & +done + +wait + +output_file=./playground/data/eval/vqav2/answers/$SPLIT/$CKPT/merge.jsonl + +# Clear out the output file if it exists. +> "$output_file" + +# Loop through the indices and concatenate each file. +for IDX in $(seq 0 $((CHUNKS-1))); do + cat ./playground/data/eval/vqav2/answers/$SPLIT/$CKPT/${CHUNKS}_${IDX}.jsonl >> "$output_file" +done + +python scripts/convert_vqav2_for_submission.py --split $SPLIT --ckpt $CKPT + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune.sh new file mode 100644 index 0000000000000000000000000000000000000000..435448394dfcef578ac478f499160fba4ceacd6c --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero3.json \ + --model_name_or_path lmsys/vicuna-13b-v1.5 \ + --version v1 \ + --data_path ./playground/data/llava_v1_5_mix665k.json \ + --image_folder ./playground/data \ + --vision_tower openai/clip-vit-large-patch14-336 \ + --pretrain_mm_mlp_adapter ./checkpoints/llava-v1.5-13b-pretrain/mm_projector.bin \ + --mm_projector_type mlp2x_gelu \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --image_aspect_ratio pad \ + --group_by_modality_length True \ + --bf16 True \ + --output_dir ./checkpoints/llava-v1.5-13b \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-5 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_lora.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_lora.sh new file mode 100644 index 0000000000000000000000000000000000000000..90f00707cf9c9ae499184f0135f7cc9d84327a21 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_lora.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +deepspeed llava/train/train_mem.py \ + --lora_enable True --lora_r 128 --lora_alpha 256 --mm_projector_lr 2e-5 \ + --deepspeed ./scripts/zero3.json \ + --model_name_or_path lmsys/vicuna-13b-v1.5 \ + --version v1 \ + --data_path ./playground/data/llava_v1_5_mix665k.json \ + --image_folder ./playground/data \ + --vision_tower openai/clip-vit-large-patch14-336 \ + --pretrain_mm_mlp_adapter ./checkpoints/llava-v1.5-13b-pretrain/mm_projector.bin \ + --mm_projector_type mlp2x_gelu \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --image_aspect_ratio pad \ + --group_by_modality_length True \ + --bf16 True \ + --output_dir ./checkpoints/llava-v1.5-13b-lora \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-4 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task.sh new file mode 100644 index 0000000000000000000000000000000000000000..063f3f13e119fdb7f6af358f50315e022f15f578 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero3.json \ + --model_name_or_path liuhaotian/llava-v1.5-13b \ + --version v1 \ + --data_path ./playground/data/llava_v1_5_mix665k.json \ + --image_folder ./playground/data \ + --vision_tower openai/clip-vit-large-patch14-336 \ + --mm_projector_type mlp2x_gelu \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --image_aspect_ratio pad \ + --group_by_modality_length True \ + --bf16 True \ + --output_dir ./checkpoints/llava-v1.5-13b-task \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-5 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task_lora.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task_lora.sh new file mode 100644 index 0000000000000000000000000000000000000000..f11303f299aeb675e23b0cb37ff4c881aec6f99e --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/finetune_task_lora.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +deepspeed llava/train/train_mem.py \ + --lora_enable True --lora_r 128 --lora_alpha 256 --mm_projector_lr 2e-5 \ + --deepspeed ./scripts/zero3.json \ + --model_name_or_path liuhaotian/llava-v1.5-13b \ + --version v1 \ + --data_path ./playground/data/llava_v1_5_mix665k.json \ + --image_folder ./playground/data \ + --vision_tower openai/clip-vit-large-patch14-336 \ + --mm_projector_type mlp2x_gelu \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --image_aspect_ratio pad \ + --group_by_modality_length True \ + --bf16 True \ + --output_dir ./checkpoints/llava-v1.5-13b-task-lora \ + --num_train_epochs 1 \ + --per_device_train_batch_size 16 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 50000 \ + --save_total_limit 1 \ + --learning_rate 2e-4 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/pretrain.sh b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/pretrain.sh new file mode 100644 index 0000000000000000000000000000000000000000..9316eaa309ea8c12d9612a01d85958550357b9a7 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/v1_5/pretrain.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +deepspeed llava/train/train_mem.py \ + --deepspeed ./scripts/zero2.json \ + --model_name_or_path lmsys/vicuna-13b-v1.5 \ + --version plain \ + --data_path ./playground/data/LLaVA-Pretrain/blip_laion_cc_sbu_558k.json \ + --image_folder ./playground/data/LLaVA-Pretrain/images \ + --vision_tower openai/clip-vit-large-patch14-336 \ + --mm_projector_type mlp2x_gelu \ + --tune_mm_mlp_adapter True \ + --mm_vision_select_layer -2 \ + --mm_use_im_start_end False \ + --mm_use_im_patch_token False \ + --bf16 True \ + --output_dir ./checkpoints/llava-v1.5-13b-pretrain \ + --num_train_epochs 1 \ + --per_device_train_batch_size 32 \ + --per_device_eval_batch_size 4 \ + --gradient_accumulation_steps 1 \ + --evaluation_strategy "no" \ + --save_strategy "steps" \ + --save_steps 24000 \ + --save_total_limit 1 \ + --learning_rate 1e-3 \ + --weight_decay 0. \ + --warmup_ratio 0.03 \ + --lr_scheduler_type "cosine" \ + --logging_steps 1 \ + --tf32 True \ + --model_max_length 2048 \ + --gradient_checkpointing True \ + --dataloader_num_workers 4 \ + --lazy_preprocess True \ + --report_to wandb diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero2.json b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero2.json new file mode 100644 index 0000000000000000000000000000000000000000..c95ebefe07b7d8d9fd0936a014679d07102cc270 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero2.json @@ -0,0 +1,23 @@ +{ + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "train_micro_batch_size_per_gpu": "auto", + "train_batch_size": "auto", + "gradient_accumulation_steps": "auto", + "zero_optimization": { + "stage": 2, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto" + } +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3.json b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3.json new file mode 100644 index 0000000000000000000000000000000000000000..6917317af62da757ca759a92b326ddfa65b203cc --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3.json @@ -0,0 +1,28 @@ +{ + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "train_micro_batch_size_per_gpu": "auto", + "train_batch_size": "auto", + "gradient_accumulation_steps": "auto", + "zero_optimization": { + "stage": 3, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto", + "stage3_prefetch_bucket_size": "auto", + "stage3_param_persistence_threshold": "auto", + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "stage3_gather_16bit_weights_on_model_save": true + } +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3_offload.json b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3_offload.json new file mode 100644 index 0000000000000000000000000000000000000000..e0a54c2c2bc10f76458c42a43de0970a9251759f --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/LLaVA/scripts/zero3_offload.json @@ -0,0 +1,56 @@ +{ + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "optimizer": { + "type": "AdamW", + "params": { + "lr": "auto", + "betas": "auto", + "eps": "auto", + "weight_decay": "auto" + } + }, + "scheduler": { + "type": "WarmupLR", + "params": { + "warmup_min_lr": "auto", + "warmup_max_lr": "auto", + "warmup_num_steps": "auto" + } + }, + "zero_optimization": { + "stage": 3, + "offload_optimizer": { + "device": "cpu", + "pin_memory": true + }, + "offload_param": { + "device": "cpu", + "pin_memory": true + }, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto", + "stage3_prefetch_bucket_size": "auto", + "stage3_param_persistence_threshold": "auto", + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "gather_16bit_weights_on_model_save": true + }, + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "steps_per_print": 1e5, + "wall_clock_breakdown": false +} \ No newline at end of file diff --git a/SupplementaryMaterial_Code/VLMEvalKit/assets/LOGO.svg b/SupplementaryMaterial_Code/VLMEvalKit/assets/LOGO.svg new file mode 100644 index 0000000000000000000000000000000000000000..39b62268249b39b1daf1c6e2ab4f0f214051b59c --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/assets/LOGO.svg @@ -0,0 +1,24 @@ + + + +Created with Fabric.js 5.3.0 + + + + + + + + + + + + + VLMEvalKit + \ No newline at end of file diff --git a/SupplementaryMaterial_Code/VLMEvalKit/assets/apple.jpg b/SupplementaryMaterial_Code/VLMEvalKit/assets/apple.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34e1859aa4b053958abbfd254e8f53dc40a6cd2d Binary files /dev/null and b/SupplementaryMaterial_Code/VLMEvalKit/assets/apple.jpg differ diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/.readthedocs.yaml b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/.readthedocs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c6cf8e2a075ea15f39dc7aba8faa98f464f52fe6 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/.readthedocs.yaml @@ -0,0 +1,17 @@ +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.8" + +formats: + - epub + +sphinx: + configuration: docs/en/conf.py + +python: + install: + - requirements: requirements/docs.txt diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/ConfigSystem.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/ConfigSystem.md new file mode 100644 index 0000000000000000000000000000000000000000..120e0cb05a36ed9d911811c71d6201b319dda7c1 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/ConfigSystem.md @@ -0,0 +1,67 @@ +# Config System + +By default, VLMEvalKit launches the evaluation by setting the model name(s) (defined in `/vlmeval/config.py`) and dataset name(s) (defined in `vlmeval/dataset/__init__.py` or `vlmeval/dataset/video_dataset_config.py`) in the `run.py` script with the `--model` and `--data` arguments. Such approach is simple and efficient in most scenarios, however, it may not be flexible enough when the user wants to evaluate multiple models / datasets with different settings. + +To address this, VLMEvalKit provides a more flexible config system. The user can specify the model and dataset settings in a json file, and pass the path to the config file to the `run.py` script with the `--config` argument. Here is a sample config json: + +```json +{ + "model": { + "GPT4o_20240806_T00_HIGH": { + "class": "GPT4V", + "model": "gpt-4o-2024-08-06", + "temperature": 0, + "img_detail": "high" + }, + "GPT4o_20240806_T10_Low": { + "class": "GPT4V", + "model": "gpt-4o-2024-08-06", + "temperature": 1.0, + "img_detail": "low" + }, + "GPT4o_20241120": {} + }, + "data": { + "MME-RealWorld-Lite": { + "class": "MMERealWorld", + "dataset": "MME-RealWorld-Lite" + }, + "MMBench_DEV_EN_V11": { + "class": "ImageMCQDataset", + "dataset": "MMBench_DEV_EN_V11" + }, + "MMBench_Video_8frame_nopack":{}, + "Video-MME_16frame_subs": { + "class": "VideoMME", + "dataset": "Video-MME", + "nframe": 16, + "use_subtitle": true + } + } +} +``` + +Explanation of the config json: + +1. Now we support two fields: `model` and `data`, each of which is a dictionary. The key of the dictionary is the name of the model / dataset (set by the user), and the value is the setting of the model / dataset. +2. For items in `model`, the value is a dictionary containing the following keys: + - `class`: The class name of the model, which should be a class name defined in `vlmeval/vlm/__init__.py` (open-source models) or `vlmeval/api/__init__.py` (API models). + - Other kwargs: Other kwargs are model-specific parameters, please refer to the definition of the model class for detailed usage. For example, `model`, `temperature`, `img_detail` are arguments of the `GPT4V` class. It's noteworthy that the `model` argument is required by most model classes. + - Tip: The defined model in the `supported_VLM` of `vlmeval/config.py` can be used as a shortcut, for example, `GPT4o_20241120: {}` is equivalent to `GPT4o_20241120: {'class': 'GPT4V', 'model': 'gpt-4o-2024-11-20', 'temperature': 0, 'img_size': -1, 'img_detail': 'high', 'retry': 10, 'verbose': False}` +3. For the dictionary `data`, we suggest users to use the official dataset name as the key (or part of the key), since we frequently determine the post-processing / judging settings based on the dataset name. For items in `data`, the value is a dictionary containing the following keys: + - `class`: The class name of the dataset, which should be a class name defined in `vlmeval/dataset/__init__.py`. + - Other kwargs: Other kwargs are dataset-specific parameters, please refer to the definition of the dataset class for detailed usage. Typically, the `dataset` argument is required by most dataset classes. It's noteworthy that the `nframe` argument or `fps` argument is required by most video dataset classes. + - Tip: The defined dataset in the `supported_video_datasets` of `vlmeval/dataset/video_dataset_config.py` can be used as a shortcut, for example, `MMBench_Video_8frame_nopack: {}` is equivalent to `MMBench_Video_8frame_nopack: {'class': 'MMBenchVideo', 'dataset': 'MMBench-Video', 'nframe': 8, 'pack': False}`. +Saving the example config json to `config.json`, you can launch the evaluation by: + +```bash +python run.py --config config.json +``` + +That will generate the following output files under the working directory `$WORK_DIR` (Following the format `{$WORK_DIR}/{$MODEL_NAME}/{$MODEL_NAME}_{$DATASET_NAME}_*`): + +- `$WORK_DIR/GPT4o_20240806_T00_HIGH/GPT4o_20240806_T00_HIGH_MME-RealWorld-Lite*` +- `$WORK_DIR/GPT4o_20240806_T10_Low/GPT4o_20240806_T10_Low_MME-RealWorld-Lite*` +- `$WORK_DIR/GPT4o_20240806_T00_HIGH/GPT4o_20240806_T00_HIGH_MMBench_DEV_EN_V11*` +- `$WORK_DIR/GPT4o_20240806_T10_Low/GPT4o_20240806_T10_Low_MMBench_DEV_EN_V11*` +... diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Contributors.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Contributors.md new file mode 100644 index 0000000000000000000000000000000000000000..ddf50c6c4eb7caf352fe29069e65a93a2d4cac49 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Contributors.md @@ -0,0 +1,21 @@ +# Contributors + +## Contributors w. 3+ Major Contributions + +> In this section, we list all the contributors who have made significant contributions (3+) to the development of VLMEvalKit. + +New Qualified Contributors (2024.09): + +1. [amitbcp](https://github.com/amitbcp): The contributor helped support MUIRBench, Phi-3.5, Idefics3, VILA, and xGen-MM +2. [czczup](https://github.com/czczup): The contributor helped support the InternVL Series (V1.5, Mini-InternVL, V2, etc.) +3. [DseidLi](https://github.com/DseidLi): The contributor helped support LLaVA-OneVision, GQA, and developed the readthedocs site for VLMEvalKit +4. [mayubo2333](https://github.com/mayubo2333): The contributor helped support MMLongBench, SlideVQA, and DUDE +5. [sun-hailong](https://github.com/sun-hailong): The contributor helped support A-OKVQA, Parrot, MMMB, and MTL-MMBench +6. [PhoenixZ810](https://github.com/PhoenixZ810): The contributor helped support Video-ChatGPT, Chat-UniVI, and Llama-VID +7. [Cuiunbo](https://github.com/Cuiunbo): The contributor helped support OmniLMM-12B, MiniCPM-V Series (V1, V2, V2.5) + +## Full Contributor List + +> In this section, we list all the contributors as well as their corresponding contributions to the development of VLMEvalKit. + +TBD. diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Development.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Development.md new file mode 100644 index 0000000000000000000000000000000000000000..0fe5a60e22252a2098ed0edd47e6f219d51a0a4d --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Development.md @@ -0,0 +1,145 @@ +# Develop new Benchmark / MLLM + +> 🛠️ How to implement a new Benchmark / VLM in VLMEvalKit? + +## Implement a new benchmark + +Example PR: **Math-Vision Benchmark** ([#292](https://github.com/open-compass/VLMEvalKit/pull/292/files)) + +In VLMEvalKit, benchmarks are organized as dataset classes. When you try to implement a new benchmark, you can either reuse existing dataset classes (*e.g.*, You can reuse `ImageMCQDataset` when implementing a new multi-choice benchmark), or support a new dataset class. Each dataset must have the following two member functions (either reuse the one of the parent class or implement your own): + +- `build_prompt(self, line)`: The function input `line` is an integer (the sample index) or a `pd.Series` object (the raw record of the sample). The function outputs a `multi-modal message`, serving as the input of an MLLM. The `multi-modal message` is an interleaved list of multi-modal messages adopting the following format (the example includes an image and a text message): `[dict(type='image', value=IMAGE_PTH), dict(type='text', value=prompt)]`. +- `evaluate(self, eval_file, **judge_kwargs)`: The function input `eval_file` is the MLLM prediction (typically in `.xlsx` format). If the benchmark requires an external LLM (typically GPT) for evaluation, then `judge_kwargs` can pass the arguments for the LLM. The function outputs the benchmark evaluation results (metrics) in the form of `dict` or `pd.DataFrame`. + +We then brief the typical steps to implement a new benchmark under VLMEvalKit: + +### 1. Prepare your benchmark tsv file + +Currently, we organize a benchmark as one single TSV file. During inference, the data file will be automatically downloaded from the definited `DATASET_URL` link to `$LMUData` file (default path is `$HOME/LMUData`, if not set explicitly). You can upload the prepared TSV file to a downloadable address (e.g., Huggingface) or send it to us at . We will assist in uploading the dataset to the server. You can also customize `LMUData` path in the environment variable `LMUData=/path/to/your/data`. + +The contents of the TSV file consist of: + +| Dataset Name \ Fields | index | image | image_path | question | hint | multi-choice
options | answer | category | l2-category | split | +| --------------------------------------- | ----- | ----- | ---------- | -------- | ---- | ----------------------- | ------ | -------- | ----------- | ----- | +| MMBench_DEV_[CN/EN] | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| MMBench_TEST_[CN/EN] | ✅ | ✅ | | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | +| CCBench | ✅ | ✅ | | ✅ | | ✅ | ✅ | ✅ | | | +| SEEDBench_IMG | ✅ | ✅ | | ✅ | | ✅ | ✅ | ✅ | | | +| MME | ✅ | ✅ | | ✅ | | | ✅ | ✅ | | | +| MMVet | ✅ | ✅ | | ✅ | | | ✅ | ✅ | | | +| MMMU_DEV_VAL | ✅ | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | +| COCO_VAL | ✅ | ✅ | | | | | ✅ | | | | +| OCRVQA_[TEST/TESTCORE] | ✅ | ✅ | | ✅ | | | ✅ | | | | +| TextVQA_VAL | ✅ | ✅ | | ✅ | | | ✅ | | | | +| VCR_[EN/ZH]\_[EASY/HARD]\_[ALL/500/100] | ✅ | ✅ | | ✅ | | | ✅ | | | | +| MMMB_[en/cn/pt/ar/tr/ru] | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | |✅ | +| MMBench_dev_[en/cn/pt/ar/tr/ru] | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |✅ | + +
Table 1. TSV fields of supported datasets.
+ +**Intro to mandatory fields in the `TSV` file:** + +- **index:** Integer, Unique for each line in `tsv` +- **image:** The base64 of the image, you can use APIs implemented in `vlmeval/smp/vlm.py` for encoding and decoding: + - Encoding: `encode_image_to_base64 `(for PIL Image) / `encode_image_file_to_base64` (for image file path) + - Decoding: `decode_base64_to_image`(for PIL Image) / `decode_base64_to_image_file` (for image file path) +- **question**: The question corresponding to the image, a string +- **answer**: The answer to the question, a string. The `test` split does not need this field + +### 2. Cutomize your benchmark prompt + +`ImageBaseDataset` defines the default prompt format. If you need to add prompts specific to the dataset or input data in the `Interleave` format to the model, you can implement this through the `build_prompt(line)` function. This function takes a line from a TSV file as input, containing fields such as index, image, question, etc. The function returns a dictionary list of multimodal messages `msg` in the format `[dict(type='image', value=IMAGE_PTH), dict(type='text', value=prompt)]`, including the image path and the text prompt to be input into VLMs. For interleave type inputs, you can directly place the dictionary of the image path at the image token position. + +### 3. Cutomize your benchmark metrics + +To add evaluation for a new benchmark, you need to customize a class object to implement the dataset’s metrics calculation. Multimodal datasets inherit from the `ImageBaseDataset` object in `vlmeval/dataset/image_base.py`. The TYPE defines the type of dataset, `DATASET_URL` is the download address of the dataset, and `DATASET_MD5` is the MD5 checksum for consistency checking of the dataset file. + +In this class, **you need to implement** the `evaluate(eval_file, **judge_kwargs)` class function to calculate metrics and output results for the custom dataset. The function input `eval_file` is the path to the model prediction results file `{model_name}_{dataset}.xlsx`. This file can be read as a pandas.DataFrame using the `load(eval_file)` method, containing fields such as index, question, answer, category, prediction, etc. The judge_kwargs will pass a dictionary related to evaluation, such as the name of the `judge model`, the number of API request threads, etc. **The return value** of the function is the calculated accuracy and other metrics, formatted as a dictionary composed of lists, organized into a pandas.DataFrame. + +## Implement a new model + +Example PR: **Support LLaVA-Next-Interleave** ([#294](https://github.com/open-compass/VLMEvalKit/pull/294)) + +**1. Support `generate_inner` API (mandatory).** + +All existing models are implemented in `vlmeval/vlm`. For a minimal model, your model class **must implement the method** `generate_inner(msgs, dataset=None)`. In this function, you feed a multi-modal message to your VLM and return the VLM prediction (which is a string). The optional argument `dataset` can be used as the flag for the model to switch among various inference strategies. + +The multi-modal messages `msgs` is a list of dictionaries, each dictionary has two keys: type and value: +- `type`: We currently support two types, choices are ["image", "text"]. +- `value`: When type=='text' , the value is the text message (a single string); when type=='image', the value can be the local path of an image file, or the image URL. + +Currently a multi-modal message may contain arbitrarily interleaved images and texts. If your model do not support that, a practice can be taking the 1st image and concatenated text messages as the input. You can set the `INTERLEAVE = False` in your model class and use `self.message_to_promptimg(message, dataset=dataset)` to build your prompt and the first image's path. + +Here are some examples of multi-modal messages: + +```python +IMAGE_PTH = 'assets/apple.jpg' +IMAGE_URL = 'https://raw.githubusercontent.com/open-compass/VLMEvalKit/main/assets/apple.jpg' +msg1 = [ + dict(type='image', value=IMAGE_PTH), + dict(type='text', value='What is in this image?') +] +msg2 = [ + dict(type='image', value=IMAGE_URL), + dict(type='image', value=IMAGE_URL), + dict(type='text', value='How many apples are there in these images?') +] +response = model.generate(msg1) +``` + +For convenience sake, we also support to take a list of string as inputs. In that case, we will check if a string is an image path or image URL and automatically convert it to the list[dict] format: + +```python +IMAGE_PTH = 'assets/apple.jpg' +IMAGE_URL = 'https://raw.githubusercontent.com/open-compass/VLMEvalKit/main/assets/apple.jpg' +msg1 = [IMAGE_PTH, 'What is in this image?'] +msg2 = [IMAGE_URL, IMAGE_URL, 'How many apples are there in these images?'] +response = model.generate(msg1) +``` + +**Support Custom Prompt (optional).** + +Besides, your model can support **custom prompt building** by implementing two optional methods: `use_custom_prompt(dataset)` and `build_prompt(line, dataset=None)`. + +Both functions take the dataset name as the input: + +- `use_custom_prompt(dataset)` returns a boolean flag, indicating whether the model should use the custom prompt building strategy. +- If `use_custom_prompt(dataset)` returns True, `build_prompt(line, dataset)` should return a customly bulit multimodal message for the corresponding `dataset`, given `line`, which is a dictionary that includes the necessary information of a data sample. If `use_custom_prompt(dataset)` returns False, the default prompt building strategy will be used. + +**Support multi-turn chatting (optional).** + +You can also support the multi-turn chatting and evaluation with your VLM by supporting the `chat_inner(message, dataset)` function. The function outputs a single string response, and the `message` is a list of chat history, following the below format. + +```python +# Assume msg1, msg2, msg3, ... are multi-modal messages following the previously described format +# `chat_inner` take the following chat history list as input: +message = [ + dict(role='user', content=msg1), + dict(role='assistant', content=msg2), + dict(role='user', content=msg3), + dict(role='assistant', content=msg4), + ...... + dict(role='user', content=msgn), +] +# `message` should contain an odd number of chat utterances, the role of utterances should be interleaved "user" and "assistant", with the role of the last utterance to be "user". +# The chat function will call `chat_inner` +response = model.chat(message) +``` + +### Example PRs: + +- VLM that doesn't support interleaved images and texts, and does not use custom prompts: [[Model] Support glm-4v-9b](https://github.com/open-compass/VLMEvalKit/pull/221) +- VLM that supports interleaved images and texts and custom prompts: [Add MiniCPM-Llama3-V-2.5](https://github.com/open-compass/VLMEvalKit/pull/205) +- VLM API: [Feature add glmv](https://github.com/open-compass/VLMEvalKit/pull/201) + +## Contribute to VLMEvalKit + +If you want to contribute codes to **VLMEvalKit**, please do the pre-commit check before you submit a PR. That helps to keep the code tidy. + +```bash +# Under the directory of VLMEvalKit, install the pre-commit hook: +pip install pre-commit +pre-commit install +pre-commit run --all-files +# Then you can commit your code. +``` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/EvalByLMDeploy.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/EvalByLMDeploy.md new file mode 100644 index 0000000000000000000000000000000000000000..fc0a8c38c26542eb44acdc74b28aaca9755735ba --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/EvalByLMDeploy.md @@ -0,0 +1,27 @@ +# Using LMDeploy to Accelerate Evaluation and Inference + +VLMEvalKit supports testing VLM models deployed by LMDeploy. Below, we use InternVL2-8B as an example to show how to test the model. + +## Step 0: Install LMDeploy + +```bash +pip install lmdeploy +``` +For other installation methods, you can refer to LMDeploy's [documentation](https://github.com/InternLM/lmdeploy). + +## Step 1: Start the Inference Service + +```bash +lmdeploy serve api_server OpenGVLab/InternVL2-8B --model-name InternVL2-8B +``` +> [!IMPORTANT] +> Since models in VLMEvalKit may have custom behaviors when building prompts for different datasets, such as InternVL2's handling of HallusionBench, it is necessary to specify `--model-name` when starting the server. This allows the VLMEvalKit to select appropriate prompt construction strategy based on the name when using the LMDeploy API. +> +> If `--server-port`, is specified, the corresponding environment variable `LMDEPLOY_API_BASE` needs to be set. + + +## Step 2: Evaluation + +```bash +python run.py --data MMStar --model lmdeploy --verbose --api-nproc 64 +``` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Makefile b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d4bb2cbb9eddb1bb1b4f366623044af8e4830919 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Quickstart.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..807d59b0ae4ba0a0595d653a70dbe281e92323d4 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/Quickstart.md @@ -0,0 +1,221 @@ +# Quickstart + +Before running the evaluation script, you need to **configure** the VLMs and set the model_paths properly. + +After that, you can use a single script `run.py` to inference and evaluate multiple VLMs and benchmarks at a same time. + +## Step 0. Installation & Setup essential keys + +**Installation.** + +```bash +git clone https://github.com/open-compass/VLMEvalKit.git +cd VLMEvalKit +pip install -e . +``` + +**Setup Keys.** + +To infer with API models (GPT-4v, Gemini-Pro-V, etc.) or use LLM APIs as the **judge or choice extractor**, you need to first setup API keys. VLMEvalKit will use an judge **LLM** to extract answer from the output if you set the key, otherwise it uses the **exact matching** mode (find "Yes", "No", "A", "B", "C"... in the output strings). **The exact matching can only be applied to the Yes-or-No tasks and the Multi-choice tasks.** +- You can place the required keys in `$VLMEvalKit/.env` or directly set them as the environment variable. If you choose to create a `.env` file, its content will look like: + + ```bash + # The .env file, place it under $VLMEvalKit + # API Keys of Proprietary VLMs + # QwenVL APIs + DASHSCOPE_API_KEY= + # Gemini w. Google Cloud Backends + GOOGLE_API_KEY= + # OpenAI API + OPENAI_API_KEY= + OPENAI_API_BASE= + # StepAI API + STEPAI_API_KEY= + # REKA API + REKA_API_KEY= + # GLMV API + GLMV_API_KEY= + # CongRong API + CW_API_BASE= + CW_API_KEY= + # SenseNova API + SENSENOVA_API_KEY= + # Hunyuan-Vision API + HUNYUAN_SECRET_KEY= + HUNYUAN_SECRET_ID= + # LMDeploy API + LMDEPLOY_API_BASE= + # You can also set a proxy for calling api models during the evaluation stage + EVAL_PROXY= + ``` + +- Fill the blanks with your API keys (if necessary). Those API keys will be automatically loaded when doing the inference and evaluation. +## Step 1. Configuration + +**VLM Configuration**: All VLMs are configured in `vlmeval/config.py`. Few legacy VLMs (like MiniGPT-4, LLaVA-v1-7B) requires additional configuration (configuring the code / model_weight root in the config file). During evaluation, you should use the model name specified in `supported_VLM` in `vlmeval/config.py` to select the VLM. Make sure you can successfully infer with the VLM before starting the evaluation with the following command `vlmutil check {MODEL_NAME}`. + +## Step 2. Evaluation + +**New!!!** We integrated a new config system to enable more flexible evaluation settings. Check the [Document](/docs/en/ConfigSystem.md) or run `python run.py --help` for more details 🔥🔥🔥 + +We use `run.py` for evaluation. To use the script, you can use `$VLMEvalKit/run.py` or create a soft-link of the script (to use the script anywhere): + +**Arguments** + +- `--data (list[str])`: Set the dataset names that are supported in VLMEvalKit (names can be found in the codebase README). +- `--model (list[str])`: Set the VLM names that are supported in VLMEvalKit (defined in `supported_VLM` in `vlmeval/config.py`). +- `--mode (str, default to 'all', choices are ['all', 'infer'])`: When `mode` set to "all", will perform both inference and evaluation; when set to "infer", will only perform the inference. +- `--api-nproc (int, default to 4)`: The number of threads for OpenAI API calling. +- `--work-dir (str, default to '.')`: The directory to save evaluation results. + +**Command for Evaluating Image Benchmarks ** + +You can run the script with `python` or `torchrun`: + +```bash +# When running with `python`, only one VLM instance is instantiated, and it might use multiple GPUs (depending on its default behavior). +# That is recommended for evaluating very large VLMs (like IDEFICS-80B-Instruct). + +# IDEFICS-80B-Instruct on MMBench_DEV_EN, MME, and SEEDBench_IMG, Inference and Evalution +python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct --verbose +# IDEFICS-80B-Instruct on MMBench_DEV_EN, MME, and SEEDBench_IMG, Inference only +python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct --verbose --mode infer + +# When running with `torchrun`, one VLM instance is instantiated on each GPU. It can speed up the inference. +# However, that is only suitable for VLMs that consume small amounts of GPU memory. + +# IDEFICS-9B-Instruct, Qwen-VL-Chat, mPLUG-Owl2 on MMBench_DEV_EN, MME, and SEEDBench_IMG. On a node with 8 GPU. Inference and Evaluation. +torchrun --nproc-per-node=8 run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct qwen_chat mPLUG-Owl2 --verbose +# Qwen-VL-Chat on MME. On a node with 2 GPU. Inference and Evaluation. +torchrun --nproc-per-node=2 run.py --data MME --model qwen_chat --verbose +``` + +**Command for Evaluating Video Benchmarks** + +```bash +# When running with `python`, only one VLM instance is instantiated, and it might use multiple GPUs (depending on its default behavior). +# That is recommended for evaluating very large VLMs (like IDEFICS-80B-Instruct). + +# IDEFICS2-8B on MMBench-Video, with 8 frames as inputs and vanilla evaluation. On a node with 8 GPUs. MMBench_Video_8frame_nopack is a defined dataset setting in `vlmeval/dataset/video_dataset_config.py`. +torchrun --nproc-per-node=8 run.py --data MMBench_Video_8frame_nopack --model idefics2_8 +# GPT-4o (API model) on MMBench-Video, with 1 frame per second as inputs and pack evaluation (all questions of a video in a single query). +python run.py --data MMBench_Video_1fps_pack --model GPT4o +``` + +The evaluation results will be printed as logs, besides. **Result Files** will also be generated in the directory `$YOUR_WORKING_DIRECTORY/{model_name}`. Files ending with `.csv` contain the evaluated metrics. + +### Frequently Asked Questions + +#### Constructing Input Prompt: The `build_prompt()` Function +If you find that the model's output does not match the expected results when evaluating a specific benchmark, it could be due to the model not constructing the input prompt correctly. + +In VLMEvalKit, each `dataset` class includes a function named `build_prompt()`, which is responsible for formatting input questions. Different benchmarks can either customize their own `build_prompt()` function or use the default implementation. + +For instance, when handling the default [Multiple-Choice QA](https://github.com/open-compass/VLMEvalKit/blob/43af13e052de6805a8b08cd04aed5e0d74f82ff5/vlmeval/dataset/image_mcq.py#L164), the `ImageMCQDataset.build_prompt()` method combines elements such as `hint`, `question`, and `options` (if present in the dataset) into a complete question format, as shown below: + +``` +HINT +QUESTION +Options: +A. Option A +B. Option B +··· +Please select the correct answer from the options above. +``` + +Additionally, since different models may have varying evaluation requirements, VLMEvalKit also supports customizing the prompt construction method at the model level through `model.build_prompt()`. For an example, you can refer to [InternVL](https://github.com/open-compass/VLMEvalKit/blob/43af13e052de6805a8b08cd04aed5e0d74f82ff5/vlmeval/vlm/internvl_chat.py#L324). + +**Note: If both `model.build_prompt()` and `dataset.build_prompt()` are defined, `model.build_prompt()` will take precedence over `dataset.build_prompt()`, effectively overriding it.** + +Some models, such as Qwen2VL and InternVL, define extensive prompt-building methods for various types of benchmarks. To provide more flexibility in adapting to different benchmarks, VLMEvalKit allows users to customize the `model.use_custom_prompt()` function within the model. By adding or modifying the `use_custom_prompt()` function, you can decide which benchmarks should utilize the model's custom prompt logic. Below is an example: + +```python +def use_custom_prompt(self, dataset: str) -> bool: + from vlmeval.dataset import DATASET_TYPE, DATASET_MODALITY + dataset_type = DATASET_TYPE(dataset, default=None) + if not self._use_custom_prompt: + return False + if listinstr(['MMVet'], dataset): + return True + if dataset_type == 'MCQ': + return True + if DATASET_MODALITY(dataset) == 'VIDEO': + return False + return False +``` +Only when the `use_custom_prompt()` function returns `True` will VLMEvalKit call the model's `build_prompt()` function for the current benchmark. +With this approach, you can flexibly control which benchmarks use the model's custom prompt logic based on your specific needs, thereby better adapting to different models and tasks. + +#### Model Splitting + +Currently, VLMEvalKit automatically supports GPU resource allocation and model splitting between processes on the same machine. This feature is supported when the inference backend is `lmdeploy` or `transformers`, with the following behaviors: + +- When launching with `python` command, the model is by default allocated to all available GPUs. If you want to specify which GPUs to use, you can use `CUDA_VISIBLE_DEVICES` environment variable. +- When starting with `torchrun` command, each model instance will be allocated to `N_GPU // N_PROC` GPUs, where `N_PROC` is the number of processes specified by the `--nproc-per-node` parameter in the torchrun command. The value of `N_GPU` is determined as follows: + - If `CUDA_VISIBLE_DEVICES` environment variable is not set, `N_GPU` will be the total number of available GPUs. + - If `CUDA_VISIBLE_DEVICES` environment variable is set, `N_GPU` will be the number of GPUs specified by the `CUDA_VISIBLE_DEVICES` environment variable, and only the specified GPUs will be utilized. +Below are specific examples of running evaluation tasks on a machine equipped with 8 GPUs: + +```bash + +torchrun --nproc-per-node=2 run.py --data MMBench_DEV_EN --model InternVL3-78B + +python run.py --data MMBench_DEV_EN --model InternVL3-78B + +CUDA_VISIBLE_DEVICES=1,2,3,4,5,6 torchrun --nproc-per-node=3 run.py --data MMBench_DEV_EN --model InternVL3-38B +``` + +PS: The feature is not compatible with `vllm` backend. When you evaluate a model with `vllm` backend, please use `python` to launch, and all visible GPU devices will be used. + +#### Performance Discrepancies + +Model performance may vary across different environments. As a result, you might observe discrepancies between your evaluation results and those listed on the official VLMEvalKit leaderboard. These differences could be attributed to variations in versions of libraries such as `transformers`, `cuda`, and `torch`. + +Besides, if you encounter unexpected performance, we recommend first reviewing the local generation records (`{model}_{dataset}.xlsx`) or the evaluation records (`{model}_{dataset}_{judge_model}.xlsx`). This may help you better understand the evaluation outcomes and identify potential issues. + +## Deploy a local language model as the judge / choice extractor +The default setting mentioned above uses OpenAI's GPT as the judge LLM. However, you can also deploy a local judge LLM with [LMDeploy](https://github.com/InternLM/lmdeploy). + +First install: +``` +pip install lmdeploy openai +``` + +And then deploy a local judge LLM with the single line of code. LMDeploy will automatically download the model from Huggingface. Assuming we use internlm2-chat-1_8b as the judge, port 23333, and the key sk-123456 (the key must start with "sk-" and follow with any number you like): +``` +lmdeploy serve api_server internlm/internlm2-chat-1_8b --server-port 23333 +``` + +You need to get the model name registered by LMDeploy with the following python code: +``` +from openai import OpenAI +client = OpenAI( + api_key='sk-123456', + base_url="http://0.0.0.0:23333/v1" +) +model_name = client.models.list().data[0].id +``` + +Now set some environment variables to tell VLMEvalKit how to use the local judge LLM. As mentioned above, you can also set them in `$VLMEvalKit/.env` file: +``` +OPENAI_API_KEY=sk-123456 +OPENAI_API_BASE=http://0.0.0.0:23333/v1/chat/completions +LOCAL_LLM= +``` + +Finally, you can run the commands in step 2 to evaluate your VLM with the local judge LLM. + +Note that + +- If you hope to deploy the judge LLM in a single GPU and evaluate your VLM on other GPUs because of limited GPU memory, try `CUDA_VISIBLE_DEVICES=x` like +``` +CUDA_VISIBLE_DEVICES=0 lmdeploy serve api_server internlm/internlm2-chat-1_8b --server-port 23333 +CUDA_VISIBLE_DEVICES=1,2,3 torchrun --nproc-per-node=3 run.py --data HallusionBench --model qwen_chat --verbose +``` +- If the local judge LLM is not good enough in following the instructions, the evaluation may fail. Please report such failures (e.g., by issues). +- It's possible to deploy the judge LLM in different ways, e.g., use a private LLM (not from HuggingFace) or use a quantized LLM. Please refer to the [LMDeploy doc](https://lmdeploy.readthedocs.io/en/latest/serving/api_server.html). You can use any other deployment framework if they support OpenAI API. + + +### Using LMDeploy to Accelerate Evaluation and Inference + +You can refer this [doc](/docs/en/EvalByLMDeploy.md) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/css/readthedocs.css b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/css/readthedocs.css new file mode 100644 index 0000000000000000000000000000000000000000..c83beffd261d9d7cb79dc499aec7187474639d89 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/css/readthedocs.css @@ -0,0 +1,63 @@ +.header-logo { + background-image: url("../image/logo.svg"); + background-size: 275px 80px; + height: 80px; + width: 275px; +} + + +@media screen and (min-width: 1100px) { + .header-logo { + top: -25px; + } +} + +pre { + white-space: pre; +} + +@media screen and (min-width: 2000px) { + .pytorch-content-left { + width: 1200px; + margin-left: 30px; + } + article.pytorch-article { + max-width: 1200px; + } + .pytorch-breadcrumbs-wrapper { + width: 1200px; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 1580px; + } +} + + +article.pytorch-article section code { + padding: .2em .4em; + background-color: #f3f4f7; + border-radius: 5px; +} + +/* Disable the change in tables */ +article.pytorch-article section table code { + padding: unset; + background-color: unset; + border-radius: unset; +} + +table.autosummary td { + width: 50% +} + +img.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +article.pytorch-article p.rubric { + font-weight: bold; +} diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo.svg b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..043530572afb48d0eac26b4b53d448aae6e9a9af --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo.svg @@ -0,0 +1,24 @@ + + + +Created with Fabric.js 5.3.0 + + + + + + + + + + + + + VLMEvalKit + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo_icon.svg b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo_icon.svg new file mode 100644 index 0000000000000000000000000000000000000000..c46dd3b5407c1f82dce4f6096acf8c8a30a6cfba --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/image/logo_icon.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/js/custom.js b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/js/custom.js new file mode 100644 index 0000000000000000000000000000000000000000..84da69d47fae8e8994685aca3b99151d01a77978 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_static/js/custom.js @@ -0,0 +1,10 @@ +var collapsedSections = []; + +$(document).ready(function () { + $('.model-summary').DataTable({ + "stateSave": false, + "lengthChange": false, + "pageLength": 20, + "order": [] + }); +}); diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/404.html b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/404.html new file mode 100644 index 0000000000000000000000000000000000000000..64910175d5d69946845b04d5e6a378de205e8388 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/404.html @@ -0,0 +1,18 @@ +{% extends "layout.html" %} + +{% block body %} + +

Page Not Found

+

+ The page you are looking for cannot be found. +

+

+ If you just switched documentation versions, it is likely that the page you were on is moved. You can look for it in + the content table left, or go to the homepage. +

+ + +{% endblock %} diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/autosummary/class.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/autosummary/class.rst new file mode 100644 index 0000000000000000000000000000000000000000..4c3a7a9abf5c5b14ac3ef3b00a2f070480295358 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/autosummary/class.rst @@ -0,0 +1,13 @@ +.. role:: hidden + :class: hidden-section +.. currentmodule:: {{ module }} + + +{{ name | underline}} + +.. autoclass:: {{ name }} + :members: + +.. + autogenerated from _templates/autosummary/class.rst + note it does not have :inherited-members: diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/callable.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/callable.rst new file mode 100644 index 0000000000000000000000000000000000000000..3a7b9d2b96c76dfa3eb1d8bef56f58f219fe7760 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/_templates/callable.rst @@ -0,0 +1,14 @@ +.. role:: hidden + :class: hidden-section +.. currentmodule:: {{ module }} + + +{{ name | underline}} + +.. autoclass:: {{ name }} + :members: + :special-members: __call__ + +.. + autogenerated from _templates/callable.rst + note it does not have :inherited-members: diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/conf.py b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..360c1622dd18fcca8c033af9122383cd66c5f686 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/conf.py @@ -0,0 +1,234 @@ +# flake8: noqa +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import ast +import subprocess +import sys + +import pytorch_sphinx_theme +from sphinx.builders.html import StandaloneHTMLBuilder + +sys.path.insert(0, os.path.abspath('../../')) + +# -- Project information ----------------------------------------------------- + +project = 'VLMEvalKit' +copyright = '2023, VLMEvalKit' +author = 'VLMEvalKit Authors' + +# The full version, including alpha/beta/rc tags +version_file = '../../vlmeval/__init__.py' + + +def get_version(): + with open(version_file, 'r') as f: + file_content = f.read() + # Parse the file content into an abstract syntax tree (AST) + tree = ast.parse(file_content, filename=version_file) + + # Iterate through the body of the AST, looking for an assignment to __version__ + for node in tree.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == '__version__': + return node.value.s + raise ValueError('__version__ not found') + + +release = get_version() + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', + 'sphinx.ext.viewcode', + 'myst_parser', + 'sphinx_copybutton', + 'sphinx_tabs.tabs', + 'notfound.extension', + 'sphinxcontrib.jquery', + 'sphinx_design', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +language = 'en' + +# The master toctree document. +root_doc = 'index' +html_context = { + 'github_version': 'latest', +} +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'pytorch_sphinx_theme' +html_theme_path = [pytorch_sphinx_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# yapf: disable +html_theme_options = { + 'menu': [ + { + 'name': 'GitHub', + 'url': 'https://github.com/open-compass/VLMEvalKit' + }, + ], + # Specify the language of shared menu + 'menu_lang': 'en', + # Disable the default edit on GitHub + 'default_edit_on_github': False, +} +# yapf: enable + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +html_css_files = [ + 'https://cdn.datatables.net/v/bs4/dt-1.12.1/datatables.min.css', + 'css/readthedocs.css' +] +html_js_files = [ + 'https://cdn.datatables.net/v/bs4/dt-1.12.1/datatables.min.js', + 'js/custom.js' +] + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'vlmevalkitdoc' + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (root_doc, 'vlmevalkit.tex', 'VLMEvalKit Documentation', author, + 'manual'), +] + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(root_doc, 'vlmevalkit', 'VLMEvalKit Documentation', [author], + 1)] + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (root_doc, 'vlmevalkit', 'VLMEvalKit Documentation', author, + 'VLMEvalKit Authors', 'AGI evaluation toolbox and benchmark.', + 'Miscellaneous'), +] + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# set priority when building html +StandaloneHTMLBuilder.supported_image_types = [ + 'image/svg+xml', 'image/gif', 'image/png', 'image/jpeg' +] + +# -- Extension configuration ------------------------------------------------- +# Ignore >>> when copying code +copybutton_prompt_text = r'>>> |\.\.\. ' +copybutton_prompt_is_regexp = True + +# Auto-generated header anchors +myst_heading_anchors = 3 +# Enable "colon_fence" extension of myst. +myst_enable_extensions = ['colon_fence', 'dollarmath'] + +# Configuration for intersphinx +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'numpy': ('https://numpy.org/doc/stable', None), + 'torch': ('https://pytorch.org/docs/stable/', None), + 'mmengine': ('https://mmengine.readthedocs.io/en/latest/', None), + 'transformers': + ('https://huggingface.co/docs/transformers/main/en/', None), +} +napoleon_custom_sections = [ + # Custom sections for data elements. + ('Meta fields', 'params_style'), + ('Data fields', 'params_style'), +] + +# Disable docstring inheritance +autodoc_inherit_docstrings = False +# Mock some imports during generate API docs. +autodoc_mock_imports = ['rich', 'attr', 'einops'] +# Disable displaying type annotations, these can be very verbose +autodoc_typehints = 'none' + +# The not found page +notfound_template = '404.html' diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/docutils.conf b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/docutils.conf new file mode 100644 index 0000000000000000000000000000000000000000..0c00c84688701117f231fd0c8ec295fb747b7d8f --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/docutils.conf @@ -0,0 +1,2 @@ +[html writers] +table_style: colwidths-auto diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/en/index.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..425c7de4de85670f8fd7a64d65fb786a9006f7e1 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/en/index.rst @@ -0,0 +1,41 @@ +Welcome to the VLMEvalKit Tutorial! +========================================== + +VLMEvalKit Getting Started Guide +------------------------------- + +To help users get started quickly, we recommend the following process: + +- For users who want to use VLMEvalKit, we recommend reading the "Start Your First Step" section to set up the environment and start a mini-experiment to familiarize yourself with the process. + +- If you want to customize more modules, such as adding datasets and models, we provide an "Advanced Tutorial." + +We always welcome users' PRs (Pull Requests) and Issues to improve VLMEvalKit! + +.. _Start Your First Step: +.. toctree:: + :maxdepth: 1 + :caption: Start Your First Step + + Quickstart.md + +.. _Advanced Tutorial: +.. toctree:: + :maxdepth: 1 + :caption: Advanced Tutorial + + Development.md + ConfigSystem.md + +.. _Other Notes: +.. toctree:: + :maxdepth: 1 + :caption: Other Notes + + Contributors.md + +Index and Tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/ja/README_ja.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/ja/README_ja.md new file mode 100644 index 0000000000000000000000000000000000000000..5bf9564b098bec3748712b150d555ef963c400b9 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/ja/README_ja.md @@ -0,0 +1,117 @@ +
+ +![LOGO](http://opencompass.openxlab.space/utils/MMLB.jpg) + +VLMEvalKit: 大規模視覚言語モデルの評価ツールキット + +[![][github-contributors-shield]][github-contributors-link] • [![][github-forks-shield]][github-forks-link] • [![][github-stars-shield]][github-stars-link] • [![][github-issues-shield]][github-issues-link] • [![][github-license-shield]][github-license-link] + +[English](/README.md) | [简体中文](/docs/zh-CN/README_zh-CN.md) | 日本語 + +🏆 OpenCompass Learderboard • +📊Datasets & Models • +🏗️Quickstart • +🛠️Development • +🎯Goal • +🖊️Citation + +🤗 HF Leaderboard • +🤗 Evaluation Records • +🔊 Discord Channel • +📝 Technical Report +
+ +**VLMEvalKit**(pythonパッケージ名は**vlmeval**)は、**大規模視覚言語モデル(LVLMs)**の**オープンソース評価ツールキット**です。このツールキットは、複数のリポジトリでのデータ準備という重労働なしに、さまざまなベンチマークでLVLMsの**ワンコマンド評価**を可能にします。VLMEvalKitでは、すべてのLVLMsに対して**生成ベースの評価**を採用し、**正確なマッチング**と**LLMベースの回答抽出**の両方で得られた評価結果を提供します。 + +PS: 日本語の README には最新のアップデートがすべて含まれていない場合があります。英語版をご確認ください。 + +## 📊 データセット、モデル、および評価結果 + +**公式のマルチモーダルリーダーボードでのパフォーマンス数値は、ここからダウンロードできます!** + +[**OpenVLM Leaderboard**](https://huggingface.co/spaces/opencompass/open_vlm_leaderboard): [すべての詳細な結果をダウンロード](http://opencompass.openxlab.space/assets/OpenVLM.json)。 + +**Supported Benchmarks** in [**VLMEvalKit Features**](https://aicarrier.feishu.cn/wiki/Qp7wwSzQ9iK1Y6kNUJVcr6zTnPe?table=tblsdEpLieDoCxtb) を確認して、すべてのサポートされているベンチマーク(70以上)を表示してください。 + +**Supported LMMs** in [**VLMEvalKit Features**](https://aicarrier.feishu.cn/wiki/Qp7wwSzQ9iK1Y6kNUJVcr6zTnPe?table=tblsdEpLieDoCxtb) を確認して、すべてのサポートされている LMMs(200以上)を表示してください。 + +**Transformersバージョンの推奨事項:** + +特定のtransformerバージョンで一部のVLMが実行できない可能性があることに注意してください。各VLMを評価するために、以下の設定を推奨します: + +- **`transformers==4.33.0`を使用してください**: `Qwenシリーズ`, `Monkeyシリーズ`, `InternLM-XComposerシリーズ`, `mPLUG-Owl2`, `OpenFlamingo v2`, `IDEFICSシリーズ`, `VisualGLM`, `MMAlaya`, `ShareCaptioner`, `MiniGPT-4シリーズ`, `InstructBLIPシリーズ`, `PandaGPT`, `VXVERSE`, `GLM-4v-9B`. +- **`transformers==4.37.0`を使用してください**: `LLaVAシリーズ`, `ShareGPT4Vシリーズ`, `TransCore-M`, `LLaVA (XTuner)`, `CogVLMシリーズ`, `EMU2シリーズ`, `Yi-VLシリーズ`, `MiniCPM-[V1/V2]`, `OmniLMM-12B`, `DeepSeek-VLシリーズ`, `InternVLシリーズ`, `Cambrianシリーズ`, `VILA-VLシリーズ`. +- **`transformers==4.40.0`を使用してください**: `IDEFICS2`, `Bunny-Llama3`, `MiniCPM-Llama3-V2.5`, `360VL-70B`, `Phi-3-Vision`, `WeMM`. +- **`transformers==4.42.0`を使用してください**: `AKI`. +- **`transformers==latest`を使用してください**: `LLaVA-Nextシリーズ`, `PaliGemma-3B`, `Chameleon-VLシリーズ`, `Video-LLaVA-7B-HF`, `Ovis1.5シリーズ`, `Mantisシリーズ`, `MiniCPM-V2.6`. + +```python +# デモ +from vlmeval.config import supported_VLM +model = supported_VLM['idefics_9b_instruct']() +# 単一画像のフォワード +ret = model.generate(['assets/apple.jpg', 'この画像には何がありますか?']) +print(ret) # この画像には葉がついた赤いリンゴがあります。 +# 複数画像のフォワード +ret = model.generate(['assets/apple.jpg', 'assets/apple.jpg', '提供された画像にはリンゴが何個ありますか?']) +print(ret) # 提供された画像にはリンゴが2個あります。 +``` + +## 🏗️ クイックスタート + +クイックスタートガイドについては、[クイックスタート](/docs/en/Quickstart.md)を参照してください。 + +## 🛠️ 開発ガイド + +カスタムベンチマーク、VLMsを開発するか、単に**VLMEvalKit**に他のコードを貢献する場合は、[開発ガイド](/docs/en/Development.md)を参照してください。 + +コミュニティからの共有を奨励し、それに応じたクレジットを共有するために、次回のレポート更新では以下のことを実施します: + +- 全ての貢献に対して感謝の意を示します +- 新しいモデル、評価セット、または主要な機能への3つ以上の主要な貢献を持つ貢献者は、テクニカルレポートの著者リストに加わることができます。適格な貢献者は、issueを作成するか、または[VLM評価キット ディスコードチャンネル](https://discord.com/invite/evDT4GZmxN)で kennyutc にDMを送ることができます。私たちはそれに応じてフォローアップします。 + +## 🎯 VLMEvalKitの目標 + +**このコードベースは以下を目的として設計されています:** + +1. 研究者や開発者が既存のLVLMsを評価し、評価結果を**簡単に再現できるようにする**ための**使いやすい**、**オープンソースの評価ツールキット**を提供します。 +2. VLMの開発者が自分のモデルを簡単に評価できるようにします。複数のサポートされているベンチマークでVLMを評価するには、単一の`generate_inner()`関数を**実装するだけで**、他のすべてのワークロード(データのダウンロード、データの前処理、予測の推論、メトリックの計算)はコードベースによって処理されます。 + +**このコードベースは以下を目的として設計されていません:** + +1. すべての**第三者ベンチマーク**の元の論文で報告された正確な精度数値を再現すること。その理由は2つあります: + 1. VLMEvalKitは、すべてのVLMに対して**生成ベースの評価**を使用します(オプションで**LLMベースの回答抽出**を使用)。一方、一部のベンチマークは異なるアプローチを使用する場合があります(SEEDBenchはPPLベースの評価を使用します)。これらのベンチマークについては、対応する結果で両方のスコアを比較します。開発者には、コードベースで他の評価パラダイムをサポートすることをお勧めします。 + 2. デフォルトでは、すべてのVLMに対して同じプロンプトテンプレートを使用してベンチマークを評価します。一方、**一部のVLMには特定のプロンプトテンプレートがある**場合があります(現時点ではコードベースでカバーされていない場合があります)。VLMの開発者には、現在カバーされていない場合でも、VLMEvalKitで独自のプロンプトテンプレートを実装することをお勧めします。これにより、再現性が向上します。 + +## 🖊️ 引用 + +この作業が役立つ場合は、このリポジトリに**スター🌟**を付けてください。サポートありがとうございます! + +[![Stargazers repo roster for @open-compass/VLMEvalKit](https://reporoster.com/stars/open-compass/VLMEvalKit)](https://github.com/open-compass/VLMEvalKit/stargazers) + +研究でVLMEvalKitを使用する場合、または公開されたオープンソースの評価結果を参照する場合は、以下のBibTeXエントリと、使用した特定のVLM/ベンチマークに対応するBibTexエントリを使用してください。 + +```bib +@misc{duan2024vlmevalkit, + title={VLMEvalKit: An Open-Source Toolkit for Evaluating Large Multi-Modality Models}, + author={Haodong Duan and Junming Yang and Yuxuan Qiao and Xinyu Fang and Lin Chen and Yuan Liu and Xiaoyi Dong and Yuhang Zang and Pan Zhang and Jiaqi Wang and Dahua Lin and Kai Chen}, + year={2024}, + eprint={2407.11691}, + archivePrefix={arXiv}, + primaryClass={cs.CV}, + url={https://arxiv.org/abs/2407.11691}, +} +``` + +

🔝Top に戻る

+ +[github-contributors-link]: https://github.com/open-compass/VLMEvalKit/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/open-compass/VLMEvalKit?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/open-compass/VLMEvalKit/network/members +[github-forks-shield]: https://img.shields.io/github/forks/open-compass/VLMEvalKit?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/open-compass/VLMEvalKit/issues +[github-issues-shield]: https://img.shields.io/github/issues/open-compass/VLMEvalKit?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/open-compass/VLMEvalKit/blob/main/LICENSE +[github-license-shield]: https://img.shields.io/github/license/open-compass/VLMEvalKit?color=white&labelColor=black&style=flat-square +[github-stars-link]: https://github.com/open-compass/VLMEvalKit/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/open-compass/VLMEvalKit?color=ffcb47&labelColor=black&style=flat-square diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/.readthedocs.yaml b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/.readthedocs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b7e46fe34090d74f165034fb5bed93f2f112f42b --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/.readthedocs.yaml @@ -0,0 +1,17 @@ +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.8" + +formats: + - epub + +sphinx: + configuration: docs/zh-CN/conf.py + +python: + install: + - requirements: requirements/docs.txt diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/ConfigSystem.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/ConfigSystem.md new file mode 100644 index 0000000000000000000000000000000000000000..14e8d49564ec5956bb6b31b3bab161be2cee402b --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/ConfigSystem.md @@ -0,0 +1,69 @@ + +# 配置系统 + +默认情况下,VLMEvalKit通过在`run.py`脚本中使用`--model`和`--data`参数设置模型名称(在`/vlmeval/config.py`中定义)和数据集名称(在`vlmeval/dataset/__init__.py` 或 `vlmeval/dataset/video_dataset_config.py` 中定义)来启动评估。这种方法在大多数情况下简单且高效,但当用户希望使用不同设置评估多个模型/数据集时,可能不够灵活。 + +为了解决这个问题,VLMEvalKit提供了一个更灵活的配置系统。用户可以在json文件中指定模型和数据集设置,并通过`--config`参数将配置文件的路径传递给`run.py`脚本。以下是一个示例配置json: + +```json +{ + "model": { + "GPT4o_20240806_T00_HIGH": { + "class": "GPT4V", + "model": "gpt-4o-2024-08-06", + "temperature": 0, + "img_detail": "high" + }, + "GPT4o_20240806_T10_Low": { + "class": "GPT4V", + "model": "gpt-4o-2024-08-06", + "temperature": 1.0, + "img_detail": "low" + }, + "GPT4o_20241120": {} + }, + "data": { + "MME-RealWorld-Lite": { + "class": "MMERealWorld", + "dataset": "MME-RealWorld-Lite" + }, + "MMBench_DEV_EN_V11": { + "class": "ImageMCQDataset", + "dataset": "MMBench_DEV_EN_V11" + }, + "MMBench_Video_8frame_nopack":{}, + "Video-MME_16frame_subs": { + "class": "VideoMME", + "dataset": "Video-MME", + "nframe": 16, + "use_subtitle": true + } + } +} +``` + +配置json的解释: + +1. 现在我们支持两个字段:`model`和`data`,每个字段都是一个字典。字典的键是模型/数据集的名称(由用户设置),值是模型/数据集的设置。 +2. 对于`model`中的项目,值是一个包含以下键的字典: + - `class`:模型的类名,应该是`vlmeval/vlm/__init__.py`(开源模型)或`vlmeval/api/__init__.py`(API模型)中定义的类名。 + - 其他kwargs:其他kwargs是模型特定的参数,请参考模型类的定义以获取详细用法。例如,`model`、`temperature`、`img_detail`是`GPT4V`类的参数。值得注意的是,大多数模型类都需要`model`参数。 + - Tip:在位于`vlmeval/config.py`的变量`supported_VLM`中的已经被定义的模型可以作为`model`的键,而不需要填对应的值即可启动。例如,`GPT4o_20240806_T00_HIGH: {}`是等价于`GPT4o_20240806_T00_HIGH: {'class': 'GPT4V', 'model': 'gpt-4o-2024-08-06', 'temperature': 0, 'img_size': -1, 'img_detail': 'high', 'retry': 10, 'verbose': False}`。 +3. 对于字典`data`,我们建议用户使用官方数据集名称作为键(或键的一部分),因为我们经常根据数据集名称确定后处理/判断设置。对于`data`中的项目,值是一个包含以下键的字典: + - `class`:数据集的类名,应该是`vlmeval/dataset/__init__.py`中定义的类名。 + - 其他kwargs:其他kwargs是数据集特定的参数,请参考数据集类的定义以获取详细用法。通常,大多数数据集类都需要`dataset`参数。大多数视频数据集类都需要 `nframe` 或 `fps` 参数。 + - Tip:在位于`vlmeval/dataset/video_dataset_config.py`的变量`supported_video_dataset`中的已经被定义的数据集可以作为`data`的键,而不需要填对应的值即可启动。例如,`MMBench_Video_8frame_nopack: {}`是等价于`MMBench_Video_8frame_nopack: {'class': 'MMBenchVideo', 'dataset': 'MMBench-Video', 'nframe': 8, 'pack': False}`。 + +将示例配置json保存为`config.json`,您可以通过以下命令启动评估: + +```bash +python run.py --config config.json +``` + +这将在工作目录`$WORK_DIR`下生成以下输出文件(格式为`{$WORK_DIR}/{$MODEL_NAME}/{$MODEL_NAME}_{$DATASET_NAME}_*`): + +- `$WORK_DIR/GPT4o_20240806_T00_HIGH/GPT4o_20240806_T00_HIGH_MME-RealWorld-Lite*` +- `$WORK_DIR/GPT4o_20240806_T10_Low/GPT4o_20240806_T10_Low_MME-RealWorld-Lite*` +- `$WORK_DIR/GPT4o_20240806_T00_HIGH/GPT4o_20240806_T00_HIGH_MMBench_DEV_EN_V11*` +- `$WORK_DIR/GPT4o_20240806_T10_Low/GPT4o_20240806_T10_Low_MMBench_DEV_EN_V11*` +...... diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Development.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Development.md new file mode 100644 index 0000000000000000000000000000000000000000..69db06498d30354aac0720063589069587a89301 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Development.md @@ -0,0 +1,139 @@ +# 🛠️ 如何在 VLMEvalKit 中实现一个新的 Benchmark 或多模态模型(VLM) + +## 实现一个新的 benchmark + +示例 PR: **添加 Math-Vision Benchmark** ([#292](https://github.com/open-compass/VLMEvalKit/pull/292/files)) + +目前在 VLMEvalKit 中,benchmark 以数据集类的形式呈现,当你新增一个 benchmark 时,你可以选择复用现有的数据集类 (如单选题 benchmark 可复用 `ImageMCQDataset`),或是实现新的数据集类。你的数据集类必须支持以下两种方法 (复用父类或自行实现): + +- `build_prompt(self, line)`: 方法输入 `line` 类型为 int (对应数据 index) 或 `pd.Series` (对应数据原始 record)。方法输出一条 `multi-modal message` 作为多模态模型输入,`multi-modal message` 是一个图文交错的列表,如以下格式 (一图一文): `[dict(type='image', value=IMAGE_PTH), dict(type='text', value=prompt)]`。 +- `evaluate(self, eval_file, **judge_kwargs)`: 方法输入 `eval_file` 为多模态模型的预测结果 (多以 `.xlsx` 格式存在),如 benchmark evaluation 需要大语言模型 (一般为 GPT) 辅助,则 `judge_kwargs` 传入大语言模型的参数。方法输出 benchmark 的评测结果,以 `dict` 或 `pd.DataFrame` 的形式。 + +以下,我们简述新增数据集的通常步骤: + +### 1. TSV 数据文件准备 (图文评测集) + +目前,我们将每一个 benchmark 数据集设置为一个单独的 TSV 文件。在推理过程中,数据文件将从数据集定义的 `DATASET_URL` 链接地址自动下载到 `$LMUData` 中(如果没有明确设置的话,默认路径是 `$HOME/LMUData`)。你可以将准备好的 TSV 文件上传到一个可下载的地址(如:huggingface),或发送给我们 ,我们将帮助上传数据集到服务器中。此外,你也可以在环境变量中自定义设置下载路径 `LMUData=/path/to/your/data`。 + +TSV 文件中的内容组成为: + +| 数据集名称 \ 字段 | index | image | image_path | question | hint | multi-choice
options | answer | category | l2-category | split | +| ---------------------- | ----- | ----- | ---------- | -------- | ---- | ----------------------- | ------ | -------- | ----------- | ----- | +| MMBench_DEV_[CN/EN] | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| MMBench_TEST_[CN/EN] | ✅ | ✅ | | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | +| CCBench | ✅ | ✅ | | ✅ | | ✅ | ✅ | ✅ | | | +| SEEDBench_IMG | ✅ | ✅ | | ✅ | | ✅ | ✅ | ✅ | | | +| MME | ✅ | ✅ | | ✅ | | | ✅ | ✅ | | | +| MMVet | ✅ | ✅ | | ✅ | | | ✅ | ✅ | | | +| MMMU_DEV_VAL | ✅ | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | +| COCO_VAL | ✅ | ✅ | | | | | ✅ | | | | +| OCRVQA_[TEST/TESTCORE] | ✅ | ✅ | | ✅ | | | ✅ | | | | +| TextVQA_VAL | ✅ | ✅ | | ✅ | | | ✅ | | | | +| VCR_[EN/ZH]\_[EASY/HARD]_[ALL/500/100] | ✅ | ✅ | | ✅ | | | ✅ | | | | + +
表 1. 支持的数据集的 TSV 字段。
+ +**TSV 中必须字段的介绍:** + +- **index:** 一个整数,`tsv` 中每一行的唯一标识 +- **image:** 图片的 base64 编码,你可以使用 `vlmeval/smp/vlm.py` 中实现的API进行编码和解码: + - 编码:`encode_image_to_base64`(对于PIL Image)/ `encode_image_file_to_base64`(对于图片文件路径) + - 解码:`decode_base64_to_image`(对于PIL Image)/ `decode_base64_to_image_file`(对于图片文件路径) +- **question:** 针对图像所提取出的问题,类型为字符串 +- **answer:** 问题的答案,类型为字符串,Test 集可缺失这一字段 + +### 2. 自定义数据集的 prompt 构建 + +`ImageBaseDataset` 定义了默认的 prompt 格式。如果需要针对数据集添加 prompt,或给模型输入 `Interleave` 的数据格式,可以通过 `build_prompt(line)` 函数实现。该函数输入为,每次给定 TSV 文件中的一行,包含 index, image, question 等内容作为 line。该函数将返回一个多模态消息 `msg` 的字典列表 `[dict(type='image', value=IMAGE_PTH), dict(type='text', value=prompt)]`,包括图片路径和将被输入到 VLMs 的文本 prompt。对于 interleave 类型输入,可以直接将图片路径的字典放置到 image token 位置。 + +### 3. 自定义数据集的指标实现 + +增加对 benchmark 的评测需要自定义一个该数据集的 class 对象,从而实现数据集的指标计算。图文多模态数据集均继承自 `vlmeval/dataset/image_base.py` 中的 `ImageBaseDataset` 对象。其中 `TYPE` 定义了数据集的类型;`DATASET_URL` 为数据集的下载地址;`DATASET_MD5` 为数据集文件的 md5 一致性编码检查。 + +在 class 中**需要实现** `evaluate(eval_file, **judge_kwargs)` 类函数,对自定义的数据集结果进行指标计算和结果输出。函数输入 `eval_file` 为模型预测结果 `{model_name}_{dataset}.xlsx` 的路径。可以通过 `load(eval_file)` 文件将其读取为 panda.DataFrames 类型,其中包含 index, question, answer, category, prediction 等字段。`judge_kwargs` 参数将传递一个评测相关的字典,如:judge 模型的名称,api 请求线程数等。**函数的返回值**为评估完成的准确度等指标,其格式为由 list 组成的字典,并组织成 panda.DataFrames 类型。 + +## 实现一个新的模型 + +示例 PR: **支持 LLaVA-Next-Interleave** ([#294](https://github.com/open-compass/VLMEvalKit/pull/294)) + +**1. 支持 `generate_inner` API (必须)** + +现有所有的模型都在 `vlmeval/vlm` 中实现。对于一个最基本的模型,你的模型类**应该实现方法** `generate_inner(msgs, dataset=None)`。这个函数将向 VLM 输入一个多模态数据,并返回 VLM 的预测(一个字符串)。可选参数 `dataset` 可以用作模型在不同推理策略之间切换的标志。 + +其中多模态消息 `msgs` 是一个字典列表,每个字典有两个键:类型和值: +- `type`:我们目前支持两种类型,选项是 ["image", "text"]。 +- `value`:当类型为 `text` 时,值是文本消息(一个字符串);当类型为 `image` 时,值可以是图像文件的本地路径,或者是图像的URL。 + +> 目前,一个多模态消息可能包含任意交错的图像和文本。如果你的模型不支持这一点,我们推荐的做法是取第一张图像和连接的文本消息作为模型的输入。你可以在模型的 class 中设置 `INTERLEAVE = False` 并调用 `self.message_to_promptimg(message, dataset=dataset)` 函数来获取你的 prompt 和第一张图片的地址。 + +一些多模态消息的例子: + +```python +IMAGE_PTH = 'assets/apple.jpg' +IMAGE_URL = 'https://raw.githubusercontent.com/open-compass/VLMEvalKit/main/assets/apple.jpg' +msg1 = [ + dict(type='image', value=IMAGE_PTH), + dict(type='text', value='What is in this image?') +] +msg2 = [ + dict(type='image', value=IMAGE_URL), + dict(type='image', value=IMAGE_URL), + dict(type='text', value='How many apples are there in these images?') +] +response = model.generate(msg1) +``` + +为了方便起见,我们还支持接受字符串列表作为输入。在这种情况下,我们将检查一个字符串是图像路径还是图像 URL,并自动将其转换为 `list[dict]` 格式: + +```python +IMAGE_PTH = 'assets/apple.jpg' +IMAGE_URL = 'https://raw.githubusercontent.com/open-compass/VLMEvalKit/main/assets/apple.jpg' +msg1 = [IMAGE_PTH, 'What is in this image?'] +msg2 = [IMAGE_URL, IMAGE_URL, 'How many apples are there in these images?'] +response = model.generate(msg1) +``` + +**2. 支持自定义提示词构建 (可选)** + +此外,你的模型可以通过实现两个可选方法来支持自定义提示构建:`use_custom_prompt(dataset)` 和 `build_prompt(line, dataset=None)`。 + +- `use_custom_prompt(dataset)` 将返回一个布尔值,指示模型是否应使用自定义提示构建策略。 +- 如果`use_custom_prompt(dataset)`返回 True,`build_prompt(line, dataset)` 应该为相应的数据集返回一个自定义构建的多模态消息,line 数据是一个包含数据样本所需信息的字典。如果`use_custom_prompt(dataset)` 返回False,则将使用默认的 prompt 构建策略。 + +**3. 支持多轮对话 (可选)** + +你可以通过支持 `chat_inner(message, dataset)` API 为你的模型新增多轮对话功能并兼容多轮对话评测。这个 API 输出一个字符串型回复,`message` 包含一个聊天记录的列表,格式如下: + +```python +# Assume msg1, msg2, msg3, ... are multi-modal messages following the previously described format +# `chat_inner` take the following chat history list as input: +message = [ + dict(role='user', content=msg1), + dict(role='assistant', content=msg2), + dict(role='user', content=msg3), + dict(role='assistant', content=msg4), + ...... + dict(role='user', content=msgn), +] +# `message` should contain an odd number of chat utterances, the role of utterances should be interleaved "user" and "assistant", with the role of the last utterance to be "user". +# The chat function will call `chat_inner` +response = model.chat(message) +``` + +### 示例 PRs: + +- 不支持交错的图像和文本,且不使用自定义提示的VLM:[[模型] 支持 glm-4v-9b](https://github.com/open-compass/VLMEvalKit/pull/221) +- 支持交错的图像和文本及自定义提示的VLM:[添加 MiniCPM-Llama3-V-2.5](https://github.com/open-compass/VLMEvalKit/pull/205) +- VLM API:[特征添加 glmv](https://github.com/open-compass/VLMEvalKit/pull/201) + +## 为 VLMEvalKit 贡献代码 + +如果你想为 **VLMEvalKit** 贡献代码,请在提交PR之前进行预提交检查。这有助于保持代码整洁。 + +```bash +# 在VLMEvalKit的目录下,安装预提交 hook: +pip install pre-commit +pre-commit install +pre-commit run --all-files +# 然后提交你的代码。 +``` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/EvalByLMDeploy.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/EvalByLMDeploy.md new file mode 100644 index 0000000000000000000000000000000000000000..cdb46c70f0cc9d2620e0a98471f0c9b354472518 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/EvalByLMDeploy.md @@ -0,0 +1,28 @@ +# 使用 LMDeploy 加速评测推理 + +VLMEvalKit 支持测试由 LMDeploy 部署的 VLM 模型,下面以 InternVL2-8B 为例,展示如何测试模型 + +## 第0步 安装 LMDeploy + +```bash +pip install lmdeploy +``` + +其他安装方式可以参考 LMDeploy 的[文档](https://github.com/InternLM/lmdeploy) + +## 第1步 启动推理服务 + +```bash +lmdeploy serve api_server OpenGVLab/InternVL2-8B --model-name InternVL2-8B +``` +> [!IMPORTANT] +> 因为 VLMEvalKit 中的模型对于不同数据集在构建 prompt 时可能有自定义行为,如 InternVL2 对于 HallusionBench 的处理,所以,server 端在启动的时候需要指定 `--model-name`,这样在使用 LMDEploy api 时可以根据名字选择合适的 prompt 构建策略。 +> +> 如果指定了 `--server-port`,需要设置对应的环境变量 `LMDEPLOY_API_BASE` + + +## 第2步 评测 + +```bash +python run.py --data MMStar --model InternVL2-8B --verbose --api-nproc 64 +``` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Makefile b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d4bb2cbb9eddb1bb1b4f366623044af8e4830919 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Quickstart.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..afc5cea19c1d183dbe648e3d0e9fc2ba46f058c0 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/Quickstart.md @@ -0,0 +1,216 @@ +# 快速开始 + +在运行评测脚本之前,你需要先**配置** VLMs,并正确设置模型路径。然后你可以使用脚本 `run.py` 进行多个VLMs和基准测试的推理和评估。 + +## 第0步 安装和设置必要的密钥 + +**安装** + +```bash +git clone https://github.com/open-compass/VLMEvalKit.git +cd VLMEvalKit +pip install -e . +``` + +**设置密钥** + +要使用 API 模型(如 GPT-4v, Gemini-Pro-V 等)进行推理,或使用 LLM API 作为**评判者或选择提取器**,你需要首先设置 API 密钥。如果你设置了密钥,VLMEvalKit 将使用一个评判 LLM 从输出中提取答案,否则它将使用**精确匹配模式**(在输出字符串中查找 "Yes", "No", "A", "B", "C"...)。**精确匹配模式只能应用于是或否任务和多项选择任务。** + +- 你可以将所需的密钥放在 `$VLMEvalKit/.env` 中,或直接将它们设置为环境变量。如果你选择创建 `.env` 文件,其内容将如下所示: + + ```bash + # .env 文件,将其放置在 $VLMEvalKit 下 + # 专有 VLMs 的 API 密钥 + # QwenVL APIs + DASHSCOPE_API_KEY= + # Gemini w. Google Cloud Backends + GOOGLE_API_KEY= + # OpenAI API + OPENAI_API_KEY= + OPENAI_API_BASE= + # StepAI API + STEPAI_API_KEY= + # REKA API + REKA_API_KEY= + # GLMV API + GLMV_API_KEY= + # CongRong API + CW_API_BASE= + CW_API_KEY= + # SenseNova API + SENSENOVA_API_KEY= + # Hunyuan-Vision API + HUNYUAN_SECRET_KEY= + HUNYUAN_SECRET_ID= + # LMDeploy API + LMDEPLOY_API_BASE= + # 你可以设置一个评估时代理,评估阶段产生的 API 调用将通过这个代理进行 + EVAL_PROXY= + ``` + +- 如果需要使用 API 在对应键值空白处填写上你的密钥。这些 API 密钥将在进行推理和评估时自动加载。 +## 第1步 配置 + +**VLM 配置**:所有 VLMs 都在 `vlmeval/config.py` 中配置。对于某些 VLMs(如 MiniGPT-4、LLaVA-v1-7B),需要额外的配置(在配置文件中配置代码 / 模型权重根目录)。在评估时,你应该使用 `vlmeval/config.py` 中 `supported_VLM` 指定的模型名称来选择 VLM。确保在开始评估之前,你可以成功使用 VLM 进行推理,使用以下命令 `vlmutil check {MODEL_NAME}`。 + +## 第2步 评测 + +**新功能!!!** 我们集成了一个新的配置系统,以实现更灵活的评估设置。查看[文档](/docs/zh-CN/ConfigSystem.md)或运行`python run.py --help`了解更多详情 🔥🔥🔥 + +我们使用 `run.py` 进行评估。你可以使用 `$VLMEvalKit/run.py` 或创建脚本的软链接运行(以便在任何地方使用该脚本): + +**参数** + +- `--data (list[str])`: 设置在 VLMEvalKit 中支持的数据集名称(可以在代码库首页的 README 中找到支持的数据集列表) +- `--model (list[str])`: 设置在 VLMEvalKit 中支持的 VLM 名称(在 `vlmeval/config.py` 中的 `supported_VLM` 中定义) +- `--mode (str, 默认值为 'all', 可选值为 ['all', 'infer'])`:当 mode 设置为 "all" 时,将执行推理和评估;当设置为 "infer" 时,只执行推理 +- `--api-nproc (int, 默认值为 4)`: 调用 API 的线程数 +- `--work-dir (str, default to '.')`: 存放测试结果的目录 + +**用于评测图像多模态评测集的命令** + +你可以使用 `python` 或 `torchrun` 来运行脚本: + +```bash +# 使用 `python` 运行时,只实例化一个 VLM,并且它可能使用多个 GPU。 +# 这推荐用于评估参数量非常大的 VLMs(如 IDEFICS-80B-Instruct)。 + +# 在 MMBench_DEV_EN、MME 和 SEEDBench_IMG 上使用 IDEFICS-80B-Instruct 进行推理和评估 +python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct --verbose +# 在 MMBench_DEV_EN、MME 和 SEEDBench_IMG 上使用 IDEFICS-80B-Instruct 仅进行推理 +python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct --verbose --mode infer + +# 使用 `torchrun` 运行时,每个 GPU 上实例化一个 VLM 实例。这可以加快推理速度。 +# 但是,这仅适用于消耗少量 GPU 内存的 VLMs。 + +# 在 MMBench_DEV_EN、MME 和 SEEDBench_IMG 上使用 IDEFICS-9B-Instruct、Qwen-VL-Chat、mPLUG-Owl2。在具有 8 个 GPU 的节点上进行推理和评估。 +torchrun --nproc-per-node=8 run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model idefics_80b_instruct qwen_chat mPLUG-Owl2 --verbose +# 在 MME 上使用 Qwen-VL-Chat。在具有 2 个 GPU 的节点上进行推理和评估。 +torchrun --nproc-per-node=2 run.py --data MME --model qwen_chat --verbose +``` + +**用于评测视频多模态评测集的命令** + +```bash +# 使用 `python` 运行时,只实例化一个 VLM,并且它可能使用多个 GPU。 +# 这推荐用于评估参数量非常大的 VLMs(如 IDEFICS-80B-Instruct)。 + +# 在 MMBench-Video 上评测 IDEFCIS2-8B, 视频采样 8 帧作为输入,不采用 pack 模式评测. MMBench_Video_8frame_nopack 是一个定义在 `vlmeval/dataset/video_dataset_config.py` 的数据集设定. +torchrun --nproc-per-node=8 run.py --data MMBench_Video_8frame_nopack --model idefics2_8 +# 在 MMBench-Video 上评测 GPT-4o (API 模型), 视频采样每秒一帧作为输入,采用 pack 模式评测 +python run.py --data MMBench_Video_1fps_pack --model GPT4o +``` + +评估结果将作为日志打印出来。此外,**结果文件**也会在目录 `$YOUR_WORKING_DIRECTORY/{model_name}` 中生成。以 `.csv` 结尾的文件包含评估的指标。 +### 常见问题 +#### 构建输入prompt:`build_prompt()`函数 +如果您在评测某个benchmark时,发现模型输出的结果与预期不符,可能是因为您使用的模型没有正确构建输入prompt。 + +在VLMEvalkit中,每个`dataset`类都包含一个名为`build_prompt()`的函数,用于构建输入问题的格式。不同的benchmark可以选择自定义`build_prompt()`函数,也可以使用默认的实现。 + +例如,在处理默认的[多选题/Multi-Choice QA]([vlmeval/dataset/image_mcq.py](https://github.com/open-compass/VLMEvalKit/blob/43af13e052de6805a8b08cd04aed5e0d74f82ff5/vlmeval/dataset/image_mcq.py#L164))时,`ImageMCQDataset.build_prompt()`类会将`hint`、`question`、`options`等元素(若数据集中包含)组合成一个完整的问题格式,如下所示: +``` +HINT +QUESTION +Options: +A. Option A +B. Option B +··· +Please select the correct answer from the options above. +``` + +此外,由于不同模型对评测的需求可能有所不同,VLMEvalkit也支持在模型层面自定义对不同benchmark构建prompt的方法,即`model.build_prompt()`,具体示例可以参考[InternVL](https://github.com/open-compass/VLMEvalKit/blob/43af13e052de6805a8b08cd04aed5e0d74f82ff5/vlmeval/vlm/internvl_chat.py#L324)。 + +**注意:当同时定义了`model.build_prompt()`以及`dataset.build_prompt()`时,`model.build_prompt()`将优先于`dataset.build_prompt()`,即前者会覆盖后者。** + +由于部分模型(如Qwen2VL,InternVL等)对于不同类型的benchmark定义了广泛的prompt构建方法,为了更灵活地适应不同的benchmark,VLMEvalkit支持在模型中自定义`model.use_custom_prompt()`函数。通过添加或者修改`use_custom_prompt()`函数,您可以决定对于哪些benchmark使用模型自定义的`use_custom_prompt()`方法,示例如下: +``` +def use_custom_prompt(self, dataset: str) -> bool: + from vlmeval.dataset import DATASET_TYPE, DATASET_MODALITY + dataset_type = DATASET_TYPE(dataset, default=None) + if not self._use_custom_prompt: + return False + if listinstr(['MMVet'], dataset): + return True + if dataset_type == 'MCQ': + return True + if DATASET_MODALITY(dataset) == 'VIDEO': + return False + return False +``` +仅当`use_custom_prompt()`函数返回`True`时,VLMEvalkit才会对当前benchmark调用模型的`build_prompt()`函数。 +通过这种方式,您可以根据具体需求灵活地控制哪些benchmark使用模型自定义的prompt构建逻辑,从而更好地适配不同模型和任务的需求。 + +#### 模型切分 + +目前 VLMEvalKit 的启动方式自动支持同机上进程间 GPU 资源的划分与模型切分。该功能在推理后端为 `lmdeploy` 或 `transformers` 时被支持,具体行为如下: + +- 基于 `python` 命令启动时,模型默认分配到所有可用的 GPU 上,如想指定使用哪些 GPU,可以使用 `CUDA_VISIBLE_DEVICES` 环境变量。 +- 基于 `torchrun` 命令启动时,每个模型实例会被分配到 `N_GPU // N_PROC` 个 GPU 上,`N_PROC` 为 torchrun 命令中的 `--nproc-per-node` 参数所指定的进程数。`N_GPU` 的取值为: + - 如 `CUDA_VISIBLE_DEVICES` 环境变量未设置,`N_GPU` 为全部可用 GPU 数量。 + - 如 `CUDA_VISIBLE_DEVICES` 环境变量被设置,`N_GPU` 为 `CUDA_VISIBLE_DEVICES` 环境变量所指定的 GPU 数量,并且,仅有指定的 GPU 会被利用。 + +下面提供了,在一台配备 8 块 GPU 的机器上运行评测任务的具体示例: +```bash +# +torchrun --nproc-per-node=2 run.py --data MMBench_DEV_EN --model InternVL3-78B +# +python run.py --data MMBench_DEV_EN --model InternVL3-78B +# +CUDA_VISIBLE_DEVICES=1,2,3,4,5,6 torchrun --nproc-per-node=3 run.py --data MMBench_DEV_EN --model InternVL3-38B +``` + +注:此方式不支持 `vllm` 后端,基于 `vllm` 后端起评测任务时,请用 `python` 命令启动,默认调用所有可见的 GPU。 + +#### 性能差距 +在不同的运行环境中,模型的性能表现可能会有所差异。因此,在评估过程中,您可能会发现自己的评测结果与VLMEvalKit官方榜单上的结果存在差距。这种差异可能与`transformers`, `cuda`, `torch`等版本的变化有关。 + +此外,对于异常的表现,我们建议您优先查看运行完成后的本地生成记录`{model}_{dataset}.xlsx`或者评估记录`{model}_{dataset}_{judge_model}.xlsx`,这可能会帮助您更好地理解评估结果并发现问题。 + + + +### 部署本地语言模型作为评判 / 选择提取器 +上述默认设置使用 OpenAI 的 GPT 作为评判 LLM。你也可以使用 [LMDeploy](https://github.com/InternLM/lmdeploy) 部署本地评判 LLM。 + +首先进行安装: +``` +pip install lmdeploy openai +``` + +然后可以通过一行代码部署本地评判 LLM。LMDeploy 将自动从 Huggingface 下载模型。假设我们使用 internlm2-chat-1_8b 作为评判,端口为 23333,密钥为 sk-123456(密钥必须以 "sk-" 开头,后跟任意数字): +``` +lmdeploy serve api_server internlm/internlm2-chat-1_8b --server-port 23333 +``` + +使用以下 Python 代码获取由 LMDeploy 注册的模型名称: +``` +from openai import OpenAI +client = OpenAI( + api_key='sk-123456', + base_url="http://0.0.0.0:23333/v1" +) +model_name = client.models.list().data[0].id +``` + +配置对应环境变量,以告诉 VLMEvalKit 如何使用本地评判 LLM。正如上面提到的,也可以在 `$VLMEvalKit/.env` 文件中设置: +``` +OPENAI_API_KEY=sk-123456 +OPENAI_API_BASE=http://0.0.0.0:23333/v1/chat/completions +LOCAL_LLM= +``` + +最后,你可以运行第2步中的命令,使用本地评判 LLM 来评估你的 VLM。 + +**请注意:** + +- 如果你希望将评判 LLM 部署在单独的一个 GPU 上,并且由于 GPU 内存有限而希望在其他 GPU 上评估你的 VLM,可以使用 `CUDA_VISIBLE_DEVICES=x` 这样的方法,例如: +``` +CUDA_VISIBLE_DEVICES=0 lmdeploy serve api_server internlm/internlm2-chat-1_8b --server-port 23333 +CUDA_VISIBLE_DEVICES=1,2,3 torchrun --nproc-per-node=3 run.py --data HallusionBench --model qwen_chat --verbose +``` +- 如果本地评判 LLM 在遵循指令方面不够好,评估过程可能会失败。请通过 issues 报告此类失败情况。 +- 可以以不同的方式部署评判 LLM,例如使用私有 LLM(而非来自 HuggingFace)或使用量化 LLM。请参考 [LMDeploy doc](https://lmdeploy.readthedocs.io/en/latest/serving/api_server.html) 文档。也可以使用其他支持 OpenAI API 框架的方法。 + +### 使用 LMDeploy 加速模型推理 + +可参考[文档](/docs/zh-CN/EvalByLMDeploy.md) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/README_zh-CN.md b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/README_zh-CN.md new file mode 100644 index 0000000000000000000000000000000000000000..92c526fcb3d2d5766469773c9eaa51196df53b4a --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/README_zh-CN.md @@ -0,0 +1,131 @@ +
+ +![LOGO](http://opencompass.openxlab.space/utils/MMLB.jpg) + +VLMEvalKit: 一种多模态大模型评测工具 + +[![][github-contributors-shield]][github-contributors-link] • [![][github-forks-shield]][github-forks-link] • [![][github-stars-shield]][github-stars-link] • [![][github-issues-shield]][github-issues-link] • [![][github-license-shield]][github-license-link] + +[English](/README.md) | 简体中文 | [日本語](/docs/ja/README_ja.md) + +🏆 OpenCompass 排行榜 • +🏗️ 快速开始 • +📊 数据集和模型 • +🛠️ 开发指南 • +🎯 我们的目标 • +🖊️ 引用 + +🤗 HuggingFace 排行榜 (存档全部性能) • +🤗 原始评测记录 • +🔊 Discord • +📝 技术报告 +
+ +**VLMEvalKit** (python 包名为 **vlmeval**) 是一款专为大型视觉语言模型 (Large Vision-Language Models, LVLMs) 评测而设计的开源工具包。该工具支持在各种基准测试上对大型视觉语言模型进行**一键评估**,无需进行繁重的数据准备工作,让评估过程更加简便。在 VLMEvalKit 中,我们对所有大型视觉语言模型生成的结果进行评测,并提供基于**精确匹配**与基于 **LLM 的答案提取**两种评测结果。 + +## 🆕 更新 + +- **[2025-04-29]** 优化 `torchrun` 启动逻辑:目前 `torchrun` 启动时,若进程数为 M,机器 GPU 卡数为 N,将会自动调整每个进程分配的 GPU 数量为 `N // M`。目前此分配方式适用于 `transformers`, `lmdeploy` 推理后端,`vllm` 推理后端仅支持使用 python 启动 🔥🔥🔥 +- **[2025-02-20]** 支持新模型:**InternVL2.5 series, QwenVL2.5 series, QVQ-72B, Doubao-VL, Janus-Pro-7B, MiniCPM-o-2.6, InternVL2-MPO, LLaVA-CoT, Hunyuan-Standard-Vision, Ovis2, Valley, SAIL-VL, Ross, Long-VITA, EMU3, SmolVLM**。支持新基准:**MMMU-Pro, WeMath, 3DSRBench, LogicVista, VL-RewardBench, CC-OCR, CG-Bench, CMMMU, WorldSense**。请参考[**VLMEvalKit Features**](https://aicarrier.feishu.cn/wiki/Qp7wwSzQ9iK1Y6kNUJVcr6zTnPe?table=tblsdEpLieDoCxtb)以获取更多信息。感谢社区的各位贡献者 🔥🔥🔥 +- **[2024-11-21]** 集成了一个新的配置系统,以实现更灵活的评估设置。查看[文档](/docs/zh-CN/ConfigSystem.md)或运行`python run.py --help`了解更多详情 🔥🔥🔥 +- **[2024-11-21]** 支持 **[QSpatial](https://andrewliao11.github.io/spatial_prompt/)**,一个用于定量空间推理的多模态基准(例如,确定大小/距离),感谢 **[andrewliao11](https://github.com/andrewliao11)** 提供官方支持 🔥🔥🔥 +- **[2024-11-21]** 支持 **[MM-Math](https://github.com/kge-sun/mm-math)**,一个包含约6K初中多模态推理数学问题的新多模态数学基准。GPT-4o-20240806在该基准上达到了22.5%的准确率 🔥🔥🔥 +- **[2024-11-16]** 支持 **[OlympiadBench](https://github.com/OpenBMB/OlympiadBench)**,一个多模态基准,包含奥林匹克级别的数学和物理问题 🔥🔥🔥 +- **[2024-11-16]** 支持 **[WildVision](https://huggingface.co/datasets/WildVision/wildvision-bench)**,一个基于多模态竞技场数据的主观多模态基准 🔥🔥🔥 +- **[2024-11-13]** 支持 **[MIA-Bench](https://arxiv.org/abs/2407.01509)**,一个多模态指令跟随基准 🔥🔥🔥 +- **[2024-11-08]** 支持 **[Aria](https://arxiv.org/abs/2410.05993)**,一个多模态原生 MoE 模型,感谢 **[teowu](https://github.com/teowu)** 🔥🔥🔥 +- **[2024-11-04]** 支持 **[WorldMedQA-V](https://www.arxiv.org/abs/2410.12722)**,该基准包含 1000 多个医学 VQA 问题,涵盖巴西、以色列、日本、西班牙等四个国家的语言,以及它们的英文翻译 🔥🔥🔥 + +## 🏗️ 快速开始 + +请参阅[**快速开始**](/docs/zh-CN/Quickstart.md)获取入门指南。 + +## 📊 评测结果,支持的数据集和模型 + +### 评测结果 + +**[OpenVLM Leaderboard](https://huggingface.co/spaces/opencompass/open_vlm_leaderboard)**: **[下载全部细粒度测试结果](http://opencompass.openxlab.space/assets/OpenVLM.json)**. + +请查看[**VLMEvalKit Features**](https://aicarrier.feishu.cn/wiki/Qp7wwSzQ9iK1Y6kNUJVcr6zTnPe?table=tblsdEpLieDoCxtb)中的 **Supported Benchmarks** 标签,以查看所有支持的图像和视频基准(70+)。 + +请查看[**VLMEvalKit Features**](https://aicarrier.feishu.cn/wiki/Qp7wwSzQ9iK1Y6kNUJVcr6zTnPe?table=tblsdEpLieDoCxtb)中的 **Supported LMMs** 标签,以查看所有支持的 LMMs,包括商业 API、开源模型等(200+)。 + +### 其他 + +**Transformers 的版本推荐:** + +**请注意**,某些 VLM 可能无法在某些特定的 transformers 版本下运行,我们建议使用以下设置来评估对应的VLM: + +- **请用** `transformers==4.33.0` **来运行**: `Qwen series`, `Monkey series`, `InternLM-XComposer Series`, `mPLUG-Owl2`, `OpenFlamingo v2`, `IDEFICS series`, `VisualGLM`, `MMAlaya`, `ShareCaptioner`, `MiniGPT-4 series`, `InstructBLIP series`, `PandaGPT`, `VXVERSE`. +- **请用** `transformers==4.37.0 ` **来运行**: `LLaVA series`, `ShareGPT4V series`, `TransCore-M`, `LLaVA (XTuner)`, `CogVLM Series`, `EMU2 Series`, `Yi-VL Series`, `MiniCPM-[V1/V2]`, `OmniLMM-12B`, `DeepSeek-VL series`, `InternVL series`, `Cambrian Series`, `VILA Series`, `Llama-3-MixSenseV1_1`, `Parrot-7B`, `PLLaVA Series`. +- **请用** `transformers==4.40.0 ` **来运行**: `IDEFICS2`, `Bunny-Llama3`, `MiniCPM-Llama3-V2.5`, `360VL-70B`, `Phi-3-Vision`, `WeMM`. +- **请用** `transformers==4.42.0 ` **来运行**: `AKI`. +- **请用** `transformers==latest` **来运行**: `LLaVA-Next series`, `PaliGemma-3B`, `Chameleon series`, `Video-LLaVA-7B-HF`, `Ovis series`, `Mantis series`, `MiniCPM-V2.6`, `OmChat-v2.0-13B-sinlge-beta`, `Idefics-3`, `GLM-4v-9B`, `VideoChat2-HD`. + +**如何测试一个 VLM 是否可以正常运行:** + +```python +from vlmeval.config import supported_VLM +model = supported_VLM['idefics_9b_instruct']() +# 前向单张图片 +ret = model.generate(['assets/apple.jpg', 'What is in this image?']) +print(ret) # 这张图片上有一个带叶子的红苹果 +# 前向多张图片 +ret = model.generate(['assets/apple.jpg', 'assets/apple.jpg', 'How many apples are there in the provided images? ']) +print(ret) # 提供的图片中有两个苹果 +``` + +## 🛠️ 开发指南 + +要开发自定义评测数据集,支持其他 VLMs,或为 VLMEvalKit 贡献代码,请参阅[**开发指南**](/docs/zh-CN/Development_zh-CN.md)。 + +为激励来自社区的共享并分享相应的 credit,在下一次 report 更新中,我们将: + +- 致谢所有的 contribution +- 具备三个或以上主要贡献 (支持新模型、评测集、或是主要特性) 的贡献者将可以加入技术报告的作者列表 。合条件的贡献者可以创建 issue 或是在 [VLMEvalKit Discord Channel](https://discord.com/invite/evDT4GZmxN) 私信 kennyutc,我们将进行跟进 + +## 🎯 VLMEvalKit 的目标 + +**该代码库的设计目标是:** + +1. 提供一个**易于使用**的**开源评估工具包**,方便研究人员和开发人员评测现有的多模态大模型,并使评测结果**易于复现**。 +2. 使 VLM 开发人员能够轻松地评测自己的模型。在多个支持的基准测试上评估 VLM,只需实现一个 `generate_inner()` 函数,所有其他工作负载(数据下载、数据预处理、预测推理、度量计算)都由代码库处理。 + +**该代码库的设计目标不是:** + +复现所有**第三方基准测试**原始论文中报告的准确数字。有两个相关的原因: +1. VLMEvalKit 对所有 VLMs 使用基于生成的评估(可选使用基于 LLM 的答案提取)。同时,一些基准测试可能官方使用不同的方法(*例如,SEEDBench 使用基于 PPL 的评估*)。对于这些基准测试,我们在相应的结果中比较两个得分。我们鼓励开发人员在代码库中支持其他评估范式。 +2. 默认情况下,我们对所有多模态模型使用相同的提示模板来评估基准测试。同时,**一些多模态模型可能有他们特定的提示模板**(目前可能未在代码库中涵盖)。我们鼓励 VLM 的开发人员在 VLMEvalKit 中实现自己的提示模板,如果目前未覆盖。这将有助于提高可复现性。 + +## 🖊️ 引用 + +如果我们的工作对您有所帮助,请考虑 **star🌟** VLMEvalKit。感谢支持! + +[![Stargazers repo roster for @open-compass/VLMEvalKit](https://reporoster.com/stars/open-compass/VLMEvalKit)](https://github.com/open-compass/VLMEvalKit/stargazers) + +如果您在研究中使用了 VLMEvalKit,或希望参考已发布的开源评估结果,请使用以下 BibTeX 条目以及与您使用的特定 VLM / 基准测试相对应的 BibTex 条目。 + +```bib +@misc{duan2024vlmevalkit, + title={VLMEvalKit: An Open-Source Toolkit for Evaluating Large Multi-Modality Models}, + author={Haodong Duan and Junming Yang and Yuxuan Qiao and Xinyu Fang and Lin Chen and Yuan Liu and Xiaoyi Dong and Yuhang Zang and Pan Zhang and Jiaqi Wang and Dahua Lin and Kai Chen}, + year={2024}, + eprint={2407.11691}, + archivePrefix={arXiv}, + primaryClass={cs.CV}, + url={https://arxiv.org/abs/2407.11691}, +} +``` + +

🔝回到顶部

+ +[github-contributors-link]: https://github.com/open-compass/VLMEvalKit/graphs/contributors +[github-contributors-shield]: https://img.shields.io/github/contributors/open-compass/VLMEvalKit?color=c4f042&labelColor=black&style=flat-square +[github-forks-link]: https://github.com/open-compass/VLMEvalKit/network/members +[github-forks-shield]: https://img.shields.io/github/forks/open-compass/VLMEvalKit?color=8ae8ff&labelColor=black&style=flat-square +[github-issues-link]: https://github.com/open-compass/VLMEvalKit/issues +[github-issues-shield]: https://img.shields.io/github/issues/open-compass/VLMEvalKit?color=ff80eb&labelColor=black&style=flat-square +[github-license-link]: https://github.com/open-compass/VLMEvalKit/blob/main/LICENSE +[github-license-shield]: https://img.shields.io/github/license/open-compass/VLMEvalKit?color=white&labelColor=black&style=flat-square +[github-stars-link]: https://github.com/open-compass/VLMEvalKit/stargazers +[github-stars-shield]: https://img.shields.io/github/stars/open-compass/VLMEvalKit?color=ffcb47&labelColor=black&style=flat-square diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/css/readthedocs.css b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/css/readthedocs.css new file mode 100644 index 0000000000000000000000000000000000000000..c83beffd261d9d7cb79dc499aec7187474639d89 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/css/readthedocs.css @@ -0,0 +1,63 @@ +.header-logo { + background-image: url("../image/logo.svg"); + background-size: 275px 80px; + height: 80px; + width: 275px; +} + + +@media screen and (min-width: 1100px) { + .header-logo { + top: -25px; + } +} + +pre { + white-space: pre; +} + +@media screen and (min-width: 2000px) { + .pytorch-content-left { + width: 1200px; + margin-left: 30px; + } + article.pytorch-article { + max-width: 1200px; + } + .pytorch-breadcrumbs-wrapper { + width: 1200px; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 1580px; + } +} + + +article.pytorch-article section code { + padding: .2em .4em; + background-color: #f3f4f7; + border-radius: 5px; +} + +/* Disable the change in tables */ +article.pytorch-article section table code { + padding: unset; + background-color: unset; + border-radius: unset; +} + +table.autosummary td { + width: 50% +} + +img.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +article.pytorch-article p.rubric { + font-weight: bold; +} diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo.svg b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..043530572afb48d0eac26b4b53d448aae6e9a9af --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo.svg @@ -0,0 +1,24 @@ + + + +Created with Fabric.js 5.3.0 + + + + + + + + + + + + + VLMEvalKit + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo_icon.svg b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo_icon.svg new file mode 100644 index 0000000000000000000000000000000000000000..c46dd3b5407c1f82dce4f6096acf8c8a30a6cfba --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/image/logo_icon.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/js/custom.js b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/js/custom.js new file mode 100644 index 0000000000000000000000000000000000000000..84da69d47fae8e8994685aca3b99151d01a77978 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_static/js/custom.js @@ -0,0 +1,10 @@ +var collapsedSections = []; + +$(document).ready(function () { + $('.model-summary').DataTable({ + "stateSave": false, + "lengthChange": false, + "pageLength": 20, + "order": [] + }); +}); diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/404.html b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/404.html new file mode 100644 index 0000000000000000000000000000000000000000..64910175d5d69946845b04d5e6a378de205e8388 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/404.html @@ -0,0 +1,18 @@ +{% extends "layout.html" %} + +{% block body %} + +

Page Not Found

+

+ The page you are looking for cannot be found. +

+

+ If you just switched documentation versions, it is likely that the page you were on is moved. You can look for it in + the content table left, or go to the homepage. +

+ + +{% endblock %} diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/autosummary/class.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/autosummary/class.rst new file mode 100644 index 0000000000000000000000000000000000000000..4c3a7a9abf5c5b14ac3ef3b00a2f070480295358 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/autosummary/class.rst @@ -0,0 +1,13 @@ +.. role:: hidden + :class: hidden-section +.. currentmodule:: {{ module }} + + +{{ name | underline}} + +.. autoclass:: {{ name }} + :members: + +.. + autogenerated from _templates/autosummary/class.rst + note it does not have :inherited-members: diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/callable.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/callable.rst new file mode 100644 index 0000000000000000000000000000000000000000..3a7b9d2b96c76dfa3eb1d8bef56f58f219fe7760 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/_templates/callable.rst @@ -0,0 +1,14 @@ +.. role:: hidden + :class: hidden-section +.. currentmodule:: {{ module }} + + +{{ name | underline}} + +.. autoclass:: {{ name }} + :members: + :special-members: __call__ + +.. + autogenerated from _templates/callable.rst + note it does not have :inherited-members: diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/conf.py b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..689daa6177913b918b6a01fe1e1ce5a6d4ca505f --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/conf.py @@ -0,0 +1,242 @@ +# flake8: noqa +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import ast +import subprocess +import sys + +import pytorch_sphinx_theme +from sphinx.builders.html import StandaloneHTMLBuilder + +sys.path.insert(0, os.path.abspath('../../')) + +# -- Project information ----------------------------------------------------- + +project = 'VLMEvalKit' +copyright = '2023, VLMEvalKit' +author = 'VLMEvalKit Authors' + +# The full version, including alpha/beta/rc tags +version_file = '../../vlmeval/__init__.py' + + +def get_version(): + with open(version_file, 'r') as f: + file_content = f.read() + # Parse the file content into an abstract syntax tree (AST) + tree = ast.parse(file_content, filename=version_file) + + # Iterate through the body of the AST, looking for an assignment to __version__ + for node in tree.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == '__version__': + return node.value.s + raise ValueError('__version__ not found') + + +release = get_version() + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', + 'sphinx.ext.viewcode', + 'myst_parser', + 'sphinx_copybutton', + 'sphinx_tabs.tabs', + 'notfound.extension', + 'sphinxcontrib.jquery', + 'sphinx_design', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +language = 'cn' + +# The master toctree document. +root_doc = 'index' +html_context = { + 'github_version': 'latest', +} +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'pytorch_sphinx_theme' +html_theme_path = [pytorch_sphinx_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# yapf: disable +html_theme_options = { + 'menu': [ + { + 'name': 'GitHub', + 'url': 'https://github.com/open-compass/VLMEvalKit' + }, + ], + # Specify the language of shared menu + 'menu_lang': 'cn', + # Disable the default edit on GitHub + 'default_edit_on_github': False, +} +# yapf: enable + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +html_css_files = [ + 'https://cdn.datatables.net/v/bs4/dt-1.12.1/datatables.min.css', + 'css/readthedocs.css' +] +html_js_files = [ + 'https://cdn.datatables.net/v/bs4/dt-1.12.1/datatables.min.js', + 'js/custom.js' +] + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'vlmevalkitdoc' + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (root_doc, 'vlmevalkit.tex', 'VLMEvalKit Documentation', author, + 'manual'), +] + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(root_doc, 'vlmevalkit', 'VLMEvalKit Documentation', [author], + 1)] + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (root_doc, 'vlmevalkit', 'VLMEvalKit Documentation', author, + 'VLMEvalKit Authors', 'AGI evaluation toolbox and benchmark.', + 'Miscellaneous'), +] + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# set priority when building html +StandaloneHTMLBuilder.supported_image_types = [ + 'image/svg+xml', 'image/gif', 'image/png', 'image/jpeg' +] + +# -- Extension configuration ------------------------------------------------- +# Ignore >>> when copying code +copybutton_prompt_text = r'>>> |\.\.\. ' +copybutton_prompt_is_regexp = True + +# Auto-generated header anchors +myst_heading_anchors = 3 +# Enable "colon_fence" extension of myst. +myst_enable_extensions = ['colon_fence', 'dollarmath'] + +# Configuration for intersphinx +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'numpy': ('https://numpy.org/doc/stable', None), + 'torch': ('https://pytorch.org/docs/stable/', None), + 'mmengine': ('https://mmengine.readthedocs.io/en/latest/', None), + 'transformers': + ('https://huggingface.co/docs/transformers/main/en/', None), +} +napoleon_custom_sections = [ + # Custom sections for data elements. + ('Meta fields', 'params_style'), + ('Data fields', 'params_style'), +] + +# Disable docstring inheritance +autodoc_inherit_docstrings = False +# Mock some imports during generate API docs. +autodoc_mock_imports = ['rich', 'attr', 'einops'] +# Disable displaying type annotations, these can be very verbose +autodoc_typehints = 'none' + +# The not found page +notfound_template = '404.html' + + +def builder_inited_handler(app): + subprocess.run(['./cp_origin_docs.sh']) + + +def setup(app): + app.connect('builder-inited', builder_inited_handler) diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/cp_origin_docs.sh b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/cp_origin_docs.sh new file mode 100644 index 0000000000000000000000000000000000000000..1e728323684a0aad1571eb392871d6c5de6644fc --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/cp_origin_docs.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +# Copy *.md files from docs/ if it doesn't have a Chinese translation + +for filename in $(find ../en/ -name '*.md' -printf "%P\n"); +do + mkdir -p $(dirname $filename) + cp -n ../en/$filename ./$filename +done diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/docutils.conf b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/docutils.conf new file mode 100644 index 0000000000000000000000000000000000000000..0c00c84688701117f231fd0c8ec295fb747b7d8f --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/docutils.conf @@ -0,0 +1,2 @@ +[html writers] +table_style: colwidths-auto diff --git a/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/index.rst b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..5147a23b2052044664a987910d4bf04ccf286d14 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/docs/zh-CN/index.rst @@ -0,0 +1,49 @@ +欢迎来到 VLMEvalKit 中文教程! +========================================== + +VLMEvalKit 上手路线 +------------------------------- + +为了用户能够快速上手,我们推荐以下流程: + +- 对于想要使用 VLMEvalKit 的用户,我们推荐先阅读 开始你的第一步_ 部分来设置环境,并启动一个迷你实验熟悉流程。 + +- 若您想进行更多模块的自定义,例如增加数据集和模型,我们提供了 进阶教程_ 。 + +我们始终非常欢迎用户的 PRs 和 Issues 来完善 VLMEvalKit! + +.. _快速开始: +.. toctree:: + :maxdepth: 1 + :caption: 快速开始 + + Quickstart.md + + +.. .. _教程: +.. .. toctree:: +.. :maxdepth: 1 +.. :caption: 教程 + +.. user_guides/framework_overview.md + +.. _进阶教程: +.. toctree:: + :maxdepth: 1 + :caption: 进阶教程 + + Development.md + ConfigSystem.md + +.. .. _其他说明: +.. .. toctree:: +.. :maxdepth: 1 +.. :caption: 其他说明 + +.. notes/contribution_guide.md + +索引与表格 +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/SupplementaryMaterial_Code/VLMEvalKit/logs/InternVL3-8B_base_20250911_211703.log b/SupplementaryMaterial_Code/VLMEvalKit/logs/InternVL3-8B_base_20250911_211703.log new file mode 100644 index 0000000000000000000000000000000000000000..25721ce769a29c2c7bc9fc881f04e65591f4f174 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/logs/InternVL3-8B_base_20250911_211703.log @@ -0,0 +1,39081 @@ +/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/torch/cuda/__init__.py:63: FutureWarning: The pynvml package is deprecated. Please install nvidia-ml-py instead. If you did not install pynvml directly, please report this to the maintainers of the package that installed pynvml for you. + import pynvml # type: ignore[import] +[2025-09-11 21:17:09] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-11 21:17:21] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-11 21:17:21] WARNING - RUN - run.py: main - 219: --reuse is not set, will not reuse previous (before one day) temporary files +fatal: detected dubious ownership in repository at '/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit' +To add an exception for this directory, call: + + git config --global --add safe.directory /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit +`torch_dtype` is deprecated! Use `dtype` instead! +Namespace(data=['POPE'], model=['InternVL3-8B'], config=None, work_dir='./outputs/20250911_211721', mode='all', api_nproc=4, retry=None, judge_args=None, judge=None, verbose=True, ignore=False, reuse=False, reuse_aux=True, use_vllm=False, use_verifier=False) +['POPE'] +use_config False +ROOT +/mnt/bn/life-mllm/users/cxr/hallucination/OPERA/pope_coco/coco_pope_adversarial.jsonl + +out_file: ./outputs/20250911_211721/InternVL3-8B/T20250911_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 +FlashAttention2 is not installed. + Fetching 4 files: 0%| | 0/4 [00:00system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 1/3000 [00:01<1:04:58, 1.30s/it]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 2/3000 [00:01<38:02, 1.31it/s] Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 3/3000 [00:02<29:40, 1.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 4/3000 [00:02<25:24, 1.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 5/3000 [00:02<23:30, 2.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000310196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 6/3000 [00:03<22:09, 2.25it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 7/3000 [00:03<21:14, 2.35it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 8/3000 [00:04<20:43, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 9/3000 [00:04<20:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 10/3000 [00:04<20:23, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 11/3000 [00:05<20:45, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000210789.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 12/3000 [00:05<20:27, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 13/3000 [00:06<20:14, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 14/3000 [00:06<20:14, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 0%| | 15/3000 [00:06<20:07, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 16/3000 [00:07<20:19, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 17/3000 [00:07<20:44, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429109.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 18/3000 [00:08<20:17, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 19/3000 [00:08<20:04, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 20/3000 [00:08<20:14, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 21/3000 [00:09<19:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 22/3000 [00:09<19:34, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 23/3000 [00:10<19:23, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000211674.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 24/3000 [00:10<19:19, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 25/3000 [00:10<19:39, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 26/3000 [00:11<20:02, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 27/3000 [00:11<19:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 28/3000 [00:12<19:53, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 29/3000 [00:12<19:51, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 30/3000 [00:12<19:53, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 31/3000 [00:13<19:35, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 32/3000 [00:13<19:43, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 33/3000 [00:14<19:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 34/3000 [00:14<19:32, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 35/3000 [00:14<19:28, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283412.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 36/3000 [00:15<19:24, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%| | 37/3000 [00:15<19:19, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 38/3000 [00:16<19:24, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 39/3000 [00:16<19:16, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 40/3000 [00:16<19:27, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 41/3000 [00:17<19:42, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265719.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 42/3000 [00:17<19:56, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 43/3000 [00:18<19:41, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 1%|▏ | 44/3000 [00:18<19:45, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toaster in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toaster in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 45/3000 [00:18<19:30, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 46/3000 [00:19<19:29, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a microwave in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a microwave in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 47/3000 [00:19<19:24, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000461331.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 48/3000 [00:20<19:49, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 49/3000 [00:20<19:34, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 50/3000 [00:20<19:54, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 51/3000 [00:21<19:48, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 52/3000 [00:21<19:44, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 53/3000 [00:22<19:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000544456.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 54/3000 [00:22<19:48, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 55/3000 [00:22<19:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 56/3000 [00:23<20:10, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 57/3000 [00:23<19:43, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 58/3000 [00:24<19:31, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 59/3000 [00:24<19:28, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017708.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 60/3000 [00:24<19:34, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 61/3000 [00:25<19:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 62/3000 [00:25<19:20, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 63/3000 [00:26<19:36, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 64/3000 [00:26<19:58, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 65/3000 [00:26<19:41, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574692.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 66/3000 [00:27<19:27, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 67/3000 [00:27<19:25, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 68/3000 [00:28<19:43, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 69/3000 [00:28<19:29, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 70/3000 [00:28<19:56, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 71/3000 [00:29<20:08, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 72/3000 [00:29<19:53, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 73/3000 [00:30<19:42, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▏ | 74/3000 [00:30<19:32, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 2%|▎ | 75/3000 [00:30<19:42, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 76/3000 [00:31<19:42, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 77/3000 [00:31<19:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239444.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 78/3000 [00:32<19:17, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 79/3000 [00:32<19:24, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 80/3000 [00:32<19:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 81/3000 [00:33<19:09, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 82/3000 [00:33<19:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a hot dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a hot dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 83/3000 [00:34<19:26, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000569839.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 84/3000 [00:34<19:42, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 85/3000 [00:34<19:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 86/3000 [00:35<19:42, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 87/3000 [00:35<19:33, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 88/3000 [00:36<19:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 89/3000 [00:36<19:17, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000219622.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 90/3000 [00:36<19:35, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 91/3000 [00:37<19:29, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 92/3000 [00:37<19:30, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 93/3000 [00:38<19:26, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 94/3000 [00:38<19:11, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 95/3000 [00:38<19:06, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 96/3000 [00:39<19:05, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 97/3000 [00:39<19:35, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 98/3000 [00:40<20:06, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 99/3000 [00:40<19:39, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 100/3000 [00:40<19:32, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 101/3000 [00:41<20:07, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482476.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 102/3000 [00:41<19:42, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 103/3000 [00:42<19:41, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 3%|▎ | 104/3000 [00:42<19:53, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 105/3000 [00:42<19:24, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 106/3000 [00:43<19:08, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 107/3000 [00:43<19:20, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131115.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 108/3000 [00:44<19:19, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 109/3000 [00:44<19:05, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 110/3000 [00:44<18:57, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 111/3000 [00:45<18:57, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▎ | 112/3000 [00:45<18:58, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 113/3000 [00:46<18:59, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000157084.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 114/3000 [00:46<18:59, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 115/3000 [00:46<18:50, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 116/3000 [00:47<19:16, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 117/3000 [00:47<19:13, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 118/3000 [00:48<18:56, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 119/3000 [00:48<18:44, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381895.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 120/3000 [00:48<18:45, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 121/3000 [00:49<18:37, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 122/3000 [00:49<18:33, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 123/3000 [00:50<18:34, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 124/3000 [00:50<18:28, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 125/3000 [00:50<18:36, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000336872.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 126/3000 [00:51<18:33, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 127/3000 [00:51<17:21, 2.76it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 128/3000 [00:51<16:20, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 129/3000 [00:52<15:36, 3.06it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 130/3000 [00:52<15:10, 3.15it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 131/3000 [00:52<14:44, 3.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000075591.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 132/3000 [00:52<14:39, 3.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 133/3000 [00:53<16:20, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 134/3000 [00:53<17:00, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 4%|▍ | 135/3000 [00:54<17:29, 2.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 136/3000 [00:54<17:53, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 137/3000 [00:54<17:55, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516916.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 138/3000 [00:55<18:04, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 139/3000 [00:55<18:17, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 140/3000 [00:56<18:19, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toothbrush in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toothbrush in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 141/3000 [00:56<18:44, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 142/3000 [00:56<18:38, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 143/3000 [00:57<18:32, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000542145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 144/3000 [00:57<18:57, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 145/3000 [00:57<16:28, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 146/3000 [00:58<14:40, 3.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 147/3000 [00:58<13:16, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 148/3000 [00:58<12:30, 3.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▍ | 149/3000 [00:58<11:39, 4.07it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000218224.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 150/3000 [00:59<11:25, 4.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 151/3000 [00:59<13:50, 3.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 152/3000 [00:59<15:26, 3.07it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 153/3000 [01:00<16:12, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 154/3000 [01:00<16:50, 2.82it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 155/3000 [01:01<17:28, 2.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000297078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 156/3000 [01:01<17:56, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 157/3000 [01:01<18:01, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 158/3000 [01:02<18:28, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 159/3000 [01:02<18:24, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 160/3000 [01:02<18:34, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 161/3000 [01:03<18:22, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000033270.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 162/3000 [01:03<18:18, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 163/3000 [01:04<18:17, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 5%|▌ | 164/3000 [01:04<18:14, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 165/3000 [01:04<18:11, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 166/3000 [01:05<19:12, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cow in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 167/3000 [01:05<19:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140583.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 168/3000 [01:06<18:49, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 169/3000 [01:06<18:40, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 170/3000 [01:06<18:34, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 171/3000 [01:07<18:30, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 172/3000 [01:07<18:49, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 173/3000 [01:08<18:44, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000421455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 174/3000 [01:08<18:48, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 175/3000 [01:08<18:35, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 176/3000 [01:09<18:23, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toothbrush in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toothbrush in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 177/3000 [01:09<18:36, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 178/3000 [01:10<18:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 179/3000 [01:10<18:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288639.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 180/3000 [01:10<18:47, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 181/3000 [01:11<18:54, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 182/3000 [01:11<19:06, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 183/3000 [01:12<18:59, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 184/3000 [01:12<18:52, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 185/3000 [01:12<18:58, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000291936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 186/3000 [01:13<19:12, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▌ | 187/3000 [01:13<18:59, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 188/3000 [01:14<18:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 189/3000 [01:14<18:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 190/3000 [01:14<18:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 191/3000 [01:15<18:20, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000063953.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 192/3000 [01:15<18:09, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 193/3000 [01:16<18:02, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 194/3000 [01:16<17:58, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 6%|▋ | 195/3000 [01:16<18:05, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 196/3000 [01:17<18:44, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 197/3000 [01:17<18:55, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526321.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 198/3000 [01:18<18:36, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 199/3000 [01:18<18:42, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 200/3000 [01:18<18:52, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 201/3000 [01:19<18:37, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 202/3000 [01:19<18:27, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 203/3000 [01:20<18:51, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042190.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 204/3000 [01:20<18:49, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 205/3000 [01:20<16:06, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 206/3000 [01:20<14:04, 3.31it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 207/3000 [01:21<12:35, 3.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 208/3000 [01:21<11:31, 4.04it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 209/3000 [01:21<11:02, 4.21it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 210/3000 [01:21<10:48, 4.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 211/3000 [01:22<13:00, 3.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 212/3000 [01:22<14:27, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 213/3000 [01:22<15:31, 2.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 214/3000 [01:23<16:48, 2.76it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 215/3000 [01:23<17:06, 2.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170517.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 216/3000 [01:24<17:15, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 217/3000 [01:24<17:42, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 218/3000 [01:24<18:07, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 219/3000 [01:25<18:14, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 220/3000 [01:25<18:07, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 221/3000 [01:26<18:27, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 222/3000 [01:26<18:11, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 223/3000 [01:26<18:16, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 7%|▋ | 224/3000 [01:27<18:06, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 225/3000 [01:27<18:06, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 226/3000 [01:28<18:17, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 227/3000 [01:28<18:05, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000360600.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 228/3000 [01:28<18:04, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 229/3000 [01:29<18:43, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 230/3000 [01:29<18:37, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 231/3000 [01:30<18:20, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 232/3000 [01:30<18:05, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 233/3000 [01:30<17:58, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 234/3000 [01:31<18:11, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 235/3000 [01:31<14:51, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 236/3000 [01:31<12:12, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 237/3000 [01:31<10:17, 4.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 238/3000 [01:31<09:07, 5.05it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 239/3000 [01:31<08:12, 5.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500257.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 240/3000 [01:32<07:47, 5.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 241/3000 [01:32<10:37, 4.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 242/3000 [01:32<12:50, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 243/3000 [01:33<14:22, 3.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 244/3000 [01:33<15:23, 2.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 245/3000 [01:33<16:03, 2.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574057.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 246/3000 [01:34<16:34, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 247/3000 [01:34<17:16, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 248/3000 [01:35<17:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 249/3000 [01:35<18:02, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 250/3000 [01:35<18:06, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 251/3000 [01:36<17:56, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456178.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 252/3000 [01:36<17:55, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 253/3000 [01:37<17:59, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 254/3000 [01:37<18:00, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 8%|▊ | 255/3000 [01:37<18:17, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 256/3000 [01:38<18:04, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 257/3000 [01:38<18:24, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000565941.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 258/3000 [01:39<19:23, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 259/3000 [01:39<18:51, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 260/3000 [01:40<18:32, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 261/3000 [01:40<18:19, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▊ | 262/3000 [01:40<18:16, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 263/3000 [01:41<18:24, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 264/3000 [01:41<18:28, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 265/3000 [01:42<18:18, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 266/3000 [01:42<18:29, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 267/3000 [01:42<18:05, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 268/3000 [01:43<18:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 269/3000 [01:43<17:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 270/3000 [01:44<18:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 271/3000 [01:44<18:12, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 272/3000 [01:44<18:56, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 273/3000 [01:45<18:34, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 274/3000 [01:45<18:32, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 275/3000 [01:46<18:23, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205729.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 276/3000 [01:46<18:22, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 277/3000 [01:46<18:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 278/3000 [01:47<18:38, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 279/3000 [01:47<18:16, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 280/3000 [01:48<18:24, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 281/3000 [01:48<18:10, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424792.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 282/3000 [01:48<18:03, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 283/3000 [01:49<17:44, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 9%|▉ | 284/3000 [01:49<17:37, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 285/3000 [01:50<17:41, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 286/3000 [01:50<17:44, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 287/3000 [01:50<18:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000329717.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 288/3000 [01:51<18:10, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 289/3000 [01:51<17:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 290/3000 [01:52<18:02, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 291/3000 [01:52<17:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 292/3000 [01:52<17:37, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 293/3000 [01:53<17:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000012333.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 294/3000 [01:53<17:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 295/3000 [01:53<16:35, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 296/3000 [01:54<15:34, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 297/3000 [01:54<14:52, 3.03it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 298/3000 [01:54<14:15, 3.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|▉ | 299/3000 [01:55<13:55, 3.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000480122.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 300/3000 [01:55<13:44, 3.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 301/3000 [01:55<14:48, 3.04it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 302/3000 [01:56<15:55, 2.82it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 303/3000 [01:56<16:26, 2.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 304/3000 [01:56<16:47, 2.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 305/3000 [01:57<17:03, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515904.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 306/3000 [01:57<17:27, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 307/3000 [01:58<17:58, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 308/3000 [01:58<18:01, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 309/3000 [01:59<18:29, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 310/3000 [01:59<18:39, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 311/3000 [01:59<18:23, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000437347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 312/3000 [02:00<18:29, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 313/3000 [02:00<14:46, 3.03it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 314/3000 [02:00<12:06, 3.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 10%|█ | 315/3000 [02:00<10:14, 4.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 316/3000 [02:00<09:04, 4.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 317/3000 [02:00<08:07, 5.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354229.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 318/3000 [02:01<07:34, 5.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 319/3000 [02:01<10:22, 4.31it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 320/3000 [02:01<12:39, 3.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 321/3000 [02:02<14:18, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 322/3000 [02:02<15:11, 2.94it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 323/3000 [02:03<16:05, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538236.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 324/3000 [02:03<16:22, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 325/3000 [02:03<16:36, 2.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 326/3000 [02:04<17:01, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 327/3000 [02:04<17:17, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 328/3000 [02:05<17:18, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 329/3000 [02:05<17:48, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236865.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 330/3000 [02:05<17:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 331/3000 [02:06<17:28, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 332/3000 [02:06<17:26, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 333/3000 [02:07<17:45, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 334/3000 [02:07<17:30, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 335/3000 [02:07<17:23, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000217397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 336/3000 [02:08<17:33, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█ | 337/3000 [02:08<17:25, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 338/3000 [02:08<17:22, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 339/3000 [02:09<17:31, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 340/3000 [02:09<17:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 341/3000 [02:10<17:24, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000060213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 342/3000 [02:10<17:32, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 343/3000 [02:11<17:52, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 11%|█▏ | 344/3000 [02:11<18:11, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 345/3000 [02:11<17:48, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 346/3000 [02:12<17:47, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 347/3000 [02:12<17:39, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000054025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 348/3000 [02:13<17:42, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 349/3000 [02:13<17:38, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 350/3000 [02:13<17:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 351/3000 [02:14<17:33, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 352/3000 [02:14<17:25, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 353/3000 [02:14<17:22, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084447.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 354/3000 [02:15<17:19, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 355/3000 [02:15<17:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 356/3000 [02:16<17:35, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 357/3000 [02:16<17:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 358/3000 [02:17<18:00, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a refrigerator in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a refrigerator in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 359/3000 [02:17<17:55, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000192660.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 360/3000 [02:17<17:45, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 361/3000 [02:18<17:26, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 362/3000 [02:18<17:22, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 363/3000 [02:18<17:25, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 364/3000 [02:19<17:06, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 365/3000 [02:19<17:01, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 366/3000 [02:20<17:11, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 367/3000 [02:20<17:05, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 368/3000 [02:20<17:06, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 369/3000 [02:21<17:03, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 370/3000 [02:21<17:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 371/3000 [02:22<17:30, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354088.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 372/3000 [02:22<17:10, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 373/3000 [02:22<17:13, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▏ | 374/3000 [02:23<17:40, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 12%|█▎ | 375/3000 [02:23<17:32, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 376/3000 [02:24<17:12, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 377/3000 [02:24<17:20, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 378/3000 [02:24<17:10, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 379/3000 [02:25<17:07, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 380/3000 [02:25<17:11, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 381/3000 [02:26<17:15, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 382/3000 [02:26<17:15, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 383/3000 [02:26<17:04, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000456552.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 384/3000 [02:27<16:58, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 385/3000 [02:27<16:54, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 386/3000 [02:28<16:51, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 387/3000 [02:28<16:54, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 388/3000 [02:28<16:50, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a refrigerator in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a refrigerator in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 389/3000 [02:29<17:03, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000350898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 390/3000 [02:29<17:14, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 391/3000 [02:29<17:02, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 392/3000 [02:30<16:50, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 393/3000 [02:30<16:42, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 394/3000 [02:31<16:50, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 395/3000 [02:31<16:51, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170365.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 396/3000 [02:31<16:50, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 397/3000 [02:32<17:05, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 398/3000 [02:32<16:53, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 399/3000 [02:33<16:43, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 400/3000 [02:33<16:42, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 401/3000 [02:33<16:39, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021645.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 402/3000 [02:34<16:35, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 403/3000 [02:34<16:35, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 13%|█▎ | 404/3000 [02:35<17:04, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 405/3000 [02:35<17:10, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 406/3000 [02:35<16:59, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 407/3000 [02:36<16:50, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528905.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 408/3000 [02:36<16:45, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 409/3000 [02:36<16:52, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 410/3000 [02:37<16:56, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 411/3000 [02:37<16:52, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▎ | 412/3000 [02:38<16:46, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 413/3000 [02:38<16:46, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 414/3000 [02:38<17:08, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 415/3000 [02:39<17:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 416/3000 [02:39<17:10, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 417/3000 [02:40<16:54, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 418/3000 [02:40<16:51, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 419/3000 [02:40<17:00, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007320.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 420/3000 [02:41<17:14, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 421/3000 [02:41<16:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 422/3000 [02:42<17:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 423/3000 [02:42<16:59, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 424/3000 [02:42<17:00, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 425/3000 [02:43<17:00, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249715.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 426/3000 [02:43<16:49, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 427/3000 [02:44<16:47, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 428/3000 [02:44<16:45, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 429/3000 [02:44<17:08, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 430/3000 [02:45<17:24, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 431/3000 [02:45<17:24, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000080022.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 432/3000 [02:46<17:02, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 433/3000 [02:46<14:41, 2.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 434/3000 [02:46<13:14, 3.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 14%|█▍ | 435/3000 [02:46<11:53, 3.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 436/3000 [02:46<10:55, 3.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 437/3000 [02:47<11:33, 3.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564336.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 438/3000 [02:47<11:26, 3.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 439/3000 [02:47<12:58, 3.29it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 440/3000 [02:48<14:26, 2.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 441/3000 [02:48<15:04, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 442/3000 [02:49<15:52, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 443/3000 [02:49<16:09, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000231589.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 444/3000 [02:49<16:29, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 445/3000 [02:50<16:57, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 446/3000 [02:50<16:47, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 447/3000 [02:51<16:43, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 448/3000 [02:51<16:32, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▍ | 449/3000 [02:51<16:27, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 450/3000 [02:52<16:28, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 451/3000 [02:52<16:38, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 452/3000 [02:53<17:35, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 453/3000 [02:53<17:23, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 454/3000 [02:53<16:57, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 455/3000 [02:54<16:58, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000083275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 456/3000 [02:54<16:57, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 457/3000 [02:55<17:05, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 458/3000 [02:55<16:50, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 459/3000 [02:55<16:43, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 460/3000 [02:56<16:47, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 461/3000 [02:56<16:53, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000406403.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 462/3000 [02:57<16:41, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 463/3000 [02:57<16:49, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 15%|█▌ | 464/3000 [02:57<16:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 465/3000 [02:58<16:56, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 466/3000 [02:58<17:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a scissors in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a scissors in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 467/3000 [02:59<17:07, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000131018.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 468/3000 [02:59<17:09, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 469/3000 [02:59<16:57, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 470/3000 [03:00<17:03, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 471/3000 [03:00<16:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 472/3000 [03:01<16:39, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 473/3000 [03:01<16:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332625.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 474/3000 [03:01<16:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 475/3000 [03:02<13:48, 3.05it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 476/3000 [03:02<11:37, 3.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 477/3000 [03:02<09:46, 4.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 478/3000 [03:02<08:40, 4.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 479/3000 [03:02<07:40, 5.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332025.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 480/3000 [03:02<07:04, 5.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 481/3000 [03:03<09:47, 4.29it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 482/3000 [03:03<11:43, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 483/3000 [03:03<13:05, 3.21it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 484/3000 [03:04<13:59, 3.00it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sheep in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sheep in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 485/3000 [03:04<14:37, 2.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 486/3000 [03:05<15:36, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▌ | 487/3000 [03:05<14:47, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 488/3000 [03:05<13:58, 3.00it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 489/3000 [03:06<13:26, 3.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 490/3000 [03:06<13:06, 3.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 491/3000 [03:06<12:58, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000455157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 492/3000 [03:06<12:48, 3.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 493/3000 [03:07<10:39, 3.92it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 494/3000 [03:07<09:05, 4.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 16%|█▋ | 495/3000 [03:07<08:18, 5.03it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 496/3000 [03:07<07:27, 5.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 497/3000 [03:07<06:52, 6.06it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069189.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 498/3000 [03:07<06:43, 6.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 499/3000 [03:08<09:30, 4.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 500/3000 [03:08<11:58, 3.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 501/3000 [03:08<13:01, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 502/3000 [03:09<13:54, 2.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 503/3000 [03:09<14:36, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199764.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 504/3000 [03:10<15:10, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 505/3000 [03:10<15:22, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 506/3000 [03:10<15:48, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 507/3000 [03:11<16:19, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 508/3000 [03:11<16:15, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 509/3000 [03:12<16:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000148766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 510/3000 [03:12<16:29, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 511/3000 [03:12<16:15, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 512/3000 [03:13<16:07, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 513/3000 [03:13<16:31, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 514/3000 [03:14<16:34, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 515/3000 [03:14<16:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175506.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 516/3000 [03:14<16:09, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 517/3000 [03:15<16:03, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 518/3000 [03:15<15:55, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 519/3000 [03:15<16:08, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 520/3000 [03:16<16:10, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 521/3000 [03:16<16:01, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000353096.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 522/3000 [03:17<16:29, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 523/3000 [03:17<16:47, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 17%|█▋ | 524/3000 [03:18<16:35, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 525/3000 [03:18<16:18, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 526/3000 [03:18<16:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 527/3000 [03:19<16:29, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000207205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 528/3000 [03:19<16:12, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 529/3000 [03:20<16:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 530/3000 [03:20<16:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 531/3000 [03:20<16:15, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 532/3000 [03:21<16:41, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 533/3000 [03:21<17:03, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000427113.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 534/3000 [03:22<16:40, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 535/3000 [03:22<16:35, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 536/3000 [03:22<16:22, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 537/3000 [03:23<16:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 538/3000 [03:23<16:27, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 539/3000 [03:24<16:19, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498374.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 540/3000 [03:24<16:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 541/3000 [03:24<16:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 542/3000 [03:25<16:00, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 543/3000 [03:25<16:06, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 544/3000 [03:26<16:28, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 545/3000 [03:26<16:36, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000013348.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 546/3000 [03:26<16:20, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 547/3000 [03:27<16:26, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 548/3000 [03:27<16:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 549/3000 [03:28<16:16, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 550/3000 [03:28<16:05, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 551/3000 [03:28<15:58, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000081336.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 552/3000 [03:29<16:32, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 553/3000 [03:29<16:33, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 554/3000 [03:30<16:22, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 18%|█▊ | 555/3000 [03:30<16:19, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 556/3000 [03:30<16:01, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 557/3000 [03:31<15:53, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 558/3000 [03:31<16:18, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 559/3000 [03:31<16:17, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 560/3000 [03:32<16:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 561/3000 [03:32<15:50, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▊ | 562/3000 [03:33<15:58, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 563/3000 [03:33<15:57, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 564/3000 [03:33<15:49, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 565/3000 [03:34<15:47, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 566/3000 [03:34<15:42, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 567/3000 [03:35<16:21, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 568/3000 [03:35<16:32, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 569/3000 [03:35<16:23, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227227.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 570/3000 [03:36<16:10, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 571/3000 [03:36<16:08, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 572/3000 [03:37<16:07, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 573/3000 [03:37<15:57, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 574/3000 [03:37<16:13, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 575/3000 [03:38<17:19, 2.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397705.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 576/3000 [03:38<16:42, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 577/3000 [03:39<16:27, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 578/3000 [03:39<16:29, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 579/3000 [03:39<16:07, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 580/3000 [03:40<16:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 581/3000 [03:40<15:49, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287305.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 582/3000 [03:41<16:19, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 583/3000 [03:41<16:26, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 19%|█▉ | 584/3000 [03:42<16:09, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 585/3000 [03:42<15:59, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 586/3000 [03:42<15:46, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 587/3000 [03:43<15:51, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000257327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 588/3000 [03:43<16:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 589/3000 [03:43<16:10, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 590/3000 [03:44<16:18, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 591/3000 [03:44<15:59, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 592/3000 [03:45<15:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 593/3000 [03:45<15:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000557016.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 594/3000 [03:45<15:36, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 595/3000 [03:46<15:36, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 596/3000 [03:46<15:52, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 597/3000 [03:47<15:43, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 598/3000 [03:47<16:00, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|█▉ | 599/3000 [03:47<16:05, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000105732.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 600/3000 [03:48<16:17, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 601/3000 [03:48<15:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 602/3000 [03:49<15:47, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 603/3000 [03:49<15:46, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 604/3000 [03:49<15:51, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 605/3000 [03:50<15:59, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534121.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 606/3000 [03:50<15:44, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 607/3000 [03:51<15:46, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 608/3000 [03:51<15:38, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 609/3000 [03:51<15:32, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 610/3000 [03:52<15:37, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 611/3000 [03:52<15:27, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000520524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 612/3000 [03:53<16:21, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 613/3000 [03:53<16:24, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 614/3000 [03:53<16:33, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 20%|██ | 615/3000 [03:54<16:14, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 616/3000 [03:54<16:24, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 617/3000 [03:55<16:05, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000580294.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 618/3000 [03:55<15:47, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 619/3000 [03:55<15:46, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 620/3000 [03:56<15:50, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 621/3000 [03:56<15:37, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 622/3000 [03:57<15:33, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 623/3000 [03:57<15:34, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000374061.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 624/3000 [03:57<15:27, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 625/3000 [03:58<16:00, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 626/3000 [03:58<16:25, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 627/3000 [03:59<16:22, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 628/3000 [03:59<16:12, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 629/3000 [03:59<15:53, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094944.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 630/3000 [04:00<15:44, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 631/3000 [04:00<15:30, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 632/3000 [04:01<15:20, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 633/3000 [04:01<15:15, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 634/3000 [04:01<15:13, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 635/3000 [04:02<15:29, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 636/3000 [04:02<15:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██ | 637/3000 [04:03<15:22, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 638/3000 [04:03<15:19, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 639/3000 [04:03<15:14, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 640/3000 [04:04<15:16, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 641/3000 [04:04<15:12, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000387098.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 642/3000 [04:05<15:57, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 643/3000 [04:05<16:02, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 21%|██▏ | 644/3000 [04:05<15:44, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 645/3000 [04:06<15:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 646/3000 [04:06<15:25, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 647/3000 [04:07<15:17, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382670.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 648/3000 [04:07<15:28, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 649/3000 [04:07<15:28, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 650/3000 [04:08<15:30, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 651/3000 [04:08<15:32, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 652/3000 [04:09<15:22, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 653/3000 [04:09<15:19, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000414516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 654/3000 [04:09<15:11, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 655/3000 [04:10<15:25, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 656/3000 [04:10<15:13, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 657/3000 [04:10<15:29, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 658/3000 [04:11<15:56, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 659/3000 [04:11<15:45, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204360.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 660/3000 [04:12<15:50, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 661/3000 [04:12<15:29, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 662/3000 [04:12<15:19, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 663/3000 [04:13<15:11, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 664/3000 [04:13<15:19, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sheep in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sheep in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 665/3000 [04:14<15:10, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 666/3000 [04:14<15:08, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 667/3000 [04:14<12:10, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 668/3000 [04:14<10:18, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 669/3000 [04:14<08:43, 4.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 670/3000 [04:15<07:41, 5.04it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 671/3000 [04:15<07:04, 5.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000237767.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 672/3000 [04:15<06:29, 5.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 673/3000 [04:15<08:54, 4.35it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▏ | 674/3000 [04:16<10:46, 3.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 22%|██▎ | 675/3000 [04:16<11:58, 3.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 676/3000 [04:16<12:49, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 677/3000 [04:17<14:03, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000370900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 678/3000 [04:17<14:40, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 679/3000 [04:18<13:46, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 680/3000 [04:18<13:05, 2.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 681/3000 [04:18<12:30, 3.09it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 682/3000 [04:18<12:03, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 683/3000 [04:19<11:50, 3.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000094501.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 684/3000 [04:19<11:53, 3.25it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 685/3000 [04:19<12:58, 2.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 686/3000 [04:20<13:56, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 687/3000 [04:20<14:13, 2.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 688/3000 [04:21<14:28, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 689/3000 [04:21<14:53, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069196.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 690/3000 [04:21<15:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 691/3000 [04:22<15:00, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 692/3000 [04:22<14:59, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 693/3000 [04:23<15:23, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 694/3000 [04:23<15:21, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 695/3000 [04:23<15:24, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000366141.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 696/3000 [04:24<15:10, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 697/3000 [04:24<15:03, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 698/3000 [04:25<14:58, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 699/3000 [04:25<14:55, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 700/3000 [04:25<14:56, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 701/3000 [04:26<15:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093946.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 702/3000 [04:26<15:19, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 703/3000 [04:27<15:27, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 23%|██▎ | 704/3000 [04:27<15:18, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 705/3000 [04:27<15:07, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 706/3000 [04:28<14:57, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 707/3000 [04:28<14:57, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000032610.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 708/3000 [04:29<15:26, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 709/3000 [04:29<15:45, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 710/3000 [04:29<15:46, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 711/3000 [04:30<15:34, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▎ | 712/3000 [04:30<15:11, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 713/3000 [04:31<15:01, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239130.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 714/3000 [04:31<14:57, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 715/3000 [04:31<14:51, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 716/3000 [04:32<15:03, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 717/3000 [04:32<14:51, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 718/3000 [04:33<15:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 719/3000 [04:33<14:53, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000226097.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 720/3000 [04:33<14:51, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 721/3000 [04:34<14:50, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 722/3000 [04:34<14:41, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 723/3000 [04:35<15:12, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 724/3000 [04:35<15:20, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 725/3000 [04:35<15:20, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000538054.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 726/3000 [04:36<15:12, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 727/3000 [04:36<15:03, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 728/3000 [04:37<15:07, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 729/3000 [04:37<14:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 730/3000 [04:37<14:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sheep in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sheep in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 731/3000 [04:38<14:56, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114710.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 732/3000 [04:38<14:53, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 733/3000 [04:38<14:45, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 734/3000 [04:39<14:49, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 24%|██▍ | 735/3000 [04:39<14:42, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 736/3000 [04:40<14:54, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 737/3000 [04:40<14:53, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000113701.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 738/3000 [04:40<15:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 739/3000 [04:41<15:37, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 740/3000 [04:41<15:45, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 741/3000 [04:42<15:21, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 742/3000 [04:42<15:14, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 743/3000 [04:43<15:01, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000065001.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 744/3000 [04:43<14:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 745/3000 [04:43<15:10, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 746/3000 [04:44<15:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 747/3000 [04:44<15:03, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 748/3000 [04:45<15:15, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▍ | 749/3000 [04:45<14:59, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482275.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 750/3000 [04:45<14:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toothbrush in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toothbrush in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 751/3000 [04:46<15:07, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 752/3000 [04:46<15:02, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 753/3000 [04:47<14:50, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 754/3000 [04:47<15:18, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 755/3000 [04:47<15:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000140983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 756/3000 [04:48<14:49, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 757/3000 [04:48<15:04, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 758/3000 [04:49<14:48, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 759/3000 [04:49<14:37, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 760/3000 [04:49<14:34, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 761/3000 [04:50<14:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044520.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 762/3000 [04:50<14:39, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toaster in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a toaster in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 763/3000 [04:51<14:40, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 25%|██▌ | 764/3000 [04:51<14:45, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 765/3000 [04:51<14:33, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 766/3000 [04:52<14:32, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a microwave in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a microwave in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 767/3000 [04:52<14:24, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000518177.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 768/3000 [04:52<14:38, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 769/3000 [04:53<14:45, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 770/3000 [04:53<14:40, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 771/3000 [04:54<14:26, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 772/3000 [04:54<14:19, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 773/3000 [04:54<14:32, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000203479.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 774/3000 [04:55<14:26, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 775/3000 [04:55<14:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 776/3000 [04:56<14:30, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 777/3000 [04:56<14:28, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 778/3000 [04:56<14:25, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 779/3000 [04:57<14:44, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551881.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 780/3000 [04:57<14:39, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 781/3000 [04:58<14:27, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 782/3000 [04:58<14:31, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 783/3000 [04:58<14:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 784/3000 [04:59<14:55, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 785/3000 [04:59<14:37, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000369541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 786/3000 [05:00<14:48, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▌ | 787/3000 [05:00<14:43, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 788/3000 [05:00<14:32, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 789/3000 [05:01<14:32, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 790/3000 [05:01<14:48, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 791/3000 [05:02<14:45, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000007795.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 792/3000 [05:02<14:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 793/3000 [05:02<14:26, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 794/3000 [05:03<14:16, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 26%|██▋ | 795/3000 [05:03<14:18, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 796/3000 [05:03<14:09, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 797/3000 [05:04<14:05, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303099.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 798/3000 [05:04<14:02, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 799/3000 [05:04<11:35, 3.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 800/3000 [05:05<11:03, 3.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 801/3000 [05:05<09:24, 3.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 802/3000 [05:05<08:00, 4.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 803/3000 [05:05<07:07, 5.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147289.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 804/3000 [05:05<06:28, 5.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 805/3000 [05:06<08:47, 4.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 806/3000 [05:06<10:31, 3.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 807/3000 [05:06<11:33, 3.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 808/3000 [05:07<12:24, 2.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 809/3000 [05:07<12:49, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102439.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 810/3000 [05:08<13:19, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 811/3000 [05:08<13:31, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 812/3000 [05:08<13:42, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 813/3000 [05:09<13:48, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 814/3000 [05:09<13:59, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 815/3000 [05:10<14:09, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 816/3000 [05:10<14:12, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 817/3000 [05:10<14:03, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 818/3000 [05:11<14:22, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 819/3000 [05:11<14:36, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 820/3000 [05:12<14:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 821/3000 [05:12<14:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500473.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 822/3000 [05:12<14:35, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 823/3000 [05:13<14:19, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 27%|██▋ | 824/3000 [05:13<14:24, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 825/3000 [05:14<14:38, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 826/3000 [05:14<14:24, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 827/3000 [05:14<14:39, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327532.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 828/3000 [05:15<14:40, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 829/3000 [05:15<14:35, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 830/3000 [05:16<14:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 831/3000 [05:16<14:21, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 832/3000 [05:16<14:36, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 833/3000 [05:17<14:26, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167110.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 834/3000 [05:17<14:39, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 835/3000 [05:17<11:42, 3.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 836/3000 [05:17<09:52, 3.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 837/3000 [05:18<08:19, 4.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 838/3000 [05:18<07:14, 4.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 839/3000 [05:18<06:40, 5.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000300876.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 840/3000 [05:18<06:13, 5.79it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 841/3000 [05:18<08:35, 4.18it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 842/3000 [05:19<10:24, 3.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 843/3000 [05:19<11:24, 3.15it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 844/3000 [05:20<12:25, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 845/3000 [05:20<12:55, 2.78it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000443240.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 846/3000 [05:20<13:09, 2.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 847/3000 [05:21<13:28, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 848/3000 [05:21<13:36, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 849/3000 [05:22<13:41, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 850/3000 [05:22<14:11, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 851/3000 [05:22<14:20, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288042.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 852/3000 [05:23<14:36, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 853/3000 [05:23<14:21, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 854/3000 [05:24<14:13, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 28%|██▊ | 855/3000 [05:24<14:23, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 856/3000 [05:24<14:15, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 857/3000 [05:25<14:16, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000270609.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 858/3000 [05:25<14:18, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a keyboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 859/3000 [05:26<14:05, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 860/3000 [05:26<14:25, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 861/3000 [05:26<14:12, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▊ | 862/3000 [05:27<14:08, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 863/3000 [05:27<14:08, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000208028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 864/3000 [05:28<13:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 865/3000 [05:28<13:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 866/3000 [05:28<14:18, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 867/3000 [05:29<14:41, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 868/3000 [05:29<14:19, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 869/3000 [05:30<14:28, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000314992.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 870/3000 [05:30<15:04, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 871/3000 [05:30<14:54, 2.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 872/3000 [05:31<14:33, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 873/3000 [05:31<14:23, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 874/3000 [05:32<14:25, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 875/3000 [05:32<14:13, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424642.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 876/3000 [05:32<14:05, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 877/3000 [05:33<13:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 878/3000 [05:33<14:05, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 879/3000 [05:34<14:04, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 880/3000 [05:34<14:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 881/3000 [05:34<13:55, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467176.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 882/3000 [05:35<14:24, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 883/3000 [05:35<12:15, 2.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 29%|██▉ | 884/3000 [05:35<10:56, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 885/3000 [05:36<09:47, 3.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 886/3000 [05:36<09:21, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 887/3000 [05:36<08:59, 3.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000087435.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 888/3000 [05:36<08:32, 4.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 889/3000 [05:36<07:24, 4.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 890/3000 [05:36<06:40, 5.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 891/3000 [05:37<06:00, 5.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 892/3000 [05:37<05:37, 6.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 893/3000 [05:37<05:22, 6.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079446.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 894/3000 [05:37<05:05, 6.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 895/3000 [05:37<07:32, 4.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 896/3000 [05:38<09:23, 3.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 897/3000 [05:38<11:23, 3.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 898/3000 [05:39<12:22, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|██▉ | 899/3000 [05:39<12:44, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 900/3000 [05:39<13:20, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 901/3000 [05:40<13:16, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 902/3000 [05:40<13:24, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 903/3000 [05:41<13:53, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 904/3000 [05:41<13:54, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 905/3000 [05:41<13:45, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000430052.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 906/3000 [05:42<13:37, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 907/3000 [05:42<13:31, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 908/3000 [05:43<13:30, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 909/3000 [05:43<13:28, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 910/3000 [05:43<13:37, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 911/3000 [05:44<13:33, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000567886.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 912/3000 [05:44<13:26, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 913/3000 [05:45<13:32, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 914/3000 [05:45<13:33, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 30%|███ | 915/3000 [05:45<13:29, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 916/3000 [05:46<13:30, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 917/3000 [05:46<13:32, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000539251.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 918/3000 [05:47<13:57, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 919/3000 [05:47<14:01, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 920/3000 [05:47<14:17, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 921/3000 [05:48<14:01, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 922/3000 [05:48<13:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 923/3000 [05:49<13:35, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000551908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 924/3000 [05:49<13:38, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 925/3000 [05:49<13:48, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 926/3000 [05:50<13:44, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 927/3000 [05:50<13:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 928/3000 [05:50<13:32, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 929/3000 [05:51<13:33, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000102906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 930/3000 [05:51<13:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 931/3000 [05:51<10:59, 3.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 932/3000 [05:52<09:05, 3.79it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 933/3000 [05:52<07:46, 4.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 934/3000 [05:52<06:55, 4.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 935/3000 [05:52<06:15, 5.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 936/3000 [05:52<05:41, 6.05it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███ | 937/3000 [05:53<08:18, 4.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 938/3000 [05:53<10:17, 3.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 939/3000 [05:53<11:06, 3.09it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 940/3000 [05:54<11:54, 2.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 941/3000 [05:54<12:24, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280734.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 942/3000 [05:55<12:38, 2.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 943/3000 [05:55<12:49, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 31%|███▏ | 944/3000 [05:55<12:55, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 945/3000 [05:56<13:05, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 946/3000 [05:56<13:03, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 947/3000 [05:56<13:04, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000111817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 948/3000 [05:57<13:08, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 949/3000 [05:57<13:16, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 950/3000 [05:58<13:22, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 951/3000 [05:58<13:28, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 952/3000 [05:58<13:21, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 953/3000 [05:59<13:40, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 954/3000 [05:59<13:46, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 955/3000 [06:00<13:33, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 956/3000 [06:00<13:36, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 957/3000 [06:00<13:34, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 958/3000 [06:01<13:25, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 959/3000 [06:01<13:28, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000489728.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 960/3000 [06:02<13:43, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 961/3000 [06:02<13:35, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 962/3000 [06:02<13:24, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 963/3000 [06:03<14:01, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 964/3000 [06:03<13:57, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 965/3000 [06:04<14:03, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000419453.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 966/3000 [06:04<14:02, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 967/3000 [06:04<12:31, 2.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 968/3000 [06:05<11:38, 2.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 969/3000 [06:05<10:43, 3.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 970/3000 [06:05<10:09, 3.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 971/3000 [06:05<09:39, 3.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 4 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000358255.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 972/3000 [06:06<09:20, 3.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 973/3000 [06:06<10:22, 3.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▏ | 974/3000 [06:06<11:06, 3.04it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 32%|███▎ | 975/3000 [06:07<11:37, 2.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 976/3000 [06:07<12:01, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 977/3000 [06:08<12:16, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000178078.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 978/3000 [06:08<12:28, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 979/3000 [06:08<12:35, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 980/3000 [06:09<12:45, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 981/3000 [06:09<12:57, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 982/3000 [06:10<12:55, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 983/3000 [06:10<13:06, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000197219.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 984/3000 [06:10<12:59, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a donut in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a donut in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 985/3000 [06:10<10:43, 3.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 986/3000 [06:11<09:59, 3.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 987/3000 [06:11<08:33, 3.92it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 988/3000 [06:11<07:17, 4.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 989/3000 [06:11<06:29, 5.17it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000460931.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 990/3000 [06:11<05:56, 5.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 991/3000 [06:12<08:09, 4.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 992/3000 [06:12<09:44, 3.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 993/3000 [06:12<10:39, 3.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 994/3000 [06:13<11:34, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 995/3000 [06:13<12:08, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506483.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 996/3000 [06:14<12:30, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 997/3000 [06:14<12:43, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 998/3000 [06:14<12:41, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 999/3000 [06:15<12:45, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 1000/3000 [06:15<12:53, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 1001/3000 [06:16<12:55, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468934.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 1002/3000 [06:16<13:01, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 1003/3000 [06:16<12:59, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 33%|███▎ | 1004/3000 [06:17<13:10, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1005/3000 [06:17<13:09, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1006/3000 [06:18<13:08, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1007/3000 [06:18<13:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000189694.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1008/3000 [06:18<13:08, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1009/3000 [06:19<10:31, 3.15it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1010/3000 [06:19<09:06, 3.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1011/3000 [06:19<07:39, 4.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▎ | 1012/3000 [06:19<06:38, 4.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1013/3000 [06:19<06:08, 5.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000273450.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1014/3000 [06:19<05:37, 5.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1015/3000 [06:20<07:40, 4.31it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1016/3000 [06:20<09:13, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1017/3000 [06:20<10:19, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1018/3000 [06:21<11:06, 2.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1019/3000 [06:21<11:40, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278226.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1020/3000 [06:22<12:28, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1021/3000 [06:22<12:32, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1022/3000 [06:22<12:59, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1023/3000 [06:23<13:13, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1024/3000 [06:23<12:57, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1025/3000 [06:24<13:03, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000449432.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1026/3000 [06:24<13:10, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1027/3000 [06:24<13:00, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1028/3000 [06:25<13:07, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1029/3000 [06:25<12:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1030/3000 [06:26<13:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1031/3000 [06:26<12:56, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153300.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1032/3000 [06:26<12:48, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1033/3000 [06:27<12:48, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1034/3000 [06:27<12:46, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 34%|███▍ | 1035/3000 [06:28<12:51, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1036/3000 [06:28<12:46, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1037/3000 [06:28<12:42, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000506178.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1038/3000 [06:29<12:59, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1039/3000 [06:29<13:02, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1040/3000 [06:30<13:21, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1041/3000 [06:30<13:05, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1042/3000 [06:30<13:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1043/3000 [06:31<13:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000249720.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1044/3000 [06:31<12:53, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1045/3000 [06:32<13:18, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1046/3000 [06:32<13:09, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1047/3000 [06:32<12:59, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1048/3000 [06:33<12:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▍ | 1049/3000 [06:33<12:53, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000205206.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1050/3000 [06:34<12:58, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1051/3000 [06:34<12:52, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1052/3000 [06:34<13:07, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1053/3000 [06:35<13:25, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1054/3000 [06:35<13:12, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1055/3000 [06:36<13:20, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018150.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1056/3000 [06:36<13:08, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1057/3000 [06:36<12:52, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1058/3000 [06:37<12:44, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1059/3000 [06:37<12:37, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1060/3000 [06:38<12:53, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1061/3000 [06:38<12:46, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303534.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1062/3000 [06:38<12:53, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1063/3000 [06:39<12:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 35%|███▌ | 1064/3000 [06:39<12:44, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1065/3000 [06:40<12:57, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1066/3000 [06:40<13:00, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1067/3000 [06:40<12:55, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000278771.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1068/3000 [06:41<13:11, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1069/3000 [06:41<12:56, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1070/3000 [06:42<12:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1071/3000 [06:42<12:40, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1072/3000 [06:42<12:32, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1073/3000 [06:43<12:29, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000134075.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1074/3000 [06:43<12:25, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1075/3000 [06:44<12:33, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1076/3000 [06:44<12:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1077/3000 [06:44<12:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1078/3000 [06:45<12:35, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1079/3000 [06:45<12:29, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000227204.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1080/3000 [06:46<12:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1081/3000 [06:46<12:44, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1082/3000 [06:46<12:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1083/3000 [06:47<13:05, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1084/3000 [06:47<13:02, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1085/3000 [06:48<13:02, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124629.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1086/3000 [06:48<12:46, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▌ | 1087/3000 [06:48<12:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1088/3000 [06:49<12:33, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1089/3000 [06:49<12:28, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1090/3000 [06:50<12:38, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1091/3000 [06:50<12:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142774.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1092/3000 [06:50<12:49, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1093/3000 [06:51<12:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1094/3000 [06:51<12:41, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 36%|███▋ | 1095/3000 [06:52<12:32, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1096/3000 [06:52<12:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1097/3000 [06:52<12:30, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1098/3000 [06:53<12:52, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1099/3000 [06:53<12:41, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1100/3000 [06:54<12:35, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1101/3000 [06:54<12:25, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1102/3000 [06:54<12:28, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1103/3000 [06:55<12:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316700.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1104/3000 [06:55<12:31, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1105/3000 [06:56<12:38, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1106/3000 [06:56<12:27, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1107/3000 [06:56<12:39, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1108/3000 [06:57<12:46, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1109/3000 [06:57<12:53, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000040361.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1110/3000 [06:58<13:00, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1111/3000 [06:58<12:39, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1112/3000 [06:58<12:26, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1113/3000 [06:59<12:56, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1114/3000 [06:59<12:44, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1115/3000 [07:00<12:40, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378873.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1116/3000 [07:00<12:30, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1117/3000 [07:00<12:45, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1118/3000 [07:01<12:35, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1119/3000 [07:01<12:24, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1120/3000 [07:02<12:41, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1121/3000 [07:02<12:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574790.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1122/3000 [07:02<12:21, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1123/3000 [07:03<12:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 37%|███▋ | 1124/3000 [07:03<12:22, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1125/3000 [07:04<12:18, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1126/3000 [07:04<12:16, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1127/3000 [07:04<12:10, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000011241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1128/3000 [07:05<12:23, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1129/3000 [07:05<12:14, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1130/3000 [07:05<12:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1131/3000 [07:06<12:07, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1132/3000 [07:06<12:14, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1133/3000 [07:07<12:29, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000525667.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1134/3000 [07:07<12:35, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1135/3000 [07:08<12:51, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1136/3000 [07:08<12:33, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1137/3000 [07:08<12:25, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1138/3000 [07:09<12:19, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1139/3000 [07:09<12:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246145.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1140/3000 [07:09<12:20, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1141/3000 [07:10<09:51, 3.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1142/3000 [07:10<08:19, 3.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1143/3000 [07:10<07:00, 4.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1144/3000 [07:10<06:05, 5.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1145/3000 [07:10<05:39, 5.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313162.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1146/3000 [07:10<05:15, 5.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1147/3000 [07:11<07:22, 4.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1148/3000 [07:11<08:46, 3.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1149/3000 [07:12<09:53, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1150/3000 [07:12<10:32, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1151/3000 [07:12<11:12, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000529668.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1152/3000 [07:13<11:39, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1153/3000 [07:13<11:42, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1154/3000 [07:14<11:55, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 38%|███▊ | 1155/3000 [07:14<11:55, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1156/3000 [07:14<11:58, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1157/3000 [07:15<12:16, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000376959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1158/3000 [07:15<12:19, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1159/3000 [07:16<12:07, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1160/3000 [07:16<12:25, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1161/3000 [07:16<12:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▊ | 1162/3000 [07:17<12:11, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1163/3000 [07:17<12:05, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000275863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1164/3000 [07:18<11:59, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1165/3000 [07:18<10:32, 2.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1166/3000 [07:18<09:16, 3.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1167/3000 [07:18<08:17, 3.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1168/3000 [07:18<07:36, 4.01it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1169/3000 [07:19<07:11, 4.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000327038.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1170/3000 [07:19<06:59, 4.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1171/3000 [07:19<08:26, 3.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1172/3000 [07:20<09:29, 3.21it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1173/3000 [07:20<10:15, 2.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1174/3000 [07:20<10:54, 2.79it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1175/3000 [07:21<11:22, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000513136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1176/3000 [07:21<11:24, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1177/3000 [07:22<11:28, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1178/3000 [07:22<11:29, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1179/3000 [07:22<11:38, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1180/3000 [07:23<12:03, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1181/3000 [07:23<11:55, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000184338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1182/3000 [07:24<12:01, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1183/3000 [07:24<11:54, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 39%|███▉ | 1184/3000 [07:24<11:48, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1185/3000 [07:25<12:00, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1186/3000 [07:25<11:57, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a donut in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a donut in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1187/3000 [07:26<12:18, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000175437.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1188/3000 [07:26<12:07, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1189/3000 [07:26<12:07, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1190/3000 [07:27<12:04, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1191/3000 [07:27<11:52, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1192/3000 [07:27<11:49, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1193/3000 [07:28<12:02, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000498100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1194/3000 [07:28<12:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a refrigerator in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a refrigerator in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1195/3000 [07:29<12:12, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1196/3000 [07:29<12:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1197/3000 [07:30<12:01, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1198/3000 [07:30<11:53, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|███▉ | 1199/3000 [07:30<11:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000375909.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1200/3000 [07:31<11:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1201/3000 [07:31<11:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1202/3000 [07:32<12:16, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1203/3000 [07:32<11:59, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1204/3000 [07:32<12:09, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1205/3000 [07:33<12:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1206/3000 [07:33<12:14, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1207/3000 [07:34<12:07, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1208/3000 [07:34<12:00, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1209/3000 [07:34<11:59, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1210/3000 [07:35<12:11, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1211/3000 [07:35<11:56, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000124930.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1212/3000 [07:36<11:52, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1213/3000 [07:36<11:48, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1214/3000 [07:36<11:49, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 40%|████ | 1215/3000 [07:37<12:00, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1216/3000 [07:37<11:57, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1217/3000 [07:38<11:59, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000112664.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1218/3000 [07:38<11:49, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1219/3000 [07:38<11:53, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1220/3000 [07:39<12:08, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1221/3000 [07:39<12:05, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1222/3000 [07:40<12:04, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1223/3000 [07:40<12:06, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377879.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1224/3000 [07:40<11:57, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1225/3000 [07:41<11:56, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1226/3000 [07:41<11:49, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1227/3000 [07:42<11:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1228/3000 [07:42<11:42, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1229/3000 [07:42<11:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1230/3000 [07:43<11:52, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1231/3000 [07:43<11:51, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1232/3000 [07:44<11:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1233/3000 [07:44<11:40, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1234/3000 [07:44<11:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1235/3000 [07:45<11:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000049473.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1236/3000 [07:45<11:41, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████ | 1237/3000 [07:46<11:35, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1238/3000 [07:46<11:47, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1239/3000 [07:46<11:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1240/3000 [07:47<11:45, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1241/3000 [07:47<11:36, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000153865.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1242/3000 [07:48<11:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1243/3000 [07:48<11:31, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 41%|████▏ | 1244/3000 [07:48<11:37, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1245/3000 [07:49<11:33, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1246/3000 [07:49<11:29, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1247/3000 [07:50<11:41, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000383185.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1248/3000 [07:50<11:27, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1249/3000 [07:50<11:27, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1250/3000 [07:51<11:27, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1251/3000 [07:51<11:19, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1252/3000 [07:51<11:15, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1253/3000 [07:52<11:12, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388983.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1254/3000 [07:52<11:09, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1255/3000 [07:53<11:42, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1256/3000 [07:53<11:50, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1257/3000 [07:53<11:37, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1258/3000 [07:54<11:28, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1259/3000 [07:54<11:39, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000295377.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1260/3000 [07:55<11:56, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1261/3000 [07:55<11:45, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1262/3000 [07:56<11:53, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1263/3000 [07:56<11:41, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1264/3000 [07:56<11:41, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1265/3000 [07:57<11:35, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000034773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1266/3000 [07:57<11:31, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1267/3000 [07:57<11:27, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1268/3000 [07:58<11:40, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1269/3000 [07:58<11:31, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1270/3000 [07:59<11:58, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1271/3000 [07:59<11:50, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000244455.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1272/3000 [08:00<11:40, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1273/3000 [08:00<11:36, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▏ | 1274/3000 [08:00<11:33, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 42%|████▎ | 1275/3000 [08:01<11:41, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1276/3000 [08:01<11:36, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1277/3000 [08:02<11:24, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1278/3000 [08:02<11:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1279/3000 [08:02<11:23, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1280/3000 [08:03<11:40, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1281/3000 [08:03<11:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1282/3000 [08:04<11:37, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1283/3000 [08:04<11:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000098493.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1284/3000 [08:04<11:35, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1285/3000 [08:05<11:16, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1286/3000 [08:05<09:42, 2.94it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1287/3000 [08:05<08:29, 3.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1288/3000 [08:05<07:44, 3.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1289/3000 [08:06<07:08, 3.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000201148.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1290/3000 [08:06<07:09, 3.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1291/3000 [08:06<08:15, 3.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1292/3000 [08:07<09:03, 3.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1293/3000 [08:07<09:37, 2.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1294/3000 [08:07<10:00, 2.84it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1295/3000 [08:08<10:31, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307166.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1296/3000 [08:08<10:37, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1297/3000 [08:09<10:44, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1298/3000 [08:09<10:47, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1299/3000 [08:09<10:48, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1300/3000 [08:10<10:57, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1301/3000 [08:10<10:53, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000313034.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1302/3000 [08:11<11:23, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1303/3000 [08:11<11:38, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 43%|████▎ | 1304/3000 [08:11<11:34, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1305/3000 [08:12<11:39, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1306/3000 [08:12<11:46, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1307/3000 [08:13<11:39, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1308/3000 [08:13<11:39, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1309/3000 [08:13<11:32, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1310/3000 [08:14<11:44, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1311/3000 [08:14<11:31, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▎ | 1312/3000 [08:15<11:18, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1313/3000 [08:15<11:23, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1314/3000 [08:15<11:18, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1315/3000 [08:16<11:14, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1316/3000 [08:16<11:12, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1317/3000 [08:17<11:29, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1318/3000 [08:17<11:36, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1319/3000 [08:17<11:20, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000526368.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1320/3000 [08:18<11:16, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1321/3000 [08:18<11:10, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1322/3000 [08:19<11:20, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1323/3000 [08:19<11:06, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1324/3000 [08:19<11:20, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1325/3000 [08:20<11:15, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429033.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1326/3000 [08:20<11:08, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1327/3000 [08:21<11:00, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1328/3000 [08:21<11:04, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1329/3000 [08:21<10:59, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1330/3000 [08:22<10:57, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1331/3000 [08:22<10:49, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000287035.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1332/3000 [08:23<11:05, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1333/3000 [08:23<11:08, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1334/3000 [08:23<11:02, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 44%|████▍ | 1335/3000 [08:24<11:14, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1336/3000 [08:24<11:15, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1337/3000 [08:25<11:07, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299074.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1338/3000 [08:25<11:12, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1339/3000 [08:26<11:32, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1340/3000 [08:26<11:27, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1341/3000 [08:26<11:25, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1342/3000 [08:27<11:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1343/3000 [08:27<11:08, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1344/3000 [08:28<11:02, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1345/3000 [08:28<10:52, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1346/3000 [08:28<10:47, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1347/3000 [08:29<10:52, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1348/3000 [08:29<11:12, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▍ | 1349/3000 [08:30<11:14, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000186709.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1350/3000 [08:30<11:24, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1351/3000 [08:30<11:08, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1352/3000 [08:31<11:04, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1353/3000 [08:31<10:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1354/3000 [08:32<10:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1355/3000 [08:32<10:51, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000025972.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1356/3000 [08:32<10:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1357/3000 [08:32<08:39, 3.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1358/3000 [08:33<07:22, 3.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1359/3000 [08:33<06:14, 4.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1360/3000 [08:33<05:33, 4.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1361/3000 [08:33<05:03, 5.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1362/3000 [08:33<04:37, 5.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1363/3000 [08:33<04:24, 6.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 45%|████▌ | 1364/3000 [08:33<04:12, 6.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1365/3000 [08:34<04:07, 6.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1366/3000 [08:34<03:59, 6.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cow in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1367/3000 [08:34<03:51, 7.05it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115636.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1368/3000 [08:34<03:54, 6.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1369/3000 [08:34<05:49, 4.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1370/3000 [08:35<07:32, 3.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1371/3000 [08:35<08:18, 3.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1372/3000 [08:36<09:05, 2.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1373/3000 [08:36<09:28, 2.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000280810.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1374/3000 [08:36<09:48, 2.76it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1375/3000 [08:37<10:05, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1376/3000 [08:37<10:11, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1377/3000 [08:38<10:26, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1378/3000 [08:38<10:38, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1379/3000 [08:38<10:37, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000037900.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1380/3000 [08:39<10:39, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1381/3000 [08:39<10:41, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1382/3000 [08:40<10:41, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1383/3000 [08:40<10:35, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1384/3000 [08:40<10:45, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1385/3000 [08:41<10:42, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1386/3000 [08:41<10:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▌ | 1387/3000 [08:42<10:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1388/3000 [08:42<10:32, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1389/3000 [08:42<10:50, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1390/3000 [08:43<10:44, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1391/3000 [08:43<10:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123017.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1392/3000 [08:44<10:39, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1393/3000 [08:44<10:52, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1394/3000 [08:44<10:59, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 46%|████▋ | 1395/3000 [08:45<11:04, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1396/3000 [08:45<10:49, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1397/3000 [08:46<10:56, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000316237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1398/3000 [08:46<10:58, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1399/3000 [08:46<11:02, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1400/3000 [08:47<11:31, 2.31it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1401/3000 [08:47<11:11, 2.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1402/3000 [08:48<10:55, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1403/3000 [08:48<10:45, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463522.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1404/3000 [08:48<10:45, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1405/3000 [08:49<08:46, 3.03it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1406/3000 [08:49<07:26, 3.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1407/3000 [08:49<06:19, 4.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1408/3000 [08:49<05:36, 4.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1409/3000 [08:49<05:03, 5.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511341.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1410/3000 [08:49<04:47, 5.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1411/3000 [08:50<06:35, 4.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1412/3000 [08:50<07:39, 3.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1413/3000 [08:51<08:29, 3.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1414/3000 [08:51<09:01, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1415/3000 [08:51<09:26, 2.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200583.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1416/3000 [08:52<09:38, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1417/3000 [08:52<09:50, 2.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1418/3000 [08:53<10:08, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1419/3000 [08:53<10:33, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1420/3000 [08:53<10:33, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1421/3000 [08:54<10:23, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000424585.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1422/3000 [08:54<10:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1423/3000 [08:55<10:26, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 47%|████▋ | 1424/3000 [08:55<10:21, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1425/3000 [08:55<10:20, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1426/3000 [08:56<10:16, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1427/3000 [08:56<10:11, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100215.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1428/3000 [08:57<10:22, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1429/3000 [08:57<10:19, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1430/3000 [08:57<10:31, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1431/3000 [08:58<10:21, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1432/3000 [08:58<10:23, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1433/3000 [08:59<10:41, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000017379.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1434/3000 [08:59<11:12, 2.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1435/3000 [08:59<10:53, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1436/3000 [09:00<10:51, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a scissors in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a scissors in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1437/3000 [09:00<10:35, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1438/3000 [09:01<10:29, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1439/3000 [09:01<10:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000511622.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1440/3000 [09:01<10:27, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1441/3000 [09:02<10:27, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1442/3000 [09:02<10:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1443/3000 [09:03<10:14, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1444/3000 [09:03<10:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1445/3000 [09:03<10:24, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000407386.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1446/3000 [09:04<10:18, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1447/3000 [09:04<10:20, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1448/3000 [09:05<10:30, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1449/3000 [09:05<10:39, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1450/3000 [09:05<10:35, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1451/3000 [09:06<10:26, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000039516.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1452/3000 [09:06<10:30, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1453/3000 [09:07<10:22, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1454/3000 [09:07<10:16, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 48%|████▊ | 1455/3000 [09:07<10:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1456/3000 [09:08<10:17, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1457/3000 [09:08<10:23, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000018918.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1458/3000 [09:09<10:17, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1459/3000 [09:09<10:17, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1460/3000 [09:09<10:21, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1461/3000 [09:10<10:18, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▊ | 1462/3000 [09:10<10:11, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a parking meter in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a parking meter in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1463/3000 [09:11<10:34, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000115626.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1464/3000 [09:11<10:18, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1465/3000 [09:11<10:20, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1466/3000 [09:12<10:12, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toothbrush in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a toothbrush in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1467/3000 [09:12<10:15, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1468/3000 [09:13<10:10, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1469/3000 [09:13<10:04, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000391735.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1470/3000 [09:13<10:31, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1471/3000 [09:14<10:25, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1472/3000 [09:14<10:31, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1473/3000 [09:15<10:19, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1474/3000 [09:15<10:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1475/3000 [09:15<10:05, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236370.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1476/3000 [09:16<10:04, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1477/3000 [09:16<10:15, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1478/3000 [09:17<10:35, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1479/3000 [09:17<10:31, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1480/3000 [09:18<10:26, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1481/3000 [09:18<10:12, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463542.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1482/3000 [09:18<10:10, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1483/3000 [09:19<09:59, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 49%|████▉ | 1484/3000 [09:19<10:03, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1485/3000 [09:20<10:05, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1486/3000 [09:20<10:01, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1487/3000 [09:20<09:56, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377352.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1488/3000 [09:21<09:51, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1489/3000 [09:21<09:58, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1490/3000 [09:22<10:09, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1491/3000 [09:22<10:00, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1492/3000 [09:22<10:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1493/3000 [09:23<10:04, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000302405.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1494/3000 [09:23<10:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1495/3000 [09:24<10:08, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1496/3000 [09:24<10:13, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1497/3000 [09:24<10:06, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1498/3000 [09:25<10:00, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|████▉ | 1499/3000 [09:25<10:07, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554328.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1500/3000 [09:26<10:17, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1501/3000 [09:26<10:10, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1502/3000 [09:26<09:59, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1503/3000 [09:27<10:06, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1504/3000 [09:27<10:01, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1505/3000 [09:28<09:55, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384040.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1506/3000 [09:28<09:54, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1507/3000 [09:28<09:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1508/3000 [09:29<09:49, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1509/3000 [09:29<10:05, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1510/3000 [09:30<10:05, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1511/3000 [09:30<09:53, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023731.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1512/3000 [09:30<09:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1513/3000 [09:31<08:02, 3.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1514/3000 [09:31<06:36, 3.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 50%|█████ | 1515/3000 [09:31<05:42, 4.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1516/3000 [09:31<04:59, 4.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1517/3000 [09:31<04:35, 5.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000463640.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1518/3000 [09:31<04:15, 5.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1519/3000 [09:32<05:53, 4.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1520/3000 [09:32<07:07, 3.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1521/3000 [09:32<07:45, 3.18it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1522/3000 [09:33<08:29, 2.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1523/3000 [09:33<08:46, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365822.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1524/3000 [09:34<09:07, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1525/3000 [09:34<09:21, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1526/3000 [09:34<09:40, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1527/3000 [09:35<09:56, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1528/3000 [09:35<09:49, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1529/3000 [09:36<09:56, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000524979.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1530/3000 [09:36<10:02, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1531/3000 [09:36<10:03, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1532/3000 [09:37<09:52, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1533/3000 [09:37<09:50, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1534/3000 [09:38<09:48, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1535/3000 [09:38<09:44, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000070813.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1536/3000 [09:38<09:39, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████ | 1537/3000 [09:39<09:42, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1538/3000 [09:39<09:39, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1539/3000 [09:40<09:32, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1540/3000 [09:40<09:35, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1541/3000 [09:40<09:52, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318209.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1542/3000 [09:41<09:55, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1543/3000 [09:41<09:45, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 51%|█████▏ | 1544/3000 [09:42<09:45, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1545/3000 [09:42<09:39, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1546/3000 [09:42<09:43, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1547/3000 [09:43<09:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016775.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1548/3000 [09:43<09:41, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1549/3000 [09:44<09:34, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1550/3000 [09:44<09:45, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1551/3000 [09:44<09:33, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1552/3000 [09:45<09:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1553/3000 [09:45<09:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015338.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1554/3000 [09:46<09:48, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1555/3000 [09:46<09:46, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1556/3000 [09:47<10:02, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1557/3000 [09:47<10:10, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1558/3000 [09:47<09:58, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an elephant in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an elephant in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1559/3000 [09:48<09:54, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000441156.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1560/3000 [09:48<09:58, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1561/3000 [09:48<09:07, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1562/3000 [09:49<08:24, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1563/3000 [09:49<07:44, 3.09it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1564/3000 [09:49<07:18, 3.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1565/3000 [09:50<07:05, 3.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000408757.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1566/3000 [09:50<06:26, 3.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1567/3000 [09:50<07:14, 3.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1568/3000 [09:51<07:58, 2.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1569/3000 [09:51<08:19, 2.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1570/3000 [09:51<08:39, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1571/3000 [09:52<08:44, 2.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1572/3000 [09:52<09:01, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1573/3000 [09:52<07:51, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▏ | 1574/3000 [09:53<07:03, 3.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 52%|█████▎ | 1575/3000 [09:53<06:52, 3.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1576/3000 [09:53<06:14, 3.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1577/3000 [09:53<05:48, 4.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000204100.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1578/3000 [09:53<05:36, 4.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1579/3000 [09:54<05:33, 4.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1580/3000 [09:54<05:41, 4.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1581/3000 [09:54<05:28, 4.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1582/3000 [09:54<05:21, 4.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1583/3000 [09:55<05:27, 4.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468169.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1584/3000 [09:55<05:19, 4.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1585/3000 [09:55<06:25, 3.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1586/3000 [09:56<07:19, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1587/3000 [09:56<07:58, 2.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1588/3000 [09:56<08:17, 2.84it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1589/3000 [09:57<08:32, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198312.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1590/3000 [09:57<08:55, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1591/3000 [09:58<09:08, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1592/3000 [09:58<09:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1593/3000 [09:58<09:24, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1594/3000 [09:59<09:30, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an elephant in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an elephant in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1595/3000 [09:59<09:46, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000485485.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1596/3000 [10:00<09:55, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1597/3000 [10:00<08:00, 2.92it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1598/3000 [10:00<06:31, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1599/3000 [10:00<05:40, 4.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1600/3000 [10:00<05:00, 4.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1601/3000 [10:00<04:24, 5.28it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000309371.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1602/3000 [10:01<04:04, 5.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1603/3000 [10:01<04:55, 4.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 53%|█████▎ | 1604/3000 [10:01<05:28, 4.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1605/3000 [10:01<05:58, 3.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1606/3000 [10:02<06:21, 3.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1607/3000 [10:02<06:35, 3.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472143.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1608/3000 [10:02<06:41, 3.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1609/3000 [10:03<07:19, 3.17it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1610/3000 [10:03<07:53, 2.94it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1611/3000 [10:04<08:07, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▎ | 1612/3000 [10:04<08:20, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1613/3000 [10:04<08:30, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000236023.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1614/3000 [10:05<08:50, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1615/3000 [10:05<09:08, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1616/3000 [10:06<09:06, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1617/3000 [10:06<09:02, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1618/3000 [10:06<09:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1619/3000 [10:07<09:11, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214244.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1620/3000 [10:07<09:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1621/3000 [10:08<09:13, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1622/3000 [10:08<09:07, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1623/3000 [10:08<09:02, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1624/3000 [10:09<09:07, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1625/3000 [10:09<09:10, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000397665.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1626/3000 [10:10<09:04, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1627/3000 [10:10<09:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1628/3000 [10:10<08:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1629/3000 [10:11<09:06, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1630/3000 [10:11<09:18, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a hot dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a hot dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1631/3000 [10:12<09:24, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000183965.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1632/3000 [10:12<09:17, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1633/3000 [10:12<09:09, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 54%|█████▍ | 1634/3000 [10:13<09:00, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1635/3000 [10:13<09:10, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1636/3000 [10:14<09:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1637/3000 [10:14<09:15, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000499105.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1638/3000 [10:14<09:07, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1639/3000 [10:15<09:09, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1640/3000 [10:15<09:19, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1641/3000 [10:16<09:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1642/3000 [10:16<09:06, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1643/3000 [10:16<09:14, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000259755.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1644/3000 [10:17<09:27, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1645/3000 [10:17<09:13, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1646/3000 [10:18<09:12, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1647/3000 [10:18<09:06, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1648/3000 [10:18<09:05, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▍ | 1649/3000 [10:19<08:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281028.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1650/3000 [10:19<08:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1651/3000 [10:20<08:58, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1652/3000 [10:20<08:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1653/3000 [10:20<08:52, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1654/3000 [10:21<08:59, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1655/3000 [10:21<09:11, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199122.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1656/3000 [10:22<09:12, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1657/3000 [10:22<09:02, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1658/3000 [10:22<09:04, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1659/3000 [10:23<09:08, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1660/3000 [10:23<09:11, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1661/3000 [10:24<08:58, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000442809.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1662/3000 [10:24<08:49, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1663/3000 [10:24<08:56, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 55%|█████▌ | 1664/3000 [10:25<08:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1665/3000 [10:25<08:55, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1666/3000 [10:26<08:56, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1667/3000 [10:26<08:57, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000482829.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1668/3000 [10:26<08:49, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1669/3000 [10:27<08:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1670/3000 [10:27<08:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1671/3000 [10:28<08:43, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1672/3000 [10:28<08:40, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1673/3000 [10:28<08:54, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000097994.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1674/3000 [10:29<09:03, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1675/3000 [10:29<08:54, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1676/3000 [10:30<08:52, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1677/3000 [10:30<08:44, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1678/3000 [10:30<08:48, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1679/3000 [10:31<08:42, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246999.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1680/3000 [10:31<08:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1681/3000 [10:32<08:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1682/3000 [10:32<08:53, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1683/3000 [10:32<08:48, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1684/3000 [10:33<08:53, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1685/3000 [10:33<08:42, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000338291.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1686/3000 [10:34<08:39, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▌ | 1687/3000 [10:34<08:33, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1688/3000 [10:34<08:50, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1689/3000 [10:35<09:01, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1690/3000 [10:35<09:02, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1691/3000 [10:36<08:56, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000331366.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1692/3000 [10:36<08:47, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1693/3000 [10:37<08:54, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1694/3000 [10:37<08:50, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 56%|█████▋ | 1695/3000 [10:37<08:50, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1696/3000 [10:38<08:42, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1697/3000 [10:38<08:44, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1698/3000 [10:39<08:37, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1699/3000 [10:39<08:32, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1700/3000 [10:39<08:38, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1701/3000 [10:40<08:33, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1702/3000 [10:40<08:28, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1703/3000 [10:41<08:51, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000108189.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1704/3000 [10:41<08:59, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1705/3000 [10:41<07:08, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1706/3000 [10:41<05:56, 3.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1707/3000 [10:41<05:03, 4.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1708/3000 [10:42<04:22, 4.92it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1709/3000 [10:42<03:57, 5.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000301575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1710/3000 [10:42<03:45, 5.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1711/3000 [10:42<05:12, 4.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1712/3000 [10:43<06:06, 3.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1713/3000 [10:43<06:44, 3.18it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1714/3000 [10:43<07:09, 2.99it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1715/3000 [10:44<07:38, 2.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000239773.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1716/3000 [10:44<07:57, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1717/3000 [10:45<08:03, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1718/3000 [10:45<08:07, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1719/3000 [10:45<08:09, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1720/3000 [10:46<08:15, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1721/3000 [10:46<08:15, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a keyboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000354976.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1722/3000 [10:47<08:21, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1723/3000 [10:47<08:31, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▋ | 1724/3000 [10:47<08:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 57%|█████▊ | 1725/3000 [10:48<08:29, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1726/3000 [10:48<08:29, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1727/3000 [10:49<08:23, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000473199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1728/3000 [10:49<08:20, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1729/3000 [10:49<06:49, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1730/3000 [10:49<05:42, 3.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1731/3000 [10:49<04:56, 4.29it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1732/3000 [10:50<04:29, 4.71it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1733/3000 [10:50<04:05, 5.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000311759.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1734/3000 [10:50<03:41, 5.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1735/3000 [10:50<05:04, 4.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1736/3000 [10:51<06:00, 3.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1737/3000 [10:51<06:38, 3.17it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1738/3000 [10:51<07:13, 2.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1739/3000 [10:52<07:34, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000431615.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1740/3000 [10:52<07:52, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1741/3000 [10:53<08:31, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1742/3000 [10:53<08:22, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1743/3000 [10:53<08:29, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1744/3000 [10:54<08:29, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1745/3000 [10:54<08:23, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343401.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1746/3000 [10:55<08:29, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1747/3000 [10:55<08:27, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1748/3000 [10:56<08:29, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1749/3000 [10:56<08:33, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1750/3000 [10:56<08:35, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1751/3000 [10:57<08:34, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246199.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1752/3000 [10:57<08:28, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1753/3000 [10:57<07:33, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1754/3000 [10:58<06:42, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 58%|█████▊ | 1755/3000 [10:58<05:56, 3.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1756/3000 [10:58<05:37, 3.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1757/3000 [10:58<05:09, 4.01it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372009.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1758/3000 [10:59<05:22, 3.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1759/3000 [10:59<06:14, 3.31it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1760/3000 [10:59<06:56, 2.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1761/3000 [11:00<07:22, 2.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▊ | 1762/3000 [11:00<07:35, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1763/3000 [11:01<07:40, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000346707.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1764/3000 [11:01<07:46, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1765/3000 [11:01<07:51, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1766/3000 [11:02<07:53, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1767/3000 [11:02<08:00, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1768/3000 [11:03<08:06, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1769/3000 [11:03<08:13, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501898.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1770/3000 [11:03<08:18, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1771/3000 [11:04<08:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1772/3000 [11:04<08:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1773/3000 [11:05<08:15, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1774/3000 [11:05<08:16, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1775/3000 [11:05<08:19, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000281766.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1776/3000 [11:06<08:16, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1777/3000 [11:06<08:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1778/3000 [11:07<08:09, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1779/3000 [11:07<08:08, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1780/3000 [11:07<08:15, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1781/3000 [11:08<08:09, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000245448.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1782/3000 [11:08<07:59, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1783/3000 [11:08<07:22, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 59%|█████▉ | 1784/3000 [11:09<06:54, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1785/3000 [11:09<06:42, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1786/3000 [11:09<06:28, 3.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1787/3000 [11:10<06:15, 3.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000510138.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1788/3000 [11:10<06:07, 3.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1789/3000 [11:10<06:33, 3.08it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1790/3000 [11:11<07:13, 2.79it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1791/3000 [11:11<07:25, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1792/3000 [11:12<07:36, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1793/3000 [11:12<07:41, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000001171.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1794/3000 [11:12<07:45, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1795/3000 [11:13<07:47, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1796/3000 [11:13<07:44, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1797/3000 [11:14<07:57, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1798/3000 [11:14<07:57, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|█████▉ | 1799/3000 [11:14<07:50, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000100238.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1800/3000 [11:15<07:54, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1801/3000 [11:15<07:56, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1802/3000 [11:15<07:52, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1803/3000 [11:16<07:48, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1804/3000 [11:16<07:53, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1805/3000 [11:17<08:02, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1806/3000 [11:17<07:59, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1807/3000 [11:17<06:23, 3.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1808/3000 [11:17<05:22, 3.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1809/3000 [11:18<04:33, 4.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1810/3000 [11:18<04:02, 4.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1811/3000 [11:18<03:39, 5.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000392364.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1812/3000 [11:18<03:20, 5.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1813/3000 [11:18<04:42, 4.21it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1814/3000 [11:19<05:38, 3.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 60%|██████ | 1815/3000 [11:19<06:10, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1816/3000 [11:20<06:41, 2.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1817/3000 [11:20<07:08, 2.76it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000188958.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1818/3000 [11:20<07:14, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1819/3000 [11:21<06:50, 2.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1820/3000 [11:21<06:39, 2.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1821/3000 [11:21<06:25, 3.06it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1822/3000 [11:22<06:18, 3.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1823/3000 [11:22<06:07, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000436127.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1824/3000 [11:22<06:00, 3.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1825/3000 [11:23<06:49, 2.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1826/3000 [11:23<07:21, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1827/3000 [11:23<07:22, 2.65it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1828/3000 [11:24<07:27, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1829/3000 [11:24<07:34, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000198397.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1830/3000 [11:25<07:44, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1831/3000 [11:25<07:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1832/3000 [11:25<07:51, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1833/3000 [11:26<08:02, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1834/3000 [11:26<07:56, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1835/3000 [11:27<07:47, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000349936.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1836/3000 [11:27<07:57, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████ | 1837/3000 [11:27<07:17, 2.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1838/3000 [11:28<06:47, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1839/3000 [11:28<06:30, 2.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1840/3000 [11:28<06:24, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1841/3000 [11:29<06:25, 3.00it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000333756.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1842/3000 [11:29<06:17, 3.07it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1843/3000 [11:29<05:08, 3.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 61%|██████▏ | 1844/3000 [11:29<04:19, 4.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1845/3000 [11:29<03:50, 5.01it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1846/3000 [11:29<03:25, 5.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1847/3000 [11:30<03:07, 6.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000474741.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1848/3000 [11:30<03:01, 6.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a keyboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1849/3000 [11:30<04:18, 4.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1850/3000 [11:30<05:17, 3.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1851/3000 [11:31<05:55, 3.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1852/3000 [11:31<06:28, 2.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1853/3000 [11:32<06:44, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000286342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1854/3000 [11:32<07:01, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1855/3000 [11:32<07:07, 2.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1856/3000 [11:33<07:13, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1857/3000 [11:33<07:19, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1858/3000 [11:34<07:17, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1859/3000 [11:34<07:16, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000093948.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1860/3000 [11:34<07:29, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1861/3000 [11:35<07:43, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1862/3000 [11:35<07:44, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1863/3000 [11:36<07:39, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1864/3000 [11:36<07:33, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1865/3000 [11:36<07:27, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405740.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1866/3000 [11:37<08:38, 2.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1867/3000 [11:37<08:14, 2.29it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1868/3000 [11:38<07:59, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1869/3000 [11:38<08:52, 2.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1870/3000 [11:39<08:34, 2.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1871/3000 [11:39<08:07, 2.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304387.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1872/3000 [11:40<07:50, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1873/3000 [11:40<07:38, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▏ | 1874/3000 [11:40<07:31, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 62%|██████▎ | 1875/3000 [11:41<07:36, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1876/3000 [11:41<07:31, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1877/3000 [11:42<07:26, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000147165.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1878/3000 [11:42<07:24, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1879/3000 [11:42<07:20, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1880/3000 [11:43<07:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1881/3000 [11:43<07:25, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1882/3000 [11:44<07:26, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1883/3000 [11:44<07:29, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000495311.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1884/3000 [11:44<07:23, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1885/3000 [11:45<07:18, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1886/3000 [11:45<07:15, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1887/3000 [11:46<07:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1888/3000 [11:46<07:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1889/3000 [11:46<07:15, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000312406.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1890/3000 [11:47<07:28, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1891/3000 [11:47<06:52, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1892/3000 [11:47<06:29, 2.85it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1893/3000 [11:48<06:08, 3.01it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1894/3000 [11:48<05:53, 3.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1895/3000 [11:48<05:43, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000515820.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1896/3000 [11:48<05:36, 3.28it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1897/3000 [11:49<04:43, 3.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1898/3000 [11:49<04:03, 4.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1899/3000 [11:49<03:40, 5.00it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1900/3000 [11:49<03:23, 5.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1901/3000 [11:49<03:05, 5.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000031971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1902/3000 [11:49<02:59, 6.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1903/3000 [11:50<04:24, 4.15it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 63%|██████▎ | 1904/3000 [11:50<05:12, 3.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1905/3000 [11:51<05:45, 3.17it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1906/3000 [11:51<06:13, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1907/3000 [11:51<06:32, 2.78it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1908/3000 [11:52<06:43, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1909/3000 [11:52<05:48, 3.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1910/3000 [11:52<05:17, 3.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1911/3000 [11:52<04:48, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▎ | 1912/3000 [11:53<05:17, 3.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1913/3000 [11:53<04:57, 3.66it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000459680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1914/3000 [11:53<04:44, 3.82it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1915/3000 [11:54<05:25, 3.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1916/3000 [11:54<06:01, 3.00it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1917/3000 [11:54<06:16, 2.88it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1918/3000 [11:55<06:32, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1919/3000 [11:55<06:39, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196462.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1920/3000 [11:56<06:53, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1921/3000 [11:56<06:52, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1922/3000 [11:56<06:54, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1923/3000 [11:57<06:54, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1924/3000 [11:57<07:01, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1925/3000 [11:58<07:17, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000276693.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1926/3000 [11:58<07:18, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1927/3000 [11:58<07:12, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1928/3000 [11:59<07:23, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1929/3000 [11:59<07:16, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1930/3000 [12:00<07:25, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1931/3000 [12:00<07:30, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000356424.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1932/3000 [12:00<07:17, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1933/3000 [12:01<07:08, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1934/3000 [12:01<07:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 64%|██████▍ | 1935/3000 [12:02<06:58, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1936/3000 [12:02<07:05, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1937/3000 [12:02<07:08, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505335.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1938/3000 [12:03<07:13, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1939/3000 [12:03<07:08, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1940/3000 [12:04<07:07, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1941/3000 [12:04<07:00, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1942/3000 [12:04<06:56, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1943/3000 [12:05<07:12, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172342.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1944/3000 [12:05<07:08, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1945/3000 [12:06<07:00, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1946/3000 [12:06<07:03, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1947/3000 [12:06<06:56, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1948/3000 [12:07<06:57, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▍ | 1949/3000 [12:07<06:55, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000384970.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1950/3000 [12:08<06:55, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1951/3000 [12:08<06:57, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1952/3000 [12:08<06:53, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1953/3000 [12:09<06:48, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1954/3000 [12:09<06:50, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an apple in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an apple in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1955/3000 [12:10<06:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000572260.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1956/3000 [12:10<07:03, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1957/3000 [12:10<06:56, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1958/3000 [12:11<07:00, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1959/3000 [12:11<07:03, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1960/3000 [12:12<07:02, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1961/3000 [12:12<06:52, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000418471.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1962/3000 [12:12<06:49, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1963/3000 [12:13<06:45, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 65%|██████▌ | 1964/3000 [12:13<06:48, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1965/3000 [12:14<06:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1966/3000 [12:14<06:42, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1967/3000 [12:14<06:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000379404.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1968/3000 [12:15<06:44, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1969/3000 [12:15<06:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1970/3000 [12:16<06:56, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1971/3000 [12:16<06:46, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1972/3000 [12:16<06:52, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1973/3000 [12:17<07:00, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044801.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1974/3000 [12:17<07:02, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1975/3000 [12:18<06:57, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1976/3000 [12:18<06:50, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1977/3000 [12:18<06:50, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1978/3000 [12:19<06:43, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1979/3000 [12:19<06:47, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000293564.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1980/3000 [12:20<06:55, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1981/3000 [12:20<06:49, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1982/3000 [12:20<06:55, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1983/3000 [12:21<06:53, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1984/3000 [12:21<06:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1985/3000 [12:22<06:40, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000452297.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1986/3000 [12:22<06:40, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▌ | 1987/3000 [12:22<06:42, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1988/3000 [12:23<06:46, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1989/3000 [12:23<06:44, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1990/3000 [12:24<06:42, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1991/3000 [12:24<06:48, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000543393.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1992/3000 [12:24<06:47, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1993/3000 [12:25<06:43, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1994/3000 [12:25<06:48, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 66%|██████▋ | 1995/3000 [12:26<06:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 1996/3000 [12:26<06:38, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 1997/3000 [12:26<06:37, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000172648.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 1998/3000 [12:27<06:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 1999/3000 [12:27<06:42, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2000/3000 [12:28<06:43, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2001/3000 [12:28<06:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2002/3000 [12:28<06:40, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2003/3000 [12:29<06:46, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000308907.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2004/3000 [12:29<06:38, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2005/3000 [12:30<06:36, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2006/3000 [12:30<06:37, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2007/3000 [12:30<06:36, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2008/3000 [12:31<06:46, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2009/3000 [12:31<06:39, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000263594.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2010/3000 [12:32<06:36, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2011/3000 [12:32<06:30, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2012/3000 [12:32<06:35, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2013/3000 [12:33<06:32, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2014/3000 [12:33<06:27, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2015/3000 [12:34<06:27, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501294.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2016/3000 [12:34<06:29, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2017/3000 [12:34<06:27, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2018/3000 [12:35<06:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2019/3000 [12:35<06:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2020/3000 [12:36<06:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2021/3000 [12:36<06:38, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000500680.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2022/3000 [12:36<06:34, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2023/3000 [12:37<06:30, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 67%|██████▋ | 2024/3000 [12:37<06:24, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2025/3000 [12:38<06:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2026/3000 [12:38<06:29, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2027/3000 [12:38<06:24, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000091954.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2028/3000 [12:39<06:21, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2029/3000 [12:39<06:18, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2030/3000 [12:40<06:20, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2031/3000 [12:40<06:16, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2032/3000 [12:40<06:14, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2033/3000 [12:41<06:36, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000454607.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2034/3000 [12:41<06:39, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2035/3000 [12:42<06:35, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2036/3000 [12:42<06:34, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2037/3000 [12:42<06:25, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2038/3000 [12:43<06:24, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2039/3000 [12:43<06:25, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000363908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2040/3000 [12:44<06:30, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2041/3000 [12:44<06:22, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2042/3000 [12:44<06:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2043/3000 [12:45<06:14, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2044/3000 [12:45<06:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2045/3000 [12:46<06:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560064.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2046/3000 [12:46<06:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2047/3000 [12:46<06:11, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2048/3000 [12:47<06:25, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2049/3000 [12:47<06:24, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2050/3000 [12:48<06:24, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2051/3000 [12:48<06:24, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000348469.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2052/3000 [12:48<06:27, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2053/3000 [12:49<06:28, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2054/3000 [12:49<06:19, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 68%|██████▊ | 2055/3000 [12:50<06:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2056/3000 [12:50<06:09, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2057/3000 [12:50<06:07, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000167724.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2058/3000 [12:51<06:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2059/3000 [12:51<06:10, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2060/3000 [12:52<06:12, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2061/3000 [12:52<06:07, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▊ | 2062/3000 [12:52<06:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2063/3000 [12:53<06:17, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000262736.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2064/3000 [12:53<06:11, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2065/3000 [12:54<06:10, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2066/3000 [12:54<06:09, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2067/3000 [12:54<06:09, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2068/3000 [12:55<06:14, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2069/3000 [12:55<06:17, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000076416.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2070/3000 [12:56<06:27, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2071/3000 [12:56<06:19, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2072/3000 [12:56<06:18, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2073/3000 [12:57<06:12, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2074/3000 [12:57<06:10, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2075/3000 [12:58<06:05, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000541783.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2076/3000 [12:58<06:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2077/3000 [12:58<06:01, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2078/3000 [12:59<06:14, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2079/3000 [12:59<06:07, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2080/3000 [13:00<06:16, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2081/3000 [13:00<06:32, 2.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000445200.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2082/3000 [13:00<06:20, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2083/3000 [13:01<06:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 69%|██████▉ | 2084/3000 [13:01<06:10, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2085/3000 [13:02<06:06, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2086/3000 [13:02<06:08, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2087/3000 [13:03<06:17, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000433574.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2088/3000 [13:03<06:17, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2089/3000 [13:03<06:10, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2090/3000 [13:04<06:19, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2091/3000 [13:04<06:07, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2092/3000 [13:05<06:25, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2093/3000 [13:05<06:22, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000212241.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2094/3000 [13:05<06:11, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2095/3000 [13:06<06:04, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2096/3000 [13:06<06:04, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2097/3000 [13:07<06:01, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2098/3000 [13:07<05:56, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|██████▉ | 2099/3000 [13:07<05:53, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000114941.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2100/3000 [13:08<06:00, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2101/3000 [13:08<05:56, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2102/3000 [13:09<05:53, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2103/3000 [13:09<05:54, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2104/3000 [13:09<05:55, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2105/3000 [13:10<05:50, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000493753.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2106/3000 [13:10<05:52, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2107/3000 [13:11<05:55, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2108/3000 [13:11<05:59, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2109/3000 [13:11<05:59, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2110/3000 [13:12<05:58, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2111/3000 [13:12<05:56, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000410597.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2112/3000 [13:13<05:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2113/3000 [13:13<05:48, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2114/3000 [13:13<05:45, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 70%|███████ | 2115/3000 [13:14<05:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2116/3000 [13:14<05:50, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2117/3000 [13:15<05:50, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000382617.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2118/3000 [13:15<05:48, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2119/3000 [13:15<05:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2120/3000 [13:16<05:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2121/3000 [13:16<05:49, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2122/3000 [13:17<05:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2123/3000 [13:17<06:00, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000467887.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2124/3000 [13:17<05:54, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2125/3000 [13:18<05:48, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2126/3000 [13:18<05:44, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2127/3000 [13:18<05:41, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2128/3000 [13:19<05:44, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2129/3000 [13:19<05:41, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000120792.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2130/3000 [13:20<05:48, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2131/3000 [13:20<05:43, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2132/3000 [13:20<05:42, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2133/3000 [13:21<05:39, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2134/3000 [13:21<05:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2135/3000 [13:22<05:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125524.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2136/3000 [13:22<05:45, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████ | 2137/3000 [13:22<05:47, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2138/3000 [13:23<05:49, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2139/3000 [13:23<05:48, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2140/3000 [13:24<05:51, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2141/3000 [13:24<05:49, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000196053.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2142/3000 [13:25<05:44, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2143/3000 [13:25<05:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 71%|███████▏ | 2144/3000 [13:25<05:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2145/3000 [13:26<05:43, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2146/3000 [13:26<05:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2147/3000 [13:26<05:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156704.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2148/3000 [13:27<05:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2149/3000 [13:27<05:41, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2150/3000 [13:28<05:47, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2151/3000 [13:28<05:38, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2152/3000 [13:28<05:37, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2153/3000 [13:29<05:42, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000088507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2154/3000 [13:29<05:41, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2155/3000 [13:30<05:37, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2156/3000 [13:30<05:40, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2157/3000 [13:30<05:34, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2158/3000 [13:31<05:38, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2159/3000 [13:31<05:43, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000279499.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2160/3000 [13:32<05:51, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2161/3000 [13:32<05:42, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2162/3000 [13:33<05:37, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2163/3000 [13:33<05:37, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2164/3000 [13:33<05:40, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2165/3000 [13:34<05:43, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000155131.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2166/3000 [13:34<05:41, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2167/3000 [13:35<05:38, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2168/3000 [13:35<05:51, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2169/3000 [13:35<05:45, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2170/3000 [13:36<05:42, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2171/3000 [13:36<05:38, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252135.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2172/3000 [13:37<05:30, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2173/3000 [13:37<05:27, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▏ | 2174/3000 [13:37<05:31, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 72%|███████▎ | 2175/3000 [13:38<05:30, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2176/3000 [13:38<05:33, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2177/3000 [13:39<06:21, 2.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000501652.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2178/3000 [13:39<06:03, 2.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2179/3000 [13:40<05:51, 2.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2180/3000 [13:40<05:51, 2.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2181/3000 [13:40<05:48, 2.35it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2182/3000 [13:41<05:44, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2183/3000 [13:41<05:39, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238691.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2184/3000 [13:42<05:40, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2185/3000 [13:42<05:31, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2186/3000 [13:42<05:25, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2187/3000 [13:43<05:20, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2188/3000 [13:43<05:17, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2189/3000 [13:44<05:20, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000332908.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2190/3000 [13:44<05:23, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2191/3000 [13:44<05:20, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2192/3000 [13:45<05:18, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2193/3000 [13:45<05:16, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2194/3000 [13:46<05:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2195/3000 [13:46<05:15, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2196/3000 [13:46<05:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2197/3000 [13:47<05:21, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2198/3000 [13:47<05:16, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2199/3000 [13:48<05:12, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2200/3000 [13:48<05:22, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2201/3000 [13:48<05:21, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000470699.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2202/3000 [13:49<05:22, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2203/3000 [13:49<05:18, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 73%|███████▎ | 2204/3000 [13:50<05:15, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2205/3000 [13:50<05:21, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2206/3000 [13:50<05:21, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2207/3000 [13:51<05:24, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000023084.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2208/3000 [13:51<05:19, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2209/3000 [13:52<05:15, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2210/3000 [13:52<05:19, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2211/3000 [13:52<05:11, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▎ | 2212/3000 [13:53<05:16, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2213/3000 [13:53<05:13, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000545353.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2214/3000 [13:54<05:13, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2215/3000 [13:54<05:13, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2216/3000 [13:54<05:15, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2217/3000 [13:55<05:15, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2218/3000 [13:55<05:14, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2219/3000 [13:56<05:14, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000394535.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2220/3000 [13:56<05:14, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2221/3000 [13:56<05:15, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2222/3000 [13:57<05:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2223/3000 [13:57<05:05, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2224/3000 [13:58<05:07, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2225/3000 [13:58<05:11, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579415.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2226/3000 [13:58<05:13, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2227/3000 [13:59<05:12, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2228/3000 [13:59<05:07, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2229/3000 [14:00<05:14, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2230/3000 [14:00<05:17, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2231/3000 [14:00<05:08, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233521.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2232/3000 [14:01<05:08, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2233/3000 [14:01<05:08, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2234/3000 [14:02<05:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 74%|███████▍ | 2235/3000 [14:02<05:04, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2236/3000 [14:02<05:07, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2237/3000 [14:03<05:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355256.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2238/3000 [14:03<05:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2239/3000 [14:04<05:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2240/3000 [14:04<05:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2241/3000 [14:04<05:03, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2242/3000 [14:05<05:12, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2243/3000 [14:05<05:06, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a keyboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000304819.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2244/3000 [14:06<05:01, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2245/3000 [14:06<05:03, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2246/3000 [14:06<05:02, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2247/3000 [14:07<05:01, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2248/3000 [14:07<05:00, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▍ | 2249/3000 [14:08<05:06, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000240434.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2250/3000 [14:08<05:12, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2251/3000 [14:09<05:03, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2252/3000 [14:09<04:59, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2253/3000 [14:09<04:55, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2254/3000 [14:10<04:52, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2255/3000 [14:10<04:49, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000199940.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2256/3000 [14:10<04:57, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2257/3000 [14:11<05:07, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2258/3000 [14:11<05:04, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2259/3000 [14:12<05:00, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2260/3000 [14:12<04:57, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2261/3000 [14:13<04:54, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000549390.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2262/3000 [14:13<04:54, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a giraffe in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a giraffe in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2263/3000 [14:13<04:54, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cow in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 75%|███████▌ | 2264/3000 [14:14<04:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2265/3000 [14:14<04:50, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2266/3000 [14:14<04:46, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2267/3000 [14:15<04:44, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2268/3000 [14:15<04:49, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2269/3000 [14:16<04:50, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2270/3000 [14:16<04:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2271/3000 [14:16<04:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2272/3000 [14:17<04:59, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2273/3000 [14:17<04:55, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000068418.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2274/3000 [14:18<04:50, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2275/3000 [14:18<04:47, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2276/3000 [14:18<04:49, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2277/3000 [14:19<04:47, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2278/3000 [14:19<04:46, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2279/3000 [14:20<04:48, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000368541.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2280/3000 [14:20<04:55, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2281/3000 [14:21<04:51, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2282/3000 [14:21<04:46, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2283/3000 [14:21<04:45, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2284/3000 [14:22<04:49, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2285/3000 [14:22<04:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000006033.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2286/3000 [14:23<04:49, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▌ | 2287/3000 [14:23<04:50, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2288/3000 [14:23<04:46, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2289/3000 [14:24<04:42, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2290/3000 [14:24<04:41, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2291/3000 [14:25<04:44, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000021327.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2292/3000 [14:25<04:45, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2293/3000 [14:25<04:46, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2294/3000 [14:26<04:48, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 76%|███████▋ | 2295/3000 [14:26<04:47, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2296/3000 [14:27<04:45, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2297/3000 [14:27<04:42, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390157.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2298/3000 [14:27<04:44, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2299/3000 [14:28<04:44, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2300/3000 [14:28<04:48, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2301/3000 [14:29<04:52, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2302/3000 [14:29<05:06, 2.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2303/3000 [14:30<05:06, 2.28it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000298633.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2304/3000 [14:30<04:59, 2.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2305/3000 [14:30<04:54, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2306/3000 [14:31<04:57, 2.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2307/3000 [14:31<04:45, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2308/3000 [14:32<04:41, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2309/3000 [14:32<04:35, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579277.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2310/3000 [14:32<04:36, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2311/3000 [14:33<04:31, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2312/3000 [14:33<04:29, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2313/3000 [14:34<04:30, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2314/3000 [14:34<04:36, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2315/3000 [14:34<04:32, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000042685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2316/3000 [14:35<04:31, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2317/3000 [14:35<04:31, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2318/3000 [14:36<04:33, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2319/3000 [14:36<04:34, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2320/3000 [14:36<04:35, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2321/3000 [14:37<04:28, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000553992.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2322/3000 [14:37<04:25, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2323/3000 [14:38<04:25, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 77%|███████▋ | 2324/3000 [14:38<04:26, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2325/3000 [14:38<04:26, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2326/3000 [14:39<04:23, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2327/3000 [14:39<04:25, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000243158.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2328/3000 [14:39<04:21, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2329/3000 [14:40<04:22, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2330/3000 [14:40<04:35, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2331/3000 [14:41<04:32, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2332/3000 [14:41<04:32, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2333/3000 [14:42<04:29, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000303971.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2334/3000 [14:42<04:26, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2335/3000 [14:42<04:22, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2336/3000 [14:43<04:20, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2337/3000 [14:43<04:19, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2338/3000 [14:44<04:28, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2339/3000 [14:44<04:32, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405762.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2340/3000 [14:44<04:33, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2341/3000 [14:45<04:27, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2342/3000 [14:45<04:22, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2343/3000 [14:46<04:18, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2344/3000 [14:46<04:19, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2345/3000 [14:46<04:15, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000343967.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2346/3000 [14:47<04:23, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2347/3000 [14:47<04:20, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2348/3000 [14:47<04:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2349/3000 [14:48<04:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2350/3000 [14:48<04:21, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2351/3000 [14:49<04:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000477598.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2352/3000 [14:49<04:17, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2353/3000 [14:50<04:24, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2354/3000 [14:50<04:24, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 78%|███████▊ | 2355/3000 [14:50<04:21, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2356/3000 [14:51<04:19, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2357/3000 [14:51<04:21, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000044993.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2358/3000 [14:52<04:16, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2359/3000 [14:52<04:16, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2360/3000 [14:52<04:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2361/3000 [14:53<04:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▊ | 2362/3000 [14:53<04:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2363/3000 [14:54<04:14, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000381195.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2364/3000 [14:54<04:12, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2365/3000 [14:54<04:13, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2366/3000 [14:55<04:15, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2367/3000 [14:55<04:12, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a carrot in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a carrot in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2368/3000 [14:56<04:11, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2369/3000 [14:56<04:16, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000337502.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2370/3000 [14:56<04:20, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2371/3000 [14:57<03:39, 2.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2372/3000 [14:57<03:15, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2373/3000 [14:57<02:55, 3.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2374/3000 [14:57<02:50, 3.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2375/3000 [14:57<02:38, 3.95it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000325347.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2376/3000 [14:58<02:37, 3.97it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2377/3000 [14:58<03:06, 3.34it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2378/3000 [14:59<03:23, 3.06it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2379/3000 [14:59<03:41, 2.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2380/3000 [14:59<03:58, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2381/3000 [15:00<03:58, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000256906.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2382/3000 [15:00<04:00, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2383/3000 [15:01<03:58, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 79%|███████▉ | 2384/3000 [15:01<04:01, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2385/3000 [15:01<04:02, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2386/3000 [15:02<04:09, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2387/3000 [15:02<04:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000061507.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2388/3000 [15:03<04:07, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2389/3000 [15:03<04:05, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2390/3000 [15:03<04:08, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2391/3000 [15:04<04:05, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2392/3000 [15:04<04:05, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2393/3000 [15:05<04:08, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000084410.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2394/3000 [15:05<04:08, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2395/3000 [15:05<04:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2396/3000 [15:06<04:00, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2397/3000 [15:06<03:58, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2398/3000 [15:07<03:56, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|███████▉ | 2399/3000 [15:07<03:53, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000288576.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2400/3000 [15:07<03:55, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2401/3000 [15:08<03:57, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2402/3000 [15:08<03:53, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2403/3000 [15:09<03:54, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2404/3000 [15:09<03:52, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2405/3000 [15:09<03:50, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000328301.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2406/3000 [15:10<03:54, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2407/3000 [15:10<03:11, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2408/3000 [15:10<02:36, 3.78it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2409/3000 [15:10<02:15, 4.35it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2410/3000 [15:10<02:02, 4.82it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2411/3000 [15:10<01:56, 5.05it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000307262.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2412/3000 [15:11<02:04, 4.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2413/3000 [15:11<02:37, 3.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2414/3000 [15:12<02:59, 3.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an apple in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an apple in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 80%|████████ | 2415/3000 [15:12<03:24, 2.86it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2416/3000 [15:12<03:32, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2417/3000 [15:13<03:43, 2.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000573796.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2418/3000 [15:13<03:43, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2419/3000 [15:14<03:46, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2420/3000 [15:14<03:49, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2421/3000 [15:14<03:49, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2422/3000 [15:15<03:47, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2423/3000 [15:15<03:48, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000154846.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2424/3000 [15:16<03:48, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2425/3000 [15:16<03:04, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2426/3000 [15:16<02:31, 3.80it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2427/3000 [15:16<02:10, 4.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2428/3000 [15:16<01:55, 4.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2429/3000 [15:16<01:42, 5.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000472375.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2430/3000 [15:16<01:39, 5.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2431/3000 [15:17<02:18, 4.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2432/3000 [15:17<02:47, 3.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2433/3000 [15:18<03:01, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2434/3000 [15:18<03:13, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2435/3000 [15:18<03:21, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000446651.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2436/3000 [15:19<03:26, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████ | 2437/3000 [15:19<03:29, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2438/3000 [15:20<03:37, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2439/3000 [15:20<03:38, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2440/3000 [15:20<03:39, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2441/3000 [15:21<03:41, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000267684.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2442/3000 [15:21<03:42, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2443/3000 [15:22<03:41, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 81%|████████▏ | 2444/3000 [15:22<03:40, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2445/3000 [15:22<03:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2446/3000 [15:23<03:44, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2447/3000 [15:23<03:43, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000238029.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2448/3000 [15:24<03:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2449/3000 [15:24<03:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2450/3000 [15:24<03:41, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2451/3000 [15:25<03:38, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2452/3000 [15:25<03:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2453/3000 [15:26<03:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000294475.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2454/3000 [15:26<03:37, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2455/3000 [15:26<03:34, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2456/3000 [15:27<03:34, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2457/3000 [15:27<03:32, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2458/3000 [15:28<03:35, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2459/3000 [15:28<03:34, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000149592.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2460/3000 [15:28<03:36, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2461/3000 [15:29<03:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2462/3000 [15:29<03:35, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2463/3000 [15:30<03:31, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2464/3000 [15:30<03:28, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2465/3000 [15:30<03:30, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000447787.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2466/3000 [15:31<03:33, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2467/3000 [15:31<03:33, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2468/3000 [15:32<03:30, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2469/3000 [15:32<03:32, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2470/3000 [15:32<03:34, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2471/3000 [15:33<03:29, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000458325.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2472/3000 [15:33<03:32, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2473/3000 [15:34<03:30, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▏ | 2474/3000 [15:34<03:31, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 82%|████████▎ | 2475/3000 [15:34<03:28, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2476/3000 [15:35<03:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2477/3000 [15:35<03:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000388237.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2478/3000 [15:36<03:25, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2479/3000 [15:36<03:24, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2480/3000 [15:36<03:26, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2481/3000 [15:37<03:23, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2482/3000 [15:37<03:25, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2483/3000 [15:38<03:24, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000038645.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2484/3000 [15:38<03:24, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2485/3000 [15:39<03:56, 2.18it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2486/3000 [15:39<03:48, 2.25it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2487/3000 [15:39<03:38, 2.35it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2488/3000 [15:40<03:31, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2489/3000 [15:40<03:26, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000071738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2490/3000 [15:41<03:33, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2491/3000 [15:41<03:33, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2492/3000 [15:41<03:28, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2493/3000 [15:42<03:29, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2494/3000 [15:42<03:29, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2495/3000 [15:43<03:28, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000170077.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2496/3000 [15:43<03:22, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2497/3000 [15:43<03:20, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2498/3000 [15:44<03:19, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2499/3000 [15:44<03:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2500/3000 [15:45<03:23, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2501/3000 [15:45<03:23, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000378751.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2502/3000 [15:45<03:22, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2503/3000 [15:46<03:19, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 83%|████████▎ | 2504/3000 [15:46<03:22, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2505/3000 [15:47<03:25, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2506/3000 [15:47<03:26, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2507/3000 [15:47<03:22, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000073182.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2508/3000 [15:48<03:19, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2509/3000 [15:48<03:15, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2510/3000 [15:49<03:16, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2511/3000 [15:49<03:12, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▎ | 2512/3000 [15:49<03:11, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2513/3000 [15:50<03:13, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000246928.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2514/3000 [15:50<03:14, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2515/3000 [15:51<03:13, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2516/3000 [15:51<03:16, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2517/3000 [15:51<03:13, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2518/3000 [15:52<03:14, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2519/3000 [15:52<03:11, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000528136.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2520/3000 [15:53<03:15, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2521/3000 [15:53<02:40, 2.98it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2522/3000 [15:53<02:11, 3.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2523/3000 [15:53<01:50, 4.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2524/3000 [15:53<01:37, 4.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2525/3000 [15:53<01:27, 5.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000209290.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2526/3000 [15:53<01:19, 5.94it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2527/3000 [15:54<01:49, 4.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2528/3000 [15:54<02:11, 3.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a wine glass in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a wine glass in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2529/3000 [15:55<02:31, 3.11it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2530/3000 [15:55<02:47, 2.81it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2531/3000 [15:56<02:55, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000564511.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2532/3000 [15:56<02:58, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2533/3000 [15:56<02:24, 3.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2534/3000 [15:56<01:59, 3.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 84%|████████▍ | 2535/3000 [15:56<01:41, 4.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2536/3000 [15:56<01:28, 5.26it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2537/3000 [15:57<01:22, 5.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000200739.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2538/3000 [15:57<01:15, 6.16it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2539/3000 [15:57<01:48, 4.23it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2540/3000 [15:58<02:13, 3.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2541/3000 [15:58<02:27, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2542/3000 [15:58<02:36, 2.93it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2543/3000 [15:59<02:51, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000462805.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2544/3000 [15:59<02:53, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2545/3000 [15:59<02:23, 3.17it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2546/3000 [15:59<01:58, 3.84it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2547/3000 [16:00<02:00, 3.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2548/3000 [16:00<01:42, 4.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▍ | 2549/3000 [16:00<01:29, 5.06it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163575.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2550/3000 [16:00<01:25, 5.27it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2551/3000 [16:01<01:53, 3.96it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2552/3000 [16:01<02:10, 3.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2553/3000 [16:01<02:22, 3.13it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2554/3000 [16:02<02:35, 2.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2555/3000 [16:02<02:41, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000059383.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2556/3000 [16:03<02:46, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2557/3000 [16:03<02:49, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2558/3000 [16:03<02:48, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2559/3000 [16:04<02:48, 2.62it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2560/3000 [16:04<02:52, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a stop sign in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a stop sign in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2561/3000 [16:05<02:58, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fire hydrant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fire hydrant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000478736.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2562/3000 [16:05<03:00, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2563/3000 [16:05<02:56, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 85%|████████▌ | 2564/3000 [16:06<02:52, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2565/3000 [16:06<02:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2566/3000 [16:07<02:53, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2567/3000 [16:07<02:53, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000156282.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2568/3000 [16:07<02:53, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2569/3000 [16:08<02:55, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2570/3000 [16:08<02:54, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2571/3000 [16:09<02:51, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2572/3000 [16:09<02:53, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2573/3000 [16:09<02:53, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000052689.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2574/3000 [16:10<02:53, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2575/3000 [16:10<02:32, 2.79it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2576/3000 [16:10<02:11, 3.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2577/3000 [16:11<02:12, 3.20it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2578/3000 [16:11<02:06, 3.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2579/3000 [16:11<01:53, 3.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 3 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2580/3000 [16:11<01:51, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2581/3000 [16:12<02:06, 3.32it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2582/3000 [16:12<02:18, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2583/3000 [16:13<02:24, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2584/3000 [16:13<02:30, 2.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2585/3000 [16:13<02:34, 2.69it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2586/3000 [16:14<02:36, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▌ | 2587/3000 [16:14<02:37, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2588/3000 [16:14<02:38, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2589/3000 [16:15<02:40, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2590/3000 [16:15<02:45, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2591/3000 [16:16<02:44, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2592/3000 [16:16<02:42, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2593/3000 [16:17<02:43, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2594/3000 [16:17<02:52, 2.36it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 86%|████████▋ | 2595/3000 [16:17<02:48, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2596/3000 [16:18<02:47, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2597/3000 [16:18<02:46, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2598/3000 [16:19<02:43, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2599/3000 [16:19<02:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2600/3000 [16:19<02:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2601/3000 [16:20<02:41, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2602/3000 [16:20<02:39, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2603/3000 [16:21<02:41, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2604/3000 [16:21<02:38, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2605/3000 [16:21<02:36, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2606/3000 [16:22<02:34, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2607/3000 [16:22<02:35, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2608/3000 [16:23<02:44, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a kite in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2609/3000 [16:23<02:40, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2610/3000 [16:23<02:38, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2611/3000 [16:24<02:34, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2612/3000 [16:24<02:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2613/3000 [16:25<02:34, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2614/3000 [16:25<02:34, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2615/3000 [16:25<02:32, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2616/3000 [16:26<02:35, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2617/3000 [16:26<02:32, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2618/3000 [16:27<02:31, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a suitcase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2619/3000 [16:27<02:30, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2620/3000 [16:27<02:30, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2621/3000 [16:28<02:29, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2622/3000 [16:28<02:31, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2623/3000 [16:29<02:31, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 87%|████████▋ | 2624/3000 [16:29<02:36, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a teddy bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2625/3000 [16:29<02:33, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2626/3000 [16:30<02:31, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bear in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2627/3000 [16:30<02:29, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2628/3000 [16:31<02:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2629/3000 [16:31<02:27, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2630/3000 [16:31<02:27, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2631/3000 [16:32<02:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2632/3000 [16:32<02:27, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2633/3000 [16:33<02:26, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2634/3000 [16:33<02:26, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2635/3000 [16:33<01:56, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2636/3000 [16:33<01:36, 3.77it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2637/3000 [16:33<01:23, 4.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2638/3000 [16:34<01:12, 5.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2639/3000 [16:34<01:04, 5.61it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 1 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2640/3000 [16:34<01:02, 5.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2641/3000 [16:34<01:23, 4.28it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2642/3000 [16:35<01:43, 3.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2643/3000 [16:35<01:55, 3.10it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2644/3000 [16:35<02:04, 2.87it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2645/3000 [16:36<02:09, 2.75it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2646/3000 [16:36<02:11, 2.70it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2647/3000 [16:37<02:12, 2.67it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2648/3000 [16:37<02:13, 2.64it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2649/3000 [16:37<02:13, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2650/3000 [16:38<02:22, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a frisbee in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2651/3000 [16:38<02:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2652/3000 [16:39<02:19, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2653/3000 [16:39<02:16, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2654/3000 [16:39<02:17, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 88%|████████▊ | 2655/3000 [16:40<02:15, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2656/3000 [16:40<02:14, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2657/3000 [16:41<02:17, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2658/3000 [16:41<02:16, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2659/3000 [16:41<02:15, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2660/3000 [16:42<02:15, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2661/3000 [16:42<02:13, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▊ | 2662/3000 [16:43<02:14, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2663/3000 [16:43<02:12, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2664/3000 [16:43<02:14, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2665/3000 [16:44<02:15, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2666/3000 [16:44<02:15, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2667/3000 [16:45<02:12, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2668/3000 [16:45<02:10, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an umbrella in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2669/3000 [16:45<02:12, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2670/3000 [16:46<02:15, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2671/3000 [16:46<02:12, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2672/3000 [16:47<02:17, 2.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2673/3000 [16:47<02:16, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2674/3000 [16:48<02:14, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2675/3000 [16:48<02:13, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2676/3000 [16:48<02:11, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2677/3000 [16:49<02:11, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2678/3000 [16:49<02:11, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a toilet in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2679/3000 [16:50<02:13, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2680/3000 [16:50<02:14, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2681/3000 [16:50<02:11, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2682/3000 [16:51<02:10, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a keyboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2683/3000 [16:51<02:06, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 89%|████████▉ | 2684/3000 [16:52<02:06, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2685/3000 [16:52<02:06, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2686/3000 [16:52<02:04, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2687/3000 [16:53<02:07, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2688/3000 [16:53<02:04, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2689/3000 [16:54<02:02, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2690/3000 [16:54<02:05, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2691/3000 [16:54<02:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2692/3000 [16:55<02:01, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an orange in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2693/3000 [16:55<02:03, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2694/3000 [16:56<02:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2695/3000 [16:56<02:03, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a surfboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2696/3000 [16:56<02:02, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2697/3000 [16:57<02:01, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2698/3000 [16:57<02:03, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|████████▉ | 2699/3000 [16:58<02:02, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2700/3000 [16:58<02:00, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2701/3000 [16:58<01:58, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2702/3000 [16:59<02:02, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2703/3000 [16:59<01:59, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2704/3000 [17:00<02:06, 2.33it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skateboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2705/3000 [17:00<02:03, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2706/3000 [17:00<01:59, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2707/3000 [17:01<01:58, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2708/3000 [17:01<01:55, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2709/3000 [17:02<01:54, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2710/3000 [17:02<01:57, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2711/3000 [17:02<01:56, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2712/3000 [17:03<01:54, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a traffic light in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2713/3000 [17:03<01:55, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2714/3000 [17:04<01:53, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 90%|█████████ | 2715/3000 [17:04<01:52, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a motorcycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2716/3000 [17:04<01:53, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a train in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2717/3000 [17:05<01:56, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bus in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2718/3000 [17:05<01:54, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2719/3000 [17:06<01:52, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2720/3000 [17:06<01:54, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2721/3000 [17:06<01:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2722/3000 [17:07<01:49, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2723/3000 [17:07<01:48, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2724/3000 [17:08<01:47, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2725/3000 [17:08<01:47, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2726/3000 [17:08<01:48, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2727/3000 [17:09<01:47, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2728/3000 [17:09<01:46, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a boat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2729/3000 [17:10<01:45, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bird in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bird in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2730/3000 [17:10<01:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2731/3000 [17:10<01:46, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2732/3000 [17:11<01:45, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2733/3000 [17:11<01:45, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2734/3000 [17:12<01:44, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2735/3000 [17:12<01:42, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2736/3000 [17:12<01:41, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████ | 2737/3000 [17:13<01:43, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2738/3000 [17:13<01:42, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2739/3000 [17:14<01:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2740/3000 [17:14<01:44, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2741/3000 [17:14<01:44, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2742/3000 [17:15<01:44, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2743/3000 [17:15<01:42, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 91%|█████████▏| 2744/3000 [17:16<01:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2745/3000 [17:16<01:40, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2746/3000 [17:16<01:39, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2747/3000 [17:17<01:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2748/3000 [17:17<01:40, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2749/3000 [17:18<01:39, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2750/3000 [17:18<01:42, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2751/3000 [17:18<01:40, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2752/3000 [17:19<01:38, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2753/3000 [17:19<01:38, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2754/3000 [17:20<01:37, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2755/3000 [17:20<01:37, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2756/3000 [17:20<01:39, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2757/3000 [17:21<01:37, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2758/3000 [17:21<01:37, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2759/3000 [17:22<01:37, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2760/3000 [17:22<01:38, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2761/3000 [17:22<01:38, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2762/3000 [17:23<01:39, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2763/3000 [17:23<01:37, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2764/3000 [17:24<01:35, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball bat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2765/3000 [17:24<01:35, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2766/3000 [17:24<01:35, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a giraffe in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a giraffe in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2767/3000 [17:25<01:35, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2768/3000 [17:25<01:33, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cow in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2769/3000 [17:26<01:32, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2770/3000 [17:26<01:32, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a zebra in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a zebra in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2771/3000 [17:26<01:33, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2772/3000 [17:27<01:32, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2773/3000 [17:27<01:31, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▏| 2774/3000 [17:28<01:30, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 92%|█████████▎| 2775/3000 [17:28<01:31, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2776/3000 [17:28<01:31, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2777/3000 [17:29<01:30, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2778/3000 [17:29<01:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2779/3000 [17:30<01:27, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2780/3000 [17:30<01:27, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2781/3000 [17:30<01:26, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2782/3000 [17:31<01:25, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2783/3000 [17:31<01:24, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2784/3000 [17:32<01:24, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2785/3000 [17:32<01:18, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2786/3000 [17:32<01:13, 2.91it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2787/3000 [17:32<01:10, 3.03it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2788/3000 [17:33<01:07, 3.14it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2789/3000 [17:33<01:05, 3.24it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2790/3000 [17:33<01:05, 3.21it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2791/3000 [17:34<01:09, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2792/3000 [17:34<01:11, 2.89it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2793/3000 [17:35<01:15, 2.73it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2794/3000 [17:35<01:19, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a horse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2795/3000 [17:35<01:19, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2796/3000 [17:36<01:18, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2797/3000 [17:36<01:18, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2798/3000 [17:37<01:18, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2799/3000 [17:37<01:17, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2800/3000 [17:37<01:20, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sink in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2801/3000 [17:38<01:19, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2802/3000 [17:38<01:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2803/3000 [17:39<01:17, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 93%|█████████▎| 2804/3000 [17:39<01:28, 2.22it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2805/3000 [17:40<01:24, 2.30it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2806/3000 [17:40<01:21, 2.38it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2807/3000 [17:40<01:20, 2.39it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2808/3000 [17:41<01:19, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2809/3000 [17:41<01:12, 2.63it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2810/3000 [17:41<01:09, 2.74it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2811/3000 [17:42<01:05, 2.90it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▎| 2812/3000 [17:42<01:02, 3.02it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2813/3000 [17:42<01:00, 3.12it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 5 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2814/3000 [17:43<00:58, 3.19it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2815/3000 [17:43<01:02, 2.94it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2816/3000 [17:43<01:05, 2.83it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2817/3000 [17:44<01:07, 2.72it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2818/3000 [17:44<01:07, 2.68it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2819/3000 [17:45<01:09, 2.60it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2820/3000 [17:45<01:12, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2821/3000 [17:45<01:11, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2822/3000 [17:46<01:10, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2823/3000 [17:46<01:09, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2824/3000 [17:47<01:11, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2825/3000 [17:47<01:10, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cake in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cake in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2826/3000 [17:47<01:09, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2827/3000 [17:48<01:08, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2828/3000 [17:48<01:08, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2829/3000 [17:49<01:07, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2830/3000 [17:49<01:07, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a skis in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2831/3000 [17:49<01:07, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a snowboard in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2832/3000 [17:50<01:07, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2833/3000 [17:50<01:07, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2834/3000 [17:51<01:05, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sandwich in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 94%|█████████▍| 2835/3000 [17:51<01:04, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2836/3000 [17:51<01:03, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2837/3000 [17:52<01:03, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2838/3000 [17:52<01:03, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2839/3000 [17:52<01:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2840/3000 [17:53<01:04, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2841/3000 [17:53<01:03, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2842/3000 [17:54<01:04, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2843/3000 [17:54<01:05, 2.41it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2844/3000 [17:55<01:04, 2.40it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2845/3000 [17:55<01:03, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2846/3000 [17:55<01:01, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2847/3000 [17:56<01:00, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2848/3000 [17:56<00:59, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▍| 2849/3000 [17:57<00:59, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2850/3000 [17:57<00:59, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2851/3000 [17:57<00:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2852/3000 [17:58<00:58, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a clock in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2853/3000 [17:58<00:57, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2854/3000 [17:58<00:56, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2855/3000 [17:59<00:56, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2856/3000 [17:59<00:58, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2857/3000 [18:00<00:58, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2858/3000 [18:00<00:57, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2859/3000 [18:01<00:56, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an oven in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there an oven in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2860/3000 [18:01<00:57, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2861/3000 [18:01<00:55, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a banana in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2862/3000 [18:02<00:54, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2863/3000 [18:02<00:54, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 95%|█████████▌| 2864/3000 [18:03<00:54, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2865/3000 [18:03<00:53, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2866/3000 [18:03<00:53, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2867/3000 [18:04<00:53, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2868/3000 [18:04<00:52, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2869/3000 [18:05<00:51, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2870/3000 [18:05<00:51, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2871/3000 [18:05<00:51, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2872/3000 [18:06<00:50, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2873/3000 [18:06<00:50, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2874/3000 [18:06<00:49, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2875/3000 [18:07<00:49, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2876/3000 [18:07<00:48, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2877/3000 [18:08<00:47, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2878/3000 [18:08<00:47, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2879/3000 [18:08<00:47, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2880/3000 [18:09<00:47, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2881/3000 [18:09<00:46, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2882/3000 [18:10<00:45, 2.58it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2883/3000 [18:10<00:45, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2884/3000 [18:10<00:45, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2885/3000 [18:11<00:44, 2.59it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2886/3000 [18:11<00:44, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▌| 2887/3000 [18:12<00:43, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2888/3000 [18:12<00:44, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2889/3000 [18:12<00:43, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2890/3000 [18:13<00:43, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cow in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2891/3000 [18:13<00:42, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bicycle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bicycle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2892/3000 [18:14<00:42, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2893/3000 [18:14<00:42, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2894/3000 [18:14<00:41, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 96%|█████████▋| 2895/3000 [18:15<00:41, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2896/3000 [18:15<00:41, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2897/3000 [18:16<00:41, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2898/3000 [18:16<00:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2899/3000 [18:16<00:40, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2900/3000 [18:17<00:40, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2901/3000 [18:17<00:39, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2902/3000 [18:18<00:39, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2903/3000 [18:18<00:38, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2904/3000 [18:18<00:37, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2905/3000 [18:19<00:37, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2906/3000 [18:19<00:36, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a mouse in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2907/3000 [18:19<00:36, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2908/3000 [18:20<00:36, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2909/3000 [18:20<00:35, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2910/3000 [18:21<00:35, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2911/3000 [18:21<00:34, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2912/3000 [18:21<00:34, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2913/3000 [18:22<00:34, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2914/3000 [18:22<00:33, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2915/3000 [18:23<00:33, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2916/3000 [18:23<00:32, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bed in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2917/3000 [18:23<00:32, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2918/3000 [18:24<00:32, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cat in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2919/3000 [18:24<00:31, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2920/3000 [18:25<00:31, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tie in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2921/3000 [18:25<00:31, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2922/3000 [18:25<00:31, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2923/3000 [18:26<00:31, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 97%|█████████▋| 2924/3000 [18:26<00:30, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2925/3000 [18:27<00:31, 2.37it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2926/3000 [18:27<00:30, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2927/3000 [18:27<00:29, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2928/3000 [18:28<00:28, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a truck in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2929/3000 [18:28<00:27, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2930/3000 [18:29<00:28, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2931/3000 [18:29<00:27, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2932/3000 [18:29<00:27, 2.44it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there an airplane in the imange?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2933/3000 [18:30<00:27, 2.43it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2934/3000 [18:30<00:26, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2935/3000 [18:31<00:25, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2936/3000 [18:31<00:25, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2937/3000 [18:31<00:24, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2938/3000 [18:32<00:24, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a remote in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2939/3000 [18:32<00:24, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a book in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2940/3000 [18:33<00:23, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2941/3000 [18:33<00:23, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dog in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2942/3000 [18:33<00:22, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2943/3000 [18:34<00:22, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2944/3000 [18:34<00:22, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2945/3000 [18:35<00:21, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2946/3000 [18:35<00:21, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2947/3000 [18:35<00:21, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2948/3000 [18:36<00:20, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a potted plant in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2949/3000 [18:36<00:20, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2950/3000 [18:37<00:20, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a vase in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2951/3000 [18:37<00:19, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2952/3000 [18:37<00:18, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2953/3000 [18:38<00:18, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2954/3000 [18:38<00:18, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 98%|█████████▊| 2955/3000 [18:39<00:18, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2956/3000 [18:39<00:17, 2.45it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2957/3000 [18:39<00:17, 2.42it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2958/3000 [18:40<00:16, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2959/3000 [18:40<00:16, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2960/3000 [18:41<00:15, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2961/3000 [18:41<00:15, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a knife in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▊| 2962/3000 [18:41<00:14, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a fork in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2963/3000 [18:42<00:14, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2964/3000 [18:42<00:14, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a pizza in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2965/3000 [18:43<00:13, 2.55it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2966/3000 [18:43<00:13, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2967/3000 [18:43<00:13, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2968/3000 [18:44<00:12, 2.57it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cell phone in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2969/3000 [18:44<00:12, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2970/3000 [18:45<00:12, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2971/3000 [18:45<00:11, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2972/3000 [18:45<00:11, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a sports ball in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2973/3000 [18:46<00:10, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a baseball glove in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2974/3000 [18:46<00:10, 2.47it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tennis racket in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2975/3000 [18:47<00:10, 2.46it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bench in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2976/3000 [18:47<00:09, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2977/3000 [18:47<00:09, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2978/3000 [18:48<00:08, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2979/3000 [18:48<00:08, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2980/3000 [18:49<00:08, 2.49it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a laptop in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2981/3000 [18:49<00:07, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2982/3000 [18:49<00:07, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2983/3000 [18:50<00:06, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 99%|█████████▉| 2984/3000 [18:50<00:06, 2.50it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2985/3000 [18:51<00:05, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a car in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2986/3000 [18:51<00:05, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a handbag in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2987/3000 [18:51<00:05, 2.51it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a backpack in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2988/3000 [18:52<00:04, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2989/3000 [18:52<00:04, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2990/3000 [18:53<00:03, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a broccoli in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2991/3000 [18:53<00:03, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a dining table in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2992/3000 [18:53<00:03, 2.48it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a spoon in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2993/3000 [18:54<00:02, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bottle in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2994/3000 [18:54<00:02, 2.53it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a tv in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2995/3000 [18:55<00:01, 2.52it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a person in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2996/3000 [18:55<00:01, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a bowl in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2997/3000 [18:55<00:01, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a cup in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2998/3000 [18:56<00:00, 2.56it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a couch in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + Yes. +struct [{'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +Yes. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|█████████▉| 2999/3000 [18:56<00:00, 2.54it/s]Setting `pad_token_id` to `eos_token_id`:151645 for open-end generation. +InternVL model version: V2.0 +dynamic ViT batch size: 7 +ours... +<|im_start|>system +你是书生·万象,英文名是InternVL,是由上海人工智能实验室、清华大学及多家合作单位联合开发的多模态大语言模型。<|im_end|> +<|im_start|>user + +Is there a chair in the image?Please answer yes or no.<|im_end|> +<|im_start|>assistant + No. +struct [{'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}, {'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}] +No. + Infer InternVL3-8B/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:56<00:00, 2.52it/s] Infer InternVL3-8B/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:56<00:00, 2.64it/s] +[2025-09-12 00:21:20] INFO - RUN - run.py: main - 404: {'nproc': 4, 'verbose': True, 'retry': 3, 'model': 'chatgpt-0125'} +/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py:74: UserWarning: OPENAI_API_KEY is not working properly, will use exact matching for evaluation + warnings.warn('OPENAI_API_KEY is not working properly, will use exact matching for evaluation') +[2025-09-12 00:21:22] ERROR - RUN - run.py: main - 484: Model InternVL3-8B x Dataset POPE combination failed: 'category', skipping this combination. +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3812, in get_loc + return self._engine.get_loc(casted_key) + ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ + File "pandas/_libs/index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item + File "pandas/_libs/hashtable_class_helper.pxi", line 7096, in pandas._libs.hashtable.PyObjectHashTable.get_item +KeyError: 'category' + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/run.py", line 455, in main + eval_results = dataset.evaluate(result_file, **judge_kwargs) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py", line 102, in evaluate + score = POPE_rating(storage) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/utils/yorn.py", line 155, in POPE_rating + data = data.assign(category=data['category'].str.split(',')).explode('category') + ~~~~^^^^^^^^^^^^ + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/frame.py", line 4107, in __getitem__ + indexer = self.columns.get_loc(key) + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3819, in get_loc + raise KeyError(key) from err +KeyError: 'category' +POPE diff --git a/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250909_213228.log b/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250909_213228.log new file mode 100644 index 0000000000000000000000000000000000000000..685d57cc09022b74316d84369e29b747e6c1da96 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250909_213228.log @@ -0,0 +1,8988 @@ +[2025-09-09 21:32:34] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 21:32:45] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 21:32:45] WARNING - RUN - run.py: main - 219: --reuse is not set, will not reuse previous (before one day) temporary files +fatal: detected dubious ownership in repository at '/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit' +To add an exception for this directory, call: + + git config --global --add safe.directory /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit +Namespace(data=['POPE'], model=['Qwen2.5-VL-7B-Instruct'], config=None, work_dir='./outputs/20250909_213245', mode='all', api_nproc=4, retry=None, judge_args=None, judge=None, verbose=True, ignore=False, reuse=False, reuse_aux=True, use_vllm=False, use_verifier=False) +['POPE'] +use_config False +ROOT +/mnt/bn/life-mllm/users/cxr/hallucination/OPERA/pope_coco/coco_pope_adversarial.jsonl + +out_file: ./outputs/20250909_213245/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00 + from vlmeval.config import supported_VLM + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/__init__.py", line 13, in + from .api import * + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/api/__init__.py", line 4, in + from .qwen_vl_api import QwenVLWrapper, QwenVLAPI, Qwen2VLAPI + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/api/qwen_vl_api.py", line 8, in + from vlmeval.vlm.qwen2_vl.prompt import Qwen2VLPromptMixin + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/vlm/__init__.py", line 5, in + from .aria import Aria + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/vlm/aria.py", line 8, in + from .base import BaseModel + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/vlm/base.py", line 2, in + from ..dataset import img_root_map, DATASET_TYPE + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/__init__.py", line 36, in + from .mvbench import MVBench, MVBench_MP4 + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/mvbench.py", line 11, in + import cv2 + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/cv2/__init__.py", line 181, in + bootstrap() + ~~~~~~~~~^^ + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/cv2/__init__.py", line 153, in bootstrap + native_module = importlib.import_module("cv2") + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/importlib/__init__.py", line 88, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ImportError: libGL.so.1: cannot open shared object file: No such file or directory diff --git a/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250910_152535.log b/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250910_152535.log new file mode 100644 index 0000000000000000000000000000000000000000..7515492f3b0cfcfca49287fb1f82faa349a48cc2 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/logs/base_20250910_152535.log @@ -0,0 +1,9062 @@ +/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/torch/cuda/__init__.py:63: FutureWarning: The pynvml package is deprecated. Please install nvidia-ml-py instead. If you did not install pynvml directly, please report this to the maintainers of the package that installed pynvml for you. + import pynvml # type: ignore[import] +[2025-09-10 15:25:41] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-10 15:25:52] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-10 15:25:52] WARNING - RUN - run.py: main - 219: --reuse is not set, will not reuse previous (before one day) temporary files +fatal: detected dubious ownership in repository at '/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit' +To add an exception for this directory, call: + + git config --global --add safe.directory /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit +Namespace(data=['POPE'], model=['Qwen2.5-VL-7B-Instruct'], config=None, work_dir='./outputs/20250910_152552', mode='all', api_nproc=4, retry=None, judge_args=None, judge=None, verbose=True, ignore=False, reuse=False, reuse_aux=True, use_vllm=False, use_verifier=False) +['POPE'] +use_config False +ROOT +/mnt/bn/life-mllm/users/cxr/hallucination/OPERA/pope_coco/coco_pope_adversarial.jsonl + +out_file: ./outputs/20250910_152552/Qwen2.5-VL-7B-Instruct/T20250910_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250910_162159/Qwen2.5-VL-7B-Instruct/T20250910_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250909_152656/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250909_152846/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250909_155723/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2714/3000 [16:50<01:49, 2.61it/s]ours... +token_confidence 12.951955795288086 12.992851257324219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2715/3000 [16:51<01:48, 2.62it/s]ours... +token_confidence 16.387598037719727 14.263287544250488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2716/3000 [16:51<01:48, 2.61it/s]ours... +token_confidence 15.030107498168945 15.168034553527832 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2717/3000 [16:51<01:45, 2.68it/s]ours... +token_confidence 16.197179794311523 16.513124465942383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2718/3000 [16:52<01:43, 2.74it/s]ours... +token_confidence 14.705284118652344 14.933954238891602 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2719/3000 [16:52<01:41, 2.76it/s]ours... +token_confidence 14.215324401855469 13.346237182617188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2720/3000 [16:53<01:47, 2.61it/s]ours... +token_confidence 15.844018936157227 16.528850555419922 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2721/3000 [16:53<01:46, 2.61it/s]ours... +token_confidence 12.048248291015625 12.313394546508789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2722/3000 [16:53<01:46, 2.61it/s]ours... +token_confidence 12.110454559326172 12.239887237548828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2723/3000 [16:54<01:44, 2.64it/s]ours... +token_confidence 13.57931137084961 16.092241287231445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2724/3000 [16:54<01:42, 2.68it/s]ours... +token_confidence 15.992012023925781 15.860612869262695 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2725/3000 [16:54<01:44, 2.64it/s]ours... +token_confidence 15.825864791870117 14.697372436523438 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2726/3000 [16:55<01:49, 2.51it/s]ours... +token_confidence 15.29498291015625 15.729904174804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2727/3000 [16:55<01:48, 2.52it/s]ours... +token_confidence 15.196319580078125 16.01811408996582 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2728/3000 [16:56<01:45, 2.58it/s]ours... +token_confidence 15.538871765136719 15.586285591125488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2729/3000 [16:56<01:43, 2.62it/s]ours... +token_confidence 15.53785514831543 15.64732551574707 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2730/3000 [16:57<01:48, 2.50it/s]ours... +token_confidence 14.242424011230469 13.629705429077148 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2731/3000 [16:57<01:43, 2.59it/s]ours... +token_confidence 15.521539688110352 15.59901237487793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2732/3000 [16:57<01:42, 2.63it/s]ours... +token_confidence 16.87135887145996 15.706315994262695 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2733/3000 [16:58<01:40, 2.66it/s]ours... +token_confidence 15.171167373657227 14.573793411254883 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2734/3000 [16:58<01:39, 2.67it/s]ours... +token_confidence 13.537984848022461 12.815352439880371 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2735/3000 [16:58<01:37, 2.71it/s]ours... +token_confidence 15.312000274658203 14.574300765991211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2736/3000 [16:59<01:35, 2.77it/s]ours... +token_confidence 13.083873748779297 12.465042114257812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2737/3000 [16:59<01:34, 2.79it/s]ours... +token_confidence 17.24624252319336 14.5382719039917 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2738/3000 [16:59<01:33, 2.82it/s]ours... +token_confidence 16.083354949951172 15.221174240112305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2739/3000 [17:00<01:34, 2.77it/s]ours... +token_confidence 16.197303771972656 16.907167434692383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2740/3000 [17:00<01:42, 2.55it/s]ours... +token_confidence 13.544330596923828 12.387659072875977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2741/3000 [17:01<01:37, 2.66it/s]ours... +token_confidence 16.872074127197266 16.27415657043457 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2742/3000 [17:01<01:34, 2.72it/s]ours... +token_confidence 14.481002807617188 16.112030029296875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2743/3000 [17:01<01:33, 2.75it/s]ours... +token_confidence 15.310724258422852 14.816671371459961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2744/3000 [17:02<01:32, 2.77it/s]ours... +token_confidence 12.721746444702148 13.268823623657227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2745/3000 [17:02<01:32, 2.75it/s]ours... +token_confidence 14.576656341552734 14.657979965209961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2746/3000 [17:02<01:33, 2.72it/s]ours... +token_confidence 11.821571350097656 10.510831832885742 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2747/3000 [17:03<01:36, 2.63it/s]ours... +token_confidence 12.207633972167969 11.629068374633789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2748/3000 [17:03<01:36, 2.61it/s]ours... +token_confidence 17.325267791748047 15.088949203491211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2749/3000 [17:04<01:35, 2.62it/s]ours... +token_confidence 16.011701583862305 15.420426368713379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2750/3000 [17:04<01:38, 2.53it/s]ours... +token_confidence 14.636474609375 14.825868606567383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2751/3000 [17:04<01:34, 2.63it/s]ours... +token_confidence 16.003902435302734 15.593954086303711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2752/3000 [17:05<01:34, 2.63it/s]ours... +token_confidence 15.140558242797852 16.32131576538086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2753/3000 [17:05<01:36, 2.56it/s]ours... +token_confidence 14.364252090454102 12.847223281860352 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2754/3000 [17:06<01:37, 2.51it/s]ours... +token_confidence 15.174251556396484 14.41487979888916 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2755/3000 [17:06<01:37, 2.52it/s]ours... +token_confidence 15.848590850830078 17.922876358032227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2756/3000 [17:06<01:33, 2.61it/s]ours... +token_confidence 15.93670654296875 17.37726593017578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2757/3000 [17:07<01:32, 2.62it/s]ours... +token_confidence 14.86981201171875 11.736557006835938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2758/3000 [17:07<01:29, 2.69it/s]ours... +token_confidence 13.605107307434082 13.446796417236328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2759/3000 [17:07<01:27, 2.74it/s]ours... +token_confidence 16.284460067749023 15.139389038085938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2760/3000 [17:08<01:30, 2.64it/s]ours... +token_confidence 13.591409683227539 11.902801513671875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2761/3000 [17:08<01:27, 2.72it/s]ours... +token_confidence 15.78936767578125 14.201725959777832 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2762/3000 [17:08<01:29, 2.67it/s]ours... +token_confidence 16.993497848510742 15.457117080688477 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2763/3000 [17:09<01:30, 2.63it/s]ours... +token_confidence 15.293987274169922 15.25715446472168 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2764/3000 [17:09<01:27, 2.70it/s]ours... +token_confidence 14.743677139282227 13.493501663208008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2765/3000 [17:10<01:26, 2.72it/s]ours... +token_confidence 15.931825637817383 15.147811889648438 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2766/3000 [17:10<01:25, 2.74it/s]ours... +token_confidence 16.453386306762695 15.060837745666504 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a giraffe in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2767/3000 [17:10<01:24, 2.75it/s]ours... +token_confidence 15.57232666015625 15.274435043334961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2768/3000 [17:11<01:25, 2.71it/s]ours... +token_confidence 13.495708465576172 12.839717864990234 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2769/3000 [17:11<01:23, 2.76it/s]ours... +token_confidence 16.19322395324707 14.899726867675781 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2770/3000 [17:11<01:27, 2.64it/s]ours... +token_confidence 15.800819396972656 14.846395492553711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a zebra in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2771/3000 [17:12<01:26, 2.64it/s]ours... +token_confidence 15.605010986328125 16.689666748046875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2772/3000 [17:12<01:24, 2.69it/s]ours... +token_confidence 13.456871032714844 11.839336395263672 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2773/3000 [17:13<01:26, 2.64it/s]ours... +token_confidence 15.637981414794922 16.828903198242188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2774/3000 [17:13<01:25, 2.64it/s]ours... +token_confidence 11.91813850402832 9.888492584228516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▎| 2775/3000 [17:13<01:23, 2.71it/s]ours... +token_confidence 15.188699722290039 13.72260856628418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2776/3000 [17:14<01:22, 2.70it/s]ours... +token_confidence 15.670330047607422 14.517780303955078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2777/3000 [17:14<01:22, 2.70it/s]ours... +token_confidence 13.129251480102539 12.08598518371582 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2778/3000 [17:14<01:21, 2.74it/s]ours... +token_confidence 16.31955337524414 15.78324031829834 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2779/3000 [17:15<01:26, 2.57it/s]ours... +token_confidence 15.124879837036133 12.015119552612305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2780/3000 [17:15<01:27, 2.52it/s]ours... +token_confidence 12.27685546875 10.389726638793945 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2781/3000 [17:16<01:23, 2.61it/s]ours... +token_confidence 17.040271759033203 15.124420166015625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2782/3000 [17:16<01:20, 2.69it/s]ours... +token_confidence 14.26854133605957 13.22358512878418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2783/3000 [17:16<01:20, 2.68it/s]ours... +token_confidence 12.7366304397583 10.630435943603516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2784/3000 [17:17<01:18, 2.74it/s]ours... +token_confidence 13.606216430664062 13.50702953338623 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2785/3000 [17:17<01:17, 2.79it/s]ours... +token_confidence 15.75493049621582 17.881084442138672 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2786/3000 [17:17<01:15, 2.82it/s]ours... +token_confidence 12.67002010345459 16.18682861328125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2787/3000 [17:18<01:18, 2.72it/s]ours... +token_confidence 17.75634002685547 17.154861450195312 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2788/3000 [17:18<01:16, 2.77it/s]ours... +token_confidence 12.284740447998047 13.264286041259766 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2789/3000 [17:18<01:15, 2.81it/s]ours... +token_confidence 16.57794952392578 15.681110382080078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2790/3000 [17:19<01:17, 2.71it/s]ours... +token_confidence 12.765362739562988 14.41952133178711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2791/3000 [17:19<01:16, 2.72it/s]ours... +token_confidence 16.614269256591797 14.104899406433105 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2792/3000 [17:20<01:15, 2.75it/s]ours... +token_confidence 12.618349075317383 15.434926986694336 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2793/3000 [17:20<01:16, 2.72it/s]ours... +token_confidence 17.28272819519043 15.083658218383789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2794/3000 [17:20<01:15, 2.73it/s]ours... +token_confidence 13.199909210205078 14.126895904541016 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2795/3000 [17:21<01:13, 2.77it/s]ours... +token_confidence 15.131181716918945 12.313817977905273 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2796/3000 [17:21<01:16, 2.68it/s]ours... +token_confidence 15.729972839355469 16.43505859375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2797/3000 [17:21<01:15, 2.70it/s]ours... +token_confidence 16.36800765991211 16.554988861083984 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2798/3000 [17:22<01:14, 2.72it/s]ours... +token_confidence 16.3364315032959 17.122943878173828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2799/3000 [17:22<01:12, 2.77it/s]ours... +token_confidence 15.978445053100586 16.803024291992188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2800/3000 [17:23<01:15, 2.64it/s]ours... +token_confidence 12.741765022277832 13.229241371154785 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2801/3000 [17:23<01:12, 2.75it/s]ours... +token_confidence 12.117425918579102 14.542166709899902 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2802/3000 [17:23<01:11, 2.79it/s]ours... +token_confidence 12.283219337463379 11.163111686706543 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2803/3000 [17:24<01:09, 2.82it/s]ours... +token_confidence 14.995990753173828 14.682619094848633 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2804/3000 [17:24<01:09, 2.84it/s]ours... +token_confidence 13.149099349975586 12.35786247253418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2805/3000 [17:24<01:10, 2.77it/s]ours... +token_confidence 15.51323127746582 14.018377304077148 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2806/3000 [17:25<01:09, 2.78it/s]ours... +token_confidence 13.386346817016602 12.537517547607422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2807/3000 [17:25<01:11, 2.68it/s]ours... +token_confidence 12.764318466186523 11.914220809936523 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2808/3000 [17:25<01:11, 2.69it/s]ours... +token_confidence 12.345309257507324 13.651040077209473 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2809/3000 [17:26<01:11, 2.69it/s]ours... +token_confidence 13.685803413391113 13.853157043457031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2810/3000 [17:26<01:13, 2.60it/s]ours... +token_confidence 16.253067016601562 16.52997589111328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2811/3000 [17:27<01:12, 2.60it/s]ours... +token_confidence 15.332502365112305 16.146690368652344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2812/3000 [17:27<01:11, 2.64it/s]ours... +token_confidence 14.977706909179688 14.922130584716797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2813/3000 [17:27<01:12, 2.59it/s]ours... +token_confidence 13.712151527404785 12.914400100708008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2814/3000 [17:28<01:09, 2.66it/s]ours... +token_confidence 12.239782333374023 9.280705451965332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2815/3000 [17:28<01:08, 2.72it/s]ours... +token_confidence 14.674808502197266 11.526883125305176 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2816/3000 [17:28<01:06, 2.75it/s]ours... +token_confidence 15.595603942871094 13.090383529663086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2817/3000 [17:29<01:07, 2.70it/s]ours... +token_confidence 14.953226089477539 11.839759826660156 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2818/3000 [17:29<01:06, 2.74it/s]ours... +token_confidence 13.8535737991333 10.836265563964844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2819/3000 [17:30<01:06, 2.71it/s]ours... +token_confidence 13.117088317871094 9.681234359741211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2820/3000 [17:30<01:08, 2.61it/s]ours... +token_confidence 17.70694351196289 15.478782653808594 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2821/3000 [17:30<01:07, 2.65it/s]ours... +token_confidence 14.855438232421875 13.630481719970703 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2822/3000 [17:31<01:06, 2.67it/s]ours... +token_confidence 12.604619026184082 10.541141510009766 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2823/3000 [17:31<01:06, 2.67it/s]ours... +token_confidence 15.155769348144531 15.065201759338379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2824/3000 [17:31<01:05, 2.69it/s]ours... +token_confidence 15.970321655273438 14.599452018737793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2825/3000 [17:32<01:04, 2.72it/s]ours... +token_confidence 12.182002067565918 12.05175495147705 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2826/3000 [17:32<01:03, 2.72it/s]ours... +token_confidence 15.771812438964844 15.05557918548584 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2827/3000 [17:32<01:02, 2.75it/s]ours... +token_confidence 15.808612823486328 15.016427993774414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2828/3000 [17:33<01:03, 2.69it/s]ours... +token_confidence 16.098630905151367 15.226439476013184 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2829/3000 [17:33<01:04, 2.66it/s]ours... +token_confidence 15.91607666015625 16.92922592163086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2830/3000 [17:34<01:05, 2.58it/s]ours... +token_confidence 15.296045303344727 15.061288833618164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2831/3000 [17:34<01:04, 2.63it/s]ours... +token_confidence 15.346101760864258 14.638544082641602 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2832/3000 [17:34<01:03, 2.63it/s]ours... +token_confidence 12.431219100952148 12.043529510498047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2833/3000 [17:35<01:03, 2.65it/s]ours... +token_confidence 15.026824951171875 16.619701385498047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2834/3000 [17:35<01:03, 2.62it/s]ours... +token_confidence 12.997920036315918 16.450607299804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2835/3000 [17:36<01:01, 2.66it/s]ours... +token_confidence 16.72187042236328 15.302582740783691 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2836/3000 [17:36<00:59, 2.74it/s]ours... +token_confidence 13.496132850646973 15.949075698852539 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2837/3000 [17:36<01:00, 2.71it/s]ours... +token_confidence 15.705968856811523 14.783227920532227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2838/3000 [17:37<00:58, 2.75it/s]ours... +token_confidence 12.34790325164795 10.51291275024414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2839/3000 [17:37<00:59, 2.70it/s]ours... +token_confidence 15.718202590942383 11.890958786010742 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2840/3000 [17:37<01:01, 2.60it/s]ours... +token_confidence 16.52416229248047 13.66783332824707 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2841/3000 [17:38<01:00, 2.62it/s]ours... +token_confidence 14.505929946899414 11.578596115112305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2842/3000 [17:38<00:59, 2.66it/s]ours... +token_confidence 12.470712661743164 8.672359466552734 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] + No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2843/3000 [17:39<00:58, 2.69it/s]ours... +token_confidence 12.478721618652344 9.429229736328125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2844/3000 [17:39<01:00, 2.59it/s]ours... +token_confidence 15.122421264648438 15.464024543762207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2845/3000 [17:39<01:00, 2.57it/s]ours... +token_confidence 16.314876556396484 14.14521598815918 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2846/3000 [17:40<00:57, 2.66it/s]ours... +token_confidence 15.533660888671875 16.74334716796875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2847/3000 [17:40<00:56, 2.70it/s]ours... +token_confidence 12.334237098693848 13.390063285827637 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2848/3000 [17:40<00:56, 2.70it/s]ours... +token_confidence 12.959967613220215 13.844331741333008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2849/3000 [17:41<00:55, 2.73it/s]ours... +token_confidence 17.078157424926758 15.376585006713867 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2850/3000 [17:41<00:57, 2.61it/s]ours... +token_confidence 14.308244705200195 14.72059440612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2851/3000 [17:42<00:56, 2.64it/s]ours... +token_confidence 15.908126831054688 16.676692962646484 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2852/3000 [17:42<00:55, 2.69it/s]ours... +token_confidence 14.59524154663086 16.536577224731445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2853/3000 [17:42<00:55, 2.67it/s]ours... +token_confidence 14.44693374633789 14.839578628540039 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2854/3000 [17:43<00:53, 2.71it/s]ours... +token_confidence 16.483417510986328 15.19800090789795 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2855/3000 [17:43<00:53, 2.69it/s]ours... +token_confidence 15.793642044067383 16.118125915527344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2856/3000 [17:43<00:52, 2.73it/s]ours... +token_confidence 17.24995994567871 14.9439697265625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2857/3000 [17:44<00:52, 2.71it/s]ours... +token_confidence 15.632209777832031 15.115020751953125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2858/3000 [17:44<00:52, 2.70it/s]ours... +token_confidence 13.132760047912598 12.95496940612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2859/3000 [17:45<00:53, 2.64it/s]ours... +token_confidence 15.164117813110352 14.176642417907715 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2860/3000 [17:45<00:57, 2.43it/s]ours... +token_confidence 13.565119743347168 13.915395736694336 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2861/3000 [17:45<00:56, 2.48it/s]ours... +token_confidence 14.506990432739258 13.547088623046875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2862/3000 [17:46<00:53, 2.59it/s]ours... +token_confidence 16.0394287109375 15.438894271850586 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2863/3000 [17:46<00:52, 2.61it/s]ours... +token_confidence 14.819707870483398 13.928895950317383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2864/3000 [17:46<00:50, 2.68it/s]ours... +token_confidence 13.002264022827148 13.536382675170898 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2865/3000 [17:47<00:50, 2.67it/s]ours... +token_confidence 14.834649085998535 13.824280738830566 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2866/3000 [17:47<00:49, 2.72it/s]ours... +token_confidence 12.05146598815918 13.035828590393066 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2867/3000 [17:48<00:48, 2.76it/s]ours... +token_confidence 14.29629135131836 13.299593925476074 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2868/3000 [17:48<00:47, 2.79it/s]ours... +token_confidence 13.031436920166016 15.473824501037598 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2869/3000 [17:48<00:48, 2.72it/s]ours... +token_confidence 15.660152435302734 18.11481475830078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2870/3000 [17:49<00:50, 2.59it/s]ours... +token_confidence 15.760446548461914 15.965296745300293 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2871/3000 [17:49<00:48, 2.64it/s]ours... +token_confidence 15.44969367980957 16.06676483154297 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2872/3000 [17:49<00:47, 2.71it/s]ours... +token_confidence 14.423019409179688 17.168079376220703 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2873/3000 [17:50<00:47, 2.70it/s]ours... +token_confidence 17.151268005371094 18.101417541503906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2874/3000 [17:50<00:45, 2.75it/s]ours... +token_confidence 15.69202995300293 16.419940948486328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2875/3000 [17:51<00:46, 2.71it/s]ours... +token_confidence 15.971855163574219 16.413341522216797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2876/3000 [17:51<00:45, 2.74it/s]ours... +token_confidence 12.235248565673828 13.651222229003906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2877/3000 [17:51<00:44, 2.77it/s]ours... +token_confidence 15.601051330566406 14.903434753417969 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2878/3000 [17:52<00:44, 2.74it/s]ours... +token_confidence 15.966558456420898 14.564645767211914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2879/3000 [17:52<00:43, 2.79it/s]ours... +token_confidence 15.518115997314453 15.863834381103516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2880/3000 [17:52<00:44, 2.68it/s]ours... +token_confidence 15.099685668945312 14.488922119140625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2881/3000 [17:53<00:43, 2.74it/s]ours... +token_confidence 15.49458122253418 15.54854965209961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2882/3000 [17:53<00:42, 2.77it/s]ours... +token_confidence 13.093046188354492 14.095588684082031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2883/3000 [17:53<00:42, 2.73it/s]ours... +token_confidence 13.31644058227539 11.29574966430664 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2884/3000 [17:54<00:42, 2.75it/s]ours... +token_confidence 13.78424072265625 13.314617156982422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2885/3000 [17:54<00:42, 2.73it/s]ours... +token_confidence 13.453228950500488 12.462068557739258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2886/3000 [17:55<00:46, 2.45it/s]ours... +token_confidence 12.064128875732422 12.846120834350586 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2887/3000 [17:55<00:44, 2.54it/s]ours... +token_confidence 16.250925064086914 14.558724403381348 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2888/3000 [17:55<00:42, 2.61it/s]ours... +token_confidence 15.45772933959961 15.302740097045898 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2889/3000 [17:56<00:42, 2.61it/s]ours... +token_confidence 15.372425079345703 16.16036033630371 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2890/3000 [17:56<00:43, 2.54it/s]ours... +token_confidence 15.302928924560547 14.47450065612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2891/3000 [17:57<00:42, 2.59it/s]ours... +token_confidence 16.043272018432617 15.59259033203125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2892/3000 [17:57<00:40, 2.66it/s]ours... +token_confidence 12.320391654968262 12.7440185546875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2893/3000 [17:57<00:39, 2.71it/s]ours... +token_confidence 15.560794830322266 13.22658920288086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2894/3000 [17:58<00:38, 2.74it/s]ours... +token_confidence 16.858182907104492 15.351642608642578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2895/3000 [17:58<00:38, 2.71it/s]ours... +token_confidence 15.34177017211914 15.048395156860352 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2896/3000 [17:58<00:38, 2.72it/s]ours... +token_confidence 12.151689529418945 11.264841079711914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2897/3000 [17:59<00:37, 2.75it/s]ours... +token_confidence 15.576156616210938 15.245094299316406 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2898/3000 [17:59<00:39, 2.60it/s]ours... +token_confidence 14.813830375671387 15.173911094665527 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2899/3000 [18:00<00:38, 2.64it/s]ours... +token_confidence 12.792268753051758 13.201255798339844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2900/3000 [18:00<00:40, 2.48it/s]ours... +token_confidence 16.821290969848633 14.513077735900879 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2901/3000 [18:00<00:40, 2.43it/s]ours... +token_confidence 15.579504013061523 15.700133323669434 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2902/3000 [18:01<00:38, 2.51it/s]ours... +token_confidence 14.45612907409668 14.479864120483398 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2903/3000 [18:01<00:38, 2.53it/s]ours... +token_confidence 15.251310348510742 14.891456604003906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2904/3000 [18:02<00:36, 2.62it/s]ours... +token_confidence 12.984794616699219 12.096078872680664 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2905/3000 [18:02<00:35, 2.69it/s]ours... +token_confidence 15.771379470825195 17.677631378173828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2906/3000 [18:02<00:34, 2.69it/s]ours... +token_confidence 12.163898468017578 11.323527336120605 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2907/3000 [18:03<00:35, 2.64it/s]ours... +token_confidence 16.515636444091797 15.210372924804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2908/3000 [18:03<00:34, 2.67it/s]ours... +token_confidence 15.564271926879883 14.350801467895508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2909/3000 [18:03<00:33, 2.72it/s]ours... +token_confidence 15.26392650604248 13.656306266784668 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2910/3000 [18:04<00:34, 2.64it/s]ours... +token_confidence 12.131585121154785 14.109987258911133 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2911/3000 [18:04<00:33, 2.67it/s]ours... +token_confidence 16.48777198791504 16.808856964111328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2912/3000 [18:04<00:32, 2.72it/s]ours... +token_confidence 14.919475555419922 14.921646118164062 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2913/3000 [18:05<00:34, 2.55it/s]ours... +token_confidence 11.788609504699707 12.877374649047852 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2914/3000 [18:05<00:32, 2.61it/s]ours... +token_confidence 12.953896522521973 14.106937408447266 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2915/3000 [18:06<00:32, 2.60it/s]ours... +token_confidence 15.460060119628906 17.7117919921875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2916/3000 [18:06<00:31, 2.71it/s]ours... +token_confidence 11.968819618225098 10.232215881347656 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2917/3000 [18:06<00:30, 2.70it/s]ours... +token_confidence 13.017515182495117 9.947013854980469 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2918/3000 [18:07<00:29, 2.74it/s]ours... +token_confidence 16.43393325805664 13.80075454711914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2919/3000 [18:07<00:30, 2.64it/s]ours... +token_confidence 14.295673370361328 11.768582344055176 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2920/3000 [18:08<00:31, 2.52it/s]ours... +token_confidence 12.89589786529541 12.988277435302734 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2921/3000 [18:08<00:30, 2.58it/s]ours... +token_confidence 15.532316207885742 15.200489044189453 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2922/3000 [18:08<00:30, 2.55it/s]ours... +token_confidence 15.774513244628906 15.326964378356934 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2923/3000 [18:09<00:30, 2.54it/s]ours... +token_confidence 15.169139862060547 16.18675994873047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2924/3000 [18:09<00:29, 2.62it/s]ours... +token_confidence 15.134042739868164 14.881011962890625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2925/3000 [18:10<00:29, 2.56it/s]ours... +token_confidence 13.74690055847168 12.868728637695312 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2926/3000 [18:10<00:28, 2.63it/s]ours... +token_confidence 12.663017272949219 14.317346572875977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2927/3000 [18:10<00:27, 2.63it/s]ours... +token_confidence 13.843515396118164 15.274571418762207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2928/3000 [18:11<00:26, 2.68it/s]ours... +token_confidence 13.94366455078125 14.65946102142334 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2929/3000 [18:11<00:26, 2.73it/s]ours... +token_confidence 16.845069885253906 14.513847351074219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2930/3000 [18:11<00:26, 2.62it/s]ours... +token_confidence 12.430644989013672 15.448990821838379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2931/3000 [18:12<00:26, 2.65it/s]ours... +token_confidence 12.295373916625977 12.1190185546875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2932/3000 [18:12<00:25, 2.68it/s]ours... +token_confidence 15.411407470703125 15.01962661743164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2933/3000 [18:12<00:24, 2.75it/s]ours... +token_confidence 15.688034057617188 15.32177448272705 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2934/3000 [18:13<00:23, 2.78it/s]ours... +token_confidence 14.707706451416016 14.776290893554688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2935/3000 [18:13<00:23, 2.73it/s]ours... +token_confidence 15.700263977050781 14.818093299865723 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2936/3000 [18:14<00:23, 2.77it/s]ours... +token_confidence 12.130331993103027 12.297551155090332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2937/3000 [18:14<00:22, 2.80it/s]ours... +token_confidence 13.463072776794434 11.724565505981445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2938/3000 [18:14<00:22, 2.76it/s]ours... +token_confidence 12.524802207946777 13.104962348937988 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2939/3000 [18:15<00:23, 2.59it/s]ours... +token_confidence 12.863550186157227 11.673877716064453 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2940/3000 [18:15<00:24, 2.45it/s]ours... +token_confidence 12.4320068359375 13.029433250427246 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2941/3000 [18:16<00:23, 2.54it/s]ours... +token_confidence 15.441240310668945 14.029318809509277 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2942/3000 [18:16<00:22, 2.62it/s]ours... +token_confidence 16.192731857299805 14.584410667419434 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2943/3000 [18:16<00:22, 2.58it/s]ours... +token_confidence 14.841495513916016 15.40988540649414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2944/3000 [18:17<00:20, 2.68it/s]ours... +token_confidence 12.241999626159668 12.089678764343262 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2945/3000 [18:17<00:20, 2.71it/s]ours... +token_confidence 12.518064498901367 12.177897453308105 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2946/3000 [18:17<00:19, 2.76it/s]ours... +token_confidence 15.955259323120117 15.428451538085938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2947/3000 [18:18<00:19, 2.72it/s]ours... +token_confidence 14.976583480834961 13.881301879882812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2948/3000 [18:18<00:19, 2.73it/s]ours... +token_confidence 16.354646682739258 14.300439834594727 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2949/3000 [18:18<00:18, 2.76it/s]ours... +token_confidence 15.270418167114258 15.130461692810059 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2950/3000 [18:19<00:18, 2.65it/s]ours... +token_confidence 12.688458442687988 12.311226844787598 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2951/3000 [18:19<00:18, 2.65it/s]ours... +token_confidence 15.531564712524414 14.41840648651123 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2952/3000 [18:20<00:17, 2.69it/s]ours... +token_confidence 15.971872329711914 15.735848426818848 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2953/3000 [18:20<00:17, 2.64it/s]ours... +token_confidence 15.693361282348633 14.993910789489746 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2954/3000 [18:20<00:17, 2.63it/s]ours... +token_confidence 11.847887992858887 10.677001953125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2955/3000 [18:21<00:17, 2.57it/s]ours... +token_confidence 15.259910583496094 15.371190071105957 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2956/3000 [18:21<00:16, 2.65it/s]ours... +token_confidence 14.762300491333008 14.649131774902344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2957/3000 [18:21<00:15, 2.70it/s]ours... +token_confidence 15.488975524902344 14.77102279663086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2958/3000 [18:22<00:15, 2.74it/s]ours... +token_confidence 11.827298164367676 9.394031524658203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2959/3000 [18:22<00:15, 2.71it/s]ours... +token_confidence 15.76671028137207 15.238225936889648 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2960/3000 [18:23<00:15, 2.63it/s]ours... +token_confidence 15.924419403076172 13.908456802368164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2961/3000 [18:23<00:14, 2.72it/s]ours... +token_confidence 15.772602081298828 13.752092361450195 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2962/3000 [18:23<00:13, 2.76it/s]ours... +token_confidence 13.5653076171875 13.96495246887207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2963/3000 [18:24<00:13, 2.66it/s]ours... +token_confidence 12.09259033203125 12.260025024414062 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2964/3000 [18:24<00:13, 2.74it/s]ours... +token_confidence 16.107776641845703 14.947851181030273 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2965/3000 [18:24<00:12, 2.76it/s]ours... +token_confidence 15.631926536560059 14.583686828613281 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2966/3000 [18:25<00:12, 2.72it/s]ours... +token_confidence 17.043785095214844 14.677785873413086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2967/3000 [18:25<00:12, 2.70it/s]ours... +token_confidence 15.33786392211914 14.302164077758789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2968/3000 [18:25<00:11, 2.73it/s]ours... +token_confidence 12.483122825622559 12.324162483215332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2969/3000 [18:26<00:11, 2.69it/s]ours... +token_confidence 14.433391571044922 13.952796936035156 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2970/3000 [18:26<00:11, 2.59it/s]ours... +token_confidence 16.882953643798828 15.140613555908203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2971/3000 [18:27<00:11, 2.56it/s]ours... +token_confidence 15.726882934570312 13.082565307617188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2972/3000 [18:27<00:11, 2.53it/s]ours... +token_confidence 14.795921325683594 13.289857864379883 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2973/3000 [18:27<00:10, 2.55it/s]ours... +token_confidence 15.143640518188477 14.62070369720459 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2974/3000 [18:28<00:10, 2.59it/s]ours... +token_confidence 14.544023513793945 14.49643611907959 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2975/3000 [18:28<00:09, 2.64it/s]ours... +token_confidence 13.911133766174316 11.553352355957031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2976/3000 [18:29<00:08, 2.68it/s]ours... +token_confidence 12.947036743164062 12.819023132324219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +.Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2977/3000 [18:29<00:08, 2.63it/s]ours... +token_confidence 14.541938781738281 12.27204418182373 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2978/3000 [18:29<00:08, 2.68it/s]ours... +token_confidence 17.270578384399414 15.474961280822754 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2979/3000 [18:30<00:07, 2.64it/s]ours... +token_confidence 13.12424373626709 10.821123123168945 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2980/3000 [18:30<00:07, 2.55it/s]ours... +token_confidence 15.575836181640625 13.822530746459961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2981/3000 [18:31<00:07, 2.49it/s]ours... +token_confidence 13.683242797851562 10.908895492553711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2982/3000 [18:31<00:07, 2.56it/s]ours... +token_confidence 15.09487533569336 16.44427490234375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2983/3000 [18:31<00:06, 2.61it/s]ours... +token_confidence 15.940685272216797 13.643317222595215 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2984/3000 [18:32<00:05, 2.70it/s]ours... +token_confidence 12.878137588500977 14.909943580627441 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2985/3000 [18:32<00:05, 2.72it/s]ours... +token_confidence 16.247880935668945 18.382619857788086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2986/3000 [18:32<00:05, 2.77it/s]ours... +token_confidence 13.070942878723145 14.920808792114258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2987/3000 [18:33<00:04, 2.65it/s]ours... +token_confidence 17.253070831298828 18.482707977294922 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2988/3000 [18:33<00:04, 2.66it/s]ours... +token_confidence 12.93958854675293 12.631311416625977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2989/3000 [18:33<00:04, 2.72it/s]ours... +token_confidence 14.985885620117188 14.054231643676758 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2990/3000 [18:34<00:03, 2.61it/s]ours... +token_confidence 15.168800354003906 14.825572967529297 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2991/3000 [18:34<00:03, 2.66it/s]ours... +token_confidence 12.53053092956543 10.482037544250488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2992/3000 [18:35<00:03, 2.56it/s]ours... +token_confidence 12.723091125488281 12.668216705322266 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2993/3000 [18:35<00:02, 2.60it/s]ours... +token_confidence 16.280488967895508 14.198299407958984 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2994/3000 [18:35<00:02, 2.63it/s]ours... +token_confidence 14.608861923217773 14.186758041381836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2995/3000 [18:36<00:01, 2.65it/s]ours... +token_confidence 15.45034408569336 16.605979919433594 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2996/3000 [18:36<00:01, 2.71it/s]ours... +token_confidence 13.651948928833008 10.436607360839844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2997/3000 [18:37<00:01, 2.70it/s]ours... +token_confidence 15.008098602294922 13.218560218811035 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2998/3000 [18:37<00:00, 2.71it/s]ours... +token_confidence 15.685447692871094 14.773058891296387 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2999/3000 [18:37<00:00, 2.78it/s]ours... +token_confidence 14.03681755065918 13.247355461120605 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:38<00:00, 2.61it/s] Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:38<00:00, 2.68it/s] +[2025-09-09 16:16:51] INFO - RUN - run.py: main - 404: {'nproc': 4, 'verbose': True, 'retry': 3, 'model': 'chatgpt-0125'} +/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py:74: UserWarning: OPENAI_API_KEY is not working properly, will use exact matching for evaluation + warnings.warn('OPENAI_API_KEY is not working properly, will use exact matching for evaluation') +[2025-09-09 16:16:53] ERROR - RUN - run.py: main - 484: Model Qwen2.5-VL-7B-Instruct x Dataset POPE combination failed: 'category', skipping this combination. +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3812, in get_loc + return self._engine.get_loc(casted_key) + ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ + File "pandas/_libs/index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item + File "pandas/_libs/hashtable_class_helper.pxi", line 7096, in pandas._libs.hashtable.PyObjectHashTable.get_item +KeyError: 'category' + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/run.py", line 455, in main + eval_results = dataset.evaluate(result_file, **judge_kwargs) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py", line 102, in evaluate + score = POPE_rating(storage) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/utils/yorn.py", line 155, in POPE_rating + data = data.assign(category=data['category'].str.split(',')).explode('category') + ~~~~^^^^^^^^^^^^ + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/frame.py", line 4107, in __getitem__ + indexer = self.columns.get_loc(key) + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3819, in get_loc + raise KeyError(key) from err +KeyError: 'category' +POPE diff --git a/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_155840.log b/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_155840.log new file mode 100644 index 0000000000000000000000000000000000000000..102a9d9e79468de84ef688482f47ae30ae60c91a --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_155840.log @@ -0,0 +1,12093 @@ +[2025-09-09 15:58:46] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 15:58:56] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 15:58:56] WARNING - RUN - run.py: main - 219: --reuse is not set, will not reuse previous (before one day) temporary files +fatal: detected dubious ownership in repository at '/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit' +To add an exception for this directory, call: + + git config --global --add safe.directory /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit +HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +[2025-09-09 15:58:57] WARNING - _http.py: http_backoff - 315: HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +Retrying in 1s [Retry 1/5]. +[2025-09-09 15:58:57] WARNING - _http.py: http_backoff - 332: Retrying in 1s [Retry 1/5]. +HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +[2025-09-09 15:58:58] WARNING - _http.py: http_backoff - 315: HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +Retrying in 2s [Retry 2/5]. +[2025-09-09 15:58:58] WARNING - _http.py: http_backoff - 332: Retrying in 2s [Retry 2/5]. +HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +[2025-09-09 15:59:00] WARNING - _http.py: http_backoff - 315: HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +Retrying in 4s [Retry 3/5]. +[2025-09-09 15:59:00] WARNING - _http.py: http_backoff - 332: Retrying in 4s [Retry 3/5]. +HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +[2025-09-09 15:59:04] WARNING - _http.py: http_backoff - 315: HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +Retrying in 8s [Retry 4/5]. +[2025-09-09 15:59:04] WARNING - _http.py: http_backoff - 332: Retrying in 8s [Retry 4/5]. +HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +[2025-09-09 15:59:13] WARNING - _http.py: http_backoff - 315: HTTP Error 429 thrown while requesting HEAD https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct/resolve/main/processor_config.json +Retrying in 8s [Retry 5/5]. +[2025-09-09 15:59:13] WARNING - _http.py: http_backoff - 332: Retrying in 8s [Retry 5/5]. +Namespace(data=['POPE'], model=['Qwen2.5-VL-7B-Instruct'], config=None, work_dir='./outputs/20250909_155856', mode='all', api_nproc=4, retry=None, judge_args=None, judge=None, verbose=True, ignore=False, reuse=False, reuse_aux=True, use_vllm=False, use_verifier=False) +['POPE'] +use_config False +ROOT +/mnt/bn/life-mllm/users/cxr/hallucination/OPERA/pope_coco/coco_pope_popular.jsonl + +out_file: ./outputs/20250909_155856/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2574/3000 [16:09<02:47, 2.55it/s]ours... +token_confidence 13.185806274414062 10.971670150756836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2575/3000 [16:10<02:43, 2.61it/s]ours... +token_confidence 16.20697593688965 14.380191802978516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2576/3000 [16:10<02:37, 2.69it/s]ours... +token_confidence 17.05599021911621 15.841775894165039 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2577/3000 [16:10<02:37, 2.68it/s]ours... +token_confidence 15.563081741333008 15.655471801757812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2578/3000 [16:11<02:36, 2.70it/s]ours... +token_confidence 13.487199783325195 15.349287033081055 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2579/3000 [16:11<02:36, 2.69it/s]ours... +token_confidence 16.037717819213867 15.536346435546875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000516601.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2580/3000 [16:11<02:40, 2.61it/s]ours... +token_confidence 16.359586715698242 16.246925354003906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2581/3000 [16:12<02:42, 2.57it/s]ours... +token_confidence 15.5537109375 16.179630279541016 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2582/3000 [16:12<02:40, 2.60it/s]ours... +token_confidence 14.909944534301758 14.333818435668945 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2583/3000 [16:13<02:42, 2.57it/s]ours... +token_confidence 12.656096458435059 11.794139862060547 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2584/3000 [16:13<02:38, 2.63it/s]ours... +token_confidence 16.482080459594727 15.065064430236816 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2585/3000 [16:13<02:37, 2.64it/s]ours... +token_confidence 15.300289154052734 14.705242156982422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000562155.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2586/3000 [16:14<02:33, 2.70it/s]ours... +token_confidence 15.906646728515625 15.912702560424805 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▌ | 2587/3000 [16:14<02:34, 2.68it/s]ours... +token_confidence 15.870368957519531 13.162230491638184 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2588/3000 [16:14<02:31, 2.72it/s]ours... +token_confidence 12.606022834777832 11.17524528503418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2589/3000 [16:15<02:30, 2.73it/s]ours... +token_confidence 15.204591751098633 15.082221984863281 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2590/3000 [16:15<02:35, 2.63it/s]ours... +token_confidence 12.256882667541504 12.537160873413086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2591/3000 [16:16<02:30, 2.71it/s]ours... +token_confidence 15.590919494628906 14.567424774169922 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000142056.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2592/3000 [16:16<02:28, 2.74it/s]ours... +token_confidence 15.675466537475586 16.636764526367188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2593/3000 [16:16<02:27, 2.77it/s]ours... +token_confidence 16.278011322021484 15.543575286865234 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2594/3000 [16:17<02:28, 2.73it/s]ours... +token_confidence 15.572725296020508 14.58071517944336 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 86%|████████▋ | 2595/3000 [16:17<02:27, 2.75it/s]ours... +token_confidence 16.574522018432617 17.98672103881836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2596/3000 [16:17<02:26, 2.76it/s]ours... +token_confidence 14.004914283752441 14.30406665802002 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2597/3000 [16:18<02:26, 2.75it/s]ours... +token_confidence 12.146379470825195 13.843416213989258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000299986.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2598/3000 [16:18<02:25, 2.77it/s]ours... +token_confidence 12.22220516204834 14.089691162109375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2599/3000 [16:18<02:24, 2.78it/s]ours... +token_confidence 15.70425033569336 17.821300506591797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2600/3000 [16:19<02:33, 2.60it/s]ours... +token_confidence 13.54855728149414 16.95240020751953 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2601/3000 [16:19<02:28, 2.69it/s]ours... +token_confidence 15.685245513916016 16.387226104736328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2602/3000 [16:20<02:25, 2.73it/s]ours... +token_confidence 12.54816722869873 12.568878173828125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2603/3000 [16:20<02:27, 2.70it/s]ours... +token_confidence 15.606624603271484 17.730854034423828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000521643.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2604/3000 [16:20<02:28, 2.67it/s]ours... +token_confidence 14.864599227905273 14.11434268951416 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2605/3000 [16:21<02:29, 2.64it/s]ours... +token_confidence 15.339092254638672 13.783312797546387 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2606/3000 [16:21<02:29, 2.63it/s]ours... +token_confidence 11.9429292678833 9.94424057006836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a surfboard in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2607/3000 [16:22<02:34, 2.55it/s]ours... +token_confidence 15.171653747558594 14.073458671569824 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2608/3000 [16:22<02:27, 2.65it/s]ours... +token_confidence 15.523128509521484 14.22565746307373 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a kite in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2609/3000 [16:22<02:26, 2.67it/s]ours... +token_confidence 15.486536026000977 14.64731216430664 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000574454.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2610/3000 [16:23<02:31, 2.58it/s]ours... +token_confidence 12.683148384094238 14.97601318359375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2611/3000 [16:23<02:27, 2.63it/s]ours... +token_confidence 17.144472122192383 16.445030212402344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2612/3000 [16:23<02:24, 2.69it/s]ours... +token_confidence 15.622812271118164 16.11835479736328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2613/3000 [16:24<02:22, 2.72it/s]ours... +token_confidence 16.804502487182617 17.622940063476562 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2614/3000 [16:24<02:20, 2.74it/s]ours... +token_confidence 11.99448299407959 13.401942253112793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2615/3000 [16:24<02:20, 2.74it/s]ours... +token_confidence 12.078943252563477 12.675005912780762 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000415727.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2616/3000 [16:25<02:19, 2.75it/s]ours... +token_confidence 16.000476837158203 15.787592887878418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2617/3000 [16:25<02:21, 2.71it/s]ours... +token_confidence 17.031757354736328 15.888835906982422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2618/3000 [16:26<02:19, 2.73it/s]ours... +token_confidence 12.58154010772705 12.938075065612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a suitcase in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2619/3000 [16:26<02:18, 2.75it/s]ours... +token_confidence 15.444633483886719 16.220272064208984 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2620/3000 [16:26<02:24, 2.64it/s]ours... +token_confidence 15.858797073364258 15.683900833129883 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2621/3000 [16:27<02:25, 2.61it/s]ours... +token_confidence 15.252557754516602 15.624467849731445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000222118.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2622/3000 [16:27<02:20, 2.69it/s]ours... +token_confidence 13.98920726776123 13.525080680847168 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a book in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2623/3000 [16:27<02:18, 2.72it/s]ours... +token_confidence 15.575546264648438 17.648761749267578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 87%|████████▋ | 2624/3000 [16:28<02:20, 2.68it/s]ours... +token_confidence 16.164844512939453 14.706867218017578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a teddy bear in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2625/3000 [16:28<02:17, 2.72it/s]ours... +token_confidence 17.29859161376953 14.778226852416992 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2626/3000 [16:28<02:16, 2.75it/s]ours... +token_confidence 13.542165756225586 16.242923736572266 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a bear in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2627/3000 [16:29<02:15, 2.76it/s]ours... +token_confidence 16.76668930053711 15.639873504638672 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514292.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2628/3000 [16:29<02:16, 2.72it/s]ours... +token_confidence 15.350324630737305 13.788320541381836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2629/3000 [16:30<02:16, 2.72it/s]ours... +token_confidence 15.503997802734375 15.678973197937012 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2630/3000 [16:30<02:20, 2.63it/s]ours... +token_confidence 17.142623901367188 15.929178237915039 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2631/3000 [16:30<02:19, 2.65it/s]ours... +token_confidence 13.962898254394531 13.680289268493652 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2632/3000 [16:31<02:19, 2.64it/s]ours... +token_confidence 12.588748931884766 12.977313995361328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2633/3000 [16:31<02:17, 2.67it/s]ours... +token_confidence 14.052141189575195 15.259004592895508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000117527.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2634/3000 [16:31<02:15, 2.69it/s]ours... +token_confidence 13.019762992858887 12.515787124633789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2635/3000 [16:32<02:15, 2.69it/s]ours... +token_confidence 14.991994857788086 14.048833847045898 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2636/3000 [16:32<02:12, 2.75it/s]ours... +token_confidence 12.511100769042969 15.293618202209473 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2637/3000 [16:33<02:22, 2.54it/s]ours... +token_confidence 15.421052932739258 16.439868927001953 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2638/3000 [16:33<02:19, 2.60it/s]ours... +token_confidence 14.709407806396484 16.0772705078125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2639/3000 [16:33<02:15, 2.66it/s]ours... +token_confidence 17.038610458374023 16.652034759521484 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000016451.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2640/3000 [16:34<02:17, 2.61it/s]ours... +token_confidence 13.40625 13.119640350341797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2641/3000 [16:34<02:12, 2.71it/s]ours... +token_confidence 15.550439834594727 13.68556022644043 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2642/3000 [16:34<02:10, 2.73it/s]ours... +token_confidence 14.3055419921875 14.767461776733398 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2643/3000 [16:35<02:10, 2.73it/s]ours... +token_confidence 13.670307159423828 12.951301574707031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2644/3000 [16:35<02:08, 2.76it/s]ours... +token_confidence 17.052474975585938 15.605857849121094 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2645/3000 [16:36<02:09, 2.75it/s]ours... +token_confidence 15.462291717529297 14.916913032531738 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429706.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2646/3000 [16:36<02:08, 2.76it/s]ours... +token_confidence 16.73343276977539 13.948563575744629 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2647/3000 [16:36<02:14, 2.63it/s]ours... +token_confidence 15.720654487609863 15.364553451538086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2648/3000 [16:37<02:21, 2.48it/s]ours... +token_confidence 16.23267936706543 15.831875801086426 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2649/3000 [16:37<02:17, 2.56it/s]ours... +token_confidence 15.326622009277344 16.716655731201172 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2650/3000 [16:38<02:25, 2.41it/s]ours... +token_confidence 15.310972213745117 14.93112564086914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a frisbee in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2651/3000 [16:38<02:17, 2.54it/s]ours... +token_confidence 12.70328140258789 12.818524360656738 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429580.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2652/3000 [16:38<02:15, 2.57it/s]ours... +token_confidence 12.778399467468262 12.509979248046875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2653/3000 [16:39<02:12, 2.61it/s]ours... +token_confidence 16.18865394592285 16.469684600830078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2654/3000 [16:39<02:11, 2.64it/s]ours... +token_confidence 15.02537727355957 14.968233108520508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 88%|████████▊ | 2655/3000 [16:39<02:07, 2.70it/s]ours... +token_confidence 15.239740371704102 14.465916633605957 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2656/3000 [16:40<02:06, 2.72it/s]ours... +token_confidence 14.78012466430664 15.418718338012695 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2657/3000 [16:40<02:04, 2.75it/s]ours... +token_confidence 15.51748275756836 15.934206008911133 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000283168.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2658/3000 [16:41<02:04, 2.75it/s]ours... +token_confidence 12.39280891418457 11.412595748901367 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2659/3000 [16:41<02:13, 2.55it/s]ours... +token_confidence 15.56553840637207 11.744608879089355 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2660/3000 [16:41<02:17, 2.47it/s]ours... +token_confidence 13.92270565032959 11.0023193359375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2661/3000 [16:42<02:26, 2.31it/s]ours... +token_confidence 13.807327270507812 12.095666885375977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▊ | 2662/3000 [16:42<02:18, 2.44it/s]ours... +token_confidence 15.71603775024414 14.570455551147461 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a bus in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2663/3000 [16:43<02:16, 2.48it/s]ours... +token_confidence 13.973983764648438 11.061643600463867 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000405205.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2664/3000 [16:43<02:11, 2.56it/s]ours... +token_confidence 15.003170013427734 14.599529266357422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2665/3000 [16:43<02:09, 2.58it/s]ours... +token_confidence 14.74234390258789 14.11686897277832 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2666/3000 [16:44<02:08, 2.60it/s]ours... +token_confidence 12.83342170715332 12.770668983459473 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2667/3000 [16:44<02:11, 2.53it/s]ours... +token_confidence 15.484586715698242 14.178182601928711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2668/3000 [16:45<02:11, 2.52it/s]ours... +token_confidence 15.601787567138672 13.867647171020508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there an umbrella in the imange?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2669/3000 [16:45<02:09, 2.56it/s]ours... +token_confidence 14.315656661987305 13.191816329956055 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000123570.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2670/3000 [16:45<02:13, 2.47it/s]ours... +token_confidence 16.06649398803711 16.02923583984375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2671/3000 [16:46<02:12, 2.49it/s]ours... +token_confidence 15.621057510375977 14.999025344848633 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2672/3000 [16:46<02:08, 2.55it/s]ours... +token_confidence 13.645299911499023 13.988800048828125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2673/3000 [16:47<02:09, 2.52it/s]ours... +token_confidence 15.750310897827148 16.41579818725586 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2674/3000 [16:47<02:12, 2.47it/s]ours... +token_confidence 15.154045104980469 14.662727355957031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2675/3000 [16:47<02:08, 2.54it/s]ours... +token_confidence 15.278373718261719 14.499848365783691 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000365317.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2676/3000 [16:48<02:03, 2.63it/s]ours... +token_confidence 16.031532287597656 15.755902290344238 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2677/3000 [16:48<02:02, 2.63it/s]ours... +token_confidence 15.69644546508789 14.234752655029297 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2678/3000 [16:48<02:00, 2.68it/s]ours... +token_confidence 12.238450050354004 10.609886169433594 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a toilet in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2679/3000 [16:49<02:00, 2.66it/s]ours... +token_confidence 15.137031555175781 15.239343643188477 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2680/3000 [16:49<02:04, 2.58it/s]ours... +token_confidence 12.165489196777344 10.615213394165039 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2681/3000 [16:50<02:01, 2.64it/s]ours... +token_confidence 15.611373901367188 15.107939720153809 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000224155.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2682/3000 [16:50<02:00, 2.65it/s]ours... +token_confidence 15.929214477539062 15.394519805908203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there a keyboard in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2683/3000 [16:50<02:01, 2.61it/s]ours... +token_confidence 15.2950439453125 16.268543243408203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 89%|████████▉ | 2684/3000 [16:51<02:00, 2.63it/s]ours... +token_confidence 14.935911178588867 15.159156799316406 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2685/3000 [16:51<01:56, 2.69it/s]ours... +token_confidence 14.721860885620117 12.971598625183105 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2686/3000 [16:51<01:54, 2.73it/s]ours... +token_confidence 16.064762115478516 14.401851654052734 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2687/3000 [16:52<01:55, 2.71it/s]ours... +token_confidence 15.311735153198242 15.141016006469727 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000191964.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2688/3000 [16:52<01:54, 2.72it/s]ours... +token_confidence 16.413665771484375 14.182106971740723 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there a banana in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2689/3000 [16:53<01:54, 2.72it/s]ours... +token_confidence 15.689712524414062 15.02493953704834 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2690/3000 [16:53<01:59, 2.59it/s]ours... +token_confidence 12.7142333984375 11.133277893066406 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2691/3000 [16:53<01:58, 2.61it/s]ours... +token_confidence 12.085797309875488 9.64483642578125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2692/3000 [16:54<01:58, 2.60it/s]ours... +token_confidence 14.662389755249023 12.394990921020508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there an orange in the imange?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2693/3000 [16:54<01:57, 2.61it/s]ours... +token_confidence 15.79429817199707 14.564404487609863 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000265472.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2694/3000 [16:55<01:56, 2.63it/s]ours... +token_confidence 13.135506629943848 13.674177169799805 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a snowboard in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2695/3000 [16:55<01:54, 2.66it/s]ours... +token_confidence 16.652305603027344 16.809280395507812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2696/3000 [16:55<01:52, 2.71it/s]ours... +token_confidence 12.371569633483887 16.23302459716797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2697/3000 [16:56<01:50, 2.73it/s]ours... +token_confidence 15.648691177368164 18.712486267089844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2698/3000 [16:56<01:50, 2.74it/s]ours... +token_confidence 17.170995712280273 16.649444580078125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|████████▉ | 2699/3000 [16:57<02:06, 2.38it/s]ours... +token_confidence 17.058822631835938 17.22918701171875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000550514.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2700/3000 [16:57<02:08, 2.33it/s]ours... +token_confidence 16.38094139099121 15.872468948364258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2701/3000 [16:57<02:00, 2.47it/s]ours... +token_confidence 16.661800384521484 15.637441635131836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2702/3000 [16:58<01:55, 2.57it/s]ours... +token_confidence 15.441038131713867 18.393943786621094 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a motorcycle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2703/3000 [16:58<01:55, 2.57it/s]ours... +token_confidence 15.581413269042969 17.02930450439453 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2704/3000 [16:58<01:54, 2.60it/s]ours... +token_confidence 14.246667861938477 16.930038452148438 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a skateboard in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2705/3000 [16:59<01:51, 2.64it/s]ours... +token_confidence 16.377925872802734 16.679279327392578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000163814.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2706/3000 [16:59<01:49, 2.69it/s]ours... +token_confidence 13.75771713256836 12.220541000366211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2707/3000 [17:00<01:50, 2.65it/s]ours... +token_confidence 12.987736701965332 13.140304565429688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2708/3000 [17:00<01:51, 2.63it/s]ours... +token_confidence 15.480758666992188 14.882207870483398 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2709/3000 [17:00<01:50, 2.63it/s]ours... +token_confidence 16.298526763916016 14.318841934204102 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2710/3000 [17:01<01:52, 2.58it/s]ours... +token_confidence 14.13290786743164 14.398820877075195 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2711/3000 [17:01<01:51, 2.59it/s]ours... +token_confidence 15.998889923095703 13.744826316833496 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000505933.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2712/3000 [17:01<01:49, 2.64it/s]ours... +token_confidence 13.647344589233398 11.885974884033203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a traffic light in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2713/3000 [17:02<01:45, 2.72it/s]ours... +token_confidence 14.837175369262695 15.469148635864258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2714/3000 [17:02<01:46, 2.68it/s]ours... +token_confidence 12.951955795288086 12.992851257324219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] + No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 90%|█████████ | 2715/3000 [17:03<01:50, 2.57it/s]ours... +token_confidence 16.387598037719727 14.263287544250488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2716/3000 [17:03<01:46, 2.66it/s]ours... +token_confidence 15.030107498168945 15.168034553527832 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a train in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2717/3000 [17:03<01:47, 2.64it/s]ours... +token_confidence 16.197179794311523 16.513124465942383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000318550.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2718/3000 [17:04<01:44, 2.69it/s]ours... +token_confidence 14.705284118652344 14.933954238891602 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2719/3000 [17:04<01:43, 2.72it/s]ours... +token_confidence 14.215324401855469 13.346237182617188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2720/3000 [17:04<01:46, 2.63it/s]ours... +token_confidence 15.844018936157227 16.528850555419922 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2721/3000 [17:05<01:43, 2.69it/s]ours... +token_confidence 12.048248291015625 12.313394546508789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2722/3000 [17:05<01:43, 2.68it/s]ours... +token_confidence 12.110454559326172 12.239887237548828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2723/3000 [17:06<01:42, 2.69it/s]ours... +token_confidence 13.57931137084961 16.092241287231445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000367528.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2724/3000 [17:06<01:42, 2.70it/s]ours... +token_confidence 15.992012023925781 15.860612869262695 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2725/3000 [17:06<01:41, 2.70it/s]ours... +token_confidence 15.825864791870117 14.697372436523438 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2726/3000 [17:07<01:54, 2.40it/s]ours... +token_confidence 15.29498291015625 15.729904174804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2727/3000 [17:07<01:50, 2.48it/s]ours... +token_confidence 15.196319580078125 16.01811408996582 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2728/3000 [17:08<01:46, 2.55it/s]ours... +token_confidence 15.538871765136719 15.586285591125488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a boat in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2729/3000 [17:08<01:44, 2.60it/s]ours... +token_confidence 15.53785514831543 15.64732551574707 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000252911.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2730/3000 [17:08<01:47, 2.51it/s]ours... +token_confidence 14.242424011230469 13.629705429077148 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2731/3000 [17:09<01:44, 2.57it/s]ours... +token_confidence 15.521539688110352 15.59901237487793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2732/3000 [17:09<01:41, 2.63it/s]ours... +token_confidence 16.87135887145996 15.706315994262695 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2733/3000 [17:09<01:39, 2.69it/s]ours... +token_confidence 15.171167373657227 14.573793411254883 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2734/3000 [17:10<01:37, 2.73it/s]ours... +token_confidence 13.537984848022461 12.815352439880371 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2735/3000 [17:10<01:38, 2.70it/s]ours... +token_confidence 15.312000274658203 14.574300765991211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000214421.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2736/3000 [17:11<01:36, 2.73it/s]ours... +token_confidence 13.083873748779297 12.465042114257812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████ | 2737/3000 [17:11<01:37, 2.71it/s]ours... +token_confidence 17.24624252319336 14.5382719039917 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2738/3000 [17:11<01:35, 2.74it/s]ours... +token_confidence 16.083354949951172 15.221174240112305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2739/3000 [17:12<01:36, 2.70it/s]ours... +token_confidence 16.197303771972656 16.907167434692383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2740/3000 [17:12<01:41, 2.55it/s]ours... +token_confidence 13.544330596923828 12.387659072875977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2741/3000 [17:12<01:38, 2.63it/s]ours... +token_confidence 16.872074127197266 16.27415657043457 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000050627.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2742/3000 [17:13<01:37, 2.64it/s]ours... +token_confidence 14.481002807617188 16.112030029296875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2743/3000 [17:13<01:34, 2.72it/s]ours... +token_confidence 15.310724258422852 14.816671371459961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 91%|█████████▏| 2744/3000 [17:14<01:33, 2.75it/s]ours... +token_confidence 12.721746444702148 13.268823623657227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2745/3000 [17:14<01:33, 2.72it/s]ours... +token_confidence 14.576656341552734 14.657979965209961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2746/3000 [17:14<01:32, 2.75it/s]ours... +token_confidence 11.821571350097656 10.510831832885742 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2747/3000 [17:15<01:36, 2.62it/s]ours... +token_confidence 12.207633972167969 11.629068374633789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000233426.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2748/3000 [17:15<01:33, 2.71it/s]ours... +token_confidence 17.325267791748047 15.088949203491211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2749/3000 [17:15<01:33, 2.69it/s]ours... +token_confidence 16.011701583862305 15.420426368713379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2750/3000 [17:16<01:35, 2.61it/s]ours... +token_confidence 14.636474609375 14.825868606567383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2751/3000 [17:16<01:33, 2.65it/s]ours... +token_confidence 16.003902435302734 15.593954086303711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2752/3000 [17:17<01:41, 2.43it/s]ours... +token_confidence 15.140558242797852 16.32131576538086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2753/3000 [17:17<01:39, 2.49it/s]ours... +token_confidence 14.364252090454102 12.847223281860352 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000372817.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2754/3000 [17:17<01:35, 2.58it/s]ours... +token_confidence 15.174251556396484 14.41487979888916 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2755/3000 [17:18<01:34, 2.58it/s]ours... +token_confidence 15.848590850830078 17.922876358032227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2756/3000 [17:18<01:31, 2.66it/s]ours... +token_confidence 15.93670654296875 17.37726593017578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2757/3000 [17:18<01:29, 2.70it/s]ours... +token_confidence 14.86981201171875 11.736557006835938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2758/3000 [17:19<01:28, 2.74it/s]ours... +token_confidence 13.605107307434082 13.446796417236328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2759/3000 [17:19<01:27, 2.76it/s]ours... +token_confidence 16.284460067749023 15.139389038085938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000536073.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2760/3000 [17:20<01:29, 2.67it/s]ours... +token_confidence 13.591409683227539 11.902801513671875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2761/3000 [17:20<01:31, 2.62it/s]ours... +token_confidence 15.78936767578125 14.201725959777832 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2762/3000 [17:20<01:29, 2.67it/s]ours... +token_confidence 16.993497848510742 15.457117080688477 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2763/3000 [17:21<01:29, 2.66it/s]ours... +token_confidence 15.293987274169922 15.25715446472168 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2764/3000 [17:21<01:28, 2.66it/s]ours... +token_confidence 14.743677139282227 13.493501663208008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a baseball bat in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2765/3000 [17:21<01:26, 2.73it/s]ours... +token_confidence 15.931825637817383 15.147811889648438 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000579231.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2766/3000 [17:22<01:24, 2.76it/s]ours... +token_confidence 16.453386306762695 15.060837745666504 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a giraffe in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2767/3000 [17:22<01:24, 2.77it/s]ours... +token_confidence 15.57232666015625 15.274435043334961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2768/3000 [17:23<01:25, 2.71it/s]ours... +token_confidence 13.495708465576172 12.839717864990234 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2769/3000 [17:23<01:29, 2.59it/s]ours... +token_confidence 16.19322395324707 14.899726867675781 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2770/3000 [17:23<01:30, 2.54it/s]ours... +token_confidence 15.800819396972656 14.846395492553711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a zebra in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2771/3000 [17:24<01:28, 2.59it/s]ours... +token_confidence 15.605010986328125 16.689666748046875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000092624.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2772/3000 [17:24<01:25, 2.66it/s]ours... +token_confidence 13.456871032714844 11.839336395263672 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2773/3000 [17:24<01:23, 2.71it/s]ours... +token_confidence 15.637981414794922 16.828903198242188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▏| 2774/3000 [17:25<01:22, 2.74it/s]ours... +token_confidence 11.91813850402832 9.888492584228516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 92%|█████████▎| 2775/3000 [17:25<01:21, 2.77it/s]ours... +token_confidence 15.188699722290039 13.72260856628418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2776/3000 [17:26<01:20, 2.79it/s]ours... +token_confidence 15.670330047607422 14.517780303955078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2777/3000 [17:26<01:22, 2.72it/s]ours... +token_confidence 13.129251480102539 12.08598518371582 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000390184.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2778/3000 [17:26<01:23, 2.67it/s]ours... +token_confidence 16.31955337524414 15.78324031829834 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2779/3000 [17:27<01:24, 2.62it/s]ours... +token_confidence 15.124879837036133 12.015119552612305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2780/3000 [17:27<01:27, 2.53it/s]ours... +token_confidence 12.27685546875 10.389726638793945 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2781/3000 [17:27<01:23, 2.63it/s]ours... +token_confidence 17.040271759033203 15.124420166015625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2782/3000 [17:28<01:21, 2.69it/s]ours... +token_confidence 14.26854133605957 13.22358512878418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2783/3000 [17:28<01:19, 2.73it/s]ours... +token_confidence 12.7366304397583 10.630435943603516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000079213.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2784/3000 [17:29<01:18, 2.77it/s]ours... +token_confidence 13.606216430664062 13.50702953338623 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2785/3000 [17:29<01:17, 2.77it/s]ours... +token_confidence 15.75493049621582 17.881084442138672 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2786/3000 [17:29<01:16, 2.81it/s]ours... +token_confidence 12.67002010345459 16.18682861328125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2787/3000 [17:30<01:15, 2.83it/s]ours... +token_confidence 17.75634002685547 17.154861450195312 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2788/3000 [17:30<01:14, 2.84it/s]ours... +token_confidence 12.284740447998047 13.264286041259766 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2789/3000 [17:30<01:13, 2.86it/s]ours... +token_confidence 16.57794952392578 15.681110382080078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000465346.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2790/3000 [17:31<01:17, 2.72it/s]ours... +token_confidence 12.765362739562988 14.41952133178711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2791/3000 [17:31<01:15, 2.78it/s]ours... +token_confidence 16.614269256591797 14.104899406433105 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2792/3000 [17:31<01:14, 2.77it/s]ours... +token_confidence 12.618349075317383 15.434926986694336 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2793/3000 [17:32<01:17, 2.67it/s]ours... +token_confidence 17.28272819519043 15.083658218383789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2794/3000 [17:32<01:18, 2.64it/s]ours... +token_confidence 13.199909210205078 14.126895904541016 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a horse in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2795/3000 [17:33<01:21, 2.51it/s]ours... +token_confidence 15.131181716918945 12.313817977905273 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000514248.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2796/3000 [17:33<01:19, 2.56it/s]ours... +token_confidence 15.729972839355469 16.43505859375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2797/3000 [17:33<01:17, 2.61it/s]ours... +token_confidence 16.36800765991211 16.554988861083984 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2798/3000 [17:34<01:15, 2.66it/s]ours... +token_confidence 16.3364315032959 17.122943878173828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2799/3000 [17:34<01:14, 2.70it/s]ours... +token_confidence 15.978445053100586 16.803024291992188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2800/3000 [17:34<01:15, 2.63it/s]ours... +token_confidence 12.741765022277832 13.229241371154785 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a sink in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2801/3000 [17:35<01:12, 2.74it/s]ours... +token_confidence 12.117425918579102 14.542166709899902 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000355776.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2802/3000 [17:35<01:10, 2.79it/s]ours... +token_confidence 12.283219337463379 11.163111686706543 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2803/3000 [17:36<01:12, 2.72it/s]ours... +token_confidence 14.995990753173828 14.682619094848633 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 93%|█████████▎| 2804/3000 [17:36<01:10, 2.77it/s]ours... +token_confidence 13.149099349975586 12.35786247253418 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a bench in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2805/3000 [17:36<01:10, 2.79it/s]ours... +token_confidence 15.51323127746582 14.018377304077148 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2806/3000 [17:37<01:11, 2.71it/s]ours... +token_confidence 13.386346817016602 12.537517547607422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2807/3000 [17:37<01:11, 2.70it/s]ours... +token_confidence 12.764318466186523 11.914220809936523 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000575355.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2808/3000 [17:37<01:10, 2.72it/s]ours... +token_confidence 12.345309257507324 13.651040077209473 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2809/3000 [17:38<01:09, 2.74it/s]ours... +token_confidence 13.685803413391113 13.853157043457031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2810/3000 [17:38<01:12, 2.62it/s]ours... +token_confidence 16.253067016601562 16.52997589111328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2811/3000 [17:39<01:15, 2.49it/s]ours... +token_confidence 15.332502365112305 16.146690368652344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▎| 2812/3000 [17:39<01:13, 2.58it/s]ours... +token_confidence 14.977706909179688 14.922130584716797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2813/3000 [17:39<01:12, 2.58it/s]ours... +token_confidence 13.712151527404785 12.914400100708008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000396068.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2814/3000 [17:40<01:12, 2.55it/s]ours... +token_confidence 12.239782333374023 9.280705451965332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2815/3000 [17:40<01:12, 2.56it/s]ours... +token_confidence 14.674808502197266 11.526883125305176 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2816/3000 [17:40<01:09, 2.65it/s]ours... +token_confidence 15.595603942871094 13.090383529663086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2817/3000 [17:41<01:09, 2.65it/s]ours... +token_confidence 14.953226089477539 11.839759826660156 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2818/3000 [17:41<01:07, 2.70it/s]ours... +token_confidence 13.8535737991333 10.836265563964844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2819/3000 [17:42<01:07, 2.69it/s]ours... +token_confidence 13.117088317871094 9.681234359741211 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000559547.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2820/3000 [17:42<01:11, 2.53it/s]ours... +token_confidence 17.70694351196289 15.478782653808594 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2821/3000 [17:42<01:10, 2.56it/s]ours... +token_confidence 14.855438232421875 13.630481719970703 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2822/3000 [17:43<01:08, 2.58it/s]ours... +token_confidence 12.604619026184082 10.541141510009766 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2823/3000 [17:43<01:09, 2.53it/s]ours... +token_confidence 15.155769348144531 15.065201759338379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2824/3000 [17:44<01:07, 2.59it/s]ours... +token_confidence 15.970321655273438 14.599452018737793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2825/3000 [17:44<01:08, 2.55it/s]ours... +token_confidence 12.182002067565918 12.05175495147705 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000230175.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2826/3000 [17:44<01:06, 2.62it/s]ours... +token_confidence 15.771812438964844 15.05557918548584 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2827/3000 [17:45<01:05, 2.66it/s]ours... +token_confidence 15.808612823486328 15.016427993774414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2828/3000 [17:45<01:04, 2.69it/s]ours... +token_confidence 16.098630905151367 15.226439476013184 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2829/3000 [17:45<01:04, 2.67it/s]ours... +token_confidence 15.91607666015625 16.92922592163086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2830/3000 [17:46<01:06, 2.57it/s]ours... +token_confidence 15.296045303344727 15.061288833618164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a skis in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2831/3000 [17:46<01:03, 2.67it/s]ours... +token_confidence 15.346101760864258 14.638544082641602 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000159969.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2832/3000 [17:47<01:03, 2.64it/s]ours... +token_confidence 12.431219100952148 12.043529510498047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2833/3000 [17:47<01:02, 2.68it/s]ours... +token_confidence 15.026824951171875 16.619701385498047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2834/3000 [17:47<01:01, 2.71it/s]ours... +token_confidence 12.997920036315918 16.450607299804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a sandwich in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 94%|█████████▍| 2835/3000 [17:48<01:00, 2.74it/s]ours... +token_confidence 16.72187042236328 15.302582740783691 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2836/3000 [17:48<00:59, 2.76it/s]ours... +token_confidence 13.496132850646973 15.949075698852539 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2837/3000 [17:48<00:58, 2.78it/s]ours... +token_confidence 15.705968856811523 14.783227920532227 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000399702.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2838/3000 [17:49<00:59, 2.75it/s]ours... +token_confidence 12.34790325164795 10.51291275024414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2839/3000 [17:49<00:58, 2.77it/s]ours... +token_confidence 15.718202590942383 11.890958786010742 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2840/3000 [17:50<01:01, 2.62it/s]ours... +token_confidence 16.52416229248047 13.66783332824707 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2841/3000 [17:50<01:00, 2.62it/s]ours... +token_confidence 14.505929946899414 11.578596115112305 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2842/3000 [17:50<00:59, 2.65it/s]ours... +token_confidence 12.470712661743164 8.672359466552734 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2843/3000 [17:51<01:00, 2.59it/s]ours... +token_confidence 12.478721618652344 9.429229736328125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000555538.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2844/3000 [17:51<01:00, 2.58it/s]ours... +token_confidence 15.122421264648438 15.464024543762207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2845/3000 [17:51<01:00, 2.56it/s]ours... +token_confidence 16.314876556396484 14.14521598815918 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2846/3000 [17:52<00:59, 2.57it/s]ours... +token_confidence 15.533660888671875 16.74334716796875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2847/3000 [17:52<00:58, 2.63it/s]ours... +token_confidence 12.334237098693848 13.390063285827637 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2848/3000 [17:53<00:58, 2.60it/s]ours... +token_confidence 12.959967613220215 13.844331741333008 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▍| 2849/3000 [17:53<00:56, 2.67it/s]ours... +token_confidence 17.078157424926758 15.376585006713867 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000264155.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2850/3000 [17:53<00:58, 2.58it/s]ours... +token_confidence 14.308244705200195 14.72059440612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2851/3000 [17:54<00:55, 2.67it/s]ours... +token_confidence 15.908126831054688 16.676692962646484 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2852/3000 [17:54<00:54, 2.71it/s]ours... +token_confidence 14.59524154663086 16.536577224731445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a clock in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2853/3000 [17:54<00:54, 2.69it/s]ours... +token_confidence 14.44693374633789 14.839578628540039 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2854/3000 [17:55<00:53, 2.72it/s]ours... +token_confidence 16.483417510986328 15.19800090789795 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2855/3000 [17:55<00:53, 2.69it/s]ours... +token_confidence 15.793642044067383 16.118125915527344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000125572.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2856/3000 [17:56<00:52, 2.73it/s]ours... +token_confidence 17.24995994567871 14.9439697265625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2857/3000 [17:56<00:52, 2.70it/s]ours... +token_confidence 15.632209777832031 15.115020751953125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2858/3000 [17:56<00:52, 2.69it/s]ours... +token_confidence 13.132760047912598 12.95496940612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2859/3000 [17:57<00:59, 2.36it/s]ours... +token_confidence 15.164117813110352 14.176642417907715 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2860/3000 [17:57<00:59, 2.33it/s]ours... +token_confidence 13.565119743347168 13.915395736694336 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2861/3000 [17:58<00:57, 2.42it/s]ours... +token_confidence 14.506990432739258 13.547088623046875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000560744.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2862/3000 [17:58<00:56, 2.46it/s]ours... +token_confidence 16.0394287109375 15.438894271850586 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2863/3000 [17:58<00:54, 2.53it/s]ours... +token_confidence 14.819707870483398 13.928895950317383 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 95%|█████████▌| 2864/3000 [17:59<00:51, 2.63it/s]ours... +token_confidence 13.002264022827148 13.536382675170898 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2865/3000 [17:59<00:51, 2.64it/s]ours... +token_confidence 14.834649085998535 13.824280738830566 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2866/3000 [18:00<00:49, 2.70it/s]ours... +token_confidence 12.05146598815918 13.035828590393066 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2867/3000 [18:00<00:49, 2.71it/s]ours... +token_confidence 14.29629135131836 13.299593925476074 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000045685.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2868/3000 [18:00<00:48, 2.74it/s]ours... +token_confidence 13.031436920166016 15.473824501037598 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2869/3000 [18:01<00:47, 2.78it/s]ours... +token_confidence 15.660152435302734 18.11481475830078 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2870/3000 [18:01<00:49, 2.65it/s]ours... +token_confidence 15.760446548461914 15.965296745300293 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2871/3000 [18:01<00:47, 2.73it/s]ours... +token_confidence 15.44969367980957 16.06676483154297 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2872/3000 [18:02<00:46, 2.75it/s]ours... +token_confidence 14.423019409179688 17.168079376220703 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2873/3000 [18:02<00:45, 2.78it/s]ours... +token_confidence 17.151268005371094 18.101417541503906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000434179.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2874/3000 [18:02<00:45, 2.78it/s]ours... +token_confidence 15.69202995300293 16.419940948486328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2875/3000 [18:03<00:45, 2.74it/s]ours... +token_confidence 15.971855163574219 16.413341522216797 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2876/3000 [18:03<00:44, 2.76it/s]ours... +token_confidence 12.235248565673828 13.651222229003906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] + +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2877/3000 [18:04<00:46, 2.67it/s]ours... +token_confidence 15.601051330566406 14.903434753417969 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2878/3000 [18:04<00:44, 2.71it/s]ours... +token_confidence 15.966558456420898 14.564645767211914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2879/3000 [18:04<00:44, 2.74it/s]ours... +token_confidence 15.518115997314453 15.863834381103516 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000008749.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2880/3000 [18:05<00:46, 2.58it/s]ours... +token_confidence 15.099685668945312 14.488922119140625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2881/3000 [18:05<00:44, 2.65it/s]ours... +token_confidence 15.49458122253418 15.54854965209961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2882/3000 [18:05<00:44, 2.66it/s]ours... +token_confidence 13.093046188354492 14.095588684082031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2883/3000 [18:06<00:44, 2.66it/s]ours... +token_confidence 13.31644058227539 11.29574966430664 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2884/3000 [18:06<00:43, 2.69it/s]ours... +token_confidence 13.78424072265625 13.314617156982422 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2885/3000 [18:07<00:43, 2.66it/s]ours... +token_confidence 13.453228950500488 12.462068557739258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000069863.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2886/3000 [18:07<00:41, 2.71it/s]ours... +token_confidence 12.064128875732422 12.846120834350586 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a backpack in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▌| 2887/3000 [18:07<00:41, 2.71it/s]ours... +token_confidence 16.250925064086914 14.558724403381348 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2888/3000 [18:08<00:40, 2.74it/s]ours... +token_confidence 15.45772933959961 15.302740097045898 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2889/3000 [18:08<00:40, 2.76it/s]ours... +token_confidence 15.372425079345703 16.16036033630371 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2890/3000 [18:08<00:42, 2.58it/s]ours... +token_confidence 15.302928924560547 14.47450065612793 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a cow in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2891/3000 [18:09<00:41, 2.60it/s]ours... +token_confidence 16.043272018432617 15.59259033203125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000041180.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2892/3000 [18:09<00:40, 2.69it/s]ours... +token_confidence 12.320391654968262 12.7440185546875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2893/3000 [18:10<00:39, 2.73it/s]ours... +token_confidence 15.560794830322266 13.22658920288086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2894/3000 [18:10<00:38, 2.77it/s]ours... +token_confidence 16.858182907104492 15.351642608642578 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 96%|█████████▋| 2895/3000 [18:10<00:38, 2.73it/s]ours... +token_confidence 15.34177017211914 15.048395156860352 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2896/3000 [18:11<00:37, 2.76it/s]ours... +token_confidence 12.151689529418945 11.264841079711914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2897/3000 [18:11<00:36, 2.79it/s]ours... +token_confidence 15.576156616210938 15.245094299316406 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000429913.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2898/3000 [18:11<00:36, 2.80it/s]ours... +token_confidence 14.813830375671387 15.173911094665527 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2899/3000 [18:12<00:36, 2.73it/s]ours... +token_confidence 12.792268753051758 13.201255798339844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2900/3000 [18:12<00:38, 2.57it/s]ours... +token_confidence 16.821290969848633 14.513077735900879 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a dog in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2901/3000 [18:13<00:38, 2.57it/s]ours... +token_confidence 15.579504013061523 15.700133323669434 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2902/3000 [18:13<00:37, 2.62it/s]ours... +token_confidence 14.45612907409668 14.479864120483398 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2903/3000 [18:13<00:36, 2.63it/s]ours... +token_confidence 15.251310348510742 14.891456604003906 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000554002.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2904/3000 [18:14<00:35, 2.69it/s]ours... +token_confidence 12.984794616699219 12.096078872680664 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2905/3000 [18:14<00:34, 2.74it/s]ours... +token_confidence 15.771379470825195 17.677631378173828 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2906/3000 [18:14<00:34, 2.76it/s]ours... +token_confidence 12.163898468017578 11.323527336120605 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a mouse in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2907/3000 [18:15<00:33, 2.74it/s]ours... +token_confidence 16.515636444091797 15.210372924804688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2908/3000 [18:15<00:33, 2.77it/s]ours... +token_confidence 15.564271926879883 14.350801467895508 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2909/3000 [18:15<00:33, 2.70it/s]ours... +token_confidence 15.26392650604248 13.656306266784668 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000141278.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2910/3000 [18:16<00:35, 2.54it/s]ours... +token_confidence 12.131585121154785 14.109987258911133 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2911/3000 [18:16<00:34, 2.58it/s]ours... +token_confidence 16.48777198791504 16.808856964111328 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2912/3000 [18:17<00:33, 2.62it/s]ours... +token_confidence 14.919475555419922 14.921646118164062 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2913/3000 [18:17<00:33, 2.62it/s]ours... +token_confidence 11.788609504699707 12.877374649047852 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2914/3000 [18:17<00:32, 2.67it/s]ours... +token_confidence 12.953896522521973 14.106937408447266 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a knife in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2915/3000 [18:18<00:31, 2.72it/s]ours... +token_confidence 15.460060119628906 17.7117919921875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000190788.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2916/3000 [18:18<00:30, 2.75it/s]ours... +token_confidence 11.968819618225098 10.232215881347656 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a bed in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2917/3000 [18:18<00:29, 2.78it/s]ours... +token_confidence 13.017515182495117 9.947013854980469 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2918/3000 [18:19<00:29, 2.74it/s]ours... +token_confidence 16.43393325805664 13.80075454711914 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a cat in the image?Please answer yes or no.'}] +yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2919/3000 [18:19<00:29, 2.72it/s]ours... +token_confidence 14.295673370361328 11.768582344055176 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2920/3000 [18:20<00:30, 2.62it/s]ours... +token_confidence 12.89589786529541 12.988277435302734 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a tie in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2921/3000 [18:20<00:29, 2.66it/s]ours... +token_confidence 15.532316207885742 15.200489044189453 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000534942.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2922/3000 [18:20<00:28, 2.70it/s]ours... +token_confidence 15.774513244628906 15.326964378356934 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2923/3000 [18:21<00:29, 2.64it/s]ours... +token_confidence 15.169139862060547 16.18675994873047 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] + +No + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 97%|█████████▋| 2924/3000 [18:21<00:29, 2.59it/s]ours... +token_confidence 15.134042739868164 14.881011962890625 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2925/3000 [18:21<00:28, 2.60it/s]ours... +token_confidence 13.74690055847168 12.868728637695312 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2926/3000 [18:22<00:28, 2.62it/s]ours... +token_confidence 12.663017272949219 14.317346572875977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] + +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2927/3000 [18:22<00:28, 2.58it/s]ours... +token_confidence 13.843515396118164 15.274571418762207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000377951.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2928/3000 [18:23<00:27, 2.65it/s]ours... +token_confidence 13.94366455078125 14.65946102142334 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a truck in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2929/3000 [18:23<00:26, 2.67it/s]ours... +token_confidence 16.845069885253906 14.513847351074219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2930/3000 [18:23<00:27, 2.52it/s]ours... +token_confidence 12.430644989013672 15.448990821838379 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2931/3000 [18:24<00:28, 2.46it/s]ours... +token_confidence 12.295373916625977 12.1190185546875 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] + no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2932/3000 [18:24<00:26, 2.56it/s]ours... +token_confidence 15.411407470703125 15.01962661743164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there an airplane in the imange?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2933/3000 [18:25<00:25, 2.59it/s]ours... +token_confidence 15.688034057617188 15.32177448272705 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000533201.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2934/3000 [18:25<00:25, 2.63it/s]ours... +token_confidence 14.707706451416016 14.776290893554688 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2935/3000 [18:25<00:25, 2.59it/s]ours... +token_confidence 15.700263977050781 14.818093299865723 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2936/3000 [18:26<00:24, 2.66it/s]ours... +token_confidence 12.130331993103027 12.297551155090332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2937/3000 [18:26<00:24, 2.60it/s]ours... +token_confidence 13.463072776794434 11.724565505981445 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2938/3000 [18:26<00:23, 2.60it/s]ours... +token_confidence 12.524802207946777 13.104962348937988 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a remote in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2939/3000 [18:27<00:24, 2.49it/s]ours... +token_confidence 12.863550186157227 11.673877716064453 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000235203.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2940/3000 [18:27<00:24, 2.42it/s]ours... +token_confidence 12.4320068359375 13.029433250427246 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a baseball glove in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2941/3000 [18:28<00:23, 2.53it/s]ours... +token_confidence 15.441240310668945 14.029318809509277 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2942/3000 [18:28<00:22, 2.56it/s]ours... +token_confidence 16.192731857299805 14.584410667419434 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2943/3000 [18:28<00:21, 2.61it/s]ours... +token_confidence 14.841495513916016 15.40988540649414 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2944/3000 [18:29<00:21, 2.64it/s]ours... +token_confidence 12.241999626159668 12.089678764343262 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2945/3000 [18:29<00:20, 2.72it/s]ours... +token_confidence 12.518064498901367 12.177897453308105 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000468997.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2946/3000 [18:30<00:20, 2.68it/s]ours... +token_confidence 15.955259323120117 15.428451538085938 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2947/3000 [18:30<00:19, 2.70it/s]ours... +token_confidence 14.976583480834961 13.881301879882812 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2948/3000 [18:30<00:18, 2.74it/s]ours... +token_confidence 16.354646682739258 14.300439834594727 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a potted plant in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2949/3000 [18:31<00:18, 2.72it/s]ours... +token_confidence 15.270418167114258 15.130461692810059 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2950/3000 [18:31<00:19, 2.62it/s]ours... +token_confidence 12.688458442687988 12.311226844787598 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a vase in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2951/3000 [18:31<00:18, 2.65it/s]ours... +token_confidence 15.531564712524414 14.41840648651123 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000401398.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2952/3000 [18:32<00:18, 2.64it/s]ours... +token_confidence 15.971872329711914 15.735848426818848 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2953/3000 [18:32<00:17, 2.63it/s]ours... +token_confidence 15.693361282348633 14.993910789489746 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2954/3000 [18:33<00:18, 2.53it/s]ours... +token_confidence 11.847887992858887 10.677001953125 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 98%|█████████▊| 2955/3000 [18:33<00:17, 2.59it/s]ours... +token_confidence 15.259910583496094 15.371190071105957 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2956/3000 [18:33<00:16, 2.62it/s]ours... +token_confidence 14.762300491333008 14.649131774902344 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2957/3000 [18:34<00:16, 2.62it/s]ours... +token_confidence 15.488975524902344 14.77102279663086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000323752.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2958/3000 [18:34<00:15, 2.69it/s]ours... +token_confidence 11.827298164367676 9.394031524658203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2959/3000 [18:34<00:15, 2.70it/s]ours... +token_confidence 15.76671028137207 15.238225936889648 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2960/3000 [18:35<00:15, 2.62it/s]ours... +token_confidence 15.924419403076172 13.908456802368164 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2961/3000 [18:35<00:14, 2.66it/s]ours... +token_confidence 15.772602081298828 13.752092361450195 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▊| 2962/3000 [18:36<00:14, 2.70it/s]ours... +token_confidence 13.5653076171875 13.96495246887207 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a fork in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2963/3000 [18:36<00:13, 2.73it/s]ours... +token_confidence 12.09259033203125 12.260025024414062 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000003845.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2964/3000 [18:36<00:13, 2.73it/s]ours... +token_confidence 16.107776641845703 14.947851181030273 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a pizza in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2965/3000 [18:37<00:13, 2.56it/s]ours... +token_confidence 15.631926536560059 14.583686828613281 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2966/3000 [18:37<00:13, 2.58it/s]ours... +token_confidence 17.043785095214844 14.677785873413086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2967/3000 [18:38<00:12, 2.60it/s]ours... +token_confidence 15.33786392211914 14.302164077758789 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] + +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2968/3000 [18:38<00:12, 2.57it/s]ours... +token_confidence 12.483122825622559 12.324162483215332 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a cell phone in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2969/3000 [18:38<00:11, 2.59it/s]ours... +token_confidence 14.433391571044922 13.952796936035156 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000122962.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2970/3000 [18:39<00:12, 2.47it/s]ours... +token_confidence 16.882953643798828 15.140613555908203 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2971/3000 [18:39<00:11, 2.57it/s]ours... +token_confidence 15.726882934570312 13.082565307617188 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2972/3000 [18:39<00:10, 2.58it/s]ours... +token_confidence 14.795921325683594 13.289857864379883 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a sports ball in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2973/3000 [18:40<00:10, 2.63it/s]ours... +token_confidence 15.143640518188477 14.62070369720459 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2974/3000 [18:40<00:09, 2.68it/s]ours... +token_confidence 14.544023513793945 14.49643611907959 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a tennis racket in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2975/3000 [18:41<00:09, 2.67it/s]ours... +token_confidence 13.911133766174316 11.553352355957031 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000015738.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2976/3000 [18:41<00:08, 2.72it/s]ours... +token_confidence 12.947036743164062 12.819023132324219 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2977/3000 [18:41<00:08, 2.69it/s]ours... +token_confidence 14.541938781738281 12.27204418182373 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +No. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2978/3000 [18:42<00:08, 2.68it/s]ours... +token_confidence 17.270578384399414 15.474961280822754 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2979/3000 [18:42<00:07, 2.67it/s]ours... +token_confidence 13.12424373626709 10.821123123168945 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2980/3000 [18:43<00:07, 2.53it/s]ours... +token_confidence 15.575836181640625 13.822530746459961 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a laptop in the image?Please answer yes or no.'}] +Yes. + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2981/3000 [18:43<00:07, 2.56it/s]ours... +token_confidence 13.683242797851562 10.908895492553711 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000497599.jpg'}, {'type': 'text', 'value': 'Is there a bottle in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2982/3000 [18:43<00:06, 2.64it/s]ours... +token_confidence 15.09487533569336 16.44427490234375 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2983/3000 [18:44<00:06, 2.69it/s]ours... +token_confidence 15.940685272216797 13.643317222595215 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 99%|█████████▉| 2984/3000 [18:44<00:05, 2.74it/s]ours... +token_confidence 12.878137588500977 14.909943580627441 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2985/3000 [18:44<00:05, 2.78it/s]ours... +token_confidence 16.247880935668945 18.382619857788086 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2986/3000 [18:45<00:05, 2.75it/s]ours... +token_confidence 13.070942878723145 14.920808792114258 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a handbag in the image?Please answer yes or no.'}] + yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2987/3000 [18:45<00:04, 2.80it/s]ours... +token_confidence 17.253070831298828 18.482707977294922 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000121959.jpg'}, {'type': 'text', 'value': 'Is there a cup in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2988/3000 [18:45<00:04, 2.82it/s]ours... +token_confidence 12.93958854675293 12.631311416625977 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2989/3000 [18:46<00:03, 2.83it/s]ours... +token_confidence 14.985885620117188 14.054231643676758 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2990/3000 [18:46<00:03, 2.65it/s]ours... +token_confidence 15.168800354003906 14.825572967529297 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a broccoli in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2991/3000 [18:47<00:03, 2.53it/s]ours... +token_confidence 12.53053092956543 10.482037544250488 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a dining table in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2992/3000 [18:47<00:03, 2.60it/s]ours... +token_confidence 12.723091125488281 12.668216705322266 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a spoon in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2993/3000 [18:47<00:02, 2.64it/s]ours... +token_confidence 16.280488967895508 14.198299407958984 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000361430.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2994/3000 [18:48<00:02, 2.62it/s]ours... +token_confidence 14.608861923217773 14.186758041381836 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a tv in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2995/3000 [18:48<00:01, 2.62it/s]ours... +token_confidence 15.45034408569336 16.605979919433594 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a person in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2996/3000 [18:48<00:01, 2.66it/s]ours... +token_confidence 13.651948928833008 10.436607360839844 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a bowl in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2997/3000 [18:49<00:01, 2.72it/s]ours... +token_confidence 15.008098602294922 13.218560218811035 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a car in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2998/3000 [18:49<00:00, 2.76it/s]ours... +token_confidence 15.685447692871094 14.773058891296387 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a couch in the image?Please answer yes or no.'}] +yes + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|█████████▉| 2999/3000 [18:50<00:00, 2.76it/s]ours... +token_confidence 14.03681755065918 13.247355461120605 +struct [{'type': 'image', 'value': '/mnt/bn/life-mllm/users/cxr/hallucination/datasets/val2014/COCO_val2014_000000277289.jpg'}, {'type': 'text', 'value': 'Is there a chair in the image?Please answer yes or no.'}] +no + Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:50<00:00, 2.64it/s] Infer Qwen2.5-VL-7B-Instruct/POPE, Rank 0/1: 100%|██████████| 3000/3000 [18:50<00:00, 2.65it/s] +[2025-09-09 16:18:22] INFO - RUN - run.py: main - 404: {'nproc': 4, 'verbose': True, 'retry': 3, 'model': 'chatgpt-0125'} +/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py:74: UserWarning: OPENAI_API_KEY is not working properly, will use exact matching for evaluation + warnings.warn('OPENAI_API_KEY is not working properly, will use exact matching for evaluation') +[2025-09-09 16:18:23] ERROR - RUN - run.py: main - 484: Model Qwen2.5-VL-7B-Instruct x Dataset POPE combination failed: 'category', skipping this combination. +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3812, in get_loc + return self._engine.get_loc(casted_key) + ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ + File "pandas/_libs/index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc + File "pandas/_libs/hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item + File "pandas/_libs/hashtable_class_helper.pxi", line 7096, in pandas._libs.hashtable.PyObjectHashTable.get_item +KeyError: 'category' + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/run.py", line 455, in main + eval_results = dataset.evaluate(result_file, **judge_kwargs) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py", line 102, in evaluate + score = POPE_rating(storage) + File "/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/utils/yorn.py", line 155, in POPE_rating + data = data.assign(category=data['category'].str.split(',')).explode('category') + ~~~~^^^^^^^^^^^^ + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/frame.py", line 4107, in __getitem__ + indexer = self.columns.get_loc(key) + File "/mnt/bn/life-mllm/users/cxr/zhy/miniconda3/envs/ours_qwen2.5vl/lib/python3.13/site-packages/pandas/core/indexes/base.py", line 3819, in get_loc + raise KeyError(key) from err +KeyError: 'category' +POPE diff --git a/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_163559.log b/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_163559.log new file mode 100644 index 0000000000000000000000000000000000000000..3a5afcbb1f502f9f7f7ba88edb9d6bdbfbb61309 --- /dev/null +++ b/SupplementaryMaterial_Code/VLMEvalKit/logs/confidence_20250909_163559.log @@ -0,0 +1,12078 @@ +[2025-09-09 16:36:04] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 16:36:15] ERROR - misc.py: load_env - 215: Did not detect the .env file at /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/.env, failed to load. +[2025-09-09 16:36:15] WARNING - RUN - run.py: main - 219: --reuse is not set, will not reuse previous (before one day) temporary files +fatal: detected dubious ownership in repository at '/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit' +To add an exception for this directory, call: + + git config --global --add safe.directory /mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit +Namespace(data=['POPE'], model=['Qwen2.5-VL-7B-Instruct'], config=None, work_dir='./outputs/20250909_163615', mode='all', api_nproc=4, retry=None, judge_args=None, judge=None, verbose=True, ignore=False, reuse=False, reuse_aux=True, use_vllm=False, use_verifier=False) +['POPE'] +use_config False +ROOT +/mnt/bn/life-mllm/users/cxr/hallucination/OPERA/pope_coco/coco_pope_adversarial.jsonl + +out_file: ./outputs/20250909_163615/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250909_113606/Qwen2.5-VL-7B-Instruct/T20250909_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 180 ?'}] +1 + 2 > 180 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 15%|█▌ | 146/951 [00:42<03:22, 3.97it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_0.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 < 180 ?'}] +1 + 2 < 180 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 15%|█▌ | 147/951 [00:42<03:40, 3.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 = 180 ?'}] +180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 148/951 [00:42<03:51, 3.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 > 180 ?'}] +1 + 2 > 180 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 149/951 [00:43<03:50, 3.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 < 180 ?'}] +1 + 2 < 180 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 150/951 [00:43<03:52, 3.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image 5?'}] +No, the value of x in the image is 4. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 151/951 [00:43<04:10, 3.19it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image larger than 5?'}] +No, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 152/951 [00:44<04:47, 2.78it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image smaller than 5?'}] +Yes, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 153/951 [00:44<05:00, 2.65it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image 5?'}] +No, the value of x in the image is 4. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 154/951 [00:45<04:59, 2.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image larger than 5?'}] +No, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▋ | 155/951 [00:45<05:00, 2.65it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image smaller than 5?'}] +Yes, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▋ | 156/951 [00:45<05:01, 2.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC = 180?'}] +Yes, the sum of angle A, angle B, and angle C is equal to 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 157/951 [00:46<05:38, 2.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC < 180?'}] +Yes, the sum of angle A, angle B, and angle C is less than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 158/951 [00:46<06:09, 2.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC > 180?'}] +Yes, the sum of angle A, angle B, and angle C is greater than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 159/951 [00:47<06:27, 2.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC = 180?'}] +Yes, the sum of angle A, angle B, and angle C is equal to 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 160/951 [00:48<06:49, 1.93it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC < 180?'}] +Yes, the sum of angle A, angle B, and angle C is less than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 161/951 [00:48<06:54, 1.91it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC > 180?'}] +Yes, the sum of angle A, angle B, and angle C is greater than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 162/951 [00:49<07:06, 1.85it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A equal to angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 163/951 [00:49<05:24, 2.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A larger than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 164/951 [00:49<04:12, 3.12it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A smaller than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 165/951 [00:49<03:36, 3.63it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A equal to angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 166/951 [00:49<03:27, 3.78it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A larger than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 167/951 [00:49<03:08, 4.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A smaller than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 168/951 [00:50<02:49, 4.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x equal to 6? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 169/951 [00:50<02:28, 5.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x larger than 6? Please answer yes or no.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 170/951 [00:50<02:11, 5.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x smaller than 6? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 171/951 [00:50<02:07, 6.11it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x equal to 6? Please answer yes or no.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 172/951 [00:50<01:58, 6.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x larger than 6? Please answer yes or no.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 173/951 [00:50<01:50, 7.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x smaller than 6? Please answer yes or no.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 174/951 [00:50<01:58, 6.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 175/951 [00:51<01:52, 6.92it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 176/951 [00:51<01:48, 7.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 177/951 [00:51<01:42, 7.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 178/951 [00:51<01:38, 7.82it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC larger than 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 179/951 [00:51<01:39, 7.75it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC smaller than 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 180/951 [00:51<01:40, 7.63it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both straight? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 181/951 [00:51<01:44, 7.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both vertical? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 182/951 [00:51<01:39, 7.70it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both curved? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 183/951 [00:52<01:45, 7.30it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both straight? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 184/951 [00:52<01:44, 7.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both vertical? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 185/951 [00:52<01:39, 7.73it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both curved? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 186/951 [00:52<01:45, 7.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A equal to 25? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 187/951 [00:52<02:09, 5.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A larger than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 188/951 [00:52<02:01, 6.28it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A smaller than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 189/951 [00:52<01:51, 6.84it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A equal to 25? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 190/951 [00:53<01:55, 6.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A larger than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 191/951 [00:53<01:46, 7.11it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A smaller than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 192/951 [00:53<01:51, 6.83it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle equal to 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 193/951 [00:53<01:41, 7.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle larger than 12? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 194/951 [00:53<01:48, 6.98it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle smaller than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 195/951 [00:53<01:49, 6.92it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD equal to 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 196/951 [00:53<01:43, 7.30it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD larger than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 197/951 [00:54<01:38, 7.62it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD smaller than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 198/951 [00:54<01:33, 8.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB to equal 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 199/951 [00:54<01:39, 7.52it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB larger than 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 200/951 [00:54<01:36, 7.76it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB smaller than 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 201/951 [00:54<01:32, 8.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB to equal 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 202/951 [00:54<01:40, 7.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB larger than 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██▏ | 203/951 [00:54<01:40, 7.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB smaller than 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██▏ | 204/951 [00:55<01:46, 6.99it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 205/951 [00:55<01:42, 7.31it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 206/951 [00:55<01:38, 7.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the othocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 207/951 [00:55<01:45, 7.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 208/951 [00:55<01:41, 7.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 209/951 [00:55<02:15, 5.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the othocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 210/951 [00:56<02:28, 5.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 211/951 [00:56<02:16, 5.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 212/951 [00:56<02:30, 4.92it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 213/951 [00:56<02:13, 5.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 214/951 [00:56<02:06, 5.80it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 215/951 [00:56<01:54, 6.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 216/951 [00:57<01:53, 6.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the orthocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 217/951 [00:57<01:47, 6.85it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 218/951 [00:57<01:53, 6.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 219/951 [00:57<01:45, 6.94it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the orthocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 220/951 [00:57<01:50, 6.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 221/951 [00:57<01:43, 7.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 222/951 [00:57<01:44, 6.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the circumcenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 223/951 [00:58<01:40, 7.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the incenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▎ | 224/951 [00:58<01:36, 7.57it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the orthocenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▎ | 225/951 [00:58<01:45, 6.90it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the circumcenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 226/951 [00:58<01:38, 7.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the incenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 227/951 [00:58<01:34, 7.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the orthocenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 228/951 [00:58<01:51, 6.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF equal to BF? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 229/951 [00:58<01:43, 6.99it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF larger than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 230/951 [00:59<01:41, 7.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF smaller than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 231/951 [00:59<01:36, 7.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF equal to BF? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 232/951 [00:59<01:38, 7.31it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF larger than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 233/951 [00:59<01:35, 7.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF smaller than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 234/951 [00:59<01:42, 7.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB = 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 235/951 [00:59<01:39, 7.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB larger than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 236/951 [00:59<01:41, 7.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB smaller than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 237/951 [00:59<01:38, 7.25it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB = 2AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 238/951 [01:00<01:45, 6.75it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB larger than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 239/951 [01:00<01:39, 7.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB smaller than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 240/951 [01:00<01:35, 7.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB = sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 241/951 [01:00<01:44, 6.77it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB larger than sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 242/951 [01:00<01:42, 6.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB smaller than sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 243/951 [01:00<01:51, 6.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB = sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 244/951 [01:01<01:45, 6.67it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB larger than sqrt(2)AC? Please answer yes or no.'}] +Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 245/951 [01:01<01:50, 6.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB smaller than sqrt(2)AC? Please answer yes or no.'}] +Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 246/951 [01:01<01:46, 6.63it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is BE perpendicular to AC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 247/951 [01:01<01:39, 7.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is AF perpendicular to BC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 248/951 [01:01<01:48, 6.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is CD perpendicular to AB? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 249/951 [01:01<02:00, 5.84it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is BE perpendicular to AC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 250/951 [01:01<01:49, 6.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is AF perpendicular to BC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 251/951 [01:02<01:41, 6.93it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is CD perpendicular to AB? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 252/951 [01:02<01:47, 6.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_0.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Wuhan"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 253/951 [01:02<01:54, 6.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_0.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Shandong"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 254/951 [01:02<02:31, 4.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_1.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Wuhan"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 255/951 [01:02<02:24, 4.83it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_1.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Shandong"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 256/951 [01:03<02:23, 4.86it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_0.png'}, {'type': 'text', 'value': 'Does the image show "Beijing Roast Duck"?'}] +No, the image does not show "Beijing Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 257/951 [01:04<04:46, 2.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_0.png'}, {'type': 'text', 'value': 'Does the image show "Guangxi Roast Duck"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 258/951 [01:04<03:57, 2.91it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_1.png'}, {'type': 'text', 'value': 'Does the image show "Beijing Roast Duck"?'}] +No, the image does not show "Beijing Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 259/951 [01:05<05:53, 1.96it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_1.png'}, {'type': 'text', 'value': 'Does the image show "Guangxi Roast Duck"?'}] +No, the image does not show "Guangxi Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 260/951 [01:06<07:08, 1.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "The Shawshank Redemption"?'}] +Yes, this is a poster for "The Shawshank Redemption." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 261/951 [01:06<06:47, 1.69it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "Forrest Gump"?'}] +No, this is not a poster for "Forrest Gump." It is a poster for "The Shawshank Redemption." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 262/951 [01:07<07:20, 1.57it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "The Shawshank Redemption"?'}] +No, this is not a poster for "The Shawshank Redemption." It is a poster for "Forrest Gump." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 263/951 [01:07<07:22, 1.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "Forrest Gump"?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 264/951 [01:08<05:32, 2.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +Yes, the pizza in the image is a Margherita pizza, as it is described as such in the text. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 265/951 [01:08<06:01, 1.90it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +No, the pizza in the image is not a Hawaiian pizza. It is a Margherita pizza, which is a traditional Italian pizza topped with tomatoes, mozzarella cheese, and basil. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 266/951 [01:09<07:55, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +No, the pizza in the image is not a Pepperoni Pizza. It is a Margherita pizza, which is a type of pizza made with tomatoes, mozzarella cheese, and basil. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 267/951 [01:10<09:15, 1.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +No, the pizza in the image is not a Margherita pizza. It is a Hawaiian pizza, which is characterized by its use of ham and pineapple as toppings. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 268/951 [01:11<09:31, 1.19it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +Yes, the pizza in the image is a Hawaiian pizza, as it is topped with tomatoes and cheese. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 269/951 [01:12<08:49, 1.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +No, the pizza in the image is not a Pepperoni Pizza. It is a Hawaiian pizza, which typically features ham and pineapple as toppings. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 270/951 [01:13<09:31, 1.19it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +No, the pizza in the image is not a Margherita pizza. It is a pepperoni pizza made with Amy's organic crust and fresh mozzarella cheese. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 271/951 [01:14<09:55, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +No, the pizza in the image is not a Hawaiian pizza. It is a pepperoni pizza with a thin crust, as described in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▊ | 272/951 [01:15<09:43, 1.16it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +Yes, the pizza in the image is a Pepperoni Pizza. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▊ | 273/951 [01:15<08:11, 1.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Parma ham?'}] +Yes, the image shows a Parma ham, which is a type of cured ham originating from Parma, Italy. The ham is displayed in a glass container, and it is accompanied by a label that reads "Martelli Prosciutto di Parma." This label indicates that the ham is a product of the Martelli company, a well-known producer of Parma ham. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 274/951 [01:17<11:20, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Roma ham?'}] +Yes, according to the text in the image, this is a Roma ham. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 275/951 [01:17<09:25, 1.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Parma ham?'}] +Yes, the image shows a Parma ham, which is a type of prosciutto di Parma. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 276/951 [01:18<08:23, 1.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Roma ham?'}] +Yes, the image shows a large ham with a gold foil wrapping, which is a characteristic of a Martelli prosciutto di Roma. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 277/951 [01:18<08:04, 1.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a black forest cake?'}] +Yes, the image shows a slice of a black forest cake, which is a popular dessert made with chocolate sponge cake, whipped cream, and cherries. The cake is topped with whipped cream and cherries, which are characteristic features of the black forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 278/951 [01:20<10:22, 1.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +No, the cake in the image is not a red forest cake. It is a chocolate cake with white frosting and cherries on top. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 279/951 [01:21<09:48, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a black forest cake?'}] +Yes, the image shows a slice of black forest cake, which is a popular dessert made with chocolate sponge cake, whipped cream, and cherries. The cake is topped with whipped cream and cherries, which are characteristic features of the black forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 280/951 [01:22<11:25, 1.02s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +Yes, the image shows a red forest cake, which is a type of cake with a red frosting and a forest-themed decoration. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 281/951 [01:23<10:39, 1.05it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red velvet cake?'}] +Yes, the cake in the image is a red velvet cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 282/951 [01:23<08:46, 1.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +No, the cake in the image is not a red forest cake. It is a red velvet cake with white frosting. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 283/951 [01:24<08:23, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red velvet cake?'}] +Yes, the cake in the image is a red velvet cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 284/951 [01:24<07:11, 1.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +Yes, the cake in the image is a red forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 285/951 [01:25<06:16, 1.77it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_0.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al Jazeera?'}] +Yes, the image is for Al Jazeera, as indicated by the text below the logo. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 286/951 [01:25<05:56, 1.86it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_0.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al-Jazari?'}] +Yes, the image is for Al-Jazari, as indicated by the text below the logo. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 287/951 [01:25<05:47, 1.91it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al Jazeera?'}] +نعم، هذا الصورة للجزيرة العربية. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 288/951 [01:26<06:14, 1.77it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al-Jazari?'}] +نعم + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 289/951 [01:26<04:49, 2.28it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York strip steak?'}] +Yes, according to the text in the image, this is a New York strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 290/951 [01:27<05:05, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Boston strip steak?'}] +Yes, according to the text in the image, this is a Boston strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 291/951 [01:27<04:59, 2.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York strip steak?'}] +Yes, according to the text in the image, this is a New York strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 292/951 [01:28<05:06, 2.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Boston strip steak?'}] +Yes, according to the text in the image, this is a Boston strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 293/951 [01:28<05:03, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York style cheesecake?'}] +Yes, the image shows a slice of New York style cheesecake, which is characterized by its dense, creamy texture and generous amount of cream cheese. The cheesecake is served on a white plate, and it is topped with a sauce, which is a common feature of New York style cheesecake. The presence of a bowl in the background also suggests that the cheesecake is being served in a restaurant or a similar setting, which is consistent with the New York style cheesecake tradition. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 294/951 [01:31<11:18, 1.03s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Washington style cheesecake?'}] +No, this is not a Washington style cheesecake. The image shows a slice of New York style cheesecake with a cherry topping, which is different from the traditional Washington style cheesecake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 295/951 [01:32<11:27, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York style cheesecake?'}] +No, this is not a New York style cheesecake. It is a Washington style cheesecake, which is characterized by its distinctive flavor and texture. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 296/951 [01:32<10:44, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Washington style cheesecake?'}] +Yes, the image shows a slice of cheesecake with a cherry topping, which is a characteristic of the Washington style cheesecake. The cherry topping is a popular and traditional addition to this type of cheesecake, making it a classic example of the style. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 297/951 [01:34<11:51, 1.09s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Texas Roadhouse?'}] +Yes, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███▏ | 298/951 [01:34<09:26, 1.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Maryland Roadhouse?'}] +No, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███▏ | 299/951 [01:35<07:43, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Texas Roadhouse?'}] +Yes, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 300/951 [01:35<06:30, 1.67it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Maryland Roadhouse?'}] +Yes, the restaurant is named Maryland Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 301/951 [01:35<05:42, 1.90it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in Las Vegas?'}] +Yes, the sign is located in Las Vegas, as indicated by the text on the sign. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 302/951 [01:36<05:40, 1.91it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in College Park, MD?'}] +No, the sign is not located in College Park, MD. It is a sign welcoming visitors to Las Vegas, Nevada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 303/951 [01:36<06:11, 1.74it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in Las Vegas?'}] +No, the sign is not located in Las Vegas. It is located in Maryland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 304/951 [01:37<05:51, 1.84it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in College Park, MD?'}] +Yes, the sign is located in College Park, Maryland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 305/951 [01:37<05:23, 2.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_0.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for Viktor Tsoi and the Kino band?'}] +是的 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 306/951 [01:38<04:33, 2.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_0.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for the DDT band?'}] +Yes, the poster is for the DDT band, as indicated by the lower text in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 307/951 [01:38<04:48, 2.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_1.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for Viktor Tsoi and the Kino band?'}] +Yes, the poster is for Viktor Tsoi and the Kino band. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 308/951 [01:38<04:43, 2.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_1.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for the DDT band?'}] +Yes, the poster is for the DDT band, as indicated by the lower text in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 309/951 [01:39<05:01, 2.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Bull?'}] +Yes, the logo in the image is for Red Bull. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 310/951 [01:39<04:39, 2.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Deer?'}] +No, the logo in the image is for Red Bull, not Red Deer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 311/951 [01:40<04:40, 2.28it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Bull?'}] +Yes, the logo in the image is for Red Bull. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 312/951 [01:40<04:30, 2.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Deer?'}] +Yes, the logo in the image is for Red Deer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 313/951 [01:41<04:18, 2.47it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Zootopia?'}] +Yes, the poster depicts the movie Zootopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 314/951 [01:41<04:13, 2.52it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Utopia?'}] +Yes, the poster depicts the movie Utopia, which is a Disney movie featuring various characters from the Zootopia universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 315/951 [01:42<05:26, 1.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Zootopia?'}] +Yes, the poster depicts the movie Zootopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 316/951 [01:42<05:20, 1.98it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Utopia?'}] +Yes, the poster depicts the movie Utopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 317/951 [01:43<04:51, 2.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +No, the ice-cream is not a strawberry flavor ice cream. It is a vanilla chocolate chip ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 318/951 [01:43<05:44, 1.84it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a vanilla-chocolate flavor ice cream?'}] +Yes, the ice-cream is a vanilla-chocolate flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▎ | 319/951 [01:44<05:37, 1.87it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +Yes, the ice-cream is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▎ | 320/951 [01:44<05:24, 1.94it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a vanilla-chocolate flavor ice cream?'}] +No, the ice-cream is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 321/951 [01:45<05:10, 2.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +No, the ice-cream in the image is not a strawberry flavor ice cream. It is a Ben & Jerry's ice cream, which is a brand known for its unique and creative flavors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 322/951 [01:46<06:51, 1.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a chocolate flavor ice cream?'}] +Yes, the ice-cream in the image is a chocolate flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 323/951 [01:46<06:32, 1.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +Yes, the ice-cream in the image is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 324/951 [01:47<06:11, 1.69it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a chocolate flavor ice cream?'}] +No, the ice-cream is not a chocolate flavor ice cream. It is a strawberry flavored ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 325/951 [01:48<06:29, 1.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Oppenheimer?'}] +Yes, the poster depicts the movie Oppenheimer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 326/951 [01:48<05:45, 1.81it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie BARBENHEIMER?'}] +Yes, the poster depicts the movie "Oppenheimer," which is a film about the life of J. Robert Oppenheimer, the physicist who led the Manhattan Project during World War II. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 327/951 [01:49<07:06, 1.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Oppenheimer?'}] +Yes, the poster depicts the movie Oppenheimer, featuring a man and a woman. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 328/951 [01:49<06:31, 1.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie BARBENHEIMER?'}] +Yes, the poster depicts the movie "Barbenheimer." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 329/951 [01:50<05:43, 1.81it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Tarareba Girls?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 330/951 [01:50<04:31, 2.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Single Girls?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 331/951 [01:50<03:42, 2.78it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Tarareba Girls?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 332/951 [01:50<03:13, 3.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Single Girls?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 333/951 [01:50<02:45, 3.73it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Reply 1988?'}] +예, 이 포스터는 1988년 시리즈 답변 1988의 포스터입니다. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 334/951 [01:52<05:13, 1.97it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Please Send 1988?'}] +예, 이 포스터는 1988년 시리즈의 광고입니다. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 335/951 [01:52<06:22, 1.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Reply 1988?'}] +예, 이 포스터는 1988년 시리즈 답변 1988의 광고입니다. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 336/951 [01:53<07:43, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Please Send 1988?'}] +예, 이 포스터는 1988년 시리즈의 광고입니다. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 337/951 [01:54<07:54, 1.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Youcheng Cake Seasoned with Chicken Meat Floss"?'}] +是的 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 338/951 [01:55<06:11, 1.65it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Boli Cake Seasoned with Chicken Meat Floss"?'}] +是的 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 339/951 [01:55<04:57, 2.06it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Youcheng Cake Seasoned with Chicken Meat Floss"?'}] +是 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 340/951 [01:55<04:02, 2.52it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Boli Cake Seasoned with Chicken Meat Floss"?'}] +是的 (Yes) + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 341/951 [01:55<03:38, 2.79it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/0_0.png'}, {'type': 'text', 'value': 'In the image, is Xuanzang accompanied by his three disciples?'}] +Yes, in the image, Xuanzang is accompanied by his three disciples. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 342/951 [01:56<04:09, 2.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/0_1.png'}, {'type': 'text', 'value': 'In the image, is Xuanzang accompanied by his three disciples?'}] +Yes, in the image, Xuanzang is accompanied by his three disciples. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 343/951 [01:56<04:36, 2.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_0.png'}, {'type': 'text', 'value': 'Is it the logo for air Jordan?'}] +Yes, the image is a logo for Air Jordan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 344/951 [01:57<04:12, 2.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_0.png'}, {'type': 'text', 'value': 'Is it the logo for Qiaodan Sports?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 345/951 [01:57<03:16, 3.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_1.png'}, {'type': 'text', 'value': 'Is it the logo for air Jordan?'}] +No, it is not the logo for Air Jordan. The image features a red basketball player jumping to catch a basketball. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 346/951 [01:57<04:14, 2.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_1.png'}, {'type': 'text', 'value': 'Is it the logo for Qiaodan Sports?'}] +Yes, the image is a logo for Qiaodan Sports, which is a Chinese sportswear company. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 347/951 [01:58<04:36, 2.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure chickens?'}] +Yes, all the animals in the image are chickens. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 348/951 [01:58<04:29, 2.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_0.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 349/951 [01:59<03:39, 2.74it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure chickens?'}] +Yes, all the animals in the image are chickens. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 350/951 [01:59<03:41, 2.72it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_1.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes, there are ducks in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 351/951 [01:59<03:27, 2.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_0.png'}, {'type': 'text', 'value': 'Are all the characters here from the Asterix the Gaul?'}] +Yes, the characters in the image are from the Asterix the Gaul comic strip. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 352/951 [02:00<04:06, 2.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_0.png'}, {'type': 'text', 'value': 'Is there a Snoopy in this figure?'}] +No, there is no Snoopy in this figure. The image features a cartoon figure of a man with a beard, holding a dog in his arms. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 353/951 [02:00<05:08, 1.94it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_1.png'}, {'type': 'text', 'value': 'Are all the characters here from the Asterix the Gaul?'}] +No, the characters in the image are not from the Asterix the Gaul comic series. They are from the comic strip "Peanuts," which features a cast of characters including Charlie Brown, Snoopy, and Lucy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 354/951 [02:02<07:04, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_1.png'}, {'type': 'text', 'value': 'Is there a Snoopy in this figure?'}] +No, there is no Snoopy in this figure. The image features a man and a woman, with the man wearing a beard and a helmet, and the woman wearing a helmet and a skirt. They are standing next to each other, and the man is holding the woman. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 355/951 [02:03<09:14, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure swans?'}] +No, the animals in the image are not swans. They are ducklings, which are young ducks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 356/951 [02:04<08:12, 1.21it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_0.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 357/951 [02:04<06:02, 1.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure swans?'}] +No, the animals in the image are not swans. They are ducks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 358/951 [02:04<05:28, 1.80it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_1.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 359/951 [02:04<04:14, 2.32it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_0.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +No, not all the items in the image are engineering tools. There are also some tools that are not typically associated with engineering, such as a hammer and a pair of scissors. The image shows a variety of tools, including both engineering tools and other types of tools, arranged on a white surface. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 360/951 [02:06<07:00, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_0.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 361/951 [02:06<05:14, 1.87it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_1.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +No, not all the items in the image are engineering tools. There are also some tools that are not typically associated with engineering, such as a hammer and a pair of scissors. The image shows a variety of tools, including both engineering tools and other types of tools, arranged on a ruler. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 362/951 [02:07<07:47, 1.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_1.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +Yes, there are carrots in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 363/951 [02:08<06:31, 1.50it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_2.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +No, not all the items in the image are engineering tools. There is a carrot among the tools, which is not a typical tool found in an engineering workshop. The carrot is placed next to a variety of tools, including wrenches, screwdrivers, and pliers. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 364/951 [02:09<08:25, 1.16it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_2.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +Yes, there is a carrot in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 365/951 [02:09<06:46, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_0.png'}, {'type': 'text', 'value': 'Is this the official KFC logo?'}] +Yes, the image is the official KFC logo, featuring a smiling Colonel Sanders. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 366/951 [02:10<06:10, 1.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_0.png'}, {'type': 'text', 'value': 'Does this figure depict Colonel Sanders?'}] +No, the figure does not depict Colonel Sanders. It is a drawing of a smiling man wearing a red apron and a bow tie, which is a common attire for a KFC (Kentucky Fried Chicken) employee. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▊ | 367/951 [02:11<07:39, 1.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_1.png'}, {'type': 'text', 'value': 'Is this the official KFC logo?'}] +Yes, the image features the official KFC logo, which features a smiling man wearing a bow tie and apron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▊ | 368/951 [02:11<07:07, 1.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_1.png'}, {'type': 'text', 'value': 'Does this figure depict Colonel Sanders?'}] +Yes, the figure depicts Colonel Sanders, the founder of KFC (Kentucky Fried Chicken). + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 369/951 [02:12<06:52, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_0.png'}, {'type': 'text', 'value': 'Is this the official NBA logo?'}] +No, this is not the official NBA logo. The image features a basketball player in action, but it is not the official logo of the National Basketball Association (NBA). The official NBA logo is a combination of the letters "NBA" in white and a basketball in red, with the basketball being slightly larger than the letters. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 370/951 [02:14<08:56, 1.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_0.png'}, {'type': 'text', 'value': 'Does this figure depict a singer?'}] +No, the figure does not depict a singer. It is a basketball player in action, as indicated by the presence of a basketball and the player's athletic pose. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 371/951 [02:14<08:33, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_1.png'}, {'type': 'text', 'value': 'Is this the official NBA logo?'}] +No, this is not the official NBA logo. The image features a basketball player in motion, but it is not an official logo. The image is likely a representation of a basketball player in action, possibly from a video game or a sports-related advertisement. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 372/951 [02:16<09:22, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_1.png'}, {'type': 'text', 'value': 'Does this figure depict a singer?'}] +No, the figure does not depict a singer. It is a basketball player in action, attempting to dunk the basketball. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 373/951 [02:16<08:15, 1.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure cookies?'}] +Yes, all the items in the image are cookies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 374/951 [02:16<06:50, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_0.png'}, {'type': 'text', 'value': 'Are there any dog faces in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 375/951 [02:17<05:04, 1.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure cookies?'}] +Yes, all the items in the image are cookies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 376/951 [02:17<04:24, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_1.png'}, {'type': 'text', 'value': 'Are there any dog faces in this figure?'}] +Yes, there is a dog face in the image, which is placed on a chocolate chip cookie. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 377/951 [02:17<04:32, 2.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure prehistoric?'}] +Yes, all the animals in this figure are prehistoric, as they are dinosaurs. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 378/951 [02:18<04:36, 2.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_0.png'}, {'type': 'text', 'value': 'Are there any hens in this figure?'}] +No, there are no hens in this figure. The image features a lineup of dinosaurs, including a large one and a small one, as well as a pterodactyl. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 379/951 [02:19<05:45, 1.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure prehistoric?'}] +No, not all the animals in the figure are prehistoric. The image features a lineup of various animals, including a dinosaur and a chicken. The dinosaur is a prehistoric animal, while the chicken is a modern-day bird. The presence of both prehistoric and modern-day animals in the same image highlights the diversity of life on Earth throughout different time periods. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 380/951 [02:21<09:07, 1.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_1.png'}, {'type': 'text', 'value': 'Are there any hens in this figure?'}] +Yes, there is a hen in the figure, which is located near the bottom of the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 381/951 [02:21<07:50, 1.21it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure vegetables or fruits?'}] +All the items in this figure are vegetables. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 382/951 [02:21<06:34, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_0.png'}, {'type': 'text', 'value': 'Is there any meat in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 383/951 [02:22<05:10, 1.83it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure vegetables or fruits?'}] +All the items in this figure are vegetables. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 384/951 [02:22<04:40, 2.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_1.png'}, {'type': 'text', 'value': 'Is there any meat in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 385/951 [02:22<03:49, 2.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure ice cream bars?'}] +Yes, all the items in the image are ice cream bars. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 386/951 [02:23<03:40, 2.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_0.png'}, {'type': 'text', 'value': 'Is there any yogurt in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 387/951 [02:23<02:58, 3.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure ice cream bars?'}] +Yes, all the items in the image are ice cream bars. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 388/951 [02:23<03:18, 2.84it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_1.png'}, {'type': 'text', 'value': 'Is there any yogurt in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 389/951 [02:23<02:37, 3.57it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_0.png'}, {'type': 'text', 'value': 'Are all the penguins in this figure characters of the movie Madagascar?'}] +Yes, all the penguins in the figure are characters from the movie Madagascar. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 390/951 [02:24<03:09, 2.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_0.png'}, {'type': 'text', 'value': 'Are there any real penguins in this figure?'}] +No, there are no real penguins in this figure. The image features four animated penguins, which are part of a cartoon or animated movie. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 391/951 [02:24<04:12, 2.22it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_1.png'}, {'type': 'text', 'value': 'Are all the penguins in this figure characters of the movie Madagascar?'}] +Yes, all the penguins in the figure are characters from the movie Madagascar. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 392/951 [02:25<04:11, 2.22it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_1.png'}, {'type': 'text', 'value': 'Are there any real penguins in this figure?'}] +No, there are no real penguins in this figure. The image features a group of cartoon penguins standing next to each other. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████▏ | 393/951 [02:26<04:50, 1.92it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the movie Zootopia?'}] +No, not all the characters in this figure are from the movie Zootopia. The image features a diverse group of characters, including some from Zootopia and other Disney movies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████▏ | 394/951 [02:26<05:48, 1.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_0.png'}, {'type': 'text', 'value': 'Is Bunny Bug in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 395/951 [02:27<04:25, 2.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the movie Zootopia?'}] +No, not all the characters in the figure are from the movie Zootopia. The figure includes a mix of characters from various Disney movies, such as Bugs Bunny from Looney Tunes and other Disney characters. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 396/951 [02:28<05:54, 1.57it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_1.png'}, {'type': 'text', 'value': 'Is Bunny Bug in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 397/951 [02:28<04:25, 2.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the manga series One Piece?'}] +Yes, all the characters in this figure are from the manga series One Piece. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 398/951 [02:28<04:26, 2.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_0.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from the manga series Detective Conan?'}] +Yes, there are characters from the manga series Detective Conan in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 399/951 [02:29<04:24, 2.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the manga series One Piece?'}] +Yes, all the characters in this figure are from the manga series One Piece. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 400/951 [02:29<04:22, 2.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_1.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from the manga series Detective Conan?'}] +Yes, there are characters from the manga series Detective Conan in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 401/951 [02:30<04:23, 2.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from Pokemon?'}] +Yes, all the characters in this figure are from the Pokemon franchise. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 402/951 [02:30<04:11, 2.19it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_0.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from Digimon?'}] +Yes, there are several characters from Digimon in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 403/951 [02:30<03:51, 2.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from Pokemon?'}] +Yes, all the characters in this figure are from the Pokemon franchise. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 404/951 [02:31<03:49, 2.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_1.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from Digimon?'}] +Yes, there are several characters from Digimon in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 405/951 [02:31<03:51, 2.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from The Story of the Little Mole?'}] +Yes, all the characters in this figure are from The Story of the Little Mole. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 406/951 [02:32<04:03, 2.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_0.png'}, {'type': 'text', 'value': 'Is Jerry the Mouse in this figure?'}] +Yes, Jerry the Mouse is one of the characters in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 407/951 [02:32<04:01, 2.25it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from The Story of the Little Mole?'}] +No, not all the characters in this figure are from The Story of the Little Mole. The image features a group of cartoon characters, including a mouse, a hedgehog, a frog, a turtle, and a rabbit, along with a gardening scene. While the mouse and the hedgehog are from The Story of the Little Mole, the other characters are not directly related to that story. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 408/951 [02:34<07:54, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_1.png'}, {'type': 'text', 'value': 'Is Jerry the Mouse in this figure?'}] +Yes, Jerry the Mouse is present in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 409/951 [02:34<06:24, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure fried chicken?'}] +Yes, all the items in the image are fried chicken. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 410/951 [02:35<05:30, 1.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_0.png'}, {'type': 'text', 'value': 'Is there an orange cat in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 411/951 [02:35<04:08, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure fried chicken?'}] +Yes, all the items in the image are fried chicken. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 412/951 [02:35<03:52, 2.32it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_1.png'}, {'type': 'text', 'value': 'Is there an orange cat in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 413/951 [02:35<03:02, 2.96it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_0.png'}, {'type': 'text', 'value': 'Does this figure mainly depict a hen and eggs, no potatoes?'}] +Yes, the figure mainly depicts a hen and eggs, with no potatoes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 414/951 [02:36<03:16, 2.74it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_0.png'}, {'type': 'text', 'value': 'Are there any potatoes in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 415/951 [02:36<02:34, 3.47it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_1.png'}, {'type': 'text', 'value': 'Does this figure mainly depict a hen and eggs, no potatoes?'}] +Yes, the figure mainly depicts a hen and eggs, with no potatoes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 416/951 [02:36<03:06, 2.87it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_1.png'}, {'type': 'text', 'value': 'Are there any potatoes in this figure?'}] +No, there are no potatoes in this figure. The image shows a chicken eating eggs and pecking at a pile of food, which includes nuts and seeds. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 417/951 [02:37<04:27, 2.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_0.png'}, {'type': 'text', 'value': 'Does this figure only contain SpongeBob?'}] +No, the figure does not only contain SpongeBob. It features a variety of different characters, including SpongeBob, from the popular animated television show. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 418/951 [02:38<05:15, 1.69it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_0.png'}, {'type': 'text', 'value': 'Are there any cheeses in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 419/951 [02:38<03:58, 2.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_1.png'}, {'type': 'text', 'value': 'Does this figure only contain SpongeBob?'}] +No, the figure does not only contain SpongeBob. It is a collage of various SpongeBob characters, including different expressions and poses. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 420/951 [02:39<04:52, 1.81it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_1.png'}, {'type': 'text', 'value': 'Are there any cheeses in this figure?'}] +Yes, there is a cheese figure in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 421/951 [02:39<04:18, 2.05it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/0_0.png'}, {'type': 'text', 'value': 'Is the sequence of the image moving?'}] +Yes, the sequence of the image is moving, as it shows a spiral pattern with circles and green and purple colors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 422/951 [02:40<04:39, 1.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/0_1.png'}, {'type': 'text', 'value': 'Is the sequence of the image moving?'}] +Yes, the sequence of the image is moving, as it shows a spiral pattern with circles and green and purple colors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 423/951 [02:41<04:51, 1.81it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 424/951 [02:41<04:56, 1.78it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson comes out of the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 425/951 [02:42<04:52, 1.80it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +No, the images are not in the correct order. The correct sequence of the images should be Homer Simpson walking into the bushes, Homer Simpson walking out of the bushes, Homer Simpson walking into the bushes, and Homer Simpson walking out of the bushes. The current sequence is Homer Simpson walking into the bushes, Homer Simpson walking out of the bushes, Homer Simpson walking into the bushes, and Homer Simpson walking out of the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 426/951 [02:44<09:34, 1.09s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson going from left to right, with each image showing him in a different stage of coming out of the bushes. The first image shows him looking at the camera, the second image shows him looking away, the third image shows him looking back, and the fourth image shows him fully emerging from the bushes. This progression of images captures the different stages of Homer's movement and adds a sense of motion to the scene. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 427/951 [02:46<12:47, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 428/951 [02:47<10:31, 1.21s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, Homer Simpson comes out of the bushes in the positive sequence images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 429/951 [02:48<08:50, 1.02s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +No, the images are not in the correct order. The correct sequence of the images should be: + +1. Homer Simpson disappears into the bushes. +2. Homer Simpson appears from the bushes. +3. Homer Simpson disappears into the bushes. +4. Homer Simpson appears from the bushes. +5. Homer Simpson disappears into the bushes. +6. Homer Simpson appears from the bushes. + +The current sequence is: + +1. Homer Simpson appears from the bushes. +2. Homer Simpson disappears into the bushes. +3. Homer Simpson appears from the bushes. +4. Homer Simpson disappears into the bushes. +5. Homer Simpson appears from the bushes. +6. Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 430/951 [02:51<16:26, 1.89s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson going from left to right, with the first image showing him in the bushes, the second image showing him coming out of the bushes, and the third image showing him standing in the grass. The fourth image shows him looking at the camera, and the fifth image shows him walking away. The sequence is consistent with the storyline of the cartoon, where Homer goes from hiding in the bushes to walking away. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 431/951 [02:54<17:33, 2.03s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 432/951 [02:54<13:30, 1.56s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson does come out of the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 433/951 [02:55<10:43, 1.24s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +No, the images are not in the correct order. The correct sequence of the images should be: + +1. Homer Simpson disappears into the bushes. +2. Homer Simpson appears from the bushes. +3. Homer Simpson disappears into the bushes. +4. Homer Simpson appears from the bushes. +5. Homer Simpson disappears into the bushes. +6. Homer Simpson appears from the bushes. + +The current sequence is: + +1. Homer Simpson appears from the bushes. +2. Homer Simpson disappears into the bushes. +3. Homer Simpson appears from the bushes. +4. Homer Simpson disappears into the bushes. +5. Homer Simpson appears from the bushes. +6. Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 434/951 [02:59<17:33, 2.04s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson coming out of the bushes, and the subsequent images show the same scene with different variations. The first image shows Homer Simpson in the bushes, the second image shows him walking out of the bushes, the third image shows him standing in the bushes, and the fourth image shows him walking out of the bushes. The sequence captures the progression of the scene, starting with Homer hiding in the bushes and ending with him walking out of them. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 435/951 [03:01<18:26, 2.14s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a dunk?'}] +Yes, the basketball player makes a dunk in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 436/951 [03:01<13:58, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a three-point shooting?'}] +Yes, the basketball player makes a three-point shooting in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 437/951 [03:02<10:49, 1.26s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the images are in the correct order. The sequence shows a basketball player dribbling the ball, followed by a player jumping in the air, and finally, a player falling to the ground. This sequence captures the progression of the basketball game, starting with the dribbling action, followed by the jump, and ending with the fall. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 438/951 [03:04<11:54, 1.39s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a dunk?'}] +Yes, the basketball player makes a dunk in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 439/951 [03:04<09:22, 1.10s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a three-point shooting?'}] +Yes, the basketball player makes a three-point shooting in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 440/951 [03:04<07:45, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the images are in the correct order. The sequence of the images shows the basketball player dribbling the ball, the defender attempting to steal the ball, and the player falling to the ground. This sequence captures the action and progression of the play. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 441/951 [03:06<08:32, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 442/951 [03:06<06:50, 1.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 443/951 [03:06<05:39, 1.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man opens the door. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + +The images are not in the correct order. The correct sequence should be: + +1. The man is standing in the hallway. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 444/951 [03:09<10:47, 1.28s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man closes the door. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + +The images are not in the correct order. The correct sequence should be: + +1. The man is standing in the hallway. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + +The man closes the door after the other three instances of him standing in the hallway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 445/951 [03:12<15:31, 1.84s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the last image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 446/951 [03:13<11:40, 1.39s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 447/951 [03:13<09:04, 1.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man is opening the door. +2. The man is standing in the hallway. +3. The man is looking at the camera. +4. The man is standing in the hallway. +5. The man is opening the door. + +The images are not in the correct order. The correct sequence should be: + +1. The man is opening the door. +2. The man is standing in the hallway. +3. The man is looking at the camera. +4. The man is standing in the hallway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 448/951 [03:15<12:20, 1.47s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man closes the door. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. + +The images are not in the correct order. The correct sequence should be: + +1. The man is standing in the hallway. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man closes the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 449/951 [03:18<14:16, 1.71s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 450/951 [03:18<10:49, 1.30s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 451/951 [03:18<08:24, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man opens the door. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. + +The images are not in the correct order. The correct sequence should be: + +1. The man is standing in the hallway. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man opens the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 452/951 [03:20<11:21, 1.37s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +1. The man closes the door. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + +The images are not in the correct order. The correct sequence should be: + +1. The man is standing in the hallway. +2. The man is standing in the hallway. +3. The man is standing in the hallway. +4. The man is standing in the hallway. +5. The man is standing in the hallway. + +The man closes the door in the last image, which is not the first image in the sequence. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 453/951 [03:24<16:00, 1.93s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 454/951 [03:24<12:04, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 455/951 [03:25<09:42, 1.17s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +In the image, the blue car is attempting to park, and it is shown in a sideways position. The correct sequence of the images would be the blue car first, followed by the yellow car, and then the other cars. The current sequence of the image shows the blue car in the middle, which is incorrect. The correct sequence should be the blue car first, followed by the yellow car, and then the other cars. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 456/951 [03:26<11:25, 1.39s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +In the image, the blue car is attempting to leave the parking space, and it is in the correct order. The sequence of the images shows the blue car moving out of the parking space, and the other cars are following the blue car. The other cars are in the correct order, as they are following the blue car's movement. The image captures the moment when the blue car is about to leave the parking space, and the other cars are positioned accordingly. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 457/951 [03:29<13:08, 1.60s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 458/951 [03:29<10:00, 1.22s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 459/951 [03:29<08:17, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +1. The blue car attempts to park. +2. The blue car is in the correct position. +3. The blue car is in the correct position. + +Based on the sequence of the images, the blue car is in the correct position in the first and third images, but not in the second image. Therefore, the correct order of the images is 1, 2, and 3. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 460/951 [03:31<10:18, 1.26s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +1. The blue car is in the parking space. +2. The blue car is attempting to leave the parking space. + +Based on the sequence of the images, the blue car is in the correct order. It is first shown in the parking space, and then it is attempting to leave the parking space. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 461/951 [03:33<11:10, 1.37s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▊ | 462/951 [03:33<08:38, 1.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▊ | 463/951 [03:34<07:16, 1.12it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +1. The blue car attempts to park. +2. The blue car is in the correct position. + +Based on the sequence of the images, the first image shows the blue car attempting to park, while the second image shows the blue car in the correct position. Therefore, the sequence is not in the correct order. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 464/951 [03:35<08:43, 1.07s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +In the image, the blue car is attempting to leave the parking space, and it is shown in a sequence of three different positions. The first position shows the car in the parking space, the second position shows the car in the process of leaving the space, and the third position shows the car outside the parking space. The sequence of the images is not in the correct order, as the first position should be the third position, and the second position should be the second position. The correct sequence would be: + +1. The blue car is in the parking space. +2. The blue car is in the process of leaving the parking space. +3. The blue car is outside the parking space. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 465/951 [03:38<13:33, 1.67s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to put on the clothes?'}] +Yes, the baby attempts to put on the clothes in the sequence of images. The baby is shown in different stages of putting on a sweater, with the first image showing the baby holding the sweater, the second image showing the baby putting on the sweater, and the third image showing the baby wearing the sweater. This sequence of images captures the baby's progress in putting on the sweater, from holding it to wearing it. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 466/951 [03:40<14:16, 1.77s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to take off the clothes?'}] +Yes, the baby in the sequence of images is attempting to take off their clothes. The baby is shown in different stages of undressing, from being fully dressed to being half-naked and finally completely naked. This sequence of images captures the baby's progress in removing their clothing, which is a common and amusing sight in young children. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 467/951 [03:42<13:54, 1.72s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'The baby attempts to put on the clothes. According to the positive sequence of the images, are they in the correct order?'}] +1. The baby is wearing a white shirt and blue jeans. +2. The baby is wearing a blue shirt and blue jeans. +3. The baby is wearing a black shirt and blue jeans. +4. The baby is wearing a black shirt and blue jeans. + +The images are not in the correct order. The correct sequence should be: + +1. The baby is wearing a white shirt and blue jeans. +2. The baby is wearing a blue shirt and blue jeans. +3. The baby is wearing a black shirt and blue jeans. +4. The baby is wearing a black shirt and blue jeans. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 468/951 [03:45<17:36, 2.19s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'The baby attempts to take off the clothes. According to the positive sequence of the images, are they in the correct order?'}] +1. The baby is wearing clothes. +2. The baby is taking off the clothes. +3. The baby is taking off the clothes. +4. The baby is taking off the clothes. + +The images are in the correct order, as the baby is shown in various stages of taking off their clothes. The first image shows the baby wearing clothes, the second image shows the baby in the process of taking off the clothes, and the third and fourth images show the baby completely naked. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 469/951 [03:47<17:38, 2.20s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to put on the clothes?'}] +Yes, the baby attempts to put on the clothes in the sequence of images. The baby is shown in different stages of putting on a jacket, with the jacket being partially on, fully on, and even being thrown off. This sequence of images captures the baby's progress in putting on the jacket, showcasing the baby's actions and the process of dressing up. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 470/951 [03:49<16:29, 2.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to take off the clothes?'}] +Yes, the baby attempts to take off the clothes in the sequence of images. The baby is shown in different stages of undressing, from being fully dressed to being half-naked, and finally completely naked. This sequence of images captures the baby's progress in removing their clothing. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 471/951 [03:51<14:56, 1.87s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'The baby attempts to put on the clothes. According to the positive sequence of the images, are they in the correct order?'}] +1. The baby is wearing a jacket. +2. The baby is wearing a jacket and jeans. +3. The baby is wearing a jacket and jeans. +4. The baby is wearing a jacket and jeans. + +The images are in the correct order, as the baby is shown wearing a jacket and jeans in each of the four images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 472/951 [03:52<14:51, 1.86s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'The baby attempts to take off the clothes. According to the positive sequence of the images, are they in the correct order?'}] +1. The baby is wearing a jacket and jeans. +2. The baby is taking off the jacket. +3. The baby is wearing a shirt. +4. The baby is taking off the shirt. +5. The baby is wearing jeans. + +The images are not in the correct order. The correct sequence should be: + +1. The baby is wearing a jacket and jeans. +2. The baby is taking off the jacket. +3. The baby is wearing a shirt. +4. The baby is taking off the shirt. +5. The baby is wearing jeans. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 473/951 [03:55<17:28, 2.19s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature increase?'}] +Yes, according to the positive sequence of the images, the temperature increases. The first image shows a red thermometer, which indicates a high temperature, while the second image shows a blue thermometer, which indicates a lower temperature. The third image shows a blue thermometer with a red line, which indicates a higher temperature than the second image. This sequence suggests that the temperature increases as the images progress. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 474/951 [03:57<16:17, 2.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature decrease?'}] +Yes, according to the positive sequence of the images, the temperature decreases. The first image shows a high temperature, while the subsequent images show lower temperatures. This progression indicates that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 475/951 [03:58<14:12, 1.79s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'The temperature increases. According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the temperature increases in the correct order. The image sequence shows the temperature increasing from left to right, starting with a low temperature and ending with a higher temperature. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 476/951 [03:59<11:53, 1.50s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'The temperature decreases. According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the temperature decreases in the correct order. The image sequence shows the temperature decreasing from the highest to the lowest value. The first image shows the highest temperature, the second image shows a slightly lower temperature, and the third image shows the lowest temperature. This sequence is consistent with the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 477/951 [04:01<11:47, 1.49s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature increase?'}] +Yes, according to the positive sequence of the images, the temperature increases. The first image shows a red line, which represents a high temperature, and the subsequent images show a blue line, which represents a lower temperature. This progression indicates that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 478/951 [04:02<11:28, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature decrease?'}] +Yes, according to the positive sequence of the images, the temperature decreases. The first image shows a high temperature, while the second and third images show lower temperatures. This progression suggests that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 479/951 [04:03<10:53, 1.38s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'The temperature increases. According to the positive sequence of the images, are they in the correct order?'}] +1. The temperature is at 0 degrees Celsius. +2. The temperature is at 20 degrees Celsius. +3. The temperature is at 40 degrees Celsius. + +The correct order of the images is 1, 2, and 3, as the temperature increases from 0 to 40 degrees Celsius. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 480/951 [04:05<11:31, 1.47s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'The temperature decreases. According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the temperature decreases in the correct order. The image shows a decrease in temperature from red to blue, indicating a decrease in heat. The sequence of the images is consistent with the natural progression of temperature, starting from a high point (red) and ending at a low point (blue). + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 481/951 [04:06<11:13, 1.43s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug put into the power outlet?'}] +No, the plug is not yet put into the power outlet. The image shows a series of plugs and outlets, but the plugs are not yet connected to the outlets. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 482/951 [04:07<09:53, 1.26s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug removed from the power outlet?'}] +Yes, the plug is removed from the power outlet in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 483/951 [04:07<07:55, 1.02s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'The plug is put into the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +1. The plug is put into the power outlet. +2. The plug is plugged into the outlet. +3. The plug is plugged into the outlet. +4. The plug is plugged into the outlet. +5. The plug is plugged into the outlet. + +The images are in the correct order, as they show the progression of the plug being inserted into the power outlet. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 484/951 [04:09<10:07, 1.30s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'The plug is removed from the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +1. The plug is removed from the power outlet. +2. The plug is inserted into the power outlet. +3. The plug is connected to the power outlet. +4. The plug is connected to the power outlet. +5. The plug is connected to the power outlet. + +The images are not in the correct order. The correct sequence should be: + +1. The plug is connected to the power outlet. +2. The plug is connected to the power outlet. +3. The plug is connected to the power outlet. +4. The plug is connected to the power outlet. +5. The plug is connected to the power outlet. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 485/951 [04:12<14:07, 1.82s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug put into the power outlet?'}] +No, the plug is not yet put into the power outlet. The image shows a row of plugs and outlets, but the plugs are not yet connected to the outlets. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 486/951 [04:13<11:55, 1.54s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug removed from the power outlet?'}] +Yes, the plug is removed from the power outlet in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 487/951 [04:14<09:21, 1.21s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'The plug is put into the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +1. The plug is put into the power outlet. +2. The plug is put into the power outlet. +3. The plug is put into the power outlet. +4. The plug is put into the power outlet. +5. The plug is put into the power outlet. + +The sequence of the images is correct, as the plug is being inserted into the power outlet in a continuous loop. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████▏ | 488/951 [04:16<10:59, 1.42s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'The plug is removed from the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +1. The plug is removed from the power outlet. +2. The plug is inserted into the power outlet. +3. The plug is connected to the power outlet. +4. The plug is connected to the power outlet. +5. The plug is connected to the power outlet. + +The correct order of the images is 2, 3, 4, 5, 1. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████▏ | 489/951 [04:18<11:57, 1.55s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving forward?'}] +Yes, the blue car is moving forward in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 490/951 [04:18<09:19, 1.21s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving backward?'}] +Yes, the blue car is moving backward in the sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 491/951 [04:18<07:29, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'The blue car is moving forward. According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the blue car is moving forward, and the sequence of the images is correct. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 492/951 [04:19<06:22, 1.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'The blue car is moving backward. According to the positive sequence of the images, are they in the correct order?'}] +1. No, the blue car is moving backward, so it should be in the sequence after the red car. + +The correct sequence of the images should be: + +1. Red car +2. White car +3. Blue car +4. White car +5. Red car + +The current sequence is: + +1. Red car +2. White car +3. Blue car +4. White car +5. Red car + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 493/951 [04:21<08:57, 1.17s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving forward?'}] +Yes, the blue car is moving forward in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 494/951 [04:21<07:18, 1.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving backward?'}] +Yes, the blue car is moving backward in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 495/951 [04:22<06:06, 1.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'The blue car is moving forward. According to the positive sequence of the images, are they in the correct order?'}] +1. Yes, the blue car is moving forward, and the sequence of the images is correct. The blue car is the first car in the sequence, followed by the red car, and then the white car. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 496/951 [04:23<06:35, 1.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'The blue car is moving backward. According to the positive sequence of the images, are they in the correct order?'}] +1. No, the blue car is moving backward, so it should be in the sequence after the red car. + +The correct sequence of the images should be: + +1. Red car +2. White car +3. Blue car +4. White car +5. Red car + +The current sequence is: + +1. Red car +2. White car +3. Blue car +4. White car +5. Red car + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 497/951 [04:25<09:03, 1.20s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical anticlockwise? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 498/951 [04:25<07:03, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical clockwise? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 499/951 [04:25<05:42, 1.32it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'The circle inside is autobiographical anticlockwise. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 500/951 [04:26<04:45, 1.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical anticlockwise? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 501/951 [04:26<03:59, 1.88it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical clockwise? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 502/951 [04:26<03:26, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'The circle inside is autobiographical anticlockwise. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 503/951 [04:27<03:07, 2.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 504/951 [04:27<02:58, 2.51it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 505/951 [04:27<02:52, 2.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 506/951 [04:28<02:50, 2.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 507/951 [04:28<02:53, 2.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 508/951 [04:29<02:54, 2.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 509/951 [04:29<02:54, 2.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 510/951 [04:29<02:57, 2.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 511/951 [04:30<02:54, 2.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 512/951 [04:30<02:51, 2.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 513/951 [04:30<02:47, 2.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 514/951 [04:31<02:47, 2.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 515/951 [04:31<02:48, 2.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 516/951 [04:32<02:47, 2.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 517/951 [04:32<03:04, 2.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 518/951 [04:33<03:07, 2.31it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 519/951 [04:33<03:04, 2.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 520/951 [04:33<03:00, 2.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 521/951 [04:34<02:57, 2.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 522/951 [04:34<02:55, 2.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 523/951 [04:35<02:53, 2.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 524/951 [04:35<02:52, 2.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 525/951 [04:35<02:58, 2.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 526/951 [04:36<03:15, 2.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 527/951 [04:36<03:09, 2.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 528/951 [04:37<03:00, 2.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 529/951 [04:37<02:53, 2.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 530/951 [04:38<02:46, 2.52it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 531/951 [04:38<02:49, 2.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 532/951 [04:38<02:46, 2.52it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to left? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 533/951 [04:39<02:43, 2.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 534/951 [04:39<02:33, 2.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 535/951 [04:39<02:26, 2.85it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to left? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 536/951 [04:40<02:23, 2.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a dog in this video? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 537/951 [04:40<02:27, 2.80it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a sloth in this video? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 538/951 [04:40<02:27, 2.80it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a cat in this video? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 539/951 [04:41<02:29, 2.75it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one word.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 540/951 [04:41<02:37, 2.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one word.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 541/951 [04:42<02:44, 2.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 542/951 [04:42<02:55, 2.32it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 543/951 [04:43<02:51, 2.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one sentence.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 544/951 [04:43<02:46, 2.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one sentence.'}] +1. No, they are not skating to the right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 545/951 [04:44<03:10, 2.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 546/951 [04:44<03:00, 2.25it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 547/951 [04:44<02:53, 2.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one sentence.'}] +0 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 548/951 [04:45<02:47, 2.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one sentence.'}] +1. No, they are not skating to the right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 549/951 [04:45<03:11, 2.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 550/951 [04:46<03:01, 2.21it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 551/951 [04:46<02:54, 2.30it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 552/951 [04:47<02:44, 2.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 553/951 [04:47<02:40, 2.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 554/951 [04:47<02:35, 2.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 555/951 [04:48<02:28, 2.67it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 556/951 [04:48<02:31, 2.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▊ | 557/951 [04:48<02:17, 2.87it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▊ | 558/951 [04:49<02:03, 3.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 559/951 [04:49<01:56, 3.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting closer? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 560/951 [04:49<02:10, 3.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting far away? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 561/951 [04:50<02:16, 2.86it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'This cartoon character getting closer. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +1. Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 562/951 [04:50<02:28, 2.63it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'This cartoon character getting further away. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 4 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 563/951 [05:32<1:23:22, 12.89s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting closer? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 564/951 [05:33<59:08, 9.17s/it] struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting far away? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 565/951 [05:33<42:02, 6.53s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'This cartoon character getting closer. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +1. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 566/951 [05:33<30:07, 4.69s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'This cartoon character getting further away. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 4 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 567/951 [06:15<1:41:47, 15.90s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +1 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 568/951 [06:16<1:11:45, 11.24s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 569/951 [06:16<50:43, 7.97s/it] struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 570/951 [06:17<36:14, 5.71s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 571/951 [06:17<26:00, 4.11s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +3 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 572/951 [06:17<18:47, 2.97s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 573/951 [06:18<13:44, 2.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 574/951 [06:18<10:21, 1.65s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 575/951 [06:18<07:56, 1.27s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +3 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 576/951 [06:19<06:09, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 577/951 [06:19<04:54, 1.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 578/951 [06:19<04:03, 1.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 579/951 [06:20<03:28, 1.79it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 580/951 [06:20<03:07, 1.97it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 581/951 [06:20<02:52, 2.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 582/951 [06:21<02:43, 2.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████▏ | 583/951 [06:21<02:40, 2.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████▏ | 584/951 [06:22<02:40, 2.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 585/951 [06:22<02:48, 2.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 586/951 [06:23<02:40, 2.28it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 587/951 [06:23<02:36, 2.32it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 588/951 [06:23<02:31, 2.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 589/951 [06:24<02:29, 2.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 590/951 [06:24<02:28, 2.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 591/951 [06:25<02:27, 2.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is China, Hongkong SAR, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, China, Hongkong SAR is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 592/951 [06:25<03:14, 1.85it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is Switzerland, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, Switzerland is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 593/951 [06:26<03:33, 1.68it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is France, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, France is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 594/951 [06:27<03:44, 1.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is the United States, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, the United States is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 595/951 [06:28<03:58, 1.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2019, Is 2010 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries from 2001 to 2019. The value of these goods exported from the UK increased over the years, with the highest value being in 2019. This indicates that the UK is a significant player in the global market for these baked goods. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 596/951 [06:30<06:14, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2019, Is 2019 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that in 2019, the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries. The value of these goods exported from the UK in 2019 was approximately 1,000,000 GBP. This information is presented in a graph that shows the value of these goods exported from the UK from 2001 to 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 597/951 [06:32<08:10, 1.38s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2010, Is 2010 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries from 2001 to 2010. The value of these goods exported from the UK increased significantly during this period, reaching a peak in 2009. The export value of these goods has been steadily increasing since 2001, with a notable increase in 2009. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 598/951 [06:34<09:24, 1.60s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2010, Is 2005 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, from 2001 to 2010, the UK exported the most value of bread, biscuits, wafers, cakes, and pastries in 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 599/951 [06:35<08:24, 1.43s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2000 to 2019, Is 2010 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +2010 exported the least value of bread, biscuits, wafers, cakes, and pastries from the UK. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 600/951 [06:36<07:06, 1.22s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2000 to 2019, Is 2019 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +2019 exported the least value of bread, biscuits, wafers, cakes, and pastries from the UK. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 601/951 [06:36<06:12, 1.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2010 to 2019, Is 2010 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, from 2010 to 2019, the UK exported the least value of bread, biscuits, wafers, cakes, and pastries in 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 602/951 [06:37<06:05, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2010 to 2019, Is 2015 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +2015 exported the least value of bread, biscuits, wafers, cakes, and pastries from the UK. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 603/951 [06:38<05:33, 1.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2000?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2000, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 604/951 [06:39<05:11, 1.11it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2005?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2005, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2005, the population in this age group is the highest, indicating that it was a significant year for the country's demographics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 605/951 [06:41<07:04, 1.23s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2030?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2030, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2030, the population in this age group is at its peak, indicating that it is the most populous age group in China during that time. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 606/951 [06:43<08:25, 1.47s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2050?'}] +Yes, the population aged between 15 and 29 years in China is expected to be the highest in 2050, as shown in the graph. The graph shows a significant increase in the population aged between 15 and 29 years from 2000 to 2050. This indicates that the population in China is growing rapidly, and the country is likely to experience a significant demographic shift in the coming decades. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 607/951 [06:45<09:20, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2000?'}] +15-29 years old population in China from 2000 to 2050 is the least in 2000. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 608/951 [06:46<07:45, 1.36s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2005?'}] +2005 is the year with the lowest population aged between 15 and 29 years in China, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2005, the population in this age group is the lowest, with only 14.5 million people falling into this category. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 609/951 [06:48<08:39, 1.52s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2030?'}] +2030 is the year with the lowest population aged between 15 and 29 years in China, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2030, the population in this age group is the lowest, with only 1.02 billion people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 610/951 [06:49<09:08, 1.61s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2050?'}] +15-29 years old population in China from 2000 to 2050. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 611/951 [06:50<07:19, 1.29s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does China have the largest population in the world, followed by India and then the USA?'}] +According to the chart, China has the largest population in the world, followed by India, and then the USA. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 612/951 [06:50<06:05, 1.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does India have the second largest population in the world?'}] +Yes, according to the chart, India has the second largest population in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 613/951 [06:51<05:00, 1.12it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does UK have the largest population in the world, followed by China and USA?'}] +According to the chart, the United States has the largest population in the world, followed by China and India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 614/951 [06:51<04:25, 1.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does China have the second largest population in the world?'}] +Yes, according to the chart, China has the second largest population in the world, with a population of approximately 1,379,600,000 people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 615/951 [06:52<04:30, 1.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does China have the largest population in the world, followed by India and then the USA?'}] +According to the chart, China has the largest population in the world, followed by India, and then the USA. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 616/951 [06:53<04:11, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does India have the second largest population in the world?'}] +According to the chart, India has the second largest population in the world, with a population of approximately 1,366,417,295 people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 617/951 [06:54<04:17, 1.30it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does UK have the largest population in the world, followed by China and USA?'}] +According to the chart, the UK does not have the largest population in the world. Instead, it is the third largest country in terms of population, behind China and the United States. The chart shows that the UK has a population of approximately 115 million people, while China has a population of over 1.4 billion people and the United States has a population of around 330 million people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 618/951 [06:56<06:08, 1.11s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does China have the second largest population in the world?'}] +Yes, according to the chart, China has the second largest population in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 619/951 [06:56<05:02, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is China the third largest country by land area in the world?'}] +Yes, according to the chart, China is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 620/951 [06:57<04:26, 1.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is US the third largest country by land area in the world?'}] +Yes, according to the chart, the United States is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 621/951 [06:57<04:06, 1.34it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is US the largest country by land area in the world?'}] +According to the chart, the United States is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 622/951 [06:58<03:41, 1.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is Russia the largest country by land area in the world?'}] +According to the chart, Russia is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 623/951 [06:58<03:21, 1.63it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is China the third largest country by land area in the world?'}] +Yes, according to the chart, China is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 624/951 [06:59<03:12, 1.70it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is US the third largest country by land area in the world?'}] +According to the chart, the United States is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 625/951 [06:59<03:05, 1.76it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is US the largest country by land area in the world?'}] +According to the chart, the United States is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 626/951 [07:00<02:58, 1.82it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is Russia the largest country by land area in the world?'}] +According to the chart, Russia is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 627/951 [07:00<02:53, 1.87it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Asian families have the highest real median household income in the United States, with White, Hispanic, and Black households following respectively?'}] +2019 data shows that Asian families had the highest real median household income in the United States, with White, Hispanic, and Black households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 628/951 [07:01<03:28, 1.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black families have the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively?'}] +2019 data shows that Black families had the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 629/951 [07:02<03:55, 1.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black and White households represent the only racial groups with median incomes surpassing the national average in the United States, while Hispanic and Asian households had median incomes below the average?'}] +2019 data shows that Black and White households were the only racial groups with median incomes surpassing the national average in the United States. Hispanic and Asian households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 630/951 [07:03<04:31, 1.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Hispanic and Asian households represent the only racial groups with median incomes surpassing the national average in the United States, while Black and White households had median incomes below the average?'}] +2019 data shows that Hispanic and Asian households were the only racial groups with median incomes surpassing the national average in the United States. In contrast, Black and White households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▋ | 631/951 [07:04<04:53, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Asian families have the highest real median household income in the United States, with White, Hispanic, and Black households following respectively?'}] +2019 data shows that Asian families had the highest real median household income in the United States, with White, Hispanic, and Black households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▋ | 632/951 [07:05<04:51, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black families have the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively?'}] +2019 data shows that Black families had the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 633/951 [07:06<04:42, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black and White households represent the only racial groups with median incomes surpassing the national average in the United States, while Hispanic and Asian households had median incomes below the average?'}] +2019 data shows that Black and White households were the only racial groups with median incomes surpassing the national average in the United States. Hispanic and Asian households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 634/951 [07:07<04:55, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Hispanic and Asian households represent the only racial groups with median incomes surpassing the national average in the United States, while Black and White households had median incomes below the average?'}] +2019 data shows that Hispanic and Asian households were the only racial groups with median incomes surpassing the national average in the United States. In contrast, Black and White households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 635/951 [07:08<05:13, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from the Americas?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from the Americas. The chart shows that the majority of Apple's revenue came from Europe, with a significant portion also coming from Asia. The Americas, including the United States, contributed to a smaller portion of Apple's revenue during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 636/951 [07:10<06:15, 1.19s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Europe?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from Europe. The chart shows that the majority of Apple's revenue came from the Americas, with Europe being the second-largest contributor. The Americas accounted for approximately 50% of Apple's revenue, while Europe accounted for around 25%. The remaining 25% of Apple's revenue came from other regions around the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 637/951 [07:12<07:51, 1.50s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Greater China?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from Greater China. In the image, it is shown that the majority of Apple's revenue distribution came from Greater China, with the region accounting for 50% or more of the company's revenue in each year. This indicates that Apple has a strong presence and significant market share in the region, and its revenue growth in Greater China has been a significant contributor to the company's overall financial performance. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 638/951 [07:14<09:10, 1.76s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Japan?'}] +From 2012 to 2022, Apple derived the majority of its revenue from Japan. In the image, the revenue distribution in different regions worldwide is shown, and it is evident that Japan is the top contributor to Apple's revenue. The chart displays the percentage of revenue generated by each region, and Japan stands out as the region with the highest percentage of revenue. This indicates that Apple has a strong presence and a significant market share in Japan, which has likely contributed to its overall global success. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 639/951 [07:17<09:56, 1.91s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from the Americas?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from the Americas. The chart shows that the majority of Apple's revenue came from Europe, with the Americas being the second-largest contributor. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 640/951 [07:18<08:59, 1.73s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Europe?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from Europe. The chart shows that the majority of Apple's revenue came from the United States, with Europe being the second-largest contributor. The chart also shows that Apple's revenue distribution varied across different regions worldwide, with the United States, Europe, and Asia being the main contributors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 641/951 [07:20<09:08, 1.77s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Greater China?'}] +2012 to 2022, Apple derived the majority of its revenue from Greater China. In the image, the revenue distribution in different regions worldwide is shown, and it is evident that Greater China has been the primary source of revenue for Apple during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 642/951 [07:21<08:24, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Japan?'}] +From 2012 to 2022, Apple derived the majority of its revenue from Japan. In the image, the revenue distribution in different regions worldwide is shown, and it is evident that Japan is the top contributor to Apple's revenue. This information is based on the data provided in the graph, which shows the percentage of revenue generated by each region. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 643/951 [07:23<08:30, 1.66s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the U.S. Central Bank higher than those of the Central Banks in the UK, Eurozone, and Japan?'}] +Yes, in 2019, the main policy interest rates of the U.S. Central Bank were higher than those of the Central Banks in the UK, Eurozone, and Japan. The U.S. Federal Reserve raised its policy interest rate four times in 2018, while the Bank of England, the European Central Bank, and the Bank of Japan did not raise their rates at all. This indicates that the U.S. Central Bank was more aggressive in tightening monetary policy in 2018 than the other central banks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 644/951 [07:25<09:47, 1.91s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the UK higher than those of the U.S. Central Bank , Eurozone, and Japan?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the UK were higher than those of the U.S. Central Bank, Eurozone, and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 645/951 [07:26<08:19, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the Eurozone higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the Eurozone were higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 646/951 [07:27<07:24, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Japan Central Bank higher than those of the Central Banks in the UK, Eurozone, and U.S.?'}] +Yes, in 2019, the main policy interest rates of the Japan Central Bank were higher than those of the Central Banks in the UK, Eurozone, and U.S. The image shows a graph comparing the interest rates of these four central banks, with the Japan Central Bank having the highest rate among them. This indicates that the Japan Central Bank was more aggressive in managing monetary policy and controlling inflation in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 647/951 [07:30<08:15, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the U.S. Central Bank higher than those of the Central Banks in the UK, Eurozone, and Japan, according to the image?'}] +Yes, the image shows that the main policy interest rates of the U.S. Central Bank were higher than those of the Central Banks in the UK, Eurozone, and Japan in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 648/951 [07:31<07:16, 1.44s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the UK higher than those of the U.S. Central Bank , Eurozone, and Japan, according to the image?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the UK were higher than those of the U.S. Central Bank, Eurozone, and Japan, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 649/951 [07:32<06:36, 1.31s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the Eurozone higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan, according to the image?'}] +Yes, the image shows that the main policy interest rates of the Central Banks in the Eurozone were higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 650/951 [07:33<06:17, 1.25s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Japan Central Bank higher than those of the Central Banks in the UK, Eurozone, and U.S., according to the image?'}] +Yes, the image shows that the main policy interest rates of the Japan Central Bank were higher than those of the Central Banks in the UK, Eurozone, and U.S. in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 651/951 [07:34<05:50, 1.17s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Harry Kane the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Harry Kane was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▊ | 652/951 [07:34<04:56, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Cristiano Ronaldo the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Cristiano Ronaldo was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▊ | 653/951 [07:35<04:23, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Antoine Griezmann the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, according to the image, Antoine Griezmann was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 654/951 [07:36<04:03, 1.22it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Harry Kane the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Harry Kane was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 655/951 [07:36<03:43, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Cristiano Ronaldo the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Cristiano Ronaldo was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 656/951 [07:37<03:29, 1.41it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Antoine Griezmann the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, according to the image, Antoine Griezmann was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 657/951 [07:37<03:26, 1.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did the United States have the largest GDP around the world, followed by China, and Japan, according to the image?'}] +Yes, according to the image, the United States had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 658/951 [07:38<03:29, 1.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did China have the largest GDP around the world, followed by the United States, and Japan, according to the image?'}] +Yes, according to the image, in 2020, China had the largest GDP among the countries shown, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 659/951 [07:39<03:33, 1.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did Japan have the largest GDP around the world, followed by the United States, and China, according to the image?'}] +In 2020, Japan had the largest GDP among the countries shown in the image, followed by the United States and China. The image displays a chart showing the share of the world's GDP in 2020, with each country's GDP represented by a bar. Japan's GDP bar is the tallest, followed by the United States and then China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 660/951 [07:41<05:03, 1.04s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did India have the largest GDP around the world, followed by China and Japan, according to the image?'}] +Yes, according to the image, India had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 661/951 [07:41<04:30, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did the United States have the largest GDP around the world, followed by China, and Japan, according to the image?'}] +Yes, according to the image, the United States had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 662/951 [07:42<04:26, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did China have the largest GDP around the world, followed by the United States, and Japan, according to the image?'}] +Yes, according to the image, in 2020, China had the largest GDP among the countries shown, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 663/951 [07:43<04:11, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did Japan have the largest GDP around the world, followed by the United States, and China, according to the image?'}] +In 2020, Japan had the largest GDP among the countries shown in the image, followed by the United States and China. The image displays a chart showing the share of the world's GDP in 2020, with each country's GDP represented by a bar. Japan's GDP bar is the tallest, followed by the United States and China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 664/951 [07:45<05:25, 1.13s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did India have the largest GDP around the world, followed by China and Japan, according to the image?'}] +Yes, according to the image, India had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 665/951 [07:45<04:47, 1.00s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were white individuals the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively?'}] +According to the image, the largest population group in the United States in 2020 was white individuals, making up 62.4% of the population. Latinos and African Americans were the second and third largest groups, respectively, with 18.7% and 13.4% of the population. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 666/951 [07:47<05:23, 1.13s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were African Americans the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively?'}] +According to the image, African Americans were the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 667/951 [07:48<04:59, 1.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were Latinos the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +According to the image, the largest population group in the United States in 2020 was Latinos, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 668/951 [07:49<04:41, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were Asians the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Asians were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 669/951 [07:50<04:34, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were white individuals the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively?'}] +According to the image, the largest population group in the United States in 2020 was white individuals, followed by Latinos and African Americans. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 670/951 [07:50<04:14, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were African Americans the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively?'}] +According to the image, African Americans were the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 671/951 [07:51<04:10, 1.12it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were Latinos the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +According to the image, the largest population group in the United States in 2020 was Latinos, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 672/951 [07:52<04:15, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were Asians the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Asians were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 673/951 [07:53<04:18, 1.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/11_1.png'}, {'type': 'text', 'value': "According to the image, between 2011 and 2020, was 2020 the year when China's exports to the United States reached their highest value?"}] +2020 was not the year when China's exports to the United States reached their highest value. The image shows that the highest value of exports from China to the United States was in 2011, with a total of $1.15 trillion. The value of exports from China to the United States has been steadily increasing since then, but it has not reached the peak of $1.15 trillion again. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 674/951 [07:55<05:58, 1.29s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/11_1.png'}, {'type': 'text', 'value': "According to the image, did China's exports to the United States experience a decrease from 2016 to 2018?"}] +According to the image, China's exports to the United States did not experience a decrease from 2016 to 2018. In fact, the data shows that the exports from China to the United States increased during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 675/951 [07:56<05:44, 1.25s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was the United States the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan?'}] +Yes, according to the image, in 2013, the United States was the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 676/951 [07:57<05:22, 1.17s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Hong Kong the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan?'}] +Yes, according to the image, in 2013, Hong Kong was the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 677/951 [07:58<05:01, 1.10s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Japn the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong?'}] +Yes, according to the image, in 2013, Japan was the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████▏ | 678/951 [07:59<04:43, 1.04s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was the United States the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan?'}] +Yes, according to the image, in 2013, the United States was the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████▏ | 679/951 [08:00<04:39, 1.03s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Hong Kong the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan?'}] +Yes, according to the image, in 2013, Hong Kong was the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 680/951 [08:01<04:27, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Japn the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong?'}] +Yes, according to the image, in 2013, Japan was the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 681/951 [08:02<04:26, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_1.png'}, {'type': 'text', 'value': 'According to the image, between March 2020 and December 2021, did the United States experience the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020?'}] +Yes, the United States experienced the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020. The image shows that the peak average number of daily reported COVID-19 deaths occurred in December 2020, with an average of 3,000 deaths per day. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 682/951 [08:04<05:32, 1.24s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_1.png'}, {'type': 'text', 'value': 'According to the image, had the total number of coronavirus deaths in the United States reached 937,000 by February 2021?'}] +Yes, according to the image, if the total number of coronavirus deaths in the United States had reached 937,000 by February 2021, it would be a significant milestone in the pandemic. The current number of deaths in the United States is significantly lower than this, with the actual number of deaths being around 470,000 as of February 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 683/951 [08:06<06:27, 1.45s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_2.png'}, {'type': 'text', 'value': 'According to the image, between March 2020 and December 2021, did the United States experience the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020?'}] +Yes, the image shows that the United States experienced the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020. The peak occurred in April 2020, with an average of 2,200 daily reported deaths. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 684/951 [08:07<06:39, 1.50s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_2.png'}, {'type': 'text', 'value': 'According to the image, had the total number of coronavirus deaths in the United States reached 937,000 by February 2021?'}] +Yes, according to the image, if the total number of coronavirus deaths in the United States had reached 937,000 by February 2021, it would be a significant milestone in the pandemic. The image shows a graph with a line that represents the number of daily reported coronavirus deaths in the United States, and it is currently at around 4,000. If the line were to continue to rise and reach 937,000 by February 2021, it would indicate a much more severe and widespread outbreak of the virus in the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 685/951 [08:10<08:21, 1.89s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did the Soviet Union suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the Soviet Union suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 686/951 [08:11<07:03, 1.60s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did the United States suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the United States suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 687/951 [08:12<05:56, 1.35s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did United Kingdom experience the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland?'}] +According to the image, the United Kingdom experienced the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 688/951 [08:13<05:24, 1.23s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did the Soviet Union suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the Soviet Union suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 689/951 [08:14<05:08, 1.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did the United States suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the United States suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 690/951 [08:15<04:39, 1.07s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did United Kingdom experience the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland?'}] +According to the image, the United Kingdom experienced the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 691/951 [08:16<04:22, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_1.png'}, {'type': 'text', 'value': 'According to the image, did the global death toll from earthquakes surpass 200,000 in any year between 2000 and 2015?'}] +2015 was the year with the highest global death toll from earthquakes, reaching 200,000. The image shows a graph displaying the number of global deaths due to earthquakes from 2000 to 2015. The data indicates that the global death toll from earthquakes surpassed 200,000 in 2015. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 692/951 [08:18<05:36, 1.30s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_1.png'}, {'type': 'text', 'value': 'According to the image, did the year 2004 witness a higher global death toll due to earthquakes than 2005?'}] +2004 witnessed a higher global death toll due to earthquakes than 2005. The image shows a graph displaying the number of global deaths due to earthquakes from 2000 to 2015. In 2004, there were 2,929 deaths, while in 2005, the number of deaths was 2,888. This indicates that the year 2004 experienced a higher global death toll due to earthquakes than 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 693/951 [08:20<07:11, 1.67s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_2.png'}, {'type': 'text', 'value': 'According to the image, did the global death toll from earthquakes surpass 200,000 in any year between 2000 and 2009?'}] +2005 was the only year in the given time period (2000-2009) where the global death toll from earthquakes surpassed 200,000. The image shows that in 2005, the global death toll from earthquakes was 200,000, which is significantly higher than the other years in the period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 694/951 [08:22<07:28, 1.74s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_2.png'}, {'type': 'text', 'value': 'According to the image, did the year 2004 witness a higher global death toll due to earthquakes than 2005?'}] +2004 witnessed a higher global death toll due to earthquakes than 2005. The image shows a bar graph displaying the number of global deaths due to earthquakes from 2000 to 2015. In 2004, there were 1,100 deaths, while in 2005, there were 900 deaths. This indicates that the year 2004 experienced a higher global death toll due to earthquakes than 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 695/951 [08:25<08:24, 1.97s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_1.png'}, {'type': 'text', 'value': 'According to the image, does DJI hold more than 50% of the commercial drone brand market share in 2021?'}] +According to the image, DJI holds more than 50% of the commercial drone brand market share in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 696/951 [08:25<06:56, 1.63s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_1.png'}, {'type': 'text', 'value': 'According to the image, is the combined market share of Autel, FreeFly, Skydio, and Parrot greater than the market share of DJI alone in 2021?'}] +Yes, the combined market share of Autel, FreeFly, Skydio, and Parrot is greater than the market share of DJI alone in 2021. The image shows that the combined market share of these four brands is approximately 35%, while DJI's market share is around 55%. This indicates that these four brands have a significant presence in the commercial drone market, and their combined market share is larger than DJI's share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 697/951 [08:28<07:36, 1.80s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_2.png'}, {'type': 'text', 'value': 'According to the image, does DJI hold more than 50% of the commercial drone brand market share in 2021?'}] +According to the image, DJI holds more than 50% of the commercial drone brand market share in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 698/951 [08:28<06:17, 1.49s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_2.png'}, {'type': 'text', 'value': 'According to the image, is the combined market share of Autel, FreeFly, Skydio, and Parrot greater than the market share of DJI alone in 2021?'}] +Yes, the combined market share of Autel, FreeFly, Skydio, and Parrot is greater than the market share of DJI alone in 2021. The image shows that Autel, FreeFly, Skydio, and Parrot together have a 45% market share, while DJI has a 55% market share. This indicates that these four brands have a significant presence in the commercial drone market, while DJI remains the dominant player. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 699/951 [08:31<07:07, 1.70s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': "According to the image, is Mark Zuckerberg'swealth greater than Larry Ellison's on 13th March 2020?"}] +Yes, according to the image, Mark Zuckerberg's wealth is greater than Larry Ellison's on 13th March 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 700/951 [08:33<08:22, 2.00s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg on March 13th, 2020?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on March 13th, 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 701/951 [08:35<07:48, 1.87s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg, on January 10th, 2021?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on January 10th, 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 702/951 [08:36<07:23, 1.78s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': "According to the image, is Mark Zuckerberg'swealth greater than Larry Ellison's on 13th March 2020?"}] +Yes, according to the image, Mark Zuckerberg's wealth is greater than Larry Ellison's on 13th March 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 703/951 [08:39<08:27, 2.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg on March 13th, 2020?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on March 13th, 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 704/951 [08:41<07:48, 1.90s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg, on January 10th, 2021?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on January 10th, 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 705/951 [08:42<07:23, 1.80s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_1.png'}, {'type': 'text', 'value': 'According to the image, in 2017, was Tencent the company with the highest revenue from video games, with Sony as the second-highest earner?'}] +Yes, according to the image, Tencent was the company with the highest revenue from video games in 2017, with Sony as the second-highest earner. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 706/951 [08:43<06:22, 1.56s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_1.png'}, {'type': 'text', 'value': 'According to the image, in 2017, did Apple generate higher revenue from video games compared to Google?'}] +2017 was a year of significant growth for video game companies. According to the image, Apple generated higher revenue from video games compared to Google. The chart shows that Apple generated $18.3 billion in revenue from video games, while Google generated $1.3 billion. This highlights the increasing popularity and revenue generated by video games, with Apple being one of the leading companies in this industry. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 707/951 [08:45<06:45, 1.66s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_2.png'}, {'type': 'text', 'value': 'According to the image, in 2017, was Tencent the company with the highest revenue from video games, with Sony as the second-highest earner?'}] +Yes, according to the image, Tencent was the company with the highest revenue from video games in 2017, with Sony as the second-highest earner. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 708/951 [08:46<05:54, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_2.png'}, {'type': 'text', 'value': 'According to the image, in 2017, did Apple generate higher revenue from video games compared to Google?'}] +2017 was a year of significant growth for video game revenue, and according to the image, Apple generated higher revenue from video games compared to Google. The chart shows that Apple generated $18.3 billion in revenue from video games, while Google generated $1.3 billion. This highlights the increasing popularity and revenue potential of video games, with companies like Apple and Google investing in the gaming industry to expand their offerings and reach a broader audience. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 709/951 [08:48<06:42, 1.66s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_1.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2020?'}] +2020 was indeed the year with the highest number of bankruptcy filings in the US, as shown in the image. The chart displays the number of bankruptcy filings by year, and it is evident that 2020 had the highest number of filings. This could be attributed to the economic impact of the COVID-19 pandemic, which led to widespread business closures, job losses, and financial strain for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 710/951 [08:50<07:20, 1.83s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_1.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2021?'}] +2021 was indeed the year with the most bankruptcy filings in the US, as shown in the image. The chart displays the number of bankruptcy filings by year, and it is evident that 2021 had the highest number of filings. This could be attributed to the economic impact of the COVID-19 pandemic, which led to widespread business closures, job losses, and financial strain for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 711/951 [08:53<07:39, 1.91s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_2.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2020?'}] +2020 was indeed the year with the highest number of bankruptcy filings in the US, as shown in the image. The chart displays the number of bankruptcy filings by year, and it is evident that 2020 had the highest number of filings. This could be attributed to the economic impact of the COVID-19 pandemic, which led to widespread business closures, job losses, and financial strain for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 712/951 [08:55<07:56, 1.99s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_2.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2021?'}] +2021 was indeed the year with the most bankruptcy filings in the US, as indicated by the image. The chart shows a significant increase in bankruptcy filings from 2019 to 2021, with the highest number of filings occurring in 2021. This could be attributed to the economic impact of the COVID-19 pandemic, which led to widespread business closures, job losses, and financial strain for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 713/951 [08:57<08:15, 2.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_1.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 90 and 94 years than those aged between 0 and 4 years?'}] +2020 data is not available in the image. The image shows a chart with a blue and pink triangle, but it does not provide information about the population aged between 90 and 94 years or those aged between 0 and 4 years. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 714/951 [08:58<07:16, 1.84s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_1.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 50 and 54 years than those aged between 0 and 4 years?'}] +2020 data is not available in the image. The image shows a chart with a blue and pink triangle, but it does not provide information about the population aged between 50 and 54 years in China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 715/951 [08:59<06:18, 1.60s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_2.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 90 and 94 years than those aged between 0 and 4 years?'}] +2020 data is not available in the image. The image shows a chart with a blue and pink triangle, but it does not provide information about the population aged between 90 and 94 years in China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 716/951 [09:00<05:38, 1.44s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_2.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 50 and 54 years than those aged between 0 and 4 years?'}] +2020 data is not available in the image. The image shows a chart with a blue and pink triangle, but it does not provide information about the population aged between 50 and 54 years in China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 717/951 [09:01<05:10, 1.33s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_1.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Black Panther" achieve the highest box office revenue in North America?'}] +2018 was a record-breaking year for the box office in North America, with "Black Panther" achieving the highest box office revenue. The image shows that the movie grossed $1.348 billion in the United States, making it the highest-grossing movie in North America in 2018. This figure is significantly higher than the previous record-holder, "Avatar," which grossed $1.68 billion in 2009. The success of "Black Panther" highlights the popularity of superhero movies and the continued growth of the film industry. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 718/951 [09:04<07:01, 1.81s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_1.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Avengers: Infinity War" achieve the highest box office revenue in North America?'}] +2018 was a record-breaking year for the box office in North America, with "Avengers: Infinity War" achieving the highest box office revenue. The movie grossed over $2.79 billion worldwide, making it the highest-grossing movie of all time. This figure includes the revenue generated in the United States and Canada, as well as other countries around the world. The success of "Avengers: Infinity War" and other blockbuster movies in 2018 contributed to the overall growth of the global box office industry. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 719/951 [09:07<07:58, 2.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_2.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Black Panther" achieve the highest box office revenue in North America?'}] +2018 was a record-breaking year for the box office in North America, with "Black Panther" achieving the highest box office revenue. The movie grossed over $1.34 billion in the United States and Canada, making it the highest-grossing movie of all time in North America. This figure is significantly higher than the previous record-holder, "Avatar," which grossed $1.78 billion worldwide. The success of "Black Panther" highlights the popularity of superhero movies and the continued growth of the film industry. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 720/951 [09:10<08:36, 2.23s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_2.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Avengers: Infinity War" achieve the highest box office revenue in North America?'}] +2018 was a record-breaking year for the box office in North America, with "Avengers: Infinity War" achieving the highest box office revenue. The movie grossed over $2.79 billion worldwide, making it the highest-grossing movie of all time. This figure includes the revenue generated in the United States and Canada, which is the primary focus of the image. The success of "Avengers: Infinity War" and other blockbuster movies in 2018 contributed to the overall growth of the box office industry in North America. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 721/951 [09:12<09:02, 2.36s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does China have the most gold metals, followed by USA and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, China has the most gold medals, followed by the United States and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 722/951 [09:13<07:10, 1.88s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does USA have the most gold metals, followed by China and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, the United States has the most gold medals, followed by China and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 723/951 [09:14<05:50, 1.54s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does Russia have the most gold metals, followed by China and USA?'}] +According to the metal number chart of 2008 Beijing Olympic, Russia has the most gold medals, followed by China and the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 724/951 [09:15<04:53, 1.29s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does China have the most gold metals, followed by USA and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, China has the most gold medals, followed by the United States and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 725/951 [09:15<04:25, 1.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does USA have the most gold metals, followed by China and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, the United States has the most gold medals, followed by China and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▋ | 726/951 [09:16<03:58, 1.06s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does Russia have the most gold metals, followed by China and USA?'}] +According to the metal number chart of 2008 Beijing Olympic, Russia has the most gold medals, followed by China and the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▋ | 727/951 [09:17<03:36, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'which country has the largest population growth rate in 2023'}] +Syria has the largest population growth rate in 2023, with a rate of 6.3%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 728/951 [09:18<03:10, 1.17it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'In 2023, did Syria have higher population growth than South Sudan?'}] +Yes, in 2023, Syria had a higher population growth rate than South Sudan. The population growth rate for Syria was 6.3%, while for South Sudan, it was 3.6%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 729/951 [09:19<03:20, 1.11it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'In 2023, did Syria have higher population growth than United Kingdom?'}] +No, Syria did not have higher population growth than the United Kingdom in 2023. The table shows that the United Kingdom had a population growth rate of 3.6% in 2023, while Syria had a population growth rate of 6.3%. This indicates that the United Kingdom experienced a higher population growth rate than Syria in 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 730/951 [09:20<04:12, 1.14s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, which country has the largest population growth rate in 2023'}] +According to the table, Niger has the largest population growth rate in 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 731/951 [09:21<03:27, 1.06it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, In 2023, did Syria have higher population growth than South Sudan?'}] +Yes, according to the table, Syria had a higher population growth rate than South Sudan in 2023. Syria's population growth rate was 3.6%, while South Sudan's population growth rate was 3.3%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 732/951 [09:22<03:50, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, In 2023, did Syria have higher population growth than United Kingdom?'}] +Yes, according to the table, Syria had a higher population growth rate than the United Kingdom in 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 733/951 [09:23<03:20, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 734/951 [09:23<02:52, 1.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 735/951 [09:24<02:35, 1.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 736/951 [09:24<02:33, 1.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 737/951 [09:25<02:18, 1.54it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 738/951 [09:26<02:12, 1.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 739/951 [09:26<02:14, 1.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 740/951 [09:27<02:08, 1.64it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the countries listed. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 741/951 [09:27<02:05, 1.68it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the countries listed, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 742/951 [09:28<02:08, 1.62it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi sell most units of the smartphone in Q2 2020?'}] +According to the table, Xiaomi sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 743/951 [09:29<02:09, 1.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Samsung sell most units of the smartphone in Q2 2020?'}] +According to the table, Samsung sold the most units of the smartphone in Q2 2020, with a total of 58 million units. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 744/951 [09:29<02:19, 1.48it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi have the largest smartphone market share in Q2 2020, followed by Samsung and Huawei?'}] +According to the table, Xiaomi had the largest smartphone market share in Q2 2020, followed by Samsung and Huawei. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 745/951 [09:30<02:27, 1.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi sell most units of the smartphone in Q2 2020?'}] +According to the table, Xiaomi sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 746/951 [09:31<02:22, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Samsung sell most units of the smartphone in Q2 2020?'}] +According to the table, Samsung sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▊ | 747/951 [09:31<02:15, 1.51it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi have the largest smartphone market share in Q2 2020, followed by Samsung and Huawei?'}] +According to the table, Xiaomi had the largest smartphone market share in Q2 2020, followed by Samsung and Huawei. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▊ | 748/951 [09:32<02:21, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, Florida has the highest average maximum temperature in 2021 among the listed states. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 749/951 [09:33<02:13, 1.51it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature among the listed states in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 750/951 [09:33<02:06, 1.59it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, According to the table, did Florida have a higher average maximum temperature than Louisana?'}] +Yes, according to the table, Florida had a higher average maximum temperature than Louisiana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 751/951 [09:34<01:53, 1.76it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, the state in the United States with the average maximum temperature in 2021 is Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 752/951 [09:34<01:58, 1.68it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature among the listed states in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 753/951 [09:35<01:56, 1.70it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, did Florida have a higher average maximum temperature than Louisana?'}] +According to the table, Florida had a higher average maximum temperature than Louisiana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 754/951 [09:35<01:46, 1.85it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, the state in the United States with the average maximum temperature in 2021 is Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 755/951 [09:36<01:52, 1.74it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature in the United States in 2020, with an average of 72.2 degrees Fahrenheit. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 756/951 [09:37<02:06, 1.55it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, did Florida have a higher average maximum temperature than South Carolina?'}] +Yes, according to the table, Florida had a higher average maximum temperature than South Carolina. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 757/951 [09:37<01:55, 1.68it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 758/951 [09:38<02:14, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 759/951 [09:39<02:20, 1.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was 0.29%, while the percentage change in August 2023 was 0.22%. This indicates that the income situation in January 2023 was better than in August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 760/951 [09:41<03:40, 1.16s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, January 2023 had a lower income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was -0.2%, while the percentage change in August 2023 was 0.2%. This indicates that the personal income in August 2023 increased by 0.2% compared to January 2023, which experienced a decrease of 0.2%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 761/951 [09:43<04:37, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 762/951 [09:44<04:06, 1.31s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is August. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 763/951 [09:45<03:38, 1.16s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was 0.8%, while the percentage change in August 2023 was 0.4%. This indicates that the income situation in January 2023 was more favorable than in August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 764/951 [09:47<04:19, 1.39s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, January 2023 had a lower income percentage change than August 2023. The table shows that the percentage change in personal income in the United States from September 2022 to August 2023 was 8.0%, while the percentage change in personal income in the United States from January 2023 to August 2023 was 0.0%. This indicates that the income situation in the United States improved significantly from January to August 2023, while it remained relatively stable from September 2022 to August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 765/951 [09:50<05:32, 1.79s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 766/951 [09:51<04:42, 1.53s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 767/951 [09:52<04:07, 1.34s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that in January 2023, the personal income percentage change was 4.4%, while in August 2023, the percentage change was 0.6%. This indicates that the income situation in the United States improved in January 2023 compared to August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 768/951 [09:54<04:42, 1.54s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, the personal income percentage change in the United States in January 2023 was 0.4%, while the percentage change in August 2023 was 0.6%. Therefore, January 2023 had a lower income percentage change than August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 769/951 [09:55<04:34, 1.51s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 2,729 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 770/951 [09:56<03:57, 1.31s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +According to the table, Beijing has the second most dense population in China in 2020. The table shows that the city of Beijing has a population density of 1,322 people per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 771/951 [09:57<03:44, 1.25s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020, with a population density of 7,759 people per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 772/951 [09:58<03:22, 1.13s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +According to the table, Zhejiang has the second most dense population in China in 2020, with a population density of 1,372 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 773/951 [09:59<03:10, 1.07s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 3,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 774/951 [10:00<02:57, 1.00s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +According to the table, Beijing has the second most dense population in China in 2020, with a population density of 13,222 per square kilometer. The city with the highest population density in China in 2020 is Shanghai, with a population density of 13,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 775/951 [10:01<03:27, 1.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020, with a population density of 1,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 776/951 [10:02<03:16, 1.12s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +According to the table, Zhejiang has the second most dense population in China in 2020, with a population density of 1,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 777/951 [10:03<03:02, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 1,667 people per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 778/951 [10:04<02:51, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +Yes, according to the table, Beijing has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 779/951 [10:05<02:29, 1.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 780/951 [10:05<02:11, 1.30it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +Yes, according to the table, Zhejiang has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 781/951 [10:06<02:02, 1.39it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +Yes, according to the table, Norway has 16 gold medals in the winter Olympics in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 782/951 [10:06<01:58, 1.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 783/951 [10:07<01:56, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +12 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 784/951 [10:07<01:28, 1.89it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 785/951 [10:08<01:36, 1.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +15 is the number of all medals won by China in the Winter Olympics 2022, according to the table. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 786/951 [10:09<01:39, 1.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +37 is the number of all medals won by China in the Winter Olympics 2022, as shown in the table. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 787/951 [10:09<01:42, 1.61it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +Yes, according to the table, Norway has won 16 gold medals in the Winter Olympics 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 788/951 [10:10<01:43, 1.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 789/951 [10:11<01:45, 1.54it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +12 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 790/951 [10:11<01:22, 1.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 791/951 [10:11<01:30, 1.76it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +15 is the number of all medals won by China in the 2022 Winter Olympics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 792/951 [10:12<01:35, 1.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +37 is the number of all medals won by China in the 2022 Winter Olympics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 793/951 [10:13<01:32, 1.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +16 is the number of gold medals won by Norway in the 2022 Winter Olympics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 794/951 [10:13<01:31, 1.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▎ | 795/951 [10:14<01:43, 1.51it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +12 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▎ | 796/951 [10:14<01:19, 1.95it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 797/951 [10:15<01:27, 1.76it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +15 is the number of all medals won by China in the Winter Olympics 2022, as shown in the table. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 798/951 [10:16<01:31, 1.67it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +37 is the number of all medals won by China in the Winter Olympics 2022, as shown in the table. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 799/951 [10:16<01:36, 1.57it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift releases the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 800/951 [10:17<01:34, 1.60it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2022 in the United States, and "Harry's House" is not among them. The table does include the album "Midnights" by Taylor Swift, which is listed as the third best-selling album of 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 801/951 [10:19<02:33, 1.02s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 802/951 [10:20<02:28, 1.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 803/951 [10:21<02:24, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by BTS has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 804/951 [10:22<02:17, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by BTS has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 805/951 [10:23<02:14, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift releases the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 806/951 [10:23<01:58, 1.22it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2021 in physical and digital sales, and "Harry's House" is not among them. The table does include the album "Midnights," which is listed as the 10th best-selling album of 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 807/951 [10:25<02:46, 1.15s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 808/951 [10:26<02:34, 1.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 809/951 [10:27<02:24, 1.02s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 810/951 [10:28<02:16, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 811/951 [10:29<02:11, 1.06it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift released the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 812/951 [10:29<01:57, 1.19it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2022 in the United States, and "Harry's House" is not among them. The table does include the album "Midnights" by Taylor Swift, which is listed as the 10th best-selling album of 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 813/951 [10:31<02:43, 1.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 814/951 [10:32<02:32, 1.11s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 815/951 [10:33<02:22, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 816/951 [10:34<02:12, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 817/951 [10:35<02:08, 1.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the UB group have the highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the highest portion of the market share for beer across India in 2020, with 54% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 818/951 [10:36<02:07, 1.04it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the Carlsberg India have the highest portion of the market share for beer across India in 2020?'}] +According to the table, Carlsberg India has the highest portion of the market share for beer across India in 2020, with a 33% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 819/951 [10:37<02:03, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the SABMiller India have the second highest portion of the market share for beer across India in 2020?'}] +According to the table, SABMiller India has the second highest portion of the market share for beer across India in 2020, with a 15% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 820/951 [10:37<02:01, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the UB Group have the second highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the second highest portion of the market share for beer across India in 2020, with a 15% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▋ | 821/951 [10:38<01:59, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the UB group have the highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the highest portion of the market share for beer across India in 2020, with 54% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▋ | 822/951 [10:39<02:00, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the Carlsberg India have the highest portion of the market share for beer across India in 2020?'}] +According to the table, Carlsberg India has the highest portion of the market share for beer across India in 2020, with 72% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 823/951 [10:40<01:57, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the SABMiller India have the second highest portion of the market share for beer across India in 2020?'}] +According to the table, the SABMiller India has the second highest portion of the market share for beer across India in 2020, with a 17% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 824/951 [10:41<01:56, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the UB Group have the second highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the second highest portion of the market share for beer across India in 2020, with 17% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 825/951 [10:42<01:59, 1.05it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does China have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, China has the highest carbon dioxide emissions worldwide in 2010, with 8,777 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 826/951 [10:43<01:56, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does US have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, the United States has the highest carbon dioxide emissions worldwide in 2010, with 5,259 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 827/951 [10:44<01:53, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does Russia have the second highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, Russia has the second highest carbon dioxide emissions worldwide in 2010, with 5,677 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 828/951 [10:45<01:53, 1.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, is the carbon dioxide emission worldwide in 2010 the same for US and India?'}] +According to the table, the carbon dioxide emission worldwide in 2010 was 8,777 million metric tons for the United States and 6,667 million metric tons for India. This indicates that the carbon dioxide emission worldwide in 2010 was higher for the United States than for India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 829/951 [10:46<02:17, 1.13s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does China have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, China has the highest carbon dioxide emissions worldwide in 2010, with 6,780 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 830/951 [10:47<02:06, 1.04s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does US have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, the United States has the highest carbon dioxide emissions worldwide in 2010, with 6,700 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 831/951 [10:48<01:58, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does Russia have the second highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, Russia has the second highest carbon dioxide emissions worldwide in 2010, with 6,749 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 832/951 [10:49<01:53, 1.05it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, is the carbon dioxide emission worldwide in 2010 the same for US and India?'}] +According to the table, the carbon dioxide emission worldwide in 2010 was 6,700 million metric tons for the United States and 6,100 million metric tons for India. This indicates that the carbon dioxide emission worldwide in 2010 was higher for the United States than for India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 833/951 [10:51<02:14, 1.14s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than Texas state?'}] +No, according to the map provided, New Mexico is not larger than Texas. The map shows the United States of America, and Texas is larger than New Mexico. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 834/951 [10:51<02:00, 1.03s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is Texas state larger than California state?'}] +No, according to the map provided, California is larger than Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 835/951 [10:52<01:36, 1.20it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than California state?'}] +No, according to the map provided, New Mexico is not larger than California. The map shows the United States of America, and both New Mexico and California are depicted as states. However, California is larger than New Mexico, as it occupies a larger area in the western part of the country. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 836/951 [10:53<01:54, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is Montana state larger than New Mexico state?'}] +No, according to the map provided, Montana state is not larger than New Mexico state. The map shows that New Mexico is larger than Montana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 837/951 [10:54<01:43, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than Texas state?'}] +No, according to the map provided, New Mexico is not larger than Texas. The map shows the United States of America, and Texas is larger than New Mexico. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 838/951 [10:55<01:39, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is Texas state larger than California state?'}] +Yes, according to the map provided, Texas is larger than California. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 839/951 [10:55<01:21, 1.37it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than California state?'}] +No, according to the map provided, New Mexico is not larger than California. The map shows the United States of America, and both New Mexico and California are depicted as states. However, California is significantly larger than New Mexico, as it occupies a much larger portion of the western coast of the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 840/951 [10:57<01:44, 1.06it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is Montana state larger than New Mexico state?'}] +No, according to the map provided, Montana state is not larger than New Mexico state. The map shows that New Mexico is larger than Montana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 841/951 [10:57<01:37, 1.12it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Delaware the farthest north?'}] +Yes, Delaware is the farthest north among the states shown on the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 842/951 [10:58<01:25, 1.27it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Arizona the farthest north?'}] +Yes, among the states shown on the map, Arizona is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 843/951 [10:58<01:14, 1.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Oklahoma the farthest north?'}] +Yes, according to the map provided, Oklahoma is the farthest north among the states of Arizona, North Carolina, and Delaware. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 844/951 [10:59<01:13, 1.46it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is North Carolina the farthest north?'}] +Yes, among the states shown on the map, North Carolina is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 845/951 [10:59<01:06, 1.58it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Delaware the farthest north?'}] +Yes, Delaware is the farthest north among the states shown on the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 846/951 [11:00<01:08, 1.54it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Arizona the farthest north?'}] +Yes, among the states shown on the map, Arizona is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 847/951 [11:01<01:02, 1.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Oklahoma the farthest north?'}] +Yes, among the states shown on the map, Oklahoma is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 848/951 [11:01<01:00, 1.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is North Carolina the farthest north?'}] +Yes, among the states shown on the map, North Carolina is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 849/951 [11:02<00:57, 1.77it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_1.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Atlantic Ocean, Southern Ocean, and Arctic Ocean?'}] +According to the map, the prime meridian intersects the Atlantic Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 850/951 [11:02<00:58, 1.71it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_1.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Pacific Ocean, Southern Ocean, and Arctic Ocean?'}] +According to the map, the prime meridian intersects the Pacific Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 851/951 [11:03<00:58, 1.72it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_2.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Atlantic Ocean, Southern Ocean, and Arctic Ocean?'}] +According to the map, the prime meridian intersects the Atlantic Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 852/951 [11:04<01:09, 1.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_2.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Pacific Ocean, Southern Ocean, and Arctic Ocean?'}] +According to the map, the prime meridian intersects the Pacific Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 853/951 [11:05<01:08, 1.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_1.png'}, {'type': 'text', 'value': 'Based on the map, did the Democratic Party win Texas in the 2020 elections?'}] +Based on the map, the Democratic Party did not win Texas in the 2020 elections. The map shows a red and blue color-coded representation of the United States, with the blue areas representing the Democratic Party's victories and the red areas representing the Republican Party's victories. Texas is colored red, indicating that it was won by the Republican Party in the 2020 elections. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 854/951 [11:06<01:42, 1.05s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_1.png'}, {'type': 'text', 'value': 'Based on the map, did the Republic Party win Texas in the 2020 elections?'}] +Based on the map, the Republic Party did not win Texas in the 2020 elections. The map shows that the Democratic Party won the majority of the states, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 855/951 [11:07<01:35, 1.01it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_2.png'}, {'type': 'text', 'value': 'Based on the map, did the Democratic Party win Texas in the 2020 elections?'}] +Based on the map, the Democratic Party did not win Texas in the 2020 elections. The map shows that the Republican Party won the majority of the states in the United States, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 856/951 [11:08<01:34, 1.00it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_2.png'}, {'type': 'text', 'value': 'Based on the map, did the Republic Party win Texas in the 2020 elections?'}] +Based on the map, the Republic Party did not win Texas in the 2020 elections. The map shows that the Democratic Party won the majority of the states, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 857/951 [11:09<01:31, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in North America?'}] +Yes, the Rocky Mountains are located in North America, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 858/951 [11:10<01:18, 1.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in Asia?'}] +No, the Rocky Mountains are not located in Asia. They are located in North America, specifically in the United States and Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 859/951 [11:10<01:12, 1.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in North America?'}] +No, the Himalayas are not located in North America. They are a mountain range in Asia, stretching from the Indian subcontinent to the Tibetan Plateau. The map in the image shows the Himalayas in the correct location, which is Asia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 860/951 [11:12<01:25, 1.06it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in Asia?'}] +Yes, the Himalayas Mountains are located in Asia, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 861/951 [11:12<01:13, 1.23it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in North America?'}] +Yes, the Rocky Mountains are located in North America, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 862/951 [11:13<01:04, 1.38it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in Asia?'}] +No, the Rocky Mountains are not located in Asia. They are located in North America, specifically in the United States and Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 863/951 [11:13<01:01, 1.43it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in North America?'}] +No, the Himalayas Mountains are not located in North America. They are located in Asia, specifically in the countries of Nepal, India, Pakistan, and Bhutan. The map in the image shows the Himalayas as part of the Asian continent, not North America. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 864/951 [11:15<01:16, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in Asia?'}] +Yes, the Himalayas Mountains are located in Asia, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 865/951 [11:15<01:05, 1.31it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Huron?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Huron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 866/951 [11:16<01:02, 1.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Ontario?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 867/951 [11:16<00:58, 1.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Huron?'}] +No, New York is not the only U.S. state that shares a border with Lake Huron. The image shows that the Great Lakes region includes parts of the United States and Canada. The U.S. states that share a border with Lake Huron are Michigan, Ohio, Indiana, Illinois, and Wisconsin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 868/951 [11:18<01:15, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Ontario?'}] +No, New York is not the only U.S. state that shares a border with Lake Ontario. The image also shows that Michigan shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 869/951 [11:19<01:12, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Huron?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Huron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 870/951 [11:19<01:06, 1.22it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Ontario?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 871/951 [11:20<01:00, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Huron?'}] +No, New York is not the only U.S. state that shares a border with Lake Huron. The image shows that the Great Lakes region includes parts of the United States and Canada. The U.S. states that share a border with Lake Huron are Michigan, Ohio, Indiana, Illinois, and Wisconsin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 872/951 [11:21<01:15, 1.05it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Ontario?'}] +No, New York is not the only U.S. state that shares a border with Lake Ontario. The image also shows that the state of Michigan shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 873/951 [11:22<01:12, 1.08it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Blue Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Blue Line towards the Pentagon on the DC Metro system. The map shows the Blue Line running through the Pentagon area, indicating that it is a viable option for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 874/951 [11:24<01:25, 1.12s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Red Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Red Line towards the Pentagon on the DC Metro system. The map shows the Red Line going through the Pentagon, indicating that it is a viable route for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 875/951 [11:25<01:27, 1.15s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Yellow Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Yellow Line towards the Pentagon on the DC Metro system. The map shows the Yellow Line running through the Pentagon area, indicating that it is a viable route for travelers. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 876/951 [11:26<01:28, 1.18s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Blue Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Blue Line towards the Pentagon on the DC Metro system. The map shows the Blue Line running through the city, with a stop at the Pentagon. This indicates that the Blue Line is a viable option for traveling to the Pentagon. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 877/951 [11:28<01:39, 1.34s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Red Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Red Line towards the Pentagon on the DC Metro system. The map shows the Red Line going through the Pentagon area, indicating that it is a viable route for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 878/951 [11:29<01:35, 1.31s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Yellow Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Yellow Line towards the Pentagon on the DC Metro system. The map shows the Yellow Line running through the Pentagon area, indicating that it is a viable route for traveling to the Pentagon. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 879/951 [11:31<01:32, 1.29s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_1.png'}, {'type': 'text', 'value': 'According to the image, is Key West the southernmost point of Florida?'}] +Yes, Key West is the southernmost point of Florida, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 880/951 [11:31<01:16, 1.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_1.png'}, {'type': 'text', 'value': 'According to the image, is Miami the southernmost point of Florida?'}] +No, Miami is not the southernmost point of Florida. The southernmost point of Florida is located at the tip of the Florida Keys, which is known as Key West. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 881/951 [11:32<01:10, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_2.png'}, {'type': 'text', 'value': 'According to the image, is Key West the southernmost point of Florida?'}] +Yes, Key West is the southernmost point of Florida, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 882/951 [11:33<01:01, 1.13it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_2.png'}, {'type': 'text', 'value': 'According to the image, is Miami the southernmost point of Florida?'}] +Yes, according to the image, Miami is the southernmost point of Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 883/951 [11:33<00:51, 1.33it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': "Based on the map, is Charles County located to the south of Prince George's County?"}] +Yes, based on the map, Charles County is located to the south of Prince George's County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 884/951 [11:34<00:47, 1.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': 'Based on the map, is Calvert County located to the east of Cecil County?'}] +Yes, based on the map, Calvert County is located to the east of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 885/951 [11:34<00:43, 1.53it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': 'Based on the map, is Kent County located to the north of Cecil County?'}] +Yes, based on the map, Kent County is located to the north of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 886/951 [11:35<00:39, 1.65it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': "Based on the map, is Charles County located to the south of Prince George's County?"}] +Yes, Charles County is located to the south of Prince George's County, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 887/951 [11:36<00:45, 1.40it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': 'Based on the map, is Calvert County located to the east of Cecil County?'}] +Yes, based on the map, Calvert County is located to the east of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 888/951 [11:36<00:44, 1.42it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': 'Based on the map, is Kent County located to the north of Cecil County?'}] +Yes, based on the map, Kent County is located to the north of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 889/951 [11:37<00:42, 1.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_1.png'}, {'type': 'text', 'value': 'According to the image, does Bolivia cover part of the Amazon Basin?'}] +Yes, Bolivia covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▎| 890/951 [11:38<00:42, 1.44it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_1.png'}, {'type': 'text', 'value': 'According to the image, does Chile cover part of the Amazon Basin?'}] +Yes, Chile covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▎| 891/951 [11:38<00:38, 1.54it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_2.png'}, {'type': 'text', 'value': 'According to the image, does Bolivia cover part of the Amazon Basin?'}] +Yes, Bolivia covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 892/951 [11:39<00:36, 1.62it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_2.png'}, {'type': 'text', 'value': 'According to the image, does Chile cover part of the Amazon Basin?'}] +Yes, Chile covers part of the Amazon Basin. The image shows a map of South America with the Amazon Basin and Chile highlighted. The Amazon Basin is a vast region that spans across several countries, including Brazil, Peru, Bolivia, and Colombia. Chile is located in the southwestern part of South America, and its border with Peru and Bolivia is close to the Amazon Basin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 893/951 [11:41<00:56, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_1.png'}, {'type': 'text', 'value': 'According to the image, does the Oyashio Current flow from the south to the north, while the Kuroshio Current flows from the north to the south?'}] +Yes, according to the image, the Oyashio Current flows from the south to the north, while the Kuroshio Current flows from the north to the south. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 894/951 [11:42<00:56, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_1.png'}, {'type': 'text', 'value': 'According to the image, does the Kuroshio Current flow through Russia?'}] +According to the image, the Kuroshio Current flows through Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 895/951 [11:42<00:48, 1.16it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_2.png'}, {'type': 'text', 'value': 'According to the image, does the Oyashio Current flow from the south to the north, while the Kuroshio Current flows from the north to the south?'}] +Yes, according to the image, the Oyashio Current flows from the south to the north, while the Kuroshio Current flows from the north to the south. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 896/951 [11:43<00:47, 1.15it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_2.png'}, {'type': 'text', 'value': 'According to the image, does the Kuroshio Current flow through Russia?'}] +According to the image, the Kuroshio Current flows through Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 897/951 [11:43<00:39, 1.36it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_1.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1415926 to 3.1415927?'}] +π (pi) is a mathematical constant that represents the ratio of a circle's circumference to its diameter. The value of π is approximately 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679. The image shows a series of numbers, which could be a representation of the digits of π. However, it is not possible to determine from the image whether the range of π is from 3.1415926 to 3.1415927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 898/951 [11:47<01:31, 1.73s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_1.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1615926 to 3.1615927?'}] +π (pi) is a mathematical constant that represents the ratio of a circle's circumference to its diameter. The value of π is approximately 3.14159265358979323846264336000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 899/951 [12:29<11:57, 13.81s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_2.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1415926 to 3.1415927?'}] +π (pi) is a mathematical constant that represents the ratio of a circle's circumference to its diameter. The value of π is approximately 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679. The image shows a series of numbers, which could be a representation of the digits of π. However, it is not possible to determine from the image whether the range of π is from 3.1415926 to 3.1415927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 900/951 [12:34<09:17, 10.94s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_2.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1615926 to 3.1615927?'}] +π (pi) is a mathematical constant that represents the ratio of a circle's circumference to its diameter. The value of π is approximately 3.14159265358979323846264336000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 901/951 [13:16<16:56, 20.33s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/1_1.png'}, {'type': 'text', 'value': "Is the formula in the image representative of the mass-energy equivalence concept in Einstein's theory?"}] +Yes, the formula in the image is representative of the mass-energy equivalence concept in Einstein's theory of relativity. The equation E=mc represents the relationship between energy (E) and mass (m) in the form of the famous equation E=mc^2. This equation states that energy and mass are interchangeable and that the energy of an object is directly proportional to its mass and the square of the speed of light. This concept is crucial in understanding the behavior of particles and the nature of the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 902/951 [13:18<12:12, 14.94s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/1_2.png'}, {'type': 'text', 'value': "Is the formula in the image representative of the mass-energy equivalence concept in Einstein's theory?"}] +Yes, the formula in the image is representative of the mass-energy equivalence concept in Einstein's theory of relativity. The equation E=mc represents the relationship between energy (E) and mass (m) in the form of the famous equation E=mc^2. This equation states that energy and mass are interchangeable and that the energy of an object is directly proportional to its mass and the square of the speed of light. This concept is crucial in understanding the behavior of particles and the nature of the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 903/951 [13:21<08:56, 11.17s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.71 to 2.72?"}] +According to the image, the Euler's Number 'e' ranges from 2.71 to 2.72. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 904/951 [13:21<06:17, 8.03s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image which is about the Euler's Number, does the Euler's Number 'e' range from 2.70 to 2.71?"}] +2.71 is the value of Euler's number, which is the base of the natural logarithm. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 905/951 [13:22<04:29, 5.85s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.72 to 2.73?"}] +According to the image, the Euler's Number 'e' ranges from 2.72 to 2.73. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 906/951 [13:23<03:13, 4.30s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.71 to 2.72?"}] +According to the image, the Euler's Number 'e' ranges from 2.71 to 2.72. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 907/951 [13:24<02:21, 3.22s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.70 to 2.71?"}] +According to the image, the Euler's Number 'e' ranges from 2.70 to 2.71. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 908/951 [13:24<01:45, 2.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.72 to 2.73?"}] +According to the image, the Euler's Number 'e' ranges from 2.72 to 2.73. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 909/951 [13:25<01:20, 1.93s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.40 to 1.41?'}] +1.40 is the value of the square root of 2, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 910/951 [13:26<01:03, 1.56s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.41 to 1.42?'}] +1.41 is the value of the square root of 2, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 911/951 [13:26<00:49, 1.24s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.42 to 1.43?'}] +1.42 is the value of the square root of 2, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 912/951 [13:27<00:48, 1.25s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.40 to 1.41?'}] +1.42 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 913/951 [13:28<00:37, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.41 to 1.42?'}] +1.42 + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 914/951 [13:28<00:27, 1.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.42 to 1.43?'}] +1.42 is the value of the square root of 2, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 915/951 [13:28<00:24, 1.49it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_1.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Gravity equation?'}] +Yes, the formula in the image is representative of the Gravity equation. The equation is written in terms of the gravitational constant (G), mass (m), and distance (r) squared. The equation is Gm/r^2, which is a fundamental equation in physics that describes the force of gravity between two objects. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▋| 916/951 [13:30<00:32, 1.09it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the image, is the formula F=G * m_1 * m_2 / r^2 representative of the Gravity equation?'}] +Yes, the formula F=G \* m\_1 \* m\_2 / r^2 is representative of the Gravity equation. It is a mathematical equation that describes the force of gravity between two objects, where F is the force, G is the gravitational constant, m\_1 and m\_2 are the masses of the two objects, and r is the distance between them. This equation is a fundamental concept in physics and is used to calculate the gravitational force between two objects, such as planets or stars, in a gravitational system. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▋| 917/951 [13:32<00:46, 1.37s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_2.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Gravity equation?'}] +Yes, the formula in the image is representative of the Gravity equation. The equation is written in terms of the gravitational constant (G), mass (m), and distance (r) squared. The equation is G \* m / r^2, which is a fundamental equation in physics that describes the force of gravity between two objects. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 918/951 [13:34<00:47, 1.43s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_2.png'}, {'type': 'text', 'value': 'According to the image, is the formula F=G * m_1 * m_2 / r^2 representative of the Gravity equation?'}] +Yes, the formula F=G \* m\_1 \* m\_2 / r^2 is representative of the Gravity equation. It is a fundamental equation in physics that describes the force of gravity between two objects, where F is the force, G is the gravitational constant, m\_1 and m\_2 are the masses of the two objects, and r is the distance between them. This equation is used to calculate the gravitational force between two objects, which is a key component in understanding the behavior of celestial bodies and the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 919/951 [13:36<00:55, 1.73s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_1.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Euler equation?'}] +Yes, the formula in the image is representative of the Euler equation. The equation is written as: + +cos(x) + sin(x) = 1 + +This equation is a fundamental equation in trigonometry and is often used to solve problems related to angles and their relationships to other angles. The Euler equation is a simple yet powerful tool that can be applied in various fields, such as physics, engineering, and mathematics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 920/951 [13:38<00:55, 1.78s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_1.png'}, {'type': 'text', 'value': 'Is the formula e^ix = cos x + i x representative of the equation in this figure?'}] +Yes, the formula e^ix = cos x + i x is representative of the equation in the figure. The equation is a mathematical expression that represents the relationship between the exponential function e^x and the trigonometric functions cos x and sin x. In the image, the equation is displayed in a graphical format, with the exponential function e^x on the x-axis and the trigonometric functions cos x and sin x on the y-axis. This representation helps to visualize the relationship between these functions and understand how they are related to each other. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 921/951 [13:41<00:59, 1.97s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_2.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Euler equation?'}] +Yes, the formula in the image is representative of the Euler equation. The equation is written as: + +cos(x) + sin(x) = 1 + +This equation is a fundamental equation in trigonometry and is often used to solve problems related to the behavior of waves, such as the wave equation in physics. The Euler equation is a simple and elegant way to describe the relationship between the sine and cosine functions, and it has applications in various fields, including physics, engineering, and mathematics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 922/951 [13:43<01:00, 2.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_2.png'}, {'type': 'text', 'value': 'Is the formula e^ix = cos x + i x representative of the equation in this figure?'}] +Yes, the formula e^ix = cos x + i x is representative of the equation in the figure. The equation is a mathematical expression that represents the relationship between the exponential function e^x and the trigonometric functions cos x and sin x. In the image, the equation is displayed in a graphical format, with the exponential function e^x on the x-axis and the trigonometric functions cos x and sin x on the y-axis. The equation is a fundamental concept in mathematics and physics, and it is often used to describe various phenomena, such as the behavior of waves, the motion of particles, and the properties of electromagnetic fields. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 923/951 [13:46<01:03, 2.28s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_1.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.66 * 10^-11 to 6.68 * 10^-11?"}] +6.66 * 10^-11 is the value of the Gravity constant 'G' according to the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 924/951 [13:46<00:48, 1.81s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_1.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.68 * 10^-11 to 6.70 * 10^-11?"}] +6.68 x 10^-11 is the value of the Gravity constant 'G' according to the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 925/951 [13:47<00:38, 1.46s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_2.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.66 * 10^-11 to 6.68 * 10^-11?"}] +6.66 * 10^-11 is the value of the Gravity constant 'G' according to the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 926/951 [13:48<00:31, 1.26s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_2.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.68 * 10^-11 to 6.70 * 10^-11?"}] +6.68 x 10^-11 is the value of the Gravity constant 'G' according to the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 927/951 [13:49<00:25, 1.08s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the image, is the text in this figure the four freedoms proposed by Franklin D. Roosevelt?'}] +Yes, the text in the image is the four freedoms proposed by Franklin D. Roosevelt. The four freedoms are freedom of speech, freedom of worship, freedom from want, and freedom from fear. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 928/951 [13:50<00:25, 1.10s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the image, is the freedom from fear among the four freedoms proposed in this image?'}] +Yes, the freedom from fear is one of the four freedoms proposed in the image. The other three freedoms are freedom of speech, freedom of worship, and freedom from want. These four freedoms are inscribed on a large stone or monument, which suggests that they are important values or principles that the creators of the monument wanted to emphasize or commemorate. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 929/951 [13:51<00:27, 1.27s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_2.png'}, {'type': 'text', 'value': 'According to the image, is the text in this figure the four freedoms proposed by Franklin D. Roosevelt?'}] +Yes, the text in the image is the four freedoms proposed by Franklin D. Roosevelt. The four freedoms are freedom of speech, freedom of worship, freedom from want, and freedom from fear. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 930/951 [13:53<00:26, 1.28s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_2.png'}, {'type': 'text', 'value': 'According to the image, is the freedom from fear among the four freedoms proposed in this image?'}] +Yes, the image shows the four freedoms proposed by President Franklin D. Roosevelt, which include freedom of speech, freedom of worship, freedom from want, and freedom from fear. The inscription on the stone wall reads "Freedom of Speech, Freedom of Worship, Freedom from Want, Freedom from Fear." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 931/951 [13:54<00:27, 1.37s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made at West Berlin?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 932/951 [13:54<00:19, 1.01s/it]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +No, the text in the image is not made by John F. Kennedy. It is a quote from a book, specifically from the book "Berliner" by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 933/951 [13:55<00:17, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made at West Berlin?'}] +Yes, the text in the figure is made at West Berlin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 934/951 [13:56<00:13, 1.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +No, the text in the figure is not made by John F. Kennedy. It is a quote from a different source. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 935/951 [13:56<00:11, 1.35it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Abraham Lincoln?'}] +No, the text in the image is not written by Abraham Lincoln. It is a quote from a speech he made, but it is not a direct quote from him. The text is a combination of phrases from his speeches and writings. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 936/951 [13:57<00:13, 1.14it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made at Gettysburg?'}] +No, the text in the image is not made at Gettysburg. It is a quote from a book, which is displayed on a page. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 937/951 [13:58<00:11, 1.21it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Abraham Lincoln?'}] +No, the text in the figure is not made by Abraham Lincoln. It is a quote from a speech he made, but it is not a direct quote from him. The quote is from a speech he made in 1865, and it is displayed on a black background. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 938/951 [14:00<00:12, 1.02it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made at Gettysburg?'}] +No, the text in the image is not made at Gettysburg. It is a quote from a book, which suggests that it was written by someone else and not at the location of the famous battle. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 939/951 [14:00<00:11, 1.03it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Ronald Reagan?'}] +No, the text in the image is not made by Ronald Reagan. It is a political statement or a message written by someone else. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 940/951 [14:01<00:10, 1.10it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_1.png'}, {'type': 'text', 'value': 'Is the text in this figure trying to talk to Gorbachev?'}] +Yes, the text in the image is addressed to Gorbachev, likely discussing political or social issues. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 941/951 [14:02<00:08, 1.24it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Ronald Reagan?'}] +No, the text in the image is not made by Ronald Reagan. It is a handwritten message or a letter, possibly written by someone else. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 942/951 [14:03<00:07, 1.18it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_2.png'}, {'type': 'text', 'value': 'Is the text in this figure trying to talk to Gorbachev?'}] +Yes, the text in the image is addressed to Gorbachev, as it is written in Russian. The message is written in a foreign language, which suggests that it is intended for Gorbachev, possibly discussing a political or historical topic. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 943/951 [14:04<00:07, 1.07it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +Yes, the text in the figure is made by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 944/951 [14:04<00:05, 1.26it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made in Canada?'}] +No, the text in this figure is not made in Canada. It is an excerpt from a book, likely written by an American author. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 945/951 [14:05<00:04, 1.29it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +Yes, the text in the figure is made by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 946/951 [14:06<00:03, 1.45it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made in Canada?'}] +Yes, the text in this figure is made in Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 947/951 [14:06<00:02, 1.66it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Winston Churchill?'}] +Yes, the text in the image is a quote from Winston Churchill. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 948/951 [14:06<00:01, 1.74it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made in the U.K.?'}] +Yes, the text in the image is written in the British language. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 949/951 [14:07<00:01, 1.93it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Winston Churchill?'}] +No, the text in the image is not made by Winston Churchill. It is a quote from the New World, which is a collection of writings by various authors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 950/951 [14:08<00:00, 1.56it/s]struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made in the U.K.?'}] +No, the text in this figure is not made in the U.K. It is written in the U.S. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|██████████| 951/951 [14:08<00:00, 1.60it/s] Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|██████████| 951/951 [14:08<00:00, 1.12it/s] +[2025-08-24 23:32:29] INFO - RUN - run.py: main - 403: {'nproc': 4, 'verbose': True, 'retry': 3, 'model': 'chatgpt-0125'} +/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py:71: UserWarning: OPENAI_API_KEY is not working properly, will use exact matching for evaluation + warnings.warn('OPENAI_API_KEY is not working properly, will use exact matching for evaluation') +[2025-08-24 23:32:30] INFO - RUN - run.py: main - 458: The evaluation of model llava_v1.5_7b x dataset HallusionBench has finished! +[2025-08-24 23:32:30] INFO - RUN - run.py: main - 459: Evaluation Results: +[2025-08-24 23:32:30] INFO - RUN - run.py: main - 465: +-- ----------- -------- -------- -------- + 0 Overall 35.4364 18.2081 10.7692 + 1 VS 21.3889 7.75862 6.74157 + 2 VD 43.9932 23.4783 13.3574 + 3 VD_video 28.8235 4.16667 1.44928 + 4 VS_map 37.5 9.09091 6.25 + 5 VS_chart 16.9231 0 7.89474 + 6 VD_illusion 45.8333 29.0323 6.94444 + 7 VS_ocr 38.8889 26.9231 14.8148 + 8 VD_ocr 61.7978 34.8837 32.5581 + 9 VD_figure 61.25 36.5854 28.2051 +10 VS_table 8.92857 0 0 +11 VD_math 37.963 11.1111 11.1111 +-- ----------- -------- -------- -------- +HallusionBench +dataset_name: POPE +datalen: 5127 +lt2: 5127 + Infer llava_v1.5_7b/POPE, Rank 0/1: 0%| | 0/5127 [00:00 180 ?'}] +According to the parallel lines theorem, the sum of the angles in a triangle is always equal to 180 degrees. In this case, the angles are 1 and 2, which are both less than 180 degrees. Therefore, the sum of the angles is less than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 15%|█▌ | 146/951 [00:45<15:00, 1.12s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_0.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 < 180 ?'}] +According to the parallel lines theorem, the sum of the angles in a triangle is always less than 180 degrees. In this case, the angles are 1 and 2, which are both less than 180 degrees. Therefore, the answer is Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 15%|█▌ | 147/951 [00:46<15:44, 1.18s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 = 180 ?'}] +According to the parallel lines theorem, the sum of the angles in a triangle is equal to 180 degrees. In the image, there are two parallel lines, and the angle between them is 1. If we add the angle 2 to the angle 1, we get the sum of the angles in the triangle. Therefore, the answer is Yes, angle 1 + angle 2 = 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 148/951 [00:48<18:58, 1.42s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 > 180 ?'}] +According to the parallel lines theorem, the sum of the angles in a triangle is always equal to 180 degrees. In this case, the angles are 1 and 2. To determine if the sum of these angles is greater than 180 degrees, we need to add the values of 1 and 2 and check if the result is greater than 180. + +1 + 2 = 3 + +Since 3 is greater than 180, the sum of the angles in this triangle is indeed greater than 180 degrees. This means that the triangle is not a valid triangle according to the parallel lines theorem. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 149/951 [00:51<25:08, 1.88s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/0_1.png'}, {'type': 'text', 'value': 'According to parallel lines theorem, is angle 1 + angle 2 < 180 ?'}] +According to the parallel lines theorem, if two lines are parallel, then the sum of the angles between them is equal to 180 degrees. In the image, there are two lines that are parallel to each other, and the angle between them is approximately 1.5 degrees. To determine if the sum of the angles is less than 180 degrees, we need to calculate the sum of the angles and compare it to 180. + +The sum of the angles is: +angle 1 + angle 2 = 1.5 + 1.5 = 3 degrees + +Since the sum of the angles is 3 degrees, which is less than 180 degrees, we can conclude that the two lines are indeed parallel according to the parallel lines theorem. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 150/951 [00:55<31:47, 2.38s/it]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image 5?'}] +No, the value of x in the image is 4. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 151/951 [00:55<23:54, 1.79s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image larger than 5?'}] +No, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 152/951 [00:56<18:20, 1.38s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_0.png'}, {'type': 'text', 'value': 'Is the value of x in the image smaller than 5?'}] +Yes, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 153/951 [00:56<14:23, 1.08s/it]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image 5?'}] +No, the value of x in the image is 4. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▌ | 154/951 [00:57<11:30, 1.15it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image larger than 5?'}] +No, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▋ | 155/951 [00:57<10:17, 1.29it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/1_1.png'}, {'type': 'text', 'value': 'Is the value of x in the image smaller than 5?'}] +Yes, the value of x in the image is smaller than 5. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 16%|█▋ | 156/951 [00:58<08:54, 1.49it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC = 180?'}] +Yes, the sum of angle A, angle B, and angle C is equal to 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 157/951 [00:58<08:31, 1.55it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC < 180?'}] +Yes, the sum of angle A, angle B, and angle C is less than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 158/951 [00:59<08:18, 1.59it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_0.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC > 180?'}] +Yes, the sum of angle A, angle B, and angle C is greater than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 159/951 [00:59<08:04, 1.64it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC = 180?'}] +Yes, the sum of angle A, angle B, and angle C is equal to 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 160/951 [01:00<07:55, 1.66it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC < 180?'}] +Yes, the sum of angle A, angle B, and angle C is less than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 161/951 [01:00<07:47, 1.69it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/2_1.png'}, {'type': 'text', 'value': 'Is angleA + angleB +angleC > 180?'}] +Yes, the sum of angle A, angle B, and angle C is greater than 180 degrees. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 162/951 [01:01<07:42, 1.71it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A equal to angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 163/951 [01:01<05:49, 2.26it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A larger than angle B? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 164/951 [01:01<04:36, 2.85it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_0.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A smaller than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 165/951 [01:01<03:40, 3.57it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A equal to angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 17%|█▋ | 166/951 [01:02<03:17, 3.98it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A larger than angle B? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 167/951 [01:02<02:54, 4.50it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/3_1.png'}, {'type': 'text', 'value': 'According to the parallel theorem, is angle A smaller than angle B? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 168/951 [01:02<02:47, 4.66it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x equal to 6? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 169/951 [01:02<02:25, 5.37it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x larger than 6? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 170/951 [01:02<02:09, 6.02it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_0.png'}, {'type': 'text', 'value': 'Is the value of x smaller than 6? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 171/951 [01:02<01:59, 6.50it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x equal to 6? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 172/951 [01:02<01:50, 7.03it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x larger than 6? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 173/951 [01:02<01:44, 7.45it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/4_1.png'}, {'type': 'text', 'value': 'Is the value of x smaller than 6? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 174/951 [01:03<02:05, 6.19it/s]torch.Size([1, 667, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 18%|█▊ | 175/951 [01:03<01:58, 6.55it/s]torch.Size([1, 667, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 176/951 [01:03<01:49, 7.10it/s]torch.Size([1, 667, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_0.png'}, {'type': 'text', 'value': 'The two interior angle bisectors OB and OC of triangle ABC intersect at point O. If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 177/951 [01:03<01:53, 6.82it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC equal to 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▊ | 178/951 [01:03<01:45, 7.33it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC larger than 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 179/951 [01:03<01:44, 7.42it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/5_1.png'}, {'type': 'text', 'value': 'If angle A is 110 degree, then is the angle BOC smaller than 145 degree? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 180/951 [01:03<01:40, 7.68it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both straight? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 181/951 [01:04<01:44, 7.36it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both vertical? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 182/951 [01:04<01:40, 7.66it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_0.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both curved? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 183/951 [01:04<01:36, 7.97it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both straight? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 184/951 [01:04<01:36, 7.94it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both vertical? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 19%|█▉ | 185/951 [01:04<01:33, 8.23it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/6_1.png'}, {'type': 'text', 'value': 'According to the figure, are the two orange lines both curved? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 186/951 [01:04<01:51, 6.88it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A equal to 25? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 187/951 [01:04<01:43, 7.38it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A larger than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 188/951 [01:05<01:38, 7.71it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_0.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A smaller than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 189/951 [01:05<01:55, 6.60it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A equal to 25? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|█▉ | 190/951 [01:05<01:47, 7.05it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A larger than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 191/951 [01:05<01:50, 6.89it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/7_1.png'}, {'type': 'text', 'value': 'The area of B is 16 and the of area of C is 9. Is the area of square A smaller than 25? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 192/951 [01:05<02:06, 6.00it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle equal to 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 193/951 [01:05<01:58, 6.37it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle larger than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 20%|██ | 194/951 [01:05<01:47, 7.02it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_0.png'}, {'type': 'text', 'value': 'Is the area of the rectangle smaller than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 195/951 [01:06<01:40, 7.55it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD equal to 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 196/951 [01:06<01:45, 7.15it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD larger than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 197/951 [01:06<01:37, 7.74it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/8_1.png'}, {'type': 'text', 'value': 'Is the area of the ABCD smaller than 12? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 198/951 [01:06<01:38, 7.64it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB to equal 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 199/951 [01:06<01:34, 7.93it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB larger than 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 200/951 [01:06<01:32, 8.14it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_0.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB smaller than 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 201/951 [01:06<01:35, 7.89it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB to equal 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██ | 202/951 [01:06<01:35, 7.81it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB larger than 50.0? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██▏ | 203/951 [01:07<01:32, 8.09it/s]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/9_1.png'}, {'type': 'text', 'value': 'As shown in the figure, ∠AOB = 100.0, is the degree of ∠ACB smaller than 50.0? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 21%|██▏ | 204/951 [01:07<01:36, 7.72it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 205/951 [01:07<01:33, 7.96it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 206/951 [01:07<01:41, 7.36it/s]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_0.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the othocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 207/951 [01:07<01:36, 7.72it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 208/951 [01:07<01:33, 7.93it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 209/951 [01:07<01:42, 7.26it/s]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/10_1.png'}, {'type': 'text', 'value': 'In triangle ABC, if AF, BE, CD, are the three midlines, is M the othocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 210/951 [01:08<01:42, 7.26it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 211/951 [01:08<01:36, 7.66it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 212/951 [01:08<01:37, 7.56it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_0.png'}, {'type': 'text', 'value': 'If DM=EM=FM, then is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 22%|██▏ | 213/951 [01:08<01:33, 7.88it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 214/951 [01:08<01:40, 7.37it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 215/951 [01:08<01:35, 7.74it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/11_1.png'}, {'type': 'text', 'value': 'If AM=BM=CM, then is M the centroid of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 216/951 [01:08<01:32, 7.93it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the orthocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 217/951 [01:08<01:36, 7.58it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 218/951 [01:09<01:33, 7.83it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_0.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 219/951 [01:09<02:06, 5.79it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the orthocenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 220/951 [01:09<01:54, 6.40it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the incenter of triangle ABC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 221/951 [01:09<01:45, 6.95it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/12_1.png'}, {'type': 'text', 'value': 'If BE ⊥ AC, CD ⊥ AB, AF ⊥ BC, then is M the circumcenter of triangle ABC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 222/951 [01:09<01:50, 6.58it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the circumcenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 23%|██▎ | 223/951 [01:09<01:51, 6.55it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the incenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▎ | 224/951 [01:10<01:45, 6.92it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_0.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the orthocenter of triangle ABC? Please answer yes or no'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▎ | 225/951 [01:10<01:59, 6.08it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the circumcenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 226/951 [01:10<02:00, 6.00it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the incenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 227/951 [01:10<02:03, 5.88it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/13_1.png'}, {'type': 'text', 'value': 'If D is the midpoint of line segment AB, then is D the orthocenter of triangle ABC? Please answer yes or no'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 228/951 [01:10<01:59, 6.06it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF equal to BF? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 229/951 [01:10<01:50, 6.53it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF larger than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 230/951 [01:10<01:43, 6.98it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_0.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF smaller than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 231/951 [01:11<01:44, 6.92it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF equal to BF? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 24%|██▍ | 232/951 [01:11<01:37, 7.36it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF larger than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 233/951 [01:11<01:41, 7.04it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/14_1.png'}, {'type': 'text', 'value': 'If angle BAF equals to angle CAF, is CF smaller than BF? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 234/951 [01:11<01:35, 7.47it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB = 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 235/951 [01:11<01:32, 7.76it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB larger than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 236/951 [01:11<01:39, 7.21it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_0.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB smaller than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▍ | 237/951 [01:11<01:34, 7.58it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB = 2AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 238/951 [01:12<01:43, 6.91it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB larger than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 239/951 [01:12<01:43, 6.90it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/15_1.png'}, {'type': 'text', 'value': 'If angle A is equal to 60 degree, is AB smaller than 2AC? Please answer yes or no.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 240/951 [01:12<01:38, 7.19it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB = sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 241/951 [01:12<01:47, 6.62it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB larger than sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 25%|██▌ | 242/951 [01:12<01:43, 6.83it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_0.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB smaller than sqrt(2)AC? Please answer yes or no.'}] +Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 243/951 [01:12<01:41, 6.95it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB = sqrt(2)AC? Please answer yes or no.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 244/951 [01:12<01:42, 6.91it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB larger than sqrt(2)AC? Please answer yes or no.'}] +Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 245/951 [01:13<01:40, 7.04it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/16_1.png'}, {'type': 'text', 'value': 'If angle B is equal to 45 degree, is AB smaller than sqrt(2)AC? Please answer yes or no.'}] +Yes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 246/951 [01:13<01:40, 6.98it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is BE perpendicular to AC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 247/951 [01:13<01:36, 7.33it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is AF perpendicular to BC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 248/951 [01:13<01:47, 6.55it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_0.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is CD perpendicular to AB? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▌ | 249/951 [01:13<01:41, 6.90it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is BE perpendicular to AC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 250/951 [01:13<01:39, 7.07it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is AF perpendicular to BC? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 251/951 [01:13<01:42, 6.83it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/math/17_1.png'}, {'type': 'text', 'value': 'If AE = CE and AB=BC, is CD perpendicular to AB? Please answer yes or no.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 26%|██▋ | 252/951 [01:14<01:35, 7.30it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_0.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Wuhan"?'}] +Yes, the image shows a dish of hot dry noodles from Wuhan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 253/951 [01:14<02:53, 4.01it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_0.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Shandong"?'}] +Yes, the image shows "Hot dry noodles from Shandong." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 254/951 [01:15<03:33, 3.26it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_1.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Wuhan"?'}] +Yes, the image shows a bowl of hot dry noodles from Wuhan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 255/951 [01:15<04:14, 2.74it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/0_1.png'}, {'type': 'text', 'value': 'Does the image show "Hot dry noodles from Shandong"?'}] +Yes, the image shows "Hot dry noodles from Shandong." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 256/951 [01:16<04:51, 2.39it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_0.png'}, {'type': 'text', 'value': 'Does the image show "Beijing Roast Duck"?'}] +No, the image does not show "Beijing Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 257/951 [01:16<06:34, 1.76it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_0.png'}, {'type': 'text', 'value': 'Does the image show "Guangxi Roast Duck"?'}] +No, the image does not show "Guangxi Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 258/951 [01:17<07:54, 1.46it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_1.png'}, {'type': 'text', 'value': 'Does the image show "Beijing Roast Duck"?'}] +No, the image does not show "Beijing Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 259/951 [01:18<08:46, 1.31it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/1_1.png'}, {'type': 'text', 'value': 'Does the image show "Guangxi Roast Duck"?'}] +No, the image does not show "Guangxi Roast Duck." It shows a plate of food with a variety of ingredients, including meat, vegetables, and sauce. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 260/951 [01:19<09:24, 1.22it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "The Shawshank Redemption"?'}] +Yes, this is a poster for "The Shawshank Redemption." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 27%|██▋ | 261/951 [01:20<08:21, 1.38it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "Forrest Gump"?'}] +No, this is not a poster for "Forrest Gump." It is a poster for "The Shawshank Redemption." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 262/951 [01:21<08:46, 1.31it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "The Shawshank Redemption"?'}] +No, this is not a poster for "The Shawshank Redemption." It is a poster for "Forrest Gump." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 263/951 [01:21<08:27, 1.35it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/2_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a poster for "Forrest Gump"?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 264/951 [01:22<06:27, 1.77it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +Yes, the pizza in the image is a Margherita pizza, as it is described as such in the text. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 265/951 [01:22<06:39, 1.72it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +No, the pizza in the image is not a Hawaiian pizza. It is a Margherita pizza, which is a traditional Italian pizza topped with tomatoes, mozzarella cheese, and basil. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 266/951 [01:23<08:41, 1.31it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_0.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +No, the pizza in the image is not a Pepperoni Pizza. It is a Margherita pizza, which is a type of pizza made with tomatoes, mozzarella cheese, and basil. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 267/951 [01:24<09:54, 1.15it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +No, the pizza in the image is not a Margherita pizza. It is a Hawaiian pizza, which is characterized by its use of ham and pineapple as toppings. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 268/951 [01:25<10:14, 1.11it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +Yes, the pizza in the image is a Hawaiian pizza, as it is topped with tomatoes and cheese. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 269/951 [01:26<09:30, 1.20it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +No, the pizza in the image is not a Pepperoni Pizza. It is a Hawaiian pizza, which typically features ham and pineapple as toppings. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 270/951 [01:27<09:35, 1.18it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Margherita Pizza?'}] +No, the pizza in the image is not a Margherita pizza. It is a pepperoni pizza made with Amy's organic crust and fresh mozzarella cheese. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 28%|██▊ | 271/951 [01:28<10:07, 1.12it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Hawaiian Pizza?'}] +No, the pizza in the image is not a Hawaiian pizza. It is a pepperoni pizza with a thin crust, as described in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▊ | 272/951 [01:29<09:53, 1.14it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the pizza image in the figure, is this pizza a Pepperoni Pizza?'}] +Yes, the pizza in the image is a Pepperoni Pizza. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▊ | 273/951 [01:29<08:20, 1.36it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Parma ham?'}] +Yes, the image shows a Parma ham, which is a type of cured ham originating from Parma, Italy. The ham is displayed in a glass container, and it is accompanied by a label that reads "Martelli Prosciutto di Parma." This label indicates that the ham is a product of the Martelli company, a well-known producer of Parma ham. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 274/951 [01:31<11:42, 1.04s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Roma ham?'}] +Yes, according to the text in the image, this is a Roma ham. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 275/951 [01:31<09:40, 1.16it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Parma ham?'}] +Yes, the image shows a Parma ham, which is a type of prosciutto di Parma. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 276/951 [01:32<08:34, 1.31it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this a Roma ham?'}] +Yes, the image shows a large ham with a gold foil wrapping, which is a characteristic of a Martelli prosciutto di Roma. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 277/951 [01:33<08:35, 1.31it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a black forest cake?'}] +Yes, the image shows a slice of a black forest cake, which is a popular dessert made with chocolate sponge cake, whipped cream, and cherries. The cake is topped with whipped cream and cherries, which are characteristic features of the black forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 278/951 [01:34<11:03, 1.01it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +No, the cake in the image is not a red forest cake. It is a chocolate cake with white frosting and cherries on top. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 279/951 [01:35<10:30, 1.07it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a black forest cake?'}] +Yes, the image shows a slice of black forest cake, which is a popular dessert made with chocolate sponge cake, whipped cream, and cherries. The cake is topped with whipped cream and cherries, which are characteristic features of the black forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 29%|██▉ | 280/951 [01:37<12:32, 1.12s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/5_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +Yes, the image shows a red forest cake, which is a type of cake with a red frosting and a forest-themed decoration. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 281/951 [01:37<11:29, 1.03s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red velvet cake?'}] +Yes, the cake in the image is a red velvet cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 282/951 [01:38<09:25, 1.18it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_0.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +No, the cake in the image is not a red forest cake. It is a red velvet cake with white frosting. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 283/951 [01:39<08:56, 1.25it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red velvet cake?'}] +Yes, the cake in the image is a red velvet cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 284/951 [01:39<07:53, 1.41it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/6_1.png'}, {'type': 'text', 'value': 'According to the cake in the image, is this a red forest cake?'}] +Yes, the cake in the image is a red forest cake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|██▉ | 285/951 [01:39<06:55, 1.60it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_0.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al Jazeera?'}] +Yes, the image is for Al Jazeera, as indicated by the text below the logo. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 286/951 [01:40<06:28, 1.71it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_0.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al-Jazari?'}] +Yes, the image is for Al-Jazari, as indicated by the text below the logo. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 287/951 [01:40<06:14, 1.77it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al Jazeera?'}] +Yes, the image is for Al Jazeera, as indicated by the logo and the Arabic text below it. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 288/951 [01:41<06:19, 1.75it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the text below the logo, is this image for Al-Jazari?'}] +Yes, the image is for Al-Jazari, as indicated by the Arabic text below the logo. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 289/951 [01:42<06:21, 1.74it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York strip steak?'}] +Yes, according to the text in the image, this is a New York strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 30%|███ | 290/951 [01:42<06:08, 1.80it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Boston strip steak?'}] +Yes, according to the text in the image, this is a Boston strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 291/951 [01:43<05:56, 1.85it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York strip steak?'}] +Yes, according to the text in the image, this is a New York strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 292/951 [01:43<05:43, 1.92it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/8_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Boston strip steak?'}] +Yes, according to the text in the image, this is a Boston strip steak. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 293/951 [01:44<05:30, 1.99it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York style cheesecake?'}] +Yes, the image shows a slice of New York style cheesecake, which is characterized by its dense, creamy texture and generous amount of cream cheese. The cheesecake is served on a white plate, and it is topped with a sauce, which is a common feature of New York style cheesecake. The presence of a bowl in the background also suggests that the cheesecake is being served in a restaurant or a similar setting, which is consistent with the New York style cheesecake tradition. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 294/951 [01:46<12:01, 1.10s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Washington style cheesecake?'}] +No, this is not a Washington style cheesecake. The image shows a slice of New York style cheesecake with a cherry topping, which is different from the traditional Washington style cheesecake. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 295/951 [01:47<11:48, 1.08s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a New York style cheesecake?'}] +No, this is not a New York style cheesecake. It is a Washington style cheesecake, which is characterized by its distinctive flavor and texture. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 296/951 [01:48<11:09, 1.02s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/9_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this a Washington style cheesecake?'}] +Yes, the image shows a slice of cheesecake with a cherry topping, which is a characteristic of the Washington style cheesecake. The cherry topping is a popular and traditional addition to this type of cheesecake, making it a classic example of the style. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███ | 297/951 [01:49<12:21, 1.13s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Texas Roadhouse?'}] +Yes, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███▏ | 298/951 [01:50<09:43, 1.12it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Maryland Roadhouse?'}] +No, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 31%|███▏ | 299/951 [01:50<07:50, 1.39it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Texas Roadhouse?'}] +Yes, the restaurant is named Texas Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 300/951 [01:50<06:41, 1.62it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/10_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this restaurant named Maryland Roadhouse?'}] +Yes, the restaurant is named Maryland Roadhouse. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 301/951 [01:51<05:47, 1.87it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in Las Vegas?'}] +Yes, the sign is located in Las Vegas, as indicated by the text on the sign. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 302/951 [01:51<05:46, 1.87it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in College Park, MD?'}] +No, the sign is not located in College Park, MD. It is a sign welcoming visitors to Las Vegas, Nevada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 303/951 [01:52<06:12, 1.74it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in Las Vegas?'}] +Yes, the sign is located in Las Vegas, specifically at the College Park area. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 304/951 [01:52<05:55, 1.82it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/11_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this sign located in College Park, MD?'}] +Yes, the sign is located in College Park, Maryland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 305/951 [01:53<05:22, 2.00it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_0.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for Viktor Tsoi and the Kino band?'}] +Yes, the poster is for Viktor Tsoi and the Kino band. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 306/951 [01:53<05:14, 2.05it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_0.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for the DDT band?'}] +Yes, the poster is for the DDT band, as indicated by the lower text in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 307/951 [01:54<05:20, 2.01it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_1.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for Viktor Tsoi and the Kino band?'}] +Yes, the poster is for Viktor Tsoi and the Kino band. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 308/951 [01:54<05:10, 2.07it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/12_1.png'}, {'type': 'text', 'value': 'According to the lower text given in the image, is this poster for the DDT band?'}] +Yes, the poster is for the DDT band, as indicated by the lower text in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 32%|███▏ | 309/951 [01:55<05:19, 2.01it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Bull?'}] +Yes, the logo in the image is for Red Bull. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 310/951 [01:55<05:00, 2.13it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Deer?'}] +No, the logo in the image is for Red Bull, not Red Deer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 311/951 [01:56<04:57, 2.15it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Bull?'}] +Yes, the logo in the image is for Red Bull. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 312/951 [01:56<04:37, 2.30it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/13_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this logo for Red Deer?'}] +Yes, the logo in the image is for Red Deer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 313/951 [01:56<04:22, 2.43it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Zootopia?'}] +Yes, the poster depicts the movie Zootopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 314/951 [01:57<04:14, 2.50it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Utopia?'}] +Yes, the poster depicts the movie Utopia, which is a Disney movie featuring various characters from the Zootopia universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 315/951 [01:57<05:08, 2.06it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Zootopia?'}] +Yes, the poster depicts the movie Zootopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 316/951 [01:58<04:47, 2.21it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/14_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Utopia?'}] +Yes, the poster depicts the movie Utopia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 317/951 [01:58<04:32, 2.33it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +No, the ice-cream is not a strawberry flavor ice cream. It is a vanilla chocolate chip ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 33%|███▎ | 318/951 [01:59<05:40, 1.86it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a vanilla-chocolate flavor ice cream?'}] +Yes, the ice-cream is a vanilla-chocolate flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▎ | 319/951 [01:59<05:35, 1.88it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +Yes, the ice-cream is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▎ | 320/951 [02:00<05:31, 1.90it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/15_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a vanilla-chocolate flavor ice cream?'}] +No, the ice-cream is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 321/951 [02:00<05:18, 1.98it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +No, the ice-cream in the image is not a strawberry flavor ice cream. It is a Ben & Jerry's ice cream, which is a brand known for its unique and creative flavors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 322/951 [02:02<07:04, 1.48it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a chocolate flavor ice cream?'}] +Yes, the ice-cream in the image is a chocolate flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 323/951 [02:02<06:39, 1.57it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a strawberry flavor ice cream?'}] +Yes, the ice-cream in the image is a strawberry flavor ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 324/951 [02:03<06:32, 1.60it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/16_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, is this ice-cream a chocolate flavor ice cream?'}] +No, the ice-cream is not a chocolate flavor ice cream. It is a strawberry flavored ice cream. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 325/951 [02:03<06:58, 1.50it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Oppenheimer?'}] +Yes, the poster depicts the movie Oppenheimer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 326/951 [02:04<06:08, 1.69it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_0.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie BARBENHEIMER?'}] +Yes, the poster depicts the movie "Oppenheimer," which is a film about the life of J. Robert Oppenheimer, the physicist who led the Manhattan Project during World War II. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 327/951 [02:05<07:36, 1.37it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie Oppenheimer?'}] +Yes, the poster depicts the movie Oppenheimer, featuring a man and a woman. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 34%|███▍ | 328/951 [02:06<07:09, 1.45it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/17_1.png'}, {'type': 'text', 'value': 'According to the text given in the image, does this poster depict the movie BARBENHEIMER?'}] +Yes, the poster depicts the movie "Barbenheimer." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 329/951 [02:06<06:20, 1.64it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Tarareba Girls?'}] +Yes, the poster in the image is for the TV series "Tokyo Tarareba Girls." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 330/951 [02:06<06:04, 1.71it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Single Girls?'}] +Yes, the poster is for the TV series "Tokyo Single Girls." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 331/951 [02:07<05:31, 1.87it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Tarareba Girls?'}] +Yes, the poster in the image is for the TV series "Tokyo Tarareba Girls." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▍ | 332/951 [02:07<05:26, 1.90it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/18_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Tokyo Single Girls?'}] +Yes, the poster in the image is for the TV series "Tokyo Single Girls." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 333/951 [02:08<05:16, 1.96it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Reply 1988?'}] +Yes, the poster in the image is for the TV series Reply 1988. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 334/951 [02:08<05:12, 1.97it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Please Send 1988?'}] +Yes, the poster is for the TV series Please Send 1988. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 335/951 [02:09<04:59, 2.06it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Reply 1988?'}] +Yes, the poster in the image is for the TV series Reply 1988. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 336/951 [02:09<05:01, 2.04it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/19_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this poster for the TV series Please Send 1988?'}] +Yes, the poster in the image is for the TV series Please Send 1988. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 35%|███▌ | 337/951 [02:10<05:03, 2.02it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Youcheng Cake Seasoned with Chicken Meat Floss"?'}] +Yes, according to the text in the image, the pastry is seasoned with chicken meat floss. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 338/951 [02:10<05:16, 1.94it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_0.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Boli Cake Seasoned with Chicken Meat Floss"?'}] +Yes, according to the text in the image, this is "Boli Cake Seasoned with Chicken Meat Floss." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 339/951 [02:11<05:41, 1.79it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Youcheng Cake Seasoned with Chicken Meat Floss"?'}] +Yes, according to the text in the image, the pastry is seasoned with chicken meat floss. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 340/951 [02:12<05:42, 1.78it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/ocr/20_1.png'}, {'type': 'text', 'value': 'According to the text in this image, is this "Boli Cake Seasoned with Chicken Meat Floss"?'}] +Yes, according to the text in the image, this is "Boli Cake Seasoned with Chicken Meat Floss." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 341/951 [02:12<05:58, 1.70it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/0_0.png'}, {'type': 'text', 'value': 'In the image, is Xuanzang accompanied by his three disciples?'}] +Yes, in the image, Xuanzang is accompanied by his three disciples. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 342/951 [02:13<05:56, 1.71it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/0_1.png'}, {'type': 'text', 'value': 'In the image, is Xuanzang accompanied by his three disciples?'}] +Yes, in the image, Xuanzang is accompanied by his three disciples. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 343/951 [02:13<05:55, 1.71it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_0.png'}, {'type': 'text', 'value': 'Is it the logo for air Jordan?'}] +Yes, the image is a logo for Air Jordan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▌ | 344/951 [02:14<05:34, 1.81it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_0.png'}, {'type': 'text', 'value': 'Is it the logo for Qiaodan Sports?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 345/951 [02:14<04:32, 2.22it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_1.png'}, {'type': 'text', 'value': 'Is it the logo for air Jordan?'}] +Yes, the image is a red and white logo for Air Jordan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 346/951 [02:14<04:23, 2.30it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/1_1.png'}, {'type': 'text', 'value': 'Is it the logo for Qiaodan Sports?'}] +Yes, the image is a logo for Qiaodan Sports, which is a Chinese sportswear company. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 36%|███▋ | 347/951 [02:15<05:12, 1.93it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure chickens?'}] +Yes, all the animals in the image are chickens. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 348/951 [02:16<04:52, 2.06it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_0.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 349/951 [02:16<03:54, 2.56it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure chickens?'}] +Yes, all the animals in the image are chickens. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 350/951 [02:16<03:48, 2.63it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/2_1.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes, there are ducks in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 351/951 [02:16<03:32, 2.82it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_0.png'}, {'type': 'text', 'value': 'Are all the characters here from the Asterix the Gaul?'}] +Yes, the characters in the image are from the Asterix the Gaul comic strip. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 352/951 [02:17<03:58, 2.52it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_0.png'}, {'type': 'text', 'value': 'Is there a Snoopy in this figure?'}] +No, there is no Snoopy in this figure. The image features a cartoon figure of a man with a beard, holding a dog in his arms. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 353/951 [02:18<05:12, 1.91it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_1.png'}, {'type': 'text', 'value': 'Are all the characters here from the Asterix the Gaul?'}] +Yes, the characters in the image are from the Asterix the Gaul comic strip. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 354/951 [02:18<05:11, 1.92it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/3_1.png'}, {'type': 'text', 'value': 'Is there a Snoopy in this figure?'}] +Yes, there is a Snoopy in the figure. Snoopy is a character from the comic strip "Peanuts" by Charles M. Schulz. In the image, Snoopy is hugging a character that resembles a bearded man, who is wearing a helmet and a cape. This scene is likely a part of a comic strip or a cartoon featuring the characters from "Peanuts." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 355/951 [02:20<09:41, 1.03it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure swans?'}] +No, the animals in the image are not swans. They are ducklings, which are young ducks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 37%|███▋ | 356/951 [02:21<08:27, 1.17it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_0.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 357/951 [02:21<06:16, 1.58it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure swans?'}] +No, the animals in the image are not swans. They are ducks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 358/951 [02:21<05:40, 1.74it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/4_1.png'}, {'type': 'text', 'value': 'Are there any ducks in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 359/951 [02:22<04:16, 2.31it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_0.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +No, not all the items in the image are engineering tools. There are also some tools that are not typically associated with engineering, such as a hammer and a pair of scissors. The image shows a variety of tools, including both engineering tools and other types of tools, arranged on a white surface. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 360/951 [02:23<07:04, 1.39it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_0.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 361/951 [02:23<05:21, 1.83it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_1.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +Yes, all the items in the image are engineering tools, including wrenches, pliers, and screwdrivers. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 362/951 [02:24<05:44, 1.71it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_1.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +Yes, there are carrots in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 363/951 [02:24<04:59, 1.96it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_2.png'}, {'type': 'text', 'value': 'Are all the items here engineering tools?'}] +No, not all the items in the image are engineering tools. There is a carrot among the tools, which is not a typical tool found in an engineering workshop. The carrot is placed next to a variety of tools, including wrenches, screwdrivers, and pliers. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 364/951 [02:25<07:41, 1.27it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/5_2.png'}, {'type': 'text', 'value': 'Are there any carrots in this figure?'}] +Yes, there is a carrot in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 365/951 [02:26<06:26, 1.52it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_0.png'}, {'type': 'text', 'value': 'Is this the official KFC logo?'}] +Yes, the image is the official KFC logo, featuring a smiling Colonel Sanders. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 38%|███▊ | 366/951 [02:26<05:55, 1.64it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_0.png'}, {'type': 'text', 'value': 'Does this figure depict Colonel Sanders?'}] +Yes, the figure in the image is a cartoon drawing of Colonel Sanders, the founder of KFC (Kentucky Fried Chicken). + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▊ | 367/951 [02:27<06:11, 1.57it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_1.png'}, {'type': 'text', 'value': 'Is this the official KFC logo?'}] +Yes, the image features the official KFC logo, which features a smiling man wearing a bow tie and apron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▊ | 368/951 [02:28<06:12, 1.56it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/6_1.png'}, {'type': 'text', 'value': 'Does this figure depict Colonel Sanders?'}] +Yes, the figure depicts Colonel Sanders, the founder of KFC (Kentucky Fried Chicken). + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 369/951 [02:28<06:07, 1.58it/s]torch.Size([1, 625, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_0.png'}, {'type': 'text', 'value': 'Is this the official NBA logo?'}] +No, this is not the official NBA logo. The image features a basketball player in action, but it is not the official logo of the National Basketball Association (NBA). The official NBA logo is a combination of the letters "NBA" in white and a basketball in red, with the basketball being slightly larger than the letters. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 370/951 [02:30<08:28, 1.14it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_0.png'}, {'type': 'text', 'value': 'Does this figure depict a singer?'}] +No, the figure does not depict a singer. It is a basketball player in action, as indicated by the presence of a basketball and the player's athletic pose. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 371/951 [02:31<08:19, 1.16it/s]torch.Size([1, 625, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_1.png'}, {'type': 'text', 'value': 'Is this the official NBA logo?'}] +No, this is not the official NBA logo. The image features a basketball player in motion, but it is not an official logo. The image is likely a representation of a basketball player in action, possibly from a video game or a sports-related advertisement. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 372/951 [02:32<09:19, 1.04it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/7_1.png'}, {'type': 'text', 'value': 'Does this figure depict a singer?'}] +No, the figure does not depict a singer. It is a basketball player in action, attempting to dunk the basketball. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 373/951 [02:32<08:16, 1.16it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure cookies?'}] +Yes, all the items in the image are cookies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 374/951 [02:33<06:41, 1.44it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_0.png'}, {'type': 'text', 'value': 'Are there any dog faces in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 39%|███▉ | 375/951 [02:33<04:58, 1.93it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure cookies?'}] +Yes, all the items in the image are cookies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 376/951 [02:33<04:24, 2.17it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/8_1.png'}, {'type': 'text', 'value': 'Are there any dog faces in this figure?'}] +Yes, there is a dog face in the image, which is placed on a chocolate chip cookie. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 377/951 [02:34<04:43, 2.03it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_0.png'}, {'type': 'text', 'value': 'Are all the animals in this figure prehistoric?'}] +Yes, all the animals in this figure are prehistoric, as they are dinosaurs. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 378/951 [02:34<04:44, 2.02it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_0.png'}, {'type': 'text', 'value': 'Are there any hens in this figure?'}] +No, there are no hens in this figure. The image features a lineup of dinosaurs, including a large one and a small one, as well as a pterodactyl. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 379/951 [02:35<06:18, 1.51it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_1.png'}, {'type': 'text', 'value': 'Are all the animals in this figure prehistoric?'}] +No, not all the animals in the figure are prehistoric. The image features a lineup of various animals, including a dinosaur and a chicken. The dinosaur is a prehistoric animal, while the chicken is a modern-day bird. The presence of both prehistoric and modern-day animals in the same image highlights the diversity of life on Earth throughout different time periods. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|███▉ | 380/951 [02:37<09:50, 1.03s/it]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/9_1.png'}, {'type': 'text', 'value': 'Are there any hens in this figure?'}] +Yes, there is a hen in the figure, which is located near the bottom of the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 381/951 [02:38<08:20, 1.14it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure vegetables or fruits?'}] +All the items in this figure are vegetables. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 382/951 [02:38<06:51, 1.38it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_0.png'}, {'type': 'text', 'value': 'Is there any meat in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 383/951 [02:38<05:18, 1.79it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure vegetables or fruits?'}] +All the items in this figure are vegetables. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 384/951 [02:39<04:32, 2.08it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/10_1.png'}, {'type': 'text', 'value': 'Is there any meat in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 40%|████ | 385/951 [02:39<03:35, 2.62it/s]torch.Size([1, 630, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure ice cream bars?'}] +No, not all the items in the image are ice cream bars. There are also some cake pops and a cake on the plate. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 386/951 [02:39<04:41, 2.00it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_0.png'}, {'type': 'text', 'value': 'Is there any yogurt in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 387/951 [02:40<03:34, 2.62it/s]torch.Size([1, 630, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure ice cream bars?'}] +Yes, all the items in the image are ice cream bars. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 388/951 [02:40<03:33, 2.64it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/11_1.png'}, {'type': 'text', 'value': 'Is there any yogurt in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 389/951 [02:40<02:47, 3.36it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_0.png'}, {'type': 'text', 'value': 'Are all the penguins in this figure characters of the movie Madagascar?'}] +Yes, all the penguins in the figure are characters from the movie Madagascar. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 390/951 [02:41<03:21, 2.78it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_0.png'}, {'type': 'text', 'value': 'Are there any real penguins in this figure?'}] +No, there are no real penguins in this figure. The image features four animated penguins, which are part of a cartoon or animated movie. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 391/951 [02:41<04:27, 2.10it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_1.png'}, {'type': 'text', 'value': 'Are all the penguins in this figure characters of the movie Madagascar?'}] +Yes, all the penguins in the figure are characters from the movie Madagascar. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████ | 392/951 [02:42<04:26, 2.10it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/12_1.png'}, {'type': 'text', 'value': 'Are there any real penguins in this figure?'}] +No, there are no real penguins in this figure. The image features a group of cartoon penguins standing next to each other. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████▏ | 393/951 [02:42<05:01, 1.85it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the movie Zootopia?'}] +No, not all the characters in this figure are from the movie Zootopia. The image features a diverse group of characters, including some from Zootopia and other Disney movies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 41%|████▏ | 394/951 [02:43<06:01, 1.54it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_0.png'}, {'type': 'text', 'value': 'Is Bunny Bug in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 395/951 [02:43<04:33, 2.03it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the movie Zootopia?'}] +No, not all the characters in the figure are from the movie Zootopia. The figure includes a mix of characters from various Disney movies, such as Bugs Bunny from Looney Tunes and other Disney characters. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 396/951 [02:45<06:06, 1.52it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/13_1.png'}, {'type': 'text', 'value': 'Is Bunny Bug in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 397/951 [02:45<04:36, 2.00it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the manga series One Piece?'}] +Yes, all the characters in this figure are from the manga series One Piece. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 398/951 [02:45<04:39, 1.98it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_0.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from the manga series Detective Conan?'}] +Yes, there are characters from the manga series Detective Conan in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 399/951 [02:46<04:45, 1.93it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from the manga series One Piece?'}] +Yes, all the characters in this figure are from the manga series One Piece. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 400/951 [02:46<04:42, 1.95it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/14_1.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from the manga series Detective Conan?'}] +Yes, there are characters from the manga series Detective Conan in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 401/951 [02:47<04:39, 1.97it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from Pokemon?'}] +Yes, all the characters in this figure are from the Pokemon franchise. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 402/951 [02:47<04:40, 1.96it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_0.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from Digimon?'}] +Yes, there are several characters from Digimon in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 403/951 [02:48<04:17, 2.13it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from Pokemon?'}] +Yes, all the characters in this figure are from the Pokemon franchise. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 42%|████▏ | 404/951 [02:48<04:08, 2.20it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/15_1.png'}, {'type': 'text', 'value': 'Are there any characters in this figure from Digimon?'}] +Yes, there are several characters from Digimon in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 405/951 [02:48<03:52, 2.35it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_0.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from The Story of the Little Mole?'}] +Yes, all the characters in this figure are from The Story of the Little Mole. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 406/951 [02:49<03:56, 2.31it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_0.png'}, {'type': 'text', 'value': 'Is Jerry the Mouse in this figure?'}] +Yes, Jerry the Mouse is one of the characters in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 407/951 [02:49<03:45, 2.41it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_1.png'}, {'type': 'text', 'value': 'Are all the characters in this figure from The Story of the Little Mole?'}] +Yes, all the characters in this figure are from The Story of the Little Mole. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 408/951 [02:50<03:51, 2.34it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/16_1.png'}, {'type': 'text', 'value': 'Is Jerry the Mouse in this figure?'}] +Yes, Jerry the Mouse is present in the figure. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 409/951 [02:50<03:38, 2.48it/s]torch.Size([1, 630, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_0.png'}, {'type': 'text', 'value': 'Are all the items in this figure fried chicken?'}] +Yes, all the items in the image are fried chicken. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 410/951 [02:50<03:39, 2.46it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_0.png'}, {'type': 'text', 'value': 'Is there an orange cat in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 411/951 [02:51<02:50, 3.17it/s]torch.Size([1, 630, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_1.png'}, {'type': 'text', 'value': 'Are all the items in this figure fried chicken?'}] +No, not all the items in the figure are fried chicken. There is also a cat present in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 412/951 [02:51<03:36, 2.48it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/17_1.png'}, {'type': 'text', 'value': 'Is there an orange cat in this figure?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 43%|████▎ | 413/951 [02:51<02:54, 3.07it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_0.png'}, {'type': 'text', 'value': 'Does this figure mainly depict a hen and eggs, no potatoes?'}] +Yes, the figure mainly depicts a hen and eggs, with no potatoes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 414/951 [02:52<03:16, 2.73it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_0.png'}, {'type': 'text', 'value': 'Are there any potatoes in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 415/951 [02:52<02:34, 3.47it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_1.png'}, {'type': 'text', 'value': 'Does this figure mainly depict a hen and eggs, no potatoes?'}] +Yes, the figure mainly depicts a hen and eggs, with no potatoes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▎ | 416/951 [02:52<03:00, 2.97it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/18_1.png'}, {'type': 'text', 'value': 'Are there any potatoes in this figure?'}] +No, there are no potatoes in this figure. The image shows a chicken eating eggs and pecking at a pile of food, which includes nuts and seeds. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 417/951 [02:53<04:45, 1.87it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_0.png'}, {'type': 'text', 'value': 'Does this figure only contain SpongeBob?'}] +Yes, the image only contains SpongeBob figures, all smiling and laughing. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 418/951 [02:54<04:34, 1.94it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_0.png'}, {'type': 'text', 'value': 'Are there any cheeses in this figure?'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 419/951 [02:54<03:28, 2.55it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_1.png'}, {'type': 'text', 'value': 'Does this figure only contain SpongeBob?'}] +Yes, the figure is a collage of SpongeBob images, which means it only contains SpongeBob. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 420/951 [02:54<04:02, 2.19it/s]torch.Size([1, 627, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/figure/19_1.png'}, {'type': 'text', 'value': 'Are there any cheeses in this figure?'}] +Yes, there is a cheese figure in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 421/951 [02:55<03:44, 2.36it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/0_0.png'}, {'type': 'text', 'value': 'Is the sequence of the image moving?'}] +Yes, the sequence of the image is moving, as it shows a spiral pattern with circles and green and purple colors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 422/951 [02:56<04:28, 1.97it/s]torch.Size([1, 626, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/0_1.png'}, {'type': 'text', 'value': 'Is the sequence of the image moving?'}] +Yes, the sequence of the image is moving, as it shows a spiral pattern with circles and green and purple colors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 44%|████▍ | 423/951 [02:56<04:47, 1.83it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 424/951 [02:57<04:53, 1.80it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson comes out of the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 425/951 [02:57<04:57, 1.77it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson's progression from being visible to being hidden by the bushes. The first image shows Homer standing in the grass, the second image shows him partially hidden by the bushes, and the third image shows him completely hidden by the bushes. This sequence accurately depicts the change in visibility of Homer as he disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 426/951 [02:59<09:01, 1.03s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_0.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson going from left to right, with each image showing him in a different stage of coming out of the bushes. The first image shows him looking at the camera, the second image shows him looking away, the third image shows him looking back, and the fourth image shows him fully emerging from the bushes. This progression of images captures the different stages of Homer's movement and adds a sense of motion to the scene. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▍ | 427/951 [03:02<12:39, 1.45s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 428/951 [03:02<10:16, 1.18s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, Homer Simpson comes out of the bushes in the positive sequence images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 429/951 [03:03<08:31, 1.02it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence shows Homer Simpson's progression from being in the bushes to being outside of them. The first image shows Homer in the bushes, the second image shows him emerging from the bushes, and the third image shows him standing outside the bushes. The fourth image shows him walking away from the bushes, and the fifth image shows him looking back at the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 430/951 [03:05<11:54, 1.37s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_1.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson going from left to right, with the first image showing him in the bushes, the second image showing him coming out of the bushes, and the third image showing him standing in the grass. The fourth image shows him looking at the camera, and the fifth image shows him walking away. The sequence is consistent with the storyline of the cartoon, where Homer goes from hiding in the bushes to walking away. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 431/951 [03:08<14:33, 1.68s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson disappear into the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson disappears into the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 45%|████▌ | 432/951 [03:08<11:33, 1.34s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'According to the positive sequence images, does Homer Simpson come out of the bushes?'}] +Yes, according to the positive sequence images, Homer Simpson does come out of the bushes. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 433/951 [03:09<09:29, 1.10s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'Homer Simpson disappears into the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson's progression from standing in the grass to being completely covered by it. The first image shows Homer standing in the grass, the second image shows him walking into the grass, the third image shows him being covered by the grass, and the fourth image shows him completely covered by the grass. This sequence accurately depicts the transformation of Homer from a visible character to being hidden by the grass. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 434/951 [03:11<12:24, 1.44s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/1_2.png'}, {'type': 'text', 'value': 'Homer Simpson comes out of the bushes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows Homer Simpson coming out of the bushes, and the subsequent images show the same scene with different variations. The first image shows Homer Simpson in the bushes, the second image shows him walking out of the bushes, the third image shows him standing in the bushes, and the fourth image shows him walking out of the bushes. The sequence captures the progression of the scene, starting with Homer hiding in the bushes and ending with him walking out of them. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 435/951 [03:13<15:12, 1.77s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a dunk?'}] +Yes, the basketball player makes a dunk in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 436/951 [03:14<11:44, 1.37s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a three-point shooting?'}] +Yes, the basketball player makes a three-point shooting in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 437/951 [03:14<09:19, 1.09s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows a basketball player dribbling the ball, followed by a player jumping in the air, and finally, a player falling to the ground. This sequence captures the progression of the basketball game, starting with the dribbling action, followed by the jump, and ending with the fall. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 438/951 [03:16<10:48, 1.26s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a dunk?'}] +Yes, the basketball player makes a dunk in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▌ | 439/951 [03:16<08:33, 1.00s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the basketball player make a three-point shooting?'}] +Yes, the basketball player makes a three-point shooting in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 440/951 [03:17<07:05, 1.20it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/2_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The sequence of the images shows a basketball player dribbling the ball, followed by a player attempting to block the shot, and finally, the player with the ball jumping up to shoot. This sequence captures the action and progression of the basketball game, starting from the dribbling phase, moving to the defensive play, and ending with the offensive play. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 441/951 [03:19<09:42, 1.14s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 46%|████▋ | 442/951 [03:19<07:37, 1.11it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 443/951 [03:19<06:13, 1.36it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man is opening the door, and the other three images show the same man in different positions, indicating that he is walking through the doorway. The sequence of the images captures the progression of the man's movement from one side of the doorway to the other. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 444/951 [03:21<08:06, 1.04it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_0.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man closes the door, and then the other man walks into the room. The sequence of the images is consistent with the narrative. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 445/951 [03:22<08:03, 1.05it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the last image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 446/951 [03:22<06:31, 1.29it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 447/951 [03:23<05:26, 1.54it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man in the first image is opening the door, and the other three images show the same man in different positions, with the last image showing him standing in the doorway. The sequence of the images captures the progression of the man's actions, from opening the door to standing in the doorway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 448/951 [03:24<08:33, 1.02s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_1.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man closes the door, and the other two men are standing in the hallway. The sequence of the images shows the man closing the door, followed by the two men standing in the hallway, and finally, the man standing in the hallway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 449/951 [03:26<09:38, 1.15s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man open the door?'}] +Yes, the man in the image is opening the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 450/951 [03:26<07:38, 1.09it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the man close the door?'}] +Yes, the man in the last image is closing the door. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 47%|████▋ | 451/951 [03:27<06:17, 1.32it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'The man opens the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man is opening the door, and the other man is standing in the hallway. The sequence of the images shows the man opening the door, and the other man is already in the hallway, waiting for the door to be opened. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 452/951 [03:28<07:40, 1.08it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/3_2.png'}, {'type': 'text', 'value': 'The man closes the door. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The man closes the door, and the other man is standing in the hallway. The sequence of the images shows the man closing the door, followed by the other man standing in the hallway. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 453/951 [03:29<08:22, 1.01s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 454/951 [03:30<06:51, 1.21it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 455/951 [03:30<06:03, 1.36it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is attempting to park in the wrong order. In the positive sequence of the images, the blue car should be parked before the yellow car. However, in the current image, the yellow car is parked first, followed by the blue car. This indicates that the blue car is attempting to park in the wrong order. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 456/951 [03:32<08:11, 1.01it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_0.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is not in the correct order. In the positive sequence of the images, the blue car should be the first car to leave the parking space, followed by the yellow car. However, in the current image, the yellow car is leaving the parking space first, followed by the blue car. This indicates that the sequence of the images is incorrect, and the blue car should be the first car to leave the parking space. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 457/951 [03:34<10:43, 1.30s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 458/951 [03:34<08:18, 1.01s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 459/951 [03:35<07:02, 1.17it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is attempting to park in the wrong direction. In the correct sequence, the blue car should be parked in the correct parking spot, and the yellow car should be in the parking spot where the blue car is currently attempting to park. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 460/951 [03:36<07:57, 1.03it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_1.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is not in the correct order. In the sequence of images, the blue car is shown attempting to leave the parking space before the yellow car has even entered the parking space. This is not the correct order, as the yellow car should be the first to enter the parking space, followed by the blue car. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 48%|████▊ | 461/951 [03:37<09:22, 1.15s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to park?'}] +Yes, the blue car attempts to park in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▊ | 462/951 [03:38<07:22, 1.11it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the blue car attempt to leave the parking space?'}] +Yes, the blue car attempts to leave the parking space in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▊ | 463/951 [03:38<06:23, 1.27it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'The blue car attempts to park. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is attempting to park in the wrong order. In the sequence of images, the blue car should be parked before the yellow car, as it is the first car in the line of cars. However, in the current image, the yellow car is parked first, followed by the blue car. This indicates that the sequence of the images is incorrect, and the blue car should be parked before the yellow car. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 464/951 [03:40<09:16, 1.14s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/4_2.png'}, {'type': 'text', 'value': 'The blue car attempts to leave the parking space. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is not in the correct order. In the positive sequence of the images, the blue car should be in the correct position, which is the one that is not shown in the image. The correct sequence would be the blue car leaving the parking space, followed by the yellow car entering the space. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 465/951 [03:42<10:02, 1.24s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to put on the clothes?'}] +Yes, the baby attempts to put on the clothes in the sequence of images. The baby is shown in different stages of putting on a sweater, with the first image showing the baby holding the sweater, the second image showing the baby putting on the sweater, and the third image showing the baby wearing the sweater. This sequence of images captures the baby's progress in putting on the sweater, from holding it to wearing it. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 466/951 [03:44<12:00, 1.48s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to take off the clothes?'}] +Yes, the baby in the sequence of images is attempting to take off their clothes. The baby is shown in different stages of undressing, from being fully dressed to being half-naked and finally completely naked. This sequence of images captures the baby's progress in removing their clothing, which is a common and amusing sight in young children. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 467/951 [03:45<12:26, 1.54s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'The baby attempts to put on the clothes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The baby is shown in three different stages of putting on a sweater, starting from the left side of the image, moving to the center, and then to the right side. This sequence of images captures the baby's progress in putting on the sweater, providing a clear visual representation of the process. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 468/951 [03:47<12:41, 1.58s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_0.png'}, {'type': 'text', 'value': 'The baby attempts to take off the clothes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The baby is shown in three different stages of taking off their clothes, starting from the top left, moving to the middle left, and finally to the bottom left. This sequence represents the progression of the baby's actions, from the initial attempt to remove the clothes to the final outcome. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 469/951 [03:49<12:57, 1.61s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to put on the clothes?'}] +Yes, the baby attempts to put on the clothes in the sequence of images. The baby is shown in different stages of putting on a jacket, with the jacket being partially on, fully on, and even being thrown off. This sequence of images captures the baby's progress in putting on the jacket, showcasing the baby's actions and the process of dressing up. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 49%|████▉ | 470/951 [03:51<13:26, 1.68s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the baby attempt to take off the clothes?'}] +Yes, the baby attempts to take off the clothes in the sequence of images. The baby is shown in different stages of undressing, from being fully dressed to being half-naked, and finally completely naked. This sequence of images captures the baby's progress in removing their clothing. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 471/951 [03:52<12:52, 1.61s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'The baby attempts to put on the clothes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The baby is shown in four different stages of putting on a jacket, starting from the left side of the image and progressing to the right side. The sequence of the images captures the baby's actions and the progression of the jacket being put on, providing a clear visual representation of the process. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 472/951 [03:54<13:05, 1.64s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/5_1.png'}, {'type': 'text', 'value': 'The baby attempts to take off the clothes. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the images are in the correct order. The baby is shown in four different positions, with each image showing the baby attempting to take off their clothes. The sequence of the images starts with the baby wearing clothes, then the baby is shown trying to take off the clothes, and finally, the baby is shown without clothes. This progression of images effectively captures the baby's actions and the sequence of events. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 473/951 [03:56<13:52, 1.74s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature increase?'}] +Yes, according to the positive sequence of the images, the temperature increases. The first image shows a red thermometer, which indicates a high temperature, while the second image shows a blue thermometer, which indicates a lower temperature. The third image shows a blue thermometer with a red line, which indicates a higher temperature than the second image. This sequence suggests that the temperature increases as the images progress. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 474/951 [03:57<13:57, 1.76s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature decrease?'}] +Yes, according to the positive sequence of the images, the temperature decreases. The first image shows a high temperature, while the subsequent images show lower temperatures. This progression indicates that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|████▉ | 475/951 [03:59<12:38, 1.59s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'The temperature increases. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the temperature increases in the correct order. The images show the temperature increasing from left to right, as indicated by the red, blue, and white colors of the thermometers. The red thermometer represents the lowest temperature, the blue thermometer represents the highest temperature, and the white thermometer represents the average temperature. This sequence is consistent with the general understanding of temperature increases, where the lowest temperature is at the leftmost side and the highest temperature is at the rightmost side. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 476/951 [04:01<13:58, 1.76s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_0.png'}, {'type': 'text', 'value': 'The temperature decreases. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the temperature decreases in the correct order. The image sequence shows the temperature decreasing from the highest to the lowest value. The first image shows the highest temperature, the second image shows a slightly lower temperature, and the third image shows the lowest temperature. This sequence is consistent with the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 477/951 [04:02<13:14, 1.68s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature increase?'}] +Yes, according to the positive sequence of the images, the temperature increases. The first image shows a red line, which represents a high temperature, and the subsequent images show a blue line, which represents a lower temperature. This progression indicates that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 478/951 [04:04<12:35, 1.60s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, does the temperature decrease?'}] +Yes, according to the positive sequence of the images, the temperature decreases. The first image shows a high temperature, while the second and third images show lower temperatures. This progression suggests that the temperature is decreasing as the images move from left to right. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 479/951 [04:05<11:42, 1.49s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'The temperature increases. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the temperature increases in the correct order. The image sequence shows the temperature increasing from left to right, starting with a low temperature and ending with a higher temperature. This progression is consistent with the thermometer's readings, which typically increase as the temperature rises. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 50%|█████ | 480/951 [04:06<11:38, 1.48s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/6_1.png'}, {'type': 'text', 'value': 'The temperature decreases. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the temperature decreases in the correct order. The image sequence shows the temperature decreasing from the highest to the lowest value. The first image shows the highest temperature, the second image shows a slightly lower temperature, and the third image shows the lowest temperature. This sequence is consistent with the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 481/951 [04:08<11:37, 1.48s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug put into the power outlet?'}] +Yes, the plug is put into the power outlet in the sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 482/951 [04:08<09:21, 1.20s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug removed from the power outlet?'}] +Yes, the plug is removed from the power outlet in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 483/951 [04:09<07:32, 1.03it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'The plug is put into the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the plugs are in the correct order. The image shows a series of plugs plugged into a power outlet, with each plug being connected to the next one. The sequence of the plugs is from left to right, and they are all plugged into the outlet in the correct order. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 484/951 [04:10<08:41, 1.12s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_0.png'}, {'type': 'text', 'value': 'The plug is removed from the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +No, the images are not in the correct order. The plug is removed from the power outlet, and the sequence of the images should be reversed to show the correct order of the plug being inserted into the outlet. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 485/951 [04:11<08:34, 1.10s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug put into the power outlet?'}] +Yes, the plug is put into the power outlet in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 486/951 [04:12<06:59, 1.11it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the plug removed from the power outlet?'}] +Yes, the plug is removed from the power outlet in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████ | 487/951 [04:12<05:54, 1.31it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'The plug is put into the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the plugs are in the correct order. The image shows a row of six plugs plugged into a power outlet, with each plug being connected to a corresponding socket. The sequence of the plugs is consistent with the order they are plugged into the outlet, starting from the leftmost plug and moving towards the rightmost plug. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████▏ | 488/951 [04:14<07:54, 1.03s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/7_1.png'}, {'type': 'text', 'value': 'The plug is removed from the power outlet. According to the positive sequence of the images, are they in the correct order?'}] +No, the plugs are not in the correct order. The image shows the plugs in a sequence that is not in line with the correct order of the power outlet. The correct order would be the plug on the left, followed by the plug on the right, and then the plug in the middle. The current arrangement of the plugs is incorrect, and they should be repositioned to match the correct sequence. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 51%|█████▏ | 489/951 [04:16<10:03, 1.31s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving forward?'}] +Yes, the blue car is moving forward in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 490/951 [04:16<08:01, 1.04s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving backward?'}] +Yes, the blue car is moving backward in the sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 491/951 [04:17<06:43, 1.14it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'The blue car is moving forward. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the blue car is moving forward in the correct order. The sequence of the images shows the blue car moving from the left to the right side of the road, and it is the last car in the line of cars. The other cars are moving in the same direction, and the blue car is following them. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 492/951 [04:18<07:59, 1.04s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_0.png'}, {'type': 'text', 'value': 'The blue car is moving backward. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is moving backward in the sequence of images. The correct order of the images should be the blue car first, followed by the red car, and then the white car. The current order is the white car, followed by the red car, and then the blue car. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 493/951 [04:20<08:43, 1.14s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving forward?'}] +Yes, the blue car is moving forward in the positive sequence of the images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 494/951 [04:20<07:04, 1.08it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the blue car moving backward?'}] +Yes, the blue car is moving backward in the sequence of images. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 495/951 [04:20<05:53, 1.29it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'The blue car is moving forward. According to the positive sequence of the images, are they in the correct order?'}] +Yes, the blue car is moving forward in the correct order. The sequence of the images shows the blue car moving from the left to the right side of the road, and it is the last car in the line of cars. The other cars are moving in the same direction, and the blue car is the only one that is moving forward. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 496/951 [04:22<07:36, 1.00s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/8_1.png'}, {'type': 'text', 'value': 'The blue car is moving backward. According to the positive sequence of the images, are they in the correct order?'}] +No, the blue car is moving backward in the sequence of images. The correct order of the images should be the blue car first, followed by the red car, and then the white car. The current order is the white car, followed by the red car, and then the blue car. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 497/951 [04:23<08:29, 1.12s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical anticlockwise? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 498/951 [04:24<06:40, 1.13it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical clockwise? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 52%|█████▏ | 499/951 [04:24<05:21, 1.40it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_0.png'}, {'type': 'text', 'value': 'The circle inside is autobiographical anticlockwise. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 500/951 [04:24<04:28, 1.68it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical anticlockwise? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 501/951 [04:25<03:48, 1.97it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the circle inside autobiographical clockwise? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 502/951 [04:25<03:20, 2.24it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/9_1.png'}, {'type': 'text', 'value': 'The circle inside is autobiographical anticlockwise. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 503/951 [04:25<03:01, 2.47it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 504/951 [04:26<03:00, 2.48it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 505/951 [04:26<02:54, 2.56it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 506/951 [04:26<02:51, 2.60it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_0.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 507/951 [04:27<02:53, 2.56it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 53%|█████▎ | 508/951 [04:27<02:54, 2.54it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 509/951 [04:28<02:50, 2.59it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 510/951 [04:28<02:48, 2.61it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_1.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▎ | 511/951 [04:28<02:47, 2.63it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey removing the wheel? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 512/951 [04:29<02:44, 2.67it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this monkey installing the wheel? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 513/951 [04:29<02:42, 2.69it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'This monkey is removing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 514/951 [04:29<02:42, 2.70it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/10_2.png'}, {'type': 'text', 'value': 'This monkey is installing the wheel. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 515/951 [04:30<02:41, 2.69it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 516/951 [04:30<02:44, 2.65it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 517/951 [04:31<02:48, 2.58it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 54%|█████▍ | 518/951 [04:31<02:49, 2.55it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_0.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 519/951 [04:31<02:54, 2.47it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 520/951 [04:32<02:58, 2.41it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 521/951 [04:32<02:58, 2.41it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 522/951 [04:33<02:56, 2.43it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_1.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▍ | 523/951 [04:33<02:54, 2.45it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this man throwing a woman into the toilet? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 524/951 [04:34<02:59, 2.37it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is this woman jumping out from the toilet? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 525/951 [04:34<02:57, 2.40it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'This man is throwing a woman into the toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 526/951 [04:34<02:55, 2.43it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/11_2.png'}, {'type': 'text', 'value': 'This woman is jumping out from a toilet. According to the positive sequence of the images, are they in the correct order? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 55%|█████▌ | 527/951 [04:35<02:56, 2.41it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 528/951 [04:35<03:16, 2.15it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 529/951 [04:36<03:08, 2.24it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 530/951 [04:36<02:58, 2.36it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 531/951 [04:36<02:52, 2.44it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 532/951 [04:37<02:47, 2.51it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to left? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 533/951 [04:37<02:42, 2.57it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▌ | 534/951 [04:38<02:33, 2.71it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle keeping in the same place? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 535/951 [04:38<02:26, 2.84it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/12_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is the circle moving towards to left? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 536/951 [04:38<02:31, 2.74it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a dog in this video? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 56%|█████▋ | 537/951 [04:39<02:17, 3.00it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a sloth in this video? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 538/951 [04:39<02:09, 3.19it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/13_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is there a cat in this video? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 539/951 [04:39<02:03, 3.33it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one word.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 540/951 [04:39<02:14, 3.06it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one word.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 541/951 [04:40<02:20, 2.92it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 542/951 [04:40<02:26, 2.80it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_0.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 543/951 [04:41<02:31, 2.70it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 544/951 [04:41<02:32, 2.67it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 545/951 [04:41<02:33, 2.64it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 57%|█████▋ | 546/951 [04:42<02:40, 2.53it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_1.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 547/951 [04:42<02:41, 2.50it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to left? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 548/951 [04:43<02:39, 2.52it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they skating to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 549/951 [04:43<02:37, 2.55it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'They are skating to left. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 550/951 [04:43<02:42, 2.47it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/14_2.png'}, {'type': 'text', 'value': 'They are skating to right. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 551/951 [04:44<02:43, 2.45it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 552/951 [04:44<02:43, 2.43it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 553/951 [04:45<02:39, 2.49it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 554/951 [04:45<02:33, 2.59it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/15_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the man running to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 555/951 [04:45<02:27, 2.68it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 58%|█████▊ | 556/951 [04:46<02:13, 2.95it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▊ | 557/951 [04:46<02:06, 3.12it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to right? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▊ | 558/951 [04:46<01:57, 3.34it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/16_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is the baby crawling to left? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 559/951 [04:46<01:51, 3.53it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting closer? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 560/951 [04:47<02:05, 3.12it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting far away? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 561/951 [04:47<02:22, 2.73it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'This cartoon character getting closer. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 562/951 [04:48<02:28, 2.61it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_0.png'}, {'type': 'text', 'value': 'This cartoon character getting further away. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 563/951 [04:48<02:30, 2.58it/s]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting closer? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 564/951 [04:48<02:28, 2.60it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, is this cartoon character getting far away? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 59%|█████▉ | 565/951 [04:49<02:30, 2.56it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'This cartoon character getting closer. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 566/951 [04:49<02:30, 2.56it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/17_1.png'}, {'type': 'text', 'value': 'This cartoon character getting further away. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 567/951 [04:50<02:29, 2.57it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 568/951 [04:50<02:24, 2.65it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 569/951 [04:50<02:20, 2.72it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|█████▉ | 570/951 [04:51<02:17, 2.77it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_0.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 571/951 [04:51<02:14, 2.82it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 572/951 [04:51<02:12, 2.85it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 573/951 [04:52<02:10, 2.89it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 574/951 [04:52<02:09, 2.91it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_1.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 60%|██████ | 575/951 [04:52<02:09, 2.91it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they hugging? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 576/951 [04:53<02:07, 2.93it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, are they growing apart? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 577/951 [04:53<02:06, 2.96it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'They are hugging. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 578/951 [04:53<02:06, 2.95it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/18_2.png'}, {'type': 'text', 'value': 'They are growing apart. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 579/951 [04:54<02:06, 2.94it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 580/951 [04:54<02:12, 2.79it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 581/951 [04:55<02:19, 2.65it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████ | 582/951 [04:55<02:19, 2.64it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_0.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████▏ | 583/951 [04:55<02:20, 2.62it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 61%|██████▏ | 584/951 [04:56<02:20, 2.62it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 585/951 [04:56<02:18, 2.65it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 586/951 [04:56<02:17, 2.65it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_1.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 587/951 [04:57<02:22, 2.55it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running counterclockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 588/951 [04:57<02:25, 2.50it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'According to the positive sequence of the images, Is he running clockwise? Answer in one sentence.'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 589/951 [04:58<02:25, 2.50it/s]torch.Size([1, 646, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'He is running counterclockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 590/951 [04:58<02:26, 2.47it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VD/video/19_2.png'}, {'type': 'text', 'value': 'He is running clockwise. According to the positive sequence of the images, are they in the correct order? Answer in one sentence.'}] +No + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 591/951 [04:59<02:25, 2.47it/s]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is China, Hongkong SAR, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, China, Hongkong SAR is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 592/951 [04:59<03:16, 1.83it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is Switzerland, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, Switzerland is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 593/951 [05:00<03:38, 1.64it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is France, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, France is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 62%|██████▏ | 594/951 [05:01<03:52, 1.54it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/0_1.png'}, {'type': 'text', 'value': 'Is the United States, the leading importing country of gold, silverware, and jewelry with the highest import value in 2018?'}] +Yes, the United States is the leading importing country of gold, silverware, and jewelry with the highest import value in 2018. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 595/951 [05:02<04:07, 1.44it/s]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2019, Is 2010 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries from 2001 to 2019. The value of these goods exported from the UK increased over the years, with the highest value being in 2019. This indicates that the UK is a significant player in the global market for these baked goods. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 596/951 [05:04<06:29, 1.10s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2019, Is 2019 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that in 2019, the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries. The value of these goods exported from the UK in 2019 was approximately 1,000,000 GBP. This information is presented in a graph that shows the value of these goods exported from the UK from 2001 to 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 597/951 [05:06<08:34, 1.45s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2010, Is 2010 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, the image shows that the United Kingdom exported the most value of bread, biscuits, wafers, cakes, and pastries from 2001 to 2010. The value of these goods exported from the UK increased significantly during this period, reaching a peak in 2009. The export value of these goods has been steadily increasing since 2001, with a notable increase in 2009. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 598/951 [05:08<09:50, 1.67s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2001 to 2010, Is 2005 exported the most value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, from 2001 to 2010, the UK exported the most value of bread, biscuits, wafers, cakes, and pastries in 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 599/951 [05:09<08:44, 1.49s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2000 to 2019, Is 2010 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, from 2000 to 2019, the least value of bread, biscuits, wafers, cakes, and pastries was exported in 2010. The value of these goods exported from the UK in 2010 was 1,000 GBP. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 600/951 [05:11<08:56, 1.53s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2000 to 2019, Is 2019 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, in 2019, the UK exported the least value of bread, biscuits, wafers, cakes, and pastries compared to the other years from 2000 to 2019. The value of these exports was 1,000 GBP, which is significantly lower than the average value of 1,100 GBP for the other years. This indicates that the UK's export of these bakery products has been declining over the years, with a notable drop in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 601/951 [05:14<10:53, 1.87s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2010 to 2019, Is 2010 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, from 2010 to 2019, the UK exported the least value of bread, biscuits, wafers, cakes, and pastries in 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 602/951 [05:15<09:31, 1.64s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/1_1.png'}, {'type': 'text', 'value': 'From 2010 to 2019, Is 2015 exported the least value of bread, biscuits, wafers, cakes and pastries from the UK?'}] +Yes, in 2015, the UK exported the least value of bread, biscuits, wafers, cakes, and pastries among the years from 2010 to 2019. The value of these exports was 1,000 GBP. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 63%|██████▎ | 603/951 [05:16<09:17, 1.60s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2000?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2000, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 604/951 [05:17<07:49, 1.35s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2005?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2005, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2005, the population in this age group is the highest, indicating that it was a significant year for the country's demographics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 605/951 [05:19<09:06, 1.58s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2030?'}] +Yes, the population aged between 15 and 29 years in China is the most in 2030, as shown in the image. The graph displays the population aged between 15 and 29 years in China from 2000 to 2050. In 2030, the population in this age group is at its peak, indicating that it is the most populous age group in China during that time. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▎ | 606/951 [05:21<10:03, 1.75s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the most in 2050?'}] +Yes, the population aged between 15 and 29 years in China is expected to be the highest in 2050, as shown in the graph. The graph shows a significant increase in the population aged between 15 and 29 years from 2000 to 2050. This indicates that the population in China is growing rapidly, and the country is likely to experience a significant demographic shift in the coming decades. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 607/951 [05:23<10:41, 1.86s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2000?'}] +Yes, the population aged between 15 and 29 years in China is the least in 2000. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 608/951 [05:24<08:35, 1.50s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2005?'}] +Yes, the population aged between 15 and 29 years in China is the least in 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 609/951 [05:25<07:07, 1.25s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2030?'}] +Yes, the population aged between 15 and 29 years in China is the least in 2030. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 610/951 [05:26<06:36, 1.16s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/2_1.png'}, {'type': 'text', 'value': 'From 2000-2050, is the population aged between 15 and 29 years in China the least in 2050?'}] +Yes, the population aged between 15 and 29 years in China is the least in 2050. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 611/951 [05:26<05:47, 1.02s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does China have the largest population in the world, followed by India and then the USA?'}] +Yes, according to the chart, China has the largest population in the world, followed by India, and then the USA. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 612/951 [05:27<05:05, 1.11it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does India have the second largest population in the world?'}] +Yes, according to the chart, India has the second largest population in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 64%|██████▍ | 613/951 [05:27<04:18, 1.31it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does UK have the largest population in the world, followed by China and USA?'}] +According to the chart, the United States has the largest population in the world, followed by China and India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 614/951 [05:28<03:57, 1.42it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_1.png'}, {'type': 'text', 'value': 'According to the chart, does China have the second largest population in the world?'}] +Yes, according to the chart, China has the second largest population in the world, with a population of approximately 1,379,600,000 people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 615/951 [05:29<04:20, 1.29it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does China have the largest population in the world, followed by India and then the USA?'}] +According to the chart, China has the largest population in the world, followed by India, and then the USA. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 616/951 [05:29<04:06, 1.36it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does India have the second largest population in the world?'}] +Yes, according to the chart, India has the second largest population in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 617/951 [05:30<03:42, 1.50it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does UK have the largest population in the world, followed by China and USA?'}] +According to the chart, the UK does not have the largest population in the world. Instead, it is the third largest country in terms of population, behind China and the United States. The chart shows that the UK has a population of approximately 115 million people, while China has a population of over 1.4 billion people and the United States has a population of around 330 million people. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▍ | 618/951 [05:32<06:03, 1.09s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/3_2.png'}, {'type': 'text', 'value': 'According to the chart, does China have the second largest population in the world?'}] +Yes, according to the chart, China has the second largest population in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 619/951 [05:33<05:02, 1.10it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is China the third largest country by land area in the world?'}] +Yes, according to the chart, China is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 620/951 [05:33<04:30, 1.22it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is US the third largest country by land area in the world?'}] +Yes, according to the chart, the United States is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 621/951 [05:34<04:08, 1.33it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is US the largest country by land area in the world?'}] +Yes, according to the chart, the United States is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 65%|██████▌ | 622/951 [05:34<03:52, 1.42it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_1.png'}, {'type': 'text', 'value': 'According to the chart, is Russia the largest country by land area in the world?'}] +Yes, according to the chart, Russia is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 623/951 [05:35<03:36, 1.52it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is China the third largest country by land area in the world?'}] +Yes, according to the chart, China is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 624/951 [05:35<03:26, 1.59it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is US the third largest country by land area in the world?'}] +Yes, according to the chart, the United States is the third largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 625/951 [05:36<03:25, 1.59it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is US the largest country by land area in the world?'}] +Yes, according to the chart, the United States is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 626/951 [05:37<03:18, 1.63it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/4_2.png'}, {'type': 'text', 'value': 'According to the chart, is Russia the largest country by land area in the world?'}] +Yes, according to the chart, Russia is the largest country by land area in the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 627/951 [05:37<03:10, 1.70it/s]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Asian families have the highest real median household income in the United States, with White, Hispanic, and Black households following respectively?'}] +Yes, according to the image, in 2019, Asian families had the highest real median household income in the United States, with White, Hispanic, and Black households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 628/951 [05:38<03:47, 1.42it/s]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black families have the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively?'}] +Yes, according to the image, in 2019, Black families had the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 629/951 [05:39<04:15, 1.26it/s]torch.Size([1, 671, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black and White households represent the only racial groups with median incomes surpassing the national average in the United States, while Hispanic and Asian households had median incomes below the average?'}] +Yes, according to the image, in 2019, Black and White households represented the only racial groups with median incomes surpassing the national average in the United States. Hispanic and Asian households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▌ | 630/951 [05:40<04:57, 1.08it/s]torch.Size([1, 671, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_1.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Hispanic and Asian households represent the only racial groups with median incomes surpassing the national average in the United States, while Black and White households had median incomes below the average?'}] +Yes, according to the image, in 2019, Hispanic and Asian households were the only racial groups with median incomes surpassing the national average in the United States. Black and White households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▋ | 631/951 [05:42<05:26, 1.02s/it]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Asian families have the highest real median household income in the United States, with White, Hispanic, and Black households following respectively?'}] +Yes, according to the image, in 2019, Asian families had the highest real median household income in the United States, with White, Hispanic, and Black households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 66%|██████▋ | 632/951 [05:43<05:24, 1.02s/it]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black families have the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively?'}] +Yes, according to the image, in 2019, Black families had the highest real median household income in the United States, with White, Hispanic, and Asian households following respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 633/951 [05:44<05:19, 1.00s/it]torch.Size([1, 671, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Black and White households represent the only racial groups with median incomes surpassing the national average in the United States, while Hispanic and Asian households had median incomes below the average?'}] +Yes, according to the image, in 2019, Black and White households represented the only racial groups with median incomes surpassing the national average in the United States. Hispanic and Asian households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 634/951 [05:45<05:40, 1.08s/it]torch.Size([1, 671, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/5_2.png'}, {'type': 'text', 'value': 'According to the image, in 2019, did Hispanic and Asian households represent the only racial groups with median incomes surpassing the national average in the United States, while Black and White households had median incomes below the average?'}] +Yes, according to the image, in 2019, Hispanic and Asian households were the only racial groups with median incomes surpassing the national average in the United States. Black and White households had median incomes below the average. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 635/951 [05:46<06:05, 1.16s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from the Americas?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from the Americas. In the image, the Americas region is shown to have the highest revenue distribution, with a significant portion of the revenue coming from the United States. This indicates that Apple's primary market and revenue source has been the Americas region during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 636/951 [05:48<07:07, 1.36s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Europe?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from Europe. The chart shows that the majority of Apple's revenue came from the Americas, with Europe being the second-largest contributor. The Americas accounted for approximately 50% of Apple's revenue, while Europe accounted for around 25%. The remaining 25% of Apple's revenue came from other regions around the world. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 637/951 [05:50<08:34, 1.64s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Greater China?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from Greater China. In the image, it is shown that the majority of Apple's revenue distribution came from Greater China, with the region accounting for 50% or more of the company's revenue in each year. This indicates that Apple has a strong presence and significant market share in the region, and its revenue growth in Greater China has been a significant contributor to the company's overall financial performance. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 638/951 [05:53<09:54, 1.90s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_1.PNG'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Japan?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from Japan. In the image, the revenue distribution in different regions worldwide is shown, and Japan is the top contributor to Apple's revenue. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 639/951 [05:54<08:54, 1.71s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from the Americas?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from the Americas. In the image, the revenue distribution in different regions worldwide is shown, and it is evident that the Americas account for the largest share of Apple's revenue. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 640/951 [05:56<08:32, 1.65s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Europe?'}] +No, from 2012 to 2022, Apple did not derive the majority of its revenue from Europe. The chart shows that the majority of Apple's revenue came from the United States, with Europe being the second-largest contributor. The chart also shows that Apple's revenue distribution varied across different regions worldwide, with the United States, Europe, and Asia being the main contributors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 67%|██████▋ | 641/951 [05:58<09:08, 1.77s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Greater China?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from Greater China. In the image, the revenue distribution in different regions worldwide is shown, and it is evident that Greater China has been the primary source of revenue for Apple during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 642/951 [06:00<09:28, 1.84s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/6_2.png'}, {'type': 'text', 'value': 'From 2012 to 2022, did Apple derive the majority of its revenue from Japan?'}] +Yes, from 2012 to 2022, Apple derived the majority of its revenue from Japan. In the image, the revenue distribution in different regions worldwide is shown, and Japan is the top contributor to Apple's revenue. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 643/951 [06:02<09:36, 1.87s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the U.S. Central Bank higher than those of the Central Banks in the UK, Eurozone, and Japan?'}] +Yes, in 2019, the main policy interest rates of the U.S. Central Bank were higher than those of the Central Banks in the UK, Eurozone, and Japan. The U.S. Federal Reserve raised its policy interest rate four times in 2018, while the Bank of England, the European Central Bank, and the Bank of Japan did not raise their rates at all. This indicates that the U.S. Central Bank was more aggressive in tightening monetary policy in 2018 than the other central banks. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 644/951 [06:04<10:43, 2.10s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the UK higher than those of the U.S. Central Bank , Eurozone, and Japan?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the UK were higher than those of the U.S. Central Bank, Eurozone, and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 645/951 [06:06<09:26, 1.85s/it]torch.Size([1, 663, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the Eurozone higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the Eurozone were higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 646/951 [06:07<09:27, 1.86s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_1.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Japan Central Bank higher than those of the Central Banks in the UK, Eurozone, and U.S.?'}] +Yes, in 2019, the main policy interest rates of the Japan Central Bank were higher than those of the Central Banks in the UK, Eurozone, and U.S. The image shows a graph comparing the interest rates of these four central banks, with the Japan Central Bank having the highest rate among them. This indicates that the Japan Central Bank was more aggressive in managing monetary policy and controlling inflation in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 647/951 [06:10<09:50, 1.94s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the U.S. Central Bank higher than those of the Central Banks in the UK, Eurozone, and Japan, according to the image?'}] +Yes, the image shows that the main policy interest rates of the U.S. Central Bank were higher than those of the Central Banks in the UK, Eurozone, and Japan in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 648/951 [06:11<09:27, 1.87s/it]torch.Size([1, 662, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the UK higher than those of the U.S. Central Bank , Eurozone, and Japan, according to the image?'}] +Yes, in 2019, the main policy interest rates of the Central Banks in the UK were higher than those of the U.S. Central Bank, Eurozone, and Japan, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 649/951 [06:13<09:34, 1.90s/it]torch.Size([1, 668, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Central Banks in the Eurozone higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan, according to the image?'}] +Yes, the image shows that the main policy interest rates of the Central Banks in the Eurozone were higher than those of the U.S. Central Bank, the Central Banks in the UK, and Japan in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 650/951 [06:15<09:35, 1.91s/it]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/7_2.PNG'}, {'type': 'text', 'value': 'In 2019, were the main policy interest rates of the Japan Central Bank higher than those of the Central Banks in the UK, Eurozone, and U.S., according to the image?'}] +Yes, the image shows that the main policy interest rates of the Japan Central Bank were higher than those of the Central Banks in the UK, Eurozone, and U.S. in 2019. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 68%|██████▊ | 651/951 [06:16<08:16, 1.66s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Harry Kane the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Harry Kane was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▊ | 652/951 [06:18<07:55, 1.59s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Cristiano Ronaldo the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Cristiano Ronaldo was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▊ | 653/951 [06:19<07:35, 1.53s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_1.PNG'}, {'type': 'text', 'value': 'According to the image, was Antoine Griezmann the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, according to the image, Antoine Griezmann was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 654/951 [06:20<06:26, 1.30s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Harry Kane the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Harry Kane was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 655/951 [06:21<06:15, 1.27s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Cristiano Ronaldo the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, Cristiano Ronaldo was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 656/951 [06:22<05:20, 1.09s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/8_2.PNG'}, {'type': 'text', 'value': 'According to the image, was Antoine Griezmann the top goalscorer at the 2018 FIFA World Cup?'}] +Yes, according to the image, Antoine Griezmann was the top goalscorer at the 2018 FIFA World Cup in Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 657/951 [06:23<05:50, 1.19s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did the United States have the largest GDP around the world, followed by China, and Japan, according to the image?'}] +Yes, according to the image, the United States had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 658/951 [06:24<05:10, 1.06s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did China have the largest GDP around the world, followed by the United States, and Japan, according to the image?'}] +Yes, according to the image, in 2020, China had the largest GDP among the countries shown, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 659/951 [06:25<05:19, 1.09s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did Japan have the largest GDP around the world, followed by the United States, and China, according to the image?'}] +Yes, according to the image, in 2020, Japan had the largest GDP among the countries shown, followed by the United States and China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 69%|██████▉ | 660/951 [06:26<04:49, 1.01it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_1.PNG'}, {'type': 'text', 'value': 'In 2020, did India have the largest GDP around the world, followed by China and Japan, according to the image?'}] +Yes, according to the image, India had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 661/951 [06:27<04:58, 1.03s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did the United States have the largest GDP around the world, followed by China, and Japan, according to the image?'}] +Yes, according to the image, the United States had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 662/951 [06:28<04:36, 1.04it/s]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did China have the largest GDP around the world, followed by the United States, and Japan, according to the image?'}] +Yes, according to the image, in 2020, China had the largest GDP among the countries shown, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 663/951 [06:29<04:56, 1.03s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did Japan have the largest GDP around the world, followed by the United States, and China, according to the image?'}] +Yes, according to the image, in 2020, Japan had the largest GDP among the countries shown, followed by the United States and China. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 664/951 [06:30<04:39, 1.03it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/9_2.PNG'}, {'type': 'text', 'value': 'In 2020, did India have the largest GDP around the world, followed by China and Japan, according to the image?'}] +Yes, according to the image, India had the largest GDP among the countries shown in 2020, followed by China and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|██████▉ | 665/951 [06:31<04:55, 1.03s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were white individuals the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, white individuals were the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 666/951 [06:32<04:51, 1.02s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were African Americans the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively?'}] +Yes, according to the image, African Americans were the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 667/951 [06:34<05:58, 1.26s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were Latinos the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Latinos were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 668/951 [06:35<05:48, 1.23s/it]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_1.PNG'}, {'type': 'text', 'value': 'According to the image, were Asians the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Asians were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 669/951 [06:37<06:42, 1.43s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were white individuals the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, white individuals were the largest population group in the United States in 2020, with Latinos and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 70%|███████ | 670/951 [06:38<06:01, 1.29s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were African Americans the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively?'}] +Yes, according to the image, African Americans were the largest population group in the United States in 2020, with Whites and Latinos as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 671/951 [06:40<06:42, 1.44s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were Latinos the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Latinos were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 672/951 [06:41<06:14, 1.34s/it]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/10_2.PNG'}, {'type': 'text', 'value': 'According to the image, were Asians the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively?'}] +Yes, according to the image, Asians were the largest population group in the United States in 2020, with Whites and African Americans as the second and third largest groups, respectively. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 673/951 [06:42<05:44, 1.24s/it]torch.Size([1, 658, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/11_1.png'}, {'type': 'text', 'value': "According to the image, between 2011 and 2020, was 2020 the year when China's exports to the United States reached their highest value?"}] +Yes, according to the image, in 2020, China's exports to the United States reached their highest value. The graph shows a significant increase in the value of exports from China to the United States between 2011 and 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 674/951 [06:45<08:00, 1.73s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/11_1.png'}, {'type': 'text', 'value': "According to the image, did China's exports to the United States experience a decrease from 2016 to 2018?"}] +Yes, according to the image, China's exports to the United States experienced a decrease from 2016 to 2018. The graph shows a decline in the number of exports from China to the United States during this period. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 675/951 [06:47<08:17, 1.80s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was the United States the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan?'}] +Yes, according to the image, in 2013, the United States was the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 676/951 [06:48<07:11, 1.57s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Hong Kong the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan?'}] +Yes, according to the image, in 2013, Hong Kong was the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████ | 677/951 [06:49<07:27, 1.63s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_1.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Japn the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong?'}] +Yes, according to the image, in 2013, Japan was the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████▏ | 678/951 [06:50<06:40, 1.47s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was the United States the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan?'}] +Yes, according to the image, in 2013, the United States was the largest recipient of exports from China in terms of US dollars, followed by Hong Kong and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 71%|███████▏ | 679/951 [06:51<05:58, 1.32s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Hong Kong the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan?'}] +Yes, according to the image, in 2013, Hong Kong was the largest recipient of exports from China in terms of US dollars, followed by the United States and Japan. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 680/951 [06:53<06:36, 1.46s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/12_2.png'}, {'type': 'text', 'value': 'According to the image, in 2013, was Japn the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong?'}] +Yes, according to the image, in 2013, Japan was the largest recipient of exports from China in terms of US dollars, followed by the United States and Hong Kong. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 681/951 [06:54<06:06, 1.36s/it]torch.Size([1, 679, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_1.png'}, {'type': 'text', 'value': 'According to the image, between March 2020 and December 2021, did the United States experience the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020?'}] +Yes, the United States experienced the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020. The image shows that the peak average number of daily reported COVID-19 deaths occurred in December 2020, with an average of 3,000 deaths per day. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 682/951 [06:56<06:50, 1.52s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_1.png'}, {'type': 'text', 'value': 'According to the image, had the total number of coronavirus deaths in the United States reached 937,000 by February 2021?'}] +Yes, according to the image, if the total number of coronavirus deaths in the United States had reached 937,000 by February 2021, it would be a significant milestone in the pandemic. The current number of deaths in the United States is significantly lower than this, with the actual number of deaths being around 470,000 as of February 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 683/951 [06:58<07:31, 1.68s/it]torch.Size([1, 679, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_2.png'}, {'type': 'text', 'value': 'According to the image, between March 2020 and December 2021, did the United States experience the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020?'}] +Yes, the image shows that the United States experienced the peak average number of daily reported COVID-19 deaths during the initial wave, which spanned from March 2020 to June 2020. The peak occurred in April 2020, with an average of 2,200 daily reported deaths. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 684/951 [07:00<07:41, 1.73s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/13_2.png'}, {'type': 'text', 'value': 'According to the image, had the total number of coronavirus deaths in the United States reached 937,000 by February 2021?'}] +Yes, according to the image, if the total number of coronavirus deaths in the United States had reached 937,000 by February 2021, it would be a significant milestone in the pandemic. The image shows a graph with a line that represents the number of daily reported coronavirus deaths in the United States, and it is currently at around 4,000. If the line were to continue to rise and reach 937,000 by February 2021, it would indicate a much more severe and widespread outbreak of the virus in the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 685/951 [07:03<09:21, 2.11s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did the Soviet Union suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the Soviet Union suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 686/951 [07:05<08:37, 1.95s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did the United States suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the United States suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 687/951 [07:06<08:04, 1.83s/it]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_1.png'}, {'type': 'text', 'value': 'According to the image, did United Kingdom experience the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland?'}] +According to the image, the United Kingdom experienced the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 688/951 [07:07<06:48, 1.55s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did the Soviet Union suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +According to the image, the Soviet Union suffered the greatest number of total deaths in World War II, with China having the second-highest. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 72%|███████▏ | 689/951 [07:09<06:54, 1.58s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did the United States suffer the greatest number of total deaths in World War II, with China having the second-highest?'}] +Yes, according to the image, the United States suffered the greatest number of total deaths in World War II, with China having the second-highest. The chart shows that the United States had 405,399 deaths, while China had 35,236,800 deaths. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 690/951 [07:10<06:56, 1.59s/it]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/14_2.png'}, {'type': 'text', 'value': 'According to the image, did United Kingdom experience the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland?'}] +According to the image, the United Kingdom experienced the highest percentage of total deaths relative to its 1939 population during World War II, followed by Poland. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 691/951 [07:12<07:05, 1.64s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_1.png'}, {'type': 'text', 'value': 'According to the image, did the global death toll from earthquakes surpass 200,000 in any year between 2000 and 2015?'}] +Yes, the global death toll from earthquakes surpassed 200,000 in the year 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 692/951 [07:13<05:55, 1.37s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_1.png'}, {'type': 'text', 'value': 'According to the image, did the year 2004 witness a higher global death toll due to earthquakes than 2005?'}] +Yes, according to the image, the year 2004 witnessed a higher global death toll due to earthquakes than 2005. The image shows a bar graph with the years 2004 and 2005 on the x-axis and the number of deaths on the y-axis. The bar for 2004 is higher than the bar for 2005, indicating that more people died due to earthquakes in 2004 than in 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 693/951 [07:16<08:19, 1.93s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_2.png'}, {'type': 'text', 'value': 'According to the image, did the global death toll from earthquakes surpass 200,000 in any year between 2000 and 2009?'}] +Yes, the global death toll from earthquakes surpassed 200,000 in the year 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 694/951 [07:17<06:49, 1.59s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/15_2.png'}, {'type': 'text', 'value': 'According to the image, did the year 2004 witness a higher global death toll due to earthquakes than 2005?'}] +Yes, according to the image, the year 2004 witnessed a higher global death toll due to earthquakes than 2005. The chart shows that in 2004, there were 16,000 deaths due to earthquakes, while in 2005, the number of deaths was 13,000. This indicates that the year 2004 experienced a higher global death toll due to earthquakes than 2005. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 695/951 [07:20<08:44, 2.05s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_1.png'}, {'type': 'text', 'value': 'According to the image, does DJI hold more than 50% of the commercial drone brand market share in 2021?'}] +Yes, according to the image, DJI holds more than 50% of the commercial drone brand market share in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 696/951 [07:21<07:02, 1.66s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_1.png'}, {'type': 'text', 'value': 'According to the image, is the combined market share of Autel, FreeFly, Skydio, and Parrot greater than the market share of DJI alone in 2021?'}] +Yes, the combined market share of Autel, FreeFly, Skydio, and Parrot is greater than the market share of DJI alone in 2021. The image shows that the combined market share of these four brands is approximately 35%, while DJI's market share is around 55%. This indicates that these four brands have a significant presence in the commercial drone market, and their combined market share is larger than DJI's share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 697/951 [07:24<08:58, 2.12s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_2.png'}, {'type': 'text', 'value': 'According to the image, does DJI hold more than 50% of the commercial drone brand market share in 2021?'}] +Yes, according to the image, DJI holds more than 50% of the commercial drone brand market share in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 73%|███████▎ | 698/951 [07:25<07:15, 1.72s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/16_2.png'}, {'type': 'text', 'value': 'According to the image, is the combined market share of Autel, FreeFly, Skydio, and Parrot greater than the market share of DJI alone in 2021?'}] +Yes, the combined market share of Autel, FreeFly, Skydio, and Parrot is greater than the market share of DJI alone in 2021. The image shows that Autel, FreeFly, Skydio, and Parrot together have a 45% market share, while DJI has a 55% market share. This indicates that these four brands have a significant presence in the commercial drone market, while DJI remains the dominant player. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 699/951 [07:27<07:59, 1.90s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': "According to the image, is Mark Zuckerberg'swealth greater than Larry Ellison's on 13th March 2020?"}] +Yes, according to the image, Mark Zuckerberg's wealth is greater than Larry Ellison's on 13th March 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 700/951 [07:29<08:04, 1.93s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg on March 13th, 2020?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on March 13th, 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▎ | 701/951 [07:31<07:56, 1.91s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_1.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg, on January 10th, 2021?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on January 10th, 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 702/951 [07:33<07:54, 1.91s/it]torch.Size([1, 650, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': "According to the image, is Mark Zuckerberg'swealth greater than Larry Ellison's on 13th March 2020?"}] +Yes, according to the image, Mark Zuckerberg's wealth is greater than Larry Ellison's on 13th March 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 703/951 [07:35<07:58, 1.93s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg on March 13th, 2020?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on March 13th, 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 704/951 [07:37<08:12, 2.00s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/17_2.png'}, {'type': 'text', 'value': 'According to the image, was Elon Musk richer than Mark Zuckerberg, on January 10th, 2021?'}] +Yes, according to the image, Elon Musk was richer than Mark Zuckerberg on January 10th, 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 705/951 [07:39<08:04, 1.97s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_1.png'}, {'type': 'text', 'value': 'According to the image, in 2017, was Tencent the company with the highest revenue from video games, with Sony as the second-highest earner?'}] +Yes, according to the image, Tencent was the company with the highest revenue from video games in 2017, with Sony as the second-highest earner. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 706/951 [07:40<07:05, 1.74s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_1.png'}, {'type': 'text', 'value': 'According to the image, in 2017, did Apple generate higher revenue from video games compared to Google?'}] +Yes, according to the image, in 2017, Apple generated higher revenue from video games compared to Google. The chart shows that Apple generated $18.3 billion in revenue from video games, while Google generated $1.3 billion. This indicates that Apple has a larger presence in the video game market and is more successful in generating revenue from this sector. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 707/951 [07:42<07:24, 1.82s/it]torch.Size([1, 655, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_2.png'}, {'type': 'text', 'value': 'According to the image, in 2017, was Tencent the company with the highest revenue from video games, with Sony as the second-highest earner?'}] +Yes, according to the image, Tencent was the company with the highest revenue from video games in 2017, with Sony as the second-highest earner. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 74%|███████▍ | 708/951 [07:43<06:17, 1.56s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/18_2.png'}, {'type': 'text', 'value': 'According to the image, in 2017, did Apple generate higher revenue from video games compared to Google?'}] +Yes, according to the image, in 2017, Apple generated higher revenue from video games compared to Google. The chart shows that Apple generated $18 billion in revenue from video games, while Google generated $1.5 billion. This indicates that Apple has a larger presence in the video game market and is more successful in generating revenue from this sector. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 709/951 [07:45<06:33, 1.62s/it]torch.Size([1, 664, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_1.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2020?'}] +Yes, the image shows that the most bankruptcy filings in the US were recorded in the year 2020 during the coronavirus pandemic. The graph displays the number of bankruptcy filings by year, and it is evident that 2020 had the highest number of filings. This is likely due to the economic impact of the pandemic, which led to widespread business closures, job losses, and financial hardship for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 710/951 [07:47<07:23, 1.84s/it]torch.Size([1, 664, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_1.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2021?'}] +Yes, the image shows that the most bankruptcy filings in the US were recorded in the year 2021, during the coronavirus pandemic. The graph displays the number of bankruptcy filings by year, and it is evident that 2021 had the highest number of filings. This could be attributed to the economic impact of the pandemic, which led to job losses, business closures, and financial strain for many individuals and companies. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 711/951 [07:50<08:48, 2.20s/it]torch.Size([1, 664, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_2.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2020?'}] +Yes, the image shows that the most bankruptcy filings in the US were recorded in the year 2020 during the coronavirus pandemic. The graph displays the number of bankruptcy filings by month, and it is evident that the highest number of filings occurred in April 2020. This indicates that the pandemic had a significant impact on businesses and individuals, leading to a surge in bankruptcy filings during that time. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 712/951 [07:52<08:45, 2.20s/it]torch.Size([1, 664, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/19_2.png'}, {'type': 'text', 'value': 'According to the image, during the coronavirus pandemic from 2019 to 2022, were the most bankruptcy filings in the US recorded in the year 2021?'}] +Yes, the image shows that the most bankruptcy filings in the US were recorded in the year 2021, during the coronavirus pandemic. The graph displays the number of bankruptcy filings by month, and it is evident that the highest number of filings occurred in 2021. This indicates that the pandemic had a significant impact on businesses and individuals, leading to increased financial distress and the need for bankruptcy protection. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▍ | 713/951 [07:55<08:40, 2.19s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_1.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 90 and 94 years than those aged between 0 and 4 years?'}] +Yes, according to the image, in 2020, China had a larger population aged between 90 and 94 years than those aged between 0 and 4 years. The chart shows that the population aged between 90 and 94 years was 14,444,000, while the population aged between 0 and 4 years was 14,443,996. This indicates that the population aged between 90 and 94 years was slightly larger than the population aged between 0 and 4 years. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 714/951 [07:58<10:09, 2.57s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_1.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 50 and 54 years than those aged between 0 and 4 years?'}] +Yes, according to the image, in 2020, China had a larger population aged between 50 and 54 years than those aged between 0 and 4 years. The chart shows that the population aged between 50 and 54 years was 144,444,000, while the population aged between 0 and 4 years was 144,444,000. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 715/951 [08:00<09:36, 2.44s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_2.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 90 and 94 years than those aged between 0 and 4 years?'}] +Yes, according to the image, in 2020, China had a larger population aged between 90 and 94 years than those aged between 0 and 4 years. The chart shows that the population aged between 90 and 94 years in China was 1,448,000, while the population aged between 0 and 4 years was 1,447,996. This indicates that the population of older adults in China was slightly larger than the population of younger individuals in the same year. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 716/951 [08:03<09:43, 2.48s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/20_2.png'}, {'type': 'text', 'value': 'According to the image, in 2020, did China have a larger population aged between 50 and 54 years than those aged between 0 and 4 years?'}] +Yes, according to the image, in 2020, China had a larger population aged between 50 and 54 years than those aged between 0 and 4 years. The chart shows that the population aged between 50 and 54 years in China was 14.4%, while the population aged between 0 and 4 years was only 1.4%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 717/951 [08:05<08:55, 2.29s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_1.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Black Panther" achieve the highest box office revenue in North America?'}] +Yes, according to the image, "Black Panther" achieved the highest box office revenue in North America in 2018, with a total of $1.34 billion. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 75%|███████▌ | 718/951 [08:06<08:03, 2.08s/it]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_1.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Avengers: Infinity War" achieve the highest box office revenue in North America?'}] +Yes, "Avengers: Infinity War" achieved the highest box office revenue in North America in 2018, with a total of $2.79 billion. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 719/951 [08:07<06:42, 1.74s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_2.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Black Panther" achieve the highest box office revenue in North America?'}] +Yes, "Black Panther" achieved the highest box office revenue in North America in 2018, with a total of $1.348 billion. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 720/951 [08:08<05:52, 1.53s/it]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/chart/21_2.png'}, {'type': 'text', 'value': 'According to the image, in 2018, did "Avengers: Infinity War" achieve the highest box office revenue in North America?'}] +Yes, "Avengers: Infinity War" achieved the highest box office revenue in North America in 2018, with a total of $2.79 billion. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 721/951 [08:09<05:10, 1.35s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does China have the most gold metals, followed by USA and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, China has the most gold medals, followed by the United States and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 722/951 [08:11<05:29, 1.44s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does USA have the most gold metals, followed by China and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, the United States has the most gold medals, followed by China and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 723/951 [08:12<05:18, 1.40s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_1.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does Russia have the most gold metals, followed by China and USA?'}] +According to the metal number chart of 2008 Beijing Olympic, Russia has the most gold medals, followed by China and the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 724/951 [08:13<04:37, 1.22s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does China have the most gold metals, followed by USA and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, China has the most gold medals, followed by the United States and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▌ | 725/951 [08:14<04:33, 1.21s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does USA have the most gold metals, followed by China and Russia?'}] +According to the metal number chart of 2008 Beijing Olympic, the United States has the most gold medals, followed by China and Russia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▋ | 726/951 [08:15<04:04, 1.09s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/0_2.png'}, {'type': 'text', 'value': 'According to the metal number chart of 2008 beijng olympic, does Russia have the most gold metals, followed by China and USA?'}] +According to the metal number chart of 2008 Beijing Olympic, Russia has the most gold medals, followed by China and the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 76%|███████▋ | 727/951 [08:16<04:21, 1.17s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'which country has the largest population growth rate in 2023'}] +The country with the largest population growth rate in 2023 is Niger. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 728/951 [08:17<03:32, 1.05it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'In 2023, did Syria have higher population growth than South Sudan?'}] +Yes, in 2023, Syria had a higher population growth rate than South Sudan. The population growth rate for Syria was 6.3%, while for South Sudan, it was 3.6%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 729/951 [08:18<04:08, 1.12s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_1.png'}, {'type': 'text', 'value': 'In 2023, did Syria have higher population growth than United Kingdom?'}] +Yes, in 2023, Syria had a higher population growth rate than the United Kingdom. The population growth rate for Syria was 6.3%, while the population growth rate for the United Kingdom was 3.7%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 730/951 [08:20<05:00, 1.36s/it]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, which country has the largest population growth rate in 2023'}] +According to the table, Niger has the largest population growth rate in 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 731/951 [08:21<04:04, 1.11s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, In 2023, did Syria have higher population growth than South Sudan?'}] +Yes, according to the table, Syria had a higher population growth rate than South Sudan in 2023. Syria's population growth rate was 3.6%, while South Sudan's population growth rate was 3.3%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 732/951 [08:22<04:20, 1.19s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/1_2.png'}, {'type': 'text', 'value': 'According to the table, In 2023, did Syria have higher population growth than United Kingdom?'}] +Yes, according to the table, Syria had a higher population growth rate than the United Kingdom in 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 733/951 [08:23<03:44, 1.03s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 734/951 [08:24<04:04, 1.13s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 735/951 [08:25<03:27, 1.04it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_1.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 736/951 [08:26<03:52, 1.08s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 77%|███████▋ | 737/951 [08:26<03:18, 1.08it/s]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 738/951 [08:28<03:43, 1.05s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_2.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the listed countries, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 739/951 [08:29<03:22, 1.04it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, which country in Europe has the higher GDP in 2021?'}] +According to the table, Germany has the highest GDP in Europe in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 740/951 [08:30<03:36, 1.03s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP?'}] +According to the table, in 2021, Germany had the highest GDP among the countries listed. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 741/951 [08:30<03:12, 1.09it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/2_3.png'}, {'type': 'text', 'value': 'According to the table, in 2021, did Germany have the highest GDP, followed by France and Italy?'}] +According to the table, in 2021, Germany had the highest GDP among the countries listed, followed by France and Italy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 742/951 [08:32<03:33, 1.02s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi sell most units of the smartphone in Q2 2020?'}] +According to the table, Xiaomi sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 743/951 [08:32<03:08, 1.10it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Samsung sell most units of the smartphone in Q2 2020?'}] +According to the table, Samsung sold the most units of the smartphone in Q2 2020, with a total of 58 million units. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 744/951 [08:34<03:33, 1.03s/it]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_1.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi have the largest smartphone market share in Q2 2020, followed by Samsung and Huawei?'}] +According to the table, Xiaomi had the largest smartphone market share in Q2 2020, followed by Samsung and Huawei. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 745/951 [08:34<03:22, 1.02it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi sell most units of the smartphone in Q2 2020?'}] +According to the table, Xiaomi sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 78%|███████▊ | 746/951 [08:36<03:27, 1.01s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Samsung sell most units of the smartphone in Q2 2020?'}] +According to the table, Samsung sold the most units of the smartphone in Q2 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▊ | 747/951 [08:36<03:07, 1.09it/s]torch.Size([1, 652, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/3_2.png'}, {'type': 'text', 'value': 'According to the table, did Xiaomi have the largest smartphone market share in Q2 2020, followed by Samsung and Huawei?'}] +According to the table, Xiaomi had the largest smartphone market share in Q2 2020, followed by Samsung and Huawei. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▊ | 748/951 [08:37<03:22, 1.00it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, Florida has the highest average maximum temperature in 2021 among the listed states. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 749/951 [08:38<02:57, 1.14it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature among the listed states in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 750/951 [08:39<03:24, 1.02s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_1.png'}, {'type': 'text', 'value': 'According to the table, According to the table, did Florida have a higher average maximum temperature than Louisana?'}] +Yes, according to the table, Florida had a higher average maximum temperature than Louisiana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 751/951 [08:40<02:49, 1.18it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, the state in the United States with the average maximum temperature in 2021 is Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 752/951 [08:41<03:28, 1.05s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature among the listed states in 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 753/951 [08:42<03:01, 1.09it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_2.png'}, {'type': 'text', 'value': 'According to the table, did Florida have a higher average maximum temperature than Louisana?'}] +Yes, according to the table, Florida had a higher average maximum temperature than Louisiana. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 754/951 [08:43<03:22, 1.03s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, Which state in the United States has the average maximum temperature in 2021 ?'}] +According to the table, the state in the United States with the average maximum temperature in 2021 is Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 755/951 [08:44<02:58, 1.10it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, did Florida have the highest average maximum temperature ?'}] +According to the table, Florida had the highest average maximum temperature in the United States in 2020, with an average of 72.2 degrees Fahrenheit. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 79%|███████▉ | 756/951 [08:45<03:22, 1.04s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/4_3.png'}, {'type': 'text', 'value': 'According to the table, did Florida have a higher average maximum temperature than South Carolina?'}] +Yes, according to the table, Florida had a higher average maximum temperature than South Carolina. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 757/951 [08:46<02:50, 1.14it/s]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 758/951 [08:47<03:17, 1.02s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 759/951 [08:48<03:14, 1.01s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was 0.29%, while the percentage change in August 2023 was 0.22%. This indicates that the income situation in January 2023 was better than in August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|███████▉ | 760/951 [08:51<05:03, 1.59s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_1.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, January 2023 had a lower income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was -0.2%, while the percentage change in August 2023 was 0.2%. This indicates that the personal income in August 2023 increased by 0.2% compared to January 2023, which experienced a decrease of 0.2%. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 761/951 [08:53<05:45, 1.82s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 762/951 [08:55<05:37, 1.78s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is August. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 763/951 [08:56<04:45, 1.52s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that the personal income percentage change in January 2023 was 0.8%, while the percentage change in August 2023 was 0.4%. This indicates that the income situation in January 2023 was more favorable than in August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 764/951 [08:59<06:01, 1.93s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_2.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, January 2023 had a lower income percentage change than August 2023. The table shows that the percentage change in personal income in the United States from September 2022 to August 2023 was 8.0%, while the percentage change in personal income in the United States from January 2023 to August 2023 was 0.0%. This indicates that the income situation in the United States improved significantly from January to August 2023, while it remained relatively stable from September 2022 to August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 80%|████████ | 765/951 [09:02<06:53, 2.22s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the image, which month has the lowest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the lowest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 766/951 [09:04<06:25, 2.08s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the image, which month has the highest percentage change in personal income in the United States from September 2022 to September 2023'}] +According to the image, the month with the highest percentage change in personal income in the United States from September 2022 to September 2023 is December. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 767/951 [09:05<05:30, 1.79s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a higher income percentage change than August 2023?'}] +According to the table, January 2023 had a higher income percentage change than August 2023. The table shows that in January 2023, the personal income percentage change was 4.4%, while in August 2023, the percentage change was 0.6%. This indicates that the income situation in the United States improved in January 2023 compared to August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 768/951 [09:07<05:48, 1.91s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/5_3.png'}, {'type': 'text', 'value': 'According to the table, Did January 2023 have a lower income percentage change than August 2023?'}] +According to the table, the personal income percentage change in the United States in January 2023 was 0.4%, while the percentage change in August 2023 was 0.6%. Therefore, January 2023 had a lower income percentage change than August 2023. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 769/951 [09:08<05:33, 1.83s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 2,729 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 770/951 [09:09<04:39, 1.54s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +Yes, according to the table, Beijing has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 771/951 [09:10<04:13, 1.41s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020, with a population density of 7,759 people per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████ | 772/951 [09:11<03:44, 1.25s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_1.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +Yes, according to the table, Zhejiang has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 773/951 [09:13<03:57, 1.33s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 3,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 774/951 [09:14<04:01, 1.36s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +Yes, according to the table, Beijing has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 81%|████████▏ | 775/951 [09:15<03:23, 1.16s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020, with a population density of 1,322 per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 776/951 [09:16<03:30, 1.20s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_2.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +Yes, according to the table, Zhejiang has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 777/951 [09:17<03:03, 1.06s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Shanghai have the most dense population in China in 2020?'}] +According to the table, Shanghai has the most dense population in China in 2020, with a population density of 1,667 people per square kilometer. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 778/951 [09:18<03:12, 1.11s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Beijing have the second most dense population in China in 2020?'}] +Yes, according to the table, Beijing has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 779/951 [09:19<02:46, 1.03it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Shandong have the most dense population in China in 2020?'}] +According to the table, Shandong has the most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 780/951 [09:20<03:01, 1.06s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/6_3.png'}, {'type': 'text', 'value': 'According to the table, does Zhejiang have the second most dense population in China in 2020?'}] +Yes, according to the table, Zhejiang has the second most dense population in China in 2020. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 781/951 [09:21<02:39, 1.06it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +Yes, according to the table, Norway has 16 gold medals in the winter Olympics in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 782/951 [09:22<02:54, 1.03s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 783/951 [09:23<02:37, 1.07it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 12. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 82%|████████▏ | 784/951 [09:24<02:51, 1.03s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 785/951 [09:25<02:35, 1.07it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals won by China in the winter Olympics in 2022 is 15. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 786/951 [09:26<02:50, 1.04s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_1.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals won by China in the winter Olympics in 2022 is 37. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 787/951 [09:27<02:37, 1.04it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +Yes, according to the table, Norway has won 16 gold medals in the Winter Olympics 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 788/951 [09:28<02:42, 1.00it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 789/951 [09:29<02:28, 1.09it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 12. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 790/951 [09:30<02:41, 1.00s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 791/951 [09:31<02:31, 1.05it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals won by China in the 2022 Winter Olympics is 15. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 792/951 [09:32<02:35, 1.02it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_2.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals won by China in the 2022 Winter Olympics is 37. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 793/951 [09:32<02:24, 1.10it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 16 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 16. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 83%|████████▎ | 794/951 [09:34<02:36, 1.00it/s]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Norway 9 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Norway in the winter Olympics in 2022 is 9. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▎ | 795/951 [09:34<02:23, 1.09it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 12 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 12. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▎ | 796/951 [09:36<02:36, 1.01s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of gold medals of Germany 8 in winter Olympics in 2022?'}] +Yes, according to the table, the number of gold medals for Germany in the winter Olympics in 2022 is 8. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 797/951 [09:36<02:24, 1.07it/s]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 15 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals won by China in the Winter Olympics 2022 is 15. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 798/951 [09:38<02:35, 1.02s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/7_3.png'}, {'type': 'text', 'value': 'According to the table, is the number of all medals of China 37 in winter Olympics in 2022?'}] +Yes, according to the table, the number of all medals for China in the Winter Olympics 2022 is 37. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 799/951 [09:38<02:21, 1.07it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift releases the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 800/951 [09:40<02:33, 1.01s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2022 in the United States, and "Harry's House" is not among them. The table does include the album "Midnights" by Taylor Swift, which is listed as the third best-selling album of 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 801/951 [09:42<03:19, 1.33s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +Yes, according to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 802/951 [09:43<03:39, 1.47s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +Yes, according to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 84%|████████▍ | 803/951 [09:44<03:15, 1.32s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by BTS has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 804/951 [09:46<03:34, 1.46s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_1.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by BTS has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 805/951 [09:47<03:21, 1.38s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift releases the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 806/951 [09:48<02:45, 1.14s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2021 in physical and digital sales, and "Harry's House" is not among them. The table does include the album "Midnights," which is listed as the 10th best-selling album of 2021. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 807/951 [09:50<03:27, 1.44s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +Yes, according to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▍ | 808/951 [09:51<03:11, 1.34s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +Yes, according to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 809/951 [09:52<02:54, 1.23s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 810/951 [09:54<03:13, 1.37s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_2.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 811/951 [09:55<03:04, 1.32s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Midnights"?'}] +Yes, according to the information provided in the table, Taylor Swift released the album "Midnights." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 812/951 [09:56<02:33, 1.10s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does Taylor Swift release the album "Harry\'s House"?'}] +According to the information provided in the table, Taylor Swift does not release the album "Harry's House." The table lists the top 10 selling albums of 2022 in the United States, and "Harry's House" is not among them. The table does include the album "Midnights" by Taylor Swift, which is listed as the 10th best-selling album of 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 85%|████████▌ | 813/951 [09:58<03:15, 1.42s/it]torch.Size([1, 659, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 814/951 [09:59<03:02, 1.33s/it]torch.Size([1, 657, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Midnights" have a sale of 422,000 in 2022?'}] +Yes, according to the information provided in the table, the album "Midnights" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 815/951 [10:00<02:46, 1.22s/it]torch.Size([1, 654, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 422,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 422,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 816/951 [10:02<03:05, 1.37s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/8_3.png'}, {'type': 'text', 'value': 'Accroding to the information provided in the table, does the album "Proof" have a sale of 1,818,000 in 2022?'}] +According to the information provided in the table, the album "Proof" by Taylor Swift has a sale of 1,818,000 in 2022. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 817/951 [10:03<02:54, 1.30s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the UB group have the highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the highest portion of the market share for beer across India in 2020, with 54% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 818/951 [10:04<02:37, 1.19s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the Carlsberg India have the highest portion of the market share for beer across India in 2020?'}] +According to the table, Carlsberg India has the highest portion of the market share for beer across India in 2020, with a 33% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 819/951 [10:05<02:58, 1.35s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the SABMiller India have the second highest portion of the market share for beer across India in 2020?'}] +Yes, according to the table, SABMiller India has the second highest portion of the market share for beer across India in 2020, with a 15% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▌ | 820/951 [10:07<02:52, 1.31s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_1.png'}, {'type': 'text', 'value': 'According to the table, does the UB Group have the second highest portion of the market share for beer across India in 2020?'}] +Yes, according to the table, the UB Group has the second highest portion of the market share for beer across India in 2020, with a 15% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▋ | 821/951 [10:08<02:34, 1.19s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the UB group have the highest portion of the market share for beer across India in 2020?'}] +According to the table, the UB Group has the highest portion of the market share for beer across India in 2020, with 54% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 86%|████████▋ | 822/951 [10:09<02:55, 1.36s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the Carlsberg India have the highest portion of the market share for beer across India in 2020?'}] +According to the table, Carlsberg India has the highest portion of the market share for beer across India in 2020, with 72% of the market share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 823/951 [10:11<02:48, 1.32s/it]torch.Size([1, 651, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the SABMiller India have the second highest portion of the market share for beer across India in 2020?'}] +Yes, according to the table, SABMiller India has the second highest portion of the market share for beer across India in 2020, with a 17% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 824/951 [10:11<02:31, 1.20s/it]torch.Size([1, 649, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/9_2.png'}, {'type': 'text', 'value': 'According to the table, does the UB Group have the second highest portion of the market share for beer across India in 2020?'}] +Yes, according to the table, the UB Group has the second highest portion of the market share for beer across India in 2020, with a 17% share. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 825/951 [10:12<02:24, 1.14s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does China have the highest carbon dioxide emissions worldwide in 2010?'}] +Yes, according to the table, China has the highest carbon dioxide emissions worldwide in 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 826/951 [10:13<02:03, 1.01it/s]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does US have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, the United States has the highest carbon dioxide emissions worldwide in 2010, with 5,259 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 827/951 [10:14<02:15, 1.09s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, does Russia have the second highest carbon dioxide emissions worldwide in 2010?'}] +Yes, according to the table, Russia has the second highest carbon dioxide emissions worldwide in 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 828/951 [10:15<02:04, 1.01s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_1.png'}, {'type': 'text', 'value': 'According to this table, is the carbon dioxide emission worldwide in 2010 the same for US and India?'}] +According to the table, the carbon dioxide emission worldwide in 2010 was 8,777 million metric tons for the United States and 6,667 million metric tons for India. This indicates that the carbon dioxide emission worldwide in 2010 was higher for the United States than for India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 829/951 [10:17<02:26, 1.20s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does China have the highest carbon dioxide emissions worldwide in 2010?'}] +Yes, according to the table, China has the highest carbon dioxide emissions worldwide in 2010. The table shows that China emitted 6,770 million metric tons of carbon dioxide in 2010, which is significantly higher than the emissions of other countries. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 830/951 [10:18<02:34, 1.28s/it]torch.Size([1, 643, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does US have the highest carbon dioxide emissions worldwide in 2010?'}] +According to the table, the United States has the highest carbon dioxide emissions worldwide in 2010, with 6,700 million metric tons. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 831/951 [10:19<02:17, 1.15s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, does Russia have the second highest carbon dioxide emissions worldwide in 2010?'}] +Yes, according to the table, Russia has the second highest carbon dioxide emissions worldwide in 2010. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 87%|████████▋ | 832/951 [10:21<02:30, 1.26s/it]torch.Size([1, 645, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/table/10_2.png'}, {'type': 'text', 'value': 'According to this table, is the carbon dioxide emission worldwide in 2010 the same for US and India?'}] +According to the table, the carbon dioxide emission worldwide in 2010 was 6,700 million metric tons for the United States and 6,100 million metric tons for India. This indicates that the carbon dioxide emission worldwide in 2010 was higher for the United States than for India. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 833/951 [10:22<02:41, 1.37s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than Texas state?'}] +No, according to the map provided, New Mexico is not larger than Texas. The map shows the United States of America, and Texas is larger than New Mexico. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 834/951 [10:23<02:18, 1.18s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is Texas state larger than California state?'}] +Yes, according to the map provided, Texas is larger than California. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 835/951 [10:24<02:21, 1.22s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than California state?'}] +No, according to the map provided, New Mexico is not larger than California. The map shows the United States of America, and both New Mexico and California are depicted as states. However, California is larger than New Mexico, as it occupies a larger area in the western part of the country. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 836/951 [10:26<02:34, 1.34s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_1.png'}, {'type': 'text', 'value': 'According to the map provided, is Montana state larger than New Mexico state?'}] +Yes, according to the map provided, Montana state is larger than New Mexico state. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 837/951 [10:26<02:03, 1.08s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than Texas state?'}] +No, according to the map provided, New Mexico is not larger than Texas. The map shows the United States of America, and Texas is larger than New Mexico. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 838/951 [10:28<02:13, 1.18s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is Texas state larger than California state?'}] +Yes, according to the map provided, Texas is larger than California. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 839/951 [10:28<01:48, 1.04it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is New Mexico state larger than California state?'}] +No, according to the map provided, New Mexico is not larger than California. The map shows the United States of America, and both New Mexico and California are depicted as states. However, California is significantly larger than New Mexico, as it occupies a much larger portion of the western coast of the United States. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 840/951 [10:30<02:02, 1.10s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/0_2.png'}, {'type': 'text', 'value': 'According to the map provided, is Montana state larger than New Mexico state?'}] +Yes, according to the map provided, Montana state is larger than New Mexico state. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 88%|████████▊ | 841/951 [10:30<01:39, 1.10it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Delaware the farthest north?'}] +Yes, Delaware is the farthest north among the states shown on the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 842/951 [10:31<01:23, 1.31it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Arizona the farthest north?'}] +Yes, among the states shown on the map, Arizona is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 843/951 [10:32<01:31, 1.18it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Oklahoma the farthest north?'}] +Yes, according to the map provided, Oklahoma is the farthest north among the states of Arizona, North Carolina, and Delaware. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▊ | 844/951 [10:32<01:23, 1.27it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_1.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is North Carolina the farthest north?'}] +Yes, among the states shown on the map, North Carolina is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 845/951 [10:34<01:39, 1.06it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Delaware the farthest north?'}] +Yes, Delaware is the farthest north among the states shown on the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 846/951 [10:34<01:26, 1.22it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Arizona the farthest north?'}] +Yes, among the states shown on the map, Arizona is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 847/951 [10:35<01:18, 1.33it/s]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is Oklahoma the farthest north?'}] +Yes, among the states shown on the map, Oklahoma is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 848/951 [10:36<01:39, 1.04it/s]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/1_2.png'}, {'type': 'text', 'value': 'According to the map provided, among Arizona, Oklahoma, North Carolina, and Delaware on the map, is North Carolina the farthest north?'}] +Yes, among the states shown on the map, North Carolina is the farthest north. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 849/951 [10:38<01:49, 1.08s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_1.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Atlantic Ocean, Southern Ocean, and Arctic Ocean?'}] +Yes, according to the map, the prime meridian intersects the Atlantic Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 850/951 [10:38<01:35, 1.06it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_1.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Pacific Ocean, Southern Ocean, and Arctic Ocean?'}] +Yes, according to the map, the prime meridian intersects the Pacific Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 89%|████████▉ | 851/951 [10:39<01:44, 1.04s/it]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_2.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Atlantic Ocean, Southern Ocean, and Arctic Ocean?'}] +Yes, according to the map, the prime meridian intersects the Atlantic Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 852/951 [10:40<01:33, 1.05it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/2_2.png'}, {'type': 'text', 'value': 'According to the map, does the prime meridian intersect the Pacific Ocean, Southern Ocean, and Arctic Ocean?'}] +Yes, according to the map, the prime meridian intersects the Pacific Ocean, Southern Ocean, and Arctic Ocean. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 853/951 [10:41<01:39, 1.02s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_1.png'}, {'type': 'text', 'value': 'Based on the map, did the Democratic Party win Texas in the 2020 elections?'}] +Based on the map, the Democratic Party did not win Texas in the 2020 elections. The map shows a red and blue color-coded representation of the United States, with the blue areas representing the Democratic Party's victories and the red areas representing the Republican Party's victories. Texas is colored red, indicating that it was won by the Republican Party in the 2020 elections. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 854/951 [10:43<02:04, 1.29s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_1.png'}, {'type': 'text', 'value': 'Based on the map, did the Republic Party win Texas in the 2020 elections?'}] +Based on the map, the Republic Party did not win Texas in the 2020 elections. The map shows that the Democratic Party won the majority of the states, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|████████▉ | 855/951 [10:44<01:51, 1.16s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_2.png'}, {'type': 'text', 'value': 'Based on the map, did the Democratic Party win Texas in the 2020 elections?'}] +Based on the map, the Democratic Party did not win Texas in the 2020 elections. The map shows that the Republican Party won the majority of the states in the United States, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 856/951 [10:45<01:49, 1.16s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/3_2.png'}, {'type': 'text', 'value': 'Based on the map, did the Republic Party win Texas in the 2020 elections?'}] +Based on the map, the Republic Party did not win Texas in the 2020 elections. The map shows that the Democratic Party won the majority of the states, including Texas. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 857/951 [10:46<01:42, 1.09s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in North America?'}] +Yes, the Rocky Mountains are located in North America, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 858/951 [10:48<01:48, 1.17s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in Asia?'}] +No, the Rocky Mountains are not located in Asia. They are located in North America, specifically in the United States and Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 859/951 [10:49<01:57, 1.28s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in North America?'}] +No, the Himalayas are not located in North America. They are a mountain range in Asia, stretching from the Indian subcontinent to the Tibetan Plateau. The map in the image shows the Himalayas in the correct location, which is Asia. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 90%|█████████ | 860/951 [10:51<02:15, 1.49s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_1.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in Asia?'}] +Yes, the Himalayas Mountains are located in Asia, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 861/951 [10:52<01:47, 1.19s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in North America?'}] +Yes, the Rocky Mountains are located in North America, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 862/951 [10:52<01:26, 1.03it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Rocky Mountains located in Asia?'}] +No, the Rocky Mountains are not located in Asia. They are located in North America, specifically in the United States and Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 863/951 [10:54<01:40, 1.14s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in North America?'}] +No, the Himalayas Mountains are not located in North America. They are located in Asia, specifically in the countries of Nepal, India, Pakistan, and Bhutan. The map in the image shows the Himalayas as part of the Asian continent, not North America. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 864/951 [10:55<01:46, 1.22s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/4_2.png'}, {'type': 'text', 'value': 'Based on the map, are the Himalayas Mountains located in Asia?'}] +Yes, the Himalayas Mountains are located in Asia, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 865/951 [10:56<01:27, 1.02s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Huron?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Huron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 866/951 [10:57<01:34, 1.11s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Ontario?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████ | 867/951 [10:57<01:19, 1.05it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Huron?'}] +No, New York is not the only U.S. state that shares a border with Lake Huron. The image shows that the Great Lakes region includes parts of the United States and Canada. The U.S. states that share a border with Lake Huron are Michigan, Ohio, Indiana, Illinois, and Wisconsin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 868/951 [10:59<01:30, 1.09s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_1.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Ontario?'}] +No, New York is not the only U.S. state that shares a border with Lake Ontario. The image also shows that Michigan shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 869/951 [11:00<01:21, 1.00it/s]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Huron?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Huron. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 91%|█████████▏| 870/951 [11:01<01:22, 1.02s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is Michigan the only U.S. state that shares a border with Lake Ontario?'}] +Yes, according to the image, Michigan is the only U.S. state that shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 871/951 [11:01<01:11, 1.12it/s]torch.Size([1, 642, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Huron?'}] +No, New York is not the only U.S. state that shares a border with Lake Huron. The image shows that the Great Lakes region includes parts of the United States and Canada. The U.S. states that share a border with Lake Huron are Michigan, Ohio, Indiana, Illinois, and Wisconsin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 872/951 [11:03<01:22, 1.05s/it]torch.Size([1, 641, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/5_2.png'}, {'type': 'text', 'value': 'According to the image, is New York the only U.S. state that shares a border with Lake Ontario?'}] +Yes, according to the image, New York is the only U.S. state that shares a border with Lake Ontario. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 873/951 [11:03<01:11, 1.10it/s]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Blue Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Blue Line towards the Pentagon on the DC Metro system. The map shows the Blue Line running through the Pentagon area, indicating that it is a viable option for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 874/951 [11:05<01:18, 1.01s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Red Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Red Line towards the Pentagon on the DC Metro system. The map shows the Red Line going through the Pentagon, indicating that it is a viable route for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 875/951 [11:06<01:37, 1.29s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_1.png'}, {'type': 'text', 'value': 'According to the map, can I take the Yellow Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Yellow Line towards the Pentagon on the DC Metro system. The map shows the Yellow Line running through the Pentagon area, indicating that it is a viable route for travelers. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 876/951 [11:08<01:51, 1.48s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Blue Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Blue Line towards the Pentagon on the DC Metro system. The map shows the Blue Line running through the city, with a stop at the Pentagon. This indicates that the Blue Line is a viable option for traveling to the Pentagon. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 877/951 [11:10<01:59, 1.62s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Red Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Red Line towards the Pentagon on the DC Metro system. The map shows the Red Line going through the Pentagon area, indicating that it is a viable route for traveling to that location. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 878/951 [11:12<02:05, 1.72s/it]torch.Size([1, 640, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/6_2.png'}, {'type': 'text', 'value': 'According to the map, can I take the Yellow Line towards the Pentagon on the DC Metro system?'}] +Yes, according to the map, you can take the Yellow Line towards the Pentagon on the DC Metro system. The map shows the Yellow Line running through the Pentagon area, indicating that it is a viable route for traveling to the Pentagon. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 92%|█████████▏| 879/951 [11:14<02:09, 1.80s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_1.png'}, {'type': 'text', 'value': 'According to the image, is Key West the southernmost point of Florida?'}] +Yes, Key West is the southernmost point of Florida, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 880/951 [11:15<01:39, 1.40s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_1.png'}, {'type': 'text', 'value': 'According to the image, is Miami the southernmost point of Florida?'}] +Yes, according to the image, Miami is the southernmost point of Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 881/951 [11:15<01:19, 1.13s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_2.png'}, {'type': 'text', 'value': 'According to the image, is Key West the southernmost point of Florida?'}] +Yes, Key West is the southernmost point of Florida, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 882/951 [11:17<01:22, 1.20s/it]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/7_2.png'}, {'type': 'text', 'value': 'According to the image, is Miami the southernmost point of Florida?'}] +Yes, according to the image, Miami is the southernmost point of Florida. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 883/951 [11:17<01:05, 1.04it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': "Based on the map, is Charles County located to the south of Prince George's County?"}] +Yes, based on the map, Charles County is located to the south of Prince George's County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 884/951 [11:18<01:07, 1.01s/it]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': 'Based on the map, is Calvert County located to the east of Cecil County?'}] +Yes, based on the map, Calvert County is located to the east of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 885/951 [11:19<00:57, 1.16it/s]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_1.png'}, {'type': 'text', 'value': 'Based on the map, is Kent County located to the north of Cecil County?'}] +Yes, based on the map, Kent County is located to the north of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 886/951 [11:19<00:50, 1.29it/s]torch.Size([1, 637, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': "Based on the map, is Charles County located to the south of Prince George's County?"}] +Yes, Charles County is located to the south of Prince George's County, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 887/951 [11:21<01:01, 1.04it/s]torch.Size([1, 636, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': 'Based on the map, is Calvert County located to the east of Cecil County?'}] +Yes, based on the map, Calvert County is located to the east of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 888/951 [11:22<01:09, 1.11s/it]torch.Size([1, 635, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/8_2.png'}, {'type': 'text', 'value': 'Based on the map, is Kent County located to the north of Cecil County?'}] +Yes, based on the map, Kent County is located to the north of Cecil County. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 93%|█████████▎| 889/951 [11:23<01:00, 1.03it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_1.png'}, {'type': 'text', 'value': 'According to the image, does Bolivia cover part of the Amazon Basin?'}] +Yes, Bolivia covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▎| 890/951 [11:24<01:04, 1.06s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_1.png'}, {'type': 'text', 'value': 'According to the image, does Chile cover part of the Amazon Basin?'}] +Yes, Chile covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▎| 891/951 [11:25<00:54, 1.09it/s]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_2.png'}, {'type': 'text', 'value': 'According to the image, does Bolivia cover part of the Amazon Basin?'}] +Yes, Bolivia covers part of the Amazon Basin, as indicated by the map. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 892/951 [11:25<00:48, 1.22it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/9_2.png'}, {'type': 'text', 'value': 'According to the image, does Chile cover part of the Amazon Basin?'}] +Yes, Chile covers part of the Amazon Basin. The image shows a map of South America with the Amazon Basin and Chile highlighted. The Amazon Basin is a vast region that spans across several countries, including Brazil, Peru, Bolivia, and Colombia. Chile is located in the southwestern part of South America, and its border with Peru and Bolivia is close to the Amazon Basin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 893/951 [11:28<01:23, 1.44s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_1.png'}, {'type': 'text', 'value': 'According to the image, does the Oyashio Current flow from the south to the north, while the Kuroshio Current flows from the north to the south?'}] +Yes, according to the image, the Oyashio Current flows from the south to the north, while the Kuroshio Current flows from the north to the south. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 894/951 [11:29<01:11, 1.26s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_1.png'}, {'type': 'text', 'value': 'According to the image, does the Kuroshio Current flow through Russia?'}] +No, the Kuroshio Current does not flow through Russia. The image shows the Kuroshio Current flowing through the East China Sea and the Pacific Ocean, but it does not pass through Russia. The current is primarily located in the waters between Japan and Taiwan, and it is an important factor in the region's climate and marine ecosystem. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 895/951 [11:30<01:14, 1.34s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_2.png'}, {'type': 'text', 'value': 'According to the image, does the Oyashio Current flow from the south to the north, while the Kuroshio Current flows from the north to the south?'}] +Yes, according to the image, the Oyashio Current flows from the south to the north, while the Kuroshio Current flows from the north to the south. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 896/951 [11:32<01:17, 1.40s/it]torch.Size([1, 634, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/map/10_2.png'}, {'type': 'text', 'value': 'According to the image, does the Kuroshio Current flow through Russia?'}] +No, the Kuroshio Current does not flow through Russia. The image shows the Kuroshio Current flowing through the East China Sea and the Pacific Ocean, but it does not pass through Russia. The current is primarily located in the waters between Japan and Taiwan, and it is an important factor in the region's climate and marine ecosystem. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 897/951 [11:34<01:23, 1.55s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_1.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1415926 to 3.1415927?'}] +Yes, according to the image, the value of π (pi) ranges from 3.1415926 to 3.1415927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 94%|█████████▍| 898/951 [11:35<01:11, 1.36s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_1.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1615926 to 3.1615927?'}] +Yes, according to the image, the value of π (pi) ranges from 3.1615926 to 3.1615927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 899/951 [11:37<01:17, 1.48s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_2.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1415926 to 3.1415927?'}] +According to the image, the value of π (pi) ranges from 3.1415926 to 3.1415927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 900/951 [11:38<01:11, 1.40s/it]torch.Size([1, 653, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/0_2.png'}, {'type': 'text', 'value': 'According to the image, does π(pi) range from 3.1615926 to 3.1615927?'}] +Yes, according to the image, the value of π (pi) ranges from 3.1615926 to 3.1615927. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 901/951 [11:39<01:03, 1.27s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/1_1.png'}, {'type': 'text', 'value': "Is the formula in the image representative of the mass-energy equivalence concept in Einstein's theory?"}] +Yes, the formula in the image is representative of the mass-energy equivalence concept in Einstein's theory of relativity. The equation E=mc represents the relationship between energy (E) and mass (m) in the form of the famous equation E=mc^2. This equation states that energy and mass are interchangeable and that the energy of an object is directly proportional to its mass and the square of the speed of light. This concept is crucial in understanding the behavior of particles and the nature of the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 902/951 [11:42<01:29, 1.82s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/1_2.png'}, {'type': 'text', 'value': "Is the formula in the image representative of the mass-energy equivalence concept in Einstein's theory?"}] +Yes, the formula in the image is representative of the mass-energy equivalence concept in Einstein's theory of relativity. The equation E=mc represents the relationship between energy (E) and mass (m) in the form of the famous equation E=mc^2. This equation states that energy and mass are interchangeable and that the energy of an object is directly proportional to its mass and the square of the speed of light. This concept is crucial in understanding the behavior of particles and the nature of the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▍| 903/951 [11:44<01:33, 1.95s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.71 to 2.72?"}] +No, the Euler's Number 'e' does not range from 2.71 to 2.72. The image shows a series of numbers, including the Euler's Number 'e', which is approximately equal to 2.71828. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 904/951 [11:45<01:22, 1.76s/it]torch.Size([1, 656, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image which is about the Euler's Number, does the Euler's Number 'e' range from 2.70 to 2.71?"}] +No, the Euler's Number 'e' does not range from 2.70 to 2.71. The Euler's Number is approximately equal to 2.71828. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 905/951 [11:47<01:22, 1.80s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_1.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.72 to 2.73?"}] +No, the Euler's Number 'e' does not range from 2.72 to 2.73. The image shows a series of numbers, including the Euler's Number 'e', which is approximately equal to 2.71828. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 906/951 [11:49<01:22, 1.83s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.71 to 2.72?"}] +No, the Euler's Number 'e' does not range from 2.71 to 2.72. The image shows a series of numbers, including the Euler's Number 'e', which is approximately equal to 2.71828. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 907/951 [11:51<01:21, 1.86s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.70 to 2.71?"}] +No, the Euler's Number 'e' does not range from 2.70 to 2.71. The image shows a series of numbers, including the Euler's Number 'e', which is approximately equal to 2.71828. The numbers in the image are not in a range of 2.70 to 2.71. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 95%|█████████▌| 908/951 [11:53<01:20, 1.88s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/2_2.png'}, {'type': 'text', 'value': "According to the image, does the Euler's Number 'e' range from 2.72 to 2.73?"}] +No, the Euler's Number 'e' does not range from 2.72 to 2.73. The image shows a series of numbers, including the Euler's Number 'e', which is approximately equal to 2.71828. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 909/951 [11:55<01:19, 1.90s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.40 to 1.41?'}] +No, the value of the square root of 2 does not range from 1.40 to 1.41. The value of the square root of 2 is approximately 1.4142. The image shows a series of numbers, including the square root of 2, which is represented by the number 1.4142. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 910/951 [11:57<01:18, 1.92s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.41 to 1.42?'}] +No, the value of the square root of 2 does not range from 1.41 to 1.42. The value of the square root of 2 is approximately 1.4142. The image shows a series of numbers, including the square root of 2, which is represented by the number 1.4142. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 911/951 [11:59<01:16, 1.91s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_1.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.42 to 1.43?'}] +No, the value of the square root of 2 does not range from 1.42 to 1.43. The value of the square root of 2 is approximately 1.4142135623734509850089977497636079580886774907317667973731768219542357098500868790785326998466564039491. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 912/951 [12:03<01:35, 2.45s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.40 to 1.41?'}] +No, the value of the square root of 2 does not range from 1.40 to 1.41. The value of the square root of 2 is approximately 1.4142. The image shows a series of numbers, including the square root of 2, which is 1.4142. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 913/951 [12:05<01:30, 2.39s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.41 to 1.42?'}] +No, the value of the square root of 2 does not range from 1.41 to 1.42. The value of the square root of 2 is approximately 1.4142. The image shows a series of numbers, including the square root of 2, which is represented by the number 1.4142. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 914/951 [12:07<01:22, 2.23s/it]torch.Size([1, 647, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/3_2.png'}, {'type': 'text', 'value': 'According to the image, does the value of the square root of 2 range from 1.42 to 1.43?'}] +No, the value of the square root of 2 does not range from 1.42 to 1.43. The value of the square root of 2 is approximately 1.414213562373450985008997749763607958088677490731766874195423570985008687907853269984665640394971607482643134862870703499169992129639937. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▌| 915/951 [12:11<01:39, 2.76s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_1.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Gravity equation?'}] +Yes, the formula in the image is representative of the Gravity equation. The equation is written in terms of the gravitational constant (G), mass (m), and distance (r) squared. The equation is Gm/r^2, which is a fundamental equation in physics that describes the force of gravity between two objects. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▋| 916/951 [12:13<01:27, 2.51s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_1.png'}, {'type': 'text', 'value': 'According to the image, is the formula F=G * m_1 * m_2 / r^2 representative of the Gravity equation?'}] +Yes, the formula F=G \* m\_1 \* m\_2 / r^2 is representative of the Gravity equation. It is a mathematical equation that describes the force of gravity between two objects, where F is the force, G is the gravitational constant, m\_1 and m\_2 are the masses of the two objects, and r is the distance between them. This equation is a fundamental concept in physics and is used to calculate the gravitational force between two objects, such as planets or stars, in a gravitational system. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 96%|█████████▋| 917/951 [12:15<01:25, 2.52s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_2.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Gravity equation?'}] +Yes, the formula in the image is representative of the Gravity equation. The equation is written in terms of the gravitational constant (G), mass (m), and distance (r) squared. The equation is G \* m / r^2, which is a fundamental equation in physics that describes the force of gravity between two objects. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 918/951 [12:17<01:13, 2.23s/it]torch.Size([1, 648, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/4_2.png'}, {'type': 'text', 'value': 'According to the image, is the formula F=G * m_1 * m_2 / r^2 representative of the Gravity equation?'}] +Yes, the formula F=G \* m\_1 \* m\_2 / r^2 is representative of the Gravity equation. It is a fundamental equation in physics that describes the force of gravity between two objects, where F is the force, G is the gravitational constant, m\_1 and m\_2 are the masses of the two objects, and r is the distance between them. This equation is used to calculate the gravitational force between two objects, which is a key component in understanding the behavior of celestial bodies and the universe. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 919/951 [12:19<01:12, 2.27s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_1.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Euler equation?'}] +Yes, the formula in the image is representative of the Euler equation. The equation is written as: + +cos(x) + sin(x) = 1 + +This equation is a fundamental equation in trigonometry and is often used to solve problems related to angles and their relationships to other angles. The Euler equation is a simple yet powerful tool that can be applied in various fields, such as physics, engineering, and mathematics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 920/951 [12:21<01:07, 2.17s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_1.png'}, {'type': 'text', 'value': 'Is the formula e^ix = cos x + i x representative of the equation in this figure?'}] +Yes, the formula e^ix = cos x + i x is representative of the equation in the figure. The equation is a mathematical expression that represents the relationship between the exponential function e^x and the trigonometric functions cos x and sin x. In the image, the equation is displayed in a graphical format, with the exponential function e^x on the x-axis and the trigonometric functions cos x and sin x on the y-axis. This representation helps to visualize the relationship between these functions and understand how they are related to each other. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 921/951 [12:24<01:08, 2.27s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_2.png'}, {'type': 'text', 'value': 'Is the formula in this image representative of the Euler equation?'}] +Yes, the formula in the image is representative of the Euler equation. The equation is written as: + +cos(x) + sin(x) = 1 + +This equation is a fundamental equation in trigonometry and is often used to solve problems related to the behavior of waves, such as the wave equation in physics. The Euler equation is a simple and elegant way to describe the relationship between the sine and cosine functions, and it has applications in various fields, including physics, engineering, and mathematics. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 922/951 [12:27<01:14, 2.57s/it]torch.Size([1, 638, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/5_2.png'}, {'type': 'text', 'value': 'Is the formula e^ix = cos x + i x representative of the equation in this figure?'}] +Yes, the formula e^ix = cos x + i x is representative of the equation in the figure. The equation is a mathematical expression that represents the relationship between the exponential function e^x and the trigonometric functions cos x and sin x. In the image, the equation is displayed in a graphical format, with the exponential function e^x on the x-axis and the trigonometric functions cos x and sin x on the y-axis. The equation is a fundamental concept in mathematics and physics, and it is often used to describe various phenomena, such as the behavior of waves, the motion of particles, and the properties of electromagnetic fields. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 923/951 [12:30<01:18, 2.80s/it]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_1.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.66 * 10^-11 to 6.68 * 10^-11?"}] +Yes, the value of Gravity constant 'G' ranges from 6.66 * 10^-11 to 6.68 * 10^-11, as shown in the image. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 924/951 [12:31<01:01, 2.27s/it]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_1.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.68 * 10^-11 to 6.70 * 10^-11?"}] +Yes, according to the image, the value of the Gravity constant 'G' ranges from 6.68 * 10^-11 to 6.70 * 10^-11. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 925/951 [12:33<00:56, 2.16s/it]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_2.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.66 * 10^-11 to 6.68 * 10^-11?"}] +Yes, according to the image, the value of the Gravity constant 'G' ranges from 6.66 * 10^-11 to 6.68 * 10^-11. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 926/951 [12:34<00:45, 1.83s/it]torch.Size([1, 661, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/6_2.png'}, {'type': 'text', 'value': "According to the image, does the value of Gravity constant 'G' range from 6.68 * 10^-11 to 6.70 * 10^-11?"}] +Yes, according to the image, the value of the Gravity constant 'G' ranges from 6.68 * 10^-11 to 6.70 * 10^-11. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 97%|█████████▋| 927/951 [12:35<00:38, 1.59s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the image, is the text in this figure the four freedoms proposed by Franklin D. Roosevelt?'}] +Yes, the text in the image is the four freedoms proposed by Franklin D. Roosevelt. The four freedoms are freedom of speech, freedom of worship, freedom from want, and freedom from fear. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 928/951 [12:37<00:38, 1.68s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_1.png'}, {'type': 'text', 'value': 'According to the image, is the freedom from fear among the four freedoms proposed in this image?'}] +Yes, the freedom from fear is one of the four freedoms proposed in the image. The other three freedoms are freedom of speech, freedom of worship, and freedom from want. These four freedoms are inscribed on a large stone or monument, which suggests that they are important values or principles that the creators of the monument wanted to emphasize or commemorate. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 929/951 [12:39<00:37, 1.69s/it]torch.Size([1, 644, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_2.png'}, {'type': 'text', 'value': 'According to the image, is the text in this figure the four freedoms proposed by Franklin D. Roosevelt?'}] +Yes, the text in the image is the four freedoms proposed by Franklin D. Roosevelt. The four freedoms are freedom of speech, freedom of worship, freedom from want, and freedom from fear. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 930/951 [12:40<00:32, 1.56s/it]torch.Size([1, 639, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/7_2.png'}, {'type': 'text', 'value': 'According to the image, is the freedom from fear among the four freedoms proposed in this image?'}] +Yes, the image shows the four freedoms proposed by President Franklin D. Roosevelt, which include freedom of speech, freedom of worship, freedom from want, and freedom from fear. The inscription on the stone wall reads "Freedom of Speech, Freedom of Worship, Freedom from Want, Freedom from Fear." + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 931/951 [12:42<00:33, 1.68s/it]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made at West Berlin?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 932/951 [12:42<00:23, 1.21s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +No, the text in the image is not made by John F. Kennedy. It is a quote from a book, specifically from the book "Berliner" by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 933/951 [12:43<00:20, 1.13s/it]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made at West Berlin?'}] +Yes, the text in the figure is made at West Berlin. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 934/951 [12:44<00:20, 1.19s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/8_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +No, the text in the figure is not made by John F. Kennedy. It is a quote from a different source. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 935/951 [12:46<00:21, 1.32s/it]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Abraham Lincoln?'}] +Yes, the text in this figure is made by Abraham Lincoln. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 98%|█████████▊| 936/951 [12:46<00:15, 1.04s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made at Gettysburg?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 937/951 [12:46<00:10, 1.31it/s]torch.Size([1, 629, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Abraham Lincoln?'}] +Yes, the text in this figure is a quote from Abraham Lincoln. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 938/951 [12:48<00:11, 1.10it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/9_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made at Gettysburg?'}] +Yes, the text in this figure is made at Gettysburg. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▊| 939/951 [12:48<00:09, 1.27it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Ronald Reagan?'}] +No, the text in the image is not made by Ronald Reagan. It is a political statement or a message written by someone else. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 940/951 [12:50<00:11, 1.01s/it]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_1.png'}, {'type': 'text', 'value': 'Is the text in this figure trying to talk to Gorbachev?'}] +Yes, the text in the image is addressed to Gorbachev, likely discussing political or social issues. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 941/951 [12:50<00:08, 1.14it/s]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Ronald Reagan?'}] +No, the text in the image is not made by Ronald Reagan. It is a handwritten message or a letter, possibly written by someone else. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 942/951 [12:52<00:08, 1.01it/s]torch.Size([1, 633, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/10_2.png'}, {'type': 'text', 'value': 'Is the text in this figure trying to talk to Gorbachev?'}] +Yes, the text in the image is addressed to Gorbachev, as it is written in Russian. The message is written in a foreign language, which suggests that it is intended for Gorbachev, possibly discussing a political or historical topic. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 943/951 [12:54<00:10, 1.27s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +Yes, the text in the figure is made by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 944/951 [12:54<00:07, 1.02s/it]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made in Canada?'}] +No, the text in this figure is not made in Canada. It is an excerpt from a book, likely written by an American author. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 945/951 [12:56<00:07, 1.19s/it]torch.Size([1, 631, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by John F. Kennedy?'}] +Yes, the text in the figure is made by John F. Kennedy. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 99%|█████████▉| 946/951 [12:56<00:04, 1.01it/s]torch.Size([1, 628, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/11_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made in Canada?'}] +Yes, the text in this figure is made in Canada. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 947/951 [12:56<00:03, 1.25it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Winston Churchill?'}] +Yes, the text in the image is a quote from Winston Churchill. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 948/951 [12:58<00:02, 1.06it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_1.png'}, {'type': 'text', 'value': 'Is the text in this figure made in the U.K.?'}] +Yes, the text in the image is written in the British language. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 949/951 [12:58<00:01, 1.28it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made by Winston Churchill?'}] +No, the text in the image is not made by Winston Churchill. It is a quote from the New World, which is a collection of writings by various authors. + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|█████████▉| 950/951 [12:59<00:00, 1.07it/s]torch.Size([1, 632, 32000]) +struct [{'type': 'image', 'value': '/home/tiger/LMUData/images/HallusionBench/VS/ocr/12_2.png'}, {'type': 'text', 'value': 'Is the text in this figure made in the U.K.?'}] +Yes + Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|██████████| 951/951 [13:00<00:00, 1.44it/s] Infer llava_v1.5_7b/HallusionBench, Rank 0/1: 100%|██████████| 951/951 [13:00<00:00, 1.22it/s] +[2025-08-25 00:07:37] INFO - RUN - run.py: main - 403: {'nproc': 4, 'verbose': True, 'retry': 3, 'model': 'chatgpt-0125'} +/mnt/bn/life-mllm/users/cxr/hallucination/VLMEvalKit/vlmeval/dataset/image_yorn.py:71: UserWarning: OPENAI_API_KEY is not working properly, will use exact matching for evaluation + warnings.warn('OPENAI_API_KEY is not working properly, will use exact matching for evaluation') +[2025-08-25 00:07:38] INFO - RUN - run.py: main - 458: The evaluation of model llava_v1.5_7b x dataset HallusionBench has finished! +[2025-08-25 00:07:38] INFO - RUN - run.py: main - 459: Evaluation Results: +[2025-08-25 00:07:38] INFO - RUN - run.py: main - 465: +-- ----------- ------- -------- -------- + 0 Overall 45.1104 18.2081 12.7473 + 1 VD 51.6074 23.0435 14.8014 + 2 VS 34.4444 8.62069 9.55056 + 3 VS_ocr 59.2593 23.0769 18.5185 + 4 VD_illusion 46.5278 27.4194 6.94444 + 5 VD_math 46.2963 13.8889 16.6667 + 6 VS_chart 31.5385 5 13.1579 + 7 VS_table 22.3214 0 2.32558 + 8 VS_map 40.625 9.09091 3.125 + 9 VD_video 48.8235 6.25 5.7971 +10 VD_ocr 65.1685 32.5581 30.2326 +11 VD_figure 58.75 34.1463 25.641 +-- ----------- ------- -------- -------- +HallusionBench +dataset_name: POPE +datalen: 5127 +lt2: 5127 + Infer llava_v1.5_7b/POPE, Rank 0/1: 0%| | 0/5127 [00:00 +out_file: ./outputs/20250901_193931/Qwen2.5-VL-7B-Instruct/T20250901_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250901_194058/Qwen2.5-VL-7B-Instruct/T20250901_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250901_194143/Qwen2.5-VL-7B-Instruct/T20250901_G/01_POPE.pkl +dataset_name: POPE +datalen: 2910 +lt2: 2910 + Fetching 1 files: 0%| | 0/1 [00:00 +out_file: ./outputs/20250915_011330/Gemma3-12B/T20250915_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 +`torch_dtype` is deprecated! Use `dtype` instead! + Loading checkpoint shards: 0%| | 0/5 [00:00 +out_file: ./outputs/20250915_005237/Gemma3-4B/T20250915_G/01_POPE.pkl +dataset_name: POPE +datalen: 3000 +lt2: 3000 +`torch_dtype` is deprecated! Use `dtype` instead! + Loading checkpoint shards: 0%| | 0/2 [00:00